Example usage for org.objectweb.asm Opcodes ALOAD

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

Introduction

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

Prototype

int ALOAD

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

Click Source Link

Usage

From source file:edu.mit.streamjit.impl.common.MessageConstraint.java

License:Open Source License

/**
 * Parse the given getHandle() call instruction and preceding instructions
 * into a WorkerData.  This is a rather brittle pattern-matching job and
 * will fail on obfuscated bytecodes.//from   www. jav a 2  s .c o  m
 * @param call
 * @return
 */
private static WorkerData dataFromCall(Class<?> klass, MethodInsnNode call) {
    //Latency is either an integer constant or a getfield on this.
    Field latencyField = null;
    int constantLatency = Integer.MIN_VALUE;
    AbstractInsnNode latencyInsn = call.getPrevious();
    if (latencyInsn instanceof FieldInsnNode) {
        FieldInsnNode fieldInsn = (FieldInsnNode) latencyInsn;
        if (fieldInsn.getOpcode() != Opcodes.GETFIELD)
            throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass
                    + ": latency field insn opcode " + fieldInsn.getOpcode());
        if (!fieldInsn.desc.equals(Type.INT_TYPE.getDescriptor()))
            throw new IllegalStreamGraphException(
                    "Unsupported getHandle() use in " + klass + ": latency field desc " + fieldInsn.desc);
        if (!fieldInsn.owner.equals(Type.getType(klass).getInternalName()))
            throw new IllegalStreamGraphException(
                    "Unsupported getHandle() use in " + klass + ": latency field owner " + fieldInsn.owner);

        //Move latencyInsn to sync up with the other else-if branches.
        latencyInsn = latencyInsn.getPrevious();
        //We must be loading from this.
        if (latencyInsn.getOpcode() != Opcodes.ALOAD)
            throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass
                    + ": getfield subject opcode " + latencyInsn.getOpcode());
        int varIdx = ((VarInsnNode) latencyInsn).var;
        if (varIdx != 0)
            throw new IllegalStreamGraphException(
                    "Unsupported getHandle() use in " + klass + ": getfield not from this but from " + varIdx);

        //Check the field we're loading from is constant (final).
        //A static field is okay here since it isn't a reference parameter.
        try {
            latencyField = klass.getDeclaredField(fieldInsn.name);
            if (!Modifier.isFinal(latencyField.getModifiers()))
                throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass
                        + ": latency field not final: " + latencyField.toGenericString());
        } catch (NoSuchFieldException ex) {
            throw new IllegalStreamGraphException(
                    "Unsupported getHandle() use in " + klass + ": getfield not from this but from " + varIdx);
        }
    } else if (latencyInsn instanceof LdcInsnNode) {
        Object constant = ((LdcInsnNode) latencyInsn).cst;
        if (!(constant instanceof Integer))
            throw new IllegalStreamGraphException(
                    "Unsupported getHandle() use in " + klass + ": ldc " + constant);
        constantLatency = ((Integer) constant);
    } else
        switch (latencyInsn.getOpcode()) {
        case Opcodes.ICONST_M1:
            constantLatency = -1;
            break;
        case Opcodes.ICONST_0:
            constantLatency = 0;
            break;
        case Opcodes.ICONST_1:
            constantLatency = 1;
            break;
        case Opcodes.ICONST_2:
            constantLatency = 2;
            break;
        case Opcodes.ICONST_3:
            constantLatency = 3;
            break;
        case Opcodes.ICONST_4:
            constantLatency = 4;
            break;
        case Opcodes.ICONST_5:
            constantLatency = 5;
            break;
        case Opcodes.BIPUSH:
        case Opcodes.SIPUSH:
            constantLatency = ((IntInsnNode) latencyInsn).operand;
            break;
        default:
            throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass
                    + ": latencyInsn opcode " + latencyInsn.getOpcode());
        }
    //Finally, we've parsed the latency parameter.

    //Next is an aload_0 for the sender parameter.
    AbstractInsnNode senderInsn = latencyInsn.getPrevious();
    if (senderInsn.getOpcode() != Opcodes.ALOAD || ((VarInsnNode) senderInsn).var != 0)
        throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass + ": bad sender");

    //Finally, a getfield of this for a final Portal instance field.
    AbstractInsnNode portalInsn = senderInsn.getPrevious();
    if (!(portalInsn instanceof FieldInsnNode))
        throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass
                + ": portal getfield opcode " + portalInsn.getOpcode());
    FieldInsnNode fieldInsn = (FieldInsnNode) portalInsn;
    if (fieldInsn.getOpcode() != Opcodes.GETFIELD)
        throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass
                + ": portal field insn opcode " + fieldInsn.getOpcode());
    if (!fieldInsn.desc.equals(Type.getType(Portal.class).getDescriptor()))
        throw new IllegalStreamGraphException(
                "Unsupported getHandle() use in " + klass + ": portal field desc " + fieldInsn.desc);
    if (!fieldInsn.owner.equals(Type.getType(klass).getInternalName()))
        throw new IllegalStreamGraphException(
                "Unsupported getHandle() use in " + klass + ": portal field owner " + fieldInsn.owner);

    portalInsn = portalInsn.getPrevious();
    //We must be loading from this.
    if (portalInsn.getOpcode() != Opcodes.ALOAD)
        throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass
                + ": portal getfield subject opcode " + portalInsn.getOpcode());
    int varIdx = ((VarInsnNode) portalInsn).var;
    if (varIdx != 0)
        throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass
                + ": portal getfield not from this but from " + varIdx);

    //Check the field we're loading from is constant (final) and nonstatic.
    Field portalField;
    try {
        portalField = klass.getDeclaredField(fieldInsn.name);
        if (!Modifier.isFinal(portalField.getModifiers()))
            throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass
                    + ": portal field not final: " + portalField.toGenericString());
        if (Modifier.isStatic(portalField.getModifiers()))
            throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass
                    + ": portal field is static: " + portalField.toGenericString());
    } catch (NoSuchFieldException ex) {
        throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass
                + ": portal getfield not from this but from " + varIdx);
    }

    return latencyField != null ? new WorkerData(portalField, latencyField)
            : new WorkerData(portalField, constantLatency);
}

From source file:edu.mit.streamjit.util.bytecode.MethodResolver.java

License:Open Source License

private void interpret(VarInsnNode insn, FrameState frame, BBInfo block) {
    int var = insn.var;
    switch (insn.getOpcode()) {
    case Opcodes.ILOAD:
        assert frame.locals[var].getType().isSubtypeOf(typeFactory.getType(int.class));
        frame.stack.push(frame.locals[var]);
        break;/*  ww w.j a  va2  s .c o m*/
    case Opcodes.LLOAD:
        assert frame.locals[var].getType().isSubtypeOf(typeFactory.getType(long.class));
        frame.stack.push(frame.locals[var]);
        break;
    case Opcodes.FLOAD:
        assert frame.locals[var].getType().isSubtypeOf(typeFactory.getType(float.class));
        frame.stack.push(frame.locals[var]);
        break;
    case Opcodes.DLOAD:
        assert frame.locals[var].getType().isSubtypeOf(typeFactory.getType(double.class));
        frame.stack.push(frame.locals[var]);
        break;
    case Opcodes.ALOAD:
        assert frame.locals[var].getType().isSubtypeOf(typeFactory.getType(Object.class));
        frame.stack.push(frame.locals[var]);
        break;
    case Opcodes.ISTORE:
        assert frame.stack.peek().getType().isSubtypeOf(typeFactory.getType(int.class));
        frame.locals[var] = frame.stack.pop();
        break;
    case Opcodes.LSTORE:
        assert frame.stack.peek().getType().isSubtypeOf(typeFactory.getType(long.class));
        frame.locals[var] = frame.stack.pop();
        break;
    case Opcodes.FSTORE:
        assert frame.stack.peek().getType().isSubtypeOf(typeFactory.getType(float.class));
        frame.locals[var] = frame.stack.pop();
        break;
    case Opcodes.DSTORE:
        assert frame.stack.peek().getType().isSubtypeOf(typeFactory.getType(double.class));
        frame.locals[var] = frame.stack.pop();
        break;
    case Opcodes.ASTORE:
        assert frame.stack.peek().getType().isSubtypeOf(typeFactory.getType(Object.class));
        frame.locals[var] = frame.stack.pop();
        break;
    default:
        throw new UnsupportedOperationException("" + insn.getOpcode());
    }
}

