Eval4j: get value from top of stack, not after local variables

This commit is contained in:
Natalia Ukhorskaya
2014-05-08 14:33:34 +04:00
parent 3fce2b8f22
commit d4211c355e
2 changed files with 16 additions and 4 deletions
@@ -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 <T: Value> Frame<T>.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<out List<TryCatchBlockNode>?> {
val insns = m.instructions
@@ -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 };
}
}