Example usage for org.objectweb.asm Opcodes INTEGER

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

Introduction

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

Prototype

Integer INTEGER

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

Click Source Link

Usage

From source file:org.jacoco.core.internal.instr.FrameTracker.java

License:Open Source License

@Override
public void visitLdcInsn(final Object cst) {
    if (cst instanceof Integer) {
        push(Opcodes.INTEGER);
    } else if (cst instanceof Float) {
        push(Opcodes.FLOAT);//from   www.jav  a  2  s.  c om
    } else if (cst instanceof Long) {
        push(Opcodes.LONG);
        push(Opcodes.TOP);
    } else if (cst instanceof Double) {
        push(Opcodes.DOUBLE);
        push(Opcodes.TOP);
    } else if (cst instanceof String) {
        push("java/lang/String");
    } else if (cst instanceof Type) {
        push("java/lang/Class");
    } else {
        throw new IllegalArgumentException();
    }
    mv.visitLdcInsn(cst);
}

From source file:org.jacoco.core.internal.instr.FrameTracker.java

License:Open Source License

@Override
public void visitIincInsn(final int var, final int increment) {
    set(var, Opcodes.INTEGER);
    mv.visitIincInsn(var, increment);
}

From source file:org.jacoco.core.internal.instr.FrameTracker.java

License:Open Source License

private void push(final Type type) {
    switch (type.getSort()) {
    case Type.VOID:
        break;//from   w w w. j  a v a2  s .  c om
    case Type.BOOLEAN:
    case Type.BYTE:
    case Type.CHAR:
    case Type.INT:
    case Type.SHORT:
        push(Opcodes.INTEGER);
        break;
    case Type.FLOAT:
        push(Opcodes.FLOAT);
        break;
    case Type.LONG:
        push(Opcodes.LONG);
        push(Opcodes.TOP);
        break;
    case Type.DOUBLE:
        push(Opcodes.DOUBLE);
        push(Opcodes.TOP);
        break;
    case Type.ARRAY:
    case Type.OBJECT:
        push(type.getInternalName());
        break;
    default:
        throw new AssertionError(type);
    }
}

From source file:org.jacoco.core.internal.instr.FrameTracker.java

License:Open Source License

private void set(final int pos, final Type type) {
    switch (type.getSort()) {
    case Type.BOOLEAN:
    case Type.BYTE:
    case Type.CHAR:
    case Type.INT:
    case Type.SHORT:
        set(pos, Opcodes.INTEGER);
        break;/*from  w w  w  .j av a2  s  . c om*/
    case Type.FLOAT:
        set(pos, Opcodes.FLOAT);
        break;
    case Type.LONG:
        set(pos, Opcodes.LONG);
        set(pos + 1, Opcodes.TOP);
        break;
    case Type.DOUBLE:
        set(pos, Opcodes.DOUBLE);
        set(pos + 1, Opcodes.TOP);
        break;
    case Type.ARRAY:
    case Type.OBJECT:
        set(pos, type.getInternalName());
        break;
    default:
        throw new AssertionError(type);
    }
}

From source file:org.jboss.byteman.agent.adapter.RuleGeneratorAdapter.java

License:Open Source License

private void dumpType(StringBuffer buffer, Object t) {

    if (t == Opcodes.TOP) {
        buffer.append("TOP");
    } else if (t == null) {
        buffer.append("null");
    } else if (t == Opcodes.INTEGER) {
        buffer.append("int");
    } else if (t == Opcodes.FLOAT) {
        buffer.append("float");
    } else if (t == Opcodes.DOUBLE) {
        buffer.append("double");
    } else if (t == Opcodes.LONG) {
        buffer.append("long");
    } else if (t == Opcodes.NULL) {
        buffer.append("null");
    } else if (t == Opcodes.UNINITIALIZED_THIS) {
        buffer.append("uninit_this");
    } else if (t instanceof String) {
        buffer.append((String) t);
    } else {//w  w  w. j  a  va  2s  .  co m
        buffer.append(((Label) t).getOffset());
    }
}

From source file:org.jboss.byteman.agent.adapter.RuleGeneratorAdapter.java

License:Open Source License

public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack,
        final Object[] stack) {
    if (type != Opcodes.F_NEW) { // uncompressed frame
        throw new IllegalStateException("ClassReader.accept() should be called with EXPAND_FRAMES flag");
    }/*w w w  .ja v  a  2s. c o  m*/

    // dumpFrame(nLocal, local, nStack, stack);

    // adjust the local types array

    int toRemove = localTypes.size();

    for (int i = toRemove; i > 0; i--) {
        localTypes.remove(i - 1);
    }

    int nextLocal = 0;

    for (int i = 0; i < nLocal; i++) {
        Object t = local[i];
        if (t == Opcodes.TOP) {
            localTypes.add(null);
        } else if (t == null) {
            localTypes.add(null);
        } else if (t == Opcodes.INTEGER) {
            localTypes.add(Type.INT_TYPE);
        } else if (t == Opcodes.FLOAT) {
            localTypes.add(Type.FLOAT_TYPE);
        } else if (t == Opcodes.DOUBLE) {
            localTypes.add(Type.DOUBLE_TYPE);
            nextLocal++;
            localTypes.add(null);
        } else if (t == Opcodes.LONG) {
            localTypes.add(Type.LONG_TYPE);
            nextLocal++;
            localTypes.add(null);
        } else if (t == Opcodes.NULL) {
            localTypes.add(null);
        } else if (t == Opcodes.UNINITIALIZED_THIS) {
            localTypes.add(null);
        } else if (t instanceof String) {
            localTypes.add(Type.getObjectType((String) t));
        } else {
            localTypes.add(null);
        }
        nextLocal++;
    }

    this.nextLocal = nextLocal;

    mv.visitFrame(type, nLocal, local, nStack, stack);
}

From source file:org.kjots.json.object.JsonObjectGeneratorBase.java

License:Apache License

/**
 * Generate a get Java character primitive property method.
 *
 * @param classVisitor The class visitor.
 * @param jsonObjectImplType The type of the JSON object implementation.
 * @param method The method.//w  w  w. j  ava 2  s.c  om
 * @param propertyName The name of the property.
 */
