From f93d209b8811f14f545348d4ddf3863a7cdc30ac Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 6 Oct 2013 13:22:16 +0400 Subject: [PATCH] Control logic will be handled by interpreter loop --- src/org/jetbrains/eval4j/interpreter.kt | 67 +++++++++++++------------ 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/src/org/jetbrains/eval4j/interpreter.kt b/src/org/jetbrains/eval4j/interpreter.kt index 122a627dd7e..05ebb8e6100 100644 --- a/src/org/jetbrains/eval4j/interpreter.kt +++ b/src/org/jetbrains/eval4j/interpreter.kt @@ -38,14 +38,7 @@ trait Eval { fun invokeMethod(instance: Value, methodDesc: String, arguments: List, invokespecial: Boolean = false): Value } -trait Control { - fun jump(label: LabelNode) - - fun returnValue(value: Value) - fun throwException(value: Value) -} - -class SingleInstructionInterpreter(private val eval: Eval, private val control: Control) : Interpreter(ASM4) { +class SingleInstructionInterpreter(private val eval: Eval) : Interpreter(ASM4) { override fun newValue(`type`: Type?): Value? { if (`type` == null) { return NOT_A_VALUE @@ -141,17 +134,7 @@ class SingleInstructionInterpreter(private val eval: Eval, private val control: F2D -> double(value.float.toDouble()) IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IFNULL, IFNONNULL -> { - val label = (insn as JumpInsnNode).label - when (insn.getOpcode()) { - IFEQ -> if (value.int == 0) control.jump(label) - IFNE -> if (value.int != 0) control.jump(label) - IFLT -> if (value.int < 0) control.jump(label) - IFGT -> if (value.int > 0) control.jump(label) - IFLE -> if (value.int <= 0) control.jump(label) - IFGE -> if (value.int >= 0) control.jump(label) - IFNULL -> if (value.obj == null) control.jump(label) - IFNONNULL -> if (value.obj != null) control.jump(label) - } + // Handled by interpreter loop, see checkUnaryCondition() null } @@ -187,7 +170,7 @@ class SingleInstructionInterpreter(private val eval: Eval, private val control: ARRAYLENGTH -> eval.getArrayLength(value) ATHROW -> { - control.throwException(value) + // Handled by interpreter loop null } @@ -208,6 +191,20 @@ class SingleInstructionInterpreter(private val eval: Eval, private val control: } } + public fun checkUnaryCondition(value: Value, opcode: Int): Boolean { + return when (opcode) { + IFEQ -> value.int == 0 + IFNE -> value.int != 0 + IFLT -> value.int < 0 + IFGT -> value.int > 0 + IFLE -> value.int <= 0 + IFGE -> value.int >= 0 + IFNULL -> value.obj == null + IFNONNULL -> value.obj != null + else -> throw UnsupportedByteCodeException("Unknown opcode: $opcode") + } + } + override fun binaryOperation(insn: AbstractInsnNode, value1: Value, value2: Value): Value? { return when (insn.getOpcode()) { IALOAD, BALOAD, CALOAD, SALOAD, @@ -290,18 +287,7 @@ class SingleInstructionInterpreter(private val eval: Eval, private val control: } IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE -> { - val label = (insn as JumpInsnNode).label - when (insn.getOpcode()) { - IF_ICMPEQ -> if (value1.int == value2.int) control.jump(label) - IF_ICMPNE -> if (value1.int != value2.int) control.jump(label) - IF_ICMPLT -> if (value1.int < value2.int) control.jump(label) - IF_ICMPGT -> if (value1.int > value2.int) control.jump(label) - IF_ICMPLE -> if (value1.int <= value2.int) control.jump(label) - IF_ICMPGE -> if (value1.int >= value2.int) control.jump(label) - - IF_ACMPEQ -> if (value1.obj == value2.obj) control.jump(label) - IF_ACMPNE -> if (value1.obj != value2.obj) control.jump(label) - } + // Handled by interpreter loop, see checkBinaryCondition() null } @@ -314,6 +300,21 @@ class SingleInstructionInterpreter(private val eval: Eval, private val control: } } + public fun checkBinaryCondition(value1: Value, value2: Value, opcode: Int): Boolean { + return when (opcode) { + IF_ICMPEQ -> value1.int == value2.int + IF_ICMPNE -> value1.int != value2.int + IF_ICMPLT -> value1.int < value2.int + IF_ICMPGT -> value1.int > value2.int + IF_ICMPLE -> value1.int <= value2.int + IF_ICMPGE -> value1.int >= value2.int + + IF_ACMPEQ -> value1.obj == value2.obj + IF_ACMPNE -> value1.obj != value2.obj + else -> throw UnsupportedByteCodeException("Unknown opcode: $opcode") + } + } + override fun ternaryOperation(insn: AbstractInsnNode, value1: Value, value2: Value, value3: Value): Value? { return when (insn.getOpcode()) { IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE -> { @@ -357,7 +358,7 @@ class SingleInstructionInterpreter(private val eval: Eval, private val control: DRETURN, ARETURN -> { // TODO: coercion, maybe? - control.returnValue(value) + // Handled by interpreter loop } else -> throw UnsupportedByteCodeException("$insn")