Example usage for org.objectweb.asm MethodVisitor visitVarInsn

List of usage examples for org.objectweb.asm MethodVisitor visitVarInsn

Introduction

In this page you can find the example usage for org.objectweb.asm MethodVisitor visitVarInsn.

Prototype

public void visitVarInsn(final int opcode, final int var) 

Source Link

Document

Visits a local variable instruction.

Usage

From source file:com.github.javalbert.bytecode.utils.AsmUtils.java

License:Apache License

public static void visitDefaultConstructor(ClassWriter cw, String classTypeDescriptor) {
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
    mv.visitCode();/*from   w ww .j a  v  a 2  s  .c  o  m*/
    Label l0 = new Label();
    mv.visitLabel(l0);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
    mv.visitInsn(RETURN);
    Label l1 = new Label();
    mv.visitLabel(l1);
    mv.visitLocalVariable("this", classTypeDescriptor, null, l0, l1, 0);
    mv.visitMaxs(1, 1);
    mv.visitEnd();
}

From source file:com.github.rgcjonas.kuemmelgtr.core.Compiler.java

License:Open Source License

public static byte[] compileFunc(TokenSource<RPNToken> source, String variable) throws ParsingError {
    // initialize class
    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);

    writer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "com/github/rgcjonas/kuemmelgtr/jit/BogusName", null,
            CompiledClassBase.class.getName().replace('.', '/'),
            new String[] { Evaluator.Function.class.getName().replace('.', '/') });

    // create constructor
    MethodVisitor construct = writer.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
    construct.visitCode();/*from w w  w.  j  a v a2s. c o m*/
    construct.visitVarInsn(Opcodes.ALOAD, 0);
    construct.visitMethodInsn(Opcodes.INVOKESPECIAL, CompiledClassBase.class.getName().replace('.', '/'),
            "<init>", "()V");
    construct.visitInsn(Opcodes.RETURN);
    construct.visitMaxs(0, 0);
    construct.visitEnd();

    MethodVisitor method = writer.visitMethod(Opcodes.ACC_PUBLIC, "evaluate", "(D)D", null,
            new String[] { "com/github/rgcjonas/kuemmelgtr/core/RuntimeError" });

    compileCommon(source, method, variable);

    writer.visitEnd();
    return writer.toByteArray();
}

From source file:com.github.rgcjonas.kuemmelgtr.core.Compiler.java

License:Open Source License

public static byte[] compileBasic(TokenSource<RPNToken> source) throws ParsingError {
    // initialize class
    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);

    writer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "com/github/rgcjonas/kuemmelgtr/jit/BogusName", null,
            CompiledClassBase.class.getName().replace('.', '/'),
            new String[] { Evaluator.Basic.class.getName().replace('.', '/') });

    // create constructor
    MethodVisitor construct = writer.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
    construct.visitCode();//from w  w  w.  jav a  2  s . c om
    construct.visitVarInsn(Opcodes.ALOAD, 0);
    construct.visitMethodInsn(Opcodes.INVOKESPECIAL, CompiledClassBase.class.getName().replace('.', '/'),
            "<init>", "()V");
    construct.visitInsn(Opcodes.RETURN);
    construct.visitMaxs(0, 0);
    construct.visitEnd();

    MethodVisitor method = writer.visitMethod(Opcodes.ACC_PUBLIC, "evaluate", "()D", null,
            new String[] { "com/github/rgcjonas/kuemmelgtr/core/ParsingError",
                    "com/github/rgcjonas/kuemmelgtr/core/RuntimeError" });

    compileCommon(source, method, null);

    writer.visitEnd();
    return writer.toByteArray();
}

From source file:com.github.rgcjonas.kuemmelgtr.core.Compiler.java

License:Open Source License

