Example usage for org.objectweb.asm Opcodes INVOKESTATIC

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

Introduction

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

Prototype

int INVOKESTATIC

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

Click Source Link

Usage

From source file:com.sun.fortress.compiler.asmbytecodeoptimizer.RemoveLiteralCoercions.java

License:Open Source License

public static Substitution removeFloatLiterals(ByteCodeMethodVisitor bcmv) {
    String floatLiteral = "com/sun/fortress/compiler/runtimeValues/FFloatLiteral";
    String RR64 = "com/sun/fortress/compiler/runtimeValues/FRR64";
    ArrayList<Insn> matches = new ArrayList<Insn>();
    matches.add(new MethodInsn("INVOKESTATIC", Opcodes.INVOKESTATIC, floatLiteral, "make",
            "(D)L" + floatLiteral + ";", "targetedForRemoval"));
    matches.add(new LabelInsn("LabelInsn", new Label(), "targetedForRemoval"));
    matches.add(new VisitLineNumberInsn("visitlinenumber", 0, new Label(), "targetedForRemoval"));
    matches.add(new MethodInsn("INVOKESTATIC", Opcodes.INVOKESTATIC, "fortress/CompilerBuiltin", "coerce_RR64",
            "(Lfortress/CompilerBuiltin$FloatLiteral;)L" + RR64 + ";", "targetedForRemoval"));
    ArrayList<Insn> replacements = new ArrayList<Insn>();
    replacements.add(new MethodInsn("INVOKESTATIC", Opcodes.INVOKESTATIC, RR64, "make", "(D)L" + RR64 + ";",
            "ReplacementInsn"));
    return new Substitution(matches, replacements);
}

From source file:com.sun.fortress.compiler.asmbytecodeoptimizer.RemoveLiteralCoercions.java

License:Open Source License

public static Substitution removeFloatLiterals2(ByteCodeMethodVisitor bcmv) {
    String floatLiteral = "com/sun/fortress/compiler/runtimeValues/FFloatLiteral";
    String RR64 = "com/sun/fortress/compiler/runtimeValues/FRR64";
    ArrayList<Insn> matches = new ArrayList<Insn>();
    matches.add(new MethodInsn("INVOKESTATIC", Opcodes.INVOKESTATIC, floatLiteral, "make",
            "(D)L" + floatLiteral + ";", "targetedForRemoval"));
    matches.add(new VarInsn("ASTORE", Opcodes.ASTORE, 0, "targetedForRemoval"));
    matches.add(new LabelInsn("LabelInsn", new Label(), "targetedForRemoval"));
    matches.add(new VisitLineNumberInsn("visitlinenumber", 0, new Label(), "targetedForRemoval"));
    matches.add(new VarInsn("ALOAD", Opcodes.ALOAD, 0, "targetedForRemoval"));
    matches.add(new LabelInsn("LabelInsn", new Label(), "targetedForRemoval"));
    matches.add(new VisitLineNumberInsn("visitlinenumber", 0, new Label(), "targetedForRemoval"));
    matches.add(new MethodInsn("INVOKESTATIC", Opcodes.INVOKESTATIC, "fortress/CompilerBuiltin", "coerce_RR64",
            "(Lfortress/CompilerBuiltin$FloatLiteral;)L" + RR64 + ";", "targetedForRemoval"));
    ArrayList<Insn> replacements = new ArrayList<Insn>();
    replacements.add(new MethodInsn("INVOKESTATIC", Opcodes.INVOKESTATIC, RR64, "make", "(D)L" + RR64 + ";",
            "ReplacementInsn"));
    return new Substitution(matches, replacements);
}

From source file:com.sun.fortress.compiler.nativeInterface.fortressConverter.java

License:Open Source License

void convertResult(MethodVisitor mv, String classDesc) {
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, FortressMethodAdapter.descToType(classDesc), constructor,
            constructorType);

}

From source file:com.sun.fortress.compiler.nativeInterface.fortressConverter.java

License:Open Source License

private MethodVisitor generateNewBody(int access, String desc, String signature, String[] exceptions,
        String name, String newName) {

    Debug.debug(Debug.Type.COMPILER, 1, "generateNewBody: ", name, " with desc ", desc);

    SignatureParser sp = new SignatureParser(desc);

    List<String> desc_args = sp.getJVMArguments();
    String desc_result = sp.getJVMResult();
    List<String> fortress_args = new ArrayList<String>();
    List<fortressConverter> convert_args = new ArrayList<fortressConverter>();

    String fsig = "(";
    StringBuilder buf = new StringBuilder();
    buf.append(fsig);//w  w  w. j  av a2s . c  om
    for (String s : desc_args) {

        SignatureAndConverter s_a_c = toImplFFFF(s, name, false);
        buf.append(s_a_c.signature);
        fortress_args.add(s_a_c.signature);

        convert_args.add(s_a_c.converter);
    }
    fsig = buf.toString();
    SignatureAndConverter s_a_c = toImplFFFF(desc_result, name, true);
    fsig = fsig + ")" + s_a_c.signature;

    fortressConverter convert_result = s_a_c.converter;

    // FORWARDING METHOD, only with type conversions on the way in/out!
    MethodVisitor mv = cv.visitMethod(access, name, fsig, signature, exceptions);
    mv.visitCode();
    Label l0 = new Label();
    mv.visitLabel(l0);
    int count = 0;
    for (String s : fortress_args) {
        fortressConverter converter = convert_args.get(count);
        mv.visitVarInsn(Opcodes.ALOAD, count++);
        converter.convertArg(mv, s);
    }

    Debug.debug(Debug.Type.COMPILER, 1, "className = ", inputClassName, " name = ", name, " access = ", access);

    mv.visitMethodInsn(Opcodes.INVOKESTATIC, inputClassName, name, sp.getSignature());

    convert_result.convertResult(mv, s_a_c.signature);

    mv.visitInsn(Opcodes.ARETURN);
    mv.visitMaxs(2, 1);
    mv.visitEnd();
    return mv;
}

