diff --git a/src/main/scala/leon/codegen/CodeGeneration.scala b/src/main/scala/leon/codegen/CodeGeneration.scala index 03b168fd2071d84e85d162365eae2e73b22431ac..df3c1c78af29d587d095a14bcbb321c9b65df9c3 100644 --- a/src/main/scala/leon/codegen/CodeGeneration.scala +++ b/src/main/scala/leon/codegen/CodeGeneration.scala @@ -81,8 +81,15 @@ trait CodeGeneration { def defToJVMName(d : Definition) : String = "Leon$CodeGen$" + idToSafeJVMName(d.id) /** Retrieve the name of the underlying lazy field from a lazy field accessor method */ - private[codegen] def underlyingField(lazyAccessor : String) = lazyAccessor + "$underlying" - + private[codegen] def underlyingField(lazyAccessor : String) = lazyAccessor + "$underlying" + + protected object ValueType { + def unapply(tp: TypeTree): Boolean = tp match { + case Int32Type | BooleanType | CharType | UnitType => true + case _ => false + } + } + /** Return the respective JVM type from a Leon type */ def typeToJVM(tpe : TypeTree) : String = tpe match { case Int32Type => "I" @@ -120,7 +127,7 @@ trait CodeGeneration { "[" + typeToJVM(base) case TypeParameter(_) => - s"L$ObjectClass;" + "L" + ObjectClass + ";" case _ => throw CompilationException("Unsupported type : " + tpe) } @@ -130,7 +137,7 @@ trait CodeGeneration { case Int32Type => s"L$BoxedIntClass;" case BooleanType | UnitType => s"L$BoxedBoolClass;" case CharType => s"L$BoxedCharClass;" - case other => typeToJVM(other) + case other => typeToJVM(other) } /** @@ -158,7 +165,8 @@ trait CodeGeneration { realParams : _* ) m.setFlags(( - if (isStatic) + // FIXME Not sure about this "FINAL" now that we can have methods in inheritable classes + if (isStatic) METHOD_ACC_PUBLIC | METHOD_ACC_FINAL | METHOD_ACC_STATIC @@ -198,14 +206,11 @@ trait CodeGeneration { mkExpr(bodyWithPost, ch)(Locals(newMapping, Map.empty, Map.empty, isStatic)) funDef.returnType match { - case Int32Type | BooleanType | UnitType => + case ValueType() => ch << IRETURN - case IntegerType | RealType | _ : ClassType | _ : TupleType | _ : SetType | _ : MapType | _ : ArrayType | _ : FunctionType | _ : TypeParameter => + case _ => ch << ARETURN - - case other => - throw CompilationException("Unsupported return type : " + other.getClass) } ch.freeze @@ -226,7 +231,7 @@ trait CodeGeneration { mkExpr(d, ch) val slot = ch.getFreshVar val instr = i.getType match { - case Int32Type | CharType | BooleanType | UnitType => IStore(slot) + case ValueType() => IStore(slot) case _ => AStore(slot) } ch << instr @@ -857,14 +862,14 @@ trait CodeGeneration { ch << Ldc(id) ch << InvokeStatic(GenericValuesClass, "get", s"(I)L$ObjectClass;") - case nt @ NoTree( tp@(Int32Type | BooleanType | UnitType | CharType)) => + case nt @ NoTree( tp@ValueType() ) => mkExpr(simplestValue(tp), ch) - case nt @ NoTree(_) => + case NoTree(_) => ch << ACONST_NULL case This(ct) => - ch << ALoad(0) // FIXME what if doInstrument etc + ch << ALoad(0) case p : Passes => mkExpr(matchToIfThenElse(p.asConstraint), ch) @@ -1011,7 +1016,7 @@ trait CodeGeneration { mkExpr(l, ch) mkExpr(r, ch) l.getType match { - case Int32Type | BooleanType | UnitType | CharType => + case ValueType() => ch << If_ICmpEq(thenn) << Goto(elze) case _ => @@ -1107,7 +1112,7 @@ trait CodeGeneration { case None => locals.varToLocal(id) match { case Some(slot) => val instr = id.getType match { - case Int32Type | CharType | BooleanType | UnitType => ILoad(slot) + case ValueType() => ILoad(slot) case _ => ALoad(slot) } ch << instr @@ -1197,13 +1202,12 @@ trait CodeGeneration { ch << Label(initLabel) // return lzy //newValue lzy.returnType match { - case Int32Type | BooleanType | UnitType | CharType => + case ValueType() => // Since the underlying field only has boxed types, we have to unbox them to return them mkUnbox(lzy.returnType, ch)(NoLocals(isStatic)) ch << IRETURN - case IntegerType | RealType | _ : ClassType | _ : TupleType | _ : SetType | _ : MapType | _ : ArrayType | _: TypeParameter => + case _ => ch << ARETURN - case other => throw CompilationException("Unsupported return type : " + other.getClass) } ch.freeze } diff --git a/src/main/scala/leon/codegen/CompilationUnit.scala b/src/main/scala/leon/codegen/CompilationUnit.scala index b7097ee5f7400a03bc8ac47fc67268ab1560b3fe..3d7fbe17d48bedf12e60ca4044587a9a8d06ca99 100644 --- a/src/main/scala/leon/codegen/CompilationUnit.scala +++ b/src/main/scala/leon/codegen/CompilationUnit.scala @@ -324,14 +324,10 @@ class CompilationUnit(val ctx: LeonContext, mkExpr(e, ch)(Locals(newMapping, Map.empty, Map.empty, isStatic = true)) e.getType match { - case Int32Type | BooleanType | UnitType => + case ValueType() => ch << IRETURN - - case IntegerType | RealType | _: TupleType | _: SetType | _: MapType | _: AbstractClassType | _: CaseClassType | _: ArrayType | _: FunctionType | _: TypeParameter => + case _ => ch << ARETURN - - case other => - throw CompilationException("Unsupported return type : " + other) } ch.freeze