From source file:edu.mit.streamjit.util.bytecode.MethodUnresolver.java

License:Open Source License

private void load(Value v, InsnList insns) {
    if (v instanceof Constant) {
        Object c = ((Constant<?>) v).getConstant();
        if (c == null)
            insns.add(new InsnNode(Opcodes.ACONST_NULL));
        else if (c instanceof Class)
            insns.add(new LdcInsnNode(org.objectweb.asm.Type.getType((Class) c)));
        else if (c instanceof Boolean)
            insns.add(loadIntegerConstant(((Boolean) c) ? 1 : 0));
        else if (c instanceof Character)
            insns.add(loadIntegerConstant((int) ((Character) c).charValue()));
        else if (c instanceof Byte || c instanceof Short || c instanceof Integer)
            insns.add(loadIntegerConstant(((Number) c).intValue()));
        else if (c instanceof Long)
            insns.add(loadLongConstant((Long) c));
        else if (c instanceof Float)
            insns.add(loadFloatConstant((Float) c));
        else if (c instanceof Double)
            insns.add(loadDoubleConstant((Double) c));
        else//from  w  ww  .j  a  va2s.c  o m
            insns.add(new LdcInsnNode(c));
        return;
    }

    assert registers.containsKey(v) : v;
    int reg = registers.get(v);
    Type t = v instanceof LocalVariable ? ((LocalVariable) v).getType().getFieldType() : v.getType();
    if (t instanceof ReferenceType || t instanceof NullType)
        insns.add(new VarInsnNode(Opcodes.ALOAD, reg));
    else if (t.equals(longType))
        insns.add(new VarInsnNode(Opcodes.LLOAD, reg));
    else if (t.equals(floatType))
        insns.add(new VarInsnNode(Opcodes.FLOAD, reg));
    else if (t.equals(doubleType))
        insns.add(new VarInsnNode(Opcodes.DLOAD, reg));
    else if (t.isSubtypeOf(intType))
        insns.add(new VarInsnNode(Opcodes.ILOAD, reg));
    else
        throw new AssertionError("unloadable value: " + v);
}

From source file:edu.ubc.mirrors.holograms.HologramClassGenerator.java

License:Open Source License

@Override
public void visit(int version, int access, String name, String signature, String superName,
        String[] interfaces) {/*from   w  w  w  .ja  v a  2 s  .  c om*/
    this.name = name;
    this.isInterface = (Opcodes.ACC_INTERFACE & access) != 0;
    this.superName = getHologramSuperclassName(isInterface, name, superName);
    interfaces = getHologramInterfaces(name, isInterface, interfaces);

    // Force everything to be public, since HologramClassLoader has to reflectively
    // construct holograms. Again, not a problem because the VM will see the original flags on the ClassMirror instead.
    // Also remove enum flags.
    int hologramAccess = forcePublic(access);
    // Also remove abstract flag. Shouldn't be necessary, but the VM (OpenJDK at least)
    // creates objects that claim to be an instance of VirtualMachineError, which is abstract.
    if (name.equals("hologram/java/lang/VirtualMachineError")) {
        hologramAccess = ~Opcodes.ACC_ABSTRACT & access;
    }

    // We need at least 1.5 to use class literal constants
    // TODO-RS: Work out a better way to interpret 45.X numbers correctly
    if (version == Opcodes.V1_1 || version < Opcodes.V1_5) {
        version = 49;
    }

    super.visit(version, hologramAccess, name, signature, this.superName, interfaces);

    if (this.name.equals(hologramThrowableType.getInternalName())) {
        // Generate aliases for the original superclass' fillInStackTrace and getStackTrace methods,
        // so we can call them in stubs without hitting hologram code.
        MethodVisitor v = super.visitMethod(Opcodes.ACC_PUBLIC, "superFillInStackTrace",
                Type.getMethodDescriptor(Type.VOID_TYPE), null, null);
        v.visitCode();
        v.visitVarInsn(Opcodes.ALOAD, 0);
        v.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Throwable.class), "fillInStackTrace",
                Type.getMethodDescriptor(Type.getType(Throwable.class)));
        v.visitInsn(Opcodes.RETURN);
        v.visitMaxs(1, 1);
        v.visitEnd();

        v = super.visitMethod(Opcodes.ACC_PUBLIC, "superGetStackTrace",
                Type.getMethodDescriptor(Type.getType(StackTraceElement[].class)), null, null);
        v.visitCode();
        v.visitVarInsn(Opcodes.ALOAD, 0);
        v.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Throwable.class), "getStackTrace",
                Type.getMethodDescriptor(Type.getType(StackTraceElement[].class)));
        v.visitInsn(Opcodes.ARETURN);
        v.visitMaxs(1, 1);
        v.visitEnd();
    }
}

