Example usage for org.objectweb.asm.tree AbstractInsnNode IINC_INSN

List of usage examples for org.objectweb.asm.tree AbstractInsnNode IINC_INSN

Introduction

In this page you can find the example usage for org.objectweb.asm.tree AbstractInsnNode IINC_INSN.

Prototype

int IINC_INSN

To view the source code for org.objectweb.asm.tree AbstractInsnNode IINC_INSN.

Click Source Link

Document

The type of IincInsnNode instructions.

Usage

From source file:pku.sei.checkedcoverage.tracer.instrumentation.TracingMethodInstrumenter.java

License:Creative Commons License

@SuppressWarnings("unchecked")
public void transform(final ListIterator<MethodNode> methodIt) {

    // do not modify abstract or native methods
    if ((this.methodNode.access & ACC_ABSTRACT) != 0 || (this.methodNode.access & ACC_NATIVE) != 0)
        return;// ww w .ja  v  a 2  s  .  c o m

    // check out what labels are jump targets (only these have to be traced)
    analyze(this.methodNode);

    this.instructionIterator = new FixedInstructionIterator(this.methodNode.instructions);
    // in the old method, initialize the new local variable for the threadtracer
    this.instructionIterator.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(Tracer.class),
            "getInstance", "()L" + Type.getInternalName(Tracer.class) + ";"));
    this.instructionIterator.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Tracer.class),
            "getThreadTracer", "()L" + Type.getInternalName(ThreadTracer.class) + ";"));
    this.instructionIterator.add(new InsnNode(DUP));
    this.instructionIterator.add(new VarInsnNode(ASTORE, this.tracerLocalVarIndex));

    this.instructionIterator.add(
            new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(ThreadTracer.class), "isPaused", "()Z"));
    final LabelNode noTracingLabel = new LabelNode();
    this.instructionIterator.add(new JumpInsnNode(IFNE, noTracingLabel));
    // create a copy of the (uninstrumented) instructions (later, while iterating through the instructions)
    final InsnList oldInstructions = new InsnList();
    final Map<LabelNode, LabelNode> labelCopies = LazyMap.decorate(new HashMap<LabelNode, LabelNode>(),
            new Factory() {
                @Override
                public Object create() {
                    return new LabelNode();
                }
            });
    // copy the try-catch-blocks
    final Object[] oldTryCatchblockNodes = this.methodNode.tryCatchBlocks.toArray();
    for (final Object o : oldTryCatchblockNodes) {
        final TryCatchBlockNode tcb = (TryCatchBlockNode) o;
        final TryCatchBlockNode newTcb = new TryCatchBlockNode(labelCopies.get(tcb.start),
                labelCopies.get(tcb.end), labelCopies.get(tcb.handler), tcb.type);
        this.methodNode.tryCatchBlocks.add(newTcb);
    }

    // increment number of local variables by one (for the threadtracer)
    ++this.methodNode.maxLocals;

    // and increment all local variable indexes after the new one by one
    for (final Object o : this.methodNode.localVariables) {
        final LocalVariableNode localVar = (LocalVariableNode) o;
        if (localVar.index >= this.tracerLocalVarIndex)
            ++localVar.index;
    }

    // store information about local variables in the ReadMethod object
    List<LocalVariable> localVariables = new ArrayList<LocalVariable>();
    for (final Object o : this.methodNode.localVariables) {
        final LocalVariableNode localVar = (LocalVariableNode) o;
        while (localVariables.size() <= localVar.index)
            localVariables.add(null);
        localVariables.set(localVar.index, new LocalVariable(localVar.index, localVar.name, localVar.desc));
    }
    this.readMethod.setLocalVariables(localVariables.toArray(new LocalVariable[localVariables.size()]));
    localVariables = null;

    // each method must start with a (dedicated) label:
    assert this.readMethod.getInstructions().isEmpty();
    traceLabel(null, InstructionType.METHODENTRY);
    assert this.readMethod.getInstructions().size() == 1
            && this.readMethod.getInstructions().get(0) instanceof LabelMarker
            && ((LabelMarker) this.readMethod.getInstructions().get(0)).isAdditionalLabel();
    this.readMethod.setMethodEntryLabel((LabelMarker) this.readMethod.getInstructions().get(0));

    // needed later:
    final LabelNode l0 = new LabelNode();
    this.instructionIterator.add(l0);

    // then, visit the instructions that were in the method before
    while (this.instructionIterator.hasNext()) {
        final AbstractInsnNode insnNode = this.instructionIterator.next();
        switch (insnNode.getType()) {
        case AbstractInsnNode.INSN:
            transformInsn((InsnNode) insnNode);
            break;
        case AbstractInsnNode.INT_INSN:
            transformIntInsn((IntInsnNode) insnNode);
            break;
        case AbstractInsnNode.VAR_INSN:
            transformVarInsn((VarInsnNode) insnNode);
            break;
        case AbstractInsnNode.TYPE_INSN:
            transformTypeInsn((TypeInsnNode) insnNode);
            break;
        case AbstractInsnNode.FIELD_INSN:
            transformFieldInsn((FieldInsnNode) insnNode);
            break;
        case AbstractInsnNode.METHOD_INSN:
            transformMethodInsn((MethodInsnNode) insnNode);
            break;
        case AbstractInsnNode.JUMP_INSN:
            transformJumpInsn((JumpInsnNode) insnNode);
            break;
        case AbstractInsnNode.LABEL:
            transformLabel((LabelNode) insnNode);
            break;
        case AbstractInsnNode.LDC_INSN:
            transformLdcInsn((LdcInsnNode) insnNode);
            break;
        case AbstractInsnNode.IINC_INSN:
            transformIincInsn((IincInsnNode) insnNode);
            break;
        case AbstractInsnNode.TABLESWITCH_INSN:
            transformTableSwitchInsn((TableSwitchInsnNode) insnNode);
            break;
        case AbstractInsnNode.LOOKUPSWITCH_INSN:
            transformLookupSwitchInsn((LookupSwitchInsnNode) insnNode);
            break;
        case AbstractInsnNode.MULTIANEWARRAY_INSN:
            transformMultiANewArrayInsn((MultiANewArrayInsnNode) insnNode);
            break;
        case AbstractInsnNode.FRAME:
            // ignore
            break;
        case AbstractInsnNode.LINE:
            // ignore
            break;
        default:
            throw new RuntimeException("Unknown instruction type " + insnNode.getType() + " ("
                    + insnNode.getClass().getSimpleName() + ")");
        }
        oldInstructions.add(insnNode.clone(labelCopies));
    }

    assert this.outstandingInitializations == 0;

    // add the (old) try-catch blocks to the readMethods
    // (can only be done down here since we use the information in the
    // labels map)
    for (final Object o : oldTryCatchblockNodes) {
        final TryCatchBlockNode tcb = (TryCatchBlockNode) o;
        this.readMethod.addTryCatchBlock(new TryCatchBlock(this.labels.get(tcb.start), this.labels.get(tcb.end),
                this.labels.get(tcb.handler), tcb.type));
    }

    final LabelNode l1 = new LabelNode();
    this.instructionIterator.add(l1);
    final int newPos = this.readMethod.getInstructions().size();
    traceLabel(null, InstructionType.METHODEXIT);
    assert this.readMethod.getInstructions().size() == newPos + 1;
    final AbstractInstruction abnormalTerminationLabel = this.readMethod.getInstructions().get(newPos);
    assert abnormalTerminationLabel instanceof LabelMarker;
    this.readMethod.setAbnormalTerminationLabel((LabelMarker) abnormalTerminationLabel);
    this.methodNode.instructions.add(new InsnNode(ATHROW));

    // add a try catch block around the method so that we can trace when this method is left
    // a thrown exception
    this.methodNode.tryCatchBlocks.add(new TryCatchBlockNode(l0, l1, l1, null));

    // now add the code that is executed if no tracing should be performed
    this.methodNode.instructions.add(noTracingLabel);
    if (this.firstLine != -1)
        this.methodNode.instructions.add(new LineNumberNode(this.firstLine, noTracingLabel));
    this.methodNode.instructions.add(new InsnNode(ACONST_NULL));
    this.methodNode.instructions.add(new VarInsnNode(ASTORE, this.tracerLocalVarIndex));
    this.methodNode.instructions.add(oldInstructions);

    // finally: create a copy of the method that gets the ThreadTracer as argument
    // this is only necessary for private methods or "<init>"
    if (this.tracer.wasRedefined(this.readMethod.getReadClass().getName())
            && (this.methodNode.access & ACC_PRIVATE) != 0) {
        final Type[] oldMethodArguments = Type.getArgumentTypes(this.methodNode.desc);
        final Type[] newMethodArguments = Arrays.copyOf(oldMethodArguments, oldMethodArguments.length + 1);
        newMethodArguments[oldMethodArguments.length] = Type.getType(ThreadTracer.class);
        final String newMethodDesc = Type.getMethodDescriptor(Type.getReturnType(this.methodNode.desc),
                newMethodArguments);
        final MethodNode newMethod = new MethodNode(this.methodNode.access, this.methodNode.name, newMethodDesc,
                this.methodNode.signature,
                (String[]) this.methodNode.exceptions.toArray(new String[this.methodNode.exceptions.size()]));
        methodIt.add(newMethod);

        int threadTracerParamPos = ((this.readMethod.getAccess() & Opcodes.ACC_STATIC) == 0 ? 1 : 0);
        for (final Type t : oldMethodArguments)
            threadTracerParamPos += t.getSize();

        final Map<LabelNode, LabelNode> newMethodLabels = LazyMap.decorate(new HashMap<LabelNode, LabelNode>(),
                new Factory() {
                    @Override
                    public Object create() {
                        return new LabelNode();
                    }
                });

        // copy the local variables information to the new method
        for (final Object o : this.methodNode.localVariables) {
            final LocalVariableNode lv = (LocalVariableNode) o;
            newMethod.localVariables.add(new LocalVariableNode(lv.name, lv.desc, lv.signature,
                    newMethodLabels.get(lv.start), newMethodLabels.get(lv.end), lv.index));
        }

        newMethod.maxLocals = this.methodNode.maxLocals;
        newMethod.maxStack = this.methodNode.maxStack;

        // copy the try-catch-blocks
        for (final Object o : this.methodNode.tryCatchBlocks) {
            final TryCatchBlockNode tcb = (TryCatchBlockNode) o;
            newMethod.tryCatchBlocks.add(new TryCatchBlockNode(newMethodLabels.get(tcb.start),
                    newMethodLabels.get(tcb.end), newMethodLabels.get(tcb.handler), tcb.type));
        }

        // skip the first 6 instructions, replace them with these:
        newMethod.instructions.add(new VarInsnNode(ALOAD, threadTracerParamPos));
        newMethod.instructions.add(new InsnNode(DUP));
        newMethod.instructions.add(new VarInsnNode(ASTORE, this.tracerLocalVarIndex));
        newMethod.instructions.add(new JumpInsnNode(IFNULL, newMethodLabels.get(noTracingLabel)));
        final Iterator<AbstractInsnNode> oldInsnIt = this.methodNode.instructions.iterator(6);
        // and add all the other instructions
        while (oldInsnIt.hasNext()) {
            final AbstractInsnNode insn = oldInsnIt.next();
            newMethod.instructions.add(insn.clone(newMethodLabels));
        }
    }

    ready();
}

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

