Commit 15b1be2e authored by Eric Bruneton's avatar Eric Bruneton

Merge branch 'retronymm/asm-unfork/new-value'

parents 0b66c85a cd93d4c9
......@@ -274,7 +274,7 @@ public class Analyzer<V extends Value> implements Opcodes {
if (newControlFlowExceptionEdge(insnIndex, tryCatchBlock)) {
Frame<V> handler = newFrame(oldFrame);
handler.clearStack();
handler.push(interpreter.newValue(catchType));
handler.push(interpreter.newExceptionValue(tryCatchBlock, handler, catchType));
merge(insnList.indexOf(tryCatchBlock.handler), handler, subroutine);
}
}
......@@ -381,21 +381,29 @@ public class Analyzer<V extends Value> implements Opcodes {
private Frame<V> computeInitialFrame(final String owner, final MethodNode method) {
Frame<V> frame = newFrame(method.maxLocals, method.maxStack);
int currentLocal = 0;
if ((method.access & ACC_STATIC) == 0) {
boolean isInstanceMethod = (method.access & ACC_STATIC) == 0;
if (isInstanceMethod) {
Type ownerType = Type.getObjectType(owner);
frame.setLocal(currentLocal++, interpreter.newValue(ownerType));
frame.setLocal(
currentLocal, interpreter.newParameterValue(isInstanceMethod, currentLocal, ownerType));
currentLocal++;
}
Type[] argumentTypes = Type.getArgumentTypes(method.desc);
for (int i = 0; i < argumentTypes.length; ++i) {
frame.setLocal(currentLocal++, interpreter.newValue(argumentTypes[i]));
frame.setLocal(
currentLocal,
interpreter.newParameterValue(isInstanceMethod, currentLocal, argumentTypes[i]));
currentLocal++;
if (argumentTypes[i].getSize() == 2) {
frame.setLocal(currentLocal++, interpreter.newValue(null));
frame.setLocal(currentLocal, interpreter.newEmptyValue(currentLocal));
currentLocal++;
}
}
while (currentLocal < method.maxLocals) {
frame.setLocal(currentLocal++, interpreter.newValue(null));
frame.setLocal(currentLocal, interpreter.newEmptyValue(currentLocal));
currentLocal++;
}
frame.setReturn(interpreter.newValue(Type.getReturnType(method.desc)));
frame.setReturn(interpreter.newReturnTypeValue(Type.getReturnType(method.desc)));
return frame;
}
......
......@@ -275,12 +275,12 @@ public class Frame<V extends Value> {
var = ((VarInsnNode) insn).var;
setLocal(var, value1);
if (value1.getSize() == 2) {
setLocal(var + 1, interpreter.newValue(null));
setLocal(var + 1, interpreter.newEmptyValue(var + 1));
}
if (var > 0) {
Value local = getLocal(var - 1);
if (local != null && local.getSize() == 2) {
setLocal(var - 1, interpreter.newValue(null));
setLocal(var - 1, interpreter.newEmptyValue(var - 1));
}
}
break;
......
......@@ -30,6 +30,7 @@ package org.objectweb.asm.tree.analysis;
import java.util.List;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
/**
* A semantic bytecode interpreter. More precisely, this interpreter only manages the computation of
......@@ -67,6 +68,12 @@ public abstract class Interpreter<V extends Value> {
* <p>Called for method parameters (including <code>this</code>), exception handler variable and
* with <code>null</code> type for variables reserved by long and double types.
*
* <p>An interpreter may choose to implement one or more of {@link
* Interpreter#newReturnTypeValue(Type)}, {@link Interpreter#newParameterValue(boolean, int,
* Type)}, {@link Interpreter#newEmptyValue(int)}, {@link
* Interpreter#newExceptionValue(TryCatchBlockNode, Frame, Type)} to distinguish different types
* of new value.
*
* @param type a primitive or reference type, or <tt>null</tt> to represent an uninitialized
* value.
* @return a value that represents the given type. The size of the returned value must be equal to
......@@ -74,6 +81,70 @@ public abstract class Interpreter<V extends Value> {
*/
public abstract V newValue(Type type);
/**
* Creates a new value that represents the given parameter type. This method is called to
* initialize the value of a local corresponding to a method parameter in a frame.
*
* <p>By default, calls <code>newValue(type)</code>.
*
* @param isInstanceMethod <tt>true</tt> if the method is non-static.
* @param local the local variable index.
* @param type a primitive or reference type.
* @return a value that represents the given type. The size of the returned value must be equal to
* the size of the given type.
*/
public V newParameterValue(final boolean isInstanceMethod, final int local, final Type type) {
return newValue(type);
}
/**
* Creates a new value that represents the given return type. This method is called to initialize
* the return type value of a frame.
*
* <p>By default, calls <code>newValue(type)</code>.
*
* @param type a primitive or reference type.
* @return a value that represents the given type. The size of the returned value must be equal to
* the size of the given type.
*/
public V newReturnTypeValue(final Type type) {
return newValue(type);
}
/**
* Creates a new uninitialized value for a local variable. This method is called to initialize the
* value of a local that does not correspond to a method parameter, and to reset one half of a
* size-2 value when the other half is assigned a size-1 value.
*
* <p>By default, calls <code>newValue(null)</code>.
*
* @param local the local variable index.
* @return a value representing an uninitialized value. The size of the returned value must be
* equal to 1.
*/
public V newEmptyValue(final int local) {
return newValue(null);
}
/**
* Creates a new value that represents the given exception type. This method is called to
* initialize the exception value on the call stack at the entry of an exception handler.
*
* <p>By default, calls <code>newValue(exceptionType)</code>.
*
* @param tryCatchBlockNode the exception handler.
* @param handlerFrame the exception handler frame.
* @param exceptionType the exception type handled by this handler.
* @return a value that represents the given <tt>exceptionType</tt>. The size of the returned
* value must be equal to 1.
*/
public V newExceptionValue(
final TryCatchBlockNode tryCatchBlockNode,
final Frame<V> handlerFrame,
final Type exceptionType) {
return newValue(exceptionType);
}
/**
* Interprets a bytecode instruction without arguments. This method is called for the following
* opcodes:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment