예제 #1
0
        private void GenIsinstCode(TypeX currType, out string codeDecl, out string codeImpl)
        {
            List <TypeX> sortedTypes = new List <TypeX>();

            if (currType.IsInstanced)
            {
                sortedTypes.Add(currType);
            }
            foreach (var tyX in currType.DerivedTypes)
            {
                if (tyX.IsInstanced)
                {
                    sortedTypes.Add(tyX);
                }
            }
            sortedTypes.Sort((x, y) => x.GetCppTypeID().CompareTo(y.GetCppTypeID()));

            CodePrinter prt = new CodePrinter();

            prt.AppendFormat("bool isinst_{0}(uint32_t typeID)",
                             currType.GetCppName());

            codeDecl = prt + ";\n";

            prt.AppendLine("\n{");
            ++prt.Indents;

            prt.AppendLine("switch (typeID)\n{");
            ++prt.Indents;

            foreach (var tyX in sortedTypes)
            {
                prt.AppendFormatLine("// {0}\ncase {1}:",
                                     tyX.PrettyName(),
                                     tyX.GetCppTypeID());
            }

            ++prt.Indents;
            prt.AppendLine("return true;");
            prt.Indents -= 2;

            prt.AppendLine("}");

            prt.AppendLine("return false;");

            --prt.Indents;
            prt.AppendLine("}");

            codeImpl = prt.ToString();
        }
예제 #2
0
        private void GenerateIsType(CodePrinter prtDecl, CodePrinter prtImpl)
        {
            if (CurrType.IsValueType)
            {
                return;
            }

            CodePrinter prt = new CodePrinter();

            prt.AppendFormat("uint8_t istype_{0}(uint32_t typeID)",
                             GenContext.GetTypeName(CurrType));

            string strDecl = prt.ToString() + ";\n";

            prt.AppendLine("\n{");
            ++prt.Indents;

            var derivedRange = new List <TypeX>(CurrType.DerivedTypes);

            derivedRange.Add(CurrType);

            List <TypeX> derTypes = new List <TypeX>();

            foreach (var derTyX in derivedRange)
            {
                // 跳过不分配在堆上的类型
                if (!derTyX.IsInstantiated || derTyX.IsValueType || derTyX.Def.IsInterface)
                {
                    continue;
                }
                derTypes.Add(derTyX);
            }

            if (derTypes.Count > 0)
            {
                prt.AppendLine("switch (typeID)\n{");
                ++prt.Indents;

                derTypes.Sort((lhs, rhs) =>
                              GenContext.GetTypeID(lhs).CompareTo(GenContext.GetTypeID(rhs)));

                foreach (var derTyX in derTypes)
                {
                    prt.AppendFormatLine("// {0}",
                                         derTyX.GetNameKey());
                    prt.AppendFormatLine("case {0}:",
                                         GenContext.GetTypeID(derTyX));
                }

                ++prt.Indents;
                prt.AppendLine("return 1;");
                --prt.Indents;

                --prt.Indents;
                prt.AppendLine("}");
            }

            prt.AppendLine("return 0;");

            --prt.Indents;
            prt.AppendLine("}");

            prtDecl.Append(strDecl);
            prtImpl.Append(prt.ToString());
        }
