Esempio n. 1
0
        public string GetTypeName(TypeX tyX)
        {
            if (tyX.IsEnumType)
            {
                return(GetTypeName(tyX.EnumTypeSig));
            }

            string strName = tyX.GeneratedTypeName;

            if (strName == null)
            {
                strName = tyX.IsValueType ? "stru_" : "cls_";

                string nameKey = tyX.GetNameKey();
                if (!tyX.IsArrayType && tyX.Def.DefinitionAssembly.IsCorLib())
                {
                    strName += nameKey;
                }
                else
                {
                    strName += NameHash(nameKey.GetHashCode()) + '_' + GetNameWithGen(tyX.Def.Name, tyX.GenArgs);
                }

                tyX.GeneratedTypeName = strName = EscapeName(strName);
            }

            return(strName);
        }
Esempio n. 2
0
        public string GetTypeName(TypeX tyX, bool expandEnum = true)
        {
            if (tyX == null)
            {
                return("il2cppDummy");
            }
            if (expandEnum)
            {
                if (tyX.IsEnumType)
                {
                    return(GetTypeName(tyX.EnumTypeSig));
                }
            }

            string strName = tyX.GeneratedTypeName;

            if (strName == null)
            {
                strName = tyX.IsValueType ? "stru_" : "cls_";

                string nameKey = tyX.GetNameKey();
                if (!tyX.HasGenArgs && tyX.Def.DefinitionAssembly.IsCorLib())
                {
                    strName += nameKey;
                }
                else
                {
                    strName += NameHash(nameKey.GetHashCode()) + '_' + GetNameWithGen(tyX.Def.Name, tyX.GenArgs);
                }

                tyX.GeneratedTypeName = strName = GetNotUsedTypeName(EscapeName(strName));
            }

            return(strName);
        }
Esempio n. 3
0
        public GenerateResult Generate()
        {
            var unitMap = new Dictionary <string, CompileUnit>();

            // 生成类型代码
            var types = TypeMgr.Types;

            foreach (TypeX tyX in types)
            {
                CompileUnit unit = new TypeGenerator(this, tyX).Generate();
                unitMap.Add(unit.Name, unit);
            }

            // 合并代码单元
            var transMap = new CompileUnitMerger(unitMap).Merge();

            // 生成字符串常量单元
            TypeX strTyX = GetTypeByName("String");

            if (strTyX != null)
            {
                StrGen.Generate(unitMap, GetTypeID(strTyX));
            }

            return(new GenerateResult(this, unitMap.Values.ToList(), transMap));
        }
Esempio n. 4
0
 public FieldX(TypeX declType, FieldDef fldDef)
 {
     Debug.Assert(declType != null);
     Debug.Assert(fldDef.DeclaringType == declType.Def);
     DeclType = declType;
     Def      = fldDef;
 }
Esempio n. 5
0
        public TypeX GetTypeX()
        {
            TypeX tyX = TypeMgr.GetTypeByName(GetNameKey());

            Debug.Assert(tyX != null);
            return(tyX);
        }
Esempio n. 6
0
 public void AddDerivedEnumTypes(TypeX enumTyX)
 {
     if (DerivedEnumTypes == null)
     {
         DerivedEnumTypes = new HashSet <TypeX>();
     }
     DerivedEnumTypes.Add(enumTyX);
 }
Esempio n. 7
0
 private bool RefToTypeIsNoRef(TypeX tyX)
 {
     if (tyX.IsValueType)
     {
         return(IsNoRefType(tyX));
     }
     return(false);
 }
Esempio n. 8
0
        public static string PrettyName(this TypeX self)
        {
            StringBuilder sb = new StringBuilder();

            PrettyName(sb, self.Def.ToTypeSig(), true);
            PrettyGenArgs(sb, self.GenArgs);
            return(sb.ToString());
        }
Esempio n. 9
0
 public void SetType(TypeX tyX)
 {
     if (tyX.HasGenArgs)
     {
         OwnerType   = tyX.Def;
         TypeGenArgs = tyX.GenArgs;
     }
 }
Esempio n. 10
0
        private static TypeX GetMethodGenType(MethodX metX, GeneratorContext genContext, int genArg = 0)
        {
            Debug.Assert(metX.HasGenArgs && metX.GenArgs.Count > genArg);
            TypeX genType = genContext.GetTypeBySig(metX.GenArgs[genArg]);

            Debug.Assert(genType != null);
            return(genType);
        }
Esempio n. 11
0
        public MethodX(TypeX declType, MethodDef metDef)
        {
            Debug.Assert(declType != null);
            Debug.Assert(metDef.DeclaringType == declType.Def);
            DeclType = declType;
            Def      = metDef;

            Debug.Assert(HasThis && !metDef.IsStatic || !HasThis && metDef.IsStatic);
        }
Esempio n. 12
0
 public bool QueryCallReplace(
     TypeManager typeMgr,
     MethodDef entryDef,
     out TypeX implTyX,
     out MethodDef implDef)
 {
     ResolveVTable(typeMgr);
     return(VTable.QueryCallReplace(entryDef, out implTyX, out implDef));
 }
