diff --git a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Anf.scala b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Anf.scala index 8692e0a8d8..a6e7b1fe90 100644 --- a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Anf.scala +++ b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Anf.scala @@ -189,7 +189,6 @@ private[lf] object Anf { case loc: source.SELoc => convertLoc(loc) case source.SEValue(x) => target.SEValue(x) case source.SEBuiltin(x) => target.SEBuiltin(x) - case source.SEBuiltinRecursiveDefinition(x) => target.SEBuiltinRecursiveDefinition(x) } } diff --git a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/ClosureConversion.scala b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/ClosureConversion.scala index 01a02e6825..5087f68f33 100644 --- a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/ClosureConversion.scala +++ b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/ClosureConversion.scala @@ -5,11 +5,7 @@ package com.daml.lf.speedy /** Closure Conversion (Phase of the speedy compiler pipeline) * - * This compilation phase transforms from SExpr0 to SExpr0. - * SExpr0 contains expression forms which exist during the speedy compilation pipeline. - * - * TODO: introduces new expression type (SExpr1) for the result of this phase, and input to the - * following ANF transformation phase. + * This compilation phase transforms from SExpr0 to SExpr1. */ import com.daml.lf.speedy.{SExpr0 => source} @@ -62,7 +58,6 @@ private[speedy] object ClosureConversion { case source.SEVal(ref) => target.SEVal(ref) case source.SEBuiltin(b) => target.SEBuiltin(b) case source.SEValue(v) => target.SEValue(v) - case source.SEBuiltinRecursiveDefinition(f) => target.SEBuiltinRecursiveDefinition(f) case source.SELocation(loc, body) => target.SELocation(loc, closureConvert(remaps, body)) @@ -158,7 +153,6 @@ private[speedy] object ClosureConversion { case _: source.SEVal => free case _: source.SEBuiltin => free case _: source.SEValue => free - case _: source.SEBuiltinRecursiveDefinition => free case source.SELocation(_, body) => go(body, bound, free) case source.SEAppGeneral(fun, args) => diff --git a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Compiler.scala b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Compiler.scala index 4d2f0877b3..171da6ff67 100644 --- a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Compiler.scala +++ b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Compiler.scala @@ -570,12 +570,6 @@ private[lf] final class Compiler( @inline private[this] def compileBuiltin(bf: BuiltinFunction): s.SExpr = bf match { - case BEqualList => - val ref: t.SEBuiltinRecursiveDefinition.Reference = - t.SEBuiltinRecursiveDefinition.Reference.EqualList - val exp: s.SExpr = s.SEBuiltinRecursiveDefinition(ref) - withLabelS(ref, exp) - case BCoerceContractId => s.SEAbs.identity // Numeric Comparisons case BLessNumeric => SBLessNumeric @@ -639,6 +633,7 @@ private[lf] final class Compiler( // List functions case BFoldl => SBFoldl case BFoldr => SBFoldr + case BEqualList => SBEqualList // Errors case BError => SBError @@ -690,8 +685,8 @@ private[lf] final class Compiler( case BTextIntercalate => SBTextIntercalate // Implemented using normal SExpr - case BFoldl | BFoldr | BCoerceContractId | BEqual | BEqualList | BLessEq | - BLess | BGreaterEq | BGreater | BLessNumeric | BLessEqNumeric | BGreaterNumeric | + + case BCoerceContractId | BLessNumeric | BLessEqNumeric | BGreaterNumeric | BGreaterEqNumeric | BEqualNumeric | BNumericToText | BTextMapEmpty | BGenMapEmpty => throw CompilationError(s"unexpected $bf") diff --git a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Pretty.scala b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Pretty.scala index dc9318109d..079cb80de7 100644 --- a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Pretty.scala +++ b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Pretty.scala @@ -513,7 +513,6 @@ private[lf] object Pretty { case SEScopeExercise(body) => text("exercise") + char('(') + prettySExpr(index)(body) + text(")") - case x: SEBuiltinRecursiveDefinition => str(x) case x: SEImportValue => str(x) case x: SELabelClosure => str(x) case x: SEDamlException => str(x) diff --git a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Profile.scala b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Profile.scala index 3ba8b45c85..ffe187c425 100644 --- a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Profile.scala +++ b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Profile.scala @@ -251,7 +251,6 @@ object Profile { implicit val lookupByKeyDefRef: Allowed[LookupByKeyDefRef] = allowAll implicit val createAndExerciseLabel: Allowed[CreateAndExerciseLabel] = allowAll implicit val exceptionMessageDefRef: Allowed[ExceptionMessageDefRef] = allowAll - implicit val sebrdr: Allowed[SEBuiltinRecursiveDefinition.Reference] = allowAll implicit val scenarioLabel: Allowed[ScenarioLabel] = allowAll implicit val exprVarName: Allowed[Ast.ExprVarName] = allowAll @@ -281,7 +280,6 @@ object Profile { case CreateAndExerciseLabel(tmplRef, name) => s"createAndExercise @${tmplRef.qualifiedName} ${name}" case ExceptionMessageDefRef(typeId) => s"message @${typeId.qualifiedName}" - case ref: SEBuiltinRecursiveDefinition.Reference => ref.toString().toLowerCase() case SubmitLabel => "submit" case SubmitMustFailLabel => "submitMustFail" case PassLabel => "pass" diff --git a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SBuiltin.scala b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SBuiltin.scala index 4fb4eddd5c..5bc95e2ffa 100644 --- a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SBuiltin.scala +++ b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SBuiltin.scala @@ -1706,6 +1706,82 @@ private[lf] object SBuiltin { } } + /** EQUAL_LIST :: (a -> a -> Bool) -> [a] -> [a] -> Bool */ + final case object SBEqualList extends SBuiltin(3) { + + private val equalListBody: SExpr = + SECaseAtomic( // case xs of + SELocA(1), + Array( + SCaseAlt( + SCPNil, // nil -> + SECaseAtomic( // case ys of + SELocA(2), + Array( + SCaseAlt(SCPNil, SEValue.True), // nil -> True + SCaseAlt(SCPDefault, SEValue.False), + ), + ), // default -> False + ), + SCaseAlt( // cons x xss -> + SCPCons, + SECaseAtomic( // case ys of + SELocA(2), + Array( + SCaseAlt(SCPNil, SEValue.False), // nil -> False + SCaseAlt( // cons y yss -> + SCPCons, + SELet1( // let sub = (f y x) in + SEAppAtomicGeneral( + SELocA(0), // f + Array( + SELocS(2), // y + SELocS(4), + ), + ), // x + SECaseAtomic( // case (f y x) of + SELocS(1), + Array( + SCaseAlt( + SCPPrimCon(Ast.PCTrue), // True -> + SEAppAtomicGeneral( + SEBuiltin(SBEqualList), //single recursive occurrence + Array( + SELocA(0), // f + SELocS(2), // yss + SELocS(4), + ), + ), // xss + ), + SCaseAlt(SCPPrimCon(Ast.PCFalse), SEValue.False), // False -> False + ), + ), + ), + ), + ), + ), + ), + ), + ) + + private val closure: SValue = { + val frame = Array.ofDim[SValue](0) // no free vars + val arity = 3 + SPAP(PClosure(Profile.LabelUnset, equalListBody, frame), new util.ArrayList[SValue](), arity) + } + + override private[speedy] def execute(args: util.ArrayList[SValue], machine: Machine) = { + val f = args.get(0) + val xs = args.get(1) + val ys = args.get(2) + machine.enterApplication( + closure, + Array(SEValue(f), SEValue(xs), SEValue(ys)), + ) + } + + } + object SBExperimental { private object SBExperimentalAnswer extends SBuiltin(1) { diff --git a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SExpr.scala b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SExpr.scala index 1a8b30e318..74a0350b65 100644 --- a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SExpr.scala +++ b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SExpr.scala @@ -443,102 +443,6 @@ object SExpr { methodName: MethodName, ) extends SDefinitionRef - // - // List builtins (equalList) are implemented as recursive - // definition to save java stack - // - - final case class SEBuiltinRecursiveDefinition(ref: SEBuiltinRecursiveDefinition.Reference) - extends SExprAtomic { - - import SEBuiltinRecursiveDefinition._ - - private val frame = Array.ofDim[SValue](0) // no free vars - val arity = 3 - - private def body: SExpr = ref match { - case Reference.EqualList => equalListBody - } - - private def closure: SValue = - SPAP(PClosure(Profile.LabelUnset, body, frame), new util.ArrayList[SValue](), arity) - - def lookupValue(machine: Machine): SValue = closure - - } - - // TODO: simplify here: There is only kind of SEBuiltinRecursiveDefinition! - EqualList - final object SEBuiltinRecursiveDefinition { - - sealed abstract class Reference - - final object Reference { - final case object EqualList extends Reference - } - - private val EqualList: SEBuiltinRecursiveDefinition = SEBuiltinRecursiveDefinition( - Reference.EqualList - ) - - // The body of an expanded recursive-builtin will always be in ANF form. - // The comments show where variables are to be found at runtime. - - private def equalListBody: SExpr = - SECaseAtomic( // case xs of - SELocA(1), - Array( - SCaseAlt( - SCPNil, // nil -> - SECaseAtomic( // case ys of - SELocA(2), - Array( - SCaseAlt(SCPNil, SEValue.True), // nil -> True - SCaseAlt(SCPDefault, SEValue.False), - ), - ), // default -> False - ), - SCaseAlt( // cons x xss -> - SCPCons, - SECaseAtomic( // case ys of - SELocA(2), - Array( - SCaseAlt(SCPNil, SEValue.False), // nil -> False - SCaseAlt( // cons y yss -> - SCPCons, - SELet1( // let sub = (f y x) in - SEAppAtomicGeneral( - SELocA(0), // f - Array( - SELocS(2), // y - SELocS(4), - ), - ), // x - SECaseAtomic( // case (f y x) of - SELocS(1), - Array( - SCaseAlt( - SCPPrimCon(PCTrue), // True -> - SEAppAtomicGeneral( - EqualList, - Array( - SELocA(0), // f - SELocS(2), // yss - SELocS(4), - ), - ), // xss - ), - SCaseAlt(SCPPrimCon(PCFalse), SEValue.False), // False -> False - ), - ), - ), - ), - ), - ), - ), - ), - ) - } - final case object AnonymousClosure private def prettyPrint(x: Any): String = diff --git a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SExpr0.scala b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SExpr0.scala index 65c502ef77..469252869e 100644 --- a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SExpr0.scala +++ b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SExpr0.scala @@ -30,9 +30,8 @@ package speedy * * Summary of which constructors are contained by: SExp0, SExpr1 and SExpr: * - * - In SExpr{0,1,} (everywhere): SEAppGeneral, SEBuiltin, SEBuiltinRecursiveDefinition, - * SELabelClosure, SELet1General, SELocation, - * SEScopeExercise, SETryCatch, SEVal, SEValue, + * - In SExpr{0,1,} (everywhere): SEAppGeneral, SEBuiltin, SELabelClosure, SELet1General, + * SELocation, SEScopeExercise, SETryCatch, SEVal, SEValue, * * - In SExpr0: SEAbs, SEVar * @@ -49,7 +48,6 @@ package speedy import com.daml.lf.data.Ref._ import com.daml.lf.speedy.SValue._ import com.daml.lf.speedy.SExpr.{SDefinitionRef, SCasePat} -import com.daml.lf.speedy.{SExpr => runTime} @SuppressWarnings(Array("org.wartremover.warts.Any")) private[speedy] object SExpr0 { @@ -139,14 +137,4 @@ private[speedy] object SExpr0 { * extended and 'body' is evaluated. */ final case class SCaseAlt(pattern: SCasePat, body: SExpr) - - // - // List builtins (equalList) are implemented as recursive - // definition to save java stack - // - - // TODO: simplify here: There is only kind of SEBuiltinRecursiveDefinition! - EqualList - final case class SEBuiltinRecursiveDefinition(ref: runTime.SEBuiltinRecursiveDefinition.Reference) - extends SExpr - } diff --git a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SExpr1.scala b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SExpr1.scala index 53d840675b..a7271038bb 100644 --- a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SExpr1.scala +++ b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SExpr1.scala @@ -12,7 +12,6 @@ package speedy import com.daml.lf.data.Ref._ import com.daml.lf.speedy.SValue._ import com.daml.lf.speedy.SExpr.{SDefinitionRef, SCasePat} -import com.daml.lf.speedy.{SExpr => runTime} private[speedy] object SExpr1 { @@ -109,8 +108,4 @@ private[speedy] object SExpr1 { * extended and 'body' is evaluated. */ final case class SCaseAlt(pattern: SCasePat, body: SExpr) - - final case class SEBuiltinRecursiveDefinition(ref: runTime.SEBuiltinRecursiveDefinition.Reference) - extends SExprAtomic - } diff --git a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/ValidateCompilation.scala b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/ValidateCompilation.scala index c573792ade..30cf0647a9 100644 --- a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/ValidateCompilation.scala +++ b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/ValidateCompilation.scala @@ -55,7 +55,6 @@ private[lf] object ValidateCompilation { case loc: SELoc => goLoc(loc) case _: SEVal => () case _: SEBuiltin => () - case _: SEBuiltinRecursiveDefinition => () case SEValue(v) => goV(v) case SEAppAtomicGeneral(fun, args) => go(fun) diff --git a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/iterable/SExprIterable.scala b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/iterable/SExprIterable.scala index 7660ef5dfb..edb2cc30d4 100644 --- a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/iterable/SExprIterable.scala +++ b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/iterable/SExprIterable.scala @@ -29,7 +29,6 @@ private[speedy] object SExprIterable { case SExpr.SETryCatch(body, handler) => Iterator(body, handler) case SExpr.SEScopeExercise(body) => Iterator(body) case SExpr.SEBuiltin(_) => Iterator.empty - case SExpr.SEBuiltinRecursiveDefinition(_) => Iterator.empty case SExpr.SELocA(_) => Iterator.empty case SExpr.SELocS(_) => Iterator.empty case SExpr.SEValue(v) => iterator(v)