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.google.gwtorm.server.SchemaGen.java

License:Apache License

private void implementSequenceMethods() {
    for (final SequenceModel seq : schema.getSequences()) {
        final Type retType = Type.getType(seq.getResultType());
        final MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, seq.getMethodName(),
                Type.getMethodDescriptor(retType, new Type[] {}), null,
                new String[] { Type.getType(OrmException.class).getInternalName() });
        mv.visitCode();/*  w w w  .j  av a2s  . c  o m*/

        mv.visitVarInsn(ALOAD, 0);
        mv.visitLdcInsn(seq.getSequenceName());
        mv.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(schemaSuperClass), "nextLong",
                Type.getMethodDescriptor(Type.getType(Long.TYPE), new Type[] { Type.getType(String.class) }));
        if (retType.getSize() == 1) {
            mv.visitInsn(L2I);
            mv.visitInsn(IRETURN);
        } else {
            mv.visitInsn(LRETURN);
        }
        mv.visitMaxs(-1, -1);
        mv.visitEnd();
    }
}

From source file:com.google.gwtorm.server.SchemaGen.java

License:Apache License

private void implementAllRelationsMethod() {
    final MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_FINAL, "allRelations",
            Type.getMethodDescriptor(Type.getType(Access[].class), new Type[] {}), null, null);
    mv.visitCode();//from www.  j a v  a 2 s .c  om

    final int r = 1;
    CodeGenSupport cgs = new CodeGenSupport(mv);
    cgs.push(relations.size());
    mv.visitTypeInsn(ANEWARRAY, Type.getType(Access.class).getInternalName());
    mv.visitVarInsn(ASTORE, r);

    int index = 0;
    for (RelationGen info : relations) {
        mv.visitVarInsn(ALOAD, r);
        cgs.push(index++);

        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKEVIRTUAL, getImplTypeName(), info.model.getMethodName(), info.getDescriptor());

        mv.visitInsn(AASTORE);
    }

    mv.visitVarInsn(ALOAD, r);
    mv.visitInsn(ARETURN);
    mv.visitMaxs(-1, -1);
    mv.visitEnd();
}

From source file:com.googlecode.d2j.converter.IR2JConverter.java

License:Apache License

