////////////////////////////////////////////////////////////////////////// // Is/As ////////////////////////////////////////////////////////////////////////// private void @is() { FTypeRef typeRef = pod.typeRef(u2()); // if a generic instance, we have to use a method call // because Fantom types don't map to Java classes exactly; // otherwise we can use straight bytecode if (typeRef.isGenericInstance()) { if (parent.IsViaType == null) { parent.IsViaType = emitter.findMethod("Fanx.Util.OpUtil", "is", new string[] { "System.Object", "Fan.Sys.Type" }, "System.Boolean"); } loadType(typeRef); code.MethInst(MethodOp.call, parent.IsViaType); } else { PERWAPI.Type type = emitter.findType(typeRef.nnameBoxed()); code.TypeInst(TypeOp.isinst, type); code.Inst(Op.ldnull); code.Inst(Op.cgt_un); } }
////////////////////////////////////////////////////////////////////////// // Overrides ////////////////////////////////////////////////////////////////////////// protected override string @base() { // if the base is a generic instance, then this must be a closure // method type (since we can't subclass List or Map). We subclass // from one of the canned Func.Indirect inner classes. FTypeRef refer = pod.typeRef(type.m_base); if (refer.isGenericInstance()) { this.funcType = (FuncType)Type.find(refer.signature, true); int paramCount = funcType.m_params.Length; if (paramCount > Func.MaxIndirectParams) { return("Fan.Sys.Func/IndirectX"); } else { return("Fan.Sys.Func/Indirect" + paramCount); } } else { string baset = nname(type.m_base); if (baset == "System.Object") { return("Fan.Sys.FanObj"); } if (baset == "Fan.Sys.Type") { return("Fan.Sys.ClassType"); } return(baset); } }
private void loadType(FTypeRef tref) { string podName = tref.podName; string typeName = tref.typeName; // if pod is "sys", then we can perform a shortcut and use // one of the predefined fields in Sys if (!tref.isGenericInstance() && podName == "sys") { PERWAPI.Field field = emitter.findField("Fan.Sys.Sys", typeName + "Type", "Fan.Sys.Type"); code.FieldInst(FieldOp.ldsfld, field); if (tref.isNullable()) { typeToNullable(); } return; } // lazy allocate my parent's type literal map: sig -> fieldName if (parent.typeLiteralFields == null) { parent.typeLiteralFields = new Hashtable(); } Hashtable map = parent.typeLiteralFields; // types are lazy loaded and then cached in a private static field called // type$literal$count which will get generated by FTypeEmit (we keep track of signature // to fieldname in the typeConstFields map) string sig = tref.signature; string fieldName = (string)map[sig]; if (fieldName == null) { fieldName = "type$literal$" + map.Count; map[sig] = fieldName; } //int fieldRef = emit.field(parent.className + "." + fieldName + ":Lfan/sys/Type;"); //code.op2(GETSTATIC, fieldRef); //code.op(DUP); //int nonNull = code.branch(IFNONNULL); //code.op(POP); //code.op2(LDC_W, emit.strConst(sig)); //code.op(ICONST_1); //code.op2(INVOKESTATIC, parent.sysFindType()); //code.op(DUP); //code.op2(PUTSTATIC, fieldRef); //code.mark(nonNull); //emitter.EmitField(string name, string type, FieldAttr attr) //PERWAPI.Field field = emitter.EmitField("Fan.Sys.Sys", typeName + "Type", "Fan.Sys.Type"); //code.FieldInst(FieldOp.ldsfld, field); // TODO - store in static field (all that crap above this) code.ldstr(sig); Method method = emitter.findMethod("Fan.Sys.Type", "find", new string[] { "System.String" }, "Fan.Sys.Type"); code.MethInst(MethodOp.call, method); }
/* * synchronized Class emit() * { * if (cls == null) * cls = FPodEmit.emitAndLoad(fpod); * return cls; * } * * synchronized void precompiled(Class cls) * throws Exception * { * this.cls = cls; * FPodEmit.initFields(fpod, cls); * } */ internal Type findType(int qname) { if (qname == 0xFFFF || qname == -1) { return(null); } // lookup type with typeRef index FTypeRef reference = fpod.typeRef(qname); // if generic instance, then this type must be used in a method // signature, not type meta-data (b/c I can't subclass generic types), // so it's safe that my pod has been loaded and is now registered (in // case the generic type is parameterized via types in my pod) if (reference.isGenericInstance()) { return(TypeParser.load(reference.signature, true, this)); } // otherwise I need to handle if I am loading my own pod, because // I might not yet be added to the system namespace if I'm just // loading my own hollow types string podName = reference.podName; string typeName = reference.typeName; Pod pod = podName == m_name ? this : doFind(podName, true, null); Type type = pod.type(typeName, false); if (type != null) { if (reference.isNullable()) { type = type.toNullable(); } return(type); } // handle generic parameter types (for sys pod only) if (m_name == "sys") { type = Sys.genericParamType(typeName); if (type != null) { if (reference.isNullable()) { type = type.toNullable(); } return(type); } } // lost cause throw UnknownTypeErr.make(podName + "::" + typeName).val; }