Example usage for org.objectweb.asm Opcodes INVOKESTATIC

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

Introduction

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

Prototype

int INVOKESTATIC

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

Click Source Link

Usage

From source file:com.nginious.http.xsp.expr.PowFunction.java

License:Apache License

/**
 * Creates bytecode for evaluating this function. The specified method visitor is
 * used for creating bytecode.//from   w  w w.  ja  v  a2  s  .  c o m
 * 
 * @param visitor the methos visitor
 * @param type the type
 */
void compile(MethodVisitor visitor, Type type) {
    value1.compile(visitor, Type.DOUBLE);
    value2.compile(visitor, Type.DOUBLE);
    visitor.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Math", "pow", "(DD)D");
}

From source file:com.nginious.http.xsp.FormatDateTagPart.java

License:Apache License

/**
 * Creates bytecode in a separate method for evaluating this format date tag part.
 * // w w w.j av  a  2  s.  c o  m
 * @param intClassName the binary class name of the class being created
 * @param writer the class writer
 * @throws XspException if unable to create bytecode
 */
void compileMethod(String intClassName, ClassWriter writer) throws XspException {
    String[] exceptions = { "com/nginious/http/xsp/XspException" };
    MethodVisitor visitor = writer.visitMethod(Opcodes.ACC_PRIVATE, this.methodName,
            "(Lcom/nginious/http/HttpRequest;Lcom/nginious/http/HttpResponse;Ljava/lang/StringBuffer;)V", null,
            exceptions);
    visitor.visitCode();

    Label tryLabel = new Label();
    Label startCatchLabel = new Label();

    // Start try block
    visitor.visitTryCatchBlock(tryLabel, startCatchLabel, startCatchLabel, "java/lang/Exception");

    visitor.visitLabel(tryLabel);

    visitor.visitTypeInsn(Opcodes.NEW, "java/text/SimpleDateFormat");
    visitor.visitInsn(Opcodes.DUP);
    pattern.compile(visitor, Type.STRING);
    visitor.visitVarInsn(Opcodes.ALOAD, 2);
    visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, "com/nginious/http/HttpResponse", "getLocale",
            "()Ljava/util/Locale;");
    visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/text/SimpleDateFormat", "<init>",
            "(Ljava/lang/String;Ljava/util/Locale;)V");
    visitor.visitVarInsn(Opcodes.ASTORE, 4);

    if (this.timeZone != null) {
        visitor.visitVarInsn(Opcodes.ALOAD, 4);
        String timeZoneDesc = timeZone.getStringContent();
        visitor.visitLdcInsn(timeZoneDesc);
        visitor.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/TimeZone", "getTimeZone",
                "(Ljava/lang/String;)Ljava/util/TimeZone;");
        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/text/SimpleDateFormat", "setTimeZone",
                "(Ljava/util/TimeZone;)V");
    }

    try {
        String expression = value.getExpressionContent();
        ExpressionParser parser = new ExpressionParser();
        TreeExpression expr = parser.parse(expression);

        if (expr.getType() != Type.ANY) {
            throw new XspException("Expression in attribute value in tag " + getName()
                    + " is not an attribute or bean property " + " at line " + getLocationDescriptor());
        }

        expr.compile(visitor, Type.ANY);
        visitor.visitTypeInsn(Opcodes.CHECKCAST, "java/util/Date");
        visitor.visitVarInsn(Opcodes.ASTORE, 5);
    } catch (ExpressionException e) {
        throw new XspException("Invalid expression in attribute value in tag " + getName() + " at line "
                + getLocationDescriptor(), e);
    }

    Label nullLabel = new Label();
    visitor.visitVarInsn(Opcodes.ALOAD, 5);
    visitor.visitJumpInsn(Opcodes.IFNULL, nullLabel);

    visitor.visitVarInsn(Opcodes.ALOAD, 4);
    visitor.visitVarInsn(Opcodes.ALOAD, 5);
    visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/text/SimpleDateFormat", "format",
            "(Ljava/util/Date;)Ljava/lang/String;");
    visitor.visitVarInsn(Opcodes.ASTORE, 5);

    if (this.var != null) {
        visitor.visitVarInsn(Opcodes.ALOAD, 1);
        var.compile(visitor, Type.STRING);
        visitor.visitVarInsn(Opcodes.ALOAD, 5);
        visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, "com/nginious/http/HttpRequest", "setAttribute",
                "(Ljava/lang/String;Ljava/lang/Object;)V");
    } else {
        visitor.visitVarInsn(Opcodes.ALOAD, 3);
        visitor.visitVarInsn(Opcodes.ALOAD, 5);
        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuffer", "append",
                "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
        visitor.visitInsn(Opcodes.POP);
    }

    visitor.visitLabel(nullLabel);
    visitor.visitInsn(Opcodes.RETURN);

    visitor.visitLabel(startCatchLabel);

    visitor.visitVarInsn(Opcodes.ASTORE, 3);
    visitor.visitTypeInsn(Opcodes.NEW, "com/nginious/http/xsp/XspException");
    visitor.visitInsn(Opcodes.DUP);
    visitor.visitLdcInsn(
            "Attribute value contains an invalid date for tag " + getName() + " at " + getLocationDescriptor());
    visitor.visitVarInsn(Opcodes.ALOAD, 3);
    visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "com/nginious/http/xsp/XspException", "<init>",
            "(Ljava/lang/String;Ljava/lang/Throwable;)V");
    visitor.visitInsn(Opcodes.ATHROW);

    visitor.visitMaxs(6, 6);
    visitor.visitEnd();

    super.compileMethod(intClassName, writer);
}

