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 TypeCppCode GenDeclCode(TypeX currType) { CodePrinter prt = new CodePrinter(); // 构造类型注释 prt.AppendFormatLine("// {0}", currType.PrettyName()); // 构造类型结构体代码 string typeName; string baseTypeName = null; if (currType.BaseType != null && !currType.Def.IsValueType) { baseTypeName = currType.BaseType.GetCppName(); typeName = currType.GetCppName(); prt.AppendFormatLine("struct {0} : {1}\n{{", typeName, baseTypeName); } else if (currType.Def.ToTypeSig().IsObjectSig()) { typeName = currType.GetCppName(); prt.AppendFormatLine("struct {0} : il2cppObject\n{{", typeName); } else { Debug.Assert( currType.Def.IsValueType || currType.Def.IsInterface); typeName = currType.GetCppName(); prt.AppendFormatLine("struct {0}\n{{", typeName); } // 添加代码映射 TypeCppCode cppCode = new TypeCppCode(typeName); CodeMap.Add(typeName, cppCode); // 添加基类型依赖 if (baseTypeName != null) { cppCode.DeclDependNames.Add(baseTypeName); } ++prt.Indents; // 构造结构体成员 List <FieldX> staticFields = new List <FieldX>(); foreach (var fldX in currType.Fields) { if (fldX.Def.IsStatic) { staticFields.Add(fldX); continue; } string fieldTypeName = fldX.FieldType.GetCppName(TypeMgr); prt.AppendFormatLine("// {0}\n{1} {2};", fldX.PrettyName(), fieldTypeName, fldX.GetCppName()); // 添加字段类型依赖 if (fldX.FieldType.IsValueType) { cppCode.DeclDependNames.Add(fieldTypeName); } } --prt.Indents; prt.AppendLine("};"); // 构造装箱类型 if (currType.Def.IsValueType) { prt.AppendFormatLine("struct box_{0} : il2cppObject\n{{", typeName); ++prt.Indents; prt.AppendFormatLine("{0} value;", currType.ToTypeSig().GetCppName(TypeMgr)); --prt.Indents; prt.AppendLine("};"); } // 构造静态字段全局变量 StringBuilder sbImpl = new StringBuilder(); foreach (var sfldX in staticFields) { string sfldTypeName = sfldX.FieldType.GetCppName(TypeMgr); string sfldCppName = sfldX.GetCppName(); string sfldPrettyName = sfldX.PrettyName(true); string sfldDef = string.Format("{0} {1};\n", sfldTypeName, sfldCppName); prt.AppendFormat("// {0}\nextern {1}", sfldPrettyName, sfldDef); sbImpl.AppendFormat("// {0}\n{1}", sfldPrettyName, sfldDef); StaticInitDecl.Append("extern " + sfldDef); StaticInitBody.AppendFormat("{0} = {1};\n", sfldCppName, sfldX.FieldType.GetInitValue(TypeMgr)); // 添加字段类型依赖 if (sfldX.FieldType.IsValueType) { cppCode.DeclDependNames.Add(sfldTypeName); cppCode.ImplDependNames.Add(sfldTypeName); } } // 静态构造函数防止多次调用的标记 if (currType.CctorMethod != null) { string onceName = string.Format("onceflag_{0}", typeName); string onceDef = string.Format("int8_t {0};\n", onceName); string locktidName = string.Format("locktid_{0}", typeName); string locktidDef = string.Format("uintptr_t {0};\n", locktidName); prt.Append("extern " + onceDef); prt.Append("extern " + locktidDef); sbImpl.Append(onceDef); sbImpl.Append(locktidDef); StaticInitDecl.Append("extern " + onceDef); StaticInitDecl.Append("extern " + locktidDef); StaticInitBody.AppendFormat("{0} = 0;\n", onceName); StaticInitBody.AppendFormat("{0} = 0;\n", locktidName); } cppCode.DeclCode.Append(prt); cppCode.ImplCode.Append(sbImpl); return(cppCode); }
private static void SigToCppName(TypeSig sig, StringBuilder sb, TypeManager typeMgr) { string elemName = GetElemTypeName(sig.ElementType); if (elemName != null) { sb.Append(elemName); return; } switch (sig.ElementType) { case ElementType.Class: case ElementType.ValueType: case ElementType.GenericInst: { TypeX type = typeMgr.GetTypeByName(sig.FullName); if (type != null) { if (type.Def.IsValueType) { sb.Append(type.GetCppName()); } else { sb.Append("struct " + type.GetCppName() + '*'); } } else { if (sig.IsValueType) { sb.Append("il2cppValueType"); } else { sb.Append("il2cppObject*"); } } } return; case ElementType.Ptr: case ElementType.ByRef: SigToCppName(sig.Next, sb, typeMgr); sb.Append('*'); return; case ElementType.SZArray: sb.Append("il2cppSZArray<"); SigToCppName(sig.Next, sb, typeMgr); sb.Append(">*"); return; case ElementType.Array: //! il2cppArray<next, 0, 10, 0, 10, ...>* break; case ElementType.Pinned: case ElementType.CModReqd: case ElementType.CModOpt: SigToCppName(sig.Next, sb, typeMgr); return; default: throw new ArgumentOutOfRangeException("SigToCppName TypeSig " + sig.FullName); } }