Example usage for org.objectweb.asm Opcodes RETURN

List of usage examples for org.objectweb.asm Opcodes RETURN

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes RETURN.

Prototype

int RETURN

To view the source code for org.objectweb.asm Opcodes RETURN.

Click Source Link

Usage

From source file:org.sonar.java.bytecode.cfg.BytecodeCFGBuilderTest.java

License:Open Source License

@Test
public void all_opcodes_should_be_visited() throws Exception {
    Instructions ins = new Instructions();
    Predicate<Integer> filterReturnAndThrow = opcode -> !((Opcodes.IRETURN <= opcode
            && opcode <= Opcodes.RETURN) || opcode == Opcodes.ATHROW);
    NO_OPERAND_INSN.stream().filter(filterReturnAndThrow).forEach(ins::visitInsn);
    INT_INSN.forEach(i -> ins.visitIntInsn(i, 0));
    VAR_INSN.forEach(i -> ins.visitVarInsn(i, 0));
    TYPE_INSN.forEach(i -> ins.visitTypeInsn(i, "java/lang/Object"));
    FIELD_INSN.forEach(i -> ins.visitFieldInsn(i, "java/lang/Object", "foo", "D(D)"));
    METHOD_INSN.forEach(i -> ins.visitMethodInsn(i, "java/lang/Object", "foo", "()V", i == INVOKEINTERFACE));

    JUMP_INSN.forEach(i -> {/* ww  w.  j  a  v a 2s .  c  o  m*/
        Label jumpLabel = new Label();
        ins.visitJumpInsn(i, jumpLabel);
        ins.visitLabel(jumpLabel);
    });

    ins.visitLdcInsn("a");
    ins.visitIincInsn(0, 1);
    Handle handle = new Handle(H_INVOKESTATIC, "", "", "()V", false);
    ins.visitInvokeDynamicInsn("sleep", "()V", handle);
    ins.visitLookupSwitchInsn(new Label(), new int[] {}, new Label[] {});
    ins.visitMultiANewArrayInsn("B", 1);

    Label l0 = new Label();
    Label dflt = new Label();
    Label case0 = new Label();
    ins.visitTableSwitchInsn(0, 1, dflt, case0);
    ins.visitLabel(dflt);
    ins.visitInsn(NOP);
    ins.visitLabel(l0);
    ins.visitInsn(NOP);

    BytecodeCFG cfg = ins.cfg();
    Multiset<String> cfgOpcodes = cfgOpcodes(cfg);
    List<String> collect = Instructions.OPCODES.stream().filter(filterReturnAndThrow)
            .map(op -> Printer.OPCODES[op]).collect(Collectors.toList());
    assertThat(cfgOpcodes).containsAll(collect);
}

From source file:org.sonar.java.bytecode.cfg.BytecodeCFGMethodVisitor.java

License:Open Source License

@Override
public void visitInsn(int opcode) {
    currentBlock.addInsn(opcode);/*from   w  ww.j  a  v  a2s . co m*/
    if ((Opcodes.IRETURN <= opcode && opcode <= Opcodes.RETURN) || opcode == Opcodes.ATHROW) {
        currentBlock.successors.add(cfg.blocks.get(0));
        currentBlock = null;
    }
}

From source file:org.sonar.java.bytecode.se.BytecodeEGWalkerExecuteTest.java

License:Open Source License

@Test
public void test_return() throws Exception {
    ProgramState programState = execute(new Instruction(Opcodes.RETURN), ProgramState.EMPTY_STATE);
    assertThat(programState.peekValue()).isNull();
    assertThat(programState.exitValue()).isNull();
}

From source file:org.sonar.plugins.monitor.agent.transform.MethodAppender.java

License:Open Source License

@Override
public MethodVisitor newAdapter(MethodVisitor base, int access, String name, String desc, String signature,
        String[] exceptions) {//from w  w w  .j a v  a2 s . co m
    final CodeGenerator cg = new CodeGenerator(base);
    return new MethodAdapter(base) {
        @Override
        public void visitInsn(int opcode) {
            if (opcode == Opcodes.RETURN) {
                append(cg);
            }
            super.visitInsn(opcode);
        }
    };
}