private void generateGetJavaCharacterPrimitivePropertyMethod(ClassVisitor classVisitor, Type jsonObjectImplType,
        Method method, String propertyName) {
    Type jsonStringPrimitiveType = Type.getType(String.class);

    MethodVisitor methodVisitor = classVisitor.visitMethod(ACC_PUBLIC + ACC_FINAL, method, null, null);

    Label start = new Label();
    Label l0 = new Label();
    Label l1 = new Label();
    Label end = new Label();

    methodVisitor.visitCode();

    methodVisitor.visitLabel(start);
    methodVisitor.visitVarInsn(ALOAD, 0);
    methodVisitor.visitLdcInsn(propertyName);
    methodVisitor.visitMethodInsn(INVOKEVIRTUAL, jsonObjectImplType,
            this.getGetJsonPrimitivePropertyMethod(jsonStringPrimitiveType));
    methodVisitor.visitVarInsn(ASTORE, 1);
    methodVisitor.visitVarInsn(ALOAD, 1);
    methodVisitor.visitJumpInsn(IFNULL, l0);
    methodVisitor.visitVarInsn(ALOAD, 1);
    methodVisitor.visitMethodInsn(INVOKEVIRTUAL, jsonStringPrimitiveType,
            new Method("isEmpty", Type.BOOLEAN_TYPE, new Type[] {}));
    methodVisitor.visitJumpInsn(IFNE, l0);
    methodVisitor.visitVarInsn(ALOAD, 1);
    methodVisitor.visitInsn(ICONST_0);
    methodVisitor.visitMethodInsn(INVOKEVIRTUAL, jsonStringPrimitiveType,
            new Method("charAt", Type.CHAR_TYPE, new Type[] { Type.INT_TYPE }));
    methodVisitor.visitJumpInsn(GOTO, l1);
    methodVisitor.visitLabel(l0);
    methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] { jsonStringPrimitiveType }, 0, null);
    methodVisitor.visitInsn(ICONST_0);
    methodVisitor.visitLabel(l1);
    methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { Opcodes.INTEGER });
    methodVisitor.visitInsn(IRETURN);
    methodVisitor.visitLabel(end);

    methodVisitor.visitLocalVariable("this", jsonObjectImplType, null, start, end, 0);
    methodVisitor.visitLocalVariable("_" + propertyName, jsonStringPrimitiveType, null, start, end, 1);
    methodVisitor.visitMaxs(2, 2);

    methodVisitor.visitEnd();
}

From source file:org.simantics.databoard.binding.reflection.AsmBindingClassLoader.java

License:Open Source License

