From 21519bc2f7e06810a008f04a1652936a3b616d7a Mon Sep 17 00:00:00 2001 From: Arya Irani Date: Sun, 10 Jun 2018 18:17:04 -0400 Subject: [PATCH 1/3] elide setting outputType on chains of unboxed functions --- .../main/src/main/scala/Builtins.scala | 76 +++++++------------ runtime-jvm/main/src/main/scala/Param.scala | 2 +- .../main/src/main/scala/UnisonToScala.scala | 58 +++++++------- .../main/src/main/scala/compilation.scala | 29 +++++-- 4 files changed, 81 insertions(+), 84 deletions(-) diff --git a/runtime-jvm/main/src/main/scala/Builtins.scala b/runtime-jvm/main/src/main/scala/Builtins.scala index c96da7326..f2e291cf9 100644 --- a/runtime-jvm/main/src/main/scala/Builtins.scala +++ b/runtime-jvm/main/src/main/scala/Builtins.scala @@ -1,7 +1,6 @@ package org.unisonweb -import java.util.function.{LongBinaryOperator, LongPredicate, LongUnaryOperator, - DoubleBinaryOperator} +import java.util.function.{DoubleBinaryOperator, LongBinaryOperator, LongPredicate, LongUnaryOperator} import org.unisonweb.Term.{Name, Term} import org.unisonweb.Value.Lambda @@ -392,11 +391,8 @@ object Builtins { arg: Name, outputType: UnboxedType, f: LongUnaryOperator): (Name, Computation) = { - val body: Computation.C1U = (r,x0) => { - // Unintuitively, we store the type of the unboxed value in `boxed` - // since that's a field we don't use for unboxed values. - r.boxed = outputType - f.applyAsLong(x0) + val body: Computation.C1U = new Computation.C1U(outputType) { + def raw(x0: U): U = f.applyAsLong(x0) } val decompile = Term.Id(name) val computation = Return(new Lambda1(arg, body, Some(outputType), decompile)) @@ -553,9 +549,8 @@ object Builtins { arg2: Name, outputType: UnboxedType, f: LongBinaryOperator): (Name, Computation) = { - val body: Computation.C2U = (r,x1,x0) => { - r.boxed = outputType - f.applyAsLong(x1, x0) + val body = new Computation.C2U(outputType) { + def raw(x1: U, x0: U): U = f.applyAsLong(x1, x0) } val decompiled = Term.Id(name) @@ -566,52 +561,41 @@ object Builtins { case List(Return(Value.Unboxed(n1, _)), Return(Value.Unboxed(n2, _))) => val n3 = f.applyAsLong(n1,n2) // constant fold - val c : Computation.C0 = r => { r.boxed = outputType; n3 } - c + new Computation.C0U(outputType) { + def raw: U = n3 + } case List(CompiledVar0,Return(Value.Unboxed(n, _))) => - val c : Computation.C1U = (r,x0) => { - r.boxed = outputType - f.applyAsLong(x0, n) + new Computation.C1U(outputType) { + def raw(x0: U): U = f.applyAsLong(x0, n) } - c case List(CompiledVar1,Return(Value.Unboxed(n, _))) => - val c : Computation.C2U = (r,x1,_) => { - r.boxed = outputType - f.applyAsLong(x1, n) + new Computation.C2U(outputType) { + def raw(x1: U, x0: U): U = f.applyAsLong(x1, n) } - c case List(Return(Value.Unboxed(n, _)), CompiledVar0) => - val c: Computation.C1U = (r,x0) => { - r.boxed = outputType - f.applyAsLong(n,x0) + new Computation.C1U(outputType) { + def raw(x0: U): U = f.applyAsLong(n,x0) } - c case List(Return(Value.Unboxed(n, _)), CompiledVar1) => - val c: Computation.C2U = (r,x1,_) => { - r.boxed = outputType - f.applyAsLong(n,x1) + new Computation.C2U(outputType) { + def raw(x1: U, x0: U): U = f.applyAsLong(n,x1) } - c case List(CompiledVar1,CompiledVar0) => - val c: Computation.C2U = (r,x1,x0) => { - r.boxed = outputType - f.applyAsLong(x1,x0) + new Computation.C2U(outputType) { + def raw(x1: U, x0: U): U = f.applyAsLong(x1,x0) } - c case List(CompiledVar0,CompiledVar1) => - val c: Computation.C2U = (r,x1,x0) => { - r.boxed = outputType - f.applyAsLong(x0,x1) + new Computation.C2U(outputType) { + def raw(x1: U, x0: U): U = f.applyAsLong(x0,x1) } - c case List(arg1: Computation.C2U, arg2: Computation.C2U) => - val c: Computation.C2U = (r,x1,x0) => { - val x1v = arg1(r, x1, x0) - val x0v = arg2(r, x1, x0) - r.boxed = outputType - f.applyAsLong(x1v, x0v) + new Computation.C2U(outputType) { + def raw(x1: U, x0: U): U = { + val x1v = arg1.raw(x1, x0) + val x0v = arg2.raw(x1, x0) + f.applyAsLong(x1v, x0v) + } } - c case List(arg1,arg2) => (r,rec,top,stackU,x1,x0,stackB,x1b,x0b) => { val x1v = eval(arg1,r,rec,top,stackU,x1,x0,stackB,x1b,x0b) val x0v = eval(arg2,r,rec,top,stackU,x1,x0,stackB,x1b,x0b) @@ -626,11 +610,9 @@ object Builtins { case Term.Compiled(p: Param) => // cast is okay, because in `fuu_u`, args are Unboxed. val n = p.toValue.asInstanceOf[Value.Unboxed].n - val body: Computation = - (r,rec,top,stackU,x1,x0,stackB,x1b,x0b) => { - r.boxed = outputType - f.applyAsLong(n, x0) - } + val body = new Computation.C1U(outputType) { + def raw(x0: U): U = f.applyAsLong(n, x0) + } new Lambda(self.names drop argCount, body, unboxedType, Term.Apply(decompiled, term)) case _ => sys.error("") diff --git a/runtime-jvm/main/src/main/scala/Param.scala b/runtime-jvm/main/src/main/scala/Param.scala index a2785df93..1ddb4efbf 100644 --- a/runtime-jvm/main/src/main/scala/Param.scala +++ b/runtime-jvm/main/src/main/scala/Param.scala @@ -122,7 +122,7 @@ object Value { Some((l.arity, l.body, l.decompile)) val identity: Lambda1 = { - val c: Computation = (r,rec,top,stackU,x1,x0,stackB,x1b,x0b) => { + val c: Computation.C1P = (r,x0,x0b) => { r.boxed = x0b.toValue x0 } diff --git a/runtime-jvm/main/src/main/scala/UnisonToScala.scala b/runtime-jvm/main/src/main/scala/UnisonToScala.scala index d4d5b3866..1e40db910 100644 --- a/runtime-jvm/main/src/main/scala/UnisonToScala.scala +++ b/runtime-jvm/main/src/main/scala/UnisonToScala.scala @@ -12,23 +12,24 @@ object UnisonToScala { def toUnboxed1(f: Value.Lambda): Env => Unboxed.F1[Param,Value] = { require (f.arity == 1) - f.unboxedType.map[Env => Unboxed.F1[Param,Value]] { - outputType => - env => { + f.body match { + case body: Computation.C1U => + env => val (stackU, stackB, top, r) = env - f.body match { - case body: Computation.C1U => new Unboxed.F1[Param,Value] { - def apply[x] = kvx => (u1,a,u2,x) => kvx(body(r,u1), outputType, u2, x) - } - case body => new Unboxed.F1[Param,Value] { - def apply[x] = kvx => (u1,a,u2,x) => { - val out = evalLam(f, r, top, stackU, U0, u1, stackB, null, a) - kvx(out, r.boxed, u2, x) - } + new Unboxed.F1[Param, Value] { + // todo: can I just call body.raw(u1) here instead of body.apply? + def apply[x] = kvx => (u1,a,u2,x) => kvx(body.raw(u1), body.outputType, u2, x) + } + case _body => + env => + val (stackU, stackB, top, r) = env + new Unboxed.F1[Param,Value] { + def apply[x] = kvx => (u1,a,u2,x) => { + val out = evalLam(f, r, top, stackU, U0, u1, stackB, null, a) + kvx(out, r.boxed, u2, x) } } - } - }.getOrElse(sys.error("`f` is expected to have an unboxed output type")) + } } def toUnboxed2(p: (Term.Name, Computation)): Env => Unboxed.F2[Value,Value,Value] = @@ -36,22 +37,23 @@ object UnisonToScala { def toUnboxed2(f: Value.Lambda): Env => Unboxed.F2[Value,Value,Value] = { require(f.arity == 2) - f.unboxedType.map[Env => Unboxed.F2[Value,Value,Value]] { - outputType => - env => { + f.body match { + case body: Computation.C2U => + env => val (stackU, stackB, top, r) = env - f.body match { - case body: Computation.C2U => new Unboxed.F2[Param, Param, Value] { - def apply[x] = kvx => (u1, a, u2, b, u3, x) => kvx(body(r, u1, u2), outputType, u3, x) - } - case body => new Unboxed.F2[Param, Param, Value] { - def apply[x] = kvx => (u1, a, u2, b, u3, x) => { - val out = evalLam(f, r, top, stackU, u1, u2, stackB, a, b) - kvx(out, r.boxed, u3, x) - } + new Unboxed.F2[Param, Param, Value] { + def apply[x] = kvx => (u1, a, u2, b, u3, x) => kvx(body.raw(u1, u2), body.outputType, u3, x) + } + + case body => + env => + val (stackU, stackB, top, r) = env + new Unboxed.F2[Param, Param, Value] { + def apply[x] = kvx => (u1, a, u2, b, u3, x) => { + val out = evalLam(f, r, top, stackU, u1, u2, stackB, a, b) + kvx(out, r.boxed, u3, x) } } - } - }.getOrElse(sys.error("`f` is expected to have an unboxed output type")) + } } } diff --git a/runtime-jvm/main/src/main/scala/compilation.scala b/runtime-jvm/main/src/main/scala/compilation.scala index caa355968..222834bd7 100644 --- a/runtime-jvm/main/src/main/scala/compilation.scala +++ b/runtime-jvm/main/src/main/scala/compilation.scala @@ -129,18 +129,31 @@ package object compilation { // Special cases for computations that take unboxed arguments and produce unboxed results, // and which are guaranteed not to throw tail call exceptions during evaluation. We check for // these in various places to emit more efficient code for common cases. - abstract class C2U extends Computation { - def apply(r: R, x1: U, x0: U): U + abstract class C2U(val outputType: UnboxedType) extends Computation { + def raw(x1: U, x0: U): U + + final def apply(r: R, x1: U, x0: U): U = { + r.boxed = outputType + raw(x1, x0) + } final def apply(r: R, rec: Lambda, top: StackPtr, stackU: Array[U], x1: U, x0: U, stackB: Array[B], x1b: B, x0b: B): U = apply(r, x1, x0) } - abstract class C1U extends C2U { - def apply(r: R, x0: U): U - final def apply(r: R, x1: U, x0: U): U = apply(r, x0) + abstract class C1U(outputType: UnboxedType) extends C2U(outputType) { + def raw(x0: U): U + final def raw(x1: U, x0: U) = raw(x0) + final def apply(r: R, x0: U): U = { + r.boxed = outputType + raw(x0) + } } - abstract class C0U extends C1U { - def apply(r: R): U - final def apply(r: R, x0: U): U = apply(r) + abstract class C0U(outputType: UnboxedType) extends C1U(outputType) { + def raw: U + final def raw(x0: U) = raw + final def apply(r: R): U = { + r.boxed = outputType + raw + } } abstract class C2P extends Computation { def apply(r: R, x1: U, x0: U, x1b: B, x0b: B): U From 1b76aff3fd429cc9db3ea5e66491f739b9f0077b Mon Sep 17 00:00:00 2001 From: Arya Irani Date: Sun, 10 Jun 2018 19:27:13 -0400 Subject: [PATCH 2/3] remove `outputType: UnboxedType` field from `Lambda` in favor of `Computation.C2U` --- .../main/src/main/scala/BuiltinTypes.scala | 2 +- .../main/src/main/scala/Builtins.scala | 26 ++++----- runtime-jvm/main/src/main/scala/Param.scala | 56 ++++++++++++------- .../main/src/main/scala/compilation.scala | 10 +++- .../src/test/scala/CompilationTests.scala | 2 +- 5 files changed, 57 insertions(+), 39 deletions(-) diff --git a/runtime-jvm/main/src/main/scala/BuiltinTypes.scala b/runtime-jvm/main/src/main/scala/BuiltinTypes.scala index 0e63f78de..6fce23bc1 100644 --- a/runtime-jvm/main/src/main/scala/BuiltinTypes.scala +++ b/runtime-jvm/main/src/main/scala/BuiltinTypes.scala @@ -134,7 +134,7 @@ object BuiltinTypes { } val lam: Computation = if (arity >= 1) - new Value.Lambda.ClosureForming(paramNames.toList, body, None, decompile) + new Value.Lambda.ClosureForming(paramNames.toList, body, decompile) .toComputation else try { Return(req(Array())) diff --git a/runtime-jvm/main/src/main/scala/Builtins.scala b/runtime-jvm/main/src/main/scala/Builtins.scala index f2e291cf9..b4670991e 100644 --- a/runtime-jvm/main/src/main/scala/Builtins.scala +++ b/runtime-jvm/main/src/main/scala/Builtins.scala @@ -71,7 +71,7 @@ object Builtins { } val decompiled = Term.Id(name) val lambda = - new Value.Lambda.ClosureForming(List(arg1, arg2, arg3), body, None, decompiled) + new Value.Lambda.ClosureForming(List(arg1, arg2, arg3), body, decompiled) name -> Return(lambda) } @@ -383,7 +383,7 @@ object Builtins { (implicit A: Decode[A], B: Encode[B]): (Name, Computation) = { val body: Computation.C1P = (r,x0,x0b) => B.encode(r, f(A.decode(x0, x0b))) val decompile = Term.Id(name) - name -> Return(new Lambda1(arg, body, None, decompile)) + name -> Return(new Lambda1(arg, body, decompile)) } // Monomorphic one-argument function on unboxed values @@ -395,7 +395,7 @@ object Builtins { def raw(x0: U): U = f.applyAsLong(x0) } val decompile = Term.Id(name) - val computation = Return(new Lambda1(arg, body, Some(outputType), decompile)) + val computation = Return(new Lambda1(arg, body, decompile)) name -> computation } @@ -427,7 +427,7 @@ object Builtins { val body: Computation.C1P = (r,x0,x0b) => { B.encodeOp(r, f(A.decode(x0, x0b)), name, Value.fromParam(x0, x0b)) } - val lambda = new Lambda.Lambda1(arg, body, None, Term.Id(name)) + val lambda = new Lambda.Lambda1(arg, body, Term.Id(name)) name -> Return(lambda) } @@ -439,7 +439,7 @@ object Builtins { (r,x1,x0,x1b,x0b) => C.encode(r, f(A.decode(x1, x1b), B.decode(x0, x0b))) val decompiled = Term.Id(name) - val lambda = new Lambda.ClosureForming(List(arg1, arg2), body, None, decompiled) + val lambda = new Lambda.ClosureForming(List(arg1, arg2), body, decompiled) name -> Return(lambda) } @@ -456,7 +456,7 @@ object Builtins { Value.fromParam(x0, x0b)) } val decompiled = Term.Id(name) - val lambda = new Lambda.ClosureForming(List(arg1, arg2), body, None, decompiled) + val lambda = new Lambda.ClosureForming(List(arg1, arg2), body, decompiled) name -> Return(lambda) } @@ -471,7 +471,7 @@ object Builtins { val body: Computation.C2P = (r,x1,x0,_,x0b) => B.encode(r, f(x1, A.decode(x0, x0b))) val decompiled = Term.Id(name) - val lambda = new Lambda.ClosureForming(List(arg1, arg2), body, None, decompiled) + val lambda = new Lambda.ClosureForming(List(arg1, arg2), body, decompiled) name -> Return(lambda) } @@ -483,7 +483,7 @@ object Builtins { name, Value.fromParam(x1,x1b), Value.fromParam(x0,x0b)) - name -> Return(new Value.Lambda.ClosureForming(List(arg1, arg2), body, None, Term.Id(name))) + name -> Return(new Value.Lambda.ClosureForming(List(arg1, arg2), body, Term.Id(name))) } @@ -499,7 +499,7 @@ object Builtins { Value.fromParam(x0, x0b)) val decompiled = Term.Id(name) - val lambda = new Lambda.ClosureForming(List(arg1, arg2), body, None, decompiled) + val lambda = new Lambda.ClosureForming(List(arg1, arg2), body, decompiled) name -> Return(lambda) } @@ -518,7 +518,7 @@ object Builtins { f(A.decode(x1, x1b), B.decode(x0, x0b)) } val decompiled = Term.Id(name) - val lambda = new Lambda.ClosureForming(List(arg1, arg2), body, None, decompiled) + val lambda = new Lambda.ClosureForming(List(arg1, arg2), body, decompiled) name -> Return(lambda) } @@ -554,7 +554,7 @@ object Builtins { } val decompiled = Term.Id(name) - val lam = new Lambda(List(arg1, arg2), body, Some(outputType), decompiled) { + val lam = new Lambda(List(arg1, arg2), body, decompiled) { self => override def saturatedNonTailCall(args: List[Computation]) = args match { @@ -613,11 +613,11 @@ object Builtins { val body = new Computation.C1U(outputType) { def raw(x0: U): U = f.applyAsLong(n, x0) } - new Lambda(self.names drop argCount, body, unboxedType, + new Lambda(self.names drop argCount, body, Term.Apply(decompiled, term)) case _ => sys.error("") } - case _ => sys.error("unpossible") + case _ => sys.error("can't underapply a function of 2 args with anything but 1 arg") } } name -> Return(lam) diff --git a/runtime-jvm/main/src/main/scala/Param.scala b/runtime-jvm/main/src/main/scala/Param.scala index 1ddb4efbf..df0f6d82d 100644 --- a/runtime-jvm/main/src/main/scala/Param.scala +++ b/runtime-jvm/main/src/main/scala/Param.scala @@ -59,7 +59,6 @@ object Value { class Lambda( final val names: List[Name], final val body: Computation, - final val unboxedType: Option[UnboxedType], // the lambda decompiled form may have one free var, referring to itself decompileWithPossibleFreeVar: Term) extends Value { self => @@ -81,14 +80,25 @@ object Value { def compose(f: Lambda): Lambda = { assert(arity == 1) - val k: Computation = (r, rec, top, stackU, x1, x0, stackB, x1b, x0b) => { - val v = evalLam(f,r,top,stackU,x1,x0,stackB,x1b,x0b) - val vb = r.boxed - self(r,top,stackU,U0,v,stackB,null,vb) + + val k: Computation = (self.body, f.body) match { + case (left: Computation.C1U, right: Computation.C1U) => + new compilation.Computation.C1U(left.outputType) { + def raw(x0: U): U = left.raw(right.raw(x0)) + } + case (left: Computation.C1U, right: Computation.C2U) => + new Computation.C2U(left.outputType) { + def raw(x1: U, x0: U): U = left.raw(right.raw(x1, x0)) + } + case _ => + (r, rec, top, stackU, x1, x0, stackB, x1b, x0b) => { + val v = evalLam(f,r,top,stackU,x1,x0,stackB,x1b,x0b) + val vb = r.boxed + self(r,top,stackU,U0,v,stackB,null,vb) + } } val compose = Term.Lam('f, 'g, 'x)('f.v('g.v('x))) // todo: intern this - new Lambda(f.names, k, self.unboxedType, - compose(self.decompile, f.decompile)) + new Lambda(f.names, k, compose(self.decompile, f.decompile)) } def saturatedNonTailCall(args: List[Computation]): Computation = @@ -112,10 +122,9 @@ object Value { object Lambda { final def toValue = this - def apply(arity: Int, body: Computation, unboxedType: Option[UnboxedType], - decompile: Term) = { + def apply(arity: Int, body: Computation, decompile: Term) = { new Lambda(names = decompile match { case Term.Lam(names, _) => names }, - body, unboxedType, decompile) + body, decompile) } def unapply(l: Lambda): Option[(Int, Computation, Term)] = @@ -126,23 +135,20 @@ object Value { r.boxed = x0b.toValue x0 } - Lambda1("x", c, None, Term.Lam('x)('x)) + Lambda1("x", c, Term.Lam('x)('x)) } /** A `Lambda` of arity 1. */ // todo: delete this and ClosureForming2 later - case class Lambda1(arg1: Name, _body: Computation, - outputType: Option[UnboxedType], decompiled: Term) - extends Lambda(names = List(arg1),_body,outputType,decompiled) { + case class Lambda1(arg1: Name, _body: Computation, decompiled: Term) + extends Lambda(names = List(arg1),_body,decompiled) { override def underapply(builtins: Environment)( argCount: Arity, substs: Map[Name, Term]): Lambda = sys.error("a lambda with arity 1 cannot be underapplied") } - class ClosureForming(names: List[Name], body: Computation, - outputType: Option[UnboxedType], - decompiled: Term) - extends Lambda(names,body,outputType,decompiled) { self => + class ClosureForming(names: List[Name], body: Computation, decompiled: Term) + extends Lambda(names,body,decompiled) { self => val namesArray = names.toArray /** Underapply this `Lambda`, passing 1 argument (named `substName`). */ @@ -157,8 +163,16 @@ object Value { val body2: Computation = arity match { // stack passed to `body2`: [a] // stack passed to `body` : [arg,a] - case 2 => (r,rec,top,stackU,x1,x0,stackB,x1b,x0b) => - body(r,rec,top,stackU,argv,x0,stackB,argvb,x0b) + case 2 => + body match { + case c2u: Computation.C2U => new Computation.C1U(c2u.outputType) { + def raw(x0: U): U = c2u.raw(argv,x0) + } + case _ => + (r,rec,top,stackU,x1,x0,stackB,x1b,x0b) => + body(r,rec,top,stackU,argv,x0,stackB,argvb,x0b) + } + // stack passed to `body2`: [a,b] // stack passed to `body` : [arg,a,b] case 3 => (r,rec,top,stackU,x1,x0,stackB,x1b,x0b) => { @@ -181,7 +195,7 @@ object Value { body(r,rec,top.inc,stackU,x1,x0,stackB,x1b,x0b) } } - new ClosureForming(names drop 1, body2, outputType, decompiled(substTerm)) + new ClosureForming(names drop 1, body2, decompiled(substTerm)) } // todo: try for more efficient implementation of underapply, O(n) vs n^2 diff --git a/runtime-jvm/main/src/main/scala/compilation.scala b/runtime-jvm/main/src/main/scala/compilation.scala index 222834bd7..5c86301a9 100644 --- a/runtime-jvm/main/src/main/scala/compilation.scala +++ b/runtime-jvm/main/src/main/scala/compilation.scala @@ -796,6 +796,9 @@ package object compilation { val needsCopy = names.length > K // inner lambda may throw SelfCall, so we create wrapper Lambda // to process those + + // note: no reason to specialize for Computation.C{2,1,0}U, as these + // won't contain a tail-recursive call, thus won't enter here val outerLambdaBody: Computation = (r,rec,top,stackU,x1,x0,stackB,x1b,x0b) => { val stackArgsCount = (innerLambda.arity - K) max 0 @@ -831,7 +834,7 @@ package object compilation { go(x1, x0, x1b, x0b) } - Lambda(names.length, outerLambdaBody, innerLambda.unboxedType, innerLambda.decompile) + Lambda(names.length, outerLambdaBody, innerLambda.decompile) } compiledLambda match { @@ -890,7 +893,7 @@ package object compilation { val shadowedRec = bodyRec.shadow(names) val cbody = compile(builtins)(body, names.reverse.toVector, shadowedRec, shadowedRec.toRecursiveVars, IsTail) - Return(Lambda(names.length, cbody, None, e)) + Return(Lambda(names.length, cbody, e)) } // 2. else { @@ -1307,9 +1310,10 @@ package object compilation { // Note: We have to make up a name here. "handler" works. Term.Lam(k.names:_*)(Term.Handle(Term.Compiled(handler))( k.decompile(k.names.map(Term.Var(_)):_*))) + // todo: worth it to specialize doIt for k.body: Computation.C{2,1,0}U? val body: Computation = (r,rec,top,stackU,x1,x0,stackB,x1b,x0b) => doIt(handler, k.body)(r,rec,top,stackU,x1,x0,stackB,x1b,x0b) - Lambda(k.arity, body, k.unboxedType, decompiled) + Lambda(k.arity, body, decompiled) } def apply(r: R, rec: Lambda, top: StackPtr, stackU: Array[U], x1: U, x0: U, diff --git a/runtime-jvm/main/src/test/scala/CompilationTests.scala b/runtime-jvm/main/src/test/scala/CompilationTests.scala index e610e06b5..221892f38 100644 --- a/runtime-jvm/main/src/test/scala/CompilationTests.scala +++ b/runtime-jvm/main/src/test/scala/CompilationTests.scala @@ -157,7 +157,7 @@ object CompilationTests { } val lam = Term.Compiled( - new ClosureForming(List("a","b","c","d"), body, Some(UnboxedType.Int64), 42)) + new ClosureForming(List("a","b","c","d"), body, 42)) val p = Let('f -> lam(1))('f.v(2,3,4)) val p2 = Let('f -> lam(1), 'g -> 'f.v(2))('g.v(3,4)) val p3 = Let('f -> lam(1), 'g -> 'f.v(2), 'h -> 'g.v(3))('h.v(4)) From 8a7ec4f50f5f1e9671733e28f7379ed50f07f227 Mon Sep 17 00:00:00 2001 From: Arya Irani Date: Sun, 10 Jun 2018 19:56:45 -0400 Subject: [PATCH 3/3] I don't think I need these here anymore for C2Us. I think the "boxed" element of the stream (the `UnboxedType`) will be read as needed, instead of relying on `Result.boxed` --- runtime-jvm/main/src/main/scala/UnisonToScala.scala | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/runtime-jvm/main/src/main/scala/UnisonToScala.scala b/runtime-jvm/main/src/main/scala/UnisonToScala.scala index 1e40db910..346b775a6 100644 --- a/runtime-jvm/main/src/main/scala/UnisonToScala.scala +++ b/runtime-jvm/main/src/main/scala/UnisonToScala.scala @@ -14,10 +14,8 @@ object UnisonToScala { require (f.arity == 1) f.body match { case body: Computation.C1U => - env => - val (stackU, stackB, top, r) = env + _env => new Unboxed.F1[Param, Value] { - // todo: can I just call body.raw(u1) here instead of body.apply? def apply[x] = kvx => (u1,a,u2,x) => kvx(body.raw(u1), body.outputType, u2, x) } case _body => @@ -39,13 +37,12 @@ object UnisonToScala { require(f.arity == 2) f.body match { case body: Computation.C2U => - env => - val (stackU, stackB, top, r) = env + _env => new Unboxed.F2[Param, Param, Value] { def apply[x] = kvx => (u1, a, u2, b, u3, x) => kvx(body.raw(u1, u2), body.outputType, u3, x) } - case body => + case _body => env => val (stackU, stackB, top, r) = env new Unboxed.F2[Param, Param, Value] {