From source file:com.nginious.http.xsp.MessageTagPart.java

License:Apache License

/**
 * Creates bytecode in a separate method for evaluating this message tag part.
 * /*from   w  w w.j ava2s  .  c  om*/
 * @param intClassName the binary class name of the class being created
 * @param writer the class writer
 * @throws XspException if unable to create bytecode
 */
void compileMethod(String intClassName, ClassWriter writer) throws XspException {
    MethodVisitor visitor = writer.visitMethod(Opcodes.ACC_PRIVATE, this.methodName,
            "(Lcom/nginious/http/HttpRequest;Lcom/nginious/http/HttpResponse;Ljava/lang/StringBuffer;)V", null,
            null);
    visitor.visitCode();

    if (this.var != null) {
        visitor.visitVarInsn(Opcodes.ALOAD, 1);
        var.compile(visitor, Type.STRING);
    } else {
        visitor.visitVarInsn(Opcodes.ALOAD, 3);
    }

    bundle.compile(visitor, Type.STRING);
    visitor.visitVarInsn(Opcodes.ALOAD, 2);
    visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, "com/nginious/http/HttpResponse", "getLocale",
            "()Ljava/util/Locale;");
    visitor.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/ResourceBundle", "getBundle",
            "(Ljava/lang/String;Ljava/util/Locale;)Ljava/util/ResourceBundle;");

    key.compile(visitor, Type.STRING);
    visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/ResourceBundle", "getString",
            "(Ljava/lang/String;)Ljava/lang/String;");

    if (this.args != null) {
        try {
            String expression = args.getExpressionContent();
            ExpressionParser parser = new ExpressionParser();
            TreeExpression expr = parser.parse(expression);

            if (expr.getType() != Type.ANY) {
                throw new XspException("Expression in attribute value in args " + getName()
                        + " is not an attribute or bean property " + " at line " + getLocationDescriptor());
            }

            expr.compile(visitor, Type.ANY);
            visitor.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/Object;");
            visitor.visitMethodInsn(Opcodes.INVOKESTATIC, "java/text/MessageFormat", "format",
                    "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;");
        } catch (ExpressionException e) {
            throw new XspException("Invalid expression in attribute value in tag " + getName() + " at line "
                    + getLocationDescriptor(), e);
        }
    }

    if (this.var != null) {
        visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, "com/nginious/http/HttpRequest", "setAttribute",
                "(Ljava/lang/String;Ljava/lang/Object;)V");
    } else {
        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuffer", "append",
                "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
        visitor.visitInsn(Opcodes.POP);
    }

    visitor.visitInsn(Opcodes.RETURN);
    visitor.visitMaxs(5, 5);
    visitor.visitEnd();

    super.compileMethod(intClassName, writer);
}

