diff --git a/annotations/org.ow2.asm_asm-debug-all_4.1/org/objectweb/asm/tree/analysis/annotations.xml b/annotations/org.ow2.asm_asm-debug-all_4.1/org/objectweb/asm/tree/analysis/annotations.xml
index ddcfa8e47c1..582d9bf2dc6 100644
--- a/annotations/org.ow2.asm_asm-debug-all_4.1/org/objectweb/asm/tree/analysis/annotations.xml
+++ b/annotations/org.ow2.asm_asm-debug-all_4.1/org/objectweb/asm/tree/analysis/annotations.xml
@@ -1,110 +1,23 @@
- -
+
-
+
+
+ -
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
+
-
- -
-
-
-
-
-
- -
+
-
- -
-
-
-
-
-
- -
+
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
-
-
-
- -
+
-
@@ -116,55 +29,19 @@
- -
-
-
- -
+
-
+
+
+
-
- -
-
-
-
-
-
- -
+
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
+
-
-
@@ -173,7 +50,22 @@
- -
+
-
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
@@ -182,172 +74,28 @@
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
-
- -
+
-
+
+
+ -
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
- -
+
-
@@ -359,64 +107,19 @@
- -
+
-
+
+
+ -
+
+
+ -
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
-
-
-
- -
+
-
-
@@ -425,94 +128,190 @@
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
+
-
- -
+
-
- -
+
-
+
+
+
+
+
+ -
- -
+
-
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
- -
-
-
- -
-
-
- -
-
-
- -
+
-
-
- -
-
-
-
-
-
- -
-
-
- -
+
-
-
- -
+
-
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
@@ -524,29 +323,53 @@
- -
-
-
- -
-
-
- -
+
-
- -
+
-
- -
+
-
+
+
+
- -
+
-
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
-
@@ -554,22 +377,82 @@
- -
+
-
- -
+
-
+
+
+
+
+
+ -
- -
+
-
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
-
- -
+
-
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
@@ -578,10 +461,136 @@
-
- -
+
-
- -
+
-
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
diff --git a/annotations/org.ow2.asm_asm-debug-all_4.1/org/objectweb/asm/tree/annotations.xml b/annotations/org.ow2.asm_asm-debug-all_4.1/org/objectweb/asm/tree/annotations.xml
index 30dfaa36edf..d3a32fab38f 100644
--- a/annotations/org.ow2.asm_asm-debug-all_4.1/org/objectweb/asm/tree/annotations.xml
+++ b/annotations/org.ow2.asm_asm-debug-all_4.1/org/objectweb/asm/tree/annotations.xml
@@ -1,158 +1,35 @@
+
-
+
+
+
+
+
+ -
+
+
+
+
+
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
-
- -
-
-
- -
+
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
+
-
@@ -164,142 +41,52 @@
- -
-
-
-
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
-
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
-
- -
+
-
- -
-
-
- -
+
-
- -
+
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
+
-
-
@@ -308,232 +95,334 @@
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
-
- -
-
-
- -
-
-
- -
+
-
- -
+
-
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
-
- -
+
-
- -
+
-
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
-
@@ -542,4 +431,133 @@
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
diff --git a/src/org/jetbrains/eval4j/interpreter.kt b/src/org/jetbrains/eval4j/interpreter.kt
index 5e1ad387477..4d6d873c12c 100644
--- a/src/org/jetbrains/eval4j/interpreter.kt
+++ b/src/org/jetbrains/eval4j/interpreter.kt
@@ -7,7 +7,6 @@ import org.objectweb.asm.Type
import org.objectweb.asm.tree.AbstractInsnNode
import org.objectweb.asm.tree.FieldInsnNode
import org.objectweb.asm.tree.IntInsnNode
-import org.objectweb.asm.tree.InvokeDynamicInsnNode
import org.objectweb.asm.tree.LdcInsnNode
import org.objectweb.asm.tree.MethodInsnNode
import org.objectweb.asm.tree.MultiANewArrayInsnNode
@@ -25,13 +24,18 @@ trait EvalStrategy {
fun isInsetanceOf(value: Value, targetType: Type): Boolean
fun newArray(arrayType: Type, size: Int): Value
+ fun newMultiDimensionalArray(arrayType: Type, dimensionSizes: List): Value
fun getArrayLength(array: Value): Value
+ fun getArrayElement(array: Value, index: Value): Value
+ fun setArrayElement(array: Value, index: Value, newValue: Value)
fun getStaticField(fieldDesc: String): Value
fun setStaticField(fieldDesc: String, newValue: Value)
+ fun invokeStaticMethod(methodDesc: String, arguments: List): Value
fun getField(instance: Value, fieldDesc: String): Value
fun setField(instance: Value, fieldDesc: String, newValue: Value)
+ fun invokeMethod(instance: Value, methodDesc: String, arguments: List, invokespecial: Boolean = false): Value
fun getLocalVariable(index: Int): Value
fun setLocalVariable(index: Int, newValue: Value)
@@ -165,15 +169,6 @@ class EvalInterpreter(private val evalStrategy: EvalStrategy) : Interpreter throw UnsupportedByteCodeException("Switch is not supported yet")
- IRETURN,
- LRETURN,
- FRETURN,
- DRETURN,
- ARETURN -> {
- evalStrategy.returnValue(value)
- null
- }
-
PUTSTATIC -> {
evalStrategy.setStaticField((insn as FieldInsnNode).desc, value)
null
@@ -223,62 +218,164 @@ class EvalInterpreter(private val evalStrategy: EvalStrategy) : Interpreter evalStrategy.getArrayElement(value1, value2)
+
+ IADD -> int(value1.int + value2.int)
+ ISUB -> int(value1.int - value2.int)
+ IMUL -> int(value1.int * value2.int)
+ IDIV -> int(value1.int / value2.int)
+ IREM -> int(value1.int % value2.int)
+ ISHL -> int(value1.int shl value2.int)
+ ISHR -> int(value1.int shr value2.int)
+ IUSHR -> int(value1.int ushr value2.int)
+ IAND -> int(value1.int and value2.int)
+ IOR -> int(value1.int or value2.int)
+ IXOR -> int(value1.int xor value2.int)
+
+ LADD -> long(value1.long + value2.long)
+ LSUB -> long(value1.long - value2.long)
+ LMUL -> long(value1.long * value2.long)
+ LDIV -> long(value1.long / value2.long)
+ LREM -> long(value1.long % value2.long)
+ LSHL -> long(value1.long shl value2.int)
+ LSHR -> long(value1.long shr value2.int)
+ LUSHR -> long(value1.long ushr value2.int)
+ LAND -> long(value1.long and value2.long)
+ LOR -> long(value1.long or value2.long)
+ LXOR -> long(value1.long xor value2.long)
+
+ FADD -> float(value1.float + value2.float)
+ FSUB -> float(value1.float - value2.float)
+ FMUL -> float(value1.float * value2.float)
+ FDIV -> float(value1.float / value2.float)
+ FREM -> float(value1.float % value2.float)
+
+ DADD -> double(value1.double + value2.double)
+ DSUB -> double(value1.double - value2.double)
+ DMUL -> double(value1.double * value2.double)
+ DDIV -> double(value1.double / value2.double)
+ DREM -> double(value1.double % value2.double)
+
+ LCMP -> {
+ val l1 = value1.long
+ val l2 = value2.long
+
+ int(when {
+ l1 > l2 -> 1
+ l1 == l2 -> 0
+ else -> -1
+ })
+ }
+
+ FCMPL,
+ FCMPG -> {
+ val l1 = value1.float
+ val l2 = value2.float
+
+ int(when {
+ l1 > l2 -> 1
+ l1 == l2 -> 0
+ l1 < l2 -> -1
+ // one of them is NaN
+ else -> if (insn.getOpcode() == FCMPG) 1 else -1
+ })
+ }
+
+ DCMPL,
+ DCMPG -> {
+ val l1 = value1.double
+ val l2 = value2.double
+
+ int(when {
+ l1 > l2 -> 1
+ l1 == l2 -> 0
+ l1 < l2 -> -1
+ // one of them is NaN
+ else -> if (insn.getOpcode() == DCMPG) 1 else -1
+ })
+ }
+
+ IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE -> {
+ val label = (insn as JumpInsnNode).label.getLabel()
+ when (insn.getOpcode()) {
+ IF_ICMPEQ -> if (value1.int == value2.int) evalStrategy.jump(label)
+ IF_ICMPNE -> if (value1.int != value2.int) evalStrategy.jump(label)
+ IF_ICMPLT -> if (value1.int < value2.int) evalStrategy.jump(label)
+ IF_ICMPGT -> if (value1.int > value2.int) evalStrategy.jump(label)
+ IF_ICMPLE -> if (value1.int <= value2.int) evalStrategy.jump(label)
+ IF_ICMPGE -> if (value1.int >= value2.int) evalStrategy.jump(label)
+
+ IF_ACMPEQ -> if (value1.obj == value2.obj) evalStrategy.jump(label)
+ IF_ACMPNE -> if (value1.obj != value2.obj) evalStrategy.jump(label)
+ }
+ null
+ }
+
+ PUTFIELD -> {
+ evalStrategy.setField(value1, (insn as FieldInsnNode).desc, value2)
+ null
+ }
+
+ else -> throw UnsupportedByteCodeException("$insn")
+ }
+ }
+
+ override fun ternaryOperation(insn: AbstractInsnNode, value1: Value, value2: Value, value3: Value): Value? {
+ return when (insn.getOpcode()) {
+ IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE -> {
+ evalStrategy.setArrayElement(value1, value2, value3)
+ null
+ }
+ else -> throw UnsupportedByteCodeException("$insn")
+ }
+ }
+
+ override fun naryOperation(insn: AbstractInsnNode, values: List): Value {
+ return when (insn.getOpcode()) {
+ MULTIANEWARRAY -> {
+ val node = insn as MultiANewArrayInsnNode
+ evalStrategy.newMultiDimensionalArray(Type.getType(node.desc), values.map { v -> v.int })
+ }
+
+ INVOKEVIRTUAL, INVOKESPECIAL, INVOKEINTERFACE -> {
+ val desc = (insn as MethodInsnNode).desc
+ evalStrategy.invokeMethod(
+ values[0],
+ desc,
+ values.subList(1, values.size()),
+ insn.getOpcode() == INVOKESPECIAL
+ )
+ }
+
+ INVOKESTATIC -> evalStrategy.invokeStaticMethod((insn as MethodInsnNode).desc, values)
+
+ INVOKEDYNAMIC -> throw UnsupportedByteCodeException("INVOKEDYNAMIC is not supported")
+ else -> throw UnsupportedByteCodeException("$insn")
+ }
+ }
+
+
+ override fun returnOperation(insn: AbstractInsnNode, value: Value, expected: Value) {
when (insn.getOpcode()) {
- IALOAD, BALOAD, CALOAD, SALOAD, IADD, ISUB, IMUL, IDIV, IREM, ISHL, ISHR, IUSHR, IAND, IOR, IXOR -> {
- return Value.INT_VALUE
- }
- FALOAD, FADD, FSUB, FMUL, FDIV, FREM -> {
- return Value.FLOAT_VALUE
- }
- LALOAD, LADD, LSUB, LMUL, LDIV, LREM, LSHL, LSHR, LUSHR, LAND, LOR, LXOR -> {
- return Value.LONG_VALUE
- }
- DALOAD, DADD, DSUB, DMUL, DDIV, DREM -> {
- return Value.DOUBLE_VALUE
- }
- AALOAD -> {
- return Value.REFERENCE_VALUE
- }
- LCMP, FCMPL, FCMPG, DCMPL, DCMPG -> {
- return Value.INT_VALUE
- }
- IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, PUTFIELD -> {
- return null
- }
- else -> {
- throw Error("Internal error.")
+ IRETURN,
+ LRETURN,
+ FRETURN,
+ DRETURN,
+ ARETURN -> {
+ // TODO: coercion, maybe?
+ evalStrategy.returnValue(value)
}
+
+ else -> throw UnsupportedByteCodeException("$insn")
}
}
- override fun ternaryOperation(insn: AbstractInsnNode, value1: Value, value2: Value?, value3: Value): Value? {
- return null
- }
-
- override fun naryOperation(insn: AbstractInsnNode, values: List): Value {
- val opcode = insn.getOpcode()!!
- if (opcode == MULTIANEWARRAY) {
- return newValue(Type.getType(((insn as MultiANewArrayInsnNode)).desc))
- }
- else if (opcode == INVOKEDYNAMIC) {
- return newValue(Type.getReturnType(((insn as InvokeDynamicInsnNode)).desc))
- }
- else {
- return newValue(Type.getReturnType(((insn as MethodInsnNode)).desc))
- }
- }
-
-
- override fun returnOperation(insn: AbstractInsnNode?, value: Value, expected: Value?) {
-
- }
-
override fun merge(v: Value, w: Value): Value {
- if (!v.equals(w)) {
- return Value.UNINITIALIZED_VALUE
- }
-
- return v
+ // We always remember the NEW value
+ return w
}
}