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); }
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); }
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)); }
public FieldX(TypeX declType, FieldDef fldDef) { Debug.Assert(declType != null); Debug.Assert(fldDef.DeclaringType == declType.Def); DeclType = declType; Def = fldDef; }
public TypeX GetTypeX() { TypeX tyX = TypeMgr.GetTypeByName(GetNameKey()); Debug.Assert(tyX != null); return(tyX); }
public void AddDerivedEnumTypes(TypeX enumTyX) { if (DerivedEnumTypes == null) { DerivedEnumTypes = new HashSet <TypeX>(); } DerivedEnumTypes.Add(enumTyX); }
private bool RefToTypeIsNoRef(TypeX tyX) { if (tyX.IsValueType) { return(IsNoRefType(tyX)); } return(false); }
public static string PrettyName(this TypeX self) { StringBuilder sb = new StringBuilder(); PrettyName(sb, self.Def.ToTypeSig(), true); PrettyGenArgs(sb, self.GenArgs); return(sb.ToString()); }
public void SetType(TypeX tyX) { if (tyX.HasGenArgs) { OwnerType = tyX.Def; TypeGenArgs = tyX.GenArgs; } }
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); }
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); }
public bool QueryCallReplace( TypeManager typeMgr, MethodDef entryDef, out TypeX implTyX, out MethodDef implDef) { ResolveVTable(typeMgr); return(VTable.QueryCallReplace(entryDef, out implTyX, out implDef)); }
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); }
public uint GetTypeID(TypeX tyX) { if (tyX.GeneratedTypeID != 0) { return(tyX.GeneratedTypeID); } tyX.GeneratedTypeID = ++TypeIDCounter; return(tyX.GeneratedTypeID); }
public uint GetStringTypeID() { if (StringTypeID == 0) { TypeX strTyX = GetTypeByName("String"); Debug.Assert(strTyX != null); StringTypeID = GetTypeID(strTyX); } Debug.Assert(StringTypeID != 0); return(StringTypeID); }
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)); }
private void AddDerivedTypeRecursive(TypeX tyX) { DerivedTypes.Add(tyX); // 递归添加 BaseType?.AddDerivedTypeRecursive(tyX); foreach (var inf in Interfaces) { inf.AddDerivedTypeRecursive(tyX); } }
public static uint GetCppTypeID(this TypeX tyX) { if (tyX == null) { return(0); } if (tyX.CppTypeID_ == 0) { tyX.CppTypeID_ = ++TypeIDCounter; } return(tyX.CppTypeID_); }
private bool IsInstanceNoRef(TypeX tyX) { if (tyX == null) { return(true); } if (tyX.IsValueType) { return(IsTypeNoRef(tyX)); } return(false); }
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 void RefValueTypeDecl(CompileUnit unit, TypeSig tySig) { if (!tySig.IsValueType) { return; } TypeX tyX = GenContext.GetTypeBySig(tySig); if (tyX != null) { unit.DeclDepends.Add(GenContext.GetTypeName(tyX)); } }
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); } }
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); }
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; }
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_); }
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); }
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); } } }
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); }
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"); }
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); } } } }