private static void compileCommon(TokenSource<RPNToken> source, MethodVisitor method, String variable)
        throws ParsingError {
    method.visitCode();//from w ww.ja  va  2 s .  c o m

    // we now can compile our token stream
    int currentStackSize = 0; // we keep track of the current stack size to throw errors if we encounter an invalid instruction
    RPNToken t;
    while ((t = source.nextToken()) != null) {
        if (t instanceof RPNToken.Operand) {
            // we push it onto the stack
            method.visitLdcInsn(((RPNToken.Operand) t).getValue());
            currentStackSize++;
        } else if (t instanceof RPNToken.Operator) {
            RPNToken.Operator op = (RPNToken.Operator) t;

            if (currentStackSize < op.getNumOperands())
                throw new ParsingError(t.getSrcLine(), t.getSrcColumn(), "Missing operand(s)");

            switch (op.getName()) {
            case "_add":
                method.visitInsn(Opcodes.DADD);
                currentStackSize--;
                break;
            case "_mult":
                method.visitInsn(Opcodes.DMUL);
                currentStackSize--;
                break;
            case "_sub":
                method.visitInsn(Opcodes.DSUB);
                currentStackSize--;
                break;
            case "_div":
                method.visitInsn(Opcodes.DDIV);
                currentStackSize--;
                break;
            case "_pow":
                method.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Math", "pow", "(DD)D");
                currentStackSize--;
                break;
            default:
                //HACK: support every function in java/lang/Math. Will be way more performant than any lookup-and-evaluate
                //TODO: implement more functions inline
                if (currentStackSize < 1)
                    throw new ParsingError(t.getSrcLine(), t.getSrcColumn(), "Missing operand");
                try {
                    Method meth = Math.class.getDeclaredMethod(op.getName(), double.class); // just check if it's available and hope it returns a double
                    if (meth.getReturnType() != double.class)
                        throw new NoSuchMethodException(); // we don't want to blow up at runtime, do we?

                    method.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Math", op.getName(), "(D)D");
                } catch (NoSuchMethodException e) {
                    // we do not give up. The method may be available at runtime.
                    method.visitVarInsn(Opcodes.ALOAD, 0);
                    method.visitInsn(Opcodes.DUP_X2); // swap the this pointer and double
                    method.visitInsn(Opcodes.POP);
                    method.visitLdcInsn(op.getName());
                    method.visitLdcInsn((int) op.getSrcLine());
                    method.visitLdcInsn((int) op.getSrcColumn());
                    method.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                            CompiledClassBase.class.getName().replace('.', '/'), "resolveAndEvaluateFunction",
                            "(DLjava/lang/String;II)D");
                }
            }
        } else if (t instanceof RPNToken.VariableRecall) {
            // maybe, maybe the variable is an argument we can load
            if (variable != null && ((RPNToken.VariableRecall) t).getName().equalsIgnoreCase(variable)) {
                method.visitVarInsn(Opcodes.DLOAD, 1);
            } else {
                // we let our parent class do the hard work
                method.visitVarInsn(Opcodes.ALOAD, 0);
                method.visitLdcInsn(((RPNToken.VariableRecall) t).getName());
                method.visitLdcInsn(t.getSrcLine());
                method.visitLdcInsn(t.getSrcColumn());
                method.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                        CompiledClassBase.class.getName().replace('.', '/'), "getVariable",
                        "(Ljava/lang/String;II)D");
            }
            currentStackSize++;
        } else if (t instanceof RPNToken.VariableAssignment) {
            // also defer to our parent class
            // we do not give up. The method may be available at runtime.
            method.visitVarInsn(Opcodes.ALOAD, 0);
            method.visitInsn(Opcodes.DUP_X2); // swap the this pointer and double
            method.visitInsn(Opcodes.POP);
            method.visitLdcInsn(((RPNToken.VariableAssignment) t).getVariableName());
            method.visitLdcInsn(t.getSrcLine());
            method.visitLdcInsn(t.getSrcColumn());
            method.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CompiledClassBase.class.getName().replace('.', '/'),
                    "setVariable", "(DLjava/lang/String;II)D");
        } else {
            throw new ParsingError(t.getSrcLine(), t.getSrcColumn(), "Unknown instruction: " + t);
        }
    }

    if (currentStackSize != 1)
        throw new ParsingError(0, 0, "Expected stack to be one value, found " + currentStackSize);

    method.visitInsn(Opcodes.DRETURN);

    method.visitMaxs(0, 0);
    method.visitEnd();
}