private void reBuildInstructions(IrMethod ir, MethodVisitor asm) {
    asm = new LdcOptimizeAdapter(asm);
    int maxLocalIndex = 0;
    for (Local local : ir.locals) {
        maxLocalIndex = Math.max(maxLocalIndex, local._ls_index);
    }//w  w  w .  j a  v a  2  s  . c om
    Map<String, Integer> lockMap = new HashMap<String, Integer>();
    for (Stmt st : ir.stmts) {
        switch (st.st) {
        case LABEL:
            LabelStmt labelStmt = (LabelStmt) st;
            Label label = (Label) labelStmt.tag;
            asm.visitLabel(label);
            if (labelStmt.lineNumber >= 0) {
                asm.visitLineNumber(labelStmt.lineNumber, label);
            }
            break;
        case ASSIGN: {
            E2Stmt e2 = (E2Stmt) st;
            Value v1 = e2.op1;
            Value v2 = e2.op2;
            switch (v1.vt) {
            case LOCAL:

                Local local = ((Local) v1);
                int i = local._ls_index;

                if (v2.vt == VT.LOCAL && (i == ((Local) v2)._ls_index)) {//
                    continue;
                }

                boolean skipOrg = false;
                if (v1.valueType.charAt(0) == 'I') {// check for IINC
                    if (v2.vt == VT.ADD) {
                        E2Expr e = (E2Expr) v2;
                        if ((e.op1 == local && e.op2.vt == VT.CONSTANT)
                                || (e.op2 == local && e.op1.vt == VT.CONSTANT)) {
                            int increment = (Integer) ((Constant) (e.op1 == local ? e.op2 : e.op1)).value;
                            if (increment >= Short.MIN_VALUE && increment <= Short.MAX_VALUE) {
                                asm.visitIincInsn(i, increment);
                                skipOrg = true;
                            }
                        }
                    } else if (v2.vt == VT.SUB) {
                        E2Expr e = (E2Expr) v2;
                        if (e.op1 == local && e.op2.vt == VT.CONSTANT) {
                            int increment = -(Integer) ((Constant) e.op2).value;
                            if (increment >= Short.MIN_VALUE && increment <= Short.MAX_VALUE) {
                                asm.visitIincInsn(i, increment);
                                skipOrg = true;
                            }
                        }
                    }
                }
                if (!skipOrg) {
                    accept(v2, asm);
                    if (i >= 0) {
                        asm.visitVarInsn(getOpcode(v1, ISTORE), i);
                    } else if (!v1.valueType.equals("V")) { // skip void type locals
                        switch (v1.valueType.charAt(0)) {
                        case 'J':
                        case 'D':
                            asm.visitInsn(POP2);
                            break;
                        default:
                            asm.visitInsn(POP);
                            break;
                        }
                    }
                }
                break;
            case STATIC_FIELD: {
                StaticFieldExpr fe = (StaticFieldExpr) v1;
                accept(v2, asm);
                insertI2x(v2.valueType, fe.type, asm);
                asm.visitFieldInsn(PUTSTATIC, toInternal(fe.owner), fe.name, fe.type);
                break;
            }
            case FIELD: {
                FieldExpr fe = (FieldExpr) v1;
                accept(fe.op, asm);
                accept(v2, asm);
                insertI2x(v2.valueType, fe.type, asm);
                asm.visitFieldInsn(PUTFIELD, toInternal(fe.owner), fe.name, fe.type);
                break;
            }
            case ARRAY:
                ArrayExpr ae = (ArrayExpr) v1;
                accept(ae.op1, asm);
                accept(ae.op2, asm);
                accept(v2, asm);
                String tp1 = ae.op1.valueType;
                String tp2 = ae.valueType;
                if (tp1.charAt(0) == '[') {
                    String arrayElementType = tp1.substring(1);
                    insertI2x(v2.valueType, arrayElementType, asm);
                    asm.visitInsn(getOpcode(arrayElementType, IASTORE));
                } else {
                    asm.visitInsn(getOpcode(tp2, IASTORE));
                }
                break;
            }
        }
            break;
        case IDENTITY: {
            E2Stmt e2 = (E2Stmt) st;
            if (e2.op2.vt == VT.EXCEPTION_REF) {
                int index = ((Local) e2.op1)._ls_index;
                if (index >= 0) {
                    asm.visitVarInsn(ASTORE, index);
                } else {
                    asm.visitInsn(POP);
                }
            }
        }
            break;

        case FILL_ARRAY_DATA: {
            E2Stmt e2 = (E2Stmt) st;
            Object arrayData = ((Constant) e2.getOp2()).value;
            int arraySize = Array.getLength(arrayData);
            String arrayValueType = e2.getOp1().valueType;
            String elementType;
            if (arrayValueType.charAt(0) == '[') {
                elementType = arrayValueType.substring(1);
            } else {
                elementType = "I";
            }
            int iastoreOP = getOpcode(elementType, IASTORE);
            accept(e2.getOp1(), asm);
            for (int i = 0; i < arraySize; i++) {
                asm.visitInsn(DUP);
                asm.visitLdcInsn(i);
                asm.visitLdcInsn(Array.get(arrayData, i));
                asm.visitInsn(iastoreOP);
            }
            asm.visitInsn(POP);
        }
            break;
        case GOTO:
            asm.visitJumpInsn(GOTO, (Label) ((GotoStmt) st).target.tag);
            break;
        case IF:
            reBuildJumpInstructions((IfStmt) st, asm);
            break;
        case LOCK: {
            Value v = ((UnopStmt) st).op;
            accept(v, asm);
            if (optimizeSynchronized) {
                switch (v.vt) {
                case LOCAL:
                    // FIXME do we have to disable local due to OptSyncTest ?
                    // break;
                case CONSTANT: {
                    String key;
                    if (v.vt == VT.LOCAL) {
                        key = "L" + ((Local) v)._ls_index;
                    } else {
                        key = "C" + ((Constant) v).value;
                    }
                    Integer integer = lockMap.get(key);
                    int nIndex = integer != null ? integer : ++maxLocalIndex;
                    asm.visitInsn(DUP);
                    asm.visitVarInsn(getOpcode(v, ISTORE), nIndex);
                    lockMap.put(key, nIndex);
                }
                    break;
                default:
                    throw new RuntimeException();
                }
            }
            asm.visitInsn(MONITORENTER);
        }
            break;
        case UNLOCK: {
            Value v = ((UnopStmt) st).op;
            if (optimizeSynchronized) {
                switch (v.vt) {
                case LOCAL:
                case CONSTANT: {
                    String key;
                    if (v.vt == VT.LOCAL) {
                        key = "L" + ((Local) v)._ls_index;
                    } else {
                        key = "C" + ((Constant) v).value;
                    }
                    Integer integer = lockMap.get(key);
                    if (integer != null) {
                        asm.visitVarInsn(getOpcode(v, ILOAD), integer);
                    } else {
                        accept(v, asm);
                    }
                }
                    break;
                // TODO other
                default: {
                    accept(v, asm);
                    break;
                }
                }
            } else {
                accept(v, asm);
            }
            asm.visitInsn(MONITOREXIT);
        }
            break;
        case NOP:
            break;
        case RETURN: {
            Value v = ((UnopStmt) st).op;
            accept(v, asm);
            insertI2x(v.valueType, ir.ret, asm);
            asm.visitInsn(getOpcode(v, IRETURN));
        }
            break;
        case RETURN_VOID:
            asm.visitInsn(RETURN);
            break;
        case LOOKUP_SWITCH: {
            LookupSwitchStmt lss = (LookupSwitchStmt) st;
            accept(lss.op, asm);
            Label targets[] = new Label[lss.targets.length];
            for (int i = 0; i < targets.length; i++) {
                targets[i] = (Label) lss.targets[i].tag;
            }
            asm.visitLookupSwitchInsn((Label) lss.defaultTarget.tag, lss.lookupValues, targets);
        }
            break;
        case TABLE_SWITCH: {
            TableSwitchStmt tss = (TableSwitchStmt) st;
            accept(tss.op, asm);
            Label targets[] = new Label[tss.targets.length];
            for (int i = 0; i < targets.length; i++) {
                targets[i] = (Label) tss.targets[i].tag;
            }
            asm.visitTableSwitchInsn(tss.lowIndex, tss.lowIndex + targets.length - 1,
                    (Label) tss.defaultTarget.tag, targets);
        }
            break;
        case THROW:
            accept(((UnopStmt) st).op, asm);
            asm.visitInsn(ATHROW);
            break;
        case VOID_INVOKE:
            InvokeExpr invokeExpr = (InvokeExpr) st.getOp();
            accept(invokeExpr, asm);
            String ret = invokeExpr.ret;
            if (invokeExpr.vt == VT.INVOKE_NEW) {
                asm.visitInsn(POP);
            } else if (!"V".equals(ret)) {
                switch (ret.charAt(0)) {
                case 'J':
                case 'D':
                    asm.visitInsn(POP2);
                    break;
                default:
                    asm.visitInsn(POP);
                    break;
                }
            }
            break;
        default:
            throw new RuntimeException("not support st: " + st.st);
        }

    }
}

