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

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

Introduction

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

Prototype

int TABLESWITCH_INSN

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

Click Source Link

Document

The type of TableSwitchInsnNode 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  .j  a v  a 2s. 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:pxb.android.dex2jar.optimize.B.java

License:Apache License

private void linkBlocks() {
    for (int i = 0; i < blocks.size(); i++) {
        Block block = blocks.get(i);//from  w w w  .j  ava2  s . co m
        AbstractInsnNode node = block.last.getPrevious();
        switch (node.getType()) {
        case AbstractInsnNode.JUMP_INSN: {
            JumpInsnNode jump = (JumpInsnNode) node;
            link(block, blockMaps.get(jump.label.getLabel()));
            if (jump.getOpcode() != GOTO) {
                link(block, blocks.get(i + 1));
            }
            break;
        }
        case AbstractInsnNode.LOOKUPSWITCH_INSN: {
            LookupSwitchInsnNode lsin = (LookupSwitchInsnNode) node;
            link(block, blockMaps.get(lsin.dflt.getLabel()));
            for (Object l : lsin.labels) {
                LabelNode label = (LabelNode) l;
                link(block, blockMaps.get(label.getLabel()));
            }
            break;
        }
        case AbstractInsnNode.TABLESWITCH_INSN: {
            TableSwitchInsnNode tsin = (TableSwitchInsnNode) node;
            link(block, blockMaps.get(tsin.dflt.getLabel()));
            for (Object l : tsin.labels) {
                LabelNode label = (LabelNode) l;
                link(block, blockMaps.get(label.getLabel()));
            }
            break;
        }
        default: {
            int insnOpcode = node.getOpcode();
            if (insnOpcode != ATHROW && (insnOpcode < IRETURN || insnOpcode > RETURN)) {
                link(block, blocks.get(i + 1));
            }
            break;
        }
        }
    }
}

From source file:pxb.android.dex2jar.optimize.D.java

License:Apache License

private void cut(MethodNode method) {
    InsnList insns = method.instructions;
    method.instructions = null;/*from ww  w  .j  av a2  s . co m*/
    {
        AbstractInsnNode p = insns.getFirst();
        if (!(p instanceof LabelNode)) {
            insns.insertBefore(p, new LabelNode());
        }
        AbstractInsnNode q = insns.getLast();
        if (!(q instanceof LabelNode)) {
            insns.insert(q, new LabelNode());
        }
    }
    @SuppressWarnings("serial")
    Map<LabelNode, LabelNode> cloneMap = new HashMap<LabelNode, LabelNode>() {
        public LabelNode get(Object key) {

            LabelNode l = super.get(key);
            if (l == null) {
                l = new LabelNode();
                put((LabelNode) key, l);
            }
            return l;
        }
    };
    Map<LabelNode, Block> preBlockMap = new HashMap<LabelNode, Block>();
    int i = 0;
    LabelNode label = null;
    Block block = null;
    List<AbstractInsnNode> currentInsnList = null;
    for (AbstractInsnNode p = insns.getFirst(); p != null; p = p.getNext()) {
        final AbstractInsnNode cp = p.clone(cloneMap);
        switch (cp.getType()) {
        case AbstractInsnNode.LABEL: {
            if (label != null) {
                block = new Block(i++, label);
                block.insns = currentInsnList;
                block.next = (LabelNode) cp;
                addToMap(block);
            }
            currentInsnList = new ArrayList<AbstractInsnNode>();
            label = (LabelNode) cp;
            preBlockMap.put(label, block);
            break;
        }
        case AbstractInsnNode.JUMP_INSN:
        case AbstractInsnNode.LOOKUPSWITCH_INSN:
        case AbstractInsnNode.TABLESWITCH_INSN: {
            if (cp.getOpcode() == GOTO) {
                block = new Block(i++, label);
                block.next = (LabelNode) ((JumpInsnNode) cp).label;
            } else {//
                block = new BranchBlock(i++, label, cp);
                block.next = (LabelNode) getNextLabelNode(p, insns).clone(cloneMap);
            }
            block.insns = currentInsnList;
            addToMap(block);
            currentInsnList = null;
            label = null;
            break;
        }
        case AbstractInsnNode.FRAME:
        case AbstractInsnNode.LINE:
            // ignore
            break;
        default:
            switch (cp.getOpcode()) {
            case IRETURN:
            case LRETURN:
            case FRETURN:
            case DRETURN:
            case ARETURN:
            case RETURN:
            case ATHROW:
                block = new EndBlock(i++, label, cp);
                block.next = null;
                getNextLabelNode(p, insns);
                block.insns = currentInsnList;
                addToMap(block);
                currentInsnList = null;
                label = null;
                break;
            default:
                currentInsnList.add(cp);
            }

        }
    }

    for (Iterator<?> it = method.tryCatchBlocks.iterator(); it.hasNext();) {
        TryCatchBlockNode tcn = (TryCatchBlockNode) it.next();

        Block s = map.get((LabelNode) tcn.start.clone(cloneMap));
        Block e = map.get((LabelNode) tcn.end.clone(cloneMap));
        Block handler = map.get(tcn.handler.clone(cloneMap));
        TcbK key = new TcbK(s, e);

        Map<Block, String> handlers = tcbs.get(key);
        if (handlers == null) {
            handlers = new TreeMap<Block, String>(new Comparator<Block>() {
                @Override
                public int compare(Block o1, Block o2) {
                    return o1.id - o2.id;
                }
            });
            tcbs.put(key, handlers);
        }
        handlers.put(handler, tcn.type);
        tcn.start = s.label;
        tcn.end = e.label;
        tcn.handler = handler.label;
    }
}

