下面列出了怎么用org.objectweb.asm.tree.LocalVariableNode的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Creates the new instructions, inlining each instantiation of each subroutine until the code is
* fully elaborated.
*/
private void emitCode() {
LinkedList<Instantiation> worklist = new LinkedList<>();
// Create an instantiation of the main "subroutine", which is just the main routine.
worklist.add(new Instantiation(null, mainSubroutineInsns));
// Emit instantiations of each subroutine we encounter, including the main subroutine.
InsnList newInstructions = new InsnList();
List<TryCatchBlockNode> newTryCatchBlocks = new ArrayList<>();
List<LocalVariableNode> newLocalVariables = new ArrayList<>();
while (!worklist.isEmpty()) {
Instantiation instantiation = worklist.removeFirst();
emitInstantiation(
instantiation, worklist, newInstructions, newTryCatchBlocks, newLocalVariables);
}
instructions = newInstructions;
tryCatchBlocks = newTryCatchBlocks;
localVariables = newLocalVariables;
}
/**
* Creates the new instructions, inlining each instantiation of each subroutine until the code is
* fully elaborated.
*/
private void emitCode() {
LinkedList<Instantiation> worklist = new LinkedList<Instantiation>();
// Create an instantiation of the main "subroutine", which is just the main routine.
worklist.add(new Instantiation(null, mainSubroutineInsns));
// Emit instantiations of each subroutine we encounter, including the main subroutine.
InsnList newInstructions = new InsnList();
List<TryCatchBlockNode> newTryCatchBlocks = new ArrayList<TryCatchBlockNode>();
List<LocalVariableNode> newLocalVariables = new ArrayList<LocalVariableNode>();
while (!worklist.isEmpty()) {
Instantiation instantiation = worklist.removeFirst();
emitInstantiation(
instantiation, worklist, newInstructions, newTryCatchBlocks, newLocalVariables);
}
instructions = newInstructions;
tryCatchBlocks = newTryCatchBlocks;
localVariables = newLocalVariables;
}
private Local getLocal(int idx) {
if (idx >= maxLocals)
throw new IllegalArgumentException("Invalid local index: " + idx);
Integer i = idx;
Local l = locals.get(i);
if (l == null) {
String name;
if (localVars != null) {
name = null;
for (LocalVariableNode lvn : localVars) {
if (lvn.index == idx) {
name = lvn.name;
break;
}
}
/* normally for try-catch blocks */
if (name == null)
name = "l" + idx;
} else {
name = "l" + idx;
}
l = Jimple.v().newLocal(name, UnknownType.v());
locals.put(i, l);
}
return l;
}
/**
* Creates the new instructions, inlining each instantiation of each subroutine until the code is
* fully elaborated.
*/
private void emitCode() {
LinkedList<Instantiation> worklist = new LinkedList<Instantiation>();
// Create an instantiation of the main "subroutine", which is just the main routine.
worklist.add(new Instantiation(null, mainSubroutineInsns));
// Emit instantiations of each subroutine we encounter, including the main subroutine.
InsnList newInstructions = new InsnList();
List<TryCatchBlockNode> newTryCatchBlocks = new ArrayList<TryCatchBlockNode>();
List<LocalVariableNode> newLocalVariables = new ArrayList<LocalVariableNode>();
while (!worklist.isEmpty()) {
Instantiation instantiation = worklist.removeFirst();
emitInstantiation(
instantiation, worklist, newInstructions, newTryCatchBlocks, newLocalVariables);
}
instructions = newInstructions;
tryCatchBlocks = newTryCatchBlocks;
localVariables = newLocalVariables;
}
/**
* Creates the new instructions, inlining each instantiation of each subroutine until the code is
* fully elaborated.
*/
private void emitCode() {
LinkedList<Instantiation> worklist = new LinkedList<Instantiation>();
// Create an instantiation of the main "subroutine", which is just the main routine.
worklist.add(new Instantiation(null, mainSubroutineInsns));
// Emit instantiations of each subroutine we encounter, including the main subroutine.
InsnList newInstructions = new InsnList();
List<TryCatchBlockNode> newTryCatchBlocks = new ArrayList<TryCatchBlockNode>();
List<LocalVariableNode> newLocalVariables = new ArrayList<LocalVariableNode>();
while (!worklist.isEmpty()) {
Instantiation instantiation = worklist.removeFirst();
emitInstantiation(
instantiation, worklist, newInstructions, newTryCatchBlocks, newLocalVariables);
}
instructions = newInstructions;
tryCatchBlocks = newTryCatchBlocks;
localVariables = newLocalVariables;
}
@Test
public void mustFindLocalVariableNodeForInstruction() {
MethodNode methodNode = findMethodsWithName(classNode.methods, "localVariablesTest").get(0);
List<AbstractInsnNode> insns = findInvocationsOf(methodNode.instructions,
MethodUtils.getAccessibleMethod(PrintStream.class, "println", String.class));
AbstractInsnNode insnNode = insns.get(0);
LocalVariableNode lvn0 = findLocalVariableNodeForInstruction(methodNode.localVariables, methodNode.instructions, insnNode, 0);
LocalVariableNode lvn1 = findLocalVariableNodeForInstruction(methodNode.localVariables, methodNode.instructions, insnNode, 1);
LocalVariableNode lvn2 = findLocalVariableNodeForInstruction(methodNode.localVariables, methodNode.instructions, insnNode, 2);
assertEquals(lvn0.name, "this");
assertEquals(lvn1.name, "val1");
assertEquals(lvn2.name, "val2");
}
private static AbstractInsnNode getParamStartNodeOfUDClassMethodCall(MethodInsnNode node, List<LocalVariableNode> locaVariables) {
String owner = node.owner;
List<Integer> descriptionMatchingLocalVariables = new ArrayList<Integer>();
for (LocalVariableNode localVar : locaVariables) {
if (localVar.desc.contains(owner)) {
descriptionMatchingLocalVariables.add(localVar.index);
}
}
boolean isOtherClassVariableFound = false;
AbstractInsnNode previousNode = node.getPrevious();
while (previousNode != null && !isOtherClassVariableFound) {
if (previousNode instanceof VarInsnNode) {
VarInsnNode varInsnNode = (VarInsnNode) previousNode;
Integer indexOfUDC = descriptionMatchingLocalVariables.indexOf(varInsnNode.var);
if (indexOfUDC != -1) {
return previousNode;
}
previousNode = previousNode.getPrevious();
return previousNode;
}
}
return null;
}
private static void createVarFieldArray(final CodeBlock block,
final RuleMethod method)
{
final int count = method.getLocalVarVariables().size();
block.bipush(count).anewarray(CodegenUtils.p(Var.class));
LocalVariableNode var;
String varName;
for (int i = 0; i < count; i++) {
var = method.getLocalVarVariables().get(i);
varName = method.name + ':' + var.name;
block.dup()
.bipush(i)
.aload(var.index)
.dup()
.ldc(varName)
.invokevirtual(CodegenUtils.p(Var.class), "setName",
CodegenUtils.sig(void.class, String.class))
.aastore();
}
}
private static String printAttr(Object o, InstructionPrinter insnPrinter) {
if (o instanceof LocalVariableNode) {
LocalVariableNode lvn = (LocalVariableNode) o;
return "index=" + lvn.index + " , name=" + lvn.name + " , desc="
+ lvn.desc + ", sig=" + lvn.signature + ", start=L"
+ insnPrinter.resolveLabel(lvn.start) + ", end=L"
+ insnPrinter.resolveLabel(lvn.end);
} else if (o instanceof AnnotationNode) {
AnnotationNode an = (AnnotationNode) o;
StringBuilder sb = new StringBuilder();
sb.append("desc = ");
sb.append(an.desc);
sb.append(" , values = ");
if (an.values != null) {
sb.append(Arrays.toString(an.values.toArray()));
} else {
sb.append("[]");
}
return sb.toString();
}
if (o == null)
return "";
return o.toString();
}
@Override
public void fix(ClassNode optifine, ClassNode minecraft) {
for (MethodNode methodNode : optifine.methods) {
if (methodNode.name.equals(stitchName)) {
for (LocalVariableNode localVariable : methodNode.localVariables) {
if (localVariable.name.equals("locsEmissive")) {
//Make this a HashSet and not just a Set so mixin only has 1 target
localVariable.desc = "Ljava/util/HashSet;";
}
}
}
}
}
private void visitLocals(MethodVisitor mv) {
for (Object l: methodFlow.localVariables) {
LocalVariableNode lvn = (LocalVariableNode)l;
lvn.signature = lvn.signature==null?null:lvn.signature;
lvn.accept(mv);
}
}
public LocalVariableCode(LocalVariableNode localVariableNode) {
name = localVariableNode.name;
desc = localVariableNode.desc;
signature = localVariableNode.signature;
start = localVariableNode.start;
end = localVariableNode.end;
index = localVariableNode.index;
//
variableType = VariableType.valueOf(desc);
}
public LocalVariableCode(LocalVariableNode localVariableNode) {
name = localVariableNode.name;
desc = localVariableNode.desc;
signature = localVariableNode.signature;
start = localVariableNode.start;
end = localVariableNode.end;
index = localVariableNode.index;
//
variableType = VariableType.valueOf(desc);
}
public static int addNewLocalVariable(
MethodNode method, String name, String desc, LabelNode start, LabelNode end) {
Optional<LocalVariableNode> lastVar =
method.localVariables.stream().max(Comparator.comparingInt(var -> var.index));
final int newIndex =
lastVar.map(var -> var.desc.matches("[JD]") ? var.index + 2 : var.index + 1).orElse(0);
LocalVariableNode variable = new LocalVariableNode(name, desc, null, start, end, newIndex);
method.localVariables.add(variable);
return newIndex;
}
public static boolean containsVariable(Variable variableRule, List<LocalVariableNode> variableNodes) {
logger.trace("containsVariable: variableRule={}, variableNodes={}", variableRule, variableNodes);
if (variableNodes == null) {
return false;
}
for (LocalVariableNode variableNode : variableNodes) {
String name = variableNode.name;
String desc = variableNode.desc;
if (!name.contains("this") && isValidVariable(variableRule, name, desc)) {
return true;
}
}
return false;
}
public LVPEntry(ClassNode cn, MethodNode mn, LocalVariableNode lvn) {
this.cn = cn;
this.mn = mn;
this.lvn = lvn;
this.text = TextUtils.toHtml(TextUtils.toBold("#" + lvn.index) + " ");
if (lvn.desc != null && !lvn.desc.isEmpty()) {
this.text += InstrUtils.getDisplayType(lvn.desc, true) + " ";
}
this.text += TextUtils.addTag(TextUtils.escape(lvn.name), "font color=#995555");
}
AsmMethodSource(int maxLocals, InsnList insns,
List<LocalVariableNode> localVars,
List<TryCatchBlockNode> tryCatchBlocks) {
this.maxLocals = maxLocals;
this.instructions = insns;
this.localVars = localVars;
this.tryCatchBlocks = tryCatchBlocks;
}
public static List<LocalVariableNode> cloneLocals(Map<LabelNode, LabelNode> labelMap, List<LocalVariableNode> locals) {
ArrayList<LocalVariableNode> clone = new ArrayList<>(locals.size());
for (LocalVariableNode node : locals) {
clone.add(new LocalVariableNode(node.name, node.desc, node.signature, labelMap.get(node.start), labelMap.get(node.end), node.index));
}
return clone;
}
public static int getLocal(List<LocalVariableNode> list, String name) {
int found = -1;
for (LocalVariableNode node : list) {
if (node.name.equals(name)) {
if (found >= 0) {
throw new RuntimeException("Duplicate local variable: " + name + " not coded to handle this scenario.");
}
found = node.index;
}
}
return found;
}
public static List<LocalVariableNode> cloneLocals(Map<LabelNode, LabelNode> labelMap, List<LocalVariableNode> locals) {
ArrayList<LocalVariableNode> clone = new ArrayList<LocalVariableNode>();
for (LocalVariableNode node : locals) {
clone.add(new LocalVariableNode(node.name, node.desc, node.signature, labelMap.get(node.start), labelMap.get(node.end), node.index));
}
return clone;
}
public static int getLocal(List<LocalVariableNode> list, String name) {
int found = -1;
for (LocalVariableNode node : list) {
if (node.name.equals(name)) {
if (found >= 0) {
throw new RuntimeException("Duplicate local variable: " + name + " not coded to handle this scenario.");
}
found = node.index;
}
}
return found;
}
public static List<LocalVariableNode> cloneLocals(Map<LabelNode, LabelNode> labelMap, List<LocalVariableNode> locals) {
ArrayList<LocalVariableNode> clone = new ArrayList<LocalVariableNode>();
for (LocalVariableNode node : locals) {
clone.add(new LocalVariableNode(node.name, node.desc, node.signature, labelMap.get(node.start), labelMap.get(node.end), node.index));
}
return clone;
}
public static int getLocal(List<LocalVariableNode> list, String name) {
int found = -1;
for (LocalVariableNode node : list) {
if (node.name.equals(name)) {
if (found >= 0) {
throw new RuntimeException("Duplicate local variable: " + name + " not coded to handle this scenario.");
}
found = node.index;
}
}
return found;
}
/**
* Gets the generated the local variable table for the specified method.
*
* @param classNode Containing class
* @param method Method
* @return generated local variable table
*/
public static List<LocalVariableNode> getGeneratedLocalVariableTable(ClassNode classNode, MethodNode method) {
String methodId = String.format("%s.%s%s", classNode.name, method.name, method.desc);
List<LocalVariableNode> localVars = Locals.calculatedLocalVariables.get(methodId);
if (localVars != null) {
return localVars;
}
localVars = Locals.generateLocalVariableTable(classNode, method);
Locals.calculatedLocalVariables.put(methodId, localVars);
return localVars;
}
public SignaturePrinter(String name, Type returnType, LocalVariableNode[] args) {
this.name = name;
this.returnType = returnType;
this.argTypes = new Type[args.length];
this.argNames = new String[args.length];
for (int l = 0; l < args.length; l++) {
if (args[l] != null) {
this.argTypes[l] = Type.getType(args[l].desc);
this.argNames[l] = args[l].name;
}
}
}
/**
* API to fetch the start node
* @param node
* @param locaVariables
* @return
* @throws IllegalArgumentException
*/
public static AbstractInsnNode getParamStartNode(AbstractInsnNode node,
List<LocalVariableNode> locaVariables)
throws IllegalArgumentException {
AbstractInsnNode paramStartNode = null;
if (node instanceof MethodInsnNode) {
MethodInsnNode min = (MethodInsnNode) node;
if ("<init>".equals(min.name)) {
paramStartNode = getInitializationInstructionsSet(node);
} else {
AbstractInsnNode traversalNode = node;
while (!isMethodStartNode(traversalNode)
&& traversalNode != null) {
traversalNode = traversalNode.getPrevious();
}
// Since we could not fetch startNode of parameter, this means
// there must be another class's method call
if (paramStartNode == null) {
traversalNode = getParamStartNodeOfUDClassMethodCall(min,
locaVariables);
}
paramStartNode = traversalNode;
}
} else if (node instanceof VarInsnNode) {
VarInsnNode varNode = (VarInsnNode) node;
if (!(varNode.var == InstrumentConstants.THREE || varNode.var == 0)) {
paramStartNode = node;
}
} else if (node instanceof FieldInsnNode) {
paramStartNode = node;
} else{isParameterSetToNull(node);
// If parameter is set to null then don't do anything as an
// exception will be thrown
}
return paramStartNode;
}
/**
* API to add local variable in method
* @param mn
* @param varName
* @param desc
* @param signature
* @param index
* @return
*/
public static LocalVariableNode addMethodLocalVariable(MethodNode mn, String varName, String desc, String signature, int index) {
InsnList list = mn.instructions;
LabelNode begin = new LabelNode();
LabelNode end = new LabelNode();
list.insert(list.getFirst(), begin);
list.insert(list.getLast(), end);
LocalVariableNode lv = new LocalVariableNode(varName, desc, signature, begin, end, index);
return lv;
}
/**
* <p>
* Adds a local variable for chained mapper task
* </p>.
*
* @param varIndex Variable index
*/
@SuppressWarnings({ "unchecked" })
private void addLocalJobConf(int varIndex) {
LabelNode begin = new LabelNode();
LabelNode end = new LabelNode();
instructions.insertBefore(instructions.getFirst(), begin);
instructions.insert(instructions.getLast(), end);
LocalVariableNode lv = new LocalVariableNode(LOCAL_CONF_VARIABLE_NAME
+ ++localJobConfAdded, Type.getDescriptor(JobConf.class), null,
begin, end, varIndex);
localVariables.add(lv);
}
/**
* <p>
* This method provides instructions to add a local variable for loop
* counter
* </p>
*
* @param varIndex
* Index at which the variable will be added
*/
@SuppressWarnings("unchecked")
private void addLocalVariable(int varIndex) {
if (!this.isVariableAdded) {
for (int j = 0; j < this.insnArr.length; j++) {
AbstractInsnNode abstractInsnNode = this.insnArr[j];
if (abstractInsnNode instanceof LabelNode) {
// adding variable declaration and initializing with ZERO
LabelNode ln = (LabelNode) abstractInsnNode;
InsnList il = new InsnList();
il.add(new LabelNode());
il.add(new InsnNode(Opcodes.ICONST_0));
il.add(new VarInsnNode(Opcodes.ISTORE, varIndex));
instructions.insertBefore(ln, il);
// adding local variable
LabelNode begin = new LabelNode();
LabelNode end = new LabelNode();
instructions.insertBefore(instructions.getFirst(), begin);
instructions.insert(instructions.getLast(), end);
LocalVariableNode lv = new LocalVariableNode(LOOP_COUNTER,
Type.INT_TYPE.getDescriptor(), null, begin, end,
varIndex);
localVariables.add(lv);
this.isVariableAdded = true;
break;
}
}
}
}
@Override
public void visitLocalVariable(final String name, final String desc,
final String signature, final Label start, final Label end,
final int index)
{
// only remember the local variables of Type com.github.fge.grappa.support.Var that are not parameters
final Type type = Type.getType(desc);
if (index > parameterCount
&& Var.class.isAssignableFrom(getClassForType(type)))
localVarVariables.add(new LocalVariableNode(name, desc, null, null,
null, index));
}