From source file:com.googlecode.d2j.converter.IR2JConverter.java

License:Apache License

private static void accept(Value value, MethodVisitor asm) {

    switch (value.et) {
    case E0://from  w  w w.  j  a  v a 2  s .  c o m
        switch (value.vt) {
        case LOCAL:
            asm.visitVarInsn(getOpcode(value, ILOAD), ((Local) value)._ls_index);
            break;
        case CONSTANT:
            Constant cst = (Constant) value;
            if (cst.value.equals(Constant.Null)) {
                asm.visitInsn(ACONST_NULL);
            } else if (cst.value instanceof Constant.Type) {
                asm.visitLdcInsn(Type.getType(((Constant.Type) cst.value).desc));
            } else {
                asm.visitLdcInsn(cst.value);
            }
            break;
        case NEW:
            asm.visitTypeInsn(NEW, toInternal(((NewExpr) value).type));
            break;
        case STATIC_FIELD:
            StaticFieldExpr sfe = (StaticFieldExpr) value;
            asm.visitFieldInsn(GETSTATIC, toInternal(sfe.owner), sfe.name, sfe.type);
            break;
        }
        break;
    case E1:
        reBuildE1Expression((E1Expr) value, asm);
        break;
    case E2:
        reBuildE2Expression((E2Expr) value, asm);
        break;
    case En:
        reBuildEnExpression((EnExpr) value, asm);
        break;
    }
}