From source file:org.spongepowered.asm.mixin.injection.callback.CallbackInjector.java

License:MIT License

/**
 * Inject the appropriate return code for the method type
 * //from   ww  w .j  a  v a  2  s .c o  m
 * @param callback callback handle
 */
protected void injectReturnCode(final Callback callback) {
    if (callback.target.returnType.equals(Type.VOID_TYPE)) {
        // Void method, so just return void
        callback.add(new InsnNode(Opcodes.RETURN));
    } else {
        // Non-void method, so work out which accessor to call to get the
        // return value, and return it
        callback.add(new VarInsnNode(Opcodes.ALOAD, callback.marshallVar));
        String accessor = CallbackInfoReturnable.getReturnAccessor(callback.target.returnType);
        String descriptor = CallbackInfoReturnable.getReturnDescriptor(callback.target.returnType);
        callback.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, callback.target.callbackInfoClass, accessor,
                descriptor, false));
        if (callback.target.returnType.getSort() == Type.OBJECT) {
            callback.add(new TypeInsnNode(Opcodes.CHECKCAST, callback.target.returnType.getInternalName()));
        }
        callback.add(new InsnNode(callback.target.returnType.getOpcode(Opcodes.IRETURN)));
    }
}

From source file:org.spongepowered.asm.mixin.transformer.MixinTransformer.java

License:MIT License

/**
 * Handles appending instructions from the source method to the target
 * method//  ww w  . j  a  v a  2  s. c  o  m
 * 
 * @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.//  w  w w .j  av  a 2 s  . c om
 * 
 * @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.//from  w ww .j  ava  2s  .  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.despector.emitter.bytecode.statement.BytecodeReturnEmitter.java

License:Open Source License

@Override
public void emit(BytecodeEmitterContext ctx, Return stmt, boolean semicolon) {
    MethodVisitor mv = ctx.getMethodVisitor();
    if (!stmt.getValue().isPresent()) {
        mv.visitInsn(Opcodes.RETURN);
    } else {//from   w w  w .  j  a  va  2  s .c  o m
        ctx.updateStack(-1);
        Instruction insn = stmt.getValue().get();
        ctx.emitInstruction(insn, ctx.getMethod().getReturnType());
        TypeSignature ret = ctx.getMethod().getReturnType();
        if (ret == ClassTypeSignature.INT || ret == ClassTypeSignature.BOOLEAN || ret == ClassTypeSignature.BYTE
                || ret == ClassTypeSignature.SHORT || ret == ClassTypeSignature.CHAR) {
            mv.visitInsn(Opcodes.IRETURN);
        } else if (ret == ClassTypeSignature.LONG) {
            mv.visitInsn(Opcodes.LRETURN);
        } else if (ret == ClassTypeSignature.FLOAT) {
            mv.visitInsn(Opcodes.FRETURN);
        } else if (ret == ClassTypeSignature.DOUBLE) {
            mv.visitInsn(Opcodes.DRETURN);
        } else {
            mv.visitInsn(Opcodes.ARETURN);
        }
    }
}

From source file:org.spongepowered.mod.asm.transformers.EventTransformer.java

License:MIT License

protected static MethodNode createSetCancelledMethod() {
    MethodNode methodNode = new MethodNode(Opcodes.ASM4, Opcodes.ACC_PUBLIC, "setCancelled", "(Z)V", null,
            null);//from   ww w  . jav a 2s  .c  o m
    methodNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
    methodNode.instructions.add(new VarInsnNode(Opcodes.ILOAD, 1));
    methodNode.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL,
            "net/minecraftforge/fml/common/eventhandler/Event", "setCanceled", "(Z)V", false));
    methodNode.instructions.add(new InsnNode(Opcodes.RETURN));
    methodNode.maxLocals = 1;
    methodNode.maxStack = 1;
    return methodNode;
}