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 GenerateIsType(CodePrinter prtDecl, CodePrinter prtImpl) { if (CurrType.IsValueType) { return; } CodePrinter prt = new CodePrinter(); prt.AppendFormat("uint8_t istype_{0}(uint32_t typeID)", GenContext.GetTypeName(CurrType)); string strDecl = prt.ToString() + ";\n"; prt.AppendLine("\n{"); ++prt.Indents; var derivedRange = new List <TypeX>(CurrType.DerivedTypes); derivedRange.Add(CurrType); List <TypeX> derTypes = new List <TypeX>(); foreach (var derTyX in derivedRange) { // 跳过不分配在堆上的类型 if (!derTyX.IsInstantiated || derTyX.IsValueType || derTyX.Def.IsInterface) { continue; } derTypes.Add(derTyX); } if (derTypes.Count > 0) { prt.AppendLine("switch (typeID)\n{"); ++prt.Indents; derTypes.Sort((lhs, rhs) => GenContext.GetTypeID(lhs).CompareTo(GenContext.GetTypeID(rhs))); foreach (var derTyX in derTypes) { prt.AppendFormatLine("// {0}", derTyX.GetNameKey()); prt.AppendFormatLine("case {0}:", GenContext.GetTypeID(derTyX)); } ++prt.Indents; prt.AppendLine("return 1;"); --prt.Indents; --prt.Indents; prt.AppendLine("}"); } prt.AppendLine("return 0;"); --prt.Indents; prt.AppendLine("}"); prtDecl.Append(strDecl); prtImpl.Append(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 void GenIsTypeFunc(CodePrinter prtDecl, CodePrinter prtImpl, bool currIsObject) { if (CurrType.IsValueType || !CurrType.NeedGenIsType) { return; } CodePrinter prt = new CodePrinter(); prt.AppendFormat("uint8_t {0}(uint32_t typeID)", GenContext.GetIsTypeFuncName(CurrType)); string strDecl = prt.ToString() + ";\n"; prt.AppendLine("\n{"); ++prt.Indents; var derivedRange = new List <TypeX>(CurrType.DerivedTypes); derivedRange.Add(CurrType); var derivedEnumTypes = CurrType.UnBoxedType?.DerivedEnumTypes; if (derivedEnumTypes != null) { derivedRange.AddRange(derivedEnumTypes); } List <TypeX> derTypes = new List <TypeX>(); foreach (var derTyX in derivedRange) { // 跳过不分配在堆上的类型 if (!derTyX.IsInstantiated || derTyX.Def.IsInterface) { continue; } // 如果当前类型是 object, 则跳过值类型 if (currIsObject && derTyX.IsValueType) { continue; } derTypes.Add(derTyX); } if (derTypes.Count > 0) { prt.AppendLine("switch (typeID)\n{"); ++prt.Indents; derTypes.Sort((lhs, rhs) => GenContext.GetTypeID(lhs).CompareTo(GenContext.GetTypeID(rhs))); foreach (var derTyX in derTypes) { prt.AppendFormatLine("// {0}", Helper.EscapeString(derTyX.GetNameKey())); prt.AppendFormatLine("case {0}:", GenContext.GetTypeID(derTyX)); } ++prt.Indents; prt.AppendLine("return 1;"); --prt.Indents; --prt.Indents; prt.AppendLine("}"); } prt.AppendLine("return 0;"); --prt.Indents; prt.AppendLine("}"); prtDecl.Append(strDecl); prtImpl.Append(prt.ToString()); }