From source file:com.googlecode.ddom.weaver.asm.MethodVisitorTee.java

License:Apache License

public void visitVarInsn(int opcode, int var) {
    for (MethodVisitor visitor : visitors) {
        visitor.visitVarInsn(opcode, var);
    }//from w ww.  j a  v a 2s  . com
}

From source file:com.googlecode.ddom.weaver.compound.CompoundClassGenerator.java

License:Apache License

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, name, desc, signature, exceptions);
    if (mv != null) {
        Type[] argumentTypes = Type.getArgumentTypes(desc);
        mv.visitCode();/*from ww  w .  j a  va 2s  .  c  om*/
        Label l0 = new Label();
        mv.visitLabel(l0);
        for (int i = 0; i < componentClasses.length; i++) {
            String componentClass = Util.classNameToInternalName(componentClasses[i]);
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitFieldInsn(Opcodes.GETFIELD, className, "c" + i, "L" + componentClass + ";");
            for (int j = 0; j < argumentTypes.length; j++) {
                mv.visitVarInsn(argumentTypes[j].getOpcode(Opcodes.ILOAD), j + 1);
            }
            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, ifaceName, name, desc);
        }
        mv.visitInsn(Opcodes.RETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", "L" + className + ";", null, l0, l1, 0);
        mv.visitMaxs(argumentTypes.length + 1, argumentTypes.length + 1);
        mv.visitEnd();
    }
    return null;
}

From source file:com.googlecode.ddom.weaver.compound.CompoundClassGenerator.java

License:Apache License

@Override
public void visitEnd() {
    for (int i = 0; i < componentClasses.length; i++) {
        String componentClass = Util.classNameToInternalName(componentClasses[i]);
        FieldVisitor fv = cv.visitField(Opcodes.ACC_PRIVATE, "c" + i, "L" + componentClass + ";", null, null);
        if (fv != null) {
            fv.visitEnd();//from  w  w w  .j  ava  2  s.co  m
        }
    }
    MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
    if (mv != null) {
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
        for (int i = 0; i < componentClasses.length; i++) {
            String componentClass = Util.classNameToInternalName(componentClasses[i]);
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitTypeInsn(Opcodes.NEW, componentClass);
            mv.visitInsn(Opcodes.DUP);
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, componentClass, "<init>", "()V");
            mv.visitFieldInsn(Opcodes.PUTFIELD, className, "c" + i, "L" + componentClass + ";");
        }
        mv.visitInsn(Opcodes.RETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", "L" + className + ";", null, l0, l1, 0);
        mv.visitMaxs(3, 1);
        mv.visitEnd();
    }
    cv.visitEnd();
}

From source file:com.googlecode.ddom.weaver.ext.ModelExtensionClass.java

License:Apache License

