List of usage examples for org.objectweb.asm.tree InsnList getLast
public AbstractInsnNode getLast()
From source file:com.android.ide.eclipse.apt.internal.analysis.InnerClassAnalyzer.java
License:Apache License
@SuppressWarnings("unchecked") private AbstractInsnNode retrieveMethodOrField(final MethodInsnNode method) { final String name = method.name; final List<MethodNode> meInsnNodes = (List<MethodNode>) mOuterClass.methods; AbstractInsnNode result = null;//from w w w.j a v a 2 s . co m for (final MethodNode methodNode : meInsnNodes) { if (methodNode.name.equals(name)) { final InsnList instructions = methodNode.instructions; result = instructions.getLast().getPrevious(); } } return result; }
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. ja va 2 s .com 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.fge.grappa.transform.process.LabellingGenerator.java
License:Apache License
@Override public void process(@Nonnull ParserClassNode classNode, @Nonnull RuleMethod method) throws Exception { Objects.requireNonNull(classNode, "classNode"); Objects.requireNonNull(method, "method"); // super methods have flag moved to the overriding method Preconditions.checkState(!method.isSuperMethod()); InsnList instructions = method.instructions; AbstractInsnNode retInsn = instructions.getLast(); while (retInsn.getOpcode() != ARETURN) retInsn = retInsn.getPrevious(); LabelNode label = new LabelNode(); CodeBlock block = CodeBlock.newCodeBlock().dup().ifnull(label).ldc(getLabelText(method)) .invokeinterface(CodegenUtils.p(Rule.class), "label", CodegenUtils.sig(Rule.class, String.class)) .label(label);/*from ww w . j av a 2s . c om*/ instructions.insertBefore(retInsn, block.getInstructionList()); }
From source file:com.github.fge.grappa.transform.process.VarFramingGenerator.java
License:Apache License
@Override public void process(@Nonnull ParserClassNode classNode, @Nonnull RuleMethod method) throws Exception { Objects.requireNonNull(classNode, "classNode"); Objects.requireNonNull(method, "method"); InsnList instructions = method.instructions; AbstractInsnNode ret = instructions.getLast(); while (ret.getOpcode() != ARETURN) ret = ret.getPrevious();//from w w w . j a va2s . co m CodeBlock block = CodeBlock.newCodeBlock(); block.newobj(CodegenUtils.p(VarFramingMatcher.class)).dup_x1().swap(); createVarFieldArray(block, method); block.invokespecial(CodegenUtils.p(VarFramingMatcher.class), "<init>", CodegenUtils.sig(void.class, Rule.class, Var[].class)); instructions.insertBefore(ret, block.getInstructionList()); method.setBodyRewritten(); }
From source file:com.liferay.portal.nio.intraband.proxy.IntrabandProxyUtilTest.java
License:Open Source License
@Test public void testDeserializerRead() { MethodNode methodNode = new MethodNode(Opcodes.ACC_PUBLIC, "name", "()V", null, null); MethodNodeGenerator methodNodeGenerator = new MethodNodeGenerator(methodNode); InsnList insnList = methodNode.instructions; for (Type type : _types) { IntrabandProxyUtil.deserializerRead(methodNodeGenerator, type); AbstractInsnNode abstractInsnNode = insnList.getLast(); String methodName = "readObject"; Type returnType = Type.getType(Serializable.class); if (type.getSort() <= Type.DOUBLE) { String name = TextFormatter.format(type.getClassName(), TextFormatter.G); methodName = "read".concat(name); returnType = type;//from w w w . j av a 2 s.c o m } else if (type.equals(Type.getType(String.class))) { methodName = "readString"; returnType = Type.getType(String.class); _assertMethodInsnNode(abstractInsnNode, Opcodes.INVOKEVIRTUAL, Type.getInternalName(Deserializer.class), "readString", Type.getType(String.class)); } _assertMethodInsnNode(abstractInsnNode, Opcodes.INVOKEVIRTUAL, Type.getInternalName(Deserializer.class), methodName, returnType); } }
From source file:com.liferay.portal.nio.intraband.proxy.IntrabandProxyUtilTest.java
License:Open Source License
@Test public void testSerializerWrite() { MethodNode methodNode = new MethodNode(Opcodes.ACC_PUBLIC, "name", "()V", null, null); MethodNodeGenerator methodNodeGenerator = new MethodNodeGenerator(methodNode); InsnList insnList = methodNode.instructions; for (Type type : _types) { IntrabandProxyUtil.serializerWrite(methodNodeGenerator, type); AbstractInsnNode abstractInsnNode = insnList.getLast(); Assert.assertTrue(abstractInsnNode instanceof MethodInsnNode); MethodInsnNode methodInsnNode = (MethodInsnNode) abstractInsnNode; Assert.assertEquals(Opcodes.INVOKEVIRTUAL, abstractInsnNode.getOpcode()); Assert.assertEquals(Type.getInternalName(Serializer.class), methodInsnNode.owner); if (type.getSort() <= Type.DOUBLE) { String name = TextFormatter.format(type.getClassName(), TextFormatter.G); Assert.assertEquals("write".concat(name), methodInsnNode.name); Assert.assertEquals(Type.getMethodDescriptor(Type.VOID_TYPE, type), methodInsnNode.desc); } else if (type.equals(Type.getType(String.class))) { Assert.assertEquals("writeString", methodInsnNode.name); Assert.assertEquals(Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String.class)), methodInsnNode.desc); } else {//from w w w . j a v a 2s . co m Assert.assertEquals("writeObject", methodInsnNode.name); Assert.assertEquals(Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Serializable.class)), methodInsnNode.desc); } } }
From source file:com.lodgon.parboiled.transform.FlagMarkingGenerator.java
License:Apache License
public void process(ParserClassNode classNode, RuleMethod method) throws Exception { checkArgNotNull(classNode, "classNode"); checkArgNotNull(method, "method"); checkState(!method.isSuperMethod()); // super methods have flag moved to the overriding method InsnList instructions = method.instructions; AbstractInsnNode ret = instructions.getLast(); while (ret.getOpcode() != ARETURN) { ret = ret.getPrevious();//from w w w . j a v a 2 s . c om } // stack: <rule> instructions.insertBefore(ret, new InsnNode(DUP)); // stack: <rule> :: <rule> LabelNode isNullLabel = new LabelNode(); instructions.insertBefore(ret, new JumpInsnNode(IFNULL, isNullLabel)); // stack: <rule> if (method.hasSuppressNodeAnnotation()) generateMarkerCall(instructions, ret, "suppressNode"); if (method.hasSuppressSubnodesAnnotation()) generateMarkerCall(instructions, ret, "suppressSubnodes"); if (method.hasSkipNodeAnnotation()) generateMarkerCall(instructions, ret, "skipNode"); if (method.hasMemoMismatchesAnnotation()) generateMarkerCall(instructions, ret, "memoMismatches"); // stack: <rule> instructions.insertBefore(ret, isNullLabel); // stack: <rule> }
From source file:com.lodgon.parboiled.transform.LabellingGenerator.java
License:Apache License
public void process(ParserClassNode classNode, RuleMethod method) throws Exception { checkArgNotNull(classNode, "classNode"); checkArgNotNull(method, "method"); checkState(!method.isSuperMethod()); // super methods have flag moved to the overriding method InsnList instructions = method.instructions; AbstractInsnNode ret = instructions.getLast(); while (ret.getOpcode() != ARETURN) { ret = ret.getPrevious();//from www . j av a2 s. c o m } LabelNode isNullLabel = new LabelNode(); // stack: <rule> instructions.insertBefore(ret, new InsnNode(DUP)); // stack: <rule> :: <rule> instructions.insertBefore(ret, new JumpInsnNode(IFNULL, isNullLabel)); // stack: <rule> instructions.insertBefore(ret, new LdcInsnNode(getLabelText(method))); // stack: <rule> :: <labelText> instructions.insertBefore(ret, new MethodInsnNode(INVOKEINTERFACE, Types.RULE.getInternalName(), "label", "(Ljava/lang/String;)" + Types.RULE_DESC)); // stack: <rule> instructions.insertBefore(ret, isNullLabel); // stack: <rule> }
From source file:com.lodgon.parboiled.transform.VarFramingGenerator.java
License:Apache License
public void process(ParserClassNode classNode, RuleMethod method) throws Exception { checkArgNotNull(classNode, "classNode"); checkArgNotNull(method, "method"); InsnList instructions = method.instructions; AbstractInsnNode ret = instructions.getLast(); while (ret.getOpcode() != ARETURN) { ret = ret.getPrevious();/*from www . j a v a 2 s .c om*/ } // stack: <Matcher> instructions.insertBefore(ret, new TypeInsnNode(NEW, VAR_FRAMING_MATCHER.getInternalName())); // stack: <Matcher> :: <VarFramingMatcher> instructions.insertBefore(ret, new InsnNode(DUP_X1)); // stack: <VarFramingMatcher> :: <Matcher> :: <VarFramingMatcher> instructions.insertBefore(ret, new InsnNode(SWAP)); // stack: <VarFramingMatcher> :: <VarFramingMatcher> :: <Matcher> createVarFieldArray(method, instructions, ret); // stack: <VarFramingMatcher> :: <VarFramingMatcher> :: <Matcher> :: <VarFieldArray> instructions.insertBefore(ret, new MethodInsnNode(INVOKESPECIAL, VAR_FRAMING_MATCHER.getInternalName(), "<init>", '(' + RULE_DESC + '[' + VAR_DESC + ")V")); // stack: <VarFramingMatcher> method.setBodyRewritten(); }
From source file:com.typesafe.path_hole.PathHole.java
License:Open Source License
private static byte[] prependToClassLoader() { Object[] ourEnhancementsToLoadClass = getMethodNode(PathHole.class, "bytecodeToPrepend", "(Ljava/lang/String;Z)V"); Object[] jlClassLoader = getMethodNode(ClassLoader.class, "loadClass", "(Ljava/lang/String;Z)Ljava/lang/Class;"); // get the bytecode to prepend InsnList prependInst = ((MethodNode) ourEnhancementsToLoadClass[1]).instructions; // lets get rid of the return statement // remove the optional label if (prependInst.getLast().getOpcode() < 0) { prependInst.remove(prependInst.getLast()); }/*from w w w . ja va 2 s. com*/ // remove the return inst. It doesn't take any args so this is all we need prependInst.remove(prependInst.getLast()); // now add this to loadClass method of jlClassLoader InsnList baseInst = ((MethodNode) jlClassLoader[1]).instructions; baseInst.insertBefore(baseInst.getFirst(), prependInst); ClassNode clClassNode = (ClassNode) jlClassLoader[0]; // we just need to add any fields referenced by the prepended bytecode to the jlClassLoader // ClassNode prependClassNode = (ClassNode) ourEnhancementsToLoadClass[0]; // write the new bytecode ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); clClassNode.accept(cw); return cw.toByteArray(); }