Пример #1
0
        public string GetMethodName(MethodX metX, string prefix)
        {
            string strName = metX.GeneratedMethodName;

            if (strName == null)
            {
                int hashCode = Helper.CombineHash(
                    metX.GetNameKey().GetHashCode(),
                    metX.GetReplacedNameKey().GetHashCode(),
                    metX.DeclType.GetNameKey().GetHashCode());

                strName = NameHash(hashCode) + '_' +
                          GetNameWithGen(metX.DeclType.Def.Name, metX.DeclType.GenArgs) + "__" +
                          GetNameWithGen(metX.Def.Name, metX.GenArgs);

                metX.GeneratedMethodName = strName = GetNotUsedMethodName(EscapeName(strName));
            }
            return(prefix + strName);
        }
Пример #2
0
        // 导出方法表结构

        /*public void DumpMethodTables(StringBuilder sb)
         * {
         *      foreach (var kv in Context.TypeMgr.MethodTableMap)
         *      {
         *              sb.AppendFormat("[{0}]\n", kv.Key);
         *              bool flag = false;
         *              foreach (var kv2 in kv.Value.VSlotMap)
         *              {
         *                      string expSigName = kv2.Key;
         *                      var entries = kv2.Value.Entries;
         *                      VirtualImpl impl = kv2.Value.Impl;
         *
         *                      // 跳过无覆盖的方法
         *                      if (entries.Count == 1 &&
         *                              impl.IsValid() &&
         *                              entries.TryGetValue(impl.ImplTable, out var defSet) &&
         *                              defSet.Count == 1 &&
         *                              defSet.First() == impl.ImplMethod)
         *                      {
         *                              continue;
         *                      }
         *
         *                      sb.AppendFormat(" - {0}: {1}\n", expSigName, impl);
         *                      foreach (var kv3 in entries)
         *                      {
         *                              foreach (var mdef in kv3.Value)
         *                                      sb.AppendFormat("   - {0} -> {1}\n", kv3.Key, mdef);
         *                      }
         *                      sb.Append('\n');
         *                      flag = true;
         *              }
         *              if (!flag)
         *                      sb.Append('\n');
         *      }
         * }*/

        public void DumpTypes(StringBuilder sb)
        {
            foreach (TypeX tyX in Context.TypeMgr.Types)
            {
                sb.AppendFormat("[{0} {1}] {2}\n",
                                tyX.IsValueType ? "struct" : "class",
                                tyX.GetNameKey(),
                                TypeAttrToString(tyX.Def.Attributes));

                if (tyX.IsInstantiated)
                {
                    sb.Append(" - Instantiated\n");
                }

                if (tyX.BaseType != null)
                {
                    sb.AppendFormat(" - Base: {0}\n", tyX.BaseType);
                }
                if (tyX.Interfaces.IsCollectionValid())
                {
                    sb.Append(" - Interfaces:\n");
                    foreach (TypeX infTyX in tyX.Interfaces)
                    {
                        sb.AppendFormat("   - {0}\n", infTyX);
                    }
                }
                if (tyX.HasVariances)
                {
                    sb.Append(" - Variances: ");
                    foreach (var vt in tyX.Variances)
                    {
                        sb.AppendFormat("{0} ", vt);
                    }
                    sb.Append('\n');
                }
                if (tyX.HasVarianceBaseTypes)
                {
                    sb.Append(" - VarianceBaseTypes:\n");
                    foreach (TypeX vaTyX in tyX.VarianceBaseTypes)
                    {
                        sb.AppendFormat("   - {0}\n", vaTyX);
                    }
                }
                if (tyX.DerivedTypes.IsCollectionValid())
                {
                    sb.Append(" - DerivedTypes:\n");
                    foreach (TypeX derivedTyX in tyX.DerivedTypes)
                    {
                        sb.AppendFormat("   - {0}\n", derivedTyX);
                    }
                }

                if (tyX.Fields.IsCollectionValid())
                {
                    sb.Append(" - Fields:\n");
                    foreach (FieldX fldX in tyX.Fields)
                    {
                        sb.AppendFormat("   - {0}, {1}, {2}\n",
                                        fldX.GetNameKey() + '|' + ((uint)fldX.Def.Attributes).ToString("X"),
                                        fldX.GetReplacedNameKey(),
                                        FieldAttrToString(fldX.Def.Attributes));
                    }
                }

                if (tyX.Methods.IsCollectionValid())
                {
                    sb.Append(" - Methods:\n");
                    foreach (MethodX metX in tyX.Methods)
                    {
                        sb.AppendFormat("   - {0}, {1}{2}, {3}{4} {5}\n",
                                        metX.GetNameKey() + '|' + ((uint)metX.Def.Attributes).ToString("X"),
                                        metX.GetReplacedNameKey(),
                                        metX.IsProcessed ? "" : " = 0",
                                        MethodAttrToString(metX.Def.Attributes),
                                        metX.Def.ImplAttributes,
                                        metX.Def.SemanticsAttributes);

                        if (metX.HasOverrideImpls)
                        {
                            foreach (var kv in metX.OverrideImpls)
                            {
                                MethodX overMetX = kv.Key;
                                sb.AppendFormat("     - {0}, {1}\n",
                                                overMetX.DeclType.GetNameKey() + " -> " + overMetX.GetNameKey() + '|' + ((uint)overMetX.Def.Attributes).ToString("X"),
                                                overMetX.GetReplacedNameKey());
                            }
                        }
                    }
                }

                /*if (tyX.IsInstantiated &&
                 *      tyX.VTable != null)
                 * {
                 *      if (Helper.IsCollectionValid(tyX.VTable.Table))
                 *      {
                 *              sb.Append(" - VTable:\n");
                 *              foreach (var kv2 in tyX.VTable.Table)
                 *              {
                 *                      sb.AppendFormat("   - [{0}]\n", kv2.Key);
                 *                      foreach (var kv3 in kv2.Value)
                 *                      {
                 *                              if (kv3.Key == kv3.Value.Item2)
                 *                                      continue;
                 *
                 *                              sb.AppendFormat("     - {0}: {1} -> {2}\n",
                 *                                      kv3.Key,
                 *                                      kv3.Value.Item1,
                 *                                      kv3.Value.Item2);
                 *                      }
                 *              }
                 *      }
                 *
                 *      if (Helper.IsCollectionValid(tyX.VTable.MethodReplaceMap))
                 *      {
                 *              sb.Append(" - ReplaceMap:\n");
                 *              foreach (var kv2 in tyX.VTable.MethodReplaceMap)
                 *              {
                 *                      sb.AppendFormat("   - {0} => {1}\n", kv2.Key.FullName, kv2.Value.Item2.FullName);
                 *              }
                 *      }
                 *
                 *      if (Helper.IsCollectionValid(tyX.VTable.FallbackTable))
                 *      {
                 *              sb.Append(" - FallbackTable:\n");
                 *              foreach (var kv2 in tyX.VTable.FallbackTable)
                 *              {
                 *                      sb.AppendFormat("   - {0} => {1}\n", kv2.Key, kv2.Value.FullName);
                 *              }
                 *      }
                 * }*/

                sb.Append('\n');
            }
        }
Пример #3
0
        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);
        }