From source file:com.sun.fortress.compiler.OverloadSet.java

License:Open Source License

public void generateCall(MethodVisitor mv, int firstArgIndex, int one_if_method_closure) {
    if (!splitDone) {
        throw new CompilerError("Must split overload set before generating call(s)");
    }//from w  ww  .j  a  va2 s .  c o m
    int l = specificDispatchOrder.length;

    TaggedFunctionName[] functionsToCall = new TaggedFunctionName[l];
    for (int i = 0; i < l; i++) {
        functionsToCall[i] = getFunctionToCall(specificDispatchOrder[i]);
    }

    //  create type structures for parameter types.
    TypeStructure[][] type_structures = new TypeStructure[l][];
    MultiMap[] spmaps = new MultiMap[l];
    TypeStructure[] return_type_structures = new TypeStructure[l];

    for (int i = 0; i < l; i++) {
        TaggedFunctionName f = functionsToCall[i];
        Functional eff = f.getF();
        List<Param> parameters = f.getParameters();
        MultiMap<String, TypeStructure> spmap = new MultiMap<String, TypeStructure>();
        spmaps[i] = spmap;
        List<StaticParam> staticParams = staticParametersOf(f.getF());

        Type rt = oa.getRangeType(eff);
        return_type_structures[i] = makeTypeStructure(rt, null, 1, 0, staticParams, eff);

        // skip parameters -- no 'this' for ordinary functions

        if (parameters.size() == 1 && oa.getDomainType(eff) instanceof TupleType) {
            TupleType tt = (TupleType) oa.getDomainType(eff);
            List<Type> tl = tt.getElements();
            int storeAtIndex = tl.size(); // DRC back this out + firstArgIndex;
            // little dubious here, not sure we are getting the
            // right type structures for generic methods.  what about 'self'
            TypeStructure[] f_type_structures = new TypeStructure[tl.size()];
            type_structures[i] = f_type_structures;

            for (int j = 0; j < tl.size(); j++) {
                Type t = STypesUtil.insertStaticParams(tl.get(j), tt.getInfo().getStaticParams());
                TypeStructure type_structure = makeTypeStructure(t, spmap, 1, storeAtIndex, staticParams, eff);
                f_type_structures[j] = type_structure;
                storeAtIndex = type_structure.successorIndex;
            }

        } else {

            int storeAtIndex = parameters.size(); // DRC back this out + firstArgIndex;
            TypeStructure[] f_type_structures = new TypeStructure[parameters.size()];
            type_structures[i] = f_type_structures;

            for (int j = 0; j < parameters.size(); j++) {
                if (j != selfIndex()) {
                    Type t = oa.getParamType(eff, j);
                    TypeStructure type_structure = makeTypeStructure(t, spmap, 1, storeAtIndex, staticParams,
                            eff);
                    f_type_structures[j] = type_structure;
                    storeAtIndex = type_structure.successorIndex;
                }
            }
        }
    }

    for (int i = 0; i < l; i++) {
        TaggedFunctionName f = functionsToCall[i];
        TypeStructure[] f_type_structures = type_structures[i];
        Label lookahead = null;
        boolean infer = false;

        List<StaticParam> staticParams = staticParametersOf(f.getF());
        boolean last_case = i == l - 1;

        /* Trust the static checker; no need to verify
         * applicability of the last one.
         * Also, static parameters will be provided by static checker for the last one
         */
        // Will need lookahead for the next one.
        lookahead = new Label();

        // if this was a generic method that needs inference, we need to include the receiver argument
        // in the inference even if the firstArgIndex is 1 so that we can include it in inference
        // and dispatch
        //KBN-WIP is there a cleaner way to do this?
        int offset = (f_type_structures.length == specificDispatchOrder[i].getParameters().size())
                ? firstArgIndex
                : 0;

        for (int j = 0; j < f_type_structures.length; j++) {
            if (j != selfIndex()) {
                //inference needed if the type structure contains generics TODO: do generics not appearing in the parameters make sense?  probably not, but might need to deal with them.
                if (f_type_structures[j].containsTypeVariables)
                    infer = true;
            }
        }

        if (infer || !last_case)
            for (int j = 0; j < f_type_structures.length; j++) {
                // Load actual parameter
                if (j != selfIndex()) {
                    mv.visitVarInsn(Opcodes.ALOAD, j + offset);
                    f_type_structures[j].emitInstanceOf(mv, lookahead, true);
                }
            }

        //Runtime inference for some cases
        if (infer) {
            @SuppressWarnings("unchecked")
            MultiMap<String, TypeStructure> staticTss = spmaps[i];

            int localCount = f_type_structures[f_type_structures.length - 1].successorIndex; //counter for use storing stuff such as lower bounds

            //create type structures for lower bounds
            Map<StaticParam, TypeStructure> lowerBounds = new HashMap<StaticParam, TypeStructure>();
            for (StaticParam sp : staticParams)
                lowerBounds.put(sp, makeParamTypeStructure(sp, localCount++, TypeStructure.COVARIANT));

            //gather different types of bounds into Multimaps for use later
            MultiMap<StaticParam, StaticParam> relativeLowerBounds = new MultiMap<StaticParam, StaticParam>(); //form X :> Y
            MultiMap<StaticParam, Type> genericUpperBounds = new MultiMap<StaticParam, Type>(); //form X <: GenericStem[\ ... \] where Y appears in ...
            MultiMap<StaticParam, Type> concreteUpperBounds = new MultiMap<StaticParam, Type>(); //form X <: T where T contains no type variables
            for (int outer = 0; outer < staticParams.size(); outer++) {
                StaticParam outerSP = staticParams.get(outer);
                for (BaseType bt : outerSP.getExtendsClause()) {
                    if (bt instanceof VarType) { // outerSP <: bt so outerSP will provide a lower bound on BT
                        String varName = ((VarType) bt).getName().getText();
                        boolean found = false;
                        for (int inner = 0; inner < outer && !found; inner++) {
                            StaticParam innerSP = staticParams.get(inner);
                            if (varName.equals(innerSP.getName().getText())) {
                                relativeLowerBounds.putItem(innerSP, outerSP); // outerSP provides a lower bound on innerSP
                                found = true;
                            }
                        }
                        if (!found)
                            throw new CompilerError(
                                    "Bad Scoping of static parameters found during runtime inference codegen:"
                                            + varName + " not declared before used in a bound");
                    } else if (bt instanceof AnyType) { //figure out if concrete or generic
                        //do nothing - no need to add meaningless upper bound
                    } else if (bt instanceof NamedType) {
                        if (isGeneric(bt))
                            genericUpperBounds.putItem(outerSP, bt);
                        else
                            concreteUpperBounds.putItem(outerSP, bt);
                    }
                }
            }

            //infer and load RTTIs
            for (int j = 0; j < staticParams.size(); j++) {
                StaticParam sp = staticParams.get(staticParams.size() - 1 - j); //reverse order due to left to right scoping
                Set<TypeStructure> instances = staticTss.get(sp.getName().getText());

                //sort static parameters by their variance and put into
                //arrays using their local variable number
                List<Integer> invariantInstances = new ArrayList<Integer>();
                List<Integer> covariantInstances = new ArrayList<Integer>();
                List<Integer> contravariantInstances = new ArrayList<Integer>();
                if (instances != null)
                    for (TypeStructure ts : instances) {
                        switch (ts.variance) {
                        case TypeStructure.INVARIANT:
                            invariantInstances.add(ts.localIndex);
                            break;
                        case TypeStructure.CONTRAVARIANT:
                            contravariantInstances.add(ts.localIndex);
                            break;
                        case TypeStructure.COVARIANT:
                            covariantInstances.add(ts.localIndex);
                            break;
                        default:
                            throw new CompilerError("Unexpected Variance on TypeStructure during "
                                    + "generic instantiation analysis for overload dispatch");
                        }
                    }

                // if any invariant instances, we must use that RTTI and check that 
                //1) any other invariant instances are the same type (each subtypes the other)
                //2) any covariant instances are subtypes of the invariant instance
                //3) any contravariant instances are supertypes of the invariant instance
                if (invariantInstances.size() > 0) {

                    //a valid instantiation must use the runtime type
                    //of all invariant instances (which must all be the same)
                    //thus, wlog, we can use the first invariant instance
                    int RTTItoUse = invariantInstances.get(0);

                    //1) for each other invariant instance, they must be the same
                    //which we test by checking that each subtypes the other
                    for (int k = 1; k < invariantInstances.size(); k++) {
                        int RTTIcompare = invariantInstances.get(k);
                        //RTTItoUse.runtimeSupertypeOf(RTTIcompare)
                        mv.visitVarInsn(Opcodes.ALOAD, RTTItoUse);
                        mv.visitVarInsn(Opcodes.ALOAD, RTTIcompare);
                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE,
                                Naming.RTTI_SUBTYPE_METHOD_NAME, Naming.RTTI_SUBTYPE_METHOD_SIG);
                        mv.visitJumpInsn(Opcodes.IFEQ, lookahead); //if false fail
                        //RTTIcompare.runtimeSupertypeOf(RTTItoUse)
                        mv.visitVarInsn(Opcodes.ALOAD, RTTIcompare);
                        mv.visitVarInsn(Opcodes.ALOAD, RTTItoUse);
                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE,
                                Naming.RTTI_SUBTYPE_METHOD_NAME, Naming.RTTI_SUBTYPE_METHOD_SIG);
                        mv.visitJumpInsn(Opcodes.IFEQ, lookahead); //if false fail
                    }

                    //2) for each covariant instance, the runtime type (RTTIcompare) must be a
                    // subtype of the instantiated type (RTTItoUse)
                    for (int RTTIcompare : covariantInstances) {
                        //RTTItoUse.runtimeSupertypeOf(RTTIcompare)
                        mv.visitVarInsn(Opcodes.ALOAD, RTTItoUse);
                        mv.visitVarInsn(Opcodes.ALOAD, RTTIcompare);
                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE,
                                Naming.RTTI_SUBTYPE_METHOD_NAME, Naming.RTTI_SUBTYPE_METHOD_SIG);
                        mv.visitJumpInsn(Opcodes.IFEQ, lookahead); //if false fail
                    }

                    //3) for each contravariant instance, the instantiated type (RTTItoUse) must be a 
                    // subtype of the runtime type (RTTIcompare)
                    for (int RTTIcompare : contravariantInstances) {
                        //RTTIcompare.runtimeSupertypeOf(RTTItoUse)
                        mv.visitVarInsn(Opcodes.ALOAD, RTTIcompare);
                        mv.visitVarInsn(Opcodes.ALOAD, RTTItoUse);
                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE,
                                Naming.RTTI_SUBTYPE_METHOD_NAME, Naming.RTTI_SUBTYPE_METHOD_SIG);
                        mv.visitJumpInsn(Opcodes.IFEQ, lookahead); //if false fail
                    }

                    //check lower bounds given by other variables
                    Set<StaticParam> relativeLB = relativeLowerBounds.get(sp);
                    if (relativeLB != null)
                        for (StaticParam lb : relativeLB) {
                            //RTTItoUse.runtimeSupertypeOf(otherLB)
                            int otherOffset = lowerBounds.get(lb).localIndex;
                            mv.visitVarInsn(Opcodes.ALOAD, RTTItoUse);
                            mv.visitVarInsn(Opcodes.ALOAD, otherOffset);
                            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE,
                                    Naming.RTTI_SUBTYPE_METHOD_NAME, Naming.RTTI_SUBTYPE_METHOD_SIG);
                            mv.visitJumpInsn(Opcodes.IFEQ, lookahead); //if false fail
                        }

                    //verify meets upper bounds
                    Set<Type> concreteUB = concreteUpperBounds.get(sp);
                    if (concreteUB != null)
                        for (Type cub : concreteUB) {
                            //transform into RTTI
                            generateRTTIfromStaticType(mv, cub);
                            mv.visitVarInsn(Opcodes.ALOAD, RTTItoUse);
                            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE,
                                    Naming.RTTI_SUBTYPE_METHOD_NAME, Naming.RTTI_SUBTYPE_METHOD_SIG);
                            mv.visitJumpInsn(Opcodes.IFEQ, lookahead); //if false fail
                        }

                    //generate more bounds for generic upper bounds
                    Set<Type> genericUB = genericUpperBounds.get(sp);
                    if (genericUB != null)
                        for (Type gub : genericUB) {
                            TypeStructure newTS = makeTypeStructure(gub, staticTss, TypeStructure.COVARIANT,
                                    localCount, staticParams, null);
                            localCount = newTS.successorIndex;
                            mv.visitVarInsn(Opcodes.ALOAD, RTTItoUse);
                            newTS.emitInstanceOf(mv, lookahead, false); //fail if RTTItoUse doesn't have this structure
                        }

                    //checks out, so store the RTTI we will use into the lower bound for this parameter
                    mv.visitVarInsn(Opcodes.ALOAD, RTTItoUse);
                    int index = lowerBounds.get(sp).localIndex;
                    mv.visitVarInsn(Opcodes.ASTORE, index);

                } else if (contravariantInstances.size() == 0) { //we can do inference for covariant-only occurrences

                    boolean started = false;
                    if (covariantInstances.size() > 0) {
                        started = true;
                        mv.visitVarInsn(Opcodes.ALOAD, covariantInstances.get(0));

                        for (int k = 1; k < covariantInstances.size(); k++) {
                            mv.visitVarInsn(Opcodes.ALOAD, covariantInstances.get(k));
                            //TODO: allow unions
                            joinStackNoUnion(mv, lookahead); //fails if cannot join w/o union
                        }
                    }

                    //incorporate lower bounds 
                    Set<StaticParam> relativeLB = relativeLowerBounds.get(sp);
                    if (relativeLB != null)
                        for (StaticParam lb : relativeLB) {
                            mv.visitVarInsn(Opcodes.ALOAD, lowerBounds.get(lb).localIndex);
                            if (started) { //join it in
                                //TODO: allow unions
                                joinStackNoUnion(mv, lookahead);
                            } else { //start with this lower bound
                                started = true;
                            }
                        }

                    if (started) {

                        //verify meets upper bounds
                        Set<Type> concreteUB = concreteUpperBounds.get(sp);
                        if (concreteUB != null)
                            for (Type cub : concreteUB) {
                                Label cleanup = new Label();
                                Label next = new Label();

                                mv.visitInsn(Opcodes.DUP);
                                generateRTTIfromStaticType(mv, cub); //transform concrete bound into RTTI
                                mv.visitInsn(Opcodes.SWAP); // LB <: CUB
                                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE,
                                        Naming.RTTI_SUBTYPE_METHOD_NAME, Naming.RTTI_SUBTYPE_METHOD_SIG);
                                mv.visitJumpInsn(Opcodes.IFEQ, cleanup);
                                mv.visitJumpInsn(Opcodes.GOTO, next);
                                mv.visitLabel(cleanup);
                                mv.visitInsn(Opcodes.POP);
                                mv.visitJumpInsn(Opcodes.GOTO, lookahead);
                                mv.visitLabel(next);
                            }

                        //checks out, so store to lower bound of sp
                        int index = lowerBounds.get(sp).localIndex;
                        mv.visitVarInsn(Opcodes.ASTORE, index);

                        //generate more bounds for generic upper bounds
                        Set<Type> genericUB = genericUpperBounds.get(sp);
                        if (genericUB != null)
                            for (Type gub : genericUB) {
                                TypeStructure newTS = makeTypeStructure(gub, staticTss, TypeStructure.COVARIANT,
                                        localCount, staticParams, null);
                                localCount = newTS.successorIndex;
                                mv.visitVarInsn(Opcodes.ALOAD, index);
                                newTS.emitInstanceOf(mv, lookahead, false); //fail if candidate doesn't have this structure
                            }

                    } else {
                        //Bottom is ok - no need to check upper bounds
                        //or generate lower bounds
                        mv.visitFieldInsn(Opcodes.GETSTATIC, Naming.RT_VALUES_PKG + "VoidRTTI",
                                Naming.RTTI_SINGLETON, Naming.RTTI_CONTAINER_DESC);
                        int index = lowerBounds.get(sp).localIndex;
                        mv.visitVarInsn(Opcodes.ASTORE, index);

                    }

                } else { //otherwise, we might need to do inference which is not implemented yet
                    throw new CompilerError("non-invariant inference with contravariance not implemented");
                }
            }

            //load instance cache table to avoid classloader when possible
            String tableName = this.generateClosureTableName(specificDispatchOrder[i]); //use original function for table name
            String tableOwner = this.generateClosureTableOwner(f);
            mv.visitFieldInsn(Opcodes.GETSTATIC, tableOwner, tableName, Naming.CACHE_TABLE_DESC);

            //load template class name
            String arrow = this.instanceArrowSchema(f); //NamingCzar.makeArrowDescriptor(f.getParameters(), f.getReturnType(),f.tagA);
            String functionName = this.functionName(f);

            String templateClass = Naming.genericFunctionPkgClass(Naming.dotToSep(f.tagA.getText()),
                    functionName, Naming.LEFT_OXFORD + Naming.RIGHT_OXFORD, arrow);

            if (otherOverloadKeys.contains(templateClass)) {
                templateClass = Naming.genericFunctionPkgClass(Naming.dotToSep(f.tagA.getText()),
                        NamingCzar.mangleAwayFromOverload(functionName),
                        Naming.LEFT_OXFORD + Naming.RIGHT_OXFORD, arrow);
                //templateClass = NamingCzar.mangleAwayFromOverload(templateClass);
            }

            mv.visitLdcInsn(templateClass);

            String ic_sig;
            if (staticParams.size() > 6) { //use an array
                //load the function: RThelpers.loadClosureClass:(BAlongTree,String,RTTI[])
                String paramList = Naming.CACHE_TABLE_DESC + NamingCzar.descString
                        + Naming.RTTI_CONTAINER_ARRAY_DESC;
                ic_sig = Naming.makeMethodDesc(paramList, Naming.internalToDesc(NamingCzar.internalObject));

                mv.visitLdcInsn(staticParams.size());
                mv.visitTypeInsn(Opcodes.ANEWARRAY, Naming.RTTI_CONTAINER_TYPE);

                //dup array enough times to store RTTIs into it  //know need at least 6 more
                mv.visitInsn(Opcodes.DUP); //first one to get arrays as top two elts on stack

                for (int numDups = staticParams.size() - 1; numDups > 0; numDups = numDups / 2)
                    mv.visitInsn(Opcodes.DUP2);
                if (staticParams.size() % 2 == 0)
                    mv.visitInsn(Opcodes.DUP); //if even, started halving with an odd number, so needs one last

                //store parameters into array
                for (int k = 0; k < staticParams.size(); k++) {
                    int index = lowerBounds.get(staticParams.get(k)).localIndex;
                    mv.visitLdcInsn(k); //index is the static param number
                    mv.visitVarInsn(Opcodes.ALOAD, index);
                    mv.visitInsn(Opcodes.AASTORE);
                }

                //array left on stack

            } else {
                //load the function: RTHelpers.loadClosureClass:(BAlongTree,(String,RTTI)^n)Object
                ic_sig = InstantiatingClassloader.jvmSignatureForOnePlusNTypes(
                        Naming.CACHE_TABLE_TYPE + ";L" + NamingCzar.internalString, staticParams.size(),
                        Naming.RTTI_CONTAINER_TYPE, Naming.internalToDesc(NamingCzar.internalObject));

                //load parameter RTTIs
                for (int k = 0; k < staticParams.size(); k++) {
                    int index = lowerBounds.get(staticParams.get(k)).localIndex;
                    mv.visitVarInsn(Opcodes.ALOAD, index);
                }

            }
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, Naming.RT_HELPERS, "loadClosureClass", ic_sig);

            //cast to object arrow
            int numParams = f.getParameters().size();
            String objectAbstractArrow = NamingCzar.objectAbstractArrowTypeForNParams(numParams);
            InstantiatingClassloader.generalizedCastTo(mv, objectAbstractArrow);

            //if a method parameters converted
            //loadThisForMethods(mv);

            //load parameters
            for (int j = 0; j < f_type_structures.length; j++) {
                // Load actual parameter
                if (j != selfIndex()) {
                    mv.visitVarInsn(Opcodes.ALOAD, j); // DRC back this out+ one_if_method_closure); // + firstArgIndex); KBN if a method, parameters already converted
                    //no cast needed here - done by apply method
                }
            }

            //call apply method
            String objectArrow = NamingCzar.objectArrowTypeForNParams(numParams);
            String applySig = InstantiatingClassloader.jvmSignatureForNTypes(numParams,
                    NamingCzar.internalObject, Naming.internalToDesc(NamingCzar.internalObject));
            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, objectArrow, Naming.APPLY_METHOD, applySig);

            //cast to correct return type
            Type f_return = f.getReturnType();
            if (f_return instanceof BottomType) {
                CodeGen.castToBottom(mv);
            } else {
                String returnType = NamingCzar.makeBoxedTypeName(f_return, f.tagA);
                InstantiatingClassloader.generalizedCastTo(mv, returnType);
            }
        } else {

            //no inferences needed
            loadThisForMethods(mv);

            for (int j = 0; j < f_type_structures.length; j++) {
                // Load actual parameter
                if (j != selfIndex()) {
                    mv.visitVarInsn(Opcodes.ALOAD, j + firstArgIndex);
                    InstantiatingClassloader.generalizedCastTo(mv, f_type_structures[j].fullname);
                }
            }

            String sig = jvmSignatureFor(f);

            invokeParticularMethod(mv, f, sig);
            Type f_return = f.getReturnType();
            if (f_return instanceof BottomType) {
                CodeGen.castToBottom(mv);
            }
        }

        mv.visitInsn(Opcodes.ARETURN);

        if (lookahead != null)
            mv.visitLabel(lookahead);
    }
}

