Interpreter is not needed to create uninitialized values
This commit is contained in:
@@ -43,10 +43,7 @@ class SingleInstructionInterpreter(private val eval: Eval) : Interpreter<Value>(
|
|||||||
return NOT_A_VALUE
|
return NOT_A_VALUE
|
||||||
}
|
}
|
||||||
|
|
||||||
return when (`type`.getSort()) {
|
return makeNotInitializedValue(`type`)
|
||||||
Type.VOID -> null
|
|
||||||
else -> NotInitialized(`type`)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun newOperation(insn: AbstractInsnNode): Value? {
|
override fun newOperation(insn: AbstractInsnNode): Value? {
|
||||||
|
|||||||
@@ -25,6 +25,13 @@ object VOID_VALUE: Value {
|
|||||||
override fun toString() = "VOID_VALUE"
|
override fun toString() = "VOID_VALUE"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun makeNotInitializedValue(t: Type): Value? {
|
||||||
|
return when (t.getSort()) {
|
||||||
|
Type.VOID -> null
|
||||||
|
else -> NotInitialized(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class NotInitialized(override val asmType: Type): Value {
|
class NotInitialized(override val asmType: Type): Value {
|
||||||
override val valid = false
|
override val valid = false
|
||||||
override fun toString() = "NotInitialized: $asmType"
|
override fun toString() = "NotInitialized: $asmType"
|
||||||
|
|||||||
@@ -77,8 +77,7 @@ fun doTest(ownerClass: Class<TestData>, methodNode: MethodNode): TestCase? {
|
|||||||
methodNode,
|
methodNode,
|
||||||
initFrame(
|
initFrame(
|
||||||
ownerClass.getInternalName(),
|
ownerClass.getInternalName(),
|
||||||
methodNode,
|
methodNode
|
||||||
SingleInstructionInterpreter(REFLECTION_EVAL)
|
|
||||||
),
|
),
|
||||||
REFLECTION_EVAL
|
REFLECTION_EVAL
|
||||||
)
|
)
|
||||||
@@ -88,30 +87,29 @@ fun doTest(ownerClass: Class<TestData>, methodNode: MethodNode): TestCase? {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <V : org.objectweb.asm.tree.analysis.Value> initFrame(
|
fun initFrame(
|
||||||
owner: String,
|
owner: String,
|
||||||
m: MethodNode,
|
m: MethodNode
|
||||||
interpreter: Interpreter<V>
|
): Frame<Value> {
|
||||||
): Frame<V> {
|
val current = Frame<Value>(m.maxLocals, m.maxStack)
|
||||||
val current = Frame<V>(m.maxLocals, m.maxStack)
|
current.setReturn(makeNotInitializedValue(Type.getReturnType(m.desc)))
|
||||||
current.setReturn(interpreter.newValue(Type.getReturnType(m.desc)))
|
|
||||||
|
|
||||||
var local = 0
|
var local = 0
|
||||||
if ((m.access and ACC_STATIC) == 0) {
|
if ((m.access and ACC_STATIC) == 0) {
|
||||||
val ctype = Type.getObjectType(owner)
|
val ctype = Type.getObjectType(owner)
|
||||||
current.setLocal(local++, interpreter.newValue(ctype))
|
current.setLocal(local++, makeNotInitializedValue(ctype))
|
||||||
}
|
}
|
||||||
|
|
||||||
val args = Type.getArgumentTypes(m.desc)
|
val args = Type.getArgumentTypes(m.desc)
|
||||||
for (i in 0..args.size - 1) {
|
for (i in 0..args.size - 1) {
|
||||||
current.setLocal(local++, interpreter.newValue(args[i]))
|
current.setLocal(local++, makeNotInitializedValue(args[i]))
|
||||||
if (args[i].getSize() == 2) {
|
if (args[i].getSize() == 2) {
|
||||||
current.setLocal(local++, interpreter.newValue(null))
|
current.setLocal(local++, NOT_A_VALUE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (local < m.maxLocals) {
|
while (local < m.maxLocals) {
|
||||||
current.setLocal(local++, interpreter.newValue(null))
|
current.setLocal(local++, NOT_A_VALUE)
|
||||||
}
|
}
|
||||||
|
|
||||||
return current
|
return current
|
||||||
|
|||||||
Reference in New Issue
Block a user