Example usage for org.objectweb.asm.tree InsnList getLast

List of usage examples for org.objectweb.asm.tree InsnList getLast

Introduction

In this page you can find the example usage for org.objectweb.asm.tree InsnList getLast.

Prototype

public AbstractInsnNode getLast() 

Source Link

Document

Returns the last instruction in this list.

Usage

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();
}