public byte[] createBindingClass(ClassInfo ci, String bindingClassName) {
    //System.out.println("BindingFactory: "+bindingClassName+" (for "+ci.clazz.getClassLoader()+")");
    int count = ci.fields.length;
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
    ClassVisitor cv = cw;//new CheckClassAdapter(cw);

    FieldVisitor fv;/*from   w w  w  .  j  av a2s. com*/
    MethodVisitor mv;
    AnnotationVisitor av0;

    String className = ci.clazz.getName().replaceAll("\\.", "/");
    bindingClassName = bindingClassName.replaceAll("\\.", "/");
    Object[] classNameX = new Object[] { className };
    String signature = "L" + bindingClassName + ";";

    // Constructor
    String superClass = "org/simantics/databoard/binding/reflection/ClassBinding";
    cv.visit(V1_6, ACC_PUBLIC + ACC_SUPER, bindingClassName, null, superClass, null);

    // Constructor
    {
        mv = cv.visitMethod(ACC_PUBLIC, "<init>", "(Lorg/simantics/databoard/type/RecordType;)V", null,
                new String[] { "org/simantics/databoard/binding/error/BindingConstructionException" });

        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitLdcInsn(Type.getType("L" + className + ";"));
        mv.visitMethodInsn(INVOKESPECIAL, superClass, "<init>", "(Ljava/lang/Class;)V");

        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitFieldInsn(PUTFIELD, bindingClassName, "type", "Lorg/simantics/databoard/type/Datatype;");

        Label l2 = new Label();
        mv.visitLabel(l2);
        mv.visitInsn(RETURN);

        Label l3 = new Label();
        mv.visitLabel(l3);
        mv.visitLocalVariable("this", signature, null, l0, l3, 0);
        mv.visitLocalVariable("type", "Lorg/simantics/databoard/type/RecordType;", null, l0, l3, 1);
        mv.visitMaxs(2, 2);
        mv.visitEnd();
    }

    // getComponent
    {
        mv = cv.visitMethod(ACC_PUBLIC, "getComponent", "(Ljava/lang/Object;I)Ljava/lang/Object;", null,
                new String[] { "org/simantics/databoard/binding/error/BindingException" });
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitTypeInsn(CHECKCAST, className);
        mv.visitVarInsn(ASTORE, 3);
        Label l1 = new Label();
        mv.visitLabel(l1);

        Label caseLabels[] = createFieldLabels(ci);
        Label elseLabel = new Label();

        if (count > 0) {
            // Switch
            mv.visitVarInsn(ILOAD, 2);
            mv.visitTableSwitchInsn(0, count - 1, elseLabel, caseLabels);

            // case i: x.field = value[i]
            for (int i = 0; i < count; i++) {
                Label label = caseLabels[i];
                Field field = ci.fields[i];
                String fieldName = field.getName();
                Class<?> fieldClass = ci.fields[i].getType();
                String typeDescriptor = toTypeDescriptor(fieldClass);

                Method getter = ci.getters[i];
                boolean useGetter = ((field.getModifiers() & Modifier.PUBLIC) == 0) && getter != null;

                mv.visitLabel(label);
                if (i == 0) {
                    mv.visitFrame(Opcodes.F_APPEND, 1, classNameX, 0, null);
                } else {
                    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                }

                // Read instance argument
                mv.visitVarInsn(ALOAD, 3);

                if (useGetter) {
                    // call getField
                    mv.visitMethodInsn(INVOKEVIRTUAL, className, getter.getName(), "()" + typeDescriptor);
                } else {
                    // Read field
                    mv.visitFieldInsn(GETFIELD, className, fieldName, typeDescriptor);
                }

                // Box 
                box(mv, fieldClass);

                mv.visitInsn(ARETURN);
            }

        }

        mv.visitLabel(elseLabel);
        if (count > 0) {
            mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        }
        mv.visitTypeInsn(NEW, "org/simantics/databoard/binding/error/BindingException");
        mv.visitInsn(DUP);
        mv.visitLdcInsn("Illegal field index");
        mv.visitMethodInsn(INVOKESPECIAL, "org/simantics/databoard/binding/error/BindingException", "<init>",
                "(Ljava/lang/String;)V");
        mv.visitInsn(ATHROW);

        // End 
        Label l19 = new Label();
        mv.visitLabel(l19);
        mv.visitLocalVariable("this", "L" + className + ";", null, l0, l19, 0);
        mv.visitLocalVariable("obj", "Ljava/lang/Object;", null, l0, l19, 1);
        mv.visitLocalVariable("index", "I", null, l0, l19, 2);
        //mv.visitLocalVariable("x", "Lorg/simantics/databoard/binding/reflection/MyClass;", null, l1, l19, 3);
        mv.visitMaxs(3, 4);
        mv.visitEnd();
    }

    // Create
    {
        mv = cv.visitMethod(ACC_PUBLIC + ACC_VARARGS, "create", "([Ljava/lang/Object;)Ljava/lang/Object;", null,
                new String[] { "org/simantics/databoard/binding/error/BindingException" });
        if (ci.beanConstructor != null) {
            mv.visitCode();
            Label l0 = new Label();
            mv.visitLabel(l0);
            mv.visitTypeInsn(NEW, className);
            mv.visitInsn(DUP);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKESPECIAL, className, "<init>",
                    "(Lorg/simantics/databoard/binding/Binding;)V");
            mv.visitVarInsn(ASTORE, 2);
            Label l1 = new Label();
            mv.visitLabel(l1);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitVarInsn(ALOAD, 2);
            mv.visitVarInsn(ALOAD, 1);
            mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "setComponents",
                    "(Ljava/lang/Object;[Ljava/lang/Object;)V");
            Label l2 = new Label();
            mv.visitLabel(l2);
            mv.visitVarInsn(ALOAD, 2);
            mv.visitInsn(ARETURN);
            Label l3 = new Label();
            mv.visitLabel(l3);
            mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l3, 0);
            mv.visitLocalVariable("values", "[Ljava/lang/Object;", null, l0, l3, 1);
            //mv.visitLocalVariable("x", "L"+className+";", null, l1, l3, 2);
            mv.visitMaxs(3, 3);
            mv.visitEnd();
        } else if (ci.argsConstructor != null) {
            mv.visitCode();
            Label l0 = new Label();
            mv.visitLabel(l0);
            mv.visitTypeInsn(NEW, className);
            mv.visitInsn(DUP);

            String constArgsDescriptor = "(";
            Class<?>[] args = ci.argsConstructor.getParameterTypes();
            for (int i = 0; i < count; i++) {
                Label label = new Label();
                Class<?> field = args[i];
                String fieldName = field.getName();
                Method getter = ci.getters[i];
                Class<?> fieldClass = ci.fields[i].getType();
                Class<?> boxClass = getBoxClass(fieldClass);
                String typeDescriptor = toTypeDescriptor(fieldClass);
                String boxTypeDescriptor = toTypeDescriptor(boxClass);
                constArgsDescriptor += typeDescriptor;

                mv.visitLabel(label);
                mv.visitVarInsn(ALOAD, 1);
                if (i < 6) {
                    mv.visitInsn(ICONST_0 + i);
                } else {
                    mv.visitIntInsn(BIPUSH, i);
                }

                mv.visitInsn(AALOAD);
                mv.visitTypeInsn(CHECKCAST, toClassCanonicalName(boxClass));
                unbox(mv, fieldClass);
            }

            Label l17 = new Label();
            mv.visitLabel(l17);
            constArgsDescriptor += ")V";
            mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", constArgsDescriptor);
            mv.visitInsn(ARETURN);
            Label l18 = new Label();
            mv.visitLabel(l18);
            mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l18, 0);
            mv.visitLocalVariable("values", "[Ljava/lang/Object;", null, l0, l18, 1);
            mv.visitMaxs(21, 2);
            mv.visitEnd();

        } else {
            mv.visitCode();
            Label l0 = new Label();
            mv.visitLabel(l0);
            mv.visitTypeInsn(NEW, className);
            mv.visitInsn(DUP);
            mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "()V");
            mv.visitVarInsn(ASTORE, 2);
            Label l1 = new Label();
            mv.visitLabel(l1);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitVarInsn(ALOAD, 2);
            mv.visitVarInsn(ALOAD, 1);
            mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "setComponents",
                    "(Ljava/lang/Object;[Ljava/lang/Object;)V");
            Label l2 = new Label();
            mv.visitLabel(l2);
            mv.visitVarInsn(ALOAD, 2);
            mv.visitInsn(ARETURN);
            Label l3 = new Label();
            mv.visitLabel(l3);
            mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l3, 0);
            mv.visitLocalVariable("values", "[Ljava/lang/Object;", null, l0, l3, 1);
            //mv.visitLocalVariable("x", "L"+className+";", null, l1, l3, 2);
            mv.visitMaxs(3, 3);
            mv.visitEnd();
        }
    }

    // CreatePartial
    mv = cv.visitMethod(ACC_PUBLIC, "createPartial", "()Ljava/lang/Object;", null,
            new String[] { "org/simantics/databoard/binding/error/BindingException" });
    if (ci.beanConstructor != null) {
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitTypeInsn(NEW, className);
        mv.visitInsn(DUP);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "(Lorg/simantics/databoard/binding/Binding;)V");
        mv.visitInsn(ARETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l1, 0);
        mv.visitMaxs(3, 1);
        mv.visitEnd();
    } else if (ci.noArgsConstructor != null) {
        // return new MyClass();
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitTypeInsn(NEW, className);
        mv.visitInsn(DUP);
        mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "()V");
        mv.visitInsn(ARETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l1, 0);
        mv.visitMaxs(2, 1);
        mv.visitEnd();
    } else {
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitIntInsn(BIPUSH, count);
        mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
        mv.visitVarInsn(ASTORE, 1);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitInsn(ICONST_0);
        mv.visitVarInsn(ISTORE, 2);
        Label l2 = new Label();
        mv.visitLabel(l2);
        Label l3 = new Label();
        mv.visitJumpInsn(GOTO, l3);
        Label l4 = new Label();
        mv.visitLabel(l4);
        mv.visitFrame(Opcodes.F_APPEND, 2, new Object[] { "[Ljava/lang/Object;", Opcodes.INTEGER }, 0, null);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, bindingClassName, "componentBindings",
                "[Lorg/simantics/databoard/binding/Binding;");
        mv.visitVarInsn(ILOAD, 2);
        mv.visitInsn(AALOAD);
        mv.visitVarInsn(ASTORE, 3);
        Label l5 = new Label();
        mv.visitLabel(l5);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitVarInsn(ILOAD, 2);
        mv.visitVarInsn(ALOAD, 3);
        mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/Binding", "createDefault",
                "()Ljava/lang/Object;");
        mv.visitInsn(AASTORE);
        Label l6 = new Label();
        mv.visitLabel(l6);
        mv.visitIincInsn(2, 1);
        mv.visitLabel(l3);
        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        mv.visitVarInsn(ILOAD, 2);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitInsn(ARRAYLENGTH);
        mv.visitJumpInsn(IF_ICMPLT, l4);
        Label l7 = new Label();
        mv.visitLabel(l7);
        mv.visitLineNumber(109, l7);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "create",
                "([Ljava/lang/Object;)Ljava/lang/Object;");
        mv.visitInsn(ARETURN);
        Label l8 = new Label();
        mv.visitLabel(l8);
        mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l8, 0);
        mv.visitLocalVariable("values", "[Ljava/lang/Object;", null, l1, l8, 1);
        mv.visitLocalVariable("i", "I", null, l2, l7, 2);
        mv.visitLocalVariable("fb", "Lorg/simantics/databoard/binding/Binding;", null, l5, l6, 3);
        mv.visitMaxs(3, 4);
        mv.visitEnd();
    }

    // setComponent
    {
        mv = cv.visitMethod(ACC_PUBLIC, "setComponent", "(Ljava/lang/Object;ILjava/lang/Object;)V", null,
                new String[] { "org/simantics/databoard/binding/error/BindingException" });
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitTypeInsn(CHECKCAST, className);
        mv.visitVarInsn(ASTORE, 4);
        Label endLabel = new Label();
        Label l1 = new Label();
        mv.visitLabel(l1);

        Label elseLabel = new Label();
        Label labels[] = new Label[count];
        for (int i = 0; i < count; i++)
            labels[i] = new Label();

        if (count > 0) {
            mv.visitVarInsn(ILOAD, 2);
            mv.visitTableSwitchInsn(0, count - 1, elseLabel, labels);

            for (int i = 0; i < count; i++) {
                Label label = labels[i];
                mv.visitLabel(label);
                Field field = ci.fields[i];
                String fieldName = field.getName();
                Class<?> fieldClass = ci.fields[i].getType();
                Class<?> boxClass = getBoxClass(fieldClass);
                String typeDescriptor = toTypeDescriptor(fieldClass);
                String boxTypeDescriptor = toTypeDescriptor(boxClass);

                Method setter = ci.setters[i];
                Class<?> setterClass = setter != null ? setter.getParameterTypes()[0] : null;
                boolean useSetter = ((field.getModifiers() & Modifier.PUBLIC) == 0) && setter != null;

                if (i == 0) {
                    mv.visitFrame(Opcodes.F_APPEND, 1, classNameX, 0, null);
                } else {
                    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                }
                mv.visitVarInsn(ALOAD, 4);
                mv.visitVarInsn(ALOAD, 3);
                mv.visitTypeInsn(CHECKCAST, toClassCanonicalName(boxClass));

                if (useSetter) {
                    unbox(mv, setterClass);
                    mv.visitMethodInsn(INVOKEVIRTUAL, className, setter.getName(), "(" + typeDescriptor + ")V");
                } else {
                    unbox(mv, fieldClass);
                    mv.visitFieldInsn(PUTFIELD, className, field.getName(), typeDescriptor);
                }
                mv.visitInsn(RETURN);
            }
        }

        mv.visitLabel(elseLabel);
        mv.visitLineNumber(178, elseLabel);
        if (count > 0) {
            mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        }
        mv.visitTypeInsn(NEW, "org/simantics/databoard/binding/error/BindingException");
        mv.visitInsn(DUP);
        mv.visitLdcInsn("Illegal field index");
        mv.visitMethodInsn(INVOKESPECIAL, "org/simantics/databoard/binding/error/BindingException", "<init>",
                "(Ljava/lang/String;)V");
        mv.visitInsn(ATHROW);

        mv.visitLabel(endLabel);
        mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, endLabel, 0);
        mv.visitLocalVariable("obj", "Ljava/lang/Object;", null, l0, endLabel, 1);
        mv.visitLocalVariable("index", "I", null, l0, endLabel, 2);
        mv.visitLocalVariable("value", "Ljava/lang/Object;", null, l0, endLabel, 3);
        //mv.visitLocalVariable("x", "L"+className+";", null, l1, endLabel, 4);
        mv.visitMaxs(3, 5);
        mv.visitEnd();
    }

    // IsImmutable
    {
        mv = cv.visitMethod(ACC_PUBLIC, "isImmutable", "()Z", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitInsn(ICONST_0);
        mv.visitInsn(IRETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", "L" + className + ";", null, l0, l1, 0);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }

    // IsInstance
    {
        mv = cv.visitMethod(ACC_PUBLIC, "isInstance", "(Ljava/lang/Object;)Z", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitTypeInsn(INSTANCEOF, className);
        mv.visitInsn(IRETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", "L" + className + ";", null, l0, l1, 0);
        mv.visitLocalVariable("obj", "Ljava/lang/Object;", null, l0, l1, 1);
        mv.visitMaxs(1, 2);
        mv.visitEnd();
    }

    // SetComponents
    {
        mv = cv.visitMethod(ACC_PUBLIC + ACC_VARARGS, "setComponents",
                "(Ljava/lang/Object;[Ljava/lang/Object;)V", null,
                new String[] { "org/simantics/databoard/binding/error/BindingException" });
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitTypeInsn(CHECKCAST, className);
        mv.visitVarInsn(ASTORE, 3);
        Label firstLabel = l0;

        for (int i = 0; i < count; i++) {
            Label label = new Label();
            if (firstLabel == l0)
                firstLabel = label;
            Field field = ci.fields[i];
            String fieldName = field.getName();
            Class<?> fieldClass = ci.fields[i].getType();
            Class<?> boxClass = getBoxClass(fieldClass);
            String typeDescriptor = toTypeDescriptor(fieldClass);
            String boxTypeDescriptor = toTypeDescriptor(boxClass);

            Method setter = ci.setters[i];
            Class<?> setterClass = setter != null ? setter.getParameterTypes()[0] : null;
            boolean useSetter = ((field.getModifiers() & Modifier.PUBLIC) == 0) && setter != null;

            mv.visitLabel(label);
            mv.visitVarInsn(ALOAD, 3);
            mv.visitVarInsn(ALOAD, 2);
            if (i < 6) {
                mv.visitInsn(ICONST_0 + i);
            } else {
                mv.visitIntInsn(BIPUSH, i);
            }
            mv.visitInsn(AALOAD);
            mv.visitTypeInsn(CHECKCAST, toClassCanonicalName(boxClass));

            if (useSetter) {
                unbox(mv, setterClass);
                mv.visitMethodInsn(INVOKEVIRTUAL, className, setter.getName(), "(" + typeDescriptor + ")V");
            } else {
                unbox(mv, fieldClass);
                mv.visitFieldInsn(PUTFIELD, className, field.getName(), typeDescriptor);
            }

        }
        Label l17 = new Label();
        mv.visitLabel(l17);
        mv.visitInsn(RETURN);
        Label endLabel = new Label();
        mv.visitLabel(endLabel);
        mv.visitLocalVariable("this", "L" + className + ";", null, l0, endLabel, 0);
        mv.visitLocalVariable("obj", "Ljava/lang/Object;", null, l0, endLabel, 1);
        mv.visitLocalVariable("value", "[Ljava/lang/Object;", null, l0, endLabel, 2);
        //mv.visitLocalVariable("x", "Lorg/simantics/databoard/binding/reflection/MyClass;", null, firstLabel, endLabel, 3);
        mv.visitMaxs(3, 4);
        mv.visitEnd();
    }

    // Add primitive setters
    {
        addGetSetPrimitive(ci, cv, "Boolean", "Z", bindingClassName);
        addGetSetPrimitive(ci, cv, "Byte", "B", bindingClassName);
        addGetSetPrimitive(ci, cv, "Int", "I", bindingClassName);
        addGetSetPrimitive(ci, cv, "Long", "J", bindingClassName);
        addGetSetPrimitive(ci, cv, "Float", "F", bindingClassName);
        addGetSetPrimitive(ci, cv, "Double", "D", bindingClassName);
    }

    cv.visitEnd();
    return cw.toByteArray();
}

From source file:org.simantics.databoard.tests.testASM.java

License:Open Source License

void createImpl(String className, Class<?> interfaze, ClassWriter cw) {
    FieldVisitor fv;//  w w w  . j a  v a  2 s.c  o  m
    MethodVisitor mv;
    AnnotationVisitor av0;

    java.lang.reflect.Method[] methods = interfaze.getMethods();
    Arrays.sort(methods, MethodInterfaceUtil.methodComparator);

    String classResourceName = className.replaceAll("\\.", "/");
    String classTypeDescriptor = "L" + classResourceName + ";";
    String interfaceResourceName = classResourceName.substring(0, classResourceName.length() - 5);
    String interfaceTypeDescriptor = "L" + interfaceResourceName + ";";

    cw.visit(V1_6, ACC_SUPER | ACC_PUBLIC, classResourceName, null, "java/lang/Object",
            new String[] { interfaceResourceName });

    // Imports
    Set<Class<?>> imports = new HashSet<Class<?>>();
    imports.add(AsyncResult.class);
    imports.add(ExecutionError.class);
    imports.add(Method.class);
    imports.add(interfaze);

    for (java.lang.reflect.Method m : methods) {
        for (Class<?> clazz : m.getExceptionTypes()) {
            imports.add(clazz);
        }
        for (Class<?> clazz : m.getParameterTypes()) {
            imports.add(clazz);
        }
        imports.add(m.getReturnType());
    }

    for (Class<?> clazz : imports) {
        if (clazz.isPrimitive())
            continue;
        String name = clazz.getName();
        if (name.startsWith("java.lang"))
            continue;
        String resourceName = name.replaceAll("\\.", "/");
        String outerName = resourceName.contains("$") ? resourceName.substring(0, resourceName.indexOf('$'))
                : null;
        String className_ = clazz.isArray()
                ? clazz.getSimpleName().substring(0, clazz.getSimpleName().length() - 2)
                : clazz.getSimpleName();
        int access = ACC_PUBLIC + ACC_STATIC + (clazz.isInterface() ? ACC_INTERFACE + ACC_ABSTRACT : 0);
        //         System.out.printf("name=%s, outerName=%s, innerName=%s\n", resourceName, outerName, className_);
        cw.visitInnerClass(resourceName, outerName, className_, access);
    }

    // Fields
    {
        fv = cw.visitField(ACC_FINAL + ACC_STATIC, "interfaze", "Ljava/lang/Class;", "Ljava/lang/Class<*>;",
                null);
        fv.visitEnd();
    }
    {
        fv = cw.visitField(ACC_FINAL + ACC_STATIC, "bindings",
                "[Lorg/simantics/databoard/method/MethodBinding;", null, null);
        fv.visitEnd();
    }
    {
        fv = cw.visitField(0, "mi", "Lorg/simantics/data/session/MethodInterface;", null, null);
        fv.visitEnd();
    }
    {
        fv = cw.visitField(0, "methods", "[Lorg/simantics/data/session/MethodInterface$Method;", null, null);
        fv.visitEnd();
    }

    // Init class - static {}
    {
        mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitLdcInsn(Type.getType(interfaceTypeDescriptor));
        mv.visitFieldInsn(PUTSTATIC, classResourceName, "interfaze", "Ljava/lang/Class;");
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitFieldInsn(GETSTATIC, classResourceName, "interfaze", "Ljava/lang/Class;");
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethods", "()[Ljava/lang/reflect/Method;");
        mv.visitVarInsn(ASTORE, 0);
        Label l2 = new Label();
        mv.visitLabel(l2);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETSTATIC, "org/simantics/data/network/MethodInterfaceUtil", "methodComparator",
                "Ljava/util/Comparator;");
        mv.visitMethodInsn(INVOKESTATIC, "java/util/Arrays", "sort",
                "([Ljava/lang/Object;Ljava/util/Comparator;)V");
        Label l3 = new Label();
        mv.visitLabel(l3);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitInsn(ARRAYLENGTH);
        mv.visitTypeInsn(ANEWARRAY, "org/simantics/databoard/method/MethodBinding");
        mv.visitFieldInsn(PUTSTATIC, classResourceName, "bindings",
                "[Lorg/simantics/databoard/method/MethodBinding;");
        Label l4 = new Label();
        mv.visitLabel(l4);
        mv.visitInsn(ICONST_0);
        mv.visitVarInsn(ISTORE, 1);
        Label l5 = new Label();
        mv.visitLabel(l5);
        Label l6 = new Label();
        mv.visitJumpInsn(GOTO, l6);
        Label l7 = new Label();
        mv.visitLabel(l7);
        mv.visitFrame(Opcodes.F_APPEND, 2, new Object[] { "[Ljava/lang/reflect/Method;", Opcodes.INTEGER }, 0,
                null);
        mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings",
                "[Lorg/simantics/databoard/method/MethodBinding;");
        mv.visitVarInsn(ILOAD, 1);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ILOAD, 1);
        mv.visitInsn(AALOAD);
        mv.visitMethodInsn(INVOKESTATIC, "org/simantics/databoard/DataTypes", "getMethodBinding",
                "(Ljava/lang/reflect/Method;)Lorg/simantics/databoard/method/MethodBinding;");
        mv.visitInsn(AASTORE);
        Label l8 = new Label();
        mv.visitLabel(l8);
        mv.visitIincInsn(1, 1);
        mv.visitLabel(l6);
        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        mv.visitVarInsn(ILOAD, 1);
        mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings",
                "[Lorg/simantics/databoard/method/MethodBinding;");
        mv.visitInsn(ARRAYLENGTH);
        mv.visitJumpInsn(IF_ICMPLT, l7);
        Label l9 = new Label();
        mv.visitLabel(l9);
        mv.visitInsn(RETURN);
        Label l10 = new Label();
        mv.visitLabel(l10);
        mv.visitLocalVariable("methods", "[Ljava/lang/reflect/Method;", null, l2, l10, 0);
        mv.visitLocalVariable("i", "I", null, l5, l9, 1);
        mv.visitMaxs(4, 2);
        mv.visitEnd();
    }

    // Constructor
    {
        mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Lorg/simantics/data/session/MethodInterface;)V", null,
                new String[] { "org/simantics/data/error/MethodNotSupportedException" });
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitFieldInsn(PUTFIELD, classResourceName, "mi", "Lorg/simantics/data/session/MethodInterface;");
        Label l2 = new Label();
        mv.visitLabel(l2);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings",
                "[Lorg/simantics/databoard/method/MethodBinding;");
        mv.visitInsn(ARRAYLENGTH);
        mv.visitTypeInsn(ANEWARRAY, "org/simantics/data/session/MethodInterface$Method");
        mv.visitFieldInsn(PUTFIELD, classResourceName, "methods",
                "[Lorg/simantics/data/session/MethodInterface$Method;");
        Label l3 = new Label();
        mv.visitLabel(l3);
        mv.visitInsn(ICONST_0);
        mv.visitVarInsn(ISTORE, 2);
        Label l4 = new Label();
        mv.visitLabel(l4);
        Label l5 = new Label();
        mv.visitJumpInsn(GOTO, l5);
        Label l6 = new Label();
        mv.visitLabel(l6);
        mv.visitFrame(Opcodes.F_FULL, 3, new Object[] { classResourceName,
                "org/simantics/data/session/MethodInterface", Opcodes.INTEGER }, 0, new Object[] {});
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, classResourceName, "methods",
                "[Lorg/simantics/data/session/MethodInterface$Method;");
        mv.visitVarInsn(ILOAD, 2);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings",
                "[Lorg/simantics/databoard/method/MethodBinding;");
        mv.visitVarInsn(ILOAD, 2);
        mv.visitInsn(AALOAD);
        mv.visitMethodInsn(INVOKEINTERFACE, "org/simantics/data/session/MethodInterface", "getMethod",
                "(Lorg/simantics/databoard/method/MethodBinding;)Lorg/simantics/data/session/MethodInterface$Method;");
        mv.visitInsn(AASTORE);
        Label l7 = new Label();
        mv.visitLabel(l7);
        mv.visitIincInsn(2, 1);
        mv.visitLabel(l5);
        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        mv.visitVarInsn(ILOAD, 2);
        mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings",
                "[Lorg/simantics/databoard/method/MethodBinding;");
        mv.visitInsn(ARRAYLENGTH);
        mv.visitJumpInsn(IF_ICMPLT, l6);
        Label l8 = new Label();
        mv.visitLabel(l8);
        mv.visitInsn(RETURN);
        Label l9 = new Label();
        mv.visitLabel(l9);
        mv.visitLocalVariable("this", classTypeDescriptor, null, l0, l9, 0);
        mv.visitLocalVariable("mi", "Lorg/simantics/data/session/MethodInterface;", null, l0, l9, 1);
        mv.visitLocalVariable("i", "I", null, l4, l8, 2);
        mv.visitMaxs(5, 3);
        mv.visitEnd();
    }

    // Method
    int methodNumber = 0;
    for (java.lang.reflect.Method m : methods) {
        String typeDescription = "";
        Class<?>[] params = m.getParameterTypes();
        for (int i = 0; i < params.length; i++) {
            if (i > 0)
                typeDescription += ";";
            typeDescription += classToTypeDescriptor(params[i]);
        }
        typeDescription = "(" + typeDescription + ")" + classToTypeDescriptor(m.getReturnType());
        System.out.println(typeDescription + " " + m.getName());

        Class<?>[] exceptions = m.getExceptionTypes();
        String[] exceptionResourceNames = new String[exceptions.length];
        for (int i = 0; i < exceptionResourceNames.length; i++) {
            exceptionResourceNames[i] = exceptions[i].getName().replaceAll("\\.", "/");
        }

        // Registers
        // 0 - this
        // 1..argRegs args
        // argRegs+1 - method
        // argRegs+2 - args (the array)
        // argRegs+3 - AsyncResult
        // argRegs+4 - e
        // argRegs+5 - ExecutionError.cause
        // argRegs+6 - e

        int argRegs = 0;
        for (int i = 0; i < params.length; i++) {
            Class<?> clazz = params[i];
            argRegs++;
            if (clazz == long.class || clazz == float.class || clazz == Double.class)
                argRegs++;
        }

        mv = cw.visitMethod(ACC_PUBLIC, m.getName(), typeDescription, null, exceptionResourceNames);
        mv.visitCode();
        Label l0 = new Label();
        Label l1 = new Label();
        Label l2 = new Label();
        mv.visitTryCatchBlock(l0, l1, l2, "org/simantics/data/session/MethodInterface$ExecutionError");
        Label l3 = new Label();
        mv.visitTryCatchBlock(l0, l1, l3, "java/lang/InterruptedException");
        Label l4 = new Label();
        mv.visitLabel(l4);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, classResourceName, "methods",
                "[Lorg/simantics/data/session/MethodInterface$Method;");
        // Method m and puts into register 
        mv.visitLdcInsn(Integer.valueOf(methodNumber));
        mv.visitInsn(AALOAD);
        mv.visitVarInsn(ASTORE, argRegs + 1);
        Label l5 = new Label();
        mv.visitLabel(l5);
        mv.visitLdcInsn(Integer.valueOf(params.length));
        mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");

        int register = 1; // argument register   
        for (int i = 0; i < params.length; i++) {
            Class<?> clazz = params[i];
            mv.visitInsn(DUP);
            mv.visitLdcInsn(Integer.valueOf(i));

            if (clazz == byte.class) {
                mv.visitVarInsn(ILOAD, register++);
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;");
            } else if (clazz == char.class) {
                mv.visitVarInsn(ILOAD, register++);
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;");
            } else if (clazz == boolean.class) {
                mv.visitVarInsn(ILOAD, register++);
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;");
            } else if (clazz == byte.class) {
                mv.visitVarInsn(ILOAD, register++);
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;");
            } else if (clazz == int.class) {
                mv.visitVarInsn(ILOAD, register++);
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
            } else if (clazz == long.class) {
                mv.visitVarInsn(LLOAD, register);
                register += 2;
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(F)Ljava/lang/Long;");
            } else if (clazz == float.class) {
                mv.visitVarInsn(FLOAD, register);
                register += 2;
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;");
            } else if (clazz == Double.class) {
                mv.visitVarInsn(DLOAD, register);
                register += 2;
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;");
            } else {
                // Push argument to stack 
                mv.visitVarInsn(ALOAD, register++);
            }
            mv.visitInsn(AASTORE);
        }

        // Store args to argRegs+2
        mv.visitVarInsn(ASTORE, argRegs + 2);
        Label l6 = new Label();
        mv.visitLabel(l6);
        mv.visitVarInsn(ALOAD, argRegs + 1 /* m */);
        mv.visitVarInsn(ALOAD, argRegs + 2 /*args*/);
        mv.visitMethodInsn(INVOKEINTERFACE, "org/simantics/data/session/MethodInterface$Method", "invoke",
                "(Ljava/lang/Object;)Lorg/simantics/data/session/MethodInterface$AsyncResult;");
        mv.visitVarInsn(ASTORE, argRegs + 3);
        mv.visitLabel(l0);
        mv.visitVarInsn(ALOAD, argRegs + 3);
        mv.visitMethodInsn(INVOKEINTERFACE, "org/simantics/data/session/MethodInterface$AsyncResult",
                "waitForResponse", "()Ljava/lang/Object;");
        // TODO Return typecase result
        Class<?> returnType = m.getReturnType();

        if (returnType == void.class) {
            mv.visitInsn(POP);
            mv.visitInsn(RETURN);
        } else if (returnType == int.class) {
            mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I");
            mv.visitLabel(l1);
            mv.visitInsn(IRETURN);
        } else if (returnType == byte.class) {
            mv.visitTypeInsn(CHECKCAST, "java/lang/Byte");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "B()");
            mv.visitLabel(l1);
            mv.visitInsn(IRETURN);
        } else if (returnType == char.class) {
            mv.visitTypeInsn(CHECKCAST, "java/lang/Character");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C");
            mv.visitLabel(l1);
            mv.visitInsn(IRETURN);
        } else if (returnType == boolean.class) {
            mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z");
            mv.visitLabel(l1);
            mv.visitInsn(IRETURN);
        } else if (returnType == short.class) {
            mv.visitTypeInsn(CHECKCAST, "java/lang/Short");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S");
            mv.visitLabel(l1);
            mv.visitInsn(IRETURN);
        } else if (returnType == long.class) {
            mv.visitTypeInsn(CHECKCAST, "java/lang/Long");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J");
            mv.visitLabel(l1);
            mv.visitInsn(LRETURN);
        } else if (returnType == double.class) {
            mv.visitTypeInsn(CHECKCAST, "java/lang/Double");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D");
            mv.visitLabel(l1);
            mv.visitInsn(DRETURN);
        } else if (returnType == float.class) {
            mv.visitTypeInsn(CHECKCAST, "java/lang/Float");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F");
            mv.visitLabel(l1);
            mv.visitInsn(FRETURN);
        } else {
            // Object
            mv.visitTypeInsn(CHECKCAST, returnType.getName().replaceAll("\\.", "/"));
            mv.visitLabel(l1);
            mv.visitInsn(ARETURN);
        }

        // Handle exceptions
        mv.visitLabel(l2);
        mv.visitFrame(Opcodes.F_FULL, argRegs + 4,
                new Object[] { classResourceName, "java/lang/Integer",
                        "org/simantics/data/session/MethodInterface$Method", "[Ljava/lang/Object;",
                        "org/simantics/data/session/MethodInterface$AsyncResult" },
                1, new Object[] { "org/simantics/data/session/MethodInterface$ExecutionError" });
        mv.visitVarInsn(ASTORE, argRegs + 4);
        Label l7 = new Label();
        mv.visitLabel(l7);
        mv.visitVarInsn(ALOAD, argRegs + 4);
        mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/data/session/MethodInterface$ExecutionError",
                "getError", "()Ljava/lang/Object;");
        mv.visitVarInsn(ASTORE, argRegs + 5); // argRegs+5 <- ExecutionError.cause

        Class<?>[] exceptionClasses = m.getExceptionTypes();
        Label nextException[] = new Label[exceptionClasses.length];
        for (int i = 0; i < exceptionClasses.length; i++) {
            Class<?> exceptionClass = exceptionClasses[i];
            String exceptionClassResourceName = exceptionClass.getName().replaceAll("\\.", "/");
            nextException[i] = new Label();
            // If instanceof MyException
            Label l8 = new Label();
            mv.visitLabel(l8);
            mv.visitVarInsn(ALOAD, argRegs + 5); // Cause
            mv.visitTypeInsn(INSTANCEOF, exceptionClassResourceName);
            mv.visitJumpInsn(IFEQ, nextException[i]); // If not, go to ExecutionError
            // If so, throw it
            mv.visitVarInsn(ALOAD, argRegs + 5); // e
            mv.visitTypeInsn(CHECKCAST, exceptionClassResourceName);
            mv.visitInsn(ATHROW);
            mv.visitLabel(nextException[i]);
        }

        // ExecutionError
        mv.visitFrame(
                Opcodes.F_APPEND, argRegs + 1, new Object[] {
                        "org/simantics/data/session/MethodInterface$ExecutionError", "java/lang/Object" },
                0, null);
        mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
        mv.visitInsn(DUP);
        mv.visitVarInsn(ALOAD, argRegs + 4);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/Throwable;)V");
        mv.visitInsn(ATHROW);

        // InteruptedException
        mv.visitLabel(l3);
        mv.visitFrame(Opcodes.F_FULL, argRegs + 4,
                new Object[] { classResourceName, "java/lang/Integer",
                        "org/simantics/data/session/MethodInterface$Method", "[Ljava/lang/Object;",
                        "org/simantics/data/session/MethodInterface$AsyncResult" },
                1, new Object[] { "java/lang/InterruptedException" });
        mv.visitVarInsn(ASTORE, argRegs + 4);
        Label l10 = new Label();
        mv.visitLabel(l10);
        mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
        mv.visitInsn(DUP);
        mv.visitVarInsn(ALOAD, argRegs + 4);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/Throwable;)V");
        mv.visitInsn(ATHROW);

        Label l11 = new Label();
        mv.visitLabel(l11);
        mv.visitLocalVariable("this", classTypeDescriptor, null, l4, l11, 0);
        //      mv.visitLocalVariable("arg1", "Ljava/lang/Integer;", null, l4, l11, 1);
        register = 1;
        for (int i = 0; i < params.length; i++) {
            Class<?> clazz = params[i];
            mv.visitLocalVariable("arg" + (i + 1), classToTypeDescriptor(clazz), null, l4, l11, register);
            register++;
            if (clazz == long.class || clazz == float.class || clazz == Double.class)
                argRegs++;
        }
        mv.visitLocalVariable("m", "Lorg/simantics/data/session/MethodInterface$Method;", null, l5, l11,
                argRegs + 1);
        mv.visitLocalVariable("args", "[Ljava/lang/Object;", null, l6, l11, argRegs + 2);
        mv.visitLocalVariable("result", "Lorg/simantics/data/session/MethodInterface$AsyncResult;", null, l0,
                l11, argRegs + 3);
        mv.visitLocalVariable("e", "Lorg/simantics/data/session/MethodInterface$ExecutionError;", null, l7, l3,
                argRegs + 4);
        mv.visitLocalVariable("cause", "Ljava/lang/Object;", null, l7, l3, argRegs + 5);
        mv.visitLocalVariable("e", "Ljava/lang/InterruptedException;", null, l10, l11, argRegs + 4);
        mv.visitMaxs(argRegs + 3, argRegs + 6);
        mv.visitEnd();
        methodNumber++;
    }

    cw.visitEnd();
}