From source file:edu.ubc.mirrors.holograms.HologramClassGenerator.java

License:Open Source License

@Override
public void visitEnd() {
    // Generate the static field used to store the corresponding ClassMirror
    int staticAccess = Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC;
    super.visitField(staticAccess, "classMirror", classMirrorType.getDescriptor(), null, null);

    // Generate the constructor that takes a mirror instance as an Object parameter
    String constructorDesc = Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Object.class));
    if (name.equals(getHologramType(Type.getType(Throwable.class), true).getInternalName())) {
        // This doesn't extend ObjectHologram so we have to set the field directly
        super.visitField(Opcodes.ACC_PUBLIC, "mirror", objectMirrorType.getDescriptor(), null, null);

        MethodVisitor methodVisitor = super.visitMethod(Opcodes.ACC_PUBLIC, "<init>", constructorDesc, null,
                null);//from  w  ww  . j a va 2s . c  o m
        methodVisitor.visitCode();
        methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
        methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, "<init>",
                Type.getMethodDescriptor(Type.VOID_TYPE));
        methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
        methodVisitor.visitVarInsn(Opcodes.ALOAD, 1);
        methodVisitor.visitTypeInsn(Opcodes.CHECKCAST, objectMirrorType.getInternalName());
        methodVisitor.visitFieldInsn(Opcodes.PUTFIELD, name, "mirror", Type.getDescriptor(ObjectMirror.class));
        methodVisitor.visitInsn(Opcodes.RETURN);
        methodVisitor.visitMaxs(2, 2);
        methodVisitor.visitEnd();

        methodVisitor = super.visitMethod(Opcodes.ACC_PUBLIC, "getMirror",
                Type.getMethodDescriptor(objectMirrorType), null, null);
        methodVisitor.visitCode();
        methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
        methodVisitor.visitFieldInsn(Opcodes.GETFIELD, name, "mirror", Type.getDescriptor(ObjectMirror.class));
        methodVisitor.visitInsn(Opcodes.ARETURN);
        methodVisitor.visitMaxs(1, 1);
        methodVisitor.visitEnd();
    } else if (!isInterface) {
        MethodVisitor methodVisitor = super.visitMethod(Opcodes.ACC_PUBLIC, "<init>", constructorDesc, null,
                null);
        methodVisitor.visitCode();
        methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
        methodVisitor.visitVarInsn(Opcodes.ALOAD, 1);
        methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, "<init>", constructorDesc);
        methodVisitor.visitInsn(Opcodes.RETURN);
        methodVisitor.visitMaxs(2, 2);
        methodVisitor.visitEnd();
    }

    // Add a class initialization method to initialize the static fields,
    // if one doesn't exist already.
    if (!hasClinit) {
        InstructionAdapter mv = new InstructionAdapter(
                super.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "<clinit>", "()V", null, null));
        mv.visitCode();
        HologramMethodGenerator.initializeStaticFields(Type.getObjectType(this.name), mv);
        mv.areturn(Type.VOID_TYPE);
        mv.visitMaxs(2, 2);
        mv.visitEnd();
    }

    super.visitEnd();
}