From source file:com.github.stokito.gag.agent.AnswerToLifeGenerator.java

License:Apache License

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String sig, String[] exceptions) {

    MethodVisitor mv = writer().visitMethod(access, name, desc, sig, exceptions);
    mv.visitCode();/*  w ww . j a  v  a 2s.c om*/

    MethodInfo method = classInfo().getMethod(name, desc);
    for (LocalVarInfo param : method.getLocalVars()) {
        AnnoInfo anno = param.getAnnoFor(ANSWER_TYPE);
        if (anno == null) {
            continue;
        }

        Type paramType = param.getType();
        switch (paramType.getSort()) {
        case Type.INT:
        case Type.BYTE:
        case Type.CHAR:
        case Type.SHORT:
            mv.visitLdcInsn(FORTY_TWO);
            mv.visitVarInsn(ISTORE, param.getIndex());
            break;
        case Type.LONG:
            mv.visitLdcInsn((long) FORTY_TWO);
            mv.visitVarInsn(LSTORE, param.getIndex());
            break;
        case Type.DOUBLE:
            mv.visitLdcInsn((double) FORTY_TWO);
            mv.visitVarInsn(DSTORE, param.getIndex());
            break;
        case Type.FLOAT:
            mv.visitLdcInsn((float) FORTY_TWO);
            mv.visitVarInsn(FSTORE, param.getIndex());
            break;
        case Type.OBJECT:
            visitObject(mv, param);
            break;
        default:
            throwUnsupportedException(param);
        }

        setInstrumented(true);
    }

    mv.visitEnd();
    return mv;
}

From source file:com.github.stokito.gag.agent.AnswerToLifeGenerator.java

License:Apache License

/** TODO: Support BigDecimal and BigInteger. */
private void visitObject(MethodVisitor mv, LocalVarInfo param) {
    Type paramType = param.getType();
    if (Type.getType(Character.class).equals(paramType)) {
        mv.visitLdcInsn((char) FORTY_TWO);
        mv.visitMethodInsn(INVOKESTATIC, paramType.getInternalName(), "valueOf",
                "(C)L" + paramType.getInternalName() + ";");
        mv.visitVarInsn(ASTORE, param.getIndex());
    } else if (supportedValueOfTypes.contains(paramType)) {
        mv.visitLdcInsn(String.valueOf(FORTY_TWO));
        mv.visitMethodInsn(INVOKESTATIC, paramType.getInternalName(), "valueOf",
                "(Ljava/lang/String;)L" + paramType.getInternalName() + ";");
        mv.visitVarInsn(ASTORE, param.getIndex());
    } else {/* w ww  .  ja v a2  s  .c o m*/
        throwUnsupportedException(param);
    }
}

From source file:com.github.stokito.gag.agent.ThisHadBetterGenerator.java

License:Apache License