From source file:com.nginious.http.xsp.XspCompiler.java

License:Apache License

/**
 * Creates subclass of {@link XspService} for the XSP file represented by the specified document
 * tree node structure.//from www .  ja v  a 2 s.  c om
 * 
 * @param document the document tree node structure
 * @param srcFilePath the XSP file source path
 * @return a descriptor for the generated subclass
 * @throws XspException if unable to create subclass
 */
private ClassDescriptor compileService(DocumentPart document, String srcFilePath) throws XspException {
    ClassWriter writer = new ClassWriter(0);

    // Create class
    String packageName = document.getMetaContent("package");
    String intServiceClazzName = createIntServiceClassName(packageName, srcFilePath);
    String serviceClazzName = createServiceClassName(packageName, srcFilePath);
    writer.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, intServiceClazzName, "Lcom/nginious/http/xsp/XspService;",
            "com/nginious/http/xsp/XspService", null);

    // Create constructor
    createConstructor(writer, "com/nginious/http/xsp/XspService");

    // Create xsp service method
    MethodVisitor visitor = createXspMethod(writer);

    Label tryLabel = new Label();
    Label startCatchLabel = new Label();
    Label endCatchLabel = new Label();

    // Start try block
    visitor.visitTryCatchBlock(tryLabel, startCatchLabel, endCatchLabel, "java/lang/Throwable");

    visitor.visitLabel(tryLabel);

    visitor.visitTypeInsn(Opcodes.NEW, "com/nginious/http/xsp/expr/HttpRequestVariables");
    visitor.visitInsn(Opcodes.DUP);
    visitor.visitVarInsn(Opcodes.ALOAD, 1);
    visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "com/nginious/http/xsp/expr/HttpRequestVariables", "<init>",
            "(Lcom/nginious/http/HttpRequest;)V");
    visitor.visitMethodInsn(Opcodes.INVOKESTATIC, "com/nginious/http/xsp/expr/Expression", "setVariables",
            "(Lcom/nginious/http/xsp/expr/Variables;)V");

    document.compile(intServiceClazzName, writer, visitor);

    visitor.visitLabel(startCatchLabel);
    visitor.visitMethodInsn(Opcodes.INVOKESTATIC, "com/nginious/http/xsp/expr/Expression", "removeVariables",
            "()V");

    visitor.visitLdcInsn(true);
    visitor.visitInsn(Opcodes.IRETURN);

    // Start finally block
    visitor.visitLabel(endCatchLabel);
    visitor.visitMethodInsn(Opcodes.INVOKESTATIC, "com/nginious/http/xsp/expr/Expression", "removeVariables",
            "()V");
    visitor.visitInsn(Opcodes.ATHROW);

    visitor.visitMaxs(12, 12);
    visitor.visitEnd();

    document.compileMethod(intServiceClazzName, writer);

    writer.visitEnd();
    byte[] clazzBytes = writer.toByteArray();
    return new ClassDescriptor(serviceClazzName, clazzBytes);
}

From source file:com.nway.spring.jdbc.bean.AsmBeanProcessor.java

License:Apache License