From source file:com.sun.fortress.compiler.OverloadSet.java

License:Open Source License

private void generateRTTIfromStaticType(MethodVisitor mv, Type t) {
    if (t instanceof TraitType) {
        List<StaticArg> args = ((TraitType) t).getArgs();
        if (args != null && args.size() > 0) {
            //recurse
            for (StaticArg sa : args) {
                if (sa instanceof TypeArg) {
                    generateRTTIfromStaticType(mv, ((TypeArg) sa).getTypeArg());
                } else {
                    throw new CompilerError("Expected TypeArg for RTTI generation");
                }/*from   w  w w  .j ava  2  s .co m*/
            }
            //find component for type and call factory
            String typeName = NamingCzar.jvmTypeDesc(t, this.ifNone, false);
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, typeName + Naming.RTTI_CLASS_SUFFIX, Naming.RTTI_FACTORY,
                    Naming.rttiFactorySig(args.size()));
        } else {
            //find component for type and grab singleton RTTI
            String typeName = NamingCzar.jvmTypeDesc(t, this.ifNone, false);
            mv.visitFieldInsn(Opcodes.GETSTATIC, typeName + Naming.RTTI_CLASS_SUFFIX, Naming.RTTI_SINGLETON,
                    Naming.RTTI_CONTAINER_DESC);
        }
    } else {
        throw new CompilerError("Expected Trait Type for RTTI generation");
    }
}