예제 #3
0
        private TypeCppCode GenDeclCode(TypeX currType)
        {
            CodePrinter prt = new CodePrinter();

            // 构造类型注释
            prt.AppendFormatLine("// {0}",
                                 currType.PrettyName());

            // 构造类型结构体代码
            string typeName;
            string baseTypeName = null;

            if (currType.BaseType != null &&
                !currType.Def.IsValueType)
            {
                baseTypeName = currType.BaseType.GetCppName();
                typeName     = currType.GetCppName();
                prt.AppendFormatLine("struct {0} : {1}\n{{",
                                     typeName,
                                     baseTypeName);
            }
            else if (currType.Def.ToTypeSig().IsObjectSig())
            {
                typeName = currType.GetCppName();
                prt.AppendFormatLine("struct {0} : il2cppObject\n{{",
                                     typeName);
            }
            else
            {
                Debug.Assert(
                    currType.Def.IsValueType ||
                    currType.Def.IsInterface);

                typeName = currType.GetCppName();
                prt.AppendFormatLine("struct {0}\n{{",
                                     typeName);
            }

            // 添加代码映射
            TypeCppCode cppCode = new TypeCppCode(typeName);

            CodeMap.Add(typeName, cppCode);

            // 添加基类型依赖
            if (baseTypeName != null)
            {
                cppCode.DeclDependNames.Add(baseTypeName);
            }

            ++prt.Indents;

            // 构造结构体成员
            List <FieldX> staticFields = new List <FieldX>();

            foreach (var fldX in currType.Fields)
            {
                if (fldX.Def.IsStatic)
                {
                    staticFields.Add(fldX);
                    continue;
                }

                string fieldTypeName = fldX.FieldType.GetCppName(TypeMgr);
                prt.AppendFormatLine("// {0}\n{1} {2};",
                                     fldX.PrettyName(),
                                     fieldTypeName,
                                     fldX.GetCppName());

                // 添加字段类型依赖
                if (fldX.FieldType.IsValueType)
                {
                    cppCode.DeclDependNames.Add(fieldTypeName);
                }
            }

            --prt.Indents;
            prt.AppendLine("};");

            // 构造装箱类型
            if (currType.Def.IsValueType)
            {
                prt.AppendFormatLine("struct box_{0} : il2cppObject\n{{",
                                     typeName);
                ++prt.Indents;

                prt.AppendFormatLine("{0} value;",
                                     currType.ToTypeSig().GetCppName(TypeMgr));

                --prt.Indents;
                prt.AppendLine("};");
            }

            // 构造静态字段全局变量
            StringBuilder sbImpl = new StringBuilder();

            foreach (var sfldX in staticFields)
            {
                string sfldTypeName   = sfldX.FieldType.GetCppName(TypeMgr);
                string sfldCppName    = sfldX.GetCppName();
                string sfldPrettyName = sfldX.PrettyName(true);
                string sfldDef        = string.Format("{0} {1};\n",
                                                      sfldTypeName,
                                                      sfldCppName);

                prt.AppendFormat("// {0}\nextern {1}",
                                 sfldPrettyName,
                                 sfldDef);

                sbImpl.AppendFormat("// {0}\n{1}",
                                    sfldPrettyName,
                                    sfldDef);

                StaticInitDecl.Append("extern " + sfldDef);

                StaticInitBody.AppendFormat("{0} = {1};\n",
                                            sfldCppName,
                                            sfldX.FieldType.GetInitValue(TypeMgr));

                // 添加字段类型依赖
                if (sfldX.FieldType.IsValueType)
                {
                    cppCode.DeclDependNames.Add(sfldTypeName);
                    cppCode.ImplDependNames.Add(sfldTypeName);
                }
            }

            // 静态构造函数防止多次调用的标记
            if (currType.CctorMethod != null)
            {
                string onceName = string.Format("onceflag_{0}",
                                                typeName);
                string onceDef = string.Format("int8_t {0};\n",
                                               onceName);

                string locktidName = string.Format("locktid_{0}",
                                                   typeName);
                string locktidDef = string.Format("uintptr_t {0};\n",
                                                  locktidName);

                prt.Append("extern " + onceDef);
                prt.Append("extern " + locktidDef);

                sbImpl.Append(onceDef);
                sbImpl.Append(locktidDef);

                StaticInitDecl.Append("extern " + onceDef);
                StaticInitDecl.Append("extern " + locktidDef);

                StaticInitBody.AppendFormat("{0} = 0;\n",
                                            onceName);
                StaticInitBody.AppendFormat("{0} = 0;\n",
                                            locktidName);
            }

            cppCode.DeclCode.Append(prt);
            cppCode.ImplCode.Append(sbImpl);

            return(cppCode);
        }
예제 #4
0
        private void GenIsTypeFunc(CodePrinter prtDecl, CodePrinter prtImpl, bool currIsObject)
        {
            if (CurrType.IsValueType || !CurrType.NeedGenIsType)
            {
                return;
            }

            CodePrinter prt = new CodePrinter();

            prt.AppendFormat("uint8_t {0}(uint32_t typeID)",
                             GenContext.GetIsTypeFuncName(CurrType));

            string strDecl = prt.ToString() + ";\n";

            prt.AppendLine("\n{");
            ++prt.Indents;

            var derivedRange = new List <TypeX>(CurrType.DerivedTypes);

            derivedRange.Add(CurrType);

            var derivedEnumTypes = CurrType.UnBoxedType?.DerivedEnumTypes;

            if (derivedEnumTypes != null)
            {
                derivedRange.AddRange(derivedEnumTypes);
            }

            List <TypeX> derTypes = new List <TypeX>();

            foreach (var derTyX in derivedRange)
            {
                // 跳过不分配在堆上的类型
                if (!derTyX.IsInstantiated || derTyX.Def.IsInterface)
                {
                    continue;
                }
                // 如果当前类型是 object, 则跳过值类型
                if (currIsObject && derTyX.IsValueType)
                {
                    continue;
                }
                derTypes.Add(derTyX);
            }

            if (derTypes.Count > 0)
            {
                prt.AppendLine("switch (typeID)\n{");
                ++prt.Indents;

                derTypes.Sort((lhs, rhs) =>
                              GenContext.GetTypeID(lhs).CompareTo(GenContext.GetTypeID(rhs)));

                foreach (var derTyX in derTypes)
                {
                    prt.AppendFormatLine("// {0}",
                                         Helper.EscapeString(derTyX.GetNameKey()));
                    prt.AppendFormatLine("case {0}:",
                                         GenContext.GetTypeID(derTyX));
                }

                ++prt.Indents;
                prt.AppendLine("return 1;");
                --prt.Indents;

                --prt.Indents;
                prt.AppendLine("}");
            }

            prt.AppendLine("return 0;");

            --prt.Indents;
            prt.AppendLine("}");

            prtDecl.Append(strDecl);
            prtImpl.Append(prt.ToString());
        }