Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LF: Factorize the logic for Ast lookup #9871

Merged
merged 25 commits into from
Jun 3, 2021
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e3e21f6
LF: Factorize the logic for Ast lookup
remyhaemmerle-da Jun 1, 2021
9131654
fix LF Adapater & TailCallTest
remyhaemmerle-da Jun 2, 2021
385374b
fix LookupError name space
remyhaemmerle-da Jun 2, 2021
1ad9355
make lookup result more generic
remyhaemmerle-da Jun 2, 2021
01fd6d0
Add LookupError.Defintiom
remyhaemmerle-da Jun 2, 2021
f751e76
comment lookupTypeSyn and lookupDataType
remyhaemmerle-da Jun 2, 2021
0b4699d
reformulate LookupError message
remyhaemmerle-da Jun 2, 2021
20b2bb9
add TODO comment around handleLookup definitions
remyhaemmerle-da Jun 2, 2021
7b6818e
use PackageSignature inside Interface
remyhaemmerle-da Jun 2, 2021
f02a475
fix ledger
remyhaemmerle-da Jun 2, 2021
d14d590
fix for scala 2.12
remyhaemmerle-da Jun 2, 2021
55a1db4
fix triggers
remyhaemmerle-da Jun 2, 2021
369ff82
fix LF test
remyhaemmerle-da Jun 2, 2021
98664ce
fix triggers tests
remyhaemmerle-da Jun 2, 2021
783887d
try to tweak canton conformance test
remyhaemmerle-da Jun 2, 2021
157eca7
formatting
remyhaemmerle-da Jun 2, 2021
5e12cd4
fix codec-benchmark
remyhaemmerle-da Jun 2, 2021
a81eab3
try to fix compatibility test
remyhaemmerle-da Jun 2, 2021
89f6990
try a bit more
remyhaemmerle-da Jun 2, 2021
1777cfc
a bit more try
remyhaemmerle-da Jun 3, 2021
1552f96
fix
remyhaemmerle-da Jun 3, 2021
94e2954
Apply suggestions from code review
remyhaemmerle-da Jun 3, 2021
372d3b3
Update compatibility/bazel_tools/testing.bzl
remyhaemmerle-da Jun 3, 2021
8a133be
fix compatibility test exlusions
remyhaemmerle-da Jun 3, 2021
bdfe9d8
fix
remyhaemmerle-da Jun 3, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// Copyright (c) 2021 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.lf.speedy.repl
package com.daml.lf
package speedy.repl