private static void visitComparable(MethodVisitor mv, boolean be, Property property, LocalVarInfo param,
        Label okay) {//w ww  .j  a va2 s .  com

    Type type = param.getType();
    int index = param.getIndex();

    switch (type.getSort()) {
    case Type.INT:
    case Type.SHORT:
        mv.visitVarInsn(ILOAD, index);
        break;
    case Type.LONG:
        mv.visitVarInsn(LLOAD, index);
        mv.visitInsn(LCONST_0);
        mv.visitInsn(LCMP);
        break;
    case Type.DOUBLE:
        mv.visitVarInsn(DLOAD, index);
        mv.visitInsn(DCONST_0);
        mv.visitInsn(DCMPG);
        break;
    case Type.FLOAT:
        mv.visitVarInsn(FLOAD, index);
        mv.visitInsn(FCONST_0);
        mv.visitInsn(FCMPG);
        break;
    case Type.OBJECT:
        if (type.equals(Type.getType(Integer.class))) {
            mv.visitVarInsn(ALOAD, index);
            mv.visitMethodInsn(INVOKEVIRTUAL, Type.getType(Integer.class).getInternalName(), "intValue", "()I");
        } else if (type.equals(Type.getType(Short.class))) {
            mv.visitVarInsn(ALOAD, index);
            mv.visitMethodInsn(INVOKEVIRTUAL, Type.getType(Short.class).getInternalName(), "intValue", "()I");
        } else if (type.equals(Type.getType(Long.class))) {
            mv.visitVarInsn(ALOAD, index);
            mv.visitMethodInsn(INVOKEVIRTUAL, Type.getType(Long.class).getInternalName(), "longValue", "()J");
            mv.visitInsn(LCONST_0);
            mv.visitInsn(LCMP);
        } else if (type.equals(Type.getType(Double.class))) {
            mv.visitVarInsn(ALOAD, index);
            mv.visitMethodInsn(INVOKEVIRTUAL, Type.getType(Double.class).getInternalName(), "doubleValue",
                    "()D");
            mv.visitInsn(DCONST_0);
            mv.visitInsn(DCMPG);
        } else if (type.equals(Type.getType(Float.class))) {
            mv.visitVarInsn(ALOAD, index);
            mv.visitMethodInsn(INVOKEVIRTUAL, Type.getType(Float.class).getInternalName(), "floatValue", "()F");
            mv.visitInsn(FCONST_0);
            mv.visitInsn(FCMPG);
        } else {
            throw new AnnotationStateError("Unsupported type: " + type);
        }
        break;
    default:
        throw new AnnotationStateError("Unsupported type: " + type);
    }

    switch (property) {
    case NEGATIVE:
        mv.visitJumpInsn(be ? IFLT : IFGE, okay);
        break;
    case POSITIVE:
        mv.visitJumpInsn(be ? IFGT : IFLE, okay);
        break;
    case ZERO:
        mv.visitJumpInsn(be ? IFEQ : IFNE, okay);
        break;
    }
}

From source file:com.github.stokito.gag.agent.ThisHadBetterGenerator.java

License:Apache License

private static void visitNullCheck(MethodVisitor mv, boolean be, LocalVarInfo param, Label okay) {
    switch (param.getType().getSort()) {
    case Type.ARRAY:
    case Type.OBJECT:
        mv.visitVarInsn(ALOAD, param.getIndex());
        break;//from w  w  w  .j  av a2 s.c  o m
    default:
        throw new AnnotationStateError("Unsupported type: " + param.getType());
    }

    mv.visitJumpInsn(be ? IFNULL : IFNONNULL, okay);
}

From source file:com.github.stokito.gag.agent.ThisHadBetterGenerator.java

License:Apache License

/**
 * The given Property needs to be either {@link Property#THE_BLUE_PILL} or
 * {@link Property#THE_RED_PILL}.//from  w ww  . j a va  2 s.c om
 */