Esempio n. 13
0
 public void QueryCallVirt(
     TypeManager typeMgr,
     TypeX entryTyX,
     MethodDef entryDef,
     out TypeX implTyX,
     out MethodDef implDef)
 {
     ResolveVTable(typeMgr);
     VTable.QueryCallVirt(entryTyX, entryDef, out implTyX, out implDef);
 }
Esempio n. 14
0
        public uint GetTypeID(TypeX tyX)
        {
            if (tyX.GeneratedTypeID != 0)
            {
                return(tyX.GeneratedTypeID);
            }

            tyX.GeneratedTypeID = ++TypeIDCounter;
            return(tyX.GeneratedTypeID);
        }
Esempio n. 15
0
 public uint GetStringTypeID()
 {
     if (StringTypeID == 0)
     {
         TypeX strTyX = GetTypeByName("String");
         Debug.Assert(strTyX != null);
         StringTypeID = GetTypeID(strTyX);
     }
     Debug.Assert(StringTypeID != 0);
     return(StringTypeID);
 }
Esempio n. 16
0
        private void QueryEntryMap(
            TypeMethodPair entryPair,
            out TypeMethodPair implPair)
        {
            // 查询直接绑定
            if (EntryMap.TryGetValue(entryPair, out var impl))
            {
                implPair = impl.MethodPair;
                return;
            }

            // 遍历查询协逆变绑定
            TypeX entryTyX = entryPair.Item1;

            if (entryTyX.HasVariances)
            {
                MethodDef entryMetDef = entryPair.Item2;

                TypeMethodPair lastImpl  = null;
                uint           lastLevel = 0;

                foreach (var kv in EntryMap)
                {
                    TypeX     keyTyX    = kv.Key.Item1;
                    MethodDef keyMetDef = kv.Key.Item2;

                    if (keyMetDef == entryMetDef &&
                        keyTyX.HasVariances &&
                        entryTyX.IsDerivedType(keyTyX))
                    {
                        TypeMethodPair currImpl  = kv.Value.MethodPair;
                        uint           currLevel = kv.Value.Level;

                        if (lastImpl == null || lastLevel < currLevel)
                        {
                            lastImpl  = currImpl;
                            lastLevel = currLevel;
                        }
                    }
                }

                if (lastImpl != null)
                {
                    implPair = lastImpl;
                    return;
                }
            }

            throw new TypeLoadException(
                      string.Format("Virtual method can't resolve in type {0}: {1} -> {2}",
                                    Name,
                                    entryPair.Item1,
                                    entryPair.Item2.FullName));
        }
Esempio n. 17
0
        private void AddDerivedTypeRecursive(TypeX tyX)
        {
            DerivedTypes.Add(tyX);

            // 递归添加
            BaseType?.AddDerivedTypeRecursive(tyX);
            foreach (var inf in Interfaces)
            {
                inf.AddDerivedTypeRecursive(tyX);
            }
        }
Esempio n. 18
0
 public static uint GetCppTypeID(this TypeX tyX)
 {
     if (tyX == null)
     {
         return(0);
     }
     if (tyX.CppTypeID_ == 0)
     {
         tyX.CppTypeID_ = ++TypeIDCounter;
     }
     return(tyX.CppTypeID_);
 }
Esempio n. 19
0
 private bool IsInstanceNoRef(TypeX tyX)
 {
     if (tyX == null)
     {
         return(true);
     }
     if (tyX.IsValueType)
     {
         return(IsTypeNoRef(tyX));
     }
     return(false);
 }
Esempio n. 20
0
        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();
        }
Esempio n. 21
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));
            }
        }
Esempio n. 22
0
        public void AddVarianceBaseType(TypeX vaBaseType)
        {
            if (VarianceBaseTypes == null)
            {
                VarianceBaseTypes = new HashSet <TypeX>();
            }

            if (VarianceBaseTypes.Add(vaBaseType))
            {
                var tySet = new HashSet <TypeX>(DerivedTypes);
                tySet.Add(this);
                vaBaseType.AddDerivedTypeRecursive(tySet);
            }
        }
Esempio n. 23
0
 public bool QueryCallReplace(
     MethodDef entryDef,
     out TypeX implTyX,
     out MethodDef implDef)
 {
     if (SameTypeReplaceMap.TryGetValue(entryDef, out var implPair))
     {
         implTyX = implPair.Item1;
         implDef = implPair.Item2;
         return(true);
     }
     implTyX = null;
     implDef = null;
     return(false);
 }
Esempio n. 24
0
        public void QueryCallVirt(
            TypeX entryTyX,
            MethodDef entryDef,
            out TypeX implTyX,
            out MethodDef implDef)
        {
            var entryPair = new TypeMethodPair(entryTyX, entryDef);

            if (!CachedMap.TryGetValue(entryPair, out var implPair))
            {
                QueryCallVirtImpl(entryPair, out implPair);
                CachedMap[entryPair] = implPair;
            }
            implTyX = implPair.Item1;
            implDef = implPair.Item2;
        }