private void visitMethodCast(MethodVisitor mv, int index, String beanSignature, int beanType,
        String beanTypeDesc, String writeMethod) {

    mv.visitVarInsn(Opcodes.ALOAD, 3);/*from  w  ww . j a va2  s. c  o  m*/
    mv.visitVarInsn(Opcodes.ALOAD, 1);

    visitInsn(mv, index);

    switch (beanType) {
    case PROPERTY_TYPE_DATE:
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/sql/ResultSet", "getTimestamp",
                "(I)Ljava/sql/Timestamp;", true);
        break;
    default:
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/springframework/jdbc/support/JdbcUtils",
                "getResultSetValue", "(Ljava/sql/ResultSet;I)Ljava/lang/Object;", false);
        mv.visitTypeInsn(Opcodes.CHECKCAST, beanTypeDesc);
        break;
    }

    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, beanSignature, writeMethod, "(L" + beanTypeDesc + ";)V", false);
}

From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java

License:Open Source License

/**
 * Calls a method with a set of arguments. After execution the stack may have an extra item pushed on it: the object that was returned
 * by this method (if any)./* ww  w.  jav a2  s.  co  m*/
 * @param method method to call
 * @param args method argument instruction lists -- each instruction list must leave one item on the stack of the type expected
 * by the method (note that if this is a non-static method, the first argument must always evaluate to the "this" pointer/reference)
 * @return instructions to invoke a method
 * @throws NullPointerException if any argument is {@code null} or array contains {@code null}
 * @throws IllegalArgumentException if the length of {@code args} doesn't match the number of parameters in {@code method}
 */
public static InsnList call(Method method, InsnList... args) {
    Validate.notNull(method);
    Validate.notNull(args);
    Validate.noNullElements(args);

    InsnList ret = new InsnList();

    for (InsnList arg : args) {
        ret.add(arg);
    }

    Type clsType = Type.getType(method.getDeclaringClass());
    Type methodType = Type.getType(method);

    if ((method.getModifiers() & Modifier.STATIC) == Modifier.STATIC) {
        Validate.isTrue(method.getParameterCount() == args.length);
        ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, clsType.getInternalName(), method.getName(),
                methodType.getDescriptor(), false));
    } else if (method.getDeclaringClass().isInterface()) {
        Validate.isTrue(method.getParameterCount() + 1 == args.length);
        ret.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, clsType.getInternalName(), method.getName(),
                methodType.getDescriptor(), true));
    } else {
        Validate.isTrue(method.getParameterCount() + 1 == args.length);
        ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, clsType.getInternalName(), method.getName(),
                methodType.getDescriptor(), false));
    }

    return ret;
}

From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java

License:Open Source License

/**
 * Generates instructions to save the operand stack to an object array.
 * @param arrayStackVar variable that the object array containing operand stack is stored
 * @param tempObjectVar variable to use for temporary objects
 * @param frame execution frame at the instruction where the operand stack is to be saved
 * @return instructions to save the operand stack in to an array and save it to the local variables table
 * @throws NullPointerException if any argument is {@code null}
 * @throws IllegalArgumentException if variables have the same index, or if variables have been released, or if variables are of wrong
 * type/* ww w  .j a v a2 s.c om*/
 */
