Skip to content
This repository was archived by the owner on Feb 23, 2018. It is now read-only.

Commit 89d9972

Browse files
committed
Merge pull request #6 from lrytz/newValue
[asm-cherry-pick] Multiple methods for initializing analysis values
2 parents faf6799 + 8133d75 commit 89d9972

File tree

3 files changed

+64
-9
lines changed

3 files changed

+64
-9
lines changed

src/main/java/scala/tools/asm/tree/analysis/Analyzer.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -158,21 +158,26 @@ public Frame<V>[] analyze(final String owner, final MethodNode m)
158158
// initializes the data structures for the control flow analysis
159159
Frame<V> current = newFrame(m.maxLocals, m.maxStack);
160160
Frame<V> handler = newFrame(m.maxLocals, m.maxStack);
161-
current.setReturn(interpreter.newValue(Type.getReturnType(m.desc)));
161+
current.setReturn(interpreter.newReturnTypeValue(Type.getReturnType(m.desc)));
162162
Type[] args = Type.getArgumentTypes(m.desc);
163163
int local = 0;
164-
if ((m.access & ACC_STATIC) == 0) {
164+
boolean isInstanceMethod = (m.access & ACC_STATIC) == 0;
165+
if (isInstanceMethod) {
165166
Type ctype = Type.getObjectType(owner);
166-
current.setLocal(local++, interpreter.newValue(ctype));
167+
current.setLocal(local, interpreter.newParameterValue(isInstanceMethod, local, ctype));
168+
local++;
167169
}
168170
for (int i = 0; i < args.length; ++i) {
169-
current.setLocal(local++, interpreter.newValue(args[i]));
171+
current.setLocal(local, interpreter.newParameterValue(isInstanceMethod, local, args[i]));
172+
local++;
170173
if (args[i].getSize() == 2) {
171-
current.setLocal(local++, interpreter.newValue(null));
174+
current.setLocal(local, interpreter.newEmptyValueAfterSize2Local(local));
175+
local++;
172176
}
173177
}
174178
while (local < m.maxLocals) {
175-
current.setLocal(local++, interpreter.newValue(null));
179+
current.setLocal(local, interpreter.newEmptyNonParameterLocalValue(local));
180+
local++;
176181
}
177182
merge(0, current, null);
178183

@@ -285,7 +290,7 @@ public Frame<V>[] analyze(final String owner, final MethodNode m)
285290
if (newControlFlowExceptionEdge(insn, tcb)) {
286291
handler.init(f);
287292
handler.clearStack();
288-
handler.push(interpreter.newValue(type));
293+
handler.push(interpreter.newExceptionValue(tcb, handler, type));
289294
merge(jump, handler, subroutine);
290295
}
291296
}

src/main/java/scala/tools/asm/tree/analysis/Frame.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,12 +312,12 @@ public void execute(final AbstractInsnNode insn,
312312
var = ((VarInsnNode) insn).var;
313313
setLocal(var, value1);
314314
if (value1.getSize() == 2) {
315-
setLocal(var + 1, interpreter.newValue(null));
315+
setLocal(var + 1, interpreter.newEmptyValueAfterSize2Local(var + 1));
316316
}
317317
if (var > 0) {
318318
Value local = getLocal(var - 1);
319319
if (local != null && local.getSize() == 2) {
320-
setLocal(var - 1, interpreter.newValue(null));
320+
setLocal(var - 1, interpreter.newEmptyValueForPreviousSize2Local(var - 1));
321321
}
322322
}
323323
break;

src/main/java/scala/tools/asm/tree/analysis/Interpreter.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
import scala.tools.asm.Type;
3535
import scala.tools.asm.tree.AbstractInsnNode;
36+
import scala.tools.asm.tree.TryCatchBlockNode;
3637

3738
/**
3839
* A semantic bytecode interpreter. More precisely, this interpreter only
@@ -70,6 +71,55 @@ protected Interpreter(final int api) {
7071
*/
7172
public abstract V newValue(Type type);
7273

74+
/**
75+
* Called by the analyzer for initializing the return type value of a frame.
76+
*/
77+
public V newReturnTypeValue(Type type) {
78+
return newValue(type);
79+
}
80+
81+
/**
82+
* Called by the analyzer when initializing the value of a parameter in a frame.
83+
*/
84+
public V newParameterValue(boolean isInstanceMethod, int local, Type type) {
85+
return newValue(type);
86+
}
87+
88+
/**
89+
* Called by the analyzer when initializing a non-parameter local in a frame.
90+
* This method has to return a size-1 value representing an empty slot.
91+
*/
92+
public V newEmptyNonParameterLocalValue(int local) {
93+
return newValue(null);
94+
}
95+
96+
/**
97+
* Called by the analyzer and the interpreter. When initializing or setting the value of a
98+
* size-2 local, the value of the subsequent slot is reset using this method.
99+
* This method has to return a size-1 value representing an empty slot.
100+
*/
101+
public V newEmptyValueAfterSize2Local(int local) {
102+
return newValue(null);
103+
}
104+
105+
/**
106+
* Called by the interpreter. When setting the value of a local variable, the interpreter checks
107+
* whether the current value stored at the preceding index is of size-2. In this case, the
108+
* preceding size-2 value is no longer valid and reset using this method.
109+
* This method has to return a size-1 value representing an empty slot.
110+
*/
111+
public V newEmptyValueForPreviousSize2Local(int local) {
112+
return newValue(null);
113+
}
114+
115+
/**
116+
* Called by the analyzer when initializing the exception value on the call stack at the entry
117+
* of an exception handler.
118+
*/
119+
public V newExceptionValue(TryCatchBlockNode tryCatchBlockNode, Frame handlerFrame, Type exceptionType) {
120+
return newValue(exceptionType);
121+
}
122+
73123
/**
74124
* Interprets a bytecode instruction without arguments. This method is
75125
* called for the following opcodes:

0 commit comments

Comments
 (0)