Esempio n. 25
0
        public static string GetCppName(this TypeX tyX, bool elemType = false)
        {
            if (elemType)
            {
                string elemName = GetElemTypeName(tyX.ToTypeSig().ElementType);
                if (elemName != null)
                {
                    return(elemName);
                }
            }

            if (tyX.CppName_ == null)
            {
                tyX.CppName_ = (tyX.Def.IsValueType ? "stru_" : "cls_") + ToCppName(tyX.FullName);
            }
            return(tyX.CppName_);
        }
Esempio n. 26
0
        public static bool GenInternalMethod(MethodX metX, CodePrinter prt, GeneratorContext genContext)
        {
            string typeName = metX.DeclType.GetNameKey();
            string metName  = metX.Def.Name;

            if (typeName == "String")
            {
                if (metName == "get_Length")
                {
                    FieldX fldLen = metX.DeclType.Fields.FirstOrDefault(
                        fld => fld.FieldType.ElementType == dnlib.DotNet.ElementType.I4);
                    prt.AppendFormatLine(@"return arg_0->{0};",
                                         genContext.GetFieldName(fldLen));

                    return(true);
                }
                else if (metName == "get_Chars")
                {
                    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);
                    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 (typeName == "System.Runtime.CompilerServices.RuntimeHelpers")
            {
                if (metX.Def.Name == "IsReferenceOrContainsReferences")
                {
                    Debug.Assert(metX.HasGenArgs && metX.GenArgs.Count == 1);
                    TypeX targetType = genContext.GetTypeBySig(metX.GenArgs[0]);
                    prt.AppendFormatLine("return {0};",
                                         genContext.IsRefOrContainsRef(targetType) ? "1" : "0");

                    return(true);
                }
            }
            return(false);
        }
Esempio n. 27
0
        private void AddDerivedTypeRecursive(TypeX tyX)
        {
            DerivedTypes.Add(tyX);

            // 递归添加
            BaseType?.AddDerivedTypeRecursive(tyX);
            foreach (var inf in Interfaces)
            {
                inf.AddDerivedTypeRecursive(tyX);
            }

            if (HasVarianceBaseTypes)
            {
                foreach (var va in VarianceBaseTypes)
                {
                    va.AddDerivedTypeRecursive(tyX);
                }
            }
        }
Esempio n. 28
0
        public bool IsTypeNoRef(TypeX tyX)
        {
            if (tyX == null)
            {
                return(true);
            }

            if (tyX.NoRefFlag != 0)
            {
                return(tyX.NoRefFlag == 1);
            }

            if (tyX.IsArrayType)
            {
                // 数组取决于其元素类型的属性
                Debug.Assert(tyX.HasGenArgs && tyX.GenArgs.Count == 1);
                TypeX elemType = GetTypeBySig(tyX.GenArgs[0]);
                tyX.NoRefFlag = (byte)(IsInstanceNoRef(elemType) ? 1 : 2);
            }
            else
            {
                tyX.NoRefFlag = 1;
                // 检查对象的字段
                foreach (var fldX in tyX.Fields)
                {
                    if (!fldX.IsInstance)
                    {
                        continue;
                    }

                    TypeX fldType = GetTypeBySig(fldX.FieldType);
                    if (!IsInstanceNoRef(fldType))
                    {
                        // 存在包含引用的字段
                        tyX.NoRefFlag = 2;
                        break;
                    }
                }
            }

            return(tyX.NoRefFlag == 1);
        }
Esempio n. 29
0
        public string GetTypeDefaultValue(TypeSig tySig)
        {
            switch (tySig.ElementType)
            {
            case ElementType.Boolean:
            case ElementType.Char:
            case ElementType.I1:
            case ElementType.I2:
            case ElementType.I4:
            case ElementType.I8:
            case ElementType.U1:
            case ElementType.U2:
            case ElementType.U4:
            case ElementType.U8:
            case ElementType.R4:
            case ElementType.R8:
            case ElementType.I:
            case ElementType.U:
                return("0");

            case ElementType.Ptr:
            case ElementType.ByRef:
            case ElementType.Object:
                return("nullptr");
            }

            if (tySig.IsValueType)
            {
                TypeX tyX = GetTypeBySig(tySig);
                if (tyX.IsEnumType)
                {
                    return(GetTypeDefaultValue(tyX.EnumTypeSig));
                }

                return(GetTypeName(tyX) + "()");
            }

            return("nullptr");
        }
Esempio n. 30
0
        public MethodX(TypeX declType, MethodDef metDef)
        {
            Debug.Assert(declType != null);
            Debug.Assert(metDef.DeclaringType == declType.Def);
            DeclType = declType;
            Def      = metDef;

            Debug.Assert(HasThis && !metDef.IsStatic || !HasThis && metDef.IsStatic);

            if (metDef.HasBody)
            {
                if (metDef.Body.HasVariables)
                {
                    LocalTypes = new List <TypeSig>();
                    foreach (var loc in metDef.Body.Variables)
                    {
                        Debug.Assert(loc.Index == LocalTypes.Count);
                        LocalTypes.Add(loc.Type);
                    }
                }
            }
        }