From source file:edu.ubc.mirrors.holograms.HologramClassGenerator.java

License:Open Source License

public static void generateArray(ClassVisitor visitor, HologramClassLoader loader,
        HologramClassMirror hologramClassMirror) {
    boolean isInterface = !hologramClassMirror.isImplementationClass();
    ClassMirror classMirror = hologramClassMirror.getOriginal();

    Type originalType = Reflection.typeForClassMirror(classMirror);
    Type originalElementType = originalType.getElementType();
    int dims = originalType.getDimensions();

    String internalName = getHologramType(originalType, !isInterface).getInternalName();

    ClassMirror superClassMirror = null;
    String superName = isInterface ? Type.getInternalName(Object.class)
            : Type.getInternalName(ObjectArrayHologram.class);
    Set<String> interfaces = new HashSet<String>();
    int access = Opcodes.ACC_PUBLIC | (isInterface ? Opcodes.ACC_INTERFACE : 0);

    if (originalElementType.getSort() == Type.OBJECT || originalElementType.getSort() == Type.ARRAY) {
        ClassMirror elementClass = loader.loadOriginalClassMirror(originalElementType.getClassName());
        superClassMirror = elementClass.getSuperClassMirror();

        if (isInterface) {
            if (superClassMirror != null) {
                Type superType = Reflection.makeArrayType(dims,
                        Type.getObjectType(superClassMirror.getClassName().replace('.', '/')));
                String superInterfaceName = getHologramType(superType).getInternalName();
                interfaces.add(superInterfaceName);
            }//from ww  w . ja  va  2 s  .  c o  m

            for (ClassMirror interfaceMirror : elementClass.getInterfaceMirrors()) {
                Type superType = Reflection.makeArrayType(dims,
                        Type.getObjectType(interfaceMirror.getClassName().replace('.', '/')));
                String interfaceName = getHologramType(superType).getInternalName();
                interfaces.add(interfaceName);
            }

            interfaces.add(hologramType.getInternalName());

            Type nMinus1Type = Reflection.makeArrayType(dims - 1, Type.getType(Object.class));
            interfaces.add(getHologramType(nMinus1Type).getInternalName());
        }
    }
    if (!isInterface) {
        interfaces.add(getHologramType(originalType, false).getInternalName());
    }

    visitor.visit(Opcodes.V1_5, access, internalName, null, superName, interfaces.toArray(new String[0]));

    if (isInterface) {
        // Generate clone()
        String cloneDesc = Type.getMethodDescriptor(objectType);
        MethodVisitor mv = visitor.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT, "clone", cloneDesc,
                null, null);
        mv.visitEnd();
    } else {
        // Generate thunk constructors
        String initDesc = Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(ObjectArrayMirror.class));
        MethodVisitor mv = visitor.visitMethod(Opcodes.ACC_PUBLIC, "<init>", initDesc, null, null);
        mv.visitCode();
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, "<init>", initDesc);
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(2, 2);
        mv.visitEnd();

        initDesc = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE);
        mv = visitor.visitMethod(Opcodes.ACC_PUBLIC, "<init>", initDesc, null, null);
        mv.visitCode();
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ILOAD, 1);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, "<init>", initDesc);
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(2, 2);
        mv.visitEnd();
    }

    // Generate the static field used to store the corresponding ClassMirror and the static initializer to set it
    int staticAccess = Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC;
    visitor.visitField(staticAccess, "classMirror", classMirrorType.getDescriptor(), null, null);

    InstructionAdapter mv = new InstructionAdapter(
            visitor.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "<clinit>", "()V", null, null));
    mv.visitCode();
    HologramMethodGenerator.initializeStaticFields(Type.getObjectType(internalName), mv);
    mv.areturn(Type.VOID_TYPE);
    mv.visitMaxs(2, 2);
    mv.visitEnd();

    visitor.visitEnd();
}

From source file:edu.ubc.mirrors.holograms.MainEntryAdaptor.java