public void accept(ClassVisitor classVisitor) {
    ImplementationInfo implementationInfo = info.getImplementation().get(ImplementationInfo.class);
    String name = Util.classNameToInternalName(info.getClassName());
    String superName = Util.classNameToInternalName(info.getSuperClassName());
    classVisitor.visit(Opcodes.V1_5,//from  w ww  .  jav  a2  s  . c  o  m
            info.isAbstract() ? Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT : Opcodes.ACC_PUBLIC, name, null,
            superName, new String[] {
                    Util.classNameToInternalName(info.getExtensionInterface().getClassInfo().getName()) });
    for (ConstructorInfo constructor : implementationInfo.getConstructors()) {
        MethodVisitor mv = classVisitor.visitMethod(Opcodes.ACC_PUBLIC, "<init>", constructor.getDescriptor(),
                constructor.getSignature(), constructor.getExceptions());
        if (mv != null) {
            mv.visitCode();
            Label l0 = new Label();
            mv.visitLabel(l0);
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            Type[] argumentTypes = constructor.getArgumentTypes();
            for (int i = 0; i < argumentTypes.length; i++) {
                mv.visitVarInsn(argumentTypes[i].getOpcode(Opcodes.ILOAD), i + 1);
            }
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, "<init>", constructor.getDescriptor());
            mv.visitInsn(Opcodes.RETURN);
            Label l1 = new Label();
            mv.visitLabel(l1);
            mv.visitLocalVariable("this", "L" + name + ";", null, l0, l1, 0);
            for (int i = 0; i < argumentTypes.length; i++) {
                mv.visitLocalVariable("arg" + i, argumentTypes[i].getDescriptor(), null, l0, l1, i + 1);
            }
            mv.visitMaxs(argumentTypes.length + 1, argumentTypes.length + 1);
            mv.visitEnd();
        }
    }
    classVisitor.visitEnd();
}

From source file:com.googlecode.ddom.weaver.ext.ModelExtensionFactoryDelegateImplementation.java

License:Apache License

public void accept(ClassVisitor classVisitor) {
    String factoryName = Util
            .classNameToInternalName(modelExtensionClassInfo.getFactoryDelegateImplementationClassName());
    classVisitor.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, factoryName, null, "java/lang/Object", new String[] {
            Util.classNameToInternalName(implementationInfo.getFactoryDelegateInterfaceName()) });
    String className = Util.classNameToInternalName(modelExtensionClassInfo.getClassName());
    {/* w ww .  j a v a  2 s. com*/
        MethodVisitor mv = classVisitor.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
        if (mv != null) {
            mv.visitCode();
            Label l0 = new Label();
            mv.visitLabel(l0);
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
            mv.visitInsn(Opcodes.RETURN);
            Label l1 = new Label();
            mv.visitLabel(l1);
            mv.visitLocalVariable("this", "L" + className + ";", null, l0, l1, 0);
            mv.visitMaxs(1, 1);
            mv.visitEnd();
        }
    }
    for (ConstructorInfo constructor : implementationInfo.getConstructors()) {
        MethodVisitor mv = classVisitor.visitMethod(Opcodes.ACC_PUBLIC, "create",
                constructor.getFactoryDelegateMethodDescriptor(), constructor.getSignature(),
                constructor.getExceptions());
        if (mv != null) {
            mv.visitCode();
            Label l0 = new Label();
            mv.visitLabel(l0);
            mv.visitTypeInsn(Opcodes.NEW, className);
            mv.visitInsn(Opcodes.DUP);
            Type[] argumentTypes = constructor.getArgumentTypes();
            for (int i = 0; i < argumentTypes.length; i++) {
                mv.visitVarInsn(argumentTypes[i].getOpcode(Opcodes.ILOAD), i + 1);
            }
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, "<init>", constructor.getDescriptor());
            mv.visitInsn(Opcodes.ARETURN);
            Label l1 = new Label();
            mv.visitLabel(l1);
            mv.visitLocalVariable("this", "L" + factoryName + ";", null, l0, l1, 0);
            for (int i = 0; i < argumentTypes.length; i++) {
                mv.visitLocalVariable("arg" + i, argumentTypes[i].getDescriptor(), null, l0, l1, i + 1);
            }
            mv.visitMaxs(argumentTypes.length + 2, argumentTypes.length + 1);
            mv.visitEnd();
        }
    }
    classVisitor.visitEnd();
}

