public string GetMethodName(MethodDef metDef, out string unitName) { MethodX metX = GenContext.TypeMgr.ResolveMethodDef(metDef); string typeName = GenContext.GetTypeName(metX.DeclType); unitName = TransMap[typeName]; return(GenContext.GetMethodName(metX, MethodGenerator.PrefixMet)); }
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 static bool GenInternalMethod(MethodGenerator metGen, CodePrinter prt) { MethodX metX = metGen.CurrMethod; GeneratorContext genContext = metGen.GenContext; string typeName = metX.DeclType.GetNameKey(); string metName = metX.Def.Name; string metSigName = metX.GetNameKey(); if (typeName == "Object") { if (metName == "GetInternalTypeID") { prt.AppendLine("return (int32_t)arg_0->TypeID;"); return(true); } } else if (typeName == "String") { FieldX fldLen = metX.DeclType.Fields.FirstOrDefault( fld => fld.FieldType.ElementType == dnlib.DotNet.ElementType.I4); FieldX fldFirstChar = metX.DeclType.Fields.FirstOrDefault( fld => fld.FieldType.ElementType == dnlib.DotNet.ElementType.Char); if (metName == "get_Length") { prt.AppendFormatLine(@"return arg_0->{0};", genContext.GetFieldName(fldLen)); return(true); } else if (metName == "get_Chars") { prt.AppendFormatLine("IL2CPP_CHECK_RANGE(0, arg_0->{0}, arg_1);", genContext.GetFieldName(fldLen)); prt.AppendFormatLine("return ((uint16_t*)&arg_0->{0})[arg_1];", genContext.GetFieldName(fldFirstChar)); return(true); } else if (metName == "InternalMarvin32HashString") { prt.AppendFormatLine("return il2cpp_HashString(&arg_0->{0}, arg_0->{1});", genContext.GetFieldName(fldFirstChar), genContext.GetFieldName(fldLen)); return(true); } else if (metName == "FastAllocateString") { prt.AppendFormatLine( "cls_String* str = (cls_String*)IL2CPP_NEW(sizeof(cls_String) + sizeof(uint16_t) * arg_0, {0}, 1);", genContext.GetStringTypeID()); prt.AppendFormatLine("str->{0} = arg_0;", genContext.GetFieldName(fldLen)); prt.AppendLine("return str;"); return(true); } else if (metSigName == ".ctor|Void(Char*,Int32,Int32)|20") { prt.AppendFormatLine("arg_0->{0} = arg_3;", genContext.GetFieldName(fldLen)); prt.AppendFormatLine("IL2CPP_MEMCPY(&arg_0->{0}, arg_1 + arg_2, sizeof(uint16_t) * arg_3);", genContext.GetFieldName(fldFirstChar)); return(true); } } else if (typeName == "System.Array") { if (metName == "get_Rank") { prt.AppendLine("if (arg_0->Rank == 0)"); ++prt.Indents; prt.AppendLine("return 1;"); --prt.Indents; prt.AppendLine("return arg_0->Rank;"); return(true); } else if (metName == "get_Length") { prt.AppendLine("return il2cpp_Array__GetLength(arg_0);"); return(true); } else if (metName == "get_LongLength") { prt.AppendLine("return il2cpp_Array__GetLongLength(arg_0);"); return(true); } else if (metName == "GetLength") { prt.AppendLine("return il2cpp_Array__GetLength(arg_0, arg_1);"); return(true); } else if (metName == "GetLowerBound") { prt.AppendLine("return il2cpp_Array__GetLowerBound(arg_0, arg_1);"); return(true); } else if (metName == "GetUpperBound") { prt.AppendLine("return il2cpp_Array__GetUpperBound(arg_0, arg_1);"); return(true); } else if (metName == "Copy") { prt.AppendLine("return il2cpp_Array__Copy(arg_0, arg_1, arg_2, arg_3, arg_4);"); return(true); } else if (metName == "Clear") { prt.AppendLine("return il2cpp_Array__Clear(arg_0, arg_1, arg_2);"); return(true); } } else if (typeName == "System.Runtime.CompilerServices.RuntimeHelpers") { if (metName == "IsReferenceOrContainsReferences") { var targetType = GetMethodGenType(metX, genContext); prt.AppendFormatLine("return {0};", genContext.IsRefOrContainsRef(targetType) ? "1" : "0"); return(true); } else if (metName == "CanCompareBits") { var targetType = GetMethodGenType(metX, genContext); bool canCompareBits = true; foreach (var fldX in targetType.Fields) { if (!Helper.IsBasicValueType(fldX.FieldType.ElementType)) { canCompareBits = false; break; } } prt.AppendFormatLine("return {0};", canCompareBits ? "1" : "0"); return(true); } else if (metName == "GetInternalTypeID") { var targetType = GetMethodGenType(metX, genContext); prt.AppendFormatLine("return {0};", genContext.GetTypeID(targetType)); return(true); } else if (metName == "FastCompareBits") { var argTySig = metX.ParamTypes[0].Next; metGen.RefValueTypeImpl(argTySig); if (Helper.IsBasicValueType(argTySig.ElementType) || genContext.GetTypeBySig(argTySig).IsEnumType) { prt.AppendLine("return *arg_0 == *arg_1 ? 1 : 0;"); } else { prt.AppendLine("return IL2CPP_MEMCMP(arg_0, arg_1, sizeof(*arg_0)) == 0 ? 1 : 0;"); } return(true); } else if (metName == "InitializeArray") { TypeX tyArg1 = genContext.GetTypeBySig(metX.ParamTypes[1]); Debug.Assert(tyArg1 != null); FieldX rtFldX = tyArg1.Fields.First(); prt.AppendFormatLine("il2cpp_Array__Init(arg_0, (il2cppFieldInfo*)arg_1.{0});", genContext.GetFieldName(rtFldX)); return(true); } else if (metName == "Equals") { prt.AppendLine("return arg_0 == arg_1 ? 1 : 0;"); return(true); } else if (metName == "GetHashCode") { prt.AppendLine("uintptr_t val = (uintptr_t)arg_0;"); prt.AppendLine("return (int32_t)((uint32_t)val ^ (uint32_t)(val >> 32) ^ (uint32_t)0x14AE055C);"); return(true); } } else if (typeName == "System.Runtime.CompilerServices.JitHelpers") { if (metName == "GetRawSzArrayData") { prt.AppendLine("IL2CPP_ASSERT(arg_0->Rank == 0);"); prt.AppendLine("return (uint8_t*)&arg_0[1];"); return(true); } } else if (typeName == "Internal.Runtime.CompilerServices.Unsafe") { if (metName == "As") { prt.AppendFormatLine("return ({0})arg_0;", genContext.GetTypeName(metX.ReturnType)); return(true); } } else if (typeName == "System.Buffer") { if (metName == "__Memmove") { prt.AppendLine("IL2CPP_MEMMOVE(arg_0, arg_1, arg_2);"); return(true); } } else if (typeName == "System.Math") { if (metName == "Abs") { prt.AppendLine("return il2cpp_Abs(arg_0);"); return(true); } else if (metName == "Sqrt") { prt.AppendLine("return il2cpp_Sqrt(arg_0);"); return(true); } else if (metName == "Sin") { prt.AppendLine("return il2cpp_Sin(arg_0);"); return(true); } else if (metName == "Cos") { prt.AppendLine("return il2cpp_Cos(arg_0);"); return(true); } else if (metName == "Tan") { prt.AppendLine("return il2cpp_Tan(arg_0);"); return(true); } else if (metName == "Pow") { prt.AppendLine("return il2cpp_Pow(arg_0, arg_1);"); return(true); } } else if (typeName == "System.Threading.Monitor") { if (metName == "ReliableEnter") { prt.AppendLine("il2cpp_SpinLock(arg_0->Flags[0]);"); prt.AppendLine("*arg_1 = 1;"); return(true); } else if (metName == "Exit") { prt.AppendLine("il2cpp_SpinUnlock(arg_0->Flags[0]);"); return(true); } } else if (typeName == "System.Threading.Interlocked") { if (metName == "CompareExchange") { prt.AppendLine("return il2cpp_CompareExchange(arg_0, arg_1, arg_2);"); return(true); } } else if (typeName == "System.GC") { if (metName == "_Collect") { prt.AppendLine("il2cpp_GC_Collect();"); return(true); } } return(false); }
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); }