From source file:pxb.android.dex2jar.optimize.D.java

License:Apache License

private void doRebuild(InsnList insnList, Stack<Block> toWriteBlock, List<LabelNode> visited) {
    while (!toWriteBlock.empty()) {
        Block b = toWriteBlock.pop();//from w w  w.  ja  v  a 2s  .c o  m
        if (visited.contains(b.label)) {
            continue;
        }
        visited.add(b.label);
        insnList.add(b.label);
        for (AbstractInsnNode p : b.insns) {
            insnList.add(p);
        }
        if (b instanceof BranchBlock) {
            BranchBlock bb = (BranchBlock) b;
            switch (bb.branchInsn.getType()) {
            case AbstractInsnNode.JUMP_INSN:
                JumpInsnNode jump = (JumpInsnNode) bb.branchInsn;
                insnList.add(jump);
                toWriteBlock.push(map.get(jump.label));
                if (visited.contains(bb.next)) {
                    insnList.add(new JumpInsnNode(GOTO, bb.next));
                } else {
                    toWriteBlock.push(map.get(bb.next));
                }
                continue;
            case AbstractInsnNode.LOOKUPSWITCH_INSN:
            case AbstractInsnNode.TABLESWITCH_INSN: {
                AbstractInsnNode ts = bb.branchInsn;
                LabelNode dfltLabel = ts.getType() == AbstractInsnNode.LOOKUPSWITCH_INSN
                        ? ((LookupSwitchInsnNode) ts).dflt
                        : ((TableSwitchInsnNode) ts).dflt;
                @SuppressWarnings("unchecked")
                List<LabelNode> labels = ts.getType() == AbstractInsnNode.LOOKUPSWITCH_INSN
                        ? ((LookupSwitchInsnNode) ts).labels
                        : ((TableSwitchInsnNode) ts).labels;

                insnList.add(ts);
                toWriteBlock.push(map.get(dfltLabel));
                List<LabelNode> cLables = new ArrayList<LabelNode>(labels);
                Collections.reverse(cLables);
                for (LabelNode labelNode : cLables) {
                    toWriteBlock.push(map.get(labelNode));
                }

                continue;
            }
            }
        } else {
            if (b instanceof EndBlock) {
                EndBlock eb = (EndBlock) b;
                insnList.add(eb.endInsn);
            }
            if (b.next != null) {
                if (visited.contains(b.next)) {
                    insnList.add(new JumpInsnNode(GOTO, b.next));
                } else {
                    toWriteBlock.push(map.get(b.next));
                }
            }
        }
    }
}

From source file:pxb.android.dex2jar.optimize.Util.java

License:Apache License

public static boolean needBreak(AbstractInsnNode ins) {
    switch (ins.getType()) {
    case AbstractInsnNode.JUMP_INSN:
    case AbstractInsnNode.LOOKUPSWITCH_INSN:
    case AbstractInsnNode.TABLESWITCH_INSN:
    case AbstractInsnNode.LABEL:
        return true;
    }/*  w ww  .j a  va2  s.  co m*/
    return false;
}

From source file:v6.java.preverifier.MethodRewriter.java

License:Open Source License

/**
 * Return the target labels used in generation of the stack map attribute.
 * //from  ww  w.  ja  va2  s. c  o  m
 * @return
 */
private Set findTargetLabels() {
    Set targetLabels = new HashSet();

    Iterator insns = updatedMethod.instructions.iterator();
    while (insns.hasNext()) {
        AbstractInsnNode insnNode = (AbstractInsnNode) insns.next();
        switch (insnNode.getType()) {
        case AbstractInsnNode.JUMP_INSN:
            JumpInsnNode jumpInsnNode = (JumpInsnNode) insnNode;
            targetLabels.add(jumpInsnNode.label);
            break;

        case AbstractInsnNode.LOOKUPSWITCH_INSN: {
            LookupSwitchInsnNode lookupSwitchNode = (LookupSwitchInsnNode) insnNode;
            Iterator labels = lookupSwitchNode.labels.iterator();
            while (labels.hasNext()) {
                Label label = (Label) labels.next();
                targetLabels.add(label);
            }
            targetLabels.add(lookupSwitchNode.dflt);
        }
            break;

        case AbstractInsnNode.TABLESWITCH_INSN: {
            TableSwitchInsnNode tableSwitchNode = (TableSwitchInsnNode) insnNode;
            Iterator labels = tableSwitchNode.labels.iterator();
            while (labels.hasNext()) {
                Label label = (Label) labels.next();
                targetLabels.add(label);
            }
            targetLabels.add(tableSwitchNode.dflt);
        }
            break;
        }
    }

    Iterator blocks = updatedMethod.tryCatchBlocks.iterator();
    while (blocks.hasNext()) {
        TryCatchBlockNode tryCatchBlock = (TryCatchBlockNode) blocks.next();
        targetLabels.add(tryCatchBlock.handler);
    }

    return targetLabels;
}