Пример #1
0
        //////////////////////////////////////////////////////////////////////////
        // 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);
            }
        }
Пример #2
0
        //////////////////////////////////////////////////////////////////////////
        // 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);
            }
        }
Пример #3
0
        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);
        }
Пример #4
0
        /*
         * 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;
        }