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

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

Introduction

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

Prototype

public void clear() 

Source Link

Document

Removes all the instructions of this list.

Usage

From source file:com.android.builder.testing.MockableJarGenerator.java

License:Apache License

/**
 * Rewrites the method bytecode to remove the "Stub!" exception.
 *//*w  w  w .  java 2s. com*/
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.liferay.portal.nio.intraband.proxy.IntrabandProxyUtil.java

License:Open Source License

protected static void rewriteGetProxyMethodSignaturesMethodNode(ClassNode classNode,
        String[] proxyMethodSignatures) {

    MethodNode methodNode = ASMUtil.findMethodNode(classNode.methods, "_getProxyMethodSignatures",
            _STRING_ARRAY_TYPE);/*from w w w  .j  a v a2  s  .c om*/

    InsnList insnList = methodNode.instructions;

    insnList.clear();

    MethodNodeGenerator methodNodeGenerator = new MethodNodeGenerator(methodNode);

    methodNodeGenerator.push(proxyMethodSignatures.length);

    methodNodeGenerator.newArray(_STRING_TYPE);

    for (int i = 0; i < proxyMethodSignatures.length; i++) {
        methodNodeGenerator.dup();

        methodNodeGenerator.push(i);
        methodNodeGenerator.push(proxyMethodSignatures[i]);

        methodNodeGenerator.arrayStore(_STRING_TYPE);
    }

    methodNodeGenerator.returnValue();

    methodNodeGenerator.endMethod();
}

From source file:pl.clareo.coroutines.core.ClassTransformer.java

License:Apache License

