List of usage examples for org.objectweb.asm.tree AbstractInsnNode TABLESWITCH_INSN
int TABLESWITCH_INSN
To view the source code for org.objectweb.asm.tree AbstractInsnNode TABLESWITCH_INSN.
Click Source Link
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; }