License:Apache License

@SuppressWarnings("unchecked")
MethodNode transform(String coroutineName, boolean generateDebugCode) {
    MethodNode transformedMethod = new MethodNode();
    transformedMethod.access = ACC_PUBLIC | ACC_FINAL | (method.access & ACC_STATIC);
    transformedMethod.name = coroutineName;
    transformedMethod.desc = COROUTINE_METHOD_DESCRIPTOR;
    transformedMethod.exceptions = method.exceptions;
    final InsnList newCode = transformedMethod.instructions;
    Analyzer analyzer = new Analyzer(new BasicInterpreter() {

        @Override//from   w  w w .j av a  2 s . c  om
        public Value binaryOperation(AbstractInsnNode insn, Value value1, Value value2)
                throws AnalyzerException {
            if (insn.getOpcode() == AALOAD) {
                return new BasicValue(((BasicValue) value1).getType().getElementType());
            }
            return super.binaryOperation(insn, value1, value2);
        };

        @Override
        public Value merge(Value v, Value w) {
            if (v == NULL_VALUE) {
                BasicValue w1 = (BasicValue) w;
                if (w1.isReference()) {
                    return w1;
                }
            }
            if (w == NULL_VALUE) {
                BasicValue v1 = (BasicValue) v;
                if (v1.isReference())
                    return v1;
            }
            if (!v.equals(w)) {
                BasicValue v1 = (BasicValue) v;
                BasicValue w1 = (BasicValue) w;
                if (v1.isReference() & w1.isReference()) {
                    Class<?> c1;
                    Class<?> c2;
                    try {
                        c1 = MethodTransformer.getClass(v1);
                        c2 = MethodTransformer.getClass(w1);
                    } catch (ClassNotFoundException e) {
                        throw new CoroutineGenerationException(
                                "It was needed to load a class during transformation process but loading unexpectedly failed",
                                e);
                    }
                    if (c1.isAssignableFrom(c2)) {
                        return v;
                    }
                    if (c2.isAssignableFrom(c1)) {
                        return w;
                    }
                }
            } else {
                return v;
            }
            return BasicValue.UNINITIALIZED_VALUE;
        }

        @Override
        public Value newValue(Type type) {
            if (type != null) {
                int typeSort = type.getSort();
                switch (typeSort) {
                case Type.VOID:
                    return NULL_VALUE;
                case Type.BOOLEAN:
                case Type.CHAR:
                case Type.BYTE:
                case Type.SHORT:
                case Type.INT:
                    return BasicValue.INT_VALUE;
                case Type.FLOAT:
                    return BasicValue.FLOAT_VALUE;
                case Type.LONG:
                    return BasicValue.LONG_VALUE;
                case Type.DOUBLE:
                    return BasicValue.DOUBLE_VALUE;
                case Type.ARRAY:
                case Type.OBJECT:
                    if (type.getInternalName().equals("null")) {
                        return NULL_VALUE;
                    }
                    return new BasicValue(type);
                default:
                    throw new Error("Internal error");
                }
            }
            return BasicValue.UNINITIALIZED_VALUE;
        }
    });
    Frame[] frames;
    try {
        frames = analyzer.analyze(methodOwner, method);
    } catch (AnalyzerException e) {
        throw new CoroutineGenerationException(e);
    }
    InsnList code = method.instructions;
    final List<Integer> yields = new ArrayList<Integer>(8);
    /*
     * Copy instructions patching variable indexes and frames, remember
     * yield indexes
     */
    int ic = 0;
    Iterator<AbstractInsnNode> i = code.iterator();
    while (i.hasNext()) {
        AbstractInsnNode insn = i.next();
        switch (insn.getType()) {
        case AbstractInsnNode.FRAME:
            FrameNode frame = (FrameNode) insn.clone(labelsMap);
            // update values
            if (frame.type == F_FULL) {
                if (isStatic) {
                    frame.local.addAll(0, argsStackMapList);
                } else {
                    frame.local.addAll(1, argsStackMapList);
                }
            }
            newCode.add(frame);
            break;
        case AbstractInsnNode.IINC_INSN:
            IincInsnNode iinc = (IincInsnNode) insn.clone(labelsMap);
            iinc.var += variableIndexOffset;
            newCode.add(iinc);
            break;
        case AbstractInsnNode.INSN:
            switch (insn.getOpcode()) {
            case DRETURN:
            case FRETURN:
            case IRETURN:
            case LRETURN:
            case ARETURN:
            case RETURN:
                newCode.add(new InsnNode(POP));
                newCode.add(throwex("java/util/NoSuchElementException"));
                break;
            default:
                newCode.add(insn.clone(labelsMap));
            }
            break;
        case AbstractInsnNode.JUMP_INSN:
            if (insn.getOpcode() == JSR) {
                throw new CoroutineGenerationException("<jsr> not allowed");
            }
            JumpInsnNode jump = (JumpInsnNode) insn;
            LabelNode target = jump.label;
            if (!labelsMap.containsKey(target)) {
                labelsMap.put(target, new LabelNode());
            }
            newCode.add(jump.clone(labelsMap));
            break;
        case AbstractInsnNode.LABEL:
            if (!labelsMap.containsKey(insn)) {
                labelsMap.put((LabelNode) insn, new LabelNode());
            }
            newCode.add(insn.clone(labelsMap));
            break;
        case AbstractInsnNode.METHOD_INSN:
            if (insn.getOpcode() == INVOKESTATIC) {
                MethodInsnNode method = (MethodInsnNode) insn;
                if (method.owner.equals(COROUTINES_NAME)) {
                    String methodName = method.name;
                    if (methodName.equals("_")) {
                        /*
                         * a call to artificial CoIterator, since it is
                         * not needed after instrumentation we replace
                         * it with null. This null will be popped by
                         * corresponding ARETURN. Stack is not changed
                         */
                        newCode.add(new InsnNode(ACONST_NULL));
                        break;
                    }
                    if (methodName.equals("yield")) {
                        /*
                         * a call to yield - core of coroutine
                         * processing
                         */
                        yields.add(ic);
                    }
                }
            }
            newCode.add(insn.clone(labelsMap));
            break;
        case AbstractInsnNode.VAR_INSN:
            if (insn.getOpcode() == RET) {
                throw new CoroutineGenerationException("<ret> not allowed");
            }
            VarInsnNode var = (VarInsnNode) insn.clone(labelsMap);
            if (var.var != 0 || isStatic) {
                var.var += variableIndexOffset;
            }
            newCode.add(var);
            break;
        default:
            newCode.add(insn.clone(labelsMap));
            break;
        }
        ic += 1;
    }
    /*
     * patch yields in transformed code
     */
    final List<LabelNode> gotos = new ArrayList<LabelNode>(9);
    final Set<TryCatchBlockNode> patchedTryCatchBlocks = new HashSet<TryCatchBlockNode>();
    int yieldIndex = 0;
    i = newCode.iterator();
    while (i.hasNext()) {
        AbstractInsnNode insn = i.next();
        /*
         * track locals
         */
        int insnType = insn.getType();
        if (insnType == AbstractInsnNode.VAR_INSN) {
            int opcode = insn.getOpcode();
            if (opcode == ASTORE || opcode == DSTORE || opcode == LSTORE || opcode == ISTORE
                    || opcode == FSTORE) {
                int varIndex = ((VarInsnNode) insn).var - variableIndexOffset;
                finals[varIndex] = false;
            }
            continue;
        }
        /*
         * track line numbers
         */
        if (insnType == AbstractInsnNode.LINE) {
            lineNumber = ((LineNumberNode) insn).line;
            continue;
        }
        if (insnType != AbstractInsnNode.METHOD_INSN) {
            continue;
        }
        MethodInsnNode method = (MethodInsnNode) insn;
        if (!method.owner.equals(COROUTINES_NAME) || !method.name.equals("yield")) {
            continue;
        }
        InsnList yieldCode = new InsnList();
        int index = yields.get(yieldIndex);
        Frame f = frames[index];
        /*
         * a) operand on the top of stack is passed to the caller, we will
         * save it in 'in' parameter OR there is nothing to be passed to the
         * caller in case of yield() overload
         */
        boolean yieldWithArgument = Type.getArgumentTypes(method.desc).length != 0;
        boolean nonemptyStack;
        Type[] stackContents = null;
        int stackTop = 0;
        if (yieldWithArgument) {
            yieldCode.add(input(getStackTop(f)));
            nonemptyStack = f.getStackSize() > 1;
            stackTop = 1;
        } else {
            nonemptyStack = f.getStackSize() > 0;
        }
        /*
         * b) save remaining stack
         */
        if (nonemptyStack) {
            stackContents = getStackContents(f);
            // sanitize stack
            for (Type t : stackContents) {
                if (t == null) {
                    throw new CoroutineGenerationException(
                            "It is not possible to yield with uninitialized memory on the stack. Probably you use construct such as: new A(..,yield,..). Please move this yield call out of constructor");
                }
            }
            yieldCode.add(savestack(frame, stackContents, stackTop));
        }
        /*
         * c) save locals and state
         */
        Type[] locals = getLocals(f);
        yieldCode.add(saveLocals(locals));
        yieldCode.add(new VarInsnNode(ALOAD, frame));
        yieldCode.add(makeInt(++yieldIndex));
        yieldCode.add(new MethodInsnNode(INVOKEVIRTUAL, FRAME_NAME, "setState", "(I)V"));
        /*
         * d) jump to exit - in debug mode save line number
         */
        if (generateDebugCode) {
            yieldCode.add(new VarInsnNode(ALOAD, frame));
            yieldCode.add(makeInt(lineNumber));
            yieldCode.add(new MethodInsnNode(INVOKEVIRTUAL, FRAME_NAME, "setLineOfCode", "(I)V"));
        }
        yieldCode.add(new JumpInsnNode(GOTO, yieldLabel));
        /*
         * e) fix jump from switch statement
         */
        LabelNode jump = new LabelNode();
        gotos.add(jump);
        yieldCode.add(jump);
        yieldCode.add(emitCleanFrame());
        /*
         * f) check if exit condition occurs, load locals, restore stack and
         * stack map
         */
        yieldCode.add(new VarInsnNode(ALOAD, frame));
        yieldCode.add(new MethodInsnNode(INVOKEVIRTUAL, FRAME_NAME, "isCoroutineClosed", "()Z"));
        LabelNode continueHere = new LabelNode();
        yieldCode.add(new JumpInsnNode(IFEQ, continueHere));
        yieldCode.add(throwex(COROUTINE_EXIT_EXCEPTION));
        yieldCode.add(continueHere);
        yieldCode.add(new FrameNode(F_SAME, 0, EMPTY_LOCALS, 0, EMPTY_STACK));
        /*
         * find previous frame node, load locals then emit new frame node
         * and load rest
         */
        FrameNode prevFrame = findPreviousFrame(code.get(index));
        Type[] prevLocals;
        if (prevFrame != null) {
            Frame oldFrame = frames[code.indexOf(prevFrame)];
            prevLocals = getLocals(oldFrame);
        } else {
            prevLocals = getLocals(frames[0]);
        }
        yieldCode.add(restoreLocals(prevLocals));
        FrameNode frameNode = mergeFrames(getFrameTypes(prevLocals), null);
        if (frameNode.type != F_SAME) {
            // bug fix - when no locals are restored and the stack is empty
            // two frames are collapsed
            yieldCode.add(frameNode);
        }
        if (nonemptyStack) {
            yieldCode.add(loadstack(frame, stackContents, stackTop));
        }
        // restore temp locals in scope
        yieldCode.add(restoreLocals(diff(locals, prevLocals)));
        /*
         * push "sent" value
         */
        yieldCode.add(new VarInsnNode(ALOAD, out));
        newCode.insertBefore(method, yieldCode);
        /*
         * patch try catch blocks
         */
        List<TryCatchBlockNode> tryCatchBlocks = analyzer.getHandlers(index);
        if (tryCatchBlocks != null) {
            for (TryCatchBlockNode tryCatchBlock : tryCatchBlocks) {
                if (!patchedTryCatchBlocks.contains(tryCatchBlock)) {
                    LabelNode handler = tryCatchBlock.handler;
                    InsnList handlerPatch = new InsnList();
                    String exceptionType = tryCatchBlock.type == null ? "java/lang/Throwable"
                            : tryCatchBlock.type;
                    FrameNode catchFrame = emitCatchFrame(exceptionType);
                    handlerPatch.add(catchFrame);
                    Type[] ls = getLocals(frames[code.indexOf(handler)]);
                    handlerPatch.add(restoreLocals(ls));
                    handlerPatch.add(
                            mergeFrames(getFrameTypes(ls), new Type[] { Type.getObjectType(exceptionType) }));
                    patchedTryCatchBlocks.add(tryCatchBlock);
                    AbstractInsnNode newHandler = labelsMap.get(handler);
                    // remove "real" frame since it is not needed now
                    newCode.remove(findNextFrame(newHandler));
                    newCode.insert(newHandler, handlerPatch);
                }
            }
        }
        newCode.remove(method);
    }
    /*
     * copy local variables (wath out for indices change) and try catch
     * blocks to new method (clone)
     */
    List<TryCatchBlockNode> tryCatchBlocks = method.tryCatchBlocks;
    if (!tryCatchBlocks.isEmpty()) {
        transformedMethod.tryCatchBlocks = new ArrayList<TryCatchBlockNode>(tryCatchBlocks.size());
        for (TryCatchBlockNode tryCatchBlock : tryCatchBlocks) {
            transformedMethod.tryCatchBlocks.add(
                    new TryCatchBlockNode(labelsMap.get(tryCatchBlock.start), labelsMap.get(tryCatchBlock.end),
                            labelsMap.get(tryCatchBlock.handler), tryCatchBlock.type));
        }
    }
    if (method.localVariables != null) {
        List<LocalVariableNode> localVariables = method.localVariables;
        List<LocalVariableNode> newLocalVariables = new ArrayList<LocalVariableNode>(localVariables.size());
        for (LocalVariableNode localVariable : localVariables) {
            int newIndex = localVariable.index;
            if (newIndex != 0 || isStatic) {
                newIndex += variableIndexOffset;
            }
            newLocalVariables
                    .add(new LocalVariableNode(localVariable.name, localVariable.desc, localVariable.signature,
                            labelsMap.get(localVariable.start), labelsMap.get(localVariable.end), newIndex));
        }
        transformedMethod.localVariables = newLocalVariables;
    }
    newCode.insert(codeBefore(gotos));
    newCode.add(codeAfter());
    return transformedMethod;
}