@SuppressWarnings("unchecked")
void transform() {
    for (MethodNode coroutine : coroutines) {
        if (log.isLoggable(Level.FINEST)) {
            log.finest("Generating method for coroutine " + coroutine.name + coroutine.desc);
        }/*from ww w  .j  a va  2  s  .  c om*/
        String coroutineName = getCoroutineName(coroutine);
        MethodTransformer methodTransformer = new MethodTransformer(coroutine, thisType);
        MethodNode coroutineImpl = methodTransformer.transform(coroutineName, generateDebugCode);
        thisNode.methods.add(coroutineImpl);
        /*
         * generate co iterators and method stubs
         */
        log.finest("Generating CoIterator implementation and method stubs");
        String baseCoIteratorName;
        Map<String, Object> annotation = getCoroutineAnnotationValues(coroutine);
        if (getBoolean(annotation, "threadLocal")) {
            baseCoIteratorName = Type.getInternalName(ThreadLocalCoIterator.class);
        } else {
            baseCoIteratorName = Type.getInternalName(SingleThreadedCoIterator.class);
        }
        String coIteratorClassName = "pl/clareo/coroutines/core/CoIterator" + num;
        ClassNode coIteratorClass = new ClassNode();
        coIteratorClass.version = Opcodes.V1_6;
        coIteratorClass.access = Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_SUPER;
        coIteratorClass.name = coIteratorClassName;
        coIteratorClass.superName = baseCoIteratorName;
        if (generateDebugCode) {
            /*
             * If debugging code is emitted create field keeping JDK logger
             */
            FieldNode loggerField = new FieldNode(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC,
                    "logger", "Ljava/util/logging/Logger;", null, null);
            coIteratorClass.fields.add(loggerField);
            MethodNode clinit = new MethodNode();
            clinit.access = Opcodes.ACC_STATIC;
            clinit.name = "<clinit>";
            clinit.desc = "()V";
            clinit.exceptions = Collections.EMPTY_LIST;
            String loggerName = thisType.getClassName();
            InsnList clinitCode = clinit.instructions;
            clinitCode.add(new LdcInsnNode(loggerName));
            clinitCode.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/util/logging/Logger", "getLogger",
                    "(Ljava/lang/String;)Ljava/util/logging/Logger;"));
            clinitCode.add(new FieldInsnNode(Opcodes.PUTSTATIC, coIteratorClassName, "logger",
                    "Ljava/util/logging/Logger;"));
            clinitCode.add(new InsnNode(Opcodes.RETURN));
            clinit.maxStack = 1;
            clinit.maxLocals = 0;
            coIteratorClass.methods.add(clinit);
        }
        /*
         * Generate constructor
         */
        MethodNode init = new MethodNode();
        init.access = Opcodes.ACC_PUBLIC;
        init.name = "<init>";
        init.desc = CO_ITERATOR_CONSTRUCTOR_DESCRIPTOR;
        init.exceptions = Collections.EMPTY_LIST;
        InsnList initCode = init.instructions;
        initCode.add(new VarInsnNode(Opcodes.ALOAD, 0));
        initCode.add(new VarInsnNode(Opcodes.ALOAD, 1));
        initCode.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, baseCoIteratorName, "<init>",
                CO_ITERATOR_CONSTRUCTOR_DESCRIPTOR));
        initCode.add(new InsnNode(Opcodes.RETURN));
        init.maxStack = 2;
        init.maxLocals = 2;
        coIteratorClass.methods.add(init);
        /*
         * Generate overriden call to coroutine
         */
        MethodNode call = new MethodNode();
        call.access = Opcodes.ACC_PROTECTED;
        call.name = "call";
        call.desc = CALL_METHOD_DESCRIPTOR;
        call.exceptions = Collections.EMPTY_LIST;
        InsnList callCode = call.instructions;
        /*
         * if debug needed generate call details
         */
        if (generateDebugCode) {
            String coroutineId = "Coroutine " + coroutine.name;
            callCode.add(loggingInstructions(coIteratorClassName, "logger", Level.FINER,
                    coroutineId + " call. Caller sent: ", 2));
            callCode.add(new FrameNode(Opcodes.F_SAME, 0, EMPTY_LOCALS, 0, EMPTY_STACK));
            callCode.add(loggingInstructions(coIteratorClassName, "logger", Level.FINEST,
                    coroutineId + " state ", 1));
            callCode.add(new FrameNode(Opcodes.F_SAME, 0, EMPTY_LOCALS, 0, EMPTY_STACK));
        }
        /*
         * push call arguments: this (if not static), frame, input, output
         */
        boolean isStatic = (coroutine.access & Opcodes.ACC_STATIC) != 0;
        if (!isStatic) {
            callCode.add(new VarInsnNode(Opcodes.ALOAD, 1));
            callCode.add(
                    new MethodInsnNode(Opcodes.INVOKEVIRTUAL, FRAME_NAME, "getThis", "()Ljava/lang/Object;"));
            callCode.add(new TypeInsnNode(Opcodes.CHECKCAST, thisType.getInternalName()));
        }
        callCode.add(new VarInsnNode(Opcodes.ALOAD, 1));
        callCode.add(new InsnNode(Opcodes.ACONST_NULL));
        callCode.add(new VarInsnNode(Opcodes.ALOAD, 2));
        callCode.add(new MethodInsnNode(isStatic ? Opcodes.INVOKESTATIC : Opcodes.INVOKEVIRTUAL,
                thisType.getInternalName(), coroutineName, COROUTINE_METHOD_DESCRIPTOR));
        // stack: *
        if (!generateDebugCode) {
            callCode.add(new InsnNode(Opcodes.ARETURN));
        } else {
            // save result display suspension point (two more locals
            // needed)
            callCode.add(new VarInsnNode(Opcodes.ASTORE, 3));
            callCode.add(new VarInsnNode(Opcodes.ALOAD, 1));
            callCode.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, FRAME_NAME, "getLineOfCode", "()I"));
            callCode.add(box_int(Type.INT));
            callCode.add(new VarInsnNode(Opcodes.ASTORE, 4));
            callCode.add(loggingInstructions(coIteratorClassName, "logger", Level.FINER,
                    "Coroutine suspended at line ", 4, ". Yielded:", 3));
            callCode.add(new FrameNode(Opcodes.F_APPEND, 2,
                    new Object[] { "java/lang/Object", "java/lang/Integer" }, 0, EMPTY_STACK));
            callCode.add(new VarInsnNode(Opcodes.ALOAD, 3));
            callCode.add(new InsnNode(Opcodes.ARETURN));
        }
        coIteratorClass.methods.add(call);
        // if debugging code is emitted it needs space for two
        // additional locals and 5 stack operand
        if (generateDebugCode) {
            call.maxStack = 5;
            call.maxLocals = 5;
        } else {
            if (isStatic) {
                call.maxStack = 3;
            } else {
                call.maxStack = 4;
            }
            call.maxLocals = 3;
        }
        /*
         * CoIterator created - define it in the runtime and verify if
         * needed
         */
        if (log.isLoggable(Level.FINEST)) {
            log.finest("Generated class " + coIteratorClassName);
        }
        ClassWriter cw = new ClassWriter(0);
        coIteratorClass.accept(cw);
        byte[] classBytes = cw.toByteArray();
        try {
            CoroutineInstrumentator.dumpClass(coIteratorClassName, classBytes);
        } catch (IOException e) {
            throw new CoroutineGenerationException("Unable to write class " + coIteratorClassName, e);
        }
        /*
         * start generating method - new method is named as the method in
         * user code, it: returns instance of appropriate CoIterator (see
         * above), saves arguments of call
         */
        if (log.isLoggable(Level.FINEST)) {
            log.finest("Instrumenting method " + coroutine.name);
        }
        InsnList code = coroutine.instructions;
        code.clear();
        /*
         * create new Frame
         */
        boolean isDebugFramePossible = generateDebugCode && coroutine.localVariables != null;
        if (isDebugFramePossible) {
            code.add(createDebugFrame(coroutine));
        } else {
            code.add(createFrame(coroutine));
        }
        /*
         * save frame in the first, and locals array in the second local
         * variable
         */
        int argsSize = Type.getArgumentsAndReturnSizes(coroutine.desc) >> 2;
        if (isStatic) {
            argsSize -= 1;
        }
        code.add(new VarInsnNode(Opcodes.ASTORE, argsSize));
        code.add(new VarInsnNode(Opcodes.ALOAD, argsSize));
        code.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, FRAME_NAME, "getLocals", "()[Ljava/lang/Object;"));
        int localsArrayIndex = argsSize + 1;
        code.add(new VarInsnNode(Opcodes.ASTORE, localsArrayIndex));
        /*
         * save all call arguments (along with this if this method is not
         * static) into locals array
         */
        Type[] argsTypes = Type.getArgumentTypes(coroutine.desc);
        if (!isStatic) {
            code.add(saveloc(localsArrayIndex, 0, 0, JAVA_LANG_OBJECT));
            code.add(savelocs(localsArrayIndex, 1, 1, argsTypes));
        } else {
            code.add(savelocs(localsArrayIndex, 0, 0, argsTypes));
        }
        /*
         * create CoIterator instance with saved frame, make initial call to
         * next if needed and return to caller
         */
        code.add(new TypeInsnNode(Opcodes.NEW, coIteratorClassName));
        code.add(new InsnNode(Opcodes.DUP));
        code.add(new VarInsnNode(Opcodes.ALOAD, argsSize));
        code.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, coIteratorClassName, "<init>",
                CO_ITERATOR_CONSTRUCTOR_DESCRIPTOR));
        if (!getBoolean(annotation, "generator", true)) {
            code.add(new InsnNode(Opcodes.DUP));
            code.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, coIteratorClassName, "next",
                    "()Ljava/lang/Object;"));
            code.add(new InsnNode(Opcodes.POP));
        }
        code.add(new InsnNode(Opcodes.ARETURN));
        /*
         * end method generation; maxs can be statically determined 3
         * operands on stack (call to frame setLocals and CoIterator
         * constructor) + 1 if any argument is long or double (debug frame
         * needs 7 operands for variable names creation); locals = argsSize
         * + 1 reference to frame + 1 array of locals
         */
        if (isDebugFramePossible) {
            coroutine.maxStack = 7;
        } else {
            boolean isCategory2ArgumentPresent = false;
            for (Type argType : argsTypes) {
                int sort = argType.getSort();
                if (sort == Type.LONG || sort == Type.DOUBLE) {
                    isCategory2ArgumentPresent = true;
                    break;
                }
            }
            coroutine.maxStack = isCategory2ArgumentPresent ? 4 : 3;
        }
        coroutine.maxLocals = localsArrayIndex + 1;
        coroutine.localVariables.clear();
        coroutine.tryCatchBlocks.clear();
        num++;
    }
}