Example usage for org.objectweb.asm.tree AbstractInsnNode getOpcode

List of usage examples for org.objectweb.asm.tree AbstractInsnNode getOpcode

Introduction

In this page you can find the example usage for org.objectweb.asm.tree AbstractInsnNode getOpcode.

Prototype

public int getOpcode() 

Source Link

Document

Returns the opcode of this instruction.

Usage

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);
        }
    }
}