From e85a6fda3934e4382f07abc0e3dc953137e475d1 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 6 Oct 2013 14:53:13 +0400 Subject: [PATCH] Support int coercions on return --- src/org/jetbrains/eval4j/interpreterLoop.kt | 19 +++++++++-- src/org/jetbrains/eval4j/values.kt | 7 +---- test/org/jetbrains/eval4j/test/TestData.java | 33 ++++++++++++++++++-- 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/org/jetbrains/eval4j/interpreterLoop.kt b/src/org/jetbrains/eval4j/interpreterLoop.kt index 62c4ca22891..7761a345c4e 100644 --- a/src/org/jetbrains/eval4j/interpreterLoop.kt +++ b/src/org/jetbrains/eval4j/interpreterLoop.kt @@ -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)) { diff --git a/src/org/jetbrains/eval4j/values.kt b/src/org/jetbrains/eval4j/values.kt index dec8e19ade2..d4235c3273c 100644 --- a/src/org/jetbrains/eval4j/values.kt +++ b/src/org/jetbrains/eval4j/values.kt @@ -69,12 +69,7 @@ fun obj(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 diff --git a/test/org/jetbrains/eval4j/test/TestData.java b/test/org/jetbrains/eval4j/test/TestData.java index 66593712f11..0686b915ddd 100644 --- a/test/org/jetbrains/eval4j/test/TestData.java +++ b/test/org/jetbrains/eval4j/test/TestData.java @@ -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; + } }