Ejemplo n.º 1
0
        public void Generate(Dictionary <string, CompileUnit> unitMap, uint strTypeID)
        {
            foreach (var unit in unitMap.Values)
            {
                foreach (string strDep in unit.StringDepends)
                {
                    unit.ImplDepends.Add(StringToUnitName(strDep));
                }
            }

            Dictionary <int, List <string> > unitStrMap = new Dictionary <int, List <string> >();

            foreach (var kv in StringMap)
            {
                int unitIdx = kv.Value.UnitIndex;
                if (!unitStrMap.TryGetValue(unitIdx, out var strList))
                {
                    strList = new List <string>();
                    unitStrMap.Add(unitIdx, strList);
                }
                strList.Add(kv.Key);
            }

            foreach (var kv in unitStrMap)
            {
                var unit = new CompileUnit();

                unit.Name     = GetUnitName(kv.Key);
                unit.DeclCode = GenStringCode(kv.Value, strTypeID);

                unitMap[unit.Name] = unit;
            }
        }
Ejemplo n.º 2
0
        private ulong GetDependOrder(CompileUnit unit, HashSet <string> stackUnitNames = null)
        {
            ulong depOrder = unit.DependOrder;

            if (depOrder != 0)
            {
                return(depOrder);
            }

            string unitName = unit.Name;

            if (stackUnitNames != null && stackUnitNames.Contains(unitName))
            {
                return(0);
            }
            if (stackUnitNames == null)
            {
                stackUnitNames = new HashSet <string>();
            }
            stackUnitNames.Add(unitName);

            unit.Optimize(UnitMap);
            foreach (string dep in unit.DeclDepends)
            {
                var depUnit = GetUnitFromMap(dep);
                if (depUnit != null)
                {
                    depOrder += GetDependOrder(depUnit, stackUnitNames);
                }
            }

            ++depOrder;
            unit.DependOrder = depOrder;
            return(depOrder);
        }
Ejemplo n.º 3
0
 public void Append(CompileUnit unit)
 {
     DeclCode += unit.DeclCode;
     DeclDepends.UnionWith(unit.DeclDepends);
     ImplCode += unit.ImplCode;
     ImplDepends.UnionWith(unit.ImplDepends);
 }
Ejemplo n.º 4
0
        private CompileUnit NewUnit()
        {
            var unit = new CompileUnit();

            unit.Name = "il2cppUnit_" + ++UnitCounter;
            UnitMap.Add(unit.Name, unit);
            return(unit);
        }
Ejemplo n.º 5
0
        private bool IsUnitFull(CompileUnit unit)
        {
#if true
            return(!unit.IsEmpty());
#else
            return(unit.DeclCode.Length > 30000 ||
                   unit.ImplCode.Length > 100000);
#endif
        }
Ejemplo n.º 6
0
        private bool IsUnitFull(CompileUnit unit)
        {
            // 生成一个 .cpp 文件比什么 LTO 都好使
#if false
            return(!unit.IsEmpty());
#else
            return(unit.DeclCode.Length > 100000 ||
                   unit.ImplCode.Length > 1000000);
#endif
        }
Ejemplo n.º 7
0
        private void RefValueTypeDecl(CompileUnit unit, TypeSig tySig)
        {
            if (!tySig.IsValueType)
            {
                return;
            }

            TypeX tyX = GenContext.GetTypeBySig(tySig);

            if (tyX != null)
            {
                unit.DeclDepends.Add(GenContext.GetTypeName(tyX));
            }
        }
Ejemplo n.º 8
0
        private CompileUnit GenInitUnit(Dictionary <string, string> transMap)
        {
            CompileUnit unit = new CompileUnit();

            unit.Name = "il2cppInit";

            CodePrinter prtGC      = new CodePrinter();
            CodePrinter prtInit    = new CodePrinter();
            bool        addedRoots = false;

            foreach (var kv in InitFldsMap)
            {
                unit.ImplDepends.Add(transMap[kv.Key]);

                foreach (var item in kv.Value)
                {
                    if (item.Item2)
                    {
                        prtGC.AppendFormatLine("IL2CPP_ADD_ROOT({0}),", item.Item1);
                        addedRoots = true;
                    }
                    prtInit.AppendFormatLine("{0} = {{}};", item.Item1);
                }
            }

            CodePrinter prtFunc = new CodePrinter();

            prtFunc.AppendLine("void il2cpp_InitVariables()\n{");
            ++prtFunc.Indents;
            if (addedRoots)
            {
                prtFunc.AppendLine("il2cppRootItem roots[] =\n{");
                ++prtFunc.Indents;
                prtFunc.Append(prtGC.ToString());
                --prtFunc.Indents;
                prtFunc.AppendLine("};");
                prtFunc.AppendLine("il2cpp_CommitRoots(roots, sizeof(roots) / sizeof(roots[0]));");
            }
            prtFunc.Append(prtInit.ToString());
            --prtFunc.Indents;
            prtFunc.AppendLine("}");

            unit.ImplCode = prtFunc.ToString();

            return(unit);
        }
Ejemplo n.º 9
0
        private uint GetDependOrder(CompileUnit unit)
        {
            uint depOrder = unit.DependOrder;

            if (depOrder != 0)
            {
                return(depOrder);
            }

            unit.Optimize(UnitMap);

            foreach (string dep in unit.DeclDepends)
            {
                depOrder += GetDependOrder(UnitMap[dep]);
            }

            ++depOrder;
            unit.DependOrder = depOrder;
            return(depOrder);
        }
Ejemplo n.º 10
0
        public Dictionary <string, string> Merge()
        {
            // 排序编译单元
            var sortedUnits = UnitMap.Values.ToList();

            sortedUnits.Sort((lhs, rhs) => GetDependOrder(lhs).CompareTo(GetDependOrder(rhs)));

            // 合并编译单元
            UnitMap.Clear();
            var transMap = new Dictionary <string, string>();

            // 收集桥接代码的所有依赖项
            var bridgeUnitNames = new HashSet <string>();
            var bridgeUnits     = new List <CompileUnit>();
            var remainUnits     = new List <CompileUnit>();

            for (; ;)
            {
                bool changed = false;
                foreach (var unit in sortedUnits)
                {
                    string unitName = unit.Name;
                    if (BridgeTypes.Contains(unitName) ||
                        bridgeUnitNames.Contains(unitName))
                    {
                        bridgeUnits.Add(unit);
                        bridgeUnitNames.Add(unitName);
                        bridgeUnitNames.UnionWith(unit.DeclDepends);
                        changed = true;
                    }
                    else
                    {
                        remainUnits.Add(unit);
                    }
                }

                if (changed)
                {
                    sortedUnits = remainUnits;
                    remainUnits = new List <CompileUnit>();
                }
                else
                {
                    break;
                }
            }
            bridgeUnits.Sort((lhs, rhs) => GetDependOrder(lhs).CompareTo(GetDependOrder(rhs)));

            // 生成桥接单元
            CompileUnit bridgeUnit = new CompileUnit();

            bridgeUnit.Name = "il2cppBridge";
            UnitMap.Add(bridgeUnit.Name, bridgeUnit);

            foreach (var unit in bridgeUnits)
            {
                bridgeUnit.DeclCode += "#define IL2CPP_BRIDGE_HAS_" + unit.Name + '\n';
                bridgeUnit.Append(unit);
                transMap[unit.Name] = bridgeUnit.Name;
            }

            // 划分其他编译单元
            CompileUnit currUnit = NewUnit();

            foreach (var unit in sortedUnits)
            {
                Debug.Assert(!bridgeUnit.DeclDepends.Contains(unit.Name));
                currUnit.Append(unit);
                transMap[unit.Name] = currUnit.Name;
                if (IsUnitFull(currUnit))
                {
                    currUnit = NewUnit();
                }
            }

            if (currUnit.IsEmpty())
            {
                UnitMap.Remove(currUnit.Name);
            }

            foreach (var unit in UnitMap.Values)
            {
                var declDeps = new HashSet <string>();
                foreach (string dep in unit.DeclDepends)
                {
                    declDeps.Add(transMap[dep]);
                }
                unit.DeclDepends = declDeps;

                var implDeps = new HashSet <string>();
                foreach (string dep in unit.ImplDepends)
                {
                    implDeps.Add(transMap[dep]);
                }
                unit.ImplDepends = implDeps;

                unit.Optimize(UnitMap);
            }

            return(transMap);
        }
Ejemplo n.º 11
0
        public Dictionary <string, string> Merge()
        {
            // 排序编译单元
            var sortedUnits = UnitMap.Values.ToList();

            sortedUnits.Sort((lhs, rhs) => GetDependOrder(lhs).CompareTo(GetDependOrder(rhs)));

            // 合并编译单元
            UnitMap.Clear();
            var transMap = new Dictionary <string, string>();

            CompileUnit bridgeUnit = new CompileUnit();

            bridgeUnit.Name = "il2cppBridge";
            UnitMap.Add(bridgeUnit.Name, bridgeUnit);

            CompileUnit currUnit = NewUnit();

            foreach (var unit in sortedUnits)
            {
                if (BridgeTypes.Contains(unit.Name))
                {
                    bridgeUnit.Append(unit);
                    transMap[unit.Name] = bridgeUnit.Name;
                }
                else
                {
                    currUnit.Append(unit);
                    transMap[unit.Name] = currUnit.Name;
                    if (IsUnitFull(currUnit))
                    {
                        currUnit = NewUnit();
                    }
                }
            }

            if (currUnit.IsEmpty())
            {
                UnitMap.Remove(currUnit.Name);
            }

            foreach (var unit in UnitMap.Values)
            {
                var declDeps = new HashSet <string>();
                foreach (string dep in unit.DeclDepends)
                {
                    declDeps.Add(transMap[dep]);
                }
                unit.DeclDepends = declDeps;

                var implDeps = new HashSet <string>();
                foreach (string dep in unit.ImplDepends)
                {
                    implDeps.Add(transMap[dep]);
                }
                unit.ImplDepends = implDeps;

                unit.Optimize(UnitMap);
            }

            return(transMap);
        }
Ejemplo n.º 12
0
        public CompileUnit Generate()
        {
            CompileUnit unit = new CompileUnit();

            unit.Name = GenContext.GetTypeName(CurrType);

            // 重排字段
            var fields = LayoutFields(out var sfields);

            // 生成类结构
            CodePrinter prtDecl = new CodePrinter();

            if (!CurrType.IsEnumType)
            {
                prtDecl.AppendFormatLine("// {0}", CurrType.GetNameKey());
                var baseType = CurrType.BaseType;

                // 值类型不继承任何基类
                if (CurrType.IsValueType)
                {
                    baseType = null;
                }

                // 接口类型继承 object
                if (baseType == null && CurrType.Def.IsInterface)
                {
                    baseType = GenContext.TypeMgr.GetTypeByName("Object");
                }

                if (baseType != null)
                {
                    string strBaseTypeName = GenContext.GetTypeName(baseType);
                    unit.DeclDepends.Add(strBaseTypeName);

                    prtDecl.AppendFormatLine("struct {0} : {1}",
                                             GenContext.GetTypeName(CurrType),
                                             strBaseTypeName);
                }
                else
                {
                    prtDecl.AppendFormatLine("struct {0}",
                                             GenContext.GetTypeName(CurrType));
                }

                prtDecl.AppendLine("{");
                ++prtDecl.Indents;

                // 生成对象内置字段
                if (CurrType.IsArrayType)
                {
                    var arrayInfo = CurrType.ArrayInfo;
                    if (arrayInfo.IsSZArray)
                    {
                        prtDecl.AppendLine("int32_t Length;");
                    }
                    else
                    {
                        uint rank = arrayInfo.Rank;
                        for (int i = 0; i < rank; ++i)
                        {
                            prtDecl.AppendFormatLine("int32_t LowerBound{0};\nint32_t Size{0};", i);
                        }
                    }
                }
                else
                {
                    string nameKey = CurrType.GetNameKey();
                    if (nameKey == "Object")
                    {
                        prtDecl.AppendLine("uint32_t TypeID;");
                    }
                    else if (nameKey == "System.Array")
                    {
                        prtDecl.AppendLine("int32_t Rank;");
                    }
                }

                // 生成字段
                foreach (var fldX in fields)
                {
                    RefValueTypeDecl(unit, fldX.FieldType);

                    prtDecl.AppendLine("// " + fldX.GetReplacedNameKey());
                    prtDecl.AppendFormatLine("{0} {1};",
                                             GenContext.GetTypeName(fldX.FieldType),
                                             GenContext.GetFieldName(fldX));
                }

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

            CodePrinter prtImpl = new CodePrinter();

            // 生成类型判断函数
            GenerateIsType(prtDecl, prtImpl);

            // 生成静态字段
            foreach (var sfldX in sfields)
            {
                RefValueTypeDecl(unit, sfldX.FieldType);

                string fldDecl = string.Format("{0} {1};",
                                               GenContext.GetTypeName(sfldX.FieldType),
                                               GenContext.GetFieldName(sfldX));

                prtDecl.AppendFormatLine("// {0} -> {1}", sfldX.DeclType.GetNameKey(), sfldX.GetReplacedNameKey());
                prtDecl.AppendLine("extern " + fldDecl);
                prtImpl.AppendLine(fldDecl);
            }

            // 生成方法
            foreach (MethodX metX in CurrType.Methods)
            {
                var metGen = new MethodGenerator(GenContext, metX);
                metGen.Generate();

                prtDecl.AppendFormatLine("// {0} -> {1}", metX.DeclType.GetNameKey(), metX.GetReplacedNameKey());
                prtDecl.Append(metGen.DeclCode);
                unit.DeclDepends.UnionWith(metGen.DeclDepends);

                prtImpl.Append(metGen.ImplCode);
                unit.ImplDepends.UnionWith(metGen.ImplDepends);

                unit.StringDepends.UnionWith(metGen.StringDepends);
            }

            unit.DeclCode = prtDecl.ToString();
            unit.ImplCode = prtImpl.ToString();

            return(unit);
        }
Ejemplo n.º 13
0
        public CompileUnit Generate()
        {
            CompileUnit unit = new CompileUnit();

            unit.Name = GenContext.GetTypeName(CurrType, false);

            // 重排字段
            var fields = LayoutFields(out var sfields);

            string nameKey      = CurrType.GetNameKey();
            bool   currIsObject = nameKey == "Object";

            // 生成类结构
            CodePrinter prtDecl = new CodePrinter();

            if (!CurrType.IsEnumType)
            {
                prtDecl.AppendFormatLine("// {0}", nameKey);
                var baseType = CurrType.BaseType;

                // 值类型不继承任何基类
                if (CurrType.IsValueType)
                {
                    baseType = null;
                }

                // 接口类型继承 object
                if (baseType == null && CurrType.Def.IsInterface)
                {
                    baseType = GenContext.TypeMgr.GetTypeByName("Object");
                }

                if (baseType != null)
                {
                    string strBaseTypeName = GenContext.GetTypeName(baseType);
                    unit.DeclDepends.Add(strBaseTypeName);

                    prtDecl.AppendFormatLine("struct {0} : {1}",
                                             GenContext.GetTypeName(CurrType),
                                             strBaseTypeName);
                }
                else
                {
                    prtDecl.AppendFormatLine("struct {0}",
                                             GenContext.GetTypeName(CurrType));
                }

                prtDecl.AppendLine("{");
                ++prtDecl.Indents;

                // 生成对象内置字段
                if (CurrType.IsArrayType)
                {
                    var arrayInfo = CurrType.ArrayInfo;
                    if (!arrayInfo.IsSZArray)
                    {
                        uint rank = arrayInfo.Rank;
                        for (int i = 0; i < rank; ++i)
                        {
                            prtDecl.AppendFormatLine("int32_t LowerBound{0};\nuint32_t Size{0};", i);
                        }
                    }
                }
                else
                {
                    if (currIsObject)
                    {
                        prtDecl.AppendLine("uint32_t TypeID;");
                        prtDecl.AppendLine("uint8_t Flags[4];");
                    }
                    else if (nameKey == "System.Array")
                    {
                        prtDecl.AppendLine("uintptr_t Length;");
                        prtDecl.AppendLine("uint32_t Rank;");
                        prtDecl.AppendLine("uint32_t ElemSize;");
                    }
                }

                bool isExplicitLayout = CurrType.Def.IsExplicitLayout;
                uint classSize        = CurrType.Def.ClassSize;
                bool hasStructSize    = CurrType.Def.HasClassLayout && classSize != 0;
                if (isExplicitLayout || hasStructSize)
                {
                    prtDecl.AppendLine("union\n{");
                    ++prtDecl.Indents;

                    if (!isExplicitLayout && fields.Count != 0)
                    {
                        prtDecl.AppendLine("struct\n{");
                        ++prtDecl.Indents;
                    }
                }

                int fldCounter = 0;

                // 生成字段
                foreach (var fldX in fields)
                {
                    RefValueTypeDecl(unit, fldX.FieldType);

                    bool isFieldExLayout = isExplicitLayout && fldX.Def.FieldOffset != 0;
                    if (isFieldExLayout)
                    {
                        prtDecl.AppendLine("struct\n{");
                        ++prtDecl.Indents;
                        prtDecl.AppendFormatLine("uint8_t padding_{0}[{1}];",
                                                 fldCounter,
                                                 fldX.Def.FieldOffset);
                    }

                    prtDecl.AppendLine("// " + fldX.GetReplacedNameKey());
                    prtDecl.AppendFormatLine("{0} {1};",
                                             GenContext.GetTypeName(fldX.FieldType),
                                             GenContext.GetFieldName(fldX));

                    if (isFieldExLayout)
                    {
                        --prtDecl.Indents;
                        prtDecl.AppendLine("};");
                    }

                    ++fldCounter;
                }

                if (isExplicitLayout || hasStructSize)
                {
                    if (!isExplicitLayout && fields.Count != 0)
                    {
                        --prtDecl.Indents;
                        prtDecl.AppendLine("};");
                    }
                    if (hasStructSize)
                    {
                        prtDecl.AppendFormatLine("uint8_t padding_struct[{0}];",
                                                 classSize);
                    }

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

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

            CodePrinter prtImpl = new CodePrinter();

            // 生成类型判断函数
            GenerateIsType(prtDecl, prtImpl, currIsObject);

            // 生成静态字段
            foreach (var sfldX in sfields)
            {
                RefValueTypeDecl(unit, sfldX.FieldType);

                string fldDecl = string.Format("{0} {1};",
                                               GenContext.GetTypeName(sfldX.FieldType),
                                               GenContext.GetFieldName(sfldX));

                prtDecl.AppendFormatLine("// {0} -> {1}", sfldX.DeclType.GetNameKey(), sfldX.GetReplacedNameKey());
                prtDecl.AppendLine("extern " + fldDecl);
                prtImpl.AppendLine(fldDecl);
            }

            // 生成方法
            foreach (MethodX metX in CurrType.Methods)
            {
                var metGen = new MethodGenerator(GenContext, metX);
                metGen.Generate();

                AppendRuntimeFlags(metX, prtDecl);

                prtDecl.AppendFormatLine("// {0}{1}{2} -> {3}",
                                         !metX.Def.HasBody && !metX.Def.IsAbstract ? "extern " : null,
                                         metX.Def.IsInternalCall ? "internalcall " : null,
                                         metX.DeclType.GetNameKey(),
                                         metX.GetReplacedNameKey());

                prtDecl.Append(metGen.DeclCode);
                unit.DeclDepends.UnionWith(metGen.DeclDepends);

                prtImpl.Append(metGen.ImplCode);
                unit.ImplDepends.UnionWith(metGen.ImplDepends);

                unit.StringDepends.UnionWith(metGen.StringDepends);
            }

            unit.DeclCode = prtDecl.ToString();
            unit.ImplCode = prtImpl.ToString();

            return(unit);
        }
Ejemplo n.º 14
0
        public CompileUnit Generate()
        {
            CompileUnit unit        = new CompileUnit();
            string      strTypeName = GenContext.GetTypeName(CurrType, false);

            unit.Name = strTypeName;

            // 重排字段
            var fields = LayoutFields(out var sfields);

            string nameKey      = CurrType.GetNameKey();
            bool   currIsObject = nameKey == "Object";

            // 生成类结构
            CodePrinter prtDecl = new CodePrinter();

            if (!CurrType.IsEnumType)
            {
                prtDecl.AppendFormatLine("// {0}", Helper.EscapeString(nameKey));

                ushort packSize = CurrType.Def.HasClassLayout ? CurrType.Def.PackingSize : (ushort)0;
                if (packSize > 2 && !Helper.IsPowerOfTwo(packSize))
                {
                    throw new TypeLoadException();
                }

                if (packSize != 0)
                {
                    prtDecl.AppendLine("#if defined(IL2CPP_MSVC_LIKE)");
                    prtDecl.AppendFormatLine("#pragma pack(push, {0})", packSize);
                    prtDecl.AppendLine("#endif");
                }

                var baseType = CurrType.BaseType;

                // 值类型不继承任何基类
                if (CurrType.IsValueType)
                {
                    baseType = null;
                }

                // 接口类型继承 object
                if (baseType == null && CurrType.Def.IsInterface)
                {
                    baseType = GenContext.GetTypeByName("Object");
                }

                if (baseType != null)
                {
                    string strBaseTypeName = GenContext.GetTypeName(baseType);
                    unit.DeclDepends.Add(strBaseTypeName);

                    prtDecl.AppendFormatLine("struct {0} : {1}",
                                             strTypeName,
                                             strBaseTypeName);
                }
                else
                {
                    prtDecl.AppendFormatLine("struct {0}",
                                             strTypeName);
                }

                prtDecl.AppendLine("{");
                ++prtDecl.Indents;

                // 生成对象内置字段
                if (CurrType.IsArrayType)
                {
                    var arrayInfo = CurrType.ArrayInfo;
                    if (!arrayInfo.IsSZArray)
                    {
                        uint rank = arrayInfo.Rank;
                        for (int i = 0; i < rank; ++i)
                        {
                            prtDecl.AppendFormatLine("int32_t LowerBound{0};\nuint32_t Size{0};", i);
                        }
                    }
                }
                else
                {
                    if (currIsObject)
                    {
                        prtDecl.AppendLine("uint32_t TypeID;");
                        prtDecl.AppendLine("uint8_t Flags[4];");
                    }
                    else if (nameKey == "System.Array")
                    {
                        prtDecl.AppendLine("uint32_t Length;");
                        prtDecl.AppendLine("uint32_t ElemSize : 24;");
                        prtDecl.AppendLine("uint32_t Rank : 8;");
                    }
                }

                bool isExplicitLayout = CurrType.Def.IsExplicitLayout;
                uint classSize        = CurrType.Def.ClassSize;
                bool hasStructSize    = CurrType.Def.HasClassLayout && classSize != 0;
                if (isExplicitLayout || hasStructSize)
                {
                    prtDecl.AppendLine("union\n{");
                    ++prtDecl.Indents;

                    if (!isExplicitLayout && fields.Count != 0)
                    {
                        prtDecl.AppendLine("struct\n{");
                        ++prtDecl.Indents;
                    }
                }

                int fldCounter = 0;

                // 生成字段
                foreach (var fldX in fields)
                {
                    RefValueTypeDecl(unit, fldX.FieldType);

                    bool isFieldExLayout = isExplicitLayout && fldX.Def.FieldOffset != 0;
                    if (isFieldExLayout)
                    {
                        prtDecl.AppendLine("struct\n{");
                        ++prtDecl.Indents;
                        prtDecl.AppendFormatLine("uint8_t padding_{0}[{1}];",
                                                 fldCounter,
                                                 fldX.Def.FieldOffset);
                    }

                    prtDecl.AppendLine("// " + fldX.GetReplacedNameKey());
                    prtDecl.AppendFormatLine("{0} {1};",
                                             GenContext.GetTypeName(fldX.FieldType),
                                             GenContext.GetFieldName(fldX));

                    if (isFieldExLayout)
                    {
                        --prtDecl.Indents;
                        prtDecl.AppendLine("};");
                    }

                    ++fldCounter;
                }

                if (isExplicitLayout || hasStructSize)
                {
                    if (!isExplicitLayout && fields.Count != 0)
                    {
                        --prtDecl.Indents;
                        prtDecl.AppendLine("};");
                    }
                    if (hasStructSize)
                    {
                        prtDecl.AppendFormatLine("uint8_t padding_struct[{0}];",
                                                 classSize);
                    }

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

                --prtDecl.Indents;

                if (packSize != 0)
                {
                    prtDecl.AppendFormatLine("}} IL2CPP_PACKED_TAIL({0});",
                                             packSize);
                }
                else
                {
                    prtDecl.AppendLine("};");
                }

                if (packSize != 0)
                {
                    prtDecl.AppendLine("#if defined(IL2CPP_MSVC_LIKE)");
                    prtDecl.AppendLine("#pragma pack(pop)");
                    prtDecl.AppendLine("#endif");
                }
            }

            CodePrinter prtImpl = new CodePrinter();

            // 生成静态字段
            foreach (var sfldX in sfields)
            {
                RefValueTypeDecl(unit, sfldX.FieldType);

                string sfldName = GenContext.GetFieldName(sfldX);
                string fldDecl  = string.Format("{0} {1};",
                                                GenContext.GetTypeName(sfldX.FieldType),
                                                sfldName);

                prtDecl.AppendFormatLine("// {0} -> {1}",
                                         Helper.EscapeString(sfldX.DeclType.GetNameKey()),
                                         Helper.EscapeString(sfldX.GetReplacedNameKey()));
                prtDecl.AppendLine("extern " + fldDecl);
                prtImpl.AppendLine(fldDecl);

                bool hasRef = GenContext.IsRefOrContainsRef(GenContext.GetTypeBySig(sfldX.FieldType));
                GenContext.AddStaticField(strTypeName, sfldName, hasRef);
            }

            // 生成类型判断函数
            GenIsTypeFunc(prtDecl, prtImpl, currIsObject);

            // 生成方法
            foreach (MethodX metX in CurrType.Methods)
            {
                var metGen = new MethodGenerator(GenContext, metX);
                metGen.Generate();

                AppendRuntimeFlags(metX, prtDecl);

                prtDecl.AppendFormatLine("// {0}{1}{2} -> {3}",
                                         Helper.IsExtern(metX.Def) ? "extern " : null,
                                         metX.Def.IsInternalCall ? "internalcall " : null,
                                         Helper.EscapeString(metX.DeclType.GetNameKey()),
                                         Helper.EscapeString(metX.GetReplacedNameKey()));

                prtDecl.Append(metGen.DeclCode);
                unit.DeclDepends.UnionWith(metGen.DeclDepends);

                prtImpl.Append(metGen.ImplCode);
                unit.ImplDepends.UnionWith(metGen.ImplDepends);

                unit.StringDepends.UnionWith(metGen.StringDepends);
            }

            GenerateMetadata(prtDecl, prtImpl);

            unit.DeclCode = prtDecl.ToString();
            unit.ImplCode = prtImpl.ToString();

            return(unit);
        }