List of usage examples for org.objectweb.asm.tree InsnList add
public void add(final InsnList insnList)
From source file:cl.inria.stiq.instrumenter.BCIUtils.java
License:Open Source License
private static InsnList cloneInstructions(ClonerMap aMap, InsnList aList) { InsnList theInsnListClone = new InsnList(); AbstractInsnNode theNode = aList.getFirst(); while (theNode != null) { AbstractInsnNode theClone = theNode.clone(aMap); if (theClone instanceof LabelNode) { LabelNode theLabelNode = (LabelNode) theClone; }/*from w w w . j av a2s. c o m*/ theInsnListClone.add(theClone); theNode = theNode.getNext(); } return theInsnListClone; }
From source file:cl.inria.stiq.instrumenter.LocationsManager.java
License:Open Source License
/** * Creates a new location at the end of the given list. *//*ww w . j a va 2s . c om*/ public int createLocation(InsnList aInsns) { int theId = itsStructureDatabase.addProbe(-1, -1, null, -1); Label theLabel = new Label(); aInsns.add(new LabelNode(theLabel)); itsLocations.add(new TmpLocationInfo(theId, theLabel)); return theId; }
From source file:com.android.builder.testing.MockableJarGenerator.java
License:Apache License
/** * Rewrites the method bytecode to remove the "Stub!" exception. *//* ww w .j ava 2 s .co m*/ private void fixMethodBody(MethodNode methodNode, ClassNode classNode) { if ((methodNode.access & Opcodes.ACC_NATIVE) != 0 || (methodNode.access & Opcodes.ACC_ABSTRACT) != 0) { // Abstract and native method don't have bodies to rewrite. return; } if ((classNode.access & Opcodes.ACC_ENUM) != 0 && ENUM_METHODS.contains(methodNode.name)) { // Don't break enum classes. return; } Type returnType = Type.getReturnType(methodNode.desc); InsnList instructions = methodNode.instructions; if (methodNode.name.equals(CONSTRUCTOR)) { // Keep the call to parent constructor, delete the exception after that. boolean deadCode = false; for (AbstractInsnNode instruction : instructions.toArray()) { if (!deadCode) { if (instruction.getOpcode() == Opcodes.INVOKESPECIAL) { instructions.insert(instruction, new InsnNode(Opcodes.RETURN)); // Start removing all following instructions. deadCode = true; } } else { instructions.remove(instruction); } } } else { instructions.clear(); if (returnDefaultValues || methodNode.name.equals(CLASS_CONSTRUCTOR)) { if (INTEGER_LIKE_TYPES.contains(returnType)) { instructions.add(new InsnNode(Opcodes.ICONST_0)); } else if (returnType.equals(Type.LONG_TYPE)) { instructions.add(new InsnNode(Opcodes.LCONST_0)); } else if (returnType.equals(Type.FLOAT_TYPE)) { instructions.add(new InsnNode(Opcodes.FCONST_0)); } else if (returnType.equals(Type.DOUBLE_TYPE)) { instructions.add(new InsnNode(Opcodes.DCONST_0)); } else { instructions.add(new InsnNode(Opcodes.ACONST_NULL)); } instructions.add(new InsnNode(returnType.getOpcode(Opcodes.IRETURN))); } else { instructions.insert(throwExceptionsList(methodNode, classNode)); } } }
From source file:com.android.builder.testing.MockableJarGenerator.java
License:Apache License
private static InsnList throwExceptionsList(MethodNode methodNode, ClassNode classNode) { try {/*from ww w. j a v a 2 s .co m*/ String runtimeException = Type.getInternalName(RuntimeException.class); Constructor<RuntimeException> constructor = RuntimeException.class.getConstructor(String.class); InsnList instructions = new InsnList(); instructions.add(new TypeInsnNode(Opcodes.NEW, runtimeException)); instructions.add(new InsnNode(Opcodes.DUP)); String className = classNode.name.replace('/', '.'); instructions.add(new LdcInsnNode("Method " + methodNode.name + " in " + className + " not mocked. " + "See http://g.co/androidstudio/not-mocked for details.")); instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, runtimeException, CONSTRUCTOR, Type.getType(constructor).getDescriptor(), false)); instructions.add(new InsnNode(Opcodes.ATHROW)); return instructions; } catch (NoSuchMethodException e) { throw new RuntimeException(e); } }
From source file:com.builtbroken.mc.patch.ClassTransformer.java
/** Fixes {@link net.minecraft.tileentity.TileEntityChest#invalidate()} causing inf loops on chunk edges */ private void injectInvalidateEdit(ClassNode cn) { final MethodNode method = ASMUtility.getMethod(cn, "invalidate", "func_145843_s"); if (method != null) { //Create method call final InsnList nodeAdd = new InsnList(); nodeAdd.add(new VarInsnNode(ALOAD, 0)); nodeAdd.add(new MethodInsnNode(INVOKESTATIC, HOOK_CLASS, "chestInvalidate", "(Lnet/minecraft/tileentity/TileEntityChest;)V", false)); //Inject method call at top of method ListIterator<AbstractInsnNode> it = method.instructions.iterator(); MethodInsnNode checkForAdjacentChests = null; while (it.hasNext()) { AbstractInsnNode node = it.next(); if (node instanceof MethodInsnNode) { if (((MethodInsnNode) node).name.equals("checkForAdjacentChests")) { checkForAdjacentChests = (MethodInsnNode) node; }/*from w w w. ja v a 2s .c o m*/ } } if (checkForAdjacentChests != null) { //Inject replacement method.instructions.insertBefore(method.instructions.get(method.instructions.size() - 1), nodeAdd); //Remove broken code method.instructions.remove(checkForAdjacentChests); } } else { CoreMod.logger.error("Failed to find 'public void invalidate()' in TileEntityChest.class"); } }
From source file:com.builtbroken.mc.patch.ClassTransformer.java
/** Fixes {@link net.minecraft.world.World#notifyBlockOfNeighborChange(int, int, int, Block)} causing chunks to load */ private void injectNotifyBlockOfNeighborChange(ClassNode cn) { final MethodNode method = ASMUtility.getMethod(cn, "notifyBlockOfNeighborChange", "func_147460_e"); if (method != null) { final InsnList edit = new InsnList(); edit.add(new VarInsnNode(ALOAD, 0)); edit.add(new VarInsnNode(ILOAD, 1)); //TODO update as needed edit.add(new VarInsnNode(ILOAD, 2)); edit.add(new VarInsnNode(ILOAD, 3)); edit.add(new VarInsnNode(ALOAD, 4)); edit.add(new MethodInsnNode(INVOKESTATIC, HOOK_CLASS, "notifyBlockOfNeighborChange", "(Lnet/minecraft/world/World;IIILnet/minecraft/block/Block;)V", false)); edit.add(new InsnNode(RETURN)); MethodInsnNode m = ASMUtility.getMethodeNode(method, "onNeighborBlockChange", "func_149695_a"); method.instructions.insertBefore(m, edit); method.instructions.remove(m);/*from w w w .ja v a2 s.co m*/ } else { CoreMod.logger.error( "Failed to find 'public void notifyBlockOfNeighborChange(int, int, int, Block)' in World.class"); } }
From source file:com.builtbroken.profiler.asm.WorldTransformer.java
/** {@link World#setBlock(int, int, int, Block, int, int)} */ private void injectSetBlock(ClassNode cn) { MethodNode setBlockMethod = getMethod(cn, "setBlock", "(IIIL" + getName(CLASS_KEY_BLOCK) + ";II)Z"); if (setBlockMethod != null) { //Create method call final InsnList nodeAdd = new InsnList(); nodeAdd.add(new VarInsnNode(Opcodes.ALOAD, 0)); nodeAdd.add(new VarInsnNode(Opcodes.ILOAD, 1)); nodeAdd.add(new VarInsnNode(Opcodes.ILOAD, 2)); nodeAdd.add(new VarInsnNode(Opcodes.ILOAD, 3)); nodeAdd.add(new MethodInsnNode(Opcodes.INVOKESTATIC, BLOCK_HOOK_CLASS, "onBlockChange", "(L" + getName(CLASS_KEY_WORLD) + ";III)V", false)); //Inject method call at top of method setBlockMethod.instructions.insertBefore(setBlockMethod.instructions.get(0), nodeAdd); //Locate all return points from the method List<AbstractInsnNode> returnNodes = new ArrayList(); for (int i = 0; i < setBlockMethod.instructions.size(); i++) { AbstractInsnNode ain = setBlockMethod.instructions.get(i); if (ain.getOpcode() == Opcodes.IRETURN) { returnNodes.add(ain);/*from ww w. java 2s .co m*/ } } //Inject calls in front of return points for (AbstractInsnNode node : returnNodes) { //Create method call final InsnList nodeAdd2 = new InsnList(); nodeAdd2.add(new VarInsnNode(Opcodes.ALOAD, 0)); nodeAdd2.add(new VarInsnNode(Opcodes.ILOAD, 1)); nodeAdd2.add(new VarInsnNode(Opcodes.ILOAD, 2)); nodeAdd2.add(new VarInsnNode(Opcodes.ILOAD, 3)); nodeAdd2.add(new MethodInsnNode(Opcodes.INVOKESTATIC, BLOCK_HOOK_CLASS, "onPostBlockChange", "(L" + getName(CLASS_KEY_WORLD) + ";III)V", false)); //Inject method call before return node setBlockMethod.instructions.insertBefore(node, nodeAdd2); } } }
From source file:com.builtbroken.profiler.asm.WorldTransformer.java
/** {@link World#setBlockMetadataWithNotify(int, int, int, int, int)} */ private void injectSetBlockWithMeta(ClassNode cn) { MethodNode setBlockMetaMethod = getMethod(cn, "setBlockMetadataWithNotify", "(IIIII)Z"); if (setBlockMetaMethod != null) { final InsnList nodeAdd = new InsnList(); nodeAdd.add(new VarInsnNode(Opcodes.ALOAD, 0)); //this nodeAdd.add(new VarInsnNode(Opcodes.ILOAD, 1)); //x nodeAdd.add(new VarInsnNode(Opcodes.ILOAD, 2)); //y nodeAdd.add(new VarInsnNode(Opcodes.ILOAD, 3)); //z nodeAdd.add(new MethodInsnNode(Opcodes.INVOKESTATIC, BLOCK_HOOK_CLASS, "onBlockMetaChange", "(L" + getName(CLASS_KEY_WORLD) + ";III)V", false)); setBlockMetaMethod.instructions.insertBefore(setBlockMetaMethod.instructions.get(0), nodeAdd); //Locate all return points from the method List<AbstractInsnNode> returnNodes = new ArrayList(); for (int i = 0; i < setBlockMetaMethod.instructions.size(); i++) { AbstractInsnNode ain = setBlockMetaMethod.instructions.get(i); if (ain.getOpcode() == Opcodes.IRETURN) { returnNodes.add(ain);/*from w ww. j a v a 2 s . c o m*/ } } //Inject calls in front of return points for (AbstractInsnNode node : returnNodes) { //Create method call final InsnList nodeAdd2 = new InsnList(); nodeAdd2.add(new VarInsnNode(Opcodes.ALOAD, 0)); nodeAdd2.add(new VarInsnNode(Opcodes.ILOAD, 1)); nodeAdd2.add(new VarInsnNode(Opcodes.ILOAD, 2)); nodeAdd2.add(new VarInsnNode(Opcodes.ILOAD, 3)); nodeAdd2.add(new MethodInsnNode(Opcodes.INVOKESTATIC, BLOCK_HOOK_CLASS, "onPostBlockMetaChange", "(L" + getName(CLASS_KEY_WORLD) + ";III)V", false)); //Inject method call before return node setBlockMetaMethod.instructions.insertBefore(node, nodeAdd2); } } }
From source file:com.dragome.callbackevictor.serverside.bytecode.transformation.asm.ContinuationMethodAnalyzer.java
License:Apache License
@SuppressWarnings("unchecked") void moveNew() throws AnalyzerException { SourceInterpreter i = new SourceInterpreter(); Analyzer a = new Analyzer(i); a.analyze(className, this); final HashMap<AbstractInsnNode, MethodInsnNode> movable = new HashMap<AbstractInsnNode, MethodInsnNode>(); Frame[] frames = a.getFrames(); for (int j = 0; j < methods.size(); j++) { MethodInsnNode mnode = methods.get(j); // require to move NEW instruction int n = instructions.indexOf(mnode); Frame f = frames[n];/* w w w .j a v a 2s. c om*/ Type[] args = Type.getArgumentTypes(mnode.desc); SourceValue v = (SourceValue) f.getStack(f.getStackSize() - args.length - 1); Set<AbstractInsnNode> insns = v.insns; for (final AbstractInsnNode ins : insns) { if (ins.getOpcode() == NEW) { movable.put(ins, mnode); } else { // other known patterns int n1 = instructions.indexOf(ins); if (ins.getOpcode() == DUP) { // <init> with params AbstractInsnNode ins1 = instructions.get(n1 - 1); if (ins1.getOpcode() == NEW) { movable.put(ins1, mnode); } } else if (ins.getOpcode() == SWAP) { // in exception handler AbstractInsnNode ins1 = instructions.get(n1 - 1); AbstractInsnNode ins2 = instructions.get(n1 - 2); if (ins1.getOpcode() == DUP_X1 && ins2.getOpcode() == NEW) { movable.put(ins2, mnode); } } } } } int updateMaxStack = 0; for (final Map.Entry<AbstractInsnNode, MethodInsnNode> e : movable.entrySet()) { AbstractInsnNode node1 = e.getKey(); int n1 = instructions.indexOf(node1); AbstractInsnNode node2 = instructions.get(n1 + 1); AbstractInsnNode node3 = instructions.get(n1 + 2); int producer = node2.getOpcode(); instructions.remove(node1); // NEW boolean requireDup = false; if (producer == DUP) { instructions.remove(node2); // DUP requireDup = true; } else if (producer == DUP_X1) { instructions.remove(node2); // DUP_X1 instructions.remove(node3); // SWAP requireDup = true; } MethodInsnNode mnode = (MethodInsnNode) e.getValue(); AbstractInsnNode nm = mnode; int varOffset = stackRecorderVar + 1; Type[] args = Type.getArgumentTypes(mnode.desc); // optimizations for some common cases if (args.length == 0) { final InsnList doNew = new InsnList(); doNew.add(node1); // NEW if (requireDup) doNew.add(new InsnNode(DUP)); instructions.insertBefore(nm, doNew); nm = doNew.getLast(); continue; } if (args.length == 1 && args[0].getSize() == 1) { final InsnList doNew = new InsnList(); doNew.add(node1); // NEW if (requireDup) { doNew.add(new InsnNode(DUP)); doNew.add(new InsnNode(DUP2_X1)); doNew.add(new InsnNode(POP2)); updateMaxStack = updateMaxStack < 2 ? 2 : updateMaxStack; // a two extra slots for temp values } else doNew.add(new InsnNode(SWAP)); instructions.insertBefore(nm, doNew); nm = doNew.getLast(); continue; } // TODO this one untested! if ((args.length == 1 && args[0].getSize() == 2) || (args.length == 2 && args[0].getSize() == 1 && args[1].getSize() == 1)) { final InsnList doNew = new InsnList(); doNew.add(node1); // NEW if (requireDup) { doNew.add(new InsnNode(DUP)); doNew.add(new InsnNode(DUP2_X2)); doNew.add(new InsnNode(POP2)); updateMaxStack = updateMaxStack < 2 ? 2 : updateMaxStack; // a two extra slots for temp values } else { doNew.add(new InsnNode(DUP_X2)); doNew.add(new InsnNode(POP)); updateMaxStack = updateMaxStack < 1 ? 1 : updateMaxStack; // an extra slot for temp value } instructions.insertBefore(nm, doNew); nm = doNew.getLast(); continue; } final InsnList doNew = new InsnList(); // generic code using temporary locals // save stack for (int j = args.length - 1; j >= 0; j--) { Type type = args[j]; doNew.add(new VarInsnNode(type.getOpcode(ISTORE), varOffset)); varOffset += type.getSize(); } if (varOffset > maxLocals) { maxLocals = varOffset; } doNew.add(node1); // NEW if (requireDup) doNew.add(new InsnNode(DUP)); // restore stack for (int j = 0; j < args.length; j++) { Type type = args[j]; varOffset -= type.getSize(); doNew.add(new VarInsnNode(type.getOpcode(ILOAD), varOffset)); // clean up store to avoid memory leak? if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) { updateMaxStack = updateMaxStack < 1 ? 1 : updateMaxStack; // an extra slot for ACONST_NULL doNew.add(new InsnNode(ACONST_NULL)); doNew.add(new VarInsnNode(type.getOpcode(ISTORE), varOffset)); } } instructions.insertBefore(nm, doNew); nm = doNew.getLast(); } maxStack += updateMaxStack; }
From source file:com.github.antag99.retinazer.weaver.SystemProcessor.java
License:Open Source License
@Override public void visitEnd() { for (FlyweightField field : flyweightFields) field.fieldNode.accept(cv);//from w ww. ja va 2 s .co m if (setupMethod == null) { setupMethod = new MethodNode(ACC_PROTECTED, "setup", "()V", null, null); setupMethod.instructions.add(new VarInsnNode(ALOAD, 0)); setupMethod.instructions .add(new MethodInsnNode(INVOKESPECIAL, metadata.superName, "setup", "()V", false)); setupMethod.instructions.add(new InsnNode(RETURN)); } InsnList insns = new InsnList(); for (FlyweightField field : flyweightFields) { String mapperName = field.mapper.componentType.getInternalName() + "$Mapper"; insns.add(new VarInsnNode(ALOAD, 0)); insns.add(new InsnNode(DUP)); insns.add(new FieldInsnNode(GETFIELD, metadata.internalName, field.mapper.name, "Lcom/github/antag99/retinazer/Mapper;")); insns.add(new TypeInsnNode(CHECKCAST, mapperName)); insns.add(new MethodInsnNode(INVOKEVIRTUAL, mapperName, "createFlyweight", "()" + field.mapper.componentType.getDescriptor(), false)); insns.add( new FieldInsnNode(PUTFIELD, metadata.internalName, field.fieldNode.name, field.fieldNode.desc)); } setupMethod.instructions.insertBefore(setupMethod.instructions.getFirst(), insns); setupMethod.accept(cv); super.visitEnd(); }