License:Open Source License

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

    MethodVisitor superVisitor = super.visitMethod(access, name, desc, signature, exceptions);
    if (superVisitor != null && name.equals("main") && (Opcodes.ACC_STATIC & access) != 0
            && desc.equals(mainDesc)) {
        superVisitor.visitCode();// w  w  w  .j a  v a2 s  .c o  m
        superVisitor.visitLdcInsn(Type.getObjectType(className));
        superVisitor.visitVarInsn(Opcodes.ALOAD, 0);
        superVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(ObjectHologram.class),
                "invokeHologramMainMethod", invokeHologramMainMethodDesc);
        superVisitor.visitInsn(Opcodes.RETURN);
        superVisitor.visitMaxs(2, 1);
        superVisitor.visitEnd();
        return null;
    } else {
        return superVisitor;
    }
}

From source file:edu.ubc.mirrors.raw.NativeClassGenerator.java

License:Open Source License

@Override
public void visitEnd() {
    if (!isInterface) {
        // Generate the no-argument constructor
        String constructorDesc = Type.getMethodDescriptor(Type.VOID_TYPE);
        MethodVisitor methodVisitor = super.visitMethod(Opcodes.ACC_PUBLIC, "<init>", constructorDesc, null,
                null);//from   w  ww.j  a  v a  2  s  .c  om
        methodVisitor.visitCode();
        methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
        methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, "<init>", constructorDesc);
        methodVisitor.visitInsn(Opcodes.RETURN);
        methodVisitor.visitMaxs(1, 1);
        methodVisitor.visitEnd();
    }

    super.visitEnd();
}

From source file:edu.umd.cs.guitar.testcase.plugin.edg.ClassDBVisitor.java

License:Open Source License

@Override
public void visitVarInsn(int opcode, int var) {
    currentMethod.setEmpty(false);/*from   w  ww.  j av  a 2s  . c om*/
    if (isActionPerformedMethod && opcode == Opcodes.ALOAD && var == 1)
        currentMethod.setSharable(false);
}

From source file:erjang.EFun.java

License:Apache License

static byte[] gen_fun_class_data(int arity) {

    String self_type = EFUN_TYPE.getInternalName() + arity;

    ClassWriter cw = new ClassWriter(true);
    cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT, self_type, null,
            EFUN_TYPE.getInternalName(), null);

    make_invoke_method(cw, self_type, arity);

    CompilerVisitor.make_invoketail_method(cw, self_type, arity, 0);

    MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "arity", "()I", null, null);
    mv.visitCode();/*  www  . j  a va  2s.c  om*/
    mv.visitLdcInsn(new Integer(arity));
    mv.visitInsn(Opcodes.IRETURN);
    mv.visitMaxs(2, 2);
    mv.visitEnd();

    mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "invoke", "(" + EPROC_TYPE.getDescriptor()
            + EOBJECT_ARR_TYPE.getDescriptor() + ")" + EOBJECT_TYPE.getDescriptor(), null, PAUSABLE_EX);
    mv.visitCode();
    mv.visitVarInsn(Opcodes.ALOAD, 0); // load this
    mv.visitVarInsn(Opcodes.ALOAD, 1); // load proc
    for (int i = 0; i < arity; i++) {
        mv.visitVarInsn(Opcodes.ALOAD, 2);
        push_int(mv, i);
        mv.visitInsn(Opcodes.AALOAD);
    }

    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, self_type, "invoke", EUtil.getSignature(arity, true));

    mv.visitInsn(Opcodes.ARETURN);
    mv.visitMaxs(arity + 2, arity + 2);
    mv.visitEnd();

    mv = cw.visitMethod(Opcodes.ACC_PROTECTED, "<init>", "()V", null, null);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, EFUN_TYPE.getInternalName(), "<init>", "()V");
    mv.visitInsn(Opcodes.RETURN);
    mv.visitMaxs(1, 1);
    mv.visitEnd();

    make_cast_method(cw, arity);

    cw.visitEnd();

    byte[] data = cw.toByteArray();
    return data;
}