List of usage examples for org.objectweb.asm Label Label
public Label()
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++; }