public static InsnList saveOperandStack(Variable arrayStackVar, Variable tempObjectVar,
        Frame<BasicValue> frame) {
    Validate.notNull(arrayStackVar);
    Validate.notNull(tempObjectVar);
    Validate.notNull(frame);
    Validate.isTrue(arrayStackVar.getType().equals(Type.getType(Object[].class)));
    Validate.isTrue(tempObjectVar.getType().equals(Type.getType(Object.class)));
    validateLocalIndicies(arrayStackVar.getIndex(), tempObjectVar.getIndex());

    InsnList ret = new InsnList();

    // Create stack storage array and save it in local vars table
    ret.add(new LdcInsnNode(frame.getStackSize()));
    ret.add(new TypeInsnNode(Opcodes.ANEWARRAY, "java/lang/Object"));
    ret.add(new VarInsnNode(Opcodes.ASTORE, arrayStackVar.getIndex()));

    // Save the stack
    for (int i = frame.getStackSize() - 1; i >= 0; i--) {
        BasicValue basicValue = frame.getStack(i);
        Type type = basicValue.getType();

        // If type is 'Lnull;', this means that the slot has been assigned null and that "there has been no merge yet that would 'raise'
        // the type toward some class or interface type" (from ASM mailing list). We know this slot will always contain null at this
        // point in the code so we can avoid saving it (but we still need to do a POP to get rid of it). When we load it back up, we can
        // simply push a null in to that slot, thereby keeping the same 'Lnull;' type.
        if ("Lnull;".equals(type.getDescriptor())) {
            ret.add(new InsnNode(Opcodes.POP));
            continue;
        }

        // Convert the item to an object (if not already an object) and stores it in local vars table. Item removed from stack.
        switch (type.getSort()) {
        case Type.BOOLEAN:
            ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf",
                    "(Z)Ljava/lang/Boolean;"));
            ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex()));
            break;
        case Type.BYTE:
            ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;",
                    false));
            ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex()));
            break;
        case Type.SHORT:
            ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf",
                    "(S)Ljava/lang/Short;", false));
            ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex()));
            break;
        case Type.CHAR:
            ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf",
                    "(C)Ljava/lang/Character;", false));
            ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex()));
            break;
        case Type.INT:
            ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf",
                    "(I)Ljava/lang/Integer;", false));
            ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex()));
            break;
        case Type.FLOAT:
            ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf",
                    "(F)Ljava/lang/Float;", false));
            ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex()));
            break;
        case Type.LONG:
            ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;",
                    false));
            ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex()));
            break;
        case Type.DOUBLE:
            ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf",
                    "(D)Ljava/lang/Double;", false));
            ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex()));
            break;
        case Type.ARRAY:
        case Type.OBJECT:
            ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex()));
            break;
        case Type.METHOD:
        case Type.VOID:
        default:
            throw new IllegalArgumentException();
        }

        // Store item in to stack storage array
        ret.add(new VarInsnNode(Opcodes.ALOAD, arrayStackVar.getIndex()));
        ret.add(new LdcInsnNode(i));
        ret.add(new VarInsnNode(Opcodes.ALOAD, tempObjectVar.getIndex()));
        ret.add(new InsnNode(Opcodes.AASTORE));
    }

    // Restore the stack
    for (int i = 0; i < frame.getStackSize(); i++) {
        BasicValue basicValue = frame.getStack(i);
        Type type = basicValue.getType();

        // If type is 'Lnull;', this means that the slot has been assigned null and that "there has been no merge yet that would 'raise'
        // the type toward some class or interface type" (from ASM mailing list). We know this slot will always contain null at this
        // point in the code so there's no specific value to load up from the array. Instead we push a null in to that slot, thereby
        // keeping the same 'Lnull;' type originally assigned to that slot (it doesn't make sense to do a CHECKCAST because 'null' is
        // not a real class and can never be a real class -- null is a reserved word in Java).
        if (type.getSort() == Type.OBJECT && "Lnull;".equals(type.getDescriptor())) {
            ret.add(new InsnNode(Opcodes.ACONST_NULL));
            continue;
        }

        // Load item from stack storage array
        ret.add(new VarInsnNode(Opcodes.ALOAD, arrayStackVar.getIndex()));
        ret.add(new LdcInsnNode(i));
        ret.add(new InsnNode(Opcodes.AALOAD));

        // Convert the item to an object (if not already an object) and stores it in local vars table. Item removed from stack.
        switch (type.getSort()) {
        case Type.BOOLEAN:
            ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Boolean"));
            ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z",
                    false));
            break;
        case Type.BYTE:
            ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Byte"));
            ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false));
            break;
        case Type.SHORT:
            ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Short"));
            ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false));
            break;
        case Type.CHAR:
            ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Character"));
            ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C",
                    false));
            break;
        case Type.INT:
            ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Integer"));
            ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false));
            break;
        case Type.FLOAT:
            ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Float"));
            ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false));
            break;
        case Type.LONG:
            ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Long"));
            ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false));
            break;
        case Type.DOUBLE:
            ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Double"));
            ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false));
            break;
        case Type.ARRAY:
        case Type.OBJECT:
            ret.add(new TypeInsnNode(Opcodes.CHECKCAST, basicValue.getType().getInternalName()));
            break;
        case Type.METHOD:
        case Type.VOID:
        default:
            throw new IllegalArgumentException();
        }
    }

    return ret;
}