From source file:org.spongepowered.asm.util.Locals.java

License:MIT License

/**
 * <p>Attempts to identify available locals at an arbitrary point in the
 * bytecode specified by node.</p>
 * //from  w w w .j  av a  2s .c  o  m
 * <p>This method builds an approximate view of the locals available at an
 * arbitrary point in the bytecode by examining the following features in
 * the bytecode:</p> 
 * <ul>
 *   <li>Any available stack map frames</li>
 *   <li>STORE opcodes</li>
 *   <li>The local variable table</li>
 * </ul>
 * 
 * <p>Inference proceeds by walking the bytecode from the start of the
 * method looking for stack frames and STORE opcodes. When either of these
 * is encountered, an attempt is made to cross-reference the values in the
 * stack map or STORE opcode with the value in the local variable table
 * which covers the code range. Stack map frames overwrite the entire
 * simulated local variable table with their own value types, STORE opcodes
 * overwrite only the local slot to which they pertain. Values in the
 * simulated locals array are spaced according to their size (unlike the
 * representation in FrameNode) and this TOP, NULL and UNINTITIALIZED_THIS
 * opcodes will be represented as null values in the simulated frame.</p>
 * 
 * <p>This code does not currently simulate the prescribed JVM behaviour
 * where overwriting the second slot of a DOUBLE or LONG actually
 * invalidates the DOUBLE or LONG stored in the previous location, so we
 * have to hope (for now) that this behaviour isn't emitted by the compiler
 * or any upstream transformers. I may have to re-think this strategy if
 * this situation is encountered in the wild.</p>
 * 
 * @param classNode ClassNode containing the method, used to initialise the
 *      implicit "this" reference in simple methods with no stack frames
 * @param method MethodNode to explore
 * @param node Node indicating the position at which to determine the locals
 *      state. The locals will be enumerated UP TO the specified node, so
 *      bear in mind that if the specified node is itself a STORE opcode,
 *      then we will be looking at the state of the locals PRIOR to its
 *      invocation
 * @return A sparse array containing a view (hopefully) of the locals at the
 *      specified location
 */
