public void GenDefineCode( int splitLines, out Dictionary <string, int> strSplitMap, out Dictionary <int, StringBuilder> codeMap, out string strTypeDefs) { List <string> sortedStrs = GetSortedStrings(); strSplitMap = new Dictionary <string, int>(); codeMap = new Dictionary <int, StringBuilder>(); HashSet <int> lenSet = new HashSet <int>(); uint strTypeID = TypeGen.TypeMgr.GetTypeByName("System.String").GetCppTypeID(); int index = 0; int counter = 0; StringBuilder currSb = new StringBuilder(); codeMap.Add(index, currSb); foreach (var str in sortedStrs) { lenSet.Add(str.Length); strSplitMap.Add(str, index); currSb.Append(GenStringCode(str, strTypeID)); ++counter; if (counter >= splitLines) { counter = 0; ++index; currSb = new StringBuilder(); codeMap.Add(index, currSb); } } Reset(); var prt = new CodePrinter(); foreach (var len in lenSet) { prt.AppendFormatLine("struct il2cppString_{0}\n{{", len + 1); ++prt.Indents; prt.AppendLine("IL2CPP_OBJECT_BODY;"); prt.AppendFormatLine("int len;\nuint16_t str[{0}];", len + 1); --prt.Indents; prt.AppendLine("};"); } strTypeDefs = prt.ToString(); }
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(); }
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 string GenStringCode(List <string> strList, uint strTypeID) { CodePrinter prt = new CodePrinter(); foreach (string str in strList) { StringProp prop = StringMap[str]; string strAry = StringToArrayOrRaw(str, out bool isRaw); prt.AppendFormatLine("// {0}", EscapeString(str)); prt.AppendFormatLine("static const struct {{ cls_Object obj; int32_t len; {5} str[{0}]; }} {1} {{ {{{2}}}, {3}, {4} }};", str.Length + 1, GetConstName(prop.ConstIndex), strTypeID, str.Length, strAry, isRaw ? "char16_t" : "uint16_t"); } return(prt.ToString()); }
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); }
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()); }
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); }
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()); }
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); }