Example usage for org.objectweb.asm Label Label

List of usage examples for org.objectweb.asm Label Label

Introduction

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

Prototype

public Label() 

Source Link

Document

Constructs a new label.

Usage

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

License:Open Source License

public static void inlineMethodCall(String className, ByteCodeMethodVisitor method, MethodInsn mi,
        ByteCodeMethodVisitor methodToInline, Boolean staticMethod) {
    List<Insn> insns = new ArrayList<Insn>();
    Label start = new Label();
    Label end = new Label();
    int argsStart = methodToInline.args.size();
    int localsStart = methodToInline.maxLocals;
    int index = 0;
    insns.add(new LabelInsn("start_" + mi._name, start, newIndex(mi, index++)));
    int[] offsets = new int[methodToInline.maxLocals + 1];

    // Static Method start at args.size() - 1, NonStatic Methods start at args.size()
    if (staticMethod)
        argsStart = argsStart - 1;/*ww w  . ja  v  a2 s.  c o m*/

    for (int i = argsStart; i >= 0; i--) {
        insns.add(new VarInsn("ASTORE", Opcodes.ASTORE, method.maxLocals + i, newIndex(mi, index++)));
        offsets[i] = method.maxLocals + i;
    }

    for (int i = localsStart - 1; i > argsStart; i--)
        offsets[i] = method.maxLocals + i;

    method.maxStack = method.maxStack + methodToInline.maxStack;
    method.maxLocals = method.maxLocals + methodToInline.args.size() + methodToInline.maxLocals;
    insns.addAll(convertInsns(mi, methodToInline.insns, offsets, index, end));
    insns.add(new LabelInsn("end_" + mi._name, end, newIndex(mi, insns.size())));

    for (Insn insn : insns) {
        insn.setParentInsn(mi);
    }

    mi.inlineExpansionInsns.addAll(insns);
}

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

License:Open Source License

public static Substitution removeIntLiterals(ByteCodeMethodVisitor bcmv) {
    String intLiteral = "com/sun/fortress/compiler/runtimeValues/FIntLiteral";
    String ZZ32 = "com/sun/fortress/compiler/runtimeValues/FZZ32";

    ArrayList<Insn> matches = new ArrayList<Insn>();
    matches.add(new MethodInsn("INVOKESTATIC", Opcodes.INVOKESTATIC, intLiteral, "make",
            "(I)L" + intLiteral + ";", "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_ZZ32",
            "(Lfortress/CompilerBuiltin$IntLiteral;)L" + ZZ32 + ";", "targetedForRemoval"));
    ArrayList<Insn> replacements = new ArrayList<Insn>();
    replacements.add(new MethodInsn("INVOKESTATIC", Opcodes.INVOKESTATIC, ZZ32, "make", "(I)L" + ZZ32 + ";",
            "ReplacementInsn"));
    return new Substitution(matches, replacements);
}

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.codegen.CodeGen.java

License:Open Source License

public void forAtomicBlock(Block x) {
    Label start = new Label();
    Label end = new Label();
    Label exit = new Label();
    Label handler = new Label();
    Label startOver = new Label();
    String type = "com/sun/fortress/runtimeSystem/TransactionAbortException";

    mv.visitLabel(startOver);/*from  www  .  j  a v a 2 s.c  o m*/
    mv.visitTryCatchBlock(start, end, handler, type);

    mv.visitLabel(start);
    forAtomicBlockHelper(x);
    mv.visitLabel(end);
    mv.visitJumpInsn(GOTO, exit);

    // Exception Handler
    mv.visitLabel(handler);
    mv.visitInsn(POP); // Pop the exception
    mv.visitMethodInsn(INVOKESTATIC, "com/sun/fortress/runtimeSystem/BaseTask", "cleanupTransaction", "()V");
    // Wait a randomized exponential amount of time after an error
    mv.visitMethodInsn(INVOKESTATIC, "com/sun/fortress/runtimeSystem/BaseTask", "delayTransaction", "()V");
    mv.visitJumpInsn(GOTO, startOver);

    // Exit
    mv.visitLabel(exit);
}

From source file:com.sun.fortress.compiler.codegen.CodeGen.java

License:Open Source License