public static LocalVariableNode[] getLocalsAt(ClassNode classNode, MethodNode method, AbstractInsnNode node) {
    LocalVariableNode[] frame = new LocalVariableNode[method.maxLocals];
    int local = 0, index = 0;

    // Initialise implicit "this" reference in non-static methods
    if ((method.access & Opcodes.ACC_STATIC) == 0) {
        frame[local++] = new LocalVariableNode("this", classNode.name, null, null, null, 0);
    }

    // Initialise method arguments
    for (Type argType : Type.getArgumentTypes(method.desc)) {
        frame[local] = new LocalVariableNode("arg" + index++, argType.toString(), null, null, null, local);
        local += argType.getSize();
    }

    for (Iterator<AbstractInsnNode> iter = method.instructions.iterator(); iter.hasNext();) {
        AbstractInsnNode insn = iter.next();
        if (insn instanceof FrameNode) {
            FrameNode frameNode = (FrameNode) insn;

            // localPos tracks the location in the frame node's locals list, which doesn't leave space for TOP entries
            for (int localPos = 0, framePos = 0; framePos < frame.length; framePos++, localPos++) {
                // Get the local at the current position in the FrameNode's locals list
                final Object localType = (localPos < frameNode.local.size()) ? frameNode.local.get(localPos)
                        : null;

                if (localType instanceof String) { // String refers to a reference type
                    frame[framePos] = Locals.getLocalVariableAt(classNode, method, node, framePos);
                } else if (localType instanceof Integer) { // Integer refers to a primitive type or other marker
                    boolean isMarkerType = localType == Opcodes.UNINITIALIZED_THIS || localType == Opcodes.TOP
                            || localType == Opcodes.NULL;
                    boolean is32bitValue = localType == Opcodes.INTEGER || localType == Opcodes.FLOAT;
                    boolean is64bitValue = localType == Opcodes.DOUBLE || localType == Opcodes.LONG;
                    if (isMarkerType) {
                        frame[framePos] = null;
                    } else if (is32bitValue || is64bitValue) {
                        frame[framePos] = Locals.getLocalVariableAt(classNode, method, node, framePos);

                        if (is64bitValue) {
                            framePos++;
                            frame[framePos] = null; // TOP
                        }
                    } else {
                        throw new RuntimeException(
                                "Unrecognised locals opcode " + localType + " in locals array at position "
                                        + localPos + " in " + classNode.name + "." + method.name + method.desc);
                    }
                } else if (localType == null) {
                    frame[framePos] = null;
                } else {
                    throw new RuntimeException("Invalid value " + localType + " in locals array at position "
                            + localPos + " in " + classNode.name + "." + method.name + method.desc);
                }
            }
        } else if (insn instanceof VarInsnNode) {
            VarInsnNode varNode = (VarInsnNode) insn;
            frame[varNode.var] = Locals.getLocalVariableAt(classNode, method, node, varNode.var);
        } else if (insn == node) {
            break;
        }
    }

    return frame;
}