List of usage examples for org.objectweb.asm.tree AbstractInsnNode getOpcode
public int getOpcode()
From source file:org.parboiled.transform.process.SuperCallRewriter.java
License:Apache License
@Override public void process(@Nonnull final ParserClassNode classNode, @Nonnull final RuleMethod method) throws Exception { Objects.requireNonNull(classNode, "classNode"); Objects.requireNonNull(method, "method"); final InsnList instructions = method.instructions; AbstractInsnNode insn = instructions.getFirst(); while (insn.getOpcode() != ARETURN) { if (insn.getOpcode() == INVOKESPECIAL) process(classNode, method, (MethodInsnNode) insn); insn = insn.getNext();//from w w w . j av a 2 s .co m } }
From source file:org.parboiled.transform.process.VarFramingGenerator.java
License:Apache License
@Override public void process(@Nonnull final ParserClassNode classNode, @Nonnull final RuleMethod method) throws Exception { Objects.requireNonNull(classNode, "classNode"); Objects.requireNonNull(method, "method"); final InsnList instructions = method.instructions; AbstractInsnNode ret = instructions.getLast(); while (ret.getOpcode() != ARETURN) ret = ret.getPrevious();//from ww w. java2 s .c o m final CodeBlock block = CodeBlock.newCodeBlock(); block.newobj(CodegenUtils.p(VarFramingMatcher.class)).dup_x1().swap(); createVarFieldArray(block, method); block.invokespecial(CodegenUtils.p(VarFramingMatcher.class), "<init>", CodegenUtils.sig(void.class, Rule.class, Var[].class)); instructions.insertBefore(ret, block.getInstructionList()); method.setBodyRewritten(); }
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);/* www .j a v a 2 s . c om*/ 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);//from ww w. j av a 2 s . c o 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 ww.j a v a2s. co m found = true; } ordinal++; } } return found; }
From source file:org.spongepowered.asm.mixin.transformer.MixinTransformer.java
License:MIT License
/** * Handles intrinsic displacement//from w ww . j av a2s. c o m * * @param targetClass Target classnode * @param mixin Mixin context * @param method Method being merged * @param target target method being checked */ private void displaceIntrinsic(ClassNode targetClass, MixinTargetContext mixin, MethodNode method, MethodNode target) { // Deliberately include invalid character in the method name so that // we guarantee no hackiness String proxyName = "proxy+" + target.name; for (Iterator<AbstractInsnNode> iter = method.instructions.iterator(); iter.hasNext();) { AbstractInsnNode insn = iter.next(); if (insn instanceof MethodInsnNode && insn.getOpcode() != Opcodes.INVOKESTATIC) { MethodInsnNode methodNode = (MethodInsnNode) insn; if (methodNode.owner.equals(targetClass.name) && methodNode.name.equals(target.name) && methodNode.desc.equals(target.desc)) { methodNode.name = proxyName; } } } target.name = proxyName; }
From source file:org.spongepowered.asm.mixin.transformer.MixinTransformer.java
License:MIT License
/** * Handles appending instructions from the source method to the target * method//from ww w . j ava 2 s .c om * * @param targetClass * @param targetMethodName * @param sourceMethod */ private void appendInsns(ClassNode targetClass, String targetMethodName, MethodNode sourceMethod) { if (Type.getReturnType(sourceMethod.desc) != Type.VOID_TYPE) { throw new IllegalArgumentException("Attempted to merge insns into a method which does not return void"); } if (targetMethodName == null || targetMethodName.length() == 0) { targetMethodName = sourceMethod.name; } boolean found = false; for (MethodNode method : targetClass.methods) { if ((targetMethodName.equals(method.name)) && sourceMethod.desc.equals(method.desc)) { found = true; AbstractInsnNode returnNode = null; Iterator<AbstractInsnNode> findReturnIter = method.instructions.iterator(); while (findReturnIter.hasNext()) { AbstractInsnNode insn = findReturnIter.next(); if (insn.getOpcode() == Opcodes.RETURN) { returnNode = insn; break; } } Iterator<AbstractInsnNode> injectIter = sourceMethod.instructions.iterator(); while (injectIter.hasNext()) { AbstractInsnNode insn = injectIter.next(); if (!(insn instanceof LineNumberNode) && insn.getOpcode() != Opcodes.RETURN) { method.instructions.insertBefore(returnNode, insn); } } } } if (!found) { sourceMethod.name = targetMethodName; targetClass.methods.add(sourceMethod); } }
From source file:org.spongepowered.asm.mixin.transformer.MixinTransformer.java
License:MIT License
/** * Identifies line numbers in the supplied ctor which correspond to the * start and end of the method body.// ww w . j a v a 2 s . c o m * * @param ctor * @return range indicating the line numbers of the specified constructor * and the position of the superclass ctor invocation */ private Range getConstructorRange(MethodNode ctor) { int line = 0, start = 0, end = 0, superIndex = -1; for (Iterator<AbstractInsnNode> iter = ctor.instructions.iterator(); iter.hasNext();) { AbstractInsnNode insn = iter.next(); if (insn instanceof LineNumberNode) { line = ((LineNumberNode) insn).line; } else if (insn instanceof MethodInsnNode) { if (insn.getOpcode() == Opcodes.INVOKESPECIAL && MixinTransformer.INIT.equals(((MethodInsnNode) insn).name) && superIndex == -1) { superIndex = ctor.instructions.indexOf(insn); start = line; } } else if (insn.getOpcode() == Opcodes.RETURN) { end = line; } } return new Range(start, end, superIndex); }
From source file:org.spongepowered.asm.mixin.transformer.MixinTransformer.java
License:MIT License
/** * Get insns corresponding to the instance initialiser (hopefully) from the * supplied constructor./* w w w. j a va 2 s . c o m*/ * * TODO Potentially rewrite this to be less horrible. * * @param mixin * @param ctor * @return initialiser bytecode extracted from the supplied constructor, or * null if the constructor range could not be parsed */ private InsnList getInitialiser(MixinTargetContext mixin, MethodNode ctor) { // Find the range of line numbers which corresponds to the constructor body Range init = this.getConstructorRange(ctor); if (!init.isValid()) { return null; } // Now we know where the constructor is, look for insns which lie OUTSIDE the method body int line = 0; InsnList initialiser = new InsnList(); boolean gatherNodes = false; int trimAtOpcode = -1; LabelNode optionalInsn = null; for (Iterator<AbstractInsnNode> iter = ctor.instructions.iterator(init.marker); iter.hasNext();) { AbstractInsnNode insn = iter.next(); if (insn instanceof LineNumberNode) { line = ((LineNumberNode) insn).line; AbstractInsnNode next = ctor.instructions.get(ctor.instructions.indexOf(insn) + 1); if (line == init.end && next.getOpcode() != Opcodes.RETURN) { gatherNodes = true; trimAtOpcode = Opcodes.RETURN; } else { gatherNodes = init.excludes(line); trimAtOpcode = -1; } } else if (gatherNodes) { if (optionalInsn != null) { initialiser.add(optionalInsn); optionalInsn = null; } if (insn instanceof LabelNode) { optionalInsn = (LabelNode) insn; } else { int opcode = insn.getOpcode(); if (opcode == trimAtOpcode) { trimAtOpcode = -1; continue; } for (int ivalidOp : MixinTransformer.INITIALISER_OPCODE_BLACKLIST) { if (opcode == ivalidOp) { // At the moment I don't handle any transient locals because I haven't seen any in the wild, but let's avoid writing // code which will likely break things and fix it if a real test case ever appears throw new InvalidMixinException(mixin, "Cannot handle " + ASMHelper.getOpcodeName(opcode) + " opcode (0x" + Integer.toHexString(opcode).toUpperCase() + ") in class initialiser"); } } initialiser.add(insn); } } } // Check that the last insn is a PUTFIELD, if it's not then AbstractInsnNode last = initialiser.getLast(); if (last != null) { if (last.getOpcode() != Opcodes.PUTFIELD) { throw new InvalidMixinException(mixin, "Could not parse initialiser, expected 0xB5, found 0x" + Integer.toHexString(last.getOpcode())); } } return initialiser; }
From source file:org.spongepowered.asm.mixin.transformer.MixinTransformer.java
License:MIT License
/** * Inject initialiser code into the target constructor * //w w w .ja va 2 s.co m * @param ctor * @param initialiser */ private void injectInitialiser(MethodNode ctor, InsnList initialiser) { for (Iterator<AbstractInsnNode> iter = ctor.instructions.iterator(0); iter.hasNext();) { AbstractInsnNode insn = iter.next(); if (insn.getOpcode() == Opcodes.INVOKESPECIAL && MixinTransformer.INIT.equals(((MethodInsnNode) insn).name)) { ctor.instructions.insert(insn, initialiser); } } }