public void forTry(Try x) {
    Label l0 = new Label();
    Label l1 = new Label();
    Label l2 = new Label();
    Label lfinally = new Label();

    Block body = x.getBody();/*from w w  w . ja  v a  2  s .  co  m*/
    Option<Catch> catchClauses = x.getCatchClause();
    List<BaseType> forbid = x.getForbidClause();
    Option<Block> finallyClause = x.getFinallyClause();
    if (!forbid.isEmpty())
        throw new RuntimeException("NYI: Forbid clauses are not yet implemented");

    mv.visitTryCatchBlock(l0, l1, l2, "com/sun/fortress/compiler/runtimeValues/FException");
    mv.visitLabel(l0);
    body.accept(this);
    mv.visitLabel(l1);
    mv.visitJumpInsn(GOTO, lfinally);
    mv.visitLabel(l2);
    // We really should have desugared this into typecase, but for now...

    mv.visitFrame(Opcodes.F_SAME1, 0, null, 1,
            new Object[] { "com/sun/fortress/compiler/runtimeValues/FException" });

    if (catchClauses.isSome()) {
        Catch _catch = catchClauses.unwrap();
        Id name = _catch.getName();

        Label done = new Label(); // first statement after the whole try-catch statement
        List<CatchClause> clauses = _catch.getClauses();
        for (CatchClause clause : clauses) {
            Label end = new Label(); // if catch clause does not match, skip clause body
            BaseType match = clause.getMatchType();

            mv.visitInsn(DUP); // Save Java exception while we fiddle with Fortress data
            mv.visitMethodInsn(INVOKEVIRTUAL, "com/sun/fortress/compiler/runtimeValues/FException", "getValue",
                    "()Lcom/sun/fortress/compiler/runtimeValues/FValue;");

            InstantiatingClassloader.generalizedInstanceOf(mv, NamingCzar.jvmBoxedTypeName(match, thisApi()));
            mv.visitJumpInsn(IFEQ, end);
            mv.visitInsn(POP);
            clause.getBody().accept(this);
            mv.visitJumpInsn(GOTO, done);
            mv.visitLabel(end);
        }
        mv.visitInsn(ATHROW); // Rethrow if no match
        mv.visitLabel(done);
    }
    mv.visitLabel(lfinally);
    if (finallyClause.isSome()) {
        finallyClause.unwrap().accept(this);
        popAll(mv, 1);
    }
}

From source file:com.sun.fortress.compiler.codegen.CodeGen.java

License:Open Source License

public void forTypecase(Typecase x) {
    Expr expr = x.getBindExpr();//  ww  w . j a  va 2s  . c om
    expr.accept(this);

    Label done = new Label();
    for (TypecaseClause c : x.getClauses()) {
        Label next = new Label();
        Label end = new Label();
        TypeOrPattern match = c.getMatchType();
        Type typ = getType(match);
        mv.visitInsn(DUP);
        InstantiatingClassloader.generalizedInstanceOf(mv, NamingCzar.jvmBoxedTypeName(typ, thisApi()));
        mv.visitJumpInsn(IFNE, next);
        mv.visitJumpInsn(GOTO, end);
        mv.visitLabel(next);
        mv.visitInsn(POP);
        c.getBody().accept(this);
        mv.visitJumpInsn(GOTO, done);
        mv.visitLabel(end);
    }

    if (x.getElseClause().isSome()) {
        mv.visitInsn(POP);
        x.getElseClause().unwrap().accept(this);
        mv.visitJumpInsn(GOTO, done);
    }

    mv.visitMethodInsn(INVOKESTATIC, NamingCzar.internalFortressVoid, NamingCzar.make,
            NamingCzar.voidToFortressVoid);

    mv.visitLabel(done);

}

From source file:com.sun.fortress.compiler.codegen.CodeGen.java

License:Open Source License

