mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 01:07:18 +03:00
Simplify handling for EqualList builtin. (#11676)
Step 1: SEBuiltinRecursiveDefinition(_) -> SEBuiltinEqualList CHANGELOG_BEGIN CHANGELOG_END Step2: Replace SEBuiltinEqualList with SBuiltin.SBEqualList update comment
This commit is contained in:
parent
90ad968d39
commit
a1fc5c6a25
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) =>
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
@ -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) {
|
||||
|
@ -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 =
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user