private InsnList dispatchTable(List<LabelNode> extLabels, List<LabelNode> resumptionLabels, LabelNode errorStateLabel) { InsnList il = new InsnList(); assert (!extLabels.isEmpty()); ArrayList<LabelNode> labels = new ArrayList<>(); labels.addAll(extLabels); labels.addAll(resumptionLabels); LabelNode[] labelArray = labels.toArray(new LabelNode[labels.size()]); int min = 1 - extLabels.size(); int max = resumptionLabels.size(); il.add(new VarInsnNode(ILOAD, LV_RESUME)); il.add(new TableSwitchInsnNode(min, max, errorStateLabel, labelArray)); return il; }
private void convertTableSwitchInsn(TableSwitchInsnNode insn) { StackFrame frame = getFrame(insn); if (units.containsKey(insn)) { frame.mergeIn(pop()); return; } Operand key = popImmediate(); UnitBox dflt = Jimple.v().newStmtBox(null); List<UnitBox> targets = new ArrayList<UnitBox>(insn.labels.size()); labels.put(insn.dflt, dflt); for (LabelNode ln : insn.labels) { UnitBox box = Jimple.v().newStmtBox(null); targets.add(box); labels.put(ln, box); } TableSwitchStmt tss = Jimple.v().newTableSwitchStmt(key.stackOrValue(), insn.min, insn.max, targets, dflt); key.addBox(tss.getKeyBox()); frame.in(key); frame.boxes(tss.getKeyBox()); setUnit(insn, tss); }
private void visitTableSwitchInsnNode(TableSwitchInsnNode node) { ExpressionStack stack = mState.getActiveStack(); int defaultLabel = stack.getLabelId(node.dflt.getLabel()); Map<Integer, String> labelCaseMap = new HashMap<>(); for (int i = 0; i <= node.max - node.min; i++) { int labelId = stack.getLabelId(((LabelNode) node.labels.get(i)).getLabel()); String caseKey = String.valueOf(node.min + i); labelCaseMap.put(labelId, caseKey); } labelCaseMap.put(defaultLabel, SwitchExpression.CaseExpression.DEFAULT); SwitchExpression switchExp = new SwitchExpression(node.getOpcode()); mState.moveNode(); updateSwitchWithCases(switchExp, defaultLabel, labelCaseMap); stack.push(switchExp); }
private static Set<AbstractInsnNode> findJumpTargets(final InsnList instructions) { final Set<AbstractInsnNode> jumpTargets = new HashSet<AbstractInsnNode>(); final ListIterator<AbstractInsnNode> it = instructions.iterator(); while (it.hasNext()) { final AbstractInsnNode o = it.next(); if (o instanceof JumpInsnNode) { jumpTargets.add(((JumpInsnNode) o).label); } else if (o instanceof TableSwitchInsnNode) { final TableSwitchInsnNode twn = (TableSwitchInsnNode) o; jumpTargets.add(twn.dflt); jumpTargets.addAll(twn.labels); } else if (o instanceof LookupSwitchInsnNode) { final LookupSwitchInsnNode lsn = (LookupSwitchInsnNode) o; jumpTargets.add(lsn.dflt); jumpTargets.addAll(lsn.labels); } } return jumpTargets; }
private void registerSwitchInstruction(BytecodeInstruction v) { if (!v.isSwitch()) throw new IllegalArgumentException("expect a switch instruction"); LabelNode defaultLabel = null; switch (v.getASMNode().getOpcode()) { case Opcodes.TABLESWITCH: TableSwitchInsnNode tableSwitchNode = (TableSwitchInsnNode) v.getASMNode(); registerTableSwitchCases(v, tableSwitchNode); defaultLabel = tableSwitchNode.dflt; break; case Opcodes.LOOKUPSWITCH: LookupSwitchInsnNode lookupSwitchNode = (LookupSwitchInsnNode) v.getASMNode(); registerLookupSwitchCases(v, lookupSwitchNode); defaultLabel = lookupSwitchNode.dflt; break; default: throw new IllegalStateException( "expect ASMNode of a switch to either be a LOOKUP- or TABLESWITCH"); } registerDefaultCase(v, defaultLabel); }
/** * <p> * This method finds Switch block in a method and processes it * </p>. * * @param scanStartIndex Start index for the scan * @param scanEndIndex End index for the scan */ private void instrumentswitchBlock(int scanStartIndex, int scanEndIndex) { for (scanIndexForswitch = scanStartIndex; scanIndexForswitch <= scanEndIndex; scanIndexForswitch++) { AbstractInsnNode currentInsnNode = insnArr[scanIndexForswitch]; if (currentInsnNode instanceof TableSwitchInsnNode && Opcodes.TABLESWITCH == currentInsnNode.getOpcode()) { processTableSwitchBlock((TableSwitchInsnNode) currentInsnNode); } else if (currentInsnNode instanceof LookupSwitchInsnNode && Opcodes.LOOKUPSWITCH == currentInsnNode.getOpcode()) { processLookupSwitchBlock((LookupSwitchInsnNode) currentInsnNode); } } }
/** * <p> * This method Handled the Switch block of TableSwitchInsnNode type in a * method * </p>. * * @param currentTableSwithInsn Type of switch block */ private void processTableSwitchBlock( TableSwitchInsnNode currentTableSwithInsn) { LabelNode currentLabel = currentTableSwithInsn.dflt; int switchStartIndex = CollectionUtil.getObjectIndexInArray(insnArr, currentTableSwithInsn); int switchTargetIndex = CollectionUtil.getObjectIndexInArray(insnArr, currentLabel); if (switchTargetIndex > switchStartIndex) { LOGGER.debug("switch block ended at: " + switchTargetIndex); switchCount++; AbstractInsnNode[] ainSwitchBlock = new AbstractInsnNode[] { currentTableSwithInsn.getPrevious(), currentLabel }; Integer[] lineNumbers = getLineNumbersForSwitchBlock(ainSwitchBlock); InsnList[] il = getInsnForswitchBlock(switchCount, lineNumbers); addInsnForswitchBlock(il, ainSwitchBlock); scanIndexForswitch = switchTargetIndex; handleTableSwitchCases(currentTableSwithInsn); } }
private static Set<AbstractInsnNode> findJumpTargets(final InsnList instructions) { final Set<AbstractInsnNode> jumpTargets = new HashSet<>(); final ListIterator<AbstractInsnNode> it = instructions.iterator(); while (it.hasNext()) { final AbstractInsnNode o = it.next(); if (o instanceof JumpInsnNode) { jumpTargets.add(((JumpInsnNode) o).label); } else if (o instanceof TableSwitchInsnNode) { final TableSwitchInsnNode twn = (TableSwitchInsnNode) o; jumpTargets.add(twn.dflt); jumpTargets.addAll(twn.labels); } else if (o instanceof LookupSwitchInsnNode) { final LookupSwitchInsnNode lsn = (LookupSwitchInsnNode) o; jumpTargets.add(lsn.dflt); jumpTargets.addAll(lsn.labels); } } return jumpTargets; }
@Override public void handle(AbstractInsnNode node) throws IncorrectNodeException { super.handle(node); LOG.debug(logNode(node)); if (node instanceof TableSwitchInsnNode) { visitTableSwitchInsnNode((TableSwitchInsnNode) node); } else if (node instanceof LookupSwitchInsnNode) { visitLookupSwitchInsnNode((LookupSwitchInsnNode) node); } else { throw new IncorrectNodeException("Incorrect node type, expected switch but was " + node.getClass().getSimpleName()); } }
private void registerTableSwitchCases(BytecodeInstruction v, TableSwitchInsnNode tableSwitchNode) { int num = 0; for (int i = tableSwitchNode.min; i <= tableSwitchNode.max; i++) { LabelNode targetLabel = (LabelNode) tableSwitchNode.labels.get(num); Branch switchBranch = createSwitchCaseBranch(v, i, targetLabel); if (!switchBranch.isSwitchCaseBranch() || !switchBranch.isActualCase()) throw new IllegalStateException( "expect created branch to be an actual case branch of a switch"); num++; } }
/** * <p> * addInstrumentationForDefaultTableswitchCase * </p> * * @param v * a {@link org.evosuite.graphs.cfg.BytecodeInstruction} object. * @param instrumentation * a {@link org.objectweb.asm.tree.InsnList} object. */ protected void addInstrumentationForDefaultTableswitchCase(BytecodeInstruction v, InsnList instrumentation) { if (!v.isTableSwitch()) throw new IllegalArgumentException("tableswitch instruction expected"); // setup instructions TableSwitchInsnNode toInstrument = (TableSwitchInsnNode) v.getASMNode(); LabelNode caseLabel = new LabelNode(); LabelNode defaultLabel = new LabelNode(); LabelNode endLabel = new LabelNode(); int keySize = (toInstrument.max - toInstrument.min) + 1; LabelNode[] caseLabels = new LabelNode[keySize]; for (int i = 0; i < keySize; i++) caseLabels[i] = caseLabel; TableSwitchInsnNode mySwitch = new TableSwitchInsnNode(toInstrument.min, toInstrument.max, defaultLabel, caseLabels); // add instrumentation addDefaultCaseInstrumentation(v, instrumentation, mySwitch, defaultLabel, caseLabel, endLabel); }
/** * Generates instructions for a switch table. This does not automatically generate jumps at the end of each default/case statement. It's * your responsibility to either add the relevant jumps, throws, or returns at each default/case statement, otherwise the code will * just fall through (which is likely not what you want). * @param indexInsnList instructions to calculate the index -- must leave an int on the stack * @param defaultInsnList instructions to execute on default statement -- must leave the stack unchanged * @param caseStartIdx the number which the case statements start at * @param caseInsnLists instructions to execute on each case statement -- must leave the stack unchanged * @return instructions for a table switch * @throws NullPointerException if any argument is {@code null} or contains {@code null} * @throws IllegalArgumentException if any numeric argument is {@code < 0}, or if {@code caseInsnLists} is empty */ public static InsnList tableSwitch(InsnList indexInsnList, InsnList defaultInsnList, int caseStartIdx, InsnList... caseInsnLists) { Validate.notNull(defaultInsnList); Validate.notNull(indexInsnList); Validate.isTrue(caseStartIdx >= 0); Validate.notNull(caseInsnLists); Validate.noNullElements(caseInsnLists); Validate.isTrue(caseInsnLists.length > 0); InsnList ret = new InsnList(); LabelNode defaultLabelNode = new LabelNode(); LabelNode[] caseLabelNodes = new LabelNode[caseInsnLists.length]; for (int i = 0; i < caseInsnLists.length; i++) { caseLabelNodes[i] = new LabelNode(); } ret.add(indexInsnList); ret.add(new TableSwitchInsnNode(caseStartIdx, caseStartIdx + caseInsnLists.length - 1, defaultLabelNode, caseLabelNodes)); for (int i = 0; i < caseInsnLists.length; i++) { LabelNode caseLabelNode = caseLabelNodes[i]; InsnList caseInsnList = caseInsnLists[i]; if (caseInsnList != null) { ret.add(caseLabelNode); ret.add(caseInsnList); } } if (defaultInsnList != null) { ret.add(defaultLabelNode); ret.add(defaultInsnList); } return ret; }
public CodeBlock visitTableSwitchInsn(final int min, final int max, final LabelNode defaultHandler, final LabelNode[] handlers) { instructionList.add(new TableSwitchInsnNode(min, max, defaultHandler, handlers)); return this; }
public CodeBlock tableswitch(final int min, final int max, final LabelNode defaultLabel, final LabelNode[] cases) { instructionList.add(new TableSwitchInsnNode(min, max, defaultLabel, cases)); return this; }
public static boolean isBranch (final AbstractInsnNode insn) { final int opcode = insn.getOpcode(); return insn instanceof JumpInsnNode || insn instanceof LookupSwitchInsnNode || insn instanceof TableSwitchInsnNode || opcode == Opcodes.ATHROW || opcode == Opcodes.RET || (opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN); }
private void interpret(TableSwitchInsnNode insn, FrameState frame, BBInfo block) { assert insn.getOpcode() == Opcodes.TABLESWITCH; ConstantFactory cf = module.constants(); SwitchInst inst = new SwitchInst(frame.stack.pop(), blockByInsn(insn.dflt).block); for (int i = insn.min; i <= insn.max; ++i) inst.put(cf.getConstant(i), blockByInsn(insn.labels.get(i-insn.min)).block); block.block.instructions().add(inst); }
@SuppressWarnings("unchecked") private void transformTableSwitchInsn(final TableSwitchInsnNode insn) { assert insn.min + insn.labels.size() - 1 == insn.max; final TableSwitchInstruction instr = new TableSwitchInstruction(this.readMethod, this.currentLine, insn.min, insn.max, null, null); this.tableSwitchInstructions.put(instr, new Pair<LabelNode, List<LabelNode>>(insn.dflt, insn.labels)); registerInstruction(instr, InstructionType.UNSAFE); }
private void updateState(AbstractInsnNode insn) { switch (insn.getType()) { case AbstractInsnNode.INSN: updateState((InsnNode) insn); break; case AbstractInsnNode.INT_INSN: updateState((IntInsnNode) insn); break; case AbstractInsnNode.VAR_INSN: updateState((VarInsnNode) insn); break; case AbstractInsnNode.TYPE_INSN: updateState((TypeInsnNode) insn); break; case AbstractInsnNode.FIELD_INSN: updateState((FieldInsnNode) insn); break; case AbstractInsnNode.METHOD_INSN: updateState((MethodInsnNode) insn); break; case AbstractInsnNode.INVOKE_DYNAMIC_INSN: updateState((InvokeDynamicInsnNode) insn); break; case AbstractInsnNode.JUMP_INSN: updateState((JumpInsnNode) insn); break; case AbstractInsnNode.LABEL: updateState((LabelNode) insn); break; case AbstractInsnNode.LDC_INSN: updateState((LdcInsnNode) insn); break; case AbstractInsnNode.IINC_INSN: updateState((IincInsnNode) insn); break; case AbstractInsnNode.TABLESWITCH_INSN: updateState((TableSwitchInsnNode) insn); break; case AbstractInsnNode.LOOKUPSWITCH_INSN: updateState((LookupSwitchInsnNode) insn); break; case AbstractInsnNode.MULTIANEWARRAY_INSN: updateState((MultiANewArrayInsnNode) insn); break; case AbstractInsnNode.LINE: updateState((LineNumberNode) insn); break; default: throw new Unreachable("Unexpected instruction " + insn); } }
private void updateState(TableSwitchInsnNode insn) { state.pop(); }
private void build(AbstractInsnNode insn, IRBuilder builder) { switch (insn.getType()) { case AbstractInsnNode.INSN: build((InsnNode) insn, builder); break; case AbstractInsnNode.INT_INSN: build((IntInsnNode) insn, builder); break; case AbstractInsnNode.VAR_INSN: build((VarInsnNode) insn, builder); break; case AbstractInsnNode.TYPE_INSN: build((TypeInsnNode) insn, builder); break; case AbstractInsnNode.FIELD_INSN: build((FieldInsnNode) insn, builder); break; case AbstractInsnNode.METHOD_INSN: build((MethodInsnNode) insn, builder); break; case AbstractInsnNode.INVOKE_DYNAMIC_INSN: build((InvokeDynamicInsnNode) insn, builder); break; case AbstractInsnNode.JUMP_INSN: build((JumpInsnNode) insn, builder); break; case AbstractInsnNode.LABEL: build((LabelNode) insn, builder); break; case AbstractInsnNode.LDC_INSN: build((LdcInsnNode) insn, builder); break; case AbstractInsnNode.IINC_INSN: build((IincInsnNode) insn, builder); break; case AbstractInsnNode.TABLESWITCH_INSN: build((TableSwitchInsnNode) insn, builder); break; case AbstractInsnNode.LOOKUPSWITCH_INSN: build((LookupSwitchInsnNode) insn, builder); break; case AbstractInsnNode.MULTIANEWARRAY_INSN: build((MultiANewArrayInsnNode) insn, builder); break; case AbstractInsnNode.LINE: build((LineNumberNode) insn, builder); break; default: throw new Unreachable("Unexpected instruction " + insn); } }
private void build(TableSwitchInsnNode insn, IRBuilder builder) { processLocalVariablesAtControlEdge(insn, builder); buildSwitch(insn.dflt, insn.labels, new int[]{insn.min}, builder); }
@Override public boolean matches(ClassMethod method) { return method.count(insn -> insn instanceof JumpInsnNode || insn instanceof TableSwitchInsnNode || insn instanceof LookupSwitchInsnNode) == 0; }
@Override public final void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { TableSwitchInsnNode node = new TableSwitchInsnNode(min, max, getLabelNode(dflt), getLabelNodes(labels)); instructions.add(node); addFrame(node); }
public static TreeSize getTreeSize(AbstractInsnNode ain) { int c = 0, p = 0; if (ain instanceof InsnNode || ain instanceof IntInsnNode || ain instanceof VarInsnNode || ain instanceof JumpInsnNode || ain instanceof TableSwitchInsnNode || ain instanceof LookupSwitchInsnNode) { c = CDS[ain.opcode()]; p = PDS[ain.opcode()]; } else if (ain instanceof FieldInsnNode) { FieldInsnNode fin = (FieldInsnNode) ain; char d = fin.desc.charAt(0); switch (fin.opcode()) { case GETFIELD: { c = 1; p = d == 'D' || d == 'J' ? 2 : 1; break; } case GETSTATIC: { c = 0; p = d == 'D' || d == 'J' ? 2 : 1; break; } case PUTFIELD: { c = d == 'D' || d == 'J' ? 3 : 2; p = 0; break; } case PUTSTATIC: { c = d == 'D' || d == 'J' ? 2 : 1; p = 0; break; } default: { c = 0; p = 0; break; } } } else if (ain instanceof MethodInsnNode) { MethodInsnNode min = (MethodInsnNode) ain; int as = Type.getArgumentsAndReturnSizes(min.desc); c = (as >> 2) - (min.opcode() == INVOKEDYNAMIC || min.opcode() == INVOKESTATIC ? 1 : 0); p = as & 0x03; } else if (ain instanceof LdcInsnNode) { Object cst = ((LdcInsnNode) ain).cst; p = cst instanceof Double || cst instanceof Long ? 2 : 1; } else if (ain instanceof MultiANewArrayInsnNode) { c = ((MultiANewArrayInsnNode) ain).dims; p = 1; } return new TreeSize(c, p); }
public static boolean instructionsEqual(AbstractInsnNode insn1, AbstractInsnNode insn2) { if (insn1 == insn2) { return true; } if (insn1 == null || insn2 == null || insn1.type() != insn2.type() || insn1.opcode() != insn2.opcode()) { return false; } int size; switch (insn1.type()) { case INSN: return true; case INT_INSN: IntInsnNode iin1 = (IntInsnNode) insn1, iin2 = (IntInsnNode) insn2; return iin1.operand == iin2.operand; case VAR_INSN: VarInsnNode vin1 = (VarInsnNode) insn1, vin2 = (VarInsnNode) insn2; return vin1.var == vin2.var; case TYPE_INSN: TypeInsnNode tin1 = (TypeInsnNode) insn1, tin2 = (TypeInsnNode) insn2; return tin1.desc.equals(tin2.desc); case FIELD_INSN: FieldInsnNode fin1 = (FieldInsnNode) insn1, fin2 = (FieldInsnNode) insn2; return fin1.desc.equals(fin2.desc) && fin1.name.equals(fin2.name) && fin1.owner.equals(fin2.owner); case METHOD_INSN: MethodInsnNode min1 = (MethodInsnNode) insn1, min2 = (MethodInsnNode) insn2; return min1.desc.equals(min2.desc) && min1.name.equals(min2.name) && min1.owner.equals(min2.owner); case INVOKE_DYNAMIC_INSN: InvokeDynamicInsnNode idin1 = (InvokeDynamicInsnNode) insn1, idin2 = (InvokeDynamicInsnNode) insn2; return idin1.bsm.equals(idin2.bsm) && Arrays.equals(idin1.bsmArgs, idin2.bsmArgs) && idin1.desc.equals(idin2.desc) && idin1.name.equals(idin2.name); case JUMP_INSN: JumpInsnNode jin1 = (JumpInsnNode) insn1, jin2 = (JumpInsnNode) insn2; return instructionsEqual(jin1.label, jin2.label); case LABEL: Label label1 = ((LabelNode) insn1).getLabel(), label2 = ((LabelNode) insn2).getLabel(); return label1 == null ? label2 == null : label1.info == null ? label2.info == null : label1.info.equals(label2.info); case LDC_INSN: LdcInsnNode lin1 = (LdcInsnNode) insn1, lin2 = (LdcInsnNode) insn2; return lin1.cst.equals(lin2.cst); case IINC_INSN: IincInsnNode iiin1 = (IincInsnNode) insn1, iiin2 = (IincInsnNode) insn2; return iiin1.incr == iiin2.incr && iiin1.var == iiin2.var; case TABLESWITCH_INSN: TableSwitchInsnNode tsin1 = (TableSwitchInsnNode) insn1, tsin2 = (TableSwitchInsnNode) insn2; size = tsin1.labels.size(); if (size != tsin2.labels.size()) { return false; } for (int i = 0; i < size; i++) { if (!instructionsEqual(tsin1.labels.get(i), tsin2.labels.get(i))) { return false; } } return instructionsEqual(tsin1.dflt, tsin2.dflt) && tsin1.max == tsin2.max && tsin1.min == tsin2.min; case LOOKUPSWITCH_INSN: LookupSwitchInsnNode lsin1 = (LookupSwitchInsnNode) insn1, lsin2 = (LookupSwitchInsnNode) insn2; size = lsin1.labels.size(); if (size != lsin2.labels.size()) { return false; } for (int i = 0; i < size; i++) { if (!instructionsEqual(lsin1.labels.get(i), lsin2.labels.get(i))) { return false; } } return instructionsEqual(lsin1.dflt, lsin2.dflt) && lsin1.keys.equals(lsin2.keys); case MULTIANEWARRAY_INSN: MultiANewArrayInsnNode manain1 = (MultiANewArrayInsnNode) insn1, manain2 = (MultiANewArrayInsnNode) insn2; return manain1.desc.equals(manain2.desc) && manain1.dims == manain2.dims; case FRAME: FrameNode fn1 = (FrameNode) insn1, fn2 = (FrameNode) insn2; return fn1.local.equals(fn2.local) && fn1.stack.equals(fn2.stack); case LINE: LineNumberNode lnn1 = (LineNumberNode) insn1, lnn2 = (LineNumberNode) insn2; return lnn1.line == lnn2.line && instructionsEqual(lnn1.start, lnn2.start); } return false; }
public TableSwitchInstruction(MethodElement method, TableSwitchInsnNode node) { super(method, node); }
/** * <p> * This method Handled the Switch cases of TableSwitchInsnNode type in a * method * </p>. * * @param currentTableSwithInsn Type of switch block */ @SuppressWarnings("rawtypes") private void handleTableSwitchCases( TableSwitchInsnNode currentTableSwithInsn) { List caseList = currentTableSwithInsn.labels; LabelNode currentLabel = currentTableSwithInsn.dflt; int min = currentTableSwithInsn.min; int max = currentTableSwithInsn.max; List<Integer> caseIndex = new ArrayList<Integer>(); for (int cases = min, i = 0; cases <= max; cases++, i++) { if (caseList.get(i) != currentLabel) { caseIndex.add(cases); } } int totalcaselogs = caseIndex.size() * 2; String[] logMsgs = new String[totalcaselogs]; int[] caseValues = new int[totalcaselogs]; AbstractInsnNode abstractCaseInsnNode[] = new AbstractInsnNode[totalcaselogs]; int index = 0; for (int i = 0; i < caseIndex.size(); i++) { int caseValue = caseIndex.get(i); AbstractInsnNode currentNode = (AbstractInsnNode) caseList.get(i); int j = i; while (currentNode.equals(currentLabel)) { currentNode = (LabelNode) caseList.get((j++)); } abstractCaseInsnNode[index] = currentNode; LabelNode nextNode = null; if (caseIndex.size() != (i + 1)) { caseIndex.get(i + 1); int k = i; LabelNode tempNextNode = (LabelNode) caseList.get(i + 1); while (tempNextNode.equals(currentLabel)) { tempNextNode = (LabelNode) caseList.get((k++) + 1); } nextNode = tempNextNode; } else { nextNode = currentLabel; } caseValues[index] = caseValue; caseValues[index + 1] = caseValue; if (nextNode.getPrevious() instanceof JumpInsnNode) { abstractCaseInsnNode[index + 1] = nextNode.getPrevious() .getPrevious(); } else { abstractCaseInsnNode[index + 1] = nextNode.getPrevious(); } logMsgs[index] = InstrumentationMessageLoader .getMessage(MessageConstants.MSG_IN_SWITCHCASE); logMsgs[index + 1] = InstrumentationMessageLoader .getMessage(MessageConstants.MSG_OUT_SWITCHCASE); index += 2; } Integer[] lineNumbers = getLineNumbersForSwitchCase(abstractCaseInsnNode); InsnList[] il = getInsnForswitchCaseBlock(logMsgs, caseValues, lineNumbers); addInsnForswitchBlock(il, abstractCaseInsnNode); }
@Override public void visit(final BranchStatement object) { // Generated Bytecode // // <index> - Evaluate the <index> expression. // <conversion> - Unbox or auto-widen the index, if needed. // TABLESWITCH label[0] , ... , label[n] - Generate a jump-table. // //////////////////////////////////////////////////////////////////////////////////////// /** * Embed the line number in the bytecode for debugging purposes. */ Utils.addLineNumber(code, object); /** * Before we can generate any bytecode, we must convert the labels to ASM labels. */ final int max = object.getLabels().size() - 1; final LabelNode[] labels = new LabelNode[max + 1]; for (int i = 0; i < labels.length; i++) { labels[i] = function.labels.nodeOf(object.getLabels().get(i).getName()); } final LabelNode dflt = function.labels.nodeOf(object.getDefaultLabel().getName()); /** * Now we can perform the actual code generation. */ object.getIndex().accept(this); convert(program.typesystem.utils.PRIMITIVE_INT, object.getIndex()); /** * If only the default label is present, then then a simple goto must be generated. * Otherwise, a verifier error may result at runtime. */ if (labels.length != 0) { code.add(new TableSwitchInsnNode(0, max, dflt, labels)); } else { code.add(new JumpInsnNode(Opcodes.GOTO, dflt)); } }
private void buildInstructions(BBInfo block) { FrameState frame = block.entryState.copy(); for (int i = block.start; i < block.end; ++i) { AbstractInsnNode insn = methodNode.instructions.get(i); if (insn.getOpcode() == -1) continue;//pseudo-instruction node if (insn instanceof FieldInsnNode) interpret((FieldInsnNode)insn, frame, block); else if (insn instanceof IincInsnNode) interpret((IincInsnNode)insn, frame, block); else if (insn instanceof InsnNode) interpret((InsnNode)insn, frame, block); else if (insn instanceof IntInsnNode) interpret((IntInsnNode)insn, frame, block); else if (insn instanceof InvokeDynamicInsnNode) interpret((InvokeDynamicInsnNode)insn, frame, block); else if (insn instanceof JumpInsnNode) interpret((JumpInsnNode)insn, frame, block); else if (insn instanceof LdcInsnNode) interpret((LdcInsnNode)insn, frame, block); else if (insn instanceof LookupSwitchInsnNode) interpret((LookupSwitchInsnNode)insn, frame, block); else if (insn instanceof MethodInsnNode) interpret((MethodInsnNode)insn, frame, block); else if (insn instanceof MultiANewArrayInsnNode) interpret((MultiANewArrayInsnNode)insn, frame, block); else if (insn instanceof TableSwitchInsnNode) interpret((TableSwitchInsnNode)insn, frame, block); else if (insn instanceof TypeInsnNode) interpret((TypeInsnNode)insn, frame, block); else if (insn instanceof VarInsnNode) interpret((VarInsnNode)insn, frame, block); } //If the block doesn't have a TerminatorInst, add a JumpInst to the //fallthrough block. (This occurs when blocks begin due to being a //jump target rather than due to a terminator opcode.) if (block.block.getTerminator() == null) block.block.instructions().add(new JumpInst(blocks.get(blocks.indexOf(block)+1).block)); for (BasicBlock b : block.block.successors()) for (BBInfo bi : blocks) if (bi.block == b) { merge(block, frame, bi); break; } }
/** * <p> * isTableSwitch * </p> * * @return a boolean. */ public boolean isTableSwitch() { return (asmNode instanceof TableSwitchInsnNode); }