/**
 * Generates the method that is called to find the closure for a generic method.
 * The method name is some minor frob on the Fortress method name, but it needs
 * the schema to help avoid overloading conflicts on the name.
 * /*from  w  ww .  j av  a 2  s . c om*/
 *  <pre>
 *  private static BAlongTree sampleLookupTable = new BAlongTree();
 *  public Object sampleLookup(long hashcode, String signature) {
 *  Object o = sampleLookupTable.get(hashcode);
 *  if (o == null) 
 *     o = findGenericMethodClosure(hashcode,
 *                                  sampleLookupTable,
 *                                  "template_class_name",
 *                                  signature);
 *  return o;
 *  }
 *  </pre>
 * @param method_name - may be mangled to avoid a name clash
 * @param table_name - always the unmangled version of the method_name
 * @param template_class_name
 * @param savedInATrait 
 */
public void generateGenericMethodClosureFinder(String method_name, final String table_name,
        String template_class_name, final String class_file, boolean savedInATrait) {

    initializedStaticFields_TO.add(new InitializedStaticField() {

        @Override
        public void forClinit(MethodVisitor my_mv) {
            my_mv.visitTypeInsn(NEW, Naming.CACHE_TABLE_TYPE);
            my_mv.visitInsn(DUP);
            my_mv.visitMethodInsn(INVOKESPECIAL, Naming.CACHE_TABLE_TYPE, "<init>", "()V");
            my_mv.visitFieldInsn(PUTSTATIC, class_file, table_name,
                    Naming.internalToDesc(Naming.CACHE_TABLE_TYPE));
        }

        @Override
        public String asmName() {
            return table_name;
        }

        @Override
        public String asmSignature() {
            return Naming.internalToDesc(Naming.CACHE_TABLE_TYPE);
        }

    });

    int hashOff = savedInATrait ? 0 : 1;
    int stringOff = hashOff + 2;
    int tmpOff = stringOff + 1;

    int access = savedInATrait ? ACC_PUBLIC + ACC_STATIC : ACC_PUBLIC;
    if (savedInATrait)
        method_name = method_name + Naming.GENERIC_METHOD_FINDER_SUFFIX_IN_TRAIT;

    List<StaticParam> to_sparams = this.currentTraitObjectDecl.getHeader().getStaticParams();

    CodeGenMethodVisitor mv = cw.visitCGMethod(access, method_name, genericMethodClosureFinderSig, null, null);
    mv.visitCode();
    Label l0 = new Label();
    mv.visitLabel(l0);
    //mv.visitLineNumber(1331, l0);
    mv.visitFieldInsn(GETSTATIC, class_file, table_name, Naming.internalToDesc(Naming.CACHE_TABLE_TYPE));
    mv.visitVarInsn(LLOAD, hashOff);
    mv.visitMethodInsn(INVOKEVIRTUAL, Naming.CACHE_TABLE_TYPE, "get", "(J)Ljava/lang/Object;");
    mv.visitVarInsn(ASTORE, tmpOff);
    Label l1 = new Label();
    mv.visitLabel(l1);
    //mv.visitLineNumber(1332, l1);
    mv.visitVarInsn(ALOAD, tmpOff);
    Label l2 = new Label();
    mv.visitJumpInsn(IFNONNULL, l2);
    Label l3 = new Label();
    mv.visitLabel(l3);
    //mv.visitLineNumber(1333, l3);
    mv.visitVarInsn(LLOAD, hashOff);
    mv.visitFieldInsn(GETSTATIC, class_file, table_name, Naming.internalToDesc(Naming.CACHE_TABLE_TYPE));
    mv.visitLdcInsn(template_class_name);
    mv.visitVarInsn(ALOAD, stringOff);
    // if in a generic trait/object, need to call different method and include one more parameter.
    if (to_sparams.size() == 0) {
        mv.visitMethodInsn(INVOKESTATIC, Naming.RT_HELPERS, "findGenericMethodClosure",
                "(JLcom/sun/fortress/runtimeSystem/BAlongTree;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;");
    } else {
        // Need to use the substitute-at-load string operation.
        String string_sargs = NamingCzar.genericDecoration(null, to_sparams, null, thisApi());
        String loadString = Naming.opForString(Naming.stringMethod, string_sargs);
        mv.visitMethodInsn(INVOKESTATIC, Naming.magicInterpClass, loadString, "()Ljava/lang/String;");
        mv.visitMethodInsn(INVOKESTATIC, Naming.RT_HELPERS, "findGenericMethodClosure",
                "(JLcom/sun/fortress/runtimeSystem/BAlongTree;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;");
    }
    mv.visitVarInsn(ASTORE, tmpOff);
    mv.visitLabel(l2);
    //mv.visitLineNumber(1335, l2);
    mv.visitFrame(F_APPEND, 1, new Object[] { "java/lang/Object" }, 0, null);
    mv.visitVarInsn(ALOAD, tmpOff);
    mv.visitInsn(ARETURN);
    Label l4 = new Label();
    mv.visitLabel(l4);

    if (!savedInATrait)
        mv.visitLocalVariable("this", Naming.internalToDesc(class_file), null, l0, l4, 0);

    mv.visitLocalVariable("hashcode", "J", null, l0, l4, hashOff);
    mv.visitLocalVariable("signature", "Ljava/lang/String;", null, l0, l4, stringOff);
    mv.visitLocalVariable("o", "Ljava/lang/Object;", null, l1, l4, tmpOff);
    // 6,6 if in a generic trait.
    //        mv.visitMaxs(5, 5);
    mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter);
    mv.visitEnd();
}