From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java

License:Open Source License

/**
 * Generates instructions to save the local variables table to an object array.
 *
 * @param arrayLocalsVar variable that the object array containing local variables table is stored
 * @param tempObjectVar variable to use for temporary objects
 * @param frame execution frame at the instruction where the local variables table is to be saved
 * @return instructions to save the local variables table in to an array
 * @throws NullPointerException if any argument is {@code null}
 * @throws IllegalArgumentException if variables have the same index, or if variables have been released, or if variables are of wrong
 * type//from   w  w  w.j a v  a2s  .c o m
 */
public static InsnList saveLocalVariableTable(Variable arrayLocalsVar, Variable tempObjectVar,
        Frame<BasicValue> frame) {
    Validate.notNull(arrayLocalsVar);
    Validate.notNull(tempObjectVar);
    Validate.notNull(frame);
    Validate.isTrue(arrayLocalsVar.getType().equals(Type.getType(Object[].class)));
    Validate.isTrue(tempObjectVar.getType().equals(Type.getType(Object.class)));
    validateLocalIndicies(arrayLocalsVar.getIndex(), tempObjectVar.getIndex());
    InsnList ret = new InsnList();

    // Create array and save it in local vars table
    ret.add(new LdcInsnNode(frame.getLocals()));
    ret.add(new TypeInsnNode(Opcodes.ANEWARRAY, "java/lang/Object"));
    ret.add(new VarInsnNode(Opcodes.ASTORE, arrayLocalsVar.getIndex()));

    // Save the locals
    for (int i = 0; i < frame.getLocals(); i++) {
        BasicValue basicValue = frame.getLocal(i);
        Type type = basicValue.getType();

        // If type == null, basicValue is pointing to uninitialized var -- basicValue.toString() will return '.'. This means that this
        // slot contains nothing to save. So, skip this slot if we encounter it.
        if (type == null) {
            continue;
        }

        // If type is 'Lnull;', this means that the slot has been assigned null and that "there has been no merge yet that would 'raise'
        // the type toward some class or interface type" (from ASM mailing list). We know this slot will always contain null at this
        // point in the code so we can avoid saving it. When we load it back up, we can simply push a null in to that slot, thereby
        // keeping the same 'Lnull;' type.
        if ("Lnull;".equals(type.getDescriptor())) {
            continue;
        }

        // Convert the item to an object (if not already an object) and stores it in array.
        switch (type.getSort()) {
        case Type.BOOLEAN:
            ret.add(new VarInsnNode(Opcodes.ILOAD, i));
            ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf",
                    "(Z)Ljava/lang/Boolean;"));
            ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex()));
            break;
        case Type.BYTE:
            ret.add(new VarInsnNode(Opcodes.ILOAD, i));
            ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;",
                    false));
            ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex()));
            break;
        case Type.SHORT:
            ret.add(new VarInsnNode(Opcodes.ILOAD, i));
            ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf",
                    "(S)Ljava/lang/Short;", false));
            ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex()));
            break;
        case Type.CHAR:
            ret.add(new VarInsnNode(Opcodes.ILOAD, i));
            ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf",
                    "(C)Ljava/lang/Character;", false));
            ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex()));
            break;
        case Type.INT:
            ret.add(new VarInsnNode(Opcodes.ILOAD, i));
            ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf",
                    "(I)Ljava/lang/Integer;", false));
            ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex()));
            break;
        case Type.FLOAT:
            ret.add(new VarInsnNode(Opcodes.FLOAD, i));
            ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf",
                    "(F)Ljava/lang/Float;", false));
            ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex()));
            break;
        case Type.LONG:
            ret.add(new VarInsnNode(Opcodes.LLOAD, i));
            ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;",
                    false));
            ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex()));
            break;
        case Type.DOUBLE:
            ret.add(new VarInsnNode(Opcodes.DLOAD, i));
            ret.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf",
                    "(D)Ljava/lang/Double;", false));
            ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex()));
            break;
        case Type.ARRAY:
        case Type.OBJECT:
            ret.add(new VarInsnNode(Opcodes.ALOAD, i));
            ret.add(new VarInsnNode(Opcodes.ASTORE, tempObjectVar.getIndex()));
            break;
        case Type.METHOD:
        case Type.VOID:
        default:
            throw new IllegalStateException();
        }

        // Store item in to locals storage array
        ret.add(new VarInsnNode(Opcodes.ALOAD, arrayLocalsVar.getIndex()));
        ret.add(new LdcInsnNode(i));
        ret.add(new VarInsnNode(Opcodes.ALOAD, tempObjectVar.getIndex()));
        ret.add(new InsnNode(Opcodes.AASTORE));
    }

    return ret;
}