From source file:com.googlecode.ddom.weaver.ext.ModelExtensionFactoryImplementation.java

License:Apache License

public void accept(ClassVisitor classVisitor) {
    // Note: the name chosen here must match what is expected in ExtensionFactoryLocator
    String name = Util.classNameToInternalName(implementationInfo.getFactoryInterface().getName() + "$$Impl");
    String factoryInterfaceName = Util
            .classNameToInternalName(implementationInfo.getFactoryInterface().getName());
    classVisitor.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, name, null, "java/lang/Object",
            new String[] { factoryInterfaceName });
    {//from w  w  w. j  a  v  a  2  s . c  o m
        FieldVisitor fw = classVisitor.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC,
                "INSTANCE", "L" + factoryInterfaceName + ";", null, null);
        if (fw != null) {
            fw.visitEnd();
        }
    }
    {
        FieldVisitor fw = classVisitor.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, "delegates",
                "Ljava/util/Map;", null, null);
        if (fw != null) {
            fw.visitEnd();
        }
    }
    {
        MethodVisitor mv = classVisitor.visitMethod(Opcodes.ACC_PRIVATE, "<init>", "()V", null, null);
        if (mv != null) {
            mv.visitCode();
            Label l0 = new Label();
            mv.visitLabel(l0);
            // Call constructor from superclass
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
            // Create delegates map
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitTypeInsn(Opcodes.NEW, "java/util/HashMap");
            mv.visitInsn(Opcodes.DUP);
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/HashMap", "<init>", "()V");
            mv.visitFieldInsn(Opcodes.PUTFIELD, name, "delegates", "Ljava/util/Map;");
            // Populate delegates map
            for (ModelExtensionInfo modelExtensionInfo : implementationInfo.getModelExtensions()) {
                for (ModelExtensionInterfaceInfo extensionInterface : modelExtensionInfo
                        .getExtensionInterfaces()) {
                    if (!extensionInterface.isAbstract()) {
                        // TODO: this is stupid; we should not recreate the info object here
                        ModelExtensionClassInfo modelExtensionClassInfo = new ModelExtensionClassInfo(
                                implementationInfo.getImplementation(), modelExtensionInfo.getRootInterface(),
                                extensionInterface);
                        String factoryDelegateImplName = Util.classNameToInternalName(
                                modelExtensionClassInfo.getFactoryDelegateImplementationClassName());
                        mv.visitVarInsn(Opcodes.ALOAD, 0);
                        mv.visitFieldInsn(Opcodes.GETFIELD, name, "delegates", "Ljava/util/Map;");
                        mv.visitLdcInsn(Type.getObjectType(Util.classNameToInternalName(
                                modelExtensionClassInfo.getExtensionInterface().getClassInfo().getName())));
                        mv.visitTypeInsn(Opcodes.NEW, factoryDelegateImplName);
                        mv.visitInsn(Opcodes.DUP);
                        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, factoryDelegateImplName, "<init>", "()V");
                        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "put",
                                "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
                        mv.visitInsn(Opcodes.POP);
                    }
                }
            }
            mv.visitInsn(Opcodes.RETURN);
            Label l1 = new Label();
            mv.visitLabel(l1);
            mv.visitLocalVariable("this", "L" + name + ";", null, l0, l1, 0);
            mv.visitMaxs(4, 1);
            mv.visitEnd();
        }
    }
    String factoryDelegateInterfaceName = Util
            .classNameToInternalName(implementationInfo.getFactoryDelegateInterfaceName());
    String getDelegateDesc = "(Ljava/lang/Class;)L" + factoryDelegateInterfaceName + ";";
    {
        MethodVisitor mv = classVisitor.visitMethod(Opcodes.ACC_PRIVATE, "getDelegate", getDelegateDesc, null,
                null);
        if (mv != null) {
            mv.visitCode();
            Label l0 = new Label();
            mv.visitLabel(l0);
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitFieldInsn(Opcodes.GETFIELD, name, "delegates", "Ljava/util/Map;");
            mv.visitVarInsn(Opcodes.ALOAD, 1);
            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "get",
                    "(Ljava/lang/Object;)Ljava/lang/Object;");
            mv.visitTypeInsn(Opcodes.CHECKCAST, factoryDelegateInterfaceName);
            mv.visitInsn(Opcodes.ARETURN);
            Label l1 = new Label();
            mv.visitLabel(l1);
            mv.visitLocalVariable("this", "L" + name + ";", null, l0, l1, 0);
            mv.visitLocalVariable("extensionInterface", "Ljava/lang/Class;", null, l0, l1, 1);
            mv.visitMaxs(2, 2);
            mv.visitEnd();
        }
    }
    String implementationName = Util.classNameToInternalName(implementationInfo.getImplementation().getName());
    for (ConstructorInfo constructor : implementationInfo.getConstructors()) {
        Type[] constructorArgumentTypes = constructor.getArgumentTypes();
        Type[] argumentTypes = new Type[constructorArgumentTypes.length + 1];
        argumentTypes[0] = Type.getObjectType("java/lang/Class");
        System.arraycopy(constructorArgumentTypes, 0, argumentTypes, 1, constructorArgumentTypes.length);
        MethodVisitor mv = classVisitor.visitMethod(Opcodes.ACC_PUBLIC, "create",
                Type.getMethodDescriptor(Type.getObjectType(implementationName), argumentTypes), null, null);
        if (mv != null) {
            mv.visitCode();
            Label l0 = new Label();
            mv.visitLabel(l0);
            mv.visitVarInsn(Opcodes.ALOAD, 1);
            Label l1 = new Label();
            mv.visitJumpInsn(Opcodes.IFNONNULL, l1);
            mv.visitTypeInsn(Opcodes.NEW, implementationName);
            mv.visitInsn(Opcodes.DUP);
            for (int i = 0; i < constructorArgumentTypes.length; i++) {
                mv.visitVarInsn(constructorArgumentTypes[i].getOpcode(Opcodes.ILOAD), i + 2);
            }
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, implementationName, "<init>",
                    constructor.getDescriptor());
            mv.visitInsn(Opcodes.ARETURN);
            mv.visitLabel(l1);
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitVarInsn(Opcodes.ALOAD, 1);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, name, "getDelegate", getDelegateDesc);
            for (int i = 0; i < constructorArgumentTypes.length; i++) {
                mv.visitVarInsn(constructorArgumentTypes[i].getOpcode(Opcodes.ILOAD), i + 2);
            }
            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, factoryDelegateInterfaceName, "create",
                    constructor.getFactoryDelegateMethodDescriptor());
            mv.visitInsn(Opcodes.ARETURN);
            Label l3 = new Label();
            mv.visitLabel(l3);
            mv.visitLocalVariable("this", "L" + name + ";", null, l0, l3, 0);
            mv.visitLocalVariable("extensionInterface", "Ljava/lang/Class;", null, l0, l3, 1);
            for (int i = 0; i < constructorArgumentTypes.length; i++) {
                mv.visitLocalVariable("arg" + i, constructorArgumentTypes[i].getDescriptor(), null, l0, l3,
                        i + 2);
            }
            mv.visitMaxs(argumentTypes.length + 1, argumentTypes.length + 1);
            mv.visitEnd();
        }
    }
    {
        MethodVisitor mv = classVisitor.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
        if (mv != null) {
            mv.visitCode();
            mv.visitTypeInsn(Opcodes.NEW, name);
            mv.visitInsn(Opcodes.DUP);
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, name, "<init>", "()V");
            mv.visitFieldInsn(Opcodes.PUTSTATIC, name, "INSTANCE", "L" + factoryInterfaceName + ";");
            mv.visitInsn(Opcodes.RETURN);
            mv.visitMaxs(2, 0);
            mv.visitEnd();
        }
    }
    classVisitor.visitEnd();
}