From source file:com.sun.fortress.compiler.codegen.CodeGen.java

License:Open Source License

private void RttiClassAndInterface(TraitObjectDecl tod, ClassNameBundle cnb, Naming.XlationData xldata) {

    TraitTypeHeader header = tod.getHeader();

    IdOrOpOrAnonymousName name = header.getName();
    List<StaticParam> sparams = header.getStaticParams();

    HashMap<Id, TraitIndex> transitive_extends = STypesUtil.allSupertraits(tod, typeAnalyzer);

    HashMap<String, Tuple2<TraitIndex, List<StaticArg>>> transitive_extends_opr_tagged = oprTagSupertraitsAndArgs(
            STypesUtil.allSupertraitsAndStaticArgs(tod, typeAnalyzer));

    HashMap<String, Tuple2<TraitIndex, List<StaticArg>>> direct_extends_opr_tagged = oprTagSupertraitsAndArgs(
            STypesUtil.immediateSupertraitsAndStaticArgs(tod, typeAnalyzer));

    HashMap<Id, TraitIndex> direct_extends = STypesUtil.immediateSupertraits(tod, typeAnalyzer);

    HashMap<Id, List<StaticArg>> direct_extends_args = STypesUtil.immediateSupertraitsStaticArgs(tod,
            typeAnalyzer);//  w  w w .ja va2s  .c o  m

    int d_e_size = direct_extends.size();

    CodeGenClassWriter prev = cw;
    cw = new CodeGenClassWriter(ClassWriter.COMPUTE_FRAMES, prev);

    /*
     * x$RTTIi
     * extends y$RTTIi for each y in extend_s
            
     * for each static parameter of x, declares method "asX"#number
            
     * x$RTTIc
     * implements x$RTTIi
            
     * fields
     * for each y in extend_s, one field, initially null, type y$RttiClass
     * for each z in static parameters, one field, init in constructor
            
     * constructor (init method)
     * parameters for static parameters, if any.
     * 
     * if no static parameters, then a static field initialized to the
     * single value of the type.
     * if static parameters, then a static field initialized to a map of
     * some sort, plus a factory receiving static parameters, that checks
     * the map, and allocates the type as necessary.
            
     * lazy_init method
     * for each y in extend_s, field = new y$RTTIc(type parameters).
     * type parameters need thinking about how we put them together.
     * If extends A[B[T]], should be new A$RTTIc(new B$RTTIc(T))
     * Seems like a factory would be appropriate, to avoid senseless
     * duplication of type parameters.
            
     * methods
     * for each static parameter #N of each type T in transitive_extends,
     * there needs to be a method as"T"#N.  For all non-self types, the
     * method will check lazy_init, and then delegate to the first type
     * in extend_s that has T in its own transitive_extends.  For T=self,
     * return the value of the appropriate static parameter.
            
     */

    /*
     * x$RTTIi
     * extends y$RTTIi for each y in extend_s
     */

    Naming.XlationData original_xldata = xldata;
    List<String> opr_params = oprsFromKindParamList(xldata.staticParameterKindNamePairs());
    xldata = opr_params.size() == 0 ? null : xlationData(Naming.RTTI_GENERIC_TAG);
    for (String opr_param : opr_params)
        xldata.addKindAndNameToStaticParams(Naming.XL_OPR, opr_param);
    String stemClassName = Naming.oprArgAnnotatedRTTI(cnb.stemClassName, opr_params);

    String rttiInterfaceName = Naming.stemInterfaceToRTTIinterface(stemClassName);
    String rttiInterfaceFileName = opr_params.size() == 0 ? rttiInterfaceName
            : Naming.stemInterfaceToRTTIinterface(Naming.fileForOprTaggedGeneric(cnb.stemClassName));

    String[] superInterfaces = new String[d_e_size];

    Id[] direct_extends_keys = new Id[d_e_size]; // will use in lazyInit
    {
        int i = 0;
        for (Id extendee : direct_extends.keySet()) {
            List<StaticArg> ti_args = direct_extends_args.get(extendee);
            String extendeeIlk = oprTaggedGenericStemNameSA(extendee, ti_args);

            //            String extendeeIlk =
            //                NamingCzar.jvmClassForToplevelTypeDecl(extendee,"",
            //                        packageAndClassName);
            direct_extends_keys[i] = extendee;
            superInterfaces[i++] = Naming.stemInterfaceToRTTIinterface(extendeeIlk);
        }
    }

    cw.visitSource(NodeUtil.getSpan(tod).begin.getFileName(), null);
    cw.visit(InstantiatingClassloader.JVM_BYTECODE_VERSION, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE,
            rttiInterfaceName, null, NamingCzar.internalObject, superInterfaces);

    /*
     * for each static parameter of x, declares method "asX"#number
     */
    {
        int i = Naming.STATIC_PARAMETER_ORIGIN;
        for (StaticParam sp : sparams) {
            if (!(sp.getKind() instanceof KindOp)) {
                String method_name = Naming.staticParameterGetterName(stemClassName, i);
                mv = cw.visitCGMethod(ACC_ABSTRACT + ACC_PUBLIC, method_name,
                        Naming.STATIC_PARAMETER_GETTER_SIG, null, null);
                mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter);
                mv.visitEnd();
                i++;
            }
        }
    }

    cw.dumpClass(rttiInterfaceFileName, xldata);

    cw = new CodeGenClassWriter(ClassWriter.COMPUTE_FRAMES, prev);

    /*
     * x$RTTIc
     * implements x$RTTIi
     */

    superInterfaces = new String[1];
    superInterfaces[0] = rttiInterfaceName;
    String rttiClassName = Naming.stemClassToRTTIclass(stemClassName);
    String rttiClassFileName = opr_params.size() == 0 ? rttiClassName
            : Naming.stemClassToRTTIclass(Naming.fileForOprTaggedGeneric(cnb.stemClassName));

    cw.visitSource(NodeUtil.getSpan(tod).begin.getFileName(), null);
    cw.visit(InstantiatingClassloader.JVM_BYTECODE_VERSION, ACC_PUBLIC, rttiClassName, null,
            Naming.RTTI_CONTAINER_TYPE, superInterfaces);

    /*
     * fields
     * for each y in extend_s, one field, initially null, type y$RttiClass
     * for each z in static parameters, one field, init in constructor
     */

    for (Id extendee : direct_extends.keySet()) {

        // This yutch is repeated below in lazyInit; needs cleanup.
        List<StaticArg> ti_args = direct_extends_args.get(extendee);
        String extendeeIlk = oprTaggedGenericStemNameSA(extendee, ti_args);

        // note fields are volatile because of double-checked locking below
        cw.visitField(ACC_PRIVATE + ACC_VOLATILE, extendeeIlk, Naming.RTTI_CONTAINER_DESC, null, null);
    }

    // Fields and Getters for static parameters
    int count_non_opr_sparams;
    {
        int i = Naming.STATIC_PARAMETER_ORIGIN;
        for (StaticParam sp : sparams) {
            if (!(sp.getKind() instanceof KindOp)) {
                String spn = sp.getName().getText();
                String stem_name = stemClassName;
                InstantiatingClassloader.fieldAndGetterForStaticParameter(cw, stem_name, spn, i);
                i++;
            }
        }
        count_non_opr_sparams = i - Naming.STATIC_PARAMETER_ORIGIN;
    }

    /*
     * constructor (init method)
     * parameters for static parameters, if any.
     */
    final int sparams_size = count_non_opr_sparams;
    {
        // Variant of this code in InstantiatingClassloader
        String init_sig = InstantiatingClassloader.jvmSignatureForOnePlusNTypes("java/lang/Class", sparams_size,
                Naming.RTTI_CONTAINER_TYPE, "V");
        mv = cw.visitCGMethod(ACC_PUBLIC, "<init>", init_sig, null, null);
        mv.visitCode();

        mv.visitVarInsn(ALOAD, 0); // this
        mv.visitVarInsn(ALOAD, 1); // class
        mv.visitMethodInsn(INVOKESPECIAL, Naming.RTTI_CONTAINER_TYPE, "<init>", "(Ljava/lang/Class;)V");

        int pno = 2; // 1 is java class
        for (StaticParam sp : sparams) {
            if (!(sp.getKind() instanceof KindOp)) {
                String spn = sp.getName().getText();
                // not yet this;  sp.getKind();
                mv.visitVarInsn(ALOAD, 0);
                mv.visitVarInsn(ALOAD, pno);
                mv.visitFieldInsn(PUTFIELD, rttiClassName, spn, Naming.RTTI_CONTAINER_DESC);
                pno++;
            }
        }

        voidEpilogue();
    }

    cw.visitField(ACC_PRIVATE + ACC_VOLATILE, "initFlag", "Ljava/lang/Object;", null, null);

    /*
     * static singleton or static map + factory.
     */
    if (sparams_size == 0) {
        // static, initialized to single instance of self
        cw.visitField(ACC_PUBLIC + ACC_STATIC + ACC_FINAL, Naming.RTTI_SINGLETON, Naming.RTTI_CONTAINER_DESC,
                null, null);

        mv = cw.visitCGMethod(ACC_STATIC, "<clinit>", "()V", null, null);
        mv.visitCode();
        // new
        mv.visitTypeInsn(NEW, rttiClassName);
        // init
        mv.visitInsn(DUP);
        mv.visitLdcInsn(org.objectweb.asm.Type.getType(cnb.classDesc));
        mv.visitMethodInsn(INVOKESPECIAL, rttiClassName, "<init>", "(Ljava/lang/Class;)V");
        // store
        mv.visitFieldInsn(PUTSTATIC, rttiClassName, Naming.RTTI_SINGLETON, Naming.RTTI_CONTAINER_DESC);

        voidEpilogue();
    } else {
        InstantiatingClassloader.emitDictionaryAndFactoryForGenericRTTIclass(cw, rttiClassName, sparams_size,
                original_xldata);
    }

    /*
     * lazy_init method
     * for each y in extend_s, field = new y$RTTIc(type parameters).
     * type parameters need thinking about how we put them together.
     * If extends A[B[T]], should be new A$RTTIc(new B$RTTIc(T))
     * Seems like a factory would be appropriate, to avoid senseless
     * duplication of type parameters.
     */
    if (d_e_size > 0) {
        mv = cw.visitCGMethod(ACC_PUBLIC, "lazyInit", "()V", null, null);
        mv.visitCode();

        Label do_ret = new Label();
        Label do_monitor_ret = new Label();

        //debugging - catch exceptions thrown inside the monitor
        Label debugTryStart = new Label();
        Label debugTryEnd = new Label();
        Label debugHandler = new Label();
        mv.visitTryCatchBlock(debugTryStart, debugTryEnd, debugHandler, "java/lang/Throwable");
        mv.visitLabel(debugTryStart);
        //end debugging - more below    

        // Double-checked locking.
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, rttiClassName, "initFlag", "Ljava/lang/Object;");
        mv.visitJumpInsn(IFNONNULL, do_ret);

        mv.visitVarInsn(ALOAD, 0);
        mv.visitInsn(MONITORENTER);

        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, rttiClassName, "initFlag", "Ljava/lang/Object;");
        mv.visitJumpInsn(IFNONNULL, do_monitor_ret);

        HashSet<String> spns = new HashSet<String>();
        for (StaticParam sp : sparams) {
            IdOrOp spn = sp.getName();
            String s = spn.getText();
            spns.add(s);
        }

        // Do the initialization.
        // Push all the type parameters
        for (Id extendee : direct_extends_keys) {
            TraitIndex ti = direct_extends.get(extendee);
            List<StaticArg> ti_args = direct_extends_args.get(extendee);
            String extendeeIlk = oprTaggedGenericStemNameSA(extendee, ti_args);

            mv.visitVarInsn(ALOAD, 0); // this ptr for store.
            // invoke factory method for value to store.
            generateTypeReference(mv, rttiClassName, extendee, ti_args, spns);
            mv.visitFieldInsn(PUTFIELD, rttiClassName, extendeeIlk, Naming.RTTI_CONTAINER_DESC);
        }

        // Mark as inited.  Just store a self-pointer and be done with it.
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(PUTFIELD, rttiClassName, "initFlag", "Ljava/lang/Object;");

        //more debugging
        mv.visitLabel(debugTryEnd);
        Label debugPassCatch = new Label();
        mv.visitJumpInsn(GOTO, debugPassCatch);
        mv.visitLabel(debugHandler);
        mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" });
        mv.visitVarInsn(ASTORE, 0);
        Label debugInternal = new Label();
        mv.visitLabel(debugInternal);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESTATIC, "com/sun/fortress/runtimeSystem/InstantiatingClassloader", "eep",
                "(Ljava/lang/Throwable;)V");
        mv.visitLabel(debugPassCatch);
        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        //end more debugging

        mv.visitLabel(do_monitor_ret);

        mv.visitVarInsn(ALOAD, 0);
        mv.visitInsn(MONITOREXIT);

        mv.visitLabel(do_ret);
        voidEpilogue();
    }

    /*
     * methods
     * for each static parameter #N of each type T in transitive_extends,
     * there needs to be a method as"T"#N.  For all non-self types, the
     * method will check lazy_init, and then delegate to the first type
     * in extend_s that has T in its own transitive_extends.  For T=self,
     * return the value of the appropriate static parameter.
     */

    /* 
     * First map extends to what they transitively extend for delegation
     * The keys of this map are the members of the extends list;
     * the values, for each car, are those things that further
     * transitively extend that extender.  Each static-parameter-probing
     * method for the type (T) whose RTTI is being generated, will either
     * return a field (static parameter) of T, or will delegate to one
     * of the types extending T.
     */
    HashMap<String, Map<String, Tuple2<TraitIndex, List<StaticArg>>>> transitive_extends_from_extends = new HashMap<String, Map<String, Tuple2<TraitIndex, List<StaticArg>>>>();

    for (Map.Entry<Id, TraitIndex> entry : direct_extends.entrySet()) {
        Id te_id = entry.getKey();
        TraitIndex te_ti = entry.getValue();
        HashMap<Id, Tuple2<TraitIndex, List<StaticArg>>> extends_transitive_extends_tmp = STypesUtil
                .allSupertraitsAndStaticArgs(te_ti.ast(), typeAnalyzer);

        Tuple2<TraitIndex, List<StaticArg>> te_pair = new Tuple2<TraitIndex, List<StaticArg>>(te_ti,
                direct_extends_args.get(te_id));
        extends_transitive_extends_tmp.put(te_id, te_pair); // put self in set.

        HashMap<String, Tuple2<TraitIndex, List<StaticArg>>> extends_transitive_extends = oprTagSupertraitsAndArgs(
                extends_transitive_extends_tmp);

        String te_id_stem = oprTaggedGenericStemNameSA(te_id, direct_extends_args.get(te_id));

        transitive_extends_from_extends.put(te_id_stem, extends_transitive_extends);
    }

    // Future opt: sort by transitive_extends, use largest as class ancestor

    // For each type in extends list, emit forwarding functions (delegates)
    // remove traits from transitive_extends as they are dealt with.

    for (Map.Entry<Id, TraitIndex> entry : direct_extends.entrySet()) {
        if (transitive_extends.size() == 0)
            break;
        Id de_id = entry.getKey();
        String de_id_stem = oprTaggedGenericStemNameSA(de_id, direct_extends_args.get(de_id));
        TraitIndex de_ti = entry.getValue();

        // iterate over all traits transitively extended by delegate (de_)            
        Map<String, Tuple2<TraitIndex, List<StaticArg>>> extends_transitive_extends = transitive_extends_from_extends
                .get(de_id_stem);
        Set<Map.Entry<String, Tuple2<TraitIndex, List<StaticArg>>>> entryset = extends_transitive_extends
                .entrySet();

        for (Map.Entry<String, Tuple2<TraitIndex, List<StaticArg>>> extends_entry : entryset) {

            // delegate for extended te_id, if not already done.
            String te_id = extends_entry.getKey();
            if (!transitive_extends_opr_tagged.containsKey(te_id))
                continue; // already done.
            else
                transitive_extends_opr_tagged.remove(te_id);

            Tuple2<TraitIndex, List<StaticArg>> te_ti = extends_entry.getValue();
            List<StaticParam> te_sp = te_ti._1.staticParameters();

            if (te_sp.size() == 0)
                continue; // no static parameters to delegate for.

            String te_stem = te_id;
            // emit delegates here
            // asX#number
            int i = Naming.STATIC_PARAMETER_ORIGIN;
            for (StaticParam a_sparam : te_sp) {
                StaticParamKind spk = a_sparam.getKind();
                if (spk instanceof KindOp)
                    continue;
                String method_name = Naming.staticParameterGetterName(te_stem, i);

                mv = cw.visitCGMethod(ACC_PUBLIC, method_name, Naming.STATIC_PARAMETER_GETTER_SIG, null, null);
                mv.visitCode();

                // lazyInit();
                mv.visitVarInsn(ALOAD, 0);
                mv.visitMethodInsn(INVOKEVIRTUAL, rttiClassName, "lazyInit", "()V");

                String delegate_id = null;
                // invoke delegate -- work in progress here
                if (direct_extends_opr_tagged.containsKey(te_id) || te_id.equals(name)) {
                    delegate_id = te_id;
                } else { //need to find a direct extend that extends the trait we're looking for
                    for (String direct_extend_id : direct_extends_opr_tagged.keySet()) {
                        if (transitive_extends_from_extends.get(direct_extend_id).containsKey(te_id)) {
                            delegate_id = direct_extend_id;
                            break;
                        }
                    }
                }
                if (delegate_id == null)
                    throw new CompilerError(
                            "Could not find directly extended trait that transitively extends" + te_id);

                mv.visitVarInsn(ALOAD, 0);
                getExtendeeField(rttiClassName, delegate_id);
                String extendeeIlk = delegate_id; // NamingCzar.jvmClassForToplevelTypeDecl(delegate_id,"",packageAndClassName);
                String field_type = Naming.stemClassToRTTIclass(extendeeIlk);
                mv.visitMethodInsn(INVOKEVIRTUAL, field_type, method_name, Naming.STATIC_PARAMETER_GETTER_SIG);

                areturnEpilogue();
                i++;
            }
        }
    }
    cw.dumpClass(rttiClassFileName, xldata);
    cw = prev;
}