import akka.actor.ActorSystem
import akka.stream._
Expand Down Expand Up @@ -223,7 +224,8 @@ class ReplService(
val (pkgId, pkg) = Decode.decodeArchiveFromInputStream(req.getPackage.newInput)
val newSignatures = signatures.updated(pkgId, AstUtil.toSignature(pkg))
val newCompiledDefinitions = compiledDefinitions ++
new Compiler(newSignatures, compilerConfig).unsafeCompilePackage(pkgId, pkg)
new Compiler(language.Interface(newSignatures), compilerConfig)
.unsafeCompilePackage(pkgId, pkg)
signatures = newSignatures
compiledDefinitions = newCompiledDefinitions
respObs.onNext(LoadPackageResponse.newBuilder.build)
Expand Down Expand Up @@ -258,12 +260,11 @@ class ReplService(
}

val signatures = this.signatures.updated(homePackageId, AstUtil.toSignature(pkg))
val defs = new Compiler(signatures, compilerConfig).unsafeCompilePackage(homePackageId, pkg)
val compiledPackages = new PureCompiledPackages(
signatures,
compiledDefinitions ++ defs,
compilerConfig,
)
val interface = language.Interface(signatures)
val defs =
new Compiler(interface, compilerConfig).unsafeCompilePackage(homePackageId, pkg)
val compiledPackages =
PureCompiledPackages(signatures, compiledDefinitions ++ defs, compilerConfig)
val runner =
new Runner(compiledPackages, Script.Action(scriptExpr, ScriptIds(scriptPackageId)), timeMode)
runner
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,9 @@ class Context(val contextId: Context.ContextId, languageVersion: LanguageVersion
if (unloadPackages.nonEmpty || newPackages.nonEmpty) {
val invalidPackages = unloadModules ++ newPackages.keys
val newExtSignature = extSignatures -- unloadPackages ++ AstUtil.toSignatures(newPackages)
val interface = language.Interface(newExtSignature)
val newExtDefns = extDefns.view.filterKeys(sdef => !invalidPackages(sdef.packageId)) ++
assertRight(Compiler.compilePackages(newExtSignature, newPackages, compilerConfig))
assertRight(Compiler.compilePackages(interface, newPackages, compilerConfig))
// we update only if we manage to compile the new packages
extSignatures = newExtSignature
extDefns = newExtDefns.toMap
Expand All @@ -128,12 +129,12 @@ class Context(val contextId: Context.ContextId, languageVersion: LanguageVersion
newModules
}

val allSignatures = this.allSignatures
val compiler = new Compiler(allSignatures, compilerConfig)
val interface = language.Interface(this.allSignatures)
val compiler = new Compiler(interface, compilerConfig)

modulesToCompile.foreach { mod =>
if (!omitValidation)
assertRight(Validation.checkModule(allSignatures, homePackageId, mod).left.map(_.pretty))
assertRight(Validation.checkModule(interface, homePackageId, mod).left.map(_.pretty))
modDefns +=
mod.name -> compiler.unsafeCompileModule(homePackageId, mod).toMap
}
Expand All @@ -156,8 +157,7 @@ class Context(val contextId: Context.ContextId, languageVersion: LanguageVersion

private def buildMachine(identifier: Identifier): Option[Speedy.Machine] = {
val defns = this.defns
val compiledPackages =
PureCompiledPackages(allSignatures, defns, compilerConfig)
val compiledPackages = PureCompiledPackages(allSignatures, defns, compilerConfig)
for {
defn <- defns.get(LfDefRef(identifier))
} yield Speedy.Machine.fromScenarioSExpr(
Expand Down Expand Up @@ -192,8 +192,7 @@ class Context(val contextId: Context.ContextId, languageVersion: LanguageVersion
mat: Materializer,
): Future[Option[(ScenarioLedger, (Speedy.Machine, Speedy.Machine), Either[SError, SValue])]] = {
val defns = this.defns
val compiledPackages =
PureCompiledPackages(allSignatures, defns, compilerConfig)
val compiledPackages = PureCompiledPackages(allSignatures, defns, compilerConfig)
val expectedScriptId = DottedName.assertFromString("Daml.Script")
val Some(scriptPackageId) = allSignatures.collectFirst {
case (pkgId, pkg) if pkg.modules contains expectedScriptId => pkgId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -961,12 +961,10 @@ class DecodeV1Spec
inside(
decoder.decoder
.decodePackage(pkgId, decoder.extract(dalfProto))
.lookupDefinition(Ref.QualifiedName assertFromString "DarReaderTest:reverseCopy")
) {
case Right(
Ast.DValue(_, _, Ast.ELocation(_, Ast.EVal(Ref.Identifier(resolvedExtId, _))), _)
) =>
(resolvedExtId: String) should ===(extId: String)
.modules(Ref.DottedName.assertFromString("DarReaderTest"))
.definitions(Ref.DottedName.assertFromString("reverseCopy"))
) { case Ast.DValue(_, _, Ast.ELocation(_, Ast.EVal(Ref.Identifier(resolvedExtId, _))), _) =>
(resolvedExtId: String) should ===(extId: String)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import java.nio.file.Paths
import com.daml.lf.archive.{Dar, DarWriter}
import com.daml.lf.data.Ref
import com.daml.lf.data.Ref.PackageId
import com.daml.lf.language.{Ast, LanguageMajorVersion, LanguageVersion}
import com.daml.lf.language.{Ast, Interface, LanguageMajorVersion, LanguageVersion}
import com.daml.lf.testing.parser.{ParserParameters, parseModules}
import com.daml.lf.validation.Validation
import com.daml.SdkVersion
Expand Down Expand Up @@ -70,11 +70,11 @@ private[daml] object DamlLfEncoder extends App {
} else None

val pkg = Ast.Package(modules, Set.empty[PackageId], parserParameters.languageVersion, metadata)
val pkgs = Map(pkgId -> pkg)
val pkgs = Interface(Map(pkgId -> pkg))

Validation.checkPackage(pkgs, pkgId, pkg).left.foreach(e => error(e.pretty))

encodeArchive(pkgId -> pkgs(pkgId), parserParameters.languageVersion)
encodeArchive(pkgId -> pkg, parserParameters.languageVersion)
}

private def makeDar(source: String, file: File)(implicit
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// Copyright (c) 2021 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.lf.testing.archive
package com.daml.lf
package testing.archive

import com.daml.lf.archive.Decode
import com.daml.lf.archive.testing.Encode
Expand Down Expand Up @@ -183,7 +184,7 @@ object EncodeV1Spec {

private def validate(pkgId: PackageId, pkg: Package): Unit =
Validation
.checkPackage(Map(pkgId -> pkg), pkgId, pkg)
.checkPackage(language.Interface(Map(pkgId -> pkg)), pkgId, pkg)
.left
.foreach(e => sys.error(e.toString))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import java.util.concurrent.ConcurrentHashMap
import com.daml.lf.data.Ref.PackageId
import com.daml.lf.engine.ConcurrentCompiledPackages.AddPackageState
import com.daml.lf.language.Ast.{Package, PackageSignature}
import com.daml.lf.language.{Util => AstUtil}
import com.daml.lf.language.{Interface, Util => AstUtil}
import com.daml.lf.speedy.Compiler
import com.daml.lf.speedy.Compiler.CompilationError

Expand All @@ -21,16 +21,18 @@ import scala.collection.concurrent.{Map => ConcurrentMap}
*/
private[lf] final class ConcurrentCompiledPackages(compilerConfig: Compiler.Config)
extends MutableCompiledPackages(compilerConfig) {
private[this] val _signatures: ConcurrentMap[PackageId, PackageSignature] =
private[this] val signatures: ConcurrentMap[PackageId, PackageSignature] =
new ConcurrentHashMap().asScala
private[this] val _defns: ConcurrentHashMap[speedy.SExpr.SDefinitionRef, speedy.SDefinition] =
private[this] val definitions
: ConcurrentHashMap[speedy.SExpr.SDefinitionRef, speedy.SDefinition] =
new ConcurrentHashMap()
private[this] val _packageDeps: ConcurrentHashMap[PackageId, Set[PackageId]] =
private[this] val packageDeps: ConcurrentHashMap[PackageId, Set[PackageId]] =
new ConcurrentHashMap()

override def getSignature(pId: PackageId): Option[PackageSignature] = _signatures.get(pId)
override def packageIds: scala.collection.Set[PackageId] = signatures.keySet
override def interface: Interface = Interface(signatures)
override def getDefinition(dref: speedy.SExpr.SDefinitionRef): Option[speedy.SDefinition] =
Option(_defns.get(dref))
Option(definitions.get(dref))

/** Might ask for a package if the package you're trying to add references it.
*
Expand All @@ -56,7 +58,7 @@ private[lf] final class ConcurrentCompiledPackages(compilerConfig: Compiler.Conf
val pkgId: PackageId = toCompile.head
toCompile = toCompile.tail

if (!_signatures.contains(pkgId)) {
if (!signatures.contains(pkgId)) {

val pkg = state.packages.get(pkgId) match {
case None => return ResultError(Error(s"Could not find package $pkgId"))
Expand All @@ -65,7 +67,7 @@ private[lf] final class ConcurrentCompiledPackages(compilerConfig: Compiler.Conf

// Load dependencies of this package and transitively its dependencies.
for (dependency <- pkg.directDeps) {
if (!_signatures.contains(dependency) && !state.seenDependencies.contains(dependency)) {
if (!signatures.contains(dependency) && !state.seenDependencies.contains(dependency)) {
return ResultNeedPackage(
dependency,
{
Expand All @@ -87,33 +89,30 @@ private[lf] final class ConcurrentCompiledPackages(compilerConfig: Compiler.Conf
// map using 'computeIfAbsent' which will ensure we only compile the
// package once. Other concurrent calls to add this package will block
// waiting for the first one to finish.
if (!_signatures.contains(pkgId)) {
val signature = AstUtil.toSignature(pkg)
val signatureLookup: PartialFunction[PackageId, PackageSignature] = { case `pkgId` =>
signature
}
if (!signatures.contains(pkgId)) {
val tempSignature = language.Interface(Map(pkgId -> pkg) orElse signatures)

// Compile the speedy definitions for this package.
val defns =
try {
new speedy.Compiler(signatureLookup orElse _signatures, compilerConfig)
.unsafeCompilePackage(pkgId, pkg)
new speedy.Compiler(tempSignature, compilerConfig).unsafeCompilePackage(pkgId, pkg)
} catch {
case CompilationError(msg) =>
return ResultError(Error(s"Compilation Error: $msg"))
case e: validation.ValidationError =>
return ResultError(Error(s"Validation Error: ${e.pretty}"))
}
defns.foreach { case (defnId, defn) =>
_defns.put(defnId, defn)
definitions.put(defnId, defn)
}
// Compute the transitive dependencies of the new package. Since we are adding
// packages in dependency order we can just union the dependencies of the
// direct dependencies to get the complete transitive dependencies.
val deps = pkg.directDeps.foldLeft(pkg.directDeps) { case (deps, dependency) =>
deps union _packageDeps.get(dependency)
deps union packageDeps.get(dependency)
}
_packageDeps.put(pkgId, deps)
_signatures.put(pkgId, signature)
packageDeps.put(pkgId, deps)
signatures.put(pkgId, AstUtil.toSignature(pkg))
}
}
}
Expand All @@ -122,16 +121,13 @@ private[lf] final class ConcurrentCompiledPackages(compilerConfig: Compiler.Conf
}

def clear(): Unit = this.synchronized[Unit] {
_signatures.clear()
_packageDeps.clear()
_defns.clear()
signatures.clear()
packageDeps.clear()
definitions.clear()
}

override def packageIds: Set[PackageId] =
_signatures.keySet.toSet

def getPackageDependencies(pkgId: PackageId): Option[Set[PackageId]] =
Option(_packageDeps.get(pkgId))
Option(packageDeps.get(pkgId))
}

object ConcurrentCompiledPackages {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import com.daml.lf.transaction.Node._
import com.daml.lf.value.Value
import java.nio.file.Files

import com.daml.lf.language.LanguageVersion
import com.daml.lf.language.{LanguageVersion, Interface}
import com.daml.lf.validation.Validation
import com.daml.lf.value.Value.ContractId

Expand Down Expand Up @@ -217,7 +217,7 @@ class Engine(val config: EngineConfig = new EngineConfig(LanguageVersion.StableV
}

private[engine] def loadPackages(pkgIds: List[PackageId]): Result[Unit] =
pkgIds.dropWhile(compiledPackages.signatures.isDefinedAt) match {
pkgIds.dropWhile(compiledPackages.packageIds.contains) match {
case pkgId :: rest =>
ResultNeedPackage(
pkgId,
Expand Down Expand Up @@ -415,7 +415,6 @@ class Engine(val config: EngineConfig = new EngineConfig(LanguageVersion.StableV
pkgIds: Set[PackageId],
pkgs: Map[PackageId, Package],
): Either[Error, Unit] = {
val allSignatures = pkgs orElse compiledPackages().signatures
for {
_ <- pkgs
.collectFirst {
Expand All @@ -427,15 +426,15 @@ class Engine(val config: EngineConfig = new EngineConfig(LanguageVersion.StableV
}
.toLeft(())
_ <- {
val unknownPackages = pkgIds.filterNot(allSignatures.isDefinedAt)
val unknownPackages = pkgIds.filterNot(pkgs.isDefinedAt)
Either.cond(
unknownPackages.isEmpty,
(),
Error(s"Unknown packages ${unknownPackages.mkString(", ")}"),
)
}
_ <- {
val missingDeps = pkgIds.flatMap(pkgId => allSignatures(pkgId).directDeps).filterNot(pkgIds)
val missingDeps = pkgs.valuesIterator.flatMap(_.directDeps).toSet.filterNot(pkgIds)
Either.cond(
missingDeps.isEmpty,
(),
Expand All @@ -445,12 +444,13 @@ class Engine(val config: EngineConfig = new EngineConfig(LanguageVersion.StableV
),
)
}
interface = Interface(pkgs)
_ <- {
pkgs.iterator
// we trust already loaded packages
.collect {
case (pkgId, pkg) if !compiledPackages.signatures.isDefinedAt(pkgId) =>
Validation.checkPackage(allSignatures, pkgId, pkg)
case (pkgId, pkg) if !compiledPackages.packageIds.contains(pkgId) =>
Validation.checkPackage(interface, pkgId, pkg)
}
.collectFirst { case Left(err) => Error(err.pretty) }
}.toLeft(())
Expand Down
Loading