diff --git a/eval4j/src/org/jetbrains/eval4j/interpreterLoop.kt b/eval4j/src/org/jetbrains/eval4j/interpreterLoop.kt index c0e22938051..1f63176ab82 100644 --- a/eval4j/src/org/jetbrains/eval4j/interpreterLoop.kt +++ b/eval4j/src/org/jetbrains/eval4j/interpreterLoop.kt @@ -163,7 +163,7 @@ fun interpreterLoop( TABLESWITCH -> UnsupportedByteCodeException("TABLESWITCH is not supported yet") IRETURN, LRETURN, FRETURN, DRETURN, ARETURN -> { - val value = frame.getStack(0)!! + val value = frame.getStackTop() val expectedType = Type.getReturnType(m.desc) if (expectedType.getSort() == Type.OBJECT) { val coerced = if (value != NULL_VALUE && value.asmType != expectedType) @@ -187,14 +187,14 @@ fun interpreterLoop( } RETURN -> return ValueReturned(VOID_VALUE) IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IFNULL, IFNONNULL -> { - if (interpreter.checkUnaryCondition(frame.getStack(0)!!, insnOpcode)) { + if (interpreter.checkUnaryCondition(frame.getStackTop(), insnOpcode)) { frame.execute(currentInsn, interpreter) goto((currentInsn as JumpInsnNode).label) continue } } IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE -> { - if (interpreter.checkBinaryCondition(frame.getStack(0)!!, frame.getStack(1)!!, insnOpcode)) { + if (interpreter.checkBinaryCondition(frame.getStackTop(1), frame.getStackTop(0), insnOpcode)) { frame.execute(currentInsn, interpreter) goto((currentInsn as JumpInsnNode).label) continue @@ -202,7 +202,7 @@ fun interpreterLoop( } ATHROW -> { - val exceptionValue = frame.getStack(0)!! + val exceptionValue = frame.getStackTop() val handled = handler.exceptionThrown(frame, currentInsn, exceptionValue) if (handled != null) return handled if (exceptionCaught(exceptionValue)) continue @@ -245,6 +245,8 @@ fun interpreterLoop( } } +private fun Frame.getStackTop(i: Int = 0) = this.getStack(this.getStackSize() - 1 - i) ?: throwEvalException(IllegalArgumentException("Couldn't get value with index = $i from top of stack")) + // Copied from org.jetbrains.org.objectweb.asm.tree.analysis.Analyzer.analyze() fun computeHandlers(m: MethodNode): Array?> { val insns = m.instructions diff --git a/eval4j/test/org/jetbrains/eval4j/test/TestData.java b/eval4j/test/org/jetbrains/eval4j/test/TestData.java index 9b1bfeb0902..4efccd6967f 100644 --- a/eval4j/test/org/jetbrains/eval4j/test/TestData.java +++ b/eval4j/test/org/jetbrains/eval4j/test/TestData.java @@ -681,6 +681,16 @@ class TestData { Number n = 1; return n.intValue(); } + + static void getValueFromStack() { + int i = 1; + boolean b = true; + Integer[] IFEQ = new Integer[] { b ? 100 : 200 }; + Integer[] IF_ICMPNE = new Integer[] { i == 1 ? 100 : 200 }; + + long l = 1; + Long[] IFEQ_L = new Long[] { b ? 100L : 200L }; + } }