From source file:com.sun.fortress.compiler.OverloadSet.java

License:Open Source License

protected void generateBody(MethodVisitor mv, int one_if_method_closure) {
    mv.visitCode();/*from   w ww .  ja  v a  2  s.c  om*/
    //   Label fail = new Label();

    generateCall(mv, firstArg(), one_if_method_closure); // Guts of overloaded method

    // Emit failure case
    //        mv.visitLabel(fail);
    //        // Boilerplate for throwing an error.
    //        // mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);

    mv.visitMethodInsn(Opcodes.INVOKESTATIC, NamingCzar.miscCodegen, NamingCzar.matchFailure,
            NamingCzar.errorReturn);
    mv.visitInsn(Opcodes.ATHROW);

    mv.visitMaxs(getParamCount(), getParamCount()); // autocomputed
    mv.visitEnd();
}

From source file:com.sun.fortress.runtimeSystem.FValueHandle.java

License:Open Source License

public void checkValue(FValue val) {
    mv.visitLdcInsn(val);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com.sun.fortress.runtimeSystem.TransactionRecord", "checkValue",
            "(Lcom.sun.fortress.compiler.runtimeValues.FValue;Lcom.sun.fortress.compiler.runtimeValues.FValue;)()");
}

From source file:com.sun.fortress.runtimeSystem.Instantiater.java