From source file:the.bytecode.club.bytecodeviewer.searching.RegexInsnFinder.java

License:Open Source License

/**
 * Refreshes the internal instruction list when you have made changes to the
 * method./*from   w  w  w .j  a  v a  2 s  .  c  o m*/
 */
public void refresh() {
    origInstructions = cleanInsn(mn.instructions);
    final List<AbstractInsnNode> il = new ArrayList<AbstractInsnNode>();
    for (final AbstractInsnNode ain : mn.instructions.toArray())
        if (ain.opcode() >= 0) {
            il.add(ain);
        }
    instructions = il.toArray(new AbstractInsnNode[il.size()]);
    offsets = new int[instructions.length];
    insnString = "";
    for (int i = 0; i < instructions.length; i++) {
        offsets[i] = -1;
        final AbstractInsnNode ain = instructions[i];
        if (ain.opcode() >= 0) {
            if (ain.opcode() >= opcodes.length) {
                try {
                    throw new UnexpectedException("Unknown opcode encountered: " + ain.opcode());
                } catch (final UnexpectedException e) {
                    new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
                }
            }
            offsets[i] = insnString.length();
            insnString += opcodes[ain.opcode()];
            switch (ain.type()) {
            case AbstractInsnNode.INT_INSN:
                final IntInsnNode iin = (IntInsnNode) ain;
                insnString += "{" + iin.operand + "}";
                break;
            case AbstractInsnNode.LDC_INSN:
                final LdcInsnNode lin = (LdcInsnNode) ain;
                insnString += "{" + lin.cst.toString().replace("}", "\\}") + "}";
                break;
            case AbstractInsnNode.VAR_INSN:
                final VarInsnNode vin = (VarInsnNode) ain;
                insnString += "_" + vin.var;
                break;
            case AbstractInsnNode.IINC_INSN:
                final IincInsnNode iiin = (IincInsnNode) ain;
                insnString += "{" + iiin.var + "," + iiin.incr + "}";
                break;
            case AbstractInsnNode.FIELD_INSN:
                final FieldInsnNode fin = (FieldInsnNode) ain;
                insnString += "{" + fin.desc + "," + fin.owner + "," + fin.name + "}";
                break;
            case AbstractInsnNode.METHOD_INSN:
                final MethodInsnNode min = (MethodInsnNode) ain;
                insnString += "{" + min.desc + "," + min.owner + "," + min.name + "}";
                break;
            case AbstractInsnNode.TYPE_INSN:
                final TypeInsnNode tin = (TypeInsnNode) ain;
                insnString += "{" + tin.desc + "}";
                break;
            case AbstractInsnNode.MULTIANEWARRAY_INSN:
                final MultiANewArrayInsnNode manain = (MultiANewArrayInsnNode) ain;
                insnString += "{" + manain.dims + "," + manain.desc + "}";
                break;
            default:
                throw new IllegalArgumentException(String.valueOf(ain.type()));
            }
            insnString += " ";
        }
    }
}