Support int coercions on return

This commit is contained in:
Andrey Breslav
2013-10-06 14:53:13 +04:00
parent 85ac477b2f
commit e85a6fda39
3 changed files with 49 additions and 10 deletions
+17 -2
View File
@@ -1,6 +1,5 @@
package org.jetbrains.eval4j
import org.objectweb.asm.tree.LabelNode
import org.objectweb.asm.tree.AbstractInsnNode
import org.objectweb.asm.tree.analysis.Frame
import org.objectweb.asm.tree.MethodNode
@@ -95,7 +94,23 @@ fun interpreterLoop(
LOOKUPSWITCH -> UnsupportedByteCodeException("LOOKUPSWITCH is not supported yet")
TABLESWITCH -> UnsupportedByteCodeException("TABLESWITCH is not supported yet")
IRETURN, LRETURN, FRETURN, DRETURN, ARETURN -> return ValueReturned(frame.getStack(0)!!)
IRETURN, LRETURN, FRETURN, DRETURN, ARETURN -> {
val value = frame.getStack(0)!!
val expectedType = Type.getReturnType(m.desc)
if (value.asmType != expectedType) {
assert(insnOpcode == IRETURN, "Only ints should be coerced")
val coerced = when (expectedType.getSort()) {
Type.BOOLEAN -> boolean(value.boolean)
Type.BYTE -> byte(value.int.toByte())
Type.SHORT -> short(value.int.toShort())
Type.CHAR -> char(value.int.toChar())
else -> throw UnsupportedByteCodeException("Should not be coerced: $expectedType")
}
return ValueReturned(coerced)
}
return ValueReturned(value)
}
RETURN -> return ValueReturned(VOID_VALUE)
IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IFNULL, IFNONNULL -> {
if (interpreter.checkUnaryCondition(frame.getStack(0)!!, insnOpcode)) {
+1 -6
View File
@@ -69,12 +69,7 @@ fun obj<T>(v: T, t: Type = if (v != null) Type.getType(v.javaClass) else Type.ge
val NULL_VALUE = ObjectValue(null, Type.getObjectType("null"))
val Value.boolean: Boolean
get(): Boolean {
assert(this.asmType == Type.BOOLEAN_TYPE)
return (this as IntValue).value == 1
}
val Value.boolean: Boolean get() = (this as IntValue).value == 1
val Value.int: Int get() = (this as IntValue).value
val Value.long: Long get() = (this as LongValue).value
val Value.float: Float get() = (this as FloatValue).value
+31 -2
View File
@@ -1,9 +1,38 @@
package org.jetbrains.eval4j.test;
public class TestData {
public void imNotAPAckage() {}
public static void testReturnVoid() {
}
public static int testReturn() {
public static boolean testReturnBoolean() {
return true;
}
public static byte testReturnByte() {
return 2;
}
public static short testReturnShort() {
return 2;
}
public static char testReturnChar() {
return '2';
}
public static int testReturnInt() {
return 2;
}
public static long testReturnLong() {
return 2;
}
public static float testReturnFloat() {
return 2.0f;
}
public static double testReturnDouble() {
return 2.0d;
}
}