License:Open Source License

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    // necessary?
    name = oprs.getMethodName(name);//from  ww  w .  ja  va  2 s. c  om
    //System.out.println("old desc=" + desc);
    //desc = types.getMethodDesc(desc);
    //System.out.println("new desc=" + desc);
    String newDesc = types.getMethodDesc(desc);
    MethodVisitor mv = cv.visitMethod(access, name, newDesc, signature, exceptions);

    if (!desc.equals(newDesc)) { // catch flattened tuples
        String params = desc.substring(desc.indexOf("(") + 1, //TODO: wrong if nested parens
                desc.indexOf(")"));
        String newParams = newDesc.substring(newDesc.indexOf("(") + 1, newDesc.indexOf(")"));
        if (params.split(";").length == 1 && //single generic parameter 
                newParams.startsWith("LTuple")) { //tuple substituted in
            //System.out.println(access + " " + name + " " + signature + " " +this.instanceName);
            if ((this.access_flags & Opcodes.ACC_INTERFACE) == 0 && //not in an interface
                    (access & Opcodes.ACC_STATIC) == 0) { //and not a static method, so generate a body  

                //extract the parameters and create strings for the types 
                List<String> paramList = InstantiationMap.extractStringParameters(newParams,
                        newParams.indexOf(Naming.LEFT_OXFORD),
                        InstantiationMap.templateClosingRightOxford(newParams), new ArrayList<String>());
                String rawParams = "";
                for (String p : paramList)
                    rawParams = rawParams + Naming.internalToDesc(p);
                final String altDesc = newDesc.substring(0, newDesc.indexOf("(") + 1) + rawParams
                        + newDesc.substring(newDesc.indexOf(")"), newDesc.length());
                String tuple_params = InstantiatingClassloader.stringListToTuple(paramList);
                String make_sig = InstantiatingClassloader.toJvmSig(paramList,
                        Naming.javaDescForTaggedFortressType(tuple_params));

                MethodVisitor altMv = cv.visitMethod(access, name, altDesc, signature, exceptions);

                altMv.visitVarInsn(Opcodes.ALOAD, 0); //load this

                final int n = paramList.size(); //load the parameters
                for (int i = 1; i <= n; i++) {
                    altMv.visitVarInsn(Opcodes.ALOAD, i);
                }
                altMv.visitMethodInsn(Opcodes.INVOKESTATIC, InstantiatingClassloader.CONCRETE_ + tuple_params,
                        "make", make_sig); //create a tuple from the parameters

                if (name.equals("<init>")) {
                    altMv.visitMethodInsn(Opcodes.INVOKESPECIAL, this.instanceName, name, newDesc); //call original method
                    altMv.visitInsn(Opcodes.RETURN); //return
                } else {
                    altMv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, this.instanceName, name, newDesc); //call original method
                    altMv.visitInsn(Opcodes.ARETURN); //return
                }
                altMv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter);
                altMv.visitEnd();
            }
        }
    }
    return new MethodInstantiater(mv, types, icl);
}

