Skip to content
Snippets Groups Projects
Commit 984286c4 authored by Philippe Suter's avatar Philippe Suter
Browse files

Steps towards boxed/unboxed values in CodeGen.

parent 25621685
No related branches found
No related tags found
No related merge requests found
......@@ -6,6 +6,9 @@ public final class Tuple {
private int arity;
private Object[] elements;
// You may think that using varargs here would show less of the internals,
// however the bytecode to generate is exactly the same, so let's reflect
// the reality instead.
public Tuple(int arity, Object[] elements) {
this.arity = arity;
this.elements = Arrays.copyOf(elements, elements.length);
......
......@@ -10,9 +10,13 @@ import cafebabe._
import cafebabe.AbstractByteCodes._
import cafebabe.ByteCodes._
import cafebabe.ClassFileTypes._
import cafebabe.Defaults.constructorName
import cafebabe.Flags._
object CodeGeneration {
private val BoxedIntClass = "java/lang/Integer"
private val BoxedBoolClass = "java/lang/Boolean"
def defToJVMName(p : Program, d : Definition) : String = "Leon$CodeGen$" + d.id.uniqueName
def typeToJVM(tpe : TypeTree)(implicit env : CompilationEnvironment) : String = tpe match {
......@@ -82,7 +86,7 @@ object CodeGeneration {
for(a <- as) {
mkExpr(a, ch)
}
ch << InvokeSpecial(ccName, "<init>", consSig)
ch << InvokeSpecial(ccName, constructorName, consSig)
case CaseClassInstanceOf(ccd, e) =>
val ccName = env.classDefToClass(ccd).getOrElse {
......@@ -151,6 +155,58 @@ object CodeGeneration {
}
}
// Leaves on the stack a value equal to `e`, always of a type compatible with java.lang.Object.
private[codegen] def mkBoxedExpr(e : Expr, ch : CodeHandler)(implicit env : CompilationEnvironment) {
e.getType match {
case Int32Type =>
ch << New(BoxedIntClass) << DUP
mkExpr(e, ch)
ch << InvokeSpecial(BoxedIntClass, constructorName, "(I)V")
case BooleanType =>
ch << New(BoxedBoolClass) << DUP
mkExpr(e, ch)
ch << InvokeSpecial(BoxedBoolClass, constructorName, "(Z)V")
case _ =>
mkExpr(e, ch)
}
}
// Assumes the top of the stack contains of value of the right type, and makes it
// compatible with java.lang.Object.
private[codegen] def mkBox(tpe : TypeTree, ch : CodeHandler)(implicit env : CompilationEnvironment) {
tpe match {
case Int32Type =>
ch << New(BoxedIntClass) << DUP_X1 << SWAP << InvokeSpecial(BoxedIntClass, constructorName, "(I)V")
case BooleanType =>
ch << New(BoxedBoolClass) << DUP_X1 << SWAP << InvokeSpecial(BoxedBoolClass, constructorName, "(Z)V")
case _ =>
}
}
// Assumes that the top of the stack contains a value that should be of type `tpe`, and unboxes it to the right (JVM) type.
private[codegen] def mkUnbox(tpe : TypeTree, ch : CodeHandler)(implicit env : CompilationEnvironment) {
tpe match {
case Int32Type =>
ch << CheckCast(BoxedIntClass) << InvokeVirtual(BoxedIntClass, "intValue", "()I")
case BooleanType =>
ch << CheckCast(BoxedBoolClass) << InvokeVirtual(BoxedBoolClass, "booleanValue", "()Z")
case ct : ClassType =>
val cn = env.classDefToClass(ct.classDef).getOrElse {
throw new CompilationException("Unsupported class type : " + ct)
}
ch << CheckCast(cn)
case _ =>
throw new CompilationException("Unsupported type in unboxing : " + tpe)
}
}
private[codegen] def mkBranch(cond : Expr, then : String, elze : String, ch : CodeHandler)(implicit env : CompilationEnvironment) {
cond match {
case BooleanLiteral(true) =>
......@@ -266,7 +322,7 @@ object CodeGeneration {
val cch = cf.addConstructor(namesTypes.map(_._2).toList).codeHandler
cch << ALoad(0) << InvokeSpecial(pName, cafebabe.Defaults.constructorName, "()V")
cch << ALoad(0) << InvokeSpecial(pName, constructorName, "()V")
var c = 1
for((nme, jvmt) <- namesTypes) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment