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; } }
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); }
public void Append(CompileUnit unit) { DeclCode += unit.DeclCode; DeclDepends.UnionWith(unit.DeclDepends); ImplCode += unit.ImplCode; ImplDepends.UnionWith(unit.ImplDepends); }
private CompileUnit NewUnit() { var unit = new CompileUnit(); unit.Name = "il2cppUnit_" + ++UnitCounter; UnitMap.Add(unit.Name, unit); return(unit); }
private bool IsUnitFull(CompileUnit unit) { #if true return(!unit.IsEmpty()); #else return(unit.DeclCode.Length > 30000 || unit.ImplCode.Length > 100000); #endif }
private bool IsUnitFull(CompileUnit unit) { // 生成一个 .cpp 文件比什么 LTO 都好使 #if false return(!unit.IsEmpty()); #else return(unit.DeclCode.Length > 100000 || unit.ImplCode.Length > 1000000); #endif }
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)); } }
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); }
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); }
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); }
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); }
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); }
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); }
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); }