public static InsnList getImportantList(InsnList list) { if (list.size() == 0) { return list; } HashMap<LabelNode, LabelNode> labels = new HashMap<>(); for (AbstractInsnNode insn = list.getFirst(); insn != null; insn = insn.getNext()) { if (insn instanceof LabelNode) { labels.put((LabelNode) insn, (LabelNode) insn); } } InsnList importantNodeList = new InsnList(); for (AbstractInsnNode insn = list.getFirst(); insn != null; insn = insn.getNext()) { if (insn instanceof LabelNode || insn instanceof LineNumberNode) { continue; } importantNodeList.add(insn.clone(labels)); } return importantNodeList; }
@Override public void run() { try { ListIterator<AbstractInsnNode> iterator = mn.instructions.iterator(); AbstractInsnNode next; //TODO: implement stream while (iterator.hasNext()) { next = iterator.next(); if (next instanceof LineNumberNode) iterator.set ( new LineNumberNode ( rand.nextInt(), ((LineNumberNode) next).start ) ); } } catch(Throwable t) { } }
/** * Finds the line number closest to the given node * * @param node the instruction node to get a line number for * @return the closest line number, or -1 if not known */ public static int findLineNumber(@NonNull AbstractInsnNode node) { AbstractInsnNode curr = node; // First search backwards while (curr != null) { if (curr.getType() == AbstractInsnNode.LINE) { return ((LineNumberNode) curr).line; } curr = curr.getPrevious(); } // Then search forwards curr = node; while (curr != null) { if (curr.getType() == AbstractInsnNode.LINE) { return ((LineNumberNode) curr).line; } curr = curr.getNext(); } return -1; }
public static InsnList getImportantList(InsnList list) { if (list.size() == 0) { return list; } HashMap<LabelNode, LabelNode> labels = new HashMap<LabelNode, LabelNode>(); for (AbstractInsnNode insn = list.getFirst(); insn != null; insn = insn.getNext()) { if (insn instanceof LabelNode) { labels.put((LabelNode) insn, (LabelNode) insn); } } InsnList importantNodeList = new InsnList(); for (AbstractInsnNode insn = list.getFirst(); insn != null; insn = insn.getNext()) { if (insn instanceof LabelNode || insn instanceof LineNumberNode) { continue; } importantNodeList.add(insn.clone(labels)); } return importantNodeList; }
@SuppressWarnings("unchecked") @Override public void visitEnd() { MethodNode methodNode = (MethodNode) mv; Iterator<AbstractInsnNode> nodeIter = methodNode.instructions.iterator(); while (nodeIter.hasNext()) { AbstractInsnNode insnNode = nodeIter.next(); if (insnNode.getType() == AbstractInsnNode.LINE) { currentLine = ((LineNumberNode) insnNode).line; methodNode.instructions.insertBefore(insnNode, getLineNumberInstrumentation()); continue; } if ((insnNode.getType() == AbstractInsnNode.VAR_INSN) || (insnNode.getType() == AbstractInsnNode.FIELD_INSN) || (insnNode.getType() == AbstractInsnNode.IINC_INSN) || (insnNode.getType() == AbstractInsnNode.INT_INSN) || (insnNode.getType() == AbstractInsnNode.INSN)) { methodNode.instructions.insert(insnNode, getInstrumentation(insnNode)); } } methodNode.accept(next); }
/** * Find line number associated with an instruction. * @param insnList instruction list for method * @param insnNode instruction within method being searched against * @throws NullPointerException if any argument is {@code null} or contains {@code null} * @throws IllegalArgumentException if arguments aren't all from the same method * @return line number node associated with the instruction, or {@code null} if no line number exists */ public static LineNumberNode findLineNumberForInstruction(InsnList insnList, AbstractInsnNode insnNode) { Validate.notNull(insnList); Validate.notNull(insnNode); int idx = insnList.indexOf(insnNode); Validate.isTrue(idx != -1); // Get index of labels and insnNode within method ListIterator<AbstractInsnNode> insnIt = insnList.iterator(idx); while (insnIt.hasPrevious()) { AbstractInsnNode node = insnIt.previous(); if (node instanceof LineNumberNode) { return (LineNumberNode) node; } } return null; }
/** * <p> * This method scans the instructions for 'else' and returns the node * </p> * * @param ifTargetIndex * Index of the target instruction of 'if' * @param endIndex * Index of the end instruction upto which scanner will work * @param nestingLevel * nesting level * @return Node */ private AbstractInsnNode scanForElse(int ifTargetIndex, int endIndex) { boolean lineNumberFound = false; LabelNode ln = (LabelNode) this.insnArr[ifTargetIndex]; for (int i = ifTargetIndex + 1; i <= endIndex; i++) { AbstractInsnNode ain = this.insnArr[i]; if (ain instanceof JumpInsnNode && InstrumentUtil.getJumpInsnOpcodesMap().containsKey( ain.getOpcode())) { if (!lineNumberFound) { return ain; } } else if (ain instanceof LineNumberNode) { LineNumberNode lnn = (LineNumberNode) ain; // if the line does not belong to the label if (lnn.start != ln) { lineNumberFound = true; return null; } } } return null; }
public static InsnList getImportantList(InsnList list) { if(list.size() == 0) return list; HashMap<LabelNode, LabelNode> labels = new HashMap<LabelNode, LabelNode>(); for(AbstractInsnNode insn = list.getFirst(); insn != null; insn = insn.getNext()) { if(insn instanceof LabelNode) labels.put((LabelNode)insn, (LabelNode)insn); } InsnList importantNodeList = new InsnList(); for(AbstractInsnNode insn = list.getFirst(); insn != null; insn = insn.getNext()) { if(insn instanceof LabelNode || insn instanceof LineNumberNode) continue; importantNodeList.add(insn.clone(labels)); } return importantNodeList; }
@Override public void write(DoStmtToken token) { expr.writeDefineVariables(token.getLocal()); LabelNode start = expr.writeLabel(node, token.getMeta().getStartLine()); LabelNode end = new LabelNode(); method.pushJump(end, start); expr.write(token.getBody()); method.popJump(); expr.writeConditional(token.getCondition(), end); add(new JumpInsnNode(GOTO, start)); add(end); add(new LineNumberNode(token.getMeta().getEndLine(), end)); expr.writeUndefineVariables(token.getLocal()); }
private void writeBody(IfStmtToken token) { LabelNode end = new LabelNode(); LabelNode elseL = new LabelNode(); expr.writePopBoolean(); add(new JumpInsnNode(IFEQ, token.getElseBody() != null ? elseL : end)); expr.stackPop(); if (token.getBody() != null) { expr.write(token.getBody()); } if (token.getElseBody() != null){ add(new JumpInsnNode(GOTO, end)); add(elseL); expr.write(token.getElseBody()); } add(end); add(new LineNumberNode(token.getMeta().getEndLine(), end)); }
@Override public void write(WhileStmtToken token) { expr.writeDefineVariables(token.getLocal()); LabelNode start = expr.writeLabel(node, token.getMeta().getStartLine()); LabelNode end = new LabelNode(); expr.writeConditional(token.getCondition(), end); method.pushJump(end, start); expr.write(BodyStmtToken.class, token.getBody()); method.popJump(); add(new JumpInsnNode(GOTO, start)); add(end); add(new LineNumberNode(token.getMeta().getEndLine(), end)); expr.writeUndefineVariables(token.getLocal()); }
public static boolean areNodesEqual(AbstractInsnNode node, AbstractInsnNode node2) { if (node.getClass() == node2.getClass() && node.getOpcode() == node2.getOpcode()) { if (node instanceof MethodInsnNode) { return ((MethodInsnNode) node).name.equals(((MethodInsnNode) node2).name) && ((MethodInsnNode) node).desc.equals(((MethodInsnNode) node2).desc) && ((MethodInsnNode) node).owner.equals(((MethodInsnNode) node2).owner); } else if (node instanceof VarInsnNode) { return ((VarInsnNode) node).var == ((VarInsnNode) node2).var; } else if (node instanceof InsnNode) { return true; } else if (node instanceof TypeInsnNode) { return ((TypeInsnNode) node).desc.equals(((TypeInsnNode) node2).desc); } else if (node instanceof JumpInsnNode) { return ((JumpInsnNode) node).label == ((JumpInsnNode) node2).label; } else if (node instanceof LabelNode) { return node == node2; } else if (node instanceof LineNumberNode) { return ((LineNumberNode) node).line == ((LineNumberNode) node2).line; } else if (node instanceof FieldInsnNode) { return ((FieldInsnNode) node).name.equals(((FieldInsnNode) node2).name) && ((FieldInsnNode) node).desc.equals(((FieldInsnNode) node2).desc) && ((FieldInsnNode) node).owner.equals(((FieldInsnNode) node2).owner); } else if (node instanceof LdcInsnNode) { return ((LdcInsnNode) node).cst.equals(((LdcInsnNode) node2).cst); } } return false; }
@SuppressWarnings("all") private static AbstractInsnNode getNext(Iterator<AbstractInsnNode> it) { while (it.hasNext()) { final AbstractInsnNode in = it.next(); if (!(in instanceof LineNumberNode)) { return in; } } return null; }
private static List<Integer> findLineNumbers(InsnList insnList) { List<Integer> lineNumbers = new ArrayList<>(); insnList.iterator().forEachRemaining(i -> { if (i instanceof LineNumberNode) { lineNumbers.add(((LineNumberNode) i).line); } }); return lineNumbers; }
@Override public boolean transform() throws Throwable { classNodes().forEach(classNode -> { classNode.methods.forEach(methodNode -> { Iterator<AbstractInsnNode> it = methodNode.instructions.iterator(); while (it.hasNext()) { if (it.next() instanceof LineNumberNode) { it.remove(); } } }); }); return true; }
public int getLineNumber(int pos) { ListIterator<AbstractInsnNode> iterator; AbstractInsnNode prev; iterator = mn.instructions.iterator(pos); while(iterator.hasPrevious()) if((prev = iterator.previous()) instanceof LineNumberNode) return ((LineNumberNode) prev).line; return -1; }
static List<AbstractInsnNode> filterBodyNoDebug(MethodNode mn) { Iterable<AbstractInsnNode> iterable = () -> mn.instructions.iterator(); return StreamSupport.stream(iterable.spliterator(), false) .filter(i -> !(i instanceof LabelNode)) .filter(i -> !(i instanceof LineNumberNode)) .collect(Collectors.toList()); }
@Override public void handle(AbstractInsnNode node) throws IncorrectNodeException { super.handle(node); LOG.debug(logNode(node)); checkType(node, LineNumberNode.class); mState.setCurrentLine(((LineNumberNode)node).line); }
private AbstractInsnNode getNextRelevant(Iterator<AbstractInsnNode> it) { AbstractInsnNode insn = null; while (it.hasNext()) { insn = it.next(); if (insn != null && !(insn instanceof LineNumberNode)) { break; } } if (insn == null) { throw new RuntimeException(); } return insn; }
@Override public void transform(byte[] bytes, ClassNode cn) { //////////////////////////////////////////////////////////////// MethodNode method = this.findMethod(cn, "sendClickBlockToController", "func_147115_a"); InsnList code = method.instructions; code.clear(); LabelNode l0 = new LabelNode(); code.add(l0); code.add(new LineNumberNode(1460, l0)); code.add(new VarInsnNode(Opcodes.ILOAD, 1)); LabelNode l1 = new LabelNode(); code.add(new JumpInsnNode(Opcodes.IFNE, l1)); LabelNode l2 = new LabelNode(); code.add(l2); code.add(new LineNumberNode(1462, l2)); code.add(new VarInsnNode(Opcodes.ALOAD, 0)); code.add(new InsnNode(Opcodes.ICONST_0)); code.add(leftClickCounter.putField()); code.add(l1); code.add(new LineNumberNode(1484, l1)); code.add(new FrameNode(Opcodes.F_SAME, 0, null, 0, null)); code.add(new InsnNode(Opcodes.RETURN)); method.maxStack = 2; method.maxLocals = 2; //////////////////////////////////////////////////////////////// }
/** * Generates instructions for line numbers. This is useful for debugging. For example, you can put a line number of 99999 or some other * special number to denote that the code being executed is instrumented code. Then if a stacktrace happens, you'll know that if * instrumented code was immediately involved. * @param num line number * @return instructions for a line number * @throws IllegalArgumentException if {@code num < 0} */ public static InsnList lineNumber(int num) { Validate.isTrue(num >= 0); InsnList ret = new InsnList(); LabelNode labelNode = new LabelNode(); ret.add(labelNode); ret.add(new LineNumberNode(num, labelNode)); return ret; }
/** * This will return an InsnList which would be reading all instructions from * beginning of statement till it reaches LineNumberNode * * @param node * - the node from which instruction list is read till starting * @return */ public static List<AbstractInsnNode> getInstructionListFromBeginingofStatement( AbstractInsnNode node, List<AbstractInsnNode> nodeList) { if (node instanceof LineNumberNode) { return nodeList; } getInstructionListFromBeginingofStatement(node.getPrevious(), nodeList); nodeList.add(node); return nodeList; }
/** * <p> * This method finds whether the if block represents a ternary operator or * not. It also injects necessary instructions to inject logging before and * after ternary operator usage. * </p> * * @param ifStartIndex * index of if block start * @param endIndex * index of else end * @param ainIfBlock * Instructions where logging to be injected * @param nestingLevel * nesting level */ private boolean processTernaryOperator(int ifStartIndex, int endIndex, int nestingLevel) { boolean ternaryOperatorFound = true; for (int g = ifStartIndex; g < endIndex; g++) { if (this.insnArr[g] instanceof LineNumberNode) { ternaryOperatorFound = false; break; } } if (ternaryOperatorFound) { InsnList[] il = new InsnList[2]; String cSymbol = env.getClassSymbol(getLogClazzName()); String mSymbol = env.getMethodSymbol(getLogClazzName(), cSymbol, name); il[0] = InstrumentUtil.addLogMessage(cSymbol, mSymbol, InstrumentationMessageLoader .getMessage(MessageConstants.MSG_BEFORE_TERNARY), "", "" + this.currentIfCount[nestingLevel]); il[1] = InstrumentUtil.addLogMessage(cSymbol, mSymbol, InstrumentationMessageLoader .getMessage(MessageConstants.MSG_AFTER_TERNARY), "", "" + this.currentIfCount[nestingLevel]); } return ternaryOperatorFound; }
/** * <p> * This method processes loops and add logging * </p> * * @param firstStmtInLoopIndex * Index of the first statement in the loop. * @param loopEndIndex * Index where loop ends. * @param nestingLevel * nesting level */ private void processLoop(int firstStmtInLoopIndex, int loopEndIndex, int nestingLevel) { logger.debug(firstStmtInLoopIndex + " " + loopEndIndex); this.currentLoopCount[nestingLevel]++; AbstractInsnNode abstractInsnNode; // adding loop entry abstractInsnNode = this.insnArr[firstStmtInLoopIndex]; AbstractInsnNode gotoNode = abstractInsnNode.getPrevious(); AbstractInsnNode lineNode = abstractInsnNode.getNext(); if ((gotoNode instanceof JumpInsnNode && Opcodes.GOTO == gotoNode .getOpcode()) || (!(lineNode instanceof LineNumberNode))) { lineNode = getPreviousLineNode(abstractInsnNode); } Integer lineNumber = ((LineNumberNode) lineNode).line; String cSymbol = env.getClassSymbol(getClassName()); String mSymbol = env.getMethodSymbol(getClassName(), cSymbol, name); InsnList il1 = InstrumentUtil.addLogMessage(cSymbol,mSymbol, InstrumentationMessageLoader .getMessage(MessageConstants.ENTERED_LOOP), lineNumber .toString(), this.currentLoopCount[nestingLevel] .toString()); instructions.insertBefore(lineNode.getPrevious(), il1); // handling map reduce output in the loop handleCtxWrite(firstStmtInLoopIndex, loopEndIndex); // adding loop exit abstractInsnNode = this.insnArr[loopEndIndex]; InsnList il2 = InstrumentUtil.addloopCounterLogging(cSymbol, mSymbol, InstrumentationMessageLoader .getMessage(MessageConstants.EXITING_LOOP), this.localVariableSize, this.currentLoopCount[nestingLevel] .toString()); // resetting the counter to ZERO il2.add(new LabelNode()); il2.add(new InsnNode(Opcodes.ICONST_0)); il2.add(new VarInsnNode(Opcodes.ISTORE, this.localVariableSize)); instructions.insert(abstractInsnNode.getNext(), il2); this.addLocalVariable(this.localVariableSize); }
/** * <p> * Finds whether a line node is found in the given range * </p> * * @param startIndex * start index for the scan * @param endIndex * end index for the line * @return boolean true if line node is found */ private boolean scanForLine(int startIndex, int endIndex) { boolean lineFound = false; for (int k = startIndex; k <= endIndex; k++) { AbstractInsnNode ain = insnArr[k]; if (ain instanceof LineNumberNode) { lineFound = true; break; } } return lineFound; }
/** * This method adds a LineNumberNode to a list of bytecode instructions. * * @param code is the bytecode being generated. * @param construct is the construct that provides the line number. */ public static void addLineNumber(final InsnList code, final IConstruct construct) { if (construct.getLocation() == null) { return; } final LabelNode label = new LabelNode(); code.add(label); code.add(new LineNumberNode(construct.getLocation().getLine(), label)); }
/** * Determines the line number corresponding to the given instruction. * Returns -1 if the line number could not be determined. * * @param insn * instruction to determine the line number for * @return * line number corresponding to the instruction, or -1 if the line * number could not be determined */ public static int getLineNo (final AbstractInsnNode insn) { // // Starting at the given instruction, traverse the instructions // backwards and find the closest LineNumberInstance. // for (AbstractInsnNode node = insn; node != null; node = node.getPrevious ()) { if (node instanceof LineNumberNode) { return ((LineNumberNode) node).line; } } return -1; }
public int getLineNumber() { AbstractInsnNode node = this.methodNode.instructions.getFirst(); while (node != null) { if (node.getType() == AbstractInsnNode.LINE) { return ((LineNumberNode) node).line; } node = node.getNext(); } return 0; }
private void handleChunkAddition(ClassNode classNode, String from, MethodNode tmn, MethodNode mn, boolean atbeginning) { Iterator<AbstractInsnNode> i = mn.instructions.iterator(); while (i.hasNext()) { processNode( i.next(), from, classNode.name ); } Iterator<AbstractInsnNode> g = mn.instructions.iterator(); while (g.hasNext()) { AbstractInsnNode ain = g.next(); if ( ain instanceof LineNumberNode ) g.remove(); else if ( ain instanceof LabelNode ) g.remove(); } AbstractInsnNode finalReturn = mn.instructions.getLast(); while (!isReturn( finalReturn.getOpcode() )) { mn.instructions.remove( finalReturn ); finalReturn = mn.instructions.getLast(); } mn.instructions.remove( finalReturn ); if ( atbeginning ) tmn.instructions.insert( mn.instructions ); else { tmn.instructions.insertBefore( tmn.instructions.getLast().getPrevious(), mn.instructions ); } }
public boolean search() { for (AbstractInsnNode ain : insns.toArray()) { if (ain instanceof LineNumberNode || ain instanceof FrameNode) continue; if (pattern.accept(ain)) { matches.add(pattern.getLastMatch()); pattern.resetMatch(); } } return size() != 0; }
private void addLabelIfNecessary(final AbstractInsnNode insn) { AbstractInsnNode next = insn.getNext(); while (next != null) { if (next instanceof LabelNode && this.jumpTargetLabels.contains(next)) return; if (next instanceof FrameNode || next instanceof LineNumberNode) next = next.getNext(); else break; } traceLabel(null, InstructionType.SAFE); }
private boolean followedByJumpLabel(final ListIterator<AbstractInsnNode> iterator) { if (!iterator.hasNext()) return false; final AbstractInsnNode nextInsn = iterator.next(); iterator.previous(); for (AbstractInsnNode insn = nextInsn; insn != null; insn = insn.getNext()) { if (insn instanceof LabelNode && this.jumpTargetLabels.contains(insn)) return true; if (!(insn instanceof FrameNode || insn instanceof LineNumberNode)) break; } return false; }
/** * Gets the next node skipping {@link LineNumberNode}s and {@link LabelNode}s. * * @param node * the node * @return the next node */ public static AbstractInsnNode getNext(final AbstractInsnNode node) { if (node == null) { return null; } AbstractInsnNode current = node; do { current = current.getNext(); if (current != null && !(current instanceof LineNumberNode || current instanceof LabelNode)) { break; } } while (current != null); return current; }
/** * Gets the previous node, skipping {@link LineNumberNode}s and {@link LabelNode}s. * * @param node * the node * @return the previous node */ public static AbstractInsnNode getPrevious(final AbstractInsnNode node) { if (node == null) { return null; } AbstractInsnNode current = node; do { current = current.getPrevious(); if (current != null && !(current instanceof LineNumberNode || current instanceof LabelNode)) { break; } } while (current != null); return current; }
public LabelNode writeLabel(MethodNode mv, int lineNumber){ LabelNode node = new LabelNode(new Label()); mv.instructions.add(node); if (lineNumber != -1) mv.instructions.add(new LineNumberNode(lineNumber, node)); return node; }
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(LineNumberNode insn) { // Intentionally empty. }
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(LineNumberNode insn, IRBuilder builder) { builder.updateCurrentDebugPosition(insn.line, null); }