From source file:com.sun.fortress.runtimeSystem.InstantiatingClassloader.java

License:Open Source License

private byte[] instantiateAbstractArrow(String name, List<String> parameters) {
    ManglingClassWriter cw = new ManglingClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);

    /*/*ww w .j a  va2 s.  com*/
     * Special case extensions to plumb tuples
     * correctly in the face of generics instantiated
     * with tuple types.
     * 
     * Except, recall that Arrow parameters are domain...;range
     * 
     * if > 1 param then
     *   unwrap = params
     *   wrap = tuple params
     * else 1 param
     *   if tuple
     *     wrap = param
     *     unwrap = untuple params
     *   else
     *     unwrap = param
     *     wrap = null
     *     
     *  Use unwrapped parameters to generate the all-Objects case
     *  for casting; check the generated signature against the input
     *  to see if we are them.
     *   
     */

    Triple<List<String>, List<String>, String> stuff = normalizeArrowParameters(parameters);

    List<String> flat_params_and_ret = stuff.getA();
    List<String> tupled_params_and_ret = stuff.getB();
    String tupleType = stuff.getC();

    List<String> flat_obj_params_and_ret = Useful.applyToAll(flat_params_and_ret, toJLO);
    List<String> norm_obj_params_and_ret = normalizeArrowParametersAndReturn(flat_obj_params_and_ret);
    List<String> norm_params_and_ret = normalizeArrowParametersAndReturn(flat_params_and_ret);

    String obj_sig = stringListToGeneric(ABSTRACT_ARROW, norm_obj_params_and_ret);
    String obj_intf_sig = stringListToGeneric(Naming.ARROW_TAG, norm_obj_params_and_ret);
    String wrapped_sig = stringListToGeneric(WRAPPED_ARROW, norm_params_and_ret);
    String typed_intf_sig = stringListToGeneric(Naming.ARROW_TAG, norm_params_and_ret);
    String unwrapped_apply_sig;

    if (parameters.size() == 2 && parameters.get(0).equals(Naming.INTERNAL_SNOWMAN))
        unwrapped_apply_sig = arrowParamsToJVMsig(parameters.subList(1, 2));
    else
        unwrapped_apply_sig = arrowParamsToJVMsig(flat_params_and_ret);

    String obj_apply_sig = arrowParamsToJVMsig(flat_obj_params_and_ret);

    String[] interfaces = new String[] { stringListToArrow(norm_params_and_ret) };
    /*
     * Note that in the case of foo -> bar,
     * normalized = flattened, and tupled does not exist (is null).
     */
    String typed_tupled_intf_sig = tupled_params_and_ret == null ? null
            : stringListToGeneric(Naming.ARROW_TAG, tupled_params_and_ret);
    String objectified_tupled_intf_sig = tupled_params_and_ret == null ? null
            : stringListToGeneric(Naming.ARROW_TAG, Useful.applyToAll(tupled_params_and_ret, toJLO));

    boolean is_all_objects = norm_obj_params_and_ret.equals(norm_params_and_ret);

    String _super = is_all_objects ? "java/lang/Object" : obj_sig;

    cw.visit(JVM_BYTECODE_VERSION, ACC_PUBLIC + ACC_SUPER + ACC_ABSTRACT, name, null, _super, interfaces);

    simpleInitMethod(cw, _super);

    /* */
    if (!is_all_objects) {
        // implement method for the object version.
        // cast parameters, invoke this.apply on cast parameters, ARETURN

        // note cut and paste from apply below, work in progress.

        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, Naming.APPLY_METHOD, obj_apply_sig, null, null);

        mv.visitVarInsn(Opcodes.ALOAD, 0); // this

        int unwrapped_l = flat_params_and_ret.size();

        for (int i = 0; i < unwrapped_l - 1; i++) {
            String t = flat_params_and_ret.get(i);
            if (!t.equals(Naming.INTERNAL_SNOWMAN) || unwrapped_l > 2) {
                mv.visitVarInsn(Opcodes.ALOAD, i + 1); // element
                // mv.visitTypeInsn(CHECKCAST, t);
                generalizedCastTo(mv, Naming.internalToType(t));
            }
        }

        mv.visitMethodInsn(INVOKEVIRTUAL, name, Naming.APPLY_METHOD, unwrapped_apply_sig);
        mv.visitInsn(Opcodes.ARETURN);
        mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter);

        mv.visitEnd();
    }

    // is instance method -- takes an Object
    {
        String sig = "(Ljava/lang/Object;)Z";
        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, IS_A, sig, null, null);

        Label fail = new Label();

        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitTypeInsn(Opcodes.INSTANCEOF, Naming.ANY_TYPE_CLASS);
        mv.visitJumpInsn(Opcodes.IFEQ, fail);

        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitTypeInsn(Opcodes.CHECKCAST, Naming.ANY_TYPE_CLASS);
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, name, IS_A,
                "(" + Naming.internalToDesc(Naming.ANY_TYPE_CLASS) + ")Z");
        mv.visitInsn(Opcodes.IRETURN);

        mv.visitLabel(fail);
        mv.visitIntInsn(BIPUSH, 0);
        mv.visitInsn(Opcodes.IRETURN);

        mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter);
        mv.visitEnd();
    }

    // is instance method -- takes an Any
    {
        String sig = "(" + Naming.internalToDesc(Naming.ANY_TYPE_CLASS) + ")Z";
        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, IS_A, sig, null, null);
        Label fail = new Label();

        //get RTTI to compare to
        mv.visitFieldInsn(GETSTATIC, name, Naming.RTTI_FIELD, Naming.RTTI_CONTAINER_DESC);
        //get RTTI of object
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(INVOKEINTERFACE, Naming.ANY_TYPE_CLASS, Naming.RTTI_GETTER,
                "()" + Naming.RTTI_CONTAINER_DESC);
        // mv.visitJumpInsn(IFNONNULL, fail);
        mv.visitMethodInsn(INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE, Naming.RTTI_SUBTYPE_METHOD_NAME,
                Naming.RTTI_SUBTYPE_METHOD_SIG);

        //mv.visitIntInsn(BIPUSH, 0);
        mv.visitJumpInsn(Opcodes.IFEQ, fail);

        mv.visitIntInsn(BIPUSH, 1);
        mv.visitInsn(Opcodes.IRETURN);

        mv.visitLabel(fail);
        mv.visitIntInsn(BIPUSH, 0);
        mv.visitInsn(Opcodes.IRETURN);
        mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter);
        mv.visitEnd();
    }

    // castTo
    {
        /*
         *  If arg0 instanceof typed_intf_sig
         *     return arg0
         *  arg0 = arg0.getWrappee()
         *  if arg0 instanceof typed_intf_sig
         *     return arg0
         *  new WrappedArrow
         *  dup
         *  push argo
         *  init
         *  return tos
         */

        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, CAST_TO, "(" +
        // Naming.internalToDesc(obj_intf_sig)
                "Ljava/lang/Object;" + ")" + Naming.internalToDesc(typed_intf_sig), null, null);

        Label not_instance1 = new Label();
        Label not_instance2 = new Label();

        // try bare instanceof
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitTypeInsn(Opcodes.INSTANCEOF, typed_intf_sig);
        mv.visitJumpInsn(Opcodes.IFEQ, not_instance1);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitTypeInsn(Opcodes.CHECKCAST, typed_intf_sig);
        mv.visitInsn(Opcodes.ARETURN);

        // unwrap
        mv.visitLabel(not_instance1);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitTypeInsn(Opcodes.CHECKCAST, obj_intf_sig);
        mv.visitMethodInsn(INVOKEINTERFACE, obj_intf_sig, getWrappee,
                "()" + Naming.internalToDesc(obj_intf_sig));
        mv.visitVarInsn(Opcodes.ASTORE, 0);

        // try instanceof on unwrapped
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitTypeInsn(Opcodes.INSTANCEOF, typed_intf_sig);
        mv.visitJumpInsn(Opcodes.IFEQ, not_instance2);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitTypeInsn(Opcodes.CHECKCAST, typed_intf_sig);
        mv.visitInsn(Opcodes.ARETURN);

        // wrap and return
        mv.visitLabel(not_instance2);
        mv.visitTypeInsn(NEW, wrapped_sig);
        mv.visitInsn(DUP);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, wrapped_sig, "<init>",
                "(" + Naming.internalToDesc(obj_intf_sig) + ")V");

        mv.visitInsn(Opcodes.ARETURN);
        mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter);

        mv.visitEnd();
    }

    if (typed_tupled_intf_sig != null) {
        /*
         *  If arg0 instanceof typed_intf_sig
         *     return arg0
         *  arg0 = arg0.getWrappee()
         *  if arg0 instanceof typed_intf_sig
         *     return arg0
         *  new WrappedArrow
         *  dup
         *  push argo
         *  init
         *  return tos
         */

        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, CAST_TO,
                "(" + Naming.internalToDesc(objectified_tupled_intf_sig) + ")"
                        + Naming.internalToDesc(typed_intf_sig),
                null, null);

        Label not_instance1 = new Label();
        Label not_instance2 = new Label();

        // try bare instanceof
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitTypeInsn(Opcodes.INSTANCEOF, typed_intf_sig);
        mv.visitJumpInsn(Opcodes.IFEQ, not_instance1);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitInsn(Opcodes.ARETURN);

        // unwrap
        mv.visitLabel(not_instance1);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(INVOKEINTERFACE, objectified_tupled_intf_sig, getWrappee,
                "()" + Naming.internalToDesc(objectified_tupled_intf_sig));
        mv.visitVarInsn(Opcodes.ASTORE, 0);

        // try instanceof on unwrapped
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitTypeInsn(Opcodes.INSTANCEOF, typed_intf_sig);
        mv.visitJumpInsn(Opcodes.IFEQ, not_instance2);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitInsn(Opcodes.ARETURN);

        // wrap and return - untupled should be okay here, since it subtypes
        mv.visitLabel(not_instance2);
        mv.visitTypeInsn(NEW, wrapped_sig);
        mv.visitInsn(DUP);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, wrapped_sig, "<init>",
                "(" + Naming.internalToDesc(obj_intf_sig) + ")V");

        mv.visitInsn(Opcodes.ARETURN);
        mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter);

        mv.visitEnd();
    }

    // getWrappee
    {
        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, getWrappee, "()" + Naming.internalToDesc(obj_intf_sig),
                null, null);

        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitInsn(ARETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd(); // return this
    }

    if (tupled_params_and_ret == null) {
        /* Single abstract method */
        if (LOG_LOADS)
            System.err.println(name + ".apply" + unwrapped_apply_sig + " abstract for abstract");
        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, Naming.APPLY_METHOD, unwrapped_apply_sig,
                null, null);
        mv.visitEnd();

    } else {
        /*
         * Establish two circular forwarding methods;
         * the eventual implementer will break the cycle.
         * 
         */
        String tupled_apply_sig = arrowParamsToJVMsig(tupled_params_and_ret);

        {
            /* Given tupled args, extract, and invoke apply. */

            if (LOG_LOADS)
                System.err.println(name + ".apply" + tupled_apply_sig + " abstract for abstract");
            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, Naming.APPLY_METHOD, tupled_apply_sig, null, null);

            mv.visitVarInsn(Opcodes.ALOAD, 0); // closure

            int unwrapped_l = flat_params_and_ret.size();

            for (int i = 0; i < unwrapped_l - 1; i++) {
                String param = flat_params_and_ret.get(i);
                mv.visitVarInsn(Opcodes.ALOAD, 1); // tuple
                mv.visitMethodInsn(INVOKEINTERFACE, tupleType, TUPLE_TYPED_ELT_PFX + (Naming.TUPLE_ORIGIN + i),
                        "()" + Naming.internalToDesc(param));
            }

            mv.visitMethodInsn(INVOKEVIRTUAL, name, Naming.APPLY_METHOD, unwrapped_apply_sig);
            mv.visitInsn(Opcodes.ARETURN);
            mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter);

            mv.visitEnd();
        }

        { /* Given untupled args, load, make a tuple, invoke apply. */
            if (LOG_LOADS)
                System.err.println(name + ".apply" + unwrapped_apply_sig + " abstract for abstract");
            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, Naming.APPLY_METHOD, unwrapped_apply_sig, null, null);

            mv.visitVarInsn(Opcodes.ALOAD, 0); // closure

            int unwrapped_l = flat_params_and_ret.size();

            for (int i = 0; i < unwrapped_l - 1; i++) {
                mv.visitVarInsn(Opcodes.ALOAD, i + 1); // element
            }

            List<String> tuple_elements = flat_params_and_ret.subList(0, unwrapped_l - 1);

            String make_sig = toJvmSig(tuple_elements, Naming.javaDescForTaggedFortressType(tupleType));
            mv.visitMethodInsn(INVOKESTATIC, stringListToGeneric(CONCRETE_TUPLE, tuple_elements), "make",
                    make_sig);

            mv.visitMethodInsn(INVOKEVIRTUAL, name, Naming.APPLY_METHOD, tupled_apply_sig);
            mv.visitInsn(Opcodes.ARETURN);
            mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter);

            mv.visitEnd();
        }

    }

    //RTTI comparison field

    final String final_name = name;
    ArrayList<InitializedStaticField> isf_list = new ArrayList<InitializedStaticField>();
    if (!parameters.contains("java/lang/Object")) {

        isf_list.add(new InitializedStaticField.StaticForUsualRttiField(final_name, this));
    } else {
        isf_list.add(new InitializedStaticField.StaticForJLOParameterizedRttiField(final_name));
    }
    cw.visitEnd();
    //      //RTTI getter
    {
        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, Naming.RTTI_GETTER, "()" + Naming.RTTI_CONTAINER_DESC,
                null, null);
        mv.visitCode();
        mv.visitFieldInsn(GETSTATIC, name, Naming.RTTI_FIELD, Naming.RTTI_CONTAINER_DESC);
        mv.visitInsn(ARETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }

    optionalStaticsAndClassInitForTO(isf_list, cw);
    return cw.toByteArray();
}