private static void visitPill(MethodVisitor mv, boolean be, Property property, LocalVarInfo param, Label okay) {

    if (param.getType().getSort() != Type.OBJECT) {
        throw new AnnotationStateError("Unsupported type: " + param.getType());
    }

    // TODO: Also handle if parameter is null.

    Label notOkay = new Label();

    // See if the param type matches a Pill type
    mv.visitVarInsn(ALOAD, param.getIndex());
    mv.visitMethodInsn(INVOKEVIRTUAL, param.getType().getInternalName(), "getClass", "()Ljava/lang/Class;");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;");
    mv.visitLdcInsn("Pill|ThePill|.*[\\.$]Pill|.*[\\.$]ThePill");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "matches", "(Ljava/lang/String;)Z");

    if (be) {
        // If the param type does not match a Pill type, that's not okay, go to exception.
        mv.visitJumpInsn(FALSE, notOkay);
    } else {
        // If the param type does not match a Pill type, then that's okay, skip exception.
        mv.visitJumpInsn(FALSE, okay);
    }

    // At this point, the param type matches a Pill type.
    // So check if the param type is an enum type.
    mv.visitVarInsn(ALOAD, param.getIndex());
    mv.visitTypeInsn(INSTANCEOF, "java/lang/Enum");

    if (be) {
        // If the param type is not an enum, that's not okay, go to exception.
        mv.visitJumpInsn(FALSE, notOkay);
    } else {
        // If the param type is not an enum, that's okay, skip exception.
        mv.visitJumpInsn(FALSE, okay);
    }

    // Check that the Pill type has the property specified in the annotation.
    // First try to match on "BLUE" (or "RED").
    mv.visitVarInsn(ALOAD, param.getIndex());
    mv.visitTypeInsn(CHECKCAST, "java/lang/Enum");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Enum", "name", "()Ljava/lang/String;");
    mv.visitLdcInsn(property == THE_BLUE_PILL ? "BLUE" : "RED");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z");
    mv.visitJumpInsn(TRUE, be ? okay : notOkay);

    // Then try to see if the value ends with "BLUE_PILL" (or "RED_PILL").
    mv.visitVarInsn(ALOAD, param.getIndex());
    mv.visitTypeInsn(CHECKCAST, "java/lang/Enum");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Enum", "name", "()Ljava/lang/String;");
    mv.visitLdcInsn(property == THE_BLUE_PILL ? "BLUE_PILL" : "RED_PILL");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "endsWith", "(Ljava/lang/String;)Z");
    mv.visitJumpInsn(be ? TRUE : FALSE, okay);

    mv.visitLabel(notOkay);
}

From source file:com.github.stokito.gag.agent.ThisHadBetterGenerator.java

License:Apache License

private static void visitDeathStarPlans(MethodVisitor mv, boolean be, LocalVarInfo param, Label okay) {

    if (param.getType().getSort() != Type.OBJECT) {
        throw new AnnotationStateError("Unsupported type: " + param.getType());
    }/*from   w  ww  .ja  v  a 2  s  . co  m*/

    Label notOkay = new Label();

    // See if the param type matches a DeathStarPlans type
    mv.visitVarInsn(ALOAD, param.getIndex());
    mv.visitMethodInsn(INVOKEVIRTUAL, param.getType().getInternalName(), "getClass", "()Ljava/lang/Class;");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;");
    mv.visitLdcInsn("DeathStarPlans|TheDeathStarPlans|.*[\\.$]DeathStarPlans|.*[\\.$]TheDeathStarPlans");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "matches", "(Ljava/lang/String;)Z");

    if (be) {
        // If the param type does not match a DeathStarPlans type, that's not okay, go to exception.
        mv.visitJumpInsn(FALSE, notOkay);
    } else {
        // If the param type does not match a DeathStarPlans type, then that's okay, skip exception.
        mv.visitJumpInsn(FALSE, okay);
    }

    // At this point, the param type matches a DeathStarPlans type.
    // So check if the param has an isStolen method.
    Label start = new Label();
    Label end = new Label();
    Label handler = new Label();
    mv.visitTryCatchBlock(start, end, handler, null);

    mv.visitLabel(start);
    mv.visitVarInsn(ALOAD, param.getIndex());
    mv.visitMethodInsn(INVOKEVIRTUAL, param.getType().getInternalName(), "getClass", "()Ljava/lang/Class;");
    mv.visitLdcInsn("isStolen");
    mv.visitInsn(ACONST_NULL);
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod",
            "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;");

    mv.visitVarInsn(ALOAD, param.getIndex());
    mv.visitInsn(ACONST_NULL);
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Method", "invoke",
            "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
    mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z");

    mv.visitJumpInsn(be ? TRUE : FALSE, okay);

    mv.visitLabel(end);
    mv.visitJumpInsn(GOTO, notOkay);
    mv.visitLabel(handler);
    mv.visitInsn(POP);

    mv.visitLabel(notOkay);
}