Example usage for org.objectweb.asm MethodVisitor visitMethodInsn

List of usage examples for org.objectweb.asm MethodVisitor visitMethodInsn

Introduction

In this page you can find the example usage for org.objectweb.asm MethodVisitor visitMethodInsn.

Prototype

@Deprecated
public void visitMethodInsn(final int opcode, final String owner, final String name, final String descriptor) 

Source Link

Document

Visits a method instruction.

Usage

From source file:com.sun.fortress.compiler.environments.TopLevelEnvGen.java

License:Open Source License

private static void putRawBaseCase(MethodVisitor mv, String className,
        Relation<String, Integer> hashCodeRelation, EnvironmentClass environmentClass, int code,
        Label notFound) {/*from w w w . j a va2  s .co  m*/

    PredicateSet<String> strings = hashCodeRelation.matchSecond(code);
    for (String testString : strings) {
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitLdcInsn(testString);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z");
        Label afterSetValue = new Label();
        mv.visitJumpInsn(Opcodes.IFEQ, afterSetValue);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ALOAD, 2);
        String idString = testString + environmentClass.namespace();
        mv.visitFieldInsn(Opcodes.PUTFIELD, className, Naming.mangleIdentifier(idString),
                environmentClass.descriptor());
        mv.visitInsn(Opcodes.RETURN);
        mv.visitLabel(afterSetValue);
    }
    mv.visitJumpInsn(Opcodes.GOTO, notFound);
}

From source file:com.sun.fortress.compiler.environments.TopLevelEnvGen.java

License:Open Source License

private static void writeRemoveMethod(ClassWriter cw, String className, String methodName, String invokeMethod,
        EnvironmentClass environmentClass) {
    MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, methodName, "(Ljava/lang/String;)V", null, null);
    mv.visitCode();/*from   w  ww.  j a  v  a 2s .com*/
    Label l0 = new Label();
    mv.visitLabel(l0);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.visitInsn(Opcodes.ACONST_NULL);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className, invokeMethod,
            "(Ljava/lang/String;" + environmentClass.descriptor() + ")V");
    Label l1 = new Label();
    mv.visitLabel(l1);
    mv.visitInsn(Opcodes.RETURN);
    Label l2 = new Label();
    mv.visitLabel(l2);
    mv.visitLocalVariable("this", Naming.internalToDesc(className), null, l0, l2, 0);
    mv.visitLocalVariable("name", "Ljava/lang/String;", null, l0, l2, 1);
    // See comment above on ClassWriter.COMPUTE_FRAMES
    mv.visitMaxs(3, 2);
    mv.visitEnd();
}

From source file:com.sun.fortress.compiler.environments.TopLevelEnvGen.java

License:Open Source License

private static void writeDumpMethod(ClassWriter cw, String className, EnvSymbolNames symbolNames) {
    MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "dump",
            "(Ljava/lang/Appendable;)Ljava/lang/Appendable;", null, new String[] { "java/io/IOException" });
    mv.visitCode();/* w ww  . j  a v a 2s.  co m*/
    Label l0 = new Label();
    mv.visitLabel(l0);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, className, "within", Type.getType(HasAt.class).getDescriptor());
    Label l1 = new Label();
    mv.visitJumpInsn(Opcodes.IFNULL, l1);
    Label l2 = new Label();
    mv.visitLabel(l2);
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, className, "within", Type.getType(HasAt.class).getDescriptor());
    mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getType(HasAt.class).getInternalName(), "at",
            "()Ljava/lang/String;");
    mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Appendable", "append",
            "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;");
    mv.visitInsn(Opcodes.POP);
    Label l3 = new Label();
    mv.visitLabel(l3);
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.visitLdcInsn("\n");
    mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Appendable", "append",
            "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;");
    mv.visitInsn(Opcodes.POP);
    Label l4 = new Label();
    mv.visitJumpInsn(Opcodes.GOTO, l4);
    mv.visitLabel(l1);
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.visitLdcInsn("Not within anything.\n");
    mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Appendable", "append",
            "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;");
    mv.visitInsn(Opcodes.POP);
    mv.visitLabel(l4);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, className, "verboseDump", "Z");
    Label l5 = new Label();
    mv.visitJumpInsn(Opcodes.IFEQ, l5);
    int linebreaks = dumpFields(mv, className, EnvironmentClass.FVALUE, symbolNames, 0);
    dumpFields(mv, className, EnvironmentClass.FTYPE, symbolNames, linebreaks);
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.visitLdcInsn("\n");
    mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Appendable", "append",
            "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;");
    mv.visitInsn(Opcodes.POP);
    mv.visitLabel(l5);
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.visitInsn(Opcodes.ARETURN);
    Label l9 = new Label();
    mv.visitLabel(l9);
    mv.visitLocalVariable("this", Naming.internalToDesc(className), null, l0, l9, 0);
    mv.visitLocalVariable("a", "Ljava/lang/Appendable;", null, l0, l9, 1);
    // See comment above on ClassWriter.COMPUTE_FRAMES
    mv.visitMaxs(2, 2);
    mv.visitEnd();
}