From source file:com.sun.fortress.compiler.codegen.CodeGenMethodVisitor.java

License:Open Source License

/**
 * the correct way to get a local is to call createCompilerLocal,
 * which will give you a stack offset that acts as a handle on the
 * local variable you requested, and then to hand that local
 * variable back again when you're done by calling
 * disposeCompilerLocal so that debug information can be generated
 * where possible, and so that stack slots can be reused in a
 * sensible way.  If you are representing a variable in Fortress
 * source code, you should do this in the constructor for a
 * VarCodeGen; CodeGen maintains a lexEnv that maps a Fortress
 * variable to the corresponding VarCodeGen. */

// Non-user-accessible local variable
public int createCompilerLocal(String _name, String type) {
    if (localVariableCount != varNames.size()) {
        throw new CompilerError(
                "Trying to create local " + _name + " but current metadata is off\nlocalVariableCount = "
                        + localVariableCount + "\nvarNames = " + varNames);
    }/* w w w  .  j a v  a 2  s .c  o m*/
    Debug.debug(Debug.Type.CODEGEN, 2, "LOCAL create ", localVariableCount, " ", _name);
    varNames.add(_name);
    varTypes.add(type);
    Label start = new Label();
    visitLabel(start);
    varFirstUse.add(start);

    return localVariableCount++;
}