List of usage examples for org.objectweb.asm.tree InsnList iterator
@Override
public ListIterator<AbstractInsnNode> iterator()
From source file:org.evosuite.setup.PutStaticMethodCollector.java
License:Open Source License
@SuppressWarnings("unchecked") public Set<MethodIdentifier> collectMethods() { Set<MethodIdentifier> methods = new LinkedHashSet<MethodIdentifier>(); for (String calledClassName : getStaticFields.keySet()) { ClassNode classNode = DependencyAnalysis.getClassNode(calledClassName); List<MethodNode> classMethods = classNode.methods; for (MethodNode mn : classMethods) { if (mn.name.equals(CLINIT)) continue; InsnList instructions = mn.instructions; Iterator<AbstractInsnNode> it = instructions.iterator(); while (it.hasNext()) { AbstractInsnNode insn = it.next(); if (insn instanceof FieldInsnNode) { FieldInsnNode fieldInsn = (FieldInsnNode) insn; if (fieldInsn.getOpcode() != Opcodes.PUTSTATIC) { continue; }//from ww w . j a v a 2 s . c om String calleeClassName = fieldInsn.owner.replaceAll("/", "."); String calleeFieldName = fieldInsn.name; if (contains(getStaticFields, calleeClassName, calleeFieldName)) { MethodIdentifier methodIdentifier = new MethodIdentifier(calledClassName, mn.name, mn.desc); methods.add(methodIdentifier); } } } } } return methods; }
From source file:org.lambdamatic.analyzer.ast.InsnCursor.java
License:Open Source License
/** * Constructor/* ww w .j a v a 2 s.c o m*/ * * @param instructions the {@link InsnList} to iterate on. * @param labels the labels to locate specific instructions. */ @SuppressWarnings("unchecked") public InsnCursor(final InsnList instructions, final Map<String, AbstractInsnNode> labels) { this.instructions = instructions; this.iterator = instructions.iterator(); this.labels = labels; }
From source file:org.qkit.core.asm.adapters.ChangeSuperclassAdapter.java
License:Open Source License
@Override public void visitEnd() { ClassNode cn = (ClassNode) cv;/*from w w w. j a v a2s .co m*/ for (MethodNode mn : cn.methods) { InsnList il = mn.instructions; Iterator<AbstractInsnNode> it = il.iterator(); while (it.hasNext()) { AbstractInsnNode ain = it.next(); if (ain instanceof MethodInsnNode) { MethodInsnNode m = (MethodInsnNode) ain; if ((m.getOpcode() == INVOKESPECIAL)) { MethodInsnNode min = (MethodInsnNode) ain; if (min.owner.equals(cn.superName)) { min.owner = superClass; } break; } } } } cn.superName = superClass; System.out.println(" [~S] " + cn.name + " extends " + cn.superName); cn.accept(next); }
From source file:org.spongepowered.asm.mixin.injection.points.BeforeInvoke.java
License:MIT License
@Override public boolean find(String desc, InsnList insns, Collection<AbstractInsnNode> nodes) { int ordinal = 0; boolean found = false; if (this.logging) { this.logger.info("{} is searching for an injection point in method with descriptor {}", this.className, desc);/*w w w . j av a2s .c o m*/ } ListIterator<AbstractInsnNode> iter = insns.iterator(); while (iter.hasNext()) { AbstractInsnNode insn = iter.next(); if (this.matchesInsn(insn)) { MemberInfo nodeInfo = new MemberInfo(insn); if (this.logging) { this.logger.info("{} is considering insn {}", this.className, nodeInfo); } if (this.target.matches(nodeInfo.owner, nodeInfo.name, nodeInfo.desc)) { if (this.logging) { this.logger.info("{} > found a matching insn, checking preconditions...", this.className); } if (this.matchesInsn(nodeInfo, ordinal)) { if (this.logging) { this.logger.info("{} > > > found a matching insn at ordinal {}", this.className, ordinal); } nodes.add(insn); found = true; if (this.ordinal == ordinal) { break; } } ordinal++; } } this.inspectInsn(desc, insns, insn); } return found; }
From source file:org.spongepowered.asm.mixin.injection.points.BeforeNew.java
License:MIT License
@Override public boolean find(String desc, InsnList insns, Collection<AbstractInsnNode> nodes) { boolean found = false; int ordinal = 0; ListIterator<AbstractInsnNode> iter = insns.iterator(); while (iter.hasNext()) { AbstractInsnNode insn = iter.next(); if (insn instanceof TypeInsnNode && insn.getOpcode() == Opcodes.NEW && this.matchesOwner((TypeInsnNode) insn)) { if (this.ordinal == -1 || this.ordinal == ordinal) { nodes.add(insn);//w w w. j ava 2 s. com found = true; } ordinal++; } } return found; }
From source file:org.spongepowered.asm.mixin.injection.points.BeforeReturn.java
License:MIT License
@Override public boolean find(String desc, InsnList insns, Collection<AbstractInsnNode> nodes) { boolean found = false; // RETURN opcode varies based on return type, thus we calculate what opcode we're actually looking for by inspecting the target method int returnOpcode = Type.getReturnType(desc).getOpcode(Opcodes.IRETURN); int ordinal = 0; ListIterator<AbstractInsnNode> iter = insns.iterator(); while (iter.hasNext()) { AbstractInsnNode insn = iter.next(); if (insn instanceof InsnNode && insn.getOpcode() == returnOpcode) { if (this.ordinal == -1 || this.ordinal == ordinal) { nodes.add(insn);// w w w.ja v a 2 s. co m found = true; } ordinal++; } } return found; }
From source file:org.spongepowered.asm.mixin.injection.points.JumpInsnPoint.java
License:MIT License
@Override public boolean find(String desc, InsnList insns, Collection<AbstractInsnNode> nodes) { boolean found = false; int ordinal = 0; ListIterator<AbstractInsnNode> iter = insns.iterator(); while (iter.hasNext()) { AbstractInsnNode insn = iter.next(); if (insn instanceof JumpInsnNode && (this.opCode == -1 || insn.getOpcode() == this.opCode)) { if (this.ordinal == -1 || this.ordinal == ordinal) { nodes.add(insn);/*from w w w. j ava2 s . c o m*/ found = true; } ordinal++; } } return found; }
From source file:org.spongepowered.despector.ast.io.insn.OpcodeDecompiler.java
License:Open Source License
private void buildIntermediates(InsnList instructions, Locals locals) { this.instructions = Lists.newArrayList(); Iterator<AbstractInsnNode> it = instructions.iterator(); while (it.hasNext()) { AbstractInsnNode next = it.next(); this.instructions.add(next); }/*from w w w .j ava2s. c o m*/ intermediate_stack = false; for (this.instructions_index = 0; this.instructions_index < this.instructions.size();) { AbstractInsnNode next = this.instructions.get(this.instructions_index++); // System.out.println(AstUtil.insnToString(next)); handleIntermediate(next); } }
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 2s . 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.FieldCallSearch.java
License:Open Source License
@Override public void search(final ClassNode node, final SearchResultNotifier srn, boolean exact) { final Iterator<MethodNode> methods = node.methods.iterator(); String owner = mOwner.getText(); if (owner.isEmpty()) { owner = null;/*w w w . ja v a 2s. com*/ } String name = mName.getText(); if (name.isEmpty()) { name = null; } String desc = mDesc.getText(); if (desc.isEmpty()) { desc = null; } while (methods.hasNext()) { final MethodNode method = methods.next(); final InsnList insnlist = method.instructions; final ListIterator<AbstractInsnNode> instructions = insnlist.iterator(); while (instructions.hasNext()) { final AbstractInsnNode insnNode = instructions.next(); if (insnNode instanceof FieldInsnNode) { final FieldInsnNode min = (FieldInsnNode) insnNode; if (name == null && owner == null && desc == null) continue; if (exact) { if (name != null && !name.equals(min.name)) { continue; } if (owner != null && !owner.equals(min.owner)) { continue; } if (desc != null && !desc.equals(min.desc)) { continue; } String desc2 = method.desc; try { desc2 = Type.getType(method.desc).toString(); if (desc2 == null || desc2.equals("null")) desc2 = method.desc; } catch (java.lang.ArrayIndexOutOfBoundsException e) { } srn.notifyOfResult(node.name + "." + method.name + desc2 + " > " + OpcodeInfo.OPCODES.get(insnNode.opcode()).toLowerCase()); } else { if (name != null && !min.name.contains(name)) { continue; } if (owner != null && !min.owner.contains(owner)) { continue; } if (desc != null && !min.desc.contains(desc)) { continue; } String desc2 = method.desc; try { desc2 = Type.getType(method.desc).toString(); if (desc2 == null || desc2.equals("null")) desc2 = method.desc; } catch (java.lang.ArrayIndexOutOfBoundsException e) { } srn.notifyOfResult(node.name + "." + method.name + desc2 + " > " + OpcodeInfo.OPCODES.get(insnNode.opcode()).toLowerCase()); } } } } }