From source file:com.offbynull.coroutines.instrumenter.asm.MethodInvokeUtils.java

License:Open Source License

/**
 * Get the number of arguments required for an invocation of some method. This includes the 'this' argument for non-static methods.
 * <p>//from   ww  w  . j a  va 2s.co m
 * NOTE THAT THIS IS NOT THE NUMBER OF ITEMS ON THE STACK. If the method takes in doubles or longs, each double or long encountered
 * would be 2 items on the stack. This method returns the number of arguments required for the method to be invoked, not the number of
 * items required to be on the stack for the method to be invoked.
 * @param invokeNode the invocation instruction (either normal invocation or invokedynamic)
 * @return number of arguments required by this method
 * @throws NullPointerException if any argument is {@code null}
 * @throws IllegalArgumentException if {@code invokeNode} is neither of type {@link MethodInsnNode} nor {@link InvokeDynamicInsnNode},
 * or if type of invocation ({@link MethodInsnNode}) cannot be determined
 */
public static int getArgumentCountRequiredForInvocation(AbstractInsnNode invokeNode) {
    Validate.notNull(invokeNode);

    if (invokeNode instanceof MethodInsnNode) {
        MethodInsnNode methodInsnNode = (MethodInsnNode) invokeNode;
        int extra;
        int paramCount;

        switch (methodInsnNode.getOpcode()) {
        case Opcodes.INVOKEVIRTUAL:
        case Opcodes.INVOKESPECIAL:
        case Opcodes.INVOKEINTERFACE:
            extra = 1;
            break;
        case Opcodes.INVOKESTATIC:
            extra = 0;
            break;
        default:
            throw new IllegalArgumentException(); // unknown invocation type? probably badly generated instruction node
        }
        Type methodType = Type.getType(methodInsnNode.desc);
        paramCount = methodType.getArgumentTypes().length;

        return paramCount + extra;
    } else if (invokeNode instanceof InvokeDynamicInsnNode) {
        InvokeDynamicInsnNode invokeDynamicInsnNode = (InvokeDynamicInsnNode) invokeNode;
        int paramCount;

        Type methodType = Type.getType(invokeDynamicInsnNode.desc);
        paramCount = methodType.getArgumentTypes().length;

        return paramCount;
    } else {
        throw new IllegalArgumentException();
    }
}

From source file:com.offbynull.coroutines.instrumenter.asm.MethodInvokeUtilsTest.java

License:Open Source License

@Test
public void mustProperlyDetermineStackSizeForStaticMethod() {
    Type type = Type.getType(MethodUtils.getAccessibleMethod(Integer.class, "decode", String.class));
    MethodInsnNode methodInsnNode = new MethodInsnNode(Opcodes.INVOKESTATIC, "java/util/Integer", "decode",
            type.getDescriptor(), false);
    int reqStackCount = MethodInvokeUtils.getArgumentCountRequiredForInvocation(methodInsnNode);

    assertEquals(1, reqStackCount);/* w w  w  . jav a  2s. co m*/
}