From source file:com.sun.fortress.compiler.environments.TopLevelEnvGen.java

License:Open Source License

private static int dumpFields(MethodVisitor mv, String className, EnvironmentClass eClass,
        EnvSymbolNames symbolNames, int linebreaks) {
    for (String fieldName : symbolNames.getSymbolNames(eClass)) {
        Label l6 = new Label();
        mv.visitLabel(l6);//  ww w  .  j a v  a  2 s . c o m
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitLdcInsn("(" + fieldName + " = ");
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Appendable", "append",
                "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;");
        mv.visitInsn(Opcodes.POP);
        Label l7 = new Label();
        mv.visitLabel(l7);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        String idString = fieldName + eClass.namespace();
        mv.visitFieldInsn(Opcodes.GETFIELD, className, Naming.mangleIdentifier(idString), eClass.descriptor());
        Label l8 = new Label();
        mv.visitJumpInsn(Opcodes.IFNULL, l8);
        Label l9 = new Label();
        mv.visitLabel(l9);
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, className, Naming.mangleIdentifier(idString), eClass.descriptor());
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, eClass.internalName(), "toString", "()Ljava/lang/String;");
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Appendable", "append",
                "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;");
        mv.visitInsn(Opcodes.POP);
        Label afterNull = new Label();
        mv.visitJumpInsn(Opcodes.GOTO, afterNull);
        mv.visitLabel(l8);
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitLdcInsn("null");
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Appendable", "append",
                "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;");
        mv.visitInsn(Opcodes.POP);
        mv.visitLabel(afterNull);
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitLdcInsn(") ");
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Appendable", "append",
                "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;");
        mv.visitInsn(Opcodes.POP);
        linebreaks = (linebreaks + 1) % 5;
        if (linebreaks == 0) {
            mv.visitVarInsn(Opcodes.ALOAD, 1);
            mv.visitLdcInsn("\n");
            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Appendable", "append",
                    "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;");
            mv.visitInsn(Opcodes.POP);
        }
    }

    return linebreaks;
}

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

License:Open Source License

void convertArg(MethodVisitor mv, String classDesc) {
    mv.visitMethodInsn(opcode(), FortressMethodAdapter.descToType(classDesc), toJavaTypeMethod,
            toJavaTypeMethodDesc);
}

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);//  w  w  w .j a v  a2  s .c om

}

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 a2 s  .  c o m*/
    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  va  2s  . co 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");
                }/* w  w  w .  j  a  v a2 s.com*/
            }
            //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

private void joinStackNoUnion(MethodVisitor mv, Label lookahead) {
    Label try2 = new Label();
    Label next = new Label();
    Label cleanup = new Label();

    mv.visitInsn(Opcodes.DUP2); //#2 <: #1
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE, Naming.RTTI_SUBTYPE_METHOD_NAME,
            Naming.RTTI_SUBTYPE_METHOD_SIG);
    mv.visitJumpInsn(Opcodes.IFEQ, try2); //if no, try opposite
    mv.visitInsn(Opcodes.POP); // want #1 (lower on the stack)
    mv.visitJumpInsn(Opcodes.GOTO, next); //done
    mv.visitLabel(try2);
    mv.visitInsn(Opcodes.SWAP);//from  ww w .  j  av  a 2  s  . c  om
    mv.visitInsn(Opcodes.DUP2); // #1 <: #2
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Naming.RTTI_CONTAINER_TYPE, Naming.RTTI_SUBTYPE_METHOD_NAME,
            Naming.RTTI_SUBTYPE_METHOD_SIG);
    mv.visitJumpInsn(Opcodes.IFEQ, cleanup); //if no, fail dispatch
    mv.visitInsn(Opcodes.POP); // want #2 (now lower on the stack)
    mv.visitJumpInsn(Opcodes.GOTO, next); //done
    mv.visitLabel(cleanup);
    mv.visitInsn(Opcodes.POP2);
    mv.visitJumpInsn(Opcodes.GOTO, lookahead);
    mv.visitLabel(next);
}