diff --git a/doc/cn/Programming_Specifications.md b/doc/cn/Programming_Specifications.md index eb57606c79fd6e6e070661ea1e96de6933aa6bcb..26a6539e6c1622dfc0f292dd476a5880c4948ac6 100644 --- a/doc/cn/Programming_Specifications.md +++ b/doc/cn/Programming_Specifications.md @@ -532,10 +532,15 @@ const int rank[] = { ``` ## 指针与引用 -### 建议3.12.1 指针类型"`*`"跟随变量名,并与类型之间有一个空格 +### 建议3.12.1 指针类型"* "跟随变量名或者类型,不要两边都留有或者都没有空格 + +指针命名: * 靠左靠右都可以,但是不要两边都有或者都没有空格。 ```cpp -int *p = nullptr; // Good +int* p = NULL; // Good +int *p = NULL; // Good +int*p = NULL; // Bad +int * p = NULL; // Bad ``` 例外:当变量被 const 修饰时,"`*`" 无法跟随变量,此时也不要跟随类型。 @@ -543,14 +548,21 @@ int *p = nullptr; // Good char * const VERSION = "V100"; ``` -### 建议3.12.2 引用类型"`&`"跟随变量名,并与类型之间有一个空格 +例外:对于如` static_cast(somePointer)/(char*)/vector `中的场景,*与类型之间不加空格。 + +### 建议3.12.2 引用类型"& "跟随变量名或者类型,不要两边都留有或者都没有空格 + +引用命名: & 靠左靠右都可以,但是不要两边都有或者都没有空格。 ```cpp int i = 8; - -int &p = i; // Good +int& p = i; // Good +int &p = i; // Good +int & p = i; // Bad +int&p = i; // Bad ``` + ## 编译预处理 ### 规则3.13.1 编译预处理的"#"统一放在行首,嵌套编译预处理语句时,"#"不缩进 编译预处理的"#"统一放在行首,即使编译预处理的代码是嵌入在函数体中的,"#"也应该放在行首。 diff --git a/src/bin/jbc2mpl b/src/bin/jbc2mpl index 3d2b5dde8d508d107ab75828d6b7489e5bc79c12..9399d7392a1a3a9f26499ecff533f4e66bbcd8b6 100755 Binary files a/src/bin/jbc2mpl and b/src/bin/jbc2mpl differ diff --git a/src/bin/maple b/src/bin/maple index 67733d2cfae90964ccff5d7e1cc67c0b46b62688..6e14c98e8a5454d124f1c4d58c83d97a5a5226ae 100755 Binary files a/src/bin/maple and b/src/bin/maple differ diff --git a/src/bin/mplcg b/src/bin/mplcg index a7a9dd9ad90feeb0e6ec84aa72c0aea5bee2ef31..4fa1184fd79b1c758d564d9af8ab18873f41da5f 100755 Binary files a/src/bin/mplcg and b/src/bin/mplcg differ diff --git a/src/deplibs/libmempool.a b/src/deplibs/libmempool.a index 4bdc164ab0c3a5d8f79d51f5a45765b8799aebb0..13285b2155ba67f1dddf8898f84ea59f4ac864d6 100644 Binary files a/src/deplibs/libmempool.a and b/src/deplibs/libmempool.a differ diff --git a/src/maple_driver/include/driver_runner.h b/src/maple_driver/include/driver_runner.h index 115152b36c52534a4af96bfd1023687f120fd7bd..bf1f981a54acb4508de7b0aca00ece0c298194e8 100644 --- a/src/maple_driver/include/driver_runner.h +++ b/src/maple_driver/include/driver_runner.h @@ -78,7 +78,6 @@ class DriverRunner final { bool timePhases = false; bool genMeMpl = false; std::string printOutExe; - }; } // namespace maple diff --git a/src/maple_driver/include/mpl_options.h b/src/maple_driver/include/mpl_options.h index edc40df4df6fa391723e27214d2f3a9ac2bef691..b4579804bb02ce109e273cff31d4052fd96278a3 100644 --- a/src/maple_driver/include/mpl_options.h +++ b/src/maple_driver/include/mpl_options.h @@ -62,6 +62,8 @@ class MplOption { CHECK_FATAL(!key.empty(), "MplOption got an empty key."); } + ~MplOption() = default; + const std::string &GetKey() const { return key; } diff --git a/src/maple_driver/include/safe_exe.h b/src/maple_driver/include/safe_exe.h index 5e2eb8e08ac5bad32f85588fe9e8dddb2981d2ac..c8a39030831c02ff53c00afc48155ba62ed25935 100644 --- a/src/maple_driver/include/safe_exe.h +++ b/src/maple_driver/include/safe_exe.h @@ -38,10 +38,10 @@ class SafeExe { // argv[0] is program name // copy args for (size_t j = 0; j < vectorArgs.size(); ++j) { - int strLength = vectorArgs[j].size(); - argv[j] = new char[strLength + 1]; - strncpy_s(argv[j], strLength + 1, vectorArgs[j].c_str(), strLength); - argv[j][strLength] = '\0'; + int strLength = vectorArgs[j].size(); + argv[j] = new char[strLength + 1]; + strncpy_s(argv[j], strLength + 1, vectorArgs[j].c_str(), strLength); + argv[j][strLength] = '\0'; } // end of arguments sentinel is nullptr argv[vectorArgs.size()] = nullptr; @@ -97,7 +97,7 @@ class SafeExe { StringUtils::Split(args, tmpArgs, ' '); // remove ' ' in vector for (auto iter = tmpArgs.begin(); iter != tmpArgs.end();) { - if (*iter == " " || *iter =="") { + if (*iter == " " || *iter == "") { iter = tmpArgs.erase(iter); } else { ++iter; diff --git a/src/maple_driver/include/usages.h b/src/maple_driver/include/usages.h index a00ad36e4910abe54fe611e7b5e37d1ac597421d..c60a280349cb1baae3a2df5cffd4b43d5a412ea4 100644 --- a/src/maple_driver/include/usages.h +++ b/src/maple_driver/include/usages.h @@ -32,12 +32,12 @@ enum OptionIndex : uint64 { // ----------jbc2mpl begin------- kUseStringFactory, kJbc2mplOutMpl, - //-------- comb begin-------- -- + // -------- comb begin-------- -- kCombTimePhases, kGenMeMpl, kGenVtableImpl, kVerify, - //----------me begin----------- + // ----------me begin----------- kMeHelp, kMeDumpPhases, kMeSkipPhases, @@ -53,7 +53,7 @@ enum OptionIndex : uint64 { kMeRange, kLessThrowAlias, kRegReadAtReturn, - //----------mpl2mpl begin--------- + // ----------mpl2mpl begin--------- kMpl2MplHelp, kMpl2MplDumpPhase, kMpl2MplSkipPhase, @@ -71,7 +71,7 @@ enum OptionIndex : uint64 { kMpl2MplMapleLinker, kMplnkDumpMuid, kEmitVtableImpl, - //----------mplcg begin--------- + // ----------mplcg begin--------- kCGQuiet, kPie, kPic, diff --git a/src/maple_driver/src/compiler_factory.cpp b/src/maple_driver/src/compiler_factory.cpp index 686e2dcd3e7b14ac96160f8bd69ec2e77362d647..fef18712492addc3a209701021cec22ce01dc8dd 100644 --- a/src/maple_driver/src/compiler_factory.cpp +++ b/src/maple_driver/src/compiler_factory.cpp @@ -32,10 +32,10 @@ CompilerFactory &CompilerFactory::GetInstance() { CompilerFactory::CompilerFactory() { // Supported compilers - ADD_COMPILER("jbc2mpl" ,Jbc2MplCompiler) - ADD_COMPILER("me" ,MapleCombCompiler) - ADD_COMPILER("mpl2mpl" ,MapleCombCompiler) - ADD_COMPILER("mplcg" ,MplcgCompiler) + ADD_COMPILER("jbc2mpl", Jbc2MplCompiler) + ADD_COMPILER("me", MapleCombCompiler) + ADD_COMPILER("mpl2mpl", MapleCombCompiler) + ADD_COMPILER("mplcg", MplcgCompiler) compilerSelector = new CompilerSelectorImpl(); } diff --git a/src/maple_ir/include/global_tables.h b/src/maple_ir/include/global_tables.h index 1a81d21f6dda151c4ae248d8e3b114539727ca9c..c61c2481999e49374686405d814556b1babb2751 100644 --- a/src/maple_ir/include/global_tables.h +++ b/src/maple_ir/include/global_tables.h @@ -74,22 +74,22 @@ class TypeTable { return const_cast(const_cast(this)->GetTypeFromTyIdx(tyIdx)); } const MIRType *GetTypeFromTyIdx(TyIdx tyIdx) const { - ASSERT(tyIdx.GetIdx() < typeTable.size(), "array index out of range"); + CHECK_FATAL(tyIdx.GetIdx() < typeTable.size(), "array index out of range"); return typeTable.at(tyIdx.GetIdx()); } MIRType *GetTypeFromTyIdx(uint32 index) const { - ASSERT(index < typeTable.size(), "array index out of range"); + CHECK_FATAL(index < typeTable.size(), "array index out of range"); return typeTable.at(index); } PrimType GetPrimTypeFromTyIdx(TyIdx tyIdx) const { - ASSERT(tyIdx.GetIdx() < typeTable.size(), "array index out of range"); + CHECK_FATAL(tyIdx.GetIdx() < typeTable.size(), "array index out of range"); return typeTable.at(tyIdx.GetIdx())->GetPrimType(); } void SetTypeWithTyIdx(TyIdx tyIdx, MIRType *type) { - ASSERT(tyIdx.GetIdx() < typeTable.size(), "array index out of range"); + CHECK_FATAL(tyIdx.GetIdx() < typeTable.size(), "array index out of range"); typeTable.at(tyIdx.GetIdx()) = type; } diff --git a/src/maple_ir/include/lexer.h b/src/maple_ir/include/lexer.h index a52b338f67147d277187a7f0590bd0e1580efcac..246bf0f55e48130ff0a26401211fd40a070763ac 100644 --- a/src/maple_ir/include/lexer.h +++ b/src/maple_ir/include/lexer.h @@ -89,6 +89,9 @@ class MIRLexer { MapleUnorderedMap keywordMap; void RemoveReturnInline(std::string &line) { + if (line.empty()) { + return; + } if (line.back() == '\n') { line.pop_back(); } diff --git a/src/maple_ir/include/mir_builder.h b/src/maple_ir/include/mir_builder.h index 7d557a1317473f5544f64c09d165919b6d0cd5a4..ae1edf30e2e1fc8c262c7bf85f9ffd7c146f38b9 100644 --- a/src/maple_ir/include/mir_builder.h +++ b/src/maple_ir/include/mir_builder.h @@ -276,7 +276,7 @@ class MIRBuilder { MIRSymbol *GetOrCreateSymbol(TyIdx, GStrIdx, MIRSymKind, MIRStorageClass, MIRFunction*, uint8, bool) const; MIRSymbol *CreatePregFormalSymbol(TyIdx, PregIdx, MIRFunction&) const; // for creating symbol - MIRSymbol *CreateSymbol(TyIdx,const std::string&, MIRSymKind, MIRStorageClass, MIRFunction*, uint8) const; + MIRSymbol *CreateSymbol(TyIdx, const std::string&, MIRSymKind, MIRStorageClass, MIRFunction*, uint8) const; MIRSymbol *CreateSymbol(TyIdx, GStrIdx, MIRSymKind, MIRStorageClass, MIRFunction*, uint8) const; // for creating nodes AddrofNode *CreateAddrof(const MIRSymbol &st, PrimType pty = PTY_ptr); diff --git a/src/maple_ir/include/mir_function.h b/src/maple_ir/include/mir_function.h index 04f8475a8eca0c078345f6b444c0797f61c767c8..e4bdaa5f12cdae1f03b53b57ebf71031a58126da 100644 --- a/src/maple_ir/include/mir_function.h +++ b/src/maple_ir/include/mir_function.h @@ -744,7 +744,7 @@ class MIRFunction { MIRInfoVector info{module->GetMPAllocator().Adapter()}; MapleVector infoIsString{module->GetMPAllocator().Adapter()}; // tells if an entry has string value MapleMap aliasVarMap{module->GetMPAllocator().Adapter()}; // source code alias variables - //for debuginfo + // for debuginfo bool withLocInfo = true; uint8_t layoutType = kLayoutUnused; diff --git a/src/maple_ir/include/mir_symbol.h b/src/maple_ir/include/mir_symbol.h index 375044238470d1609612fd64789075a8a15e2002..b09a4fe180ca0a85cc62bfcdfe9cadbe7a111a74 100644 --- a/src/maple_ir/include/mir_symbol.h +++ b/src/maple_ir/include/mir_symbol.h @@ -312,6 +312,7 @@ class MIRSymbol { bool IsReflectionFieldsInfoCompact() const; bool IsReflectionSuperclassInfo() const; bool IsReflectionFieldOffsetData() const; + bool IsReflectionMethodAddrData() const; bool IsReflectionClassInfo() const; bool IsReflectionArrayClassInfo() const; bool IsReflectionClassInfoPtr() const; @@ -518,9 +519,12 @@ class MIRLabelTable { return labelTable; } - MapleMap &GetStrIdxToLabelIdxMap() { + const MapleMap &GetStrIdxToLabelIdxMap() const { return strIdxToLabIdxMap; } + void EraseStrIdxToLabelIdxElem(GStrIdx idx) { + strIdxToLabIdxMap.erase(idx); + } private: static constexpr uint32 kDummyLabel = 0; diff --git a/src/maple_ir/include/mir_type.h b/src/maple_ir/include/mir_type.h index 226e5d8bdee3fd963693f9336cda6ab667caaf67..40ac9fcffc13b8a8a2d883daf7e4e0c57efa2fb7 100644 --- a/src/maple_ir/include/mir_type.h +++ b/src/maple_ir/include/mir_type.h @@ -426,6 +426,11 @@ class MIRType { typeKind = kind; } + bool IsIncomplete() const { + return typeKind == kTypeStructIncomplete || typeKind == kTypeClassIncomplete || + typeKind == kTypeInterfaceIncomplete; + } + bool IsNameIsLocal() const { return nameIsLocal; } @@ -701,10 +706,12 @@ class MIRStructType : public MIRType { FieldVector &GetFields() { return fields; } - const FieldVector &GetFields() const { return fields; } + void SetFields(const FieldVector &fields) { + this->fields = fields; + } const FieldPair &GetFieldsElemt(size_t n) const { ASSERT(n < fields.size(), "array index out of range"); @@ -734,6 +741,9 @@ class MIRStructType : public MIRType { FieldVector &GetParentFields() { return parentFields; } + void SetParentFields(const FieldVector &parentFields) { + this->parentFields = parentFields; + } const FieldVector &GetParentFields() const { return parentFields; } @@ -907,10 +917,6 @@ class MIRStructType : public MIRType { void DumpFieldsAndMethods(int indent, bool hasMethod) const; void Dump(int indent, bool dontUseName = false) const override; - bool IsIncomplete() const { - return typeKind == kTypeStructIncomplete || typeKind == kTypeClassIncomplete || - typeKind == kTypeInterfaceIncomplete; - } virtual void SetComplete() { typeKind = (typeKind == kTypeUnion) ? typeKind : kTypeStruct; @@ -1251,6 +1257,9 @@ class MIRInterfaceType : public MIRStructType { std::vector &GetParentsTyIdx() { return parentsTyIdx; } + void SetParentsTyIdx(const std::vector &parents) { + parentsTyIdx = parents; + } const std::vector &GetParentsTyIdx() const { return parentsTyIdx; } diff --git a/src/maple_ir/src/bin_mpl_export.cpp b/src/maple_ir/src/bin_mpl_export.cpp index f60eca3ce8a4a24e33705789e34f2e6e3009f24c..0df30c257bfdbda5c8fdf4b207953ae288ca1d65 100644 --- a/src/maple_ir/src/bin_mpl_export.cpp +++ b/src/maple_ir/src/bin_mpl_export.cpp @@ -473,7 +473,8 @@ void BinaryMplExport::OutputFieldPair(const FieldPair &fp) { (fa.GetAttr(FLDATTR_public) || fa.GetAttr(FLDATTR_protected))) { const char *fieldName = (GlobalTables::GetStrTable().GetStringFromStrIdx(fp.first)).c_str(); MIRSymbol *fieldVar = mod.GetMIRBuilder()->GetGlobalDecl(fieldName); - if (fieldVar != nullptr && dynamic_cast(fieldVar->GetKonst())) { + if ((fieldVar != nullptr) && (fieldVar->GetKonst() != nullptr) && + (fieldVar->GetKonst()->GetKind() == kConstStr16Const)) { WriteNum(kBinInitConst); OutputConst(fieldVar->GetKonst()); } else { diff --git a/src/maple_ir/src/global_tables.cpp b/src/maple_ir/src/global_tables.cpp index 705d1b8c3b37c5c38356115b088094cfb1d38ed5..45e89d13d02467945877a33b500511a703d6a6d3 100644 --- a/src/maple_ir/src/global_tables.cpp +++ b/src/maple_ir/src/global_tables.cpp @@ -135,11 +135,11 @@ MIRType *TypeTable::GetOrCreateFunctionType(MIRModule &module, TyIdx retTyIdx, c } MIRType *TypeTable::GetOrCreateStructOrUnion(const std::string &name, const FieldVector &fields, - const FieldVector &printFields, MIRModule &module, bool forStruct) { + const FieldVector &parentFields, MIRModule &module, bool forStruct) { GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name); MIRStructType type(forStruct ? kTypeStruct : kTypeUnion, strIdx); - type.GetFields() = fields; - type.GetParentFields() = printFields; + type.SetFields(fields); + type.SetParentFields(parentFields); TyIdx tyIdx = GetOrCreateMIRType(&type); // Global? module.GetTypeNameTab()->SetGStrIdxToTyIdx(strIdx, tyIdx); diff --git a/src/maple_ir/src/mir_function.cpp b/src/maple_ir/src/mir_function.cpp index 57f9840c831752373bf7f0c9c9017094b59176ea..878b4446b8d74ec70c777c13e0a5b1e6f0a81d80 100644 --- a/src/maple_ir/src/mir_function.cpp +++ b/src/maple_ir/src/mir_function.cpp @@ -105,7 +105,6 @@ MIRType *MIRFunction::GetNthParamType(size_t i) { } LabelIdx MIRFunction::GetOrCreateLableIdxFromName(const std::string &name) { - // TODO: this function should never be used after parsing, so move to parser? GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name); LabelIdx labelIdx = GetLabelTab()->GetStIdxFromStrIdx(strIdx); if (labelIdx == 0) { diff --git a/src/maple_ir/src/mir_symbol.cpp b/src/maple_ir/src/mir_symbol.cpp index 985f0b1df196b4c2cb2376eb837ecb25aef11339..5afe80a247ee216787636970c9b11f0b4f47a4ed 100644 --- a/src/maple_ir/src/mir_symbol.cpp +++ b/src/maple_ir/src/mir_symbol.cpp @@ -178,6 +178,10 @@ bool MIRSymbol::IsReflectionFieldOffsetData() const { return StringUtils::StartsWith(GetName(), kFieldOffsetDataPrefixStr); } +bool MIRSymbol::IsReflectionMethodAddrData() const { + return (GetName().find(kMethodAddrDataPrefixStr) == 0); +} + bool MIRSymbol::IsReflectionClassInfo() const { return StringUtils::StartsWith(GetName(), CLASSINFO_PREFIX_STR); } diff --git a/src/maple_ir/src/parser.cpp b/src/maple_ir/src/parser.cpp index 3cb28b8289bb68652a9f9f920f91b69f47d09ddc..40f39d73ec62c299e2dcff85d256c48ed22a141f 100644 --- a/src/maple_ir/src/parser.cpp +++ b/src/maple_ir/src/parser.cpp @@ -44,7 +44,6 @@ const std::map tkPragmaKind = { { TK_class, kPragmaClass { TK_param, kPragmaParam }, { TK_func_ex, kPragmaFuncExecptioni }, { TK_func_var, kPragmaFuncVar } }; - const std::map tkPragmaValType = { { TK_i8, kValueByte }, { TK_i16, kValueShort }, { TK_u16, kValueChar }, @@ -915,7 +914,7 @@ bool MIRParser::ParseInterfaceType(TyIdx &sTyIdx) { tk = lexer.GetTokenKind(); } MIRInterfaceType interfaceType(tkind); - interfaceType.GetParentsTyIdx() = parents; + interfaceType.SetParentsTyIdx(parents); if (!ParseFields(interfaceType)) { return false; } @@ -1104,15 +1103,14 @@ bool MIRParser::ParseDefinedTypename(TyIdx &definedTyIdx, MIRTypeKind kind) { TyIdx prevTypeIdx(0); if (definedTyIdx.GetIdx()) { MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(definedTyIdx); - auto *stype = dynamic_cast(type); - if (stype != nullptr) { + if (type->IsStructType()) { + auto *stype = static_cast(type); // check whether need to update from incomplete class to interface if (stype->GetKind() == kind) { lexer.NextToken(); return true; - } else { - prevTypeIdx = definedTyIdx; } + prevTypeIdx = definedTyIdx; } } if (tk == kTkGname) { @@ -1467,8 +1465,8 @@ bool MIRParser::ParseTypedef() { prevTyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(strIdx); if (prevTyIdx != 0) { MIRType *prevType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(prevTyIdx); - prevStructType = dynamic_cast(prevType); - ASSERT(prevStructType != nullptr, "prevStructType is null"); + CHECK_FATAL(prevType->IsStructType(), "type error"); + prevStructType = static_cast(prevType); if ((prevType->GetKind() != kTypeByName) && (prevStructType && !prevStructType->IsIncomplete())) { // allow duplicated type def if kKeepFirst is set which is the default if (options & kKeepFirst) { @@ -1493,8 +1491,7 @@ bool MIRParser::ParseTypedef() { prevTyIdx = mod.CurFunction()->GetTyIdxFromGStrIdx(strIdx); if (prevTyIdx != 0) { MIRType *prevType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(prevTyIdx); - prevStructType = dynamic_cast(prevType); - if ((prevType->GetKind() != kTypeByName) && (prevStructType && !prevStructType->IsIncomplete())) { + if ((prevType->GetKind() != kTypeByName) && (prevType->IsStructType() && !prevType->IsIncomplete())) { Error("redefined local type name "); return false; } diff --git a/src/maple_me/src/alias_class.cpp b/src/maple_me/src/alias_class.cpp index 7ab4faf2ff2f7a6b0962657e9f18aacb68d1d4b1..5b6c553ea71e46c71a3c3b27263d1e54238965b4 100644 --- a/src/maple_me/src/alias_class.cpp +++ b/src/maple_me/src/alias_class.cpp @@ -85,11 +85,12 @@ AliasElem *AliasClass::FindOrCreateAliasElem(OriginalSt &ost) { } AliasElem *AliasClass::FindOrCreateExtraLevAliasElem(BaseNode &expr, TyIdx tyIdx, FieldID fieldId) { - AliasElem *ae = CreateAliasElemsExpr(kOpcodeInfo.IsTypeCvt(expr.GetOpCode()) ? *expr.Opnd(0) : expr); - if (ae == nullptr) { + AliasElem *aliasElem = CreateAliasElemsExpr(kOpcodeInfo.IsTypeCvt(expr.GetOpCode()) ? *expr.Opnd(0) : expr); + if (aliasElem == nullptr) { return nullptr; } - OriginalSt *newOst = GetAliasAnalysisTable()->FindOrCreateExtraLevOriginalSt(ae->GetOriginalSt(), tyIdx, fieldId); + OriginalSt *newOst = GetAliasAnalysisTable()->FindOrCreateExtraLevOriginalSt(aliasElem->GetOriginalSt(), + tyIdx, fieldId); CHECK_FATAL(newOst != nullptr, "null ptr check"); if (newOst->GetIndex().idx == osym2Elem.size()) { osym2Elem.push_back(nullptr); @@ -127,8 +128,8 @@ AliasElem *AliasClass::CreateAliasElemsExpr(BaseNode &expr) { } case OP_iaddrof: { auto &iread = static_cast(expr); - AliasElem *ae = FindOrCreateExtraLevAliasElem(*iread.Opnd(0), iread.GetTyIdx(), iread.GetFieldID()); - return &FindOrCreateAliasElemOfAddrofOSt(ae->GetOriginalSt()); + AliasElem *aliasElem = FindOrCreateExtraLevAliasElem(*iread.Opnd(0), iread.GetTyIdx(), iread.GetFieldID()); + return &FindOrCreateAliasElemOfAddrofOSt(aliasElem->GetOriginalSt()); } case OP_malloc: case OP_gcmalloc: @@ -213,11 +214,12 @@ void AliasClass::ApplyUnionForCopies(StmtNode &stmt) { return; } case OP_iassign: { - auto &iass = static_cast(stmt); - AliasElem *rhsAliasElem = CreateAliasElemsExpr(*iass.Opnd(1)); - AliasElem *lhsAliasElem = FindOrCreateExtraLevAliasElem(*iass.Opnd(0), iass.GetTyIdx(), iass.GetFieldID()); + auto &iassignNode = static_cast(stmt); + AliasElem *rhsAliasElem = CreateAliasElemsExpr(*iassignNode.Opnd(1)); + AliasElem *lhsAliasElem = FindOrCreateExtraLevAliasElem(*iassignNode.Opnd(0), iassignNode.GetTyIdx(), + iassignNode.GetFieldID()); ASSERT(lhsAliasElem != nullptr, "aliaselem of lhs should not be null"); - ApplyUnionForDassignCopy(*lhsAliasElem, rhsAliasElem, *iass.Opnd(1)); + ApplyUnionForDassignCopy(*lhsAliasElem, rhsAliasElem, *iassignNode.Opnd(1)); return; } case OP_throw: { @@ -381,8 +383,8 @@ void AliasClass::UnionForNotAllDefsSeen() { continue; } for (size_t elemIdA : *(aliasElem->GetAssignSet())) { - AliasElem *aeA = id2Elem[elemIdA]; - if (aeA->IsNotAllDefsSeen() || aeA->IsNextLevNotAllDefsSeen()) { + AliasElem *aliasElemA = id2Elem[elemIdA]; + if (aliasElemA->IsNotAllDefsSeen() || aliasElemA->IsNextLevNotAllDefsSeen()) { for (unsigned int elemIdB : *(aliasElem->GetAssignSet())) { CollectRootIDOfNextLevelNodes(id2Elem[elemIdB]->GetOriginalSt(), rootIDOfNADSs); } @@ -637,8 +639,8 @@ void AliasClass::CollectMayUseFromNADS(std::set &mayUseOsts) { mayUseOsts.insert(¬AllDefsSeenAE->GetOriginalSt()); } else { for (unsigned int elemID : *(notAllDefsSeenAE->GetClassSet())) { - AliasElem *ae = id2Elem[elemID]; - mayUseOsts.insert(&ae->GetOriginalSt()); + AliasElem *aliasElem = id2Elem[elemID]; + mayUseOsts.insert(&aliasElem->GetOriginalSt()); } } } diff --git a/src/maple_me/src/me_bb_layout.cpp b/src/maple_me/src/me_bb_layout.cpp index e3665c04fe9c558960265a6c76e6010a6ed20f74..90a42de1501978f79f05aaf2a12c64ecaf0c86c2 100644 --- a/src/maple_me/src/me_bb_layout.cpp +++ b/src/maple_me/src/me_bb_layout.cpp @@ -180,7 +180,7 @@ bool BBLayout::BBCanBeMoved(const BB &fromBB, const BB &toAfterBB) const { // Return true if bb1 and bb2 has the branch conditon.such as // bb1 : brfalse (a > 3) bb2: brfalse (a > 3)/ brtrue (a <= 3) bool BBLayout::HasSameBranchCond(BB &bb1, BB &bb2) const { - if(func.GetIRMap() == nullptr) { + if (func.GetIRMap() == nullptr) { return false; } auto &meStmt1 = static_cast(bb1.GetMeStmts().back()); diff --git a/src/maple_me/src/me_cfg.cpp b/src/maple_me/src/me_cfg.cpp index 36cce7f93d8e408a51e06df3c7515e29ed3a64c0..4f1f0795ac46fd85440215ef9d87d69e61e9df81 100644 --- a/src/maple_me/src/me_cfg.cpp +++ b/src/maple_me/src/me_cfg.cpp @@ -59,13 +59,13 @@ void MeCFG::BuildMirCFG() { case kBBCondGoto: { StmtNode &lastStmt = bb->GetStmtNodes().back(); ASSERT(lastStmt.IsCondBr(), "runtime check error"); - /* succ[0] is fallthru, succ[1] is gotoBB */ + // succ[0] is fallthru, succ[1] is gotoBB auto rightNextBB = bIt; ++rightNextBB; CHECK_FATAL(rightNextBB != eIt, "null ptr check "); (*rightNextBB)->GetPred().push_back(bb); bb->GetSucc().push_back(*rightNextBB); - /* link goto */ + // link goto auto &gotoStmt = static_cast(lastStmt); LabelIdx lblIdx = gotoStmt.GetOffset(); BB *meBB = func.GetLabelBBAt(lblIdx); @@ -106,14 +106,14 @@ void MeCFG::BuildMirCFG() { break; } } - /* deal try blocks, add catch handler to try's succ */ + // deal try blocks, add catch handler to try's succ if (bb->GetAttributes(kBBAttrIsTry)) { auto it = func.GetBBTryNodeMap().find(bb); CHECK_FATAL(it != func.GetBBTryNodeMap().end(), "try bb without try"); StmtNode *currTry = it->second; const auto *tryNode = static_cast(currTry); bool hasFinallyHandler = false; - /* add exception handler bb */ + // add exception handler bb for (size_t j = 0; j < tryNode->GetOffsetsCount(); ++j) { LabelIdx labelIdx = tryNode->GetOffset(j); ASSERT(func.GetLabelBBIdMap().find(labelIdx) != func.GetLabelBBIdMap().end(), "runtime check error"); @@ -124,7 +124,7 @@ void MeCFG::BuildMirCFG() { if (meBB->GetAttributes(kBBAttrIsJSFinally) || meBB->GetAttributes(kBBAttrIsCatch)) { hasFinallyHandler = true; } - /* avoid redundant succ */ + // avoid redundant succ for (; si < bb->GetSucc().size(); ++si) { if (meBB == bb->GetSucc(si)) { break; @@ -135,7 +135,7 @@ void MeCFG::BuildMirCFG() { meBB->GetPred().push_back(bb); } } - /* if try block don't have finally catch handler, add common_exit_bb as its succ */ + // if try block don't have finally catch handler, add common_exit_bb as its succ if (!hasFinallyHandler) { if (!bb->GetAttributes(kBBAttrIsExit)) { bb->SetAttributes(kBBAttrIsExit); // may exit @@ -155,12 +155,10 @@ void MeCFG::BuildMirCFG() { // merge all blocks in entryBlocks for (BB *bb : entryBlocks) { func.GetCommonEntryBB()->GetSucc().push_back(bb); - } // merge all blocks in exitBlocks for (BB *bb : exitBlocks) { func.GetCommonExitBB()->GetPred().push_back(bb); - } } @@ -539,7 +537,7 @@ void MeCFG::UnreachCodeAnalysis(bool updatePhi) { BBId idx = bb->GetBBId(); if (!visitedBBs[idx] && !bb->GetAttributes(kBBAttrIsEntry)) { bb->SetAttributes(kBBAttrWontExit); - /* avoid redundant pred before adding to common_exit_bb's pred list */ + // avoid redundant pred before adding to common_exit_bb's pred list size_t pi = 0; for (; pi < func.GetCommonExitBB()->GetPred().size(); ++pi) { if (bb == func.GetCommonExitBB()->GetPred(pi)) { @@ -651,7 +649,7 @@ void MeCFG::Verify() const { continue; } ASSERT(bb->GetKind() != kBBUnknown, "runtime check error"); - /* verify succ[1] is goto bb */ + // verify succ[1] is goto bb if (bb->GetKind() == kBBCondGoto) { if (!bb->GetAttributes(kBBAttrIsTry) && !bb->GetAttributes(kBBAttrWontExit)) { ASSERT(bb->GetStmtNodes().rbegin().base().d() != nullptr, "runtime check error"); @@ -743,7 +741,7 @@ void MeCFG::Dump() const { } } -/* replace special char in FunctionName for output file */ +// replace special char in FunctionName for output file static void ReplaceFilename(std::string &fileName) { for (char &c : fileName) { if (c == ';' || c == '/' || c == '|') { @@ -812,25 +810,25 @@ void MeCFG::DumpToFileInStrs(std::ofstream &cfgFile) const { } } -/* generate dot file for cfg */ +// generate dot file for cfg void MeCFG::DumpToFile(const std::string &prefix, bool dumpInStrs) const { if (MeOption::noDot) { return; } std::ofstream cfgFile; - std::streambuf *coutBuf = LogInfo::MapleLogger().rdbuf(); /* keep original cout buffer */ + std::streambuf *coutBuf = LogInfo::MapleLogger().rdbuf(); // keep original cout buffer std::streambuf *buf = cfgFile.rdbuf(); LogInfo::MapleLogger().rdbuf(buf); const std::string &fileName = ConstructFileNameToDump(prefix); cfgFile.open(fileName.c_str(), std::ios::trunc); cfgFile << "digraph {\n"; cfgFile << " # /*" << func.GetName().c_str() << " (red line is exception handler)*/\n"; - /* dump edge */ + // dump edge auto eIt = func.valid_end(); for (auto bIt = func.valid_begin(); bIt != eIt; ++bIt) { auto *bb = *bIt; if (bIt == func.common_exit()) { - /* specical case for common_exit_bb */ + // specical case for common_exit_bb for (auto it = bb->GetPred().begin(); it != bb->GetPred().end(); ++it) { cfgFile << "BB" << (*it)->GetBBId() << " -> " << "BB" << bb->GetBBId() << "[style=dotted];\n"; @@ -852,7 +850,7 @@ void MeCFG::DumpToFile(const std::string &prefix, bool dumpInStrs) const { } } } - /* dump instruction in each BB */ + // dump instruction in each BB if (dumpInStrs) { DumpToFileInStrs(cfgFile); } diff --git a/src/maple_me/src/me_ir.cpp b/src/maple_me/src/me_ir.cpp index aae72090fe0af01b707665b8eb36cbc8f86cb923..05f1bf7f27f79fec4e43f2cf177dd6e2e82fcc2a 100644 --- a/src/maple_me/src/me_ir.cpp +++ b/src/maple_me/src/me_ir.cpp @@ -114,7 +114,7 @@ bool RegMeExpr::IsSameVariableValue(const VarMeExpr &expr) const { return true; } - if (GetMeOp() == kMeOpReg &&GetDefBy() == kDefByStmt && GetDefStmt()->GetOp() == OP_regassign) { + if (GetMeOp() == kMeOpReg && GetDefBy() == kDefByStmt && GetDefStmt()->GetOp() == OP_regassign) { auto *stmt = static_cast(GetDefStmt()); if (stmt->GetRHS() == &expr) { return true; @@ -861,8 +861,7 @@ MeExpr *IassignMeStmt::GetLHSRef(SSATab &ssaTab, bool excludeLocalRefVar) { MIRType *baseType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(lhsVar->GetTyIdx()); ASSERT(baseType != nullptr, "null ptr check"); auto *pType = static_cast(baseType)->GetPointedType(); - auto *structType = dynamic_cast(pType); - if (structType == nullptr) { + if (!pType->IsStructType()) { if (pType->GetKind() == kTypePointer) { if (lhsVar->GetFieldID() == 0) { if (static_cast(pType)->GetPrimType() != PTY_ref) { @@ -884,6 +883,7 @@ MeExpr *IassignMeStmt::GetLHSRef(SSATab &ssaTab, bool excludeLocalRefVar) { return nullptr; } } else { + auto *structType = static_cast(pType); if (lhsVar->GetFieldID() == 0) { return nullptr; // struct assign is not ref } diff --git a/src/maple_util/include/mpl_logging.h b/src/maple_util/include/mpl_logging.h index 5dc9374d7ac514b13141a6485994d5bd5ebdad0e..441c452b84c247f32261305079f515c59f30bc51 100644 --- a/src/maple_util/include/mpl_logging.h +++ b/src/maple_util/include/mpl_logging.h @@ -126,7 +126,6 @@ // instead of exit(1) so that the program will not completely exit, to allow the // developer to print stack trace and peruse the program environment at the point // of the assertion. - namespace maple { extern class LogInfo logInfo; extern class LogInfo &log; diff --git a/src/maple_util/include/name_mangler.h b/src/maple_util/include/name_mangler.h index 1ac9a706b22186b21abfdd9f407363236fc2c712..6d0c3131be9f8125528c858adb71c9ee1c14a136 100644 --- a/src/maple_util/include/name_mangler.h +++ b/src/maple_util/include/name_mangler.h @@ -89,6 +89,7 @@ static constexpr const char kMethodsInfoCompactPrefixStr[] = "__methods_infocomp static constexpr const char kFieldsInfoPrefixStr[] = "__fields_info__"; static constexpr const char kFieldsInfoCompactPrefixStr[] = "__fields_infocompact__"; static constexpr const char kFieldOffsetDataPrefixStr[] = "__fieldOffsetData__"; +static constexpr const char kMethodAddrDataPrefixStr[] = "__methodAddrData__"; static constexpr const char kRegJNITabPrefixStr[] = "__reg_jni_tab"; static constexpr const char kRegJNIFuncTabPrefixStr[] = "__reg_jni_func_tab"; static constexpr const char kReflectionStrtabPrefixStr[] = "__reflection_strtab"; diff --git a/src/maple_util/include/utils.h b/src/maple_util/include/utils.h index b80c125f59dee6468e93be0786a4b1f399f0c8d9..c0f9c78f9360b87c7603e191813d7043ef4dae42 100644 --- a/src/maple_util/include/utils.h +++ b/src/maple_util/include/utils.h @@ -18,7 +18,6 @@ #include "mpl_logging.h" namespace maple { namespace utils { - // Operations on char inline constexpr bool IsDigit(char c) { return (c >= '0' && c <= '9'); @@ -41,7 +40,6 @@ inline constexpr bool IsAlnum(char c) { } namespace __ToDigitImpl { - template struct TypeMax {}; diff --git a/src/mempool/include/maple_string.h b/src/mempool/include/maple_string.h index 54119e3b110c1358ac70aa28cd47808bd5f19c4d..bf95cb54c56bbd3bc3d2f66dbb5d4d6fcd24875c 100644 --- a/src/mempool/include/maple_string.h +++ b/src/mempool/include/maple_string.h @@ -73,11 +73,11 @@ class MapleString { if (str == nullptr) { return *this; } - size_t size = strlen(str); + unsigned int size = strlen(str); CHECK_FATAL(size <= UINT_MAX - 1, "str too large"); // if data is null, old_size = 0, else +1 - size_t oldSize = (data == nullptr) ? 0 : (dataLength + 1); + unsigned int oldSize = (data == nullptr) ? 0 : (dataLength + 1); if (oldSize < (1 + size)) { data = static_cast(memPool->Realloc(data, oldSize * sizeof(char), (1 + size) * sizeof(char))); } @@ -95,10 +95,10 @@ class MapleString { } MapleString &operator=(const std::string &str) { - size_t size = str.length(); + unsigned int size = str.length(); CHECK_FATAL(size <= UINT_MAX - 1, "str too large"); - size_t oldSize = (data == nullptr) ? 0 : (dataLength + 1); + unsigned int oldSize = (data == nullptr) ? 0 : (dataLength + 1); if (oldSize < (1 + size)) { data = static_cast(memPool->Realloc(data, oldSize * sizeof(char), (1 + size) * sizeof(char))); } @@ -118,10 +118,10 @@ class MapleString { if (&str == this) { return *this; } - size_t size = str.dataLength; + unsigned int size = str.dataLength; CHECK_FATAL(size <= UINT_MAX - 1, "str too large"); - int oldSize = (data == nullptr) ? 0 : (dataLength + 1); + unsigned int oldSize = (data == nullptr) ? 0 : (dataLength + 1); data = static_cast(memPool->Realloc(data, oldSize * sizeof(char), (1 + size) * sizeof(char))); CHECK_FATAL(data != nullptr, "null ptr check"); if (size == 0) { @@ -136,7 +136,7 @@ class MapleString { } MapleString &operator+=(const char c) { - int oldSize = (data == nullptr) ? 0 : (dataLength + 1); + unsigned int oldSize = (data == nullptr) ? 0 : (dataLength + 1); CHECK_FATAL(oldSize <= UINT_MAX - 1, "str too large"); data = static_cast(memPool->Realloc(data, oldSize * sizeof(char), (dataLength + 1 + 1) * sizeof(char))); @@ -150,8 +150,8 @@ class MapleString { if (str == nullptr) { return *this; } - size_t size = strlen(str); - int oldSize = (data == nullptr) ? 0 : (dataLength + 1); + unsigned int size = strlen(str); + unsigned int oldSize = (data == nullptr) ? 0 : (dataLength + 1); CHECK_FATAL(size <= UINT_MAX - oldSize, "str too large"); data = static_cast(memPool->Realloc(data, oldSize * sizeof(char), (dataLength + size + 1) * sizeof(char))); @@ -164,7 +164,7 @@ class MapleString { } MapleString &operator+=(const MapleString &str) { - int oldSize = (data == nullptr) ? 0 : (dataLength + 1); + unsigned int oldSize = (data == nullptr) ? 0 : (dataLength + 1); CHECK_FATAL(str.dataLength <= UINT_MAX - oldSize, "str too large"); data = static_cast( @@ -177,8 +177,8 @@ class MapleString { } MapleString &operator+=(const std::string &str) { - size_t size = str.length(); - int oldSize = (data == nullptr) ? 0 : (dataLength + 1); + unsigned int size = str.length(); + unsigned int oldSize = (data == nullptr) ? 0 : (dataLength + 1); CHECK_FATAL(size <= UINT_MAX - oldSize, "str too large"); data = static_cast(memPool->Realloc(data, oldSize * sizeof(char), (dataLength + size + 1) * sizeof(char))); @@ -231,20 +231,7 @@ class MapleString { return ::strlen(s); } - inline static char *NewData(MemPool *memPool, const char *source, size_t len) { - MIR_ASSERT(memPool && "Pointer to Mempool can not be nullptr"); - if (source == nullptr && len == 0) { - return nullptr; - } - char *str = static_cast(memPool->Malloc((len + 1) * sizeof(char))); - CHECK_FATAL(str != nullptr, "MemPool::Malloc failed"); - if (source != nullptr && len != 0) { - errno_t err = memcpy_s(str, len, source, len); - CHECK_FATAL(err == EOK, "memcpy_s failed"); - } - str[len] = 0; - return str; - } + inline static char *NewData(MemPool *memPool, const char *source, size_t len); friend bool operator==(const MapleString&, const MapleString&); friend bool operator==(const MapleString&, const char*); diff --git a/src/mpl2mpl/include/muid_replacement.h b/src/mpl2mpl/include/muid_replacement.h index dd2c0cef4e38330024d23ed27178b26728be3b17..51dc0e116832f211f68f7da164ab35b0f476bcdb 100644 --- a/src/mpl2mpl/include/muid_replacement.h +++ b/src/mpl2mpl/include/muid_replacement.h @@ -97,6 +97,8 @@ class MUIDReplacement : public FuncOptimizeImpl { void ReplaceStmts(); void GenerateGlobalRootList(); void CollectImplicitUndefClassInfo(StmtNode &stmt); + void ReplaceMethodMetaFuncAddr(MIRSymbol &funcSymbol, int64 index); + void ReplaceFieldMetaStaticAddr(MIRSymbol &mirSymbol, int64 index); void CollectFuncAndDataFromKlasses(); void CollectFuncAndDataFromGlobalTab(); void CollectFuncAndDataFromFuncList(); diff --git a/src/mpl2mpl/include/reflection_analysis.h b/src/mpl2mpl/include/reflection_analysis.h index 7e4c4b7850707f2f9f17e450120c05efaa4cfc7f..225e314f6b2b2302ced7cf5647f2fa934711df01 100644 --- a/src/mpl2mpl/include/reflection_analysis.h +++ b/src/mpl2mpl/include/reflection_analysis.h @@ -54,7 +54,7 @@ enum class ClassProperty : uint32 { enum class MethodProperty : uint32 { kVtabIndex, kDeclarclass, - kAddr, + kPaddrData, kMod, kMethodName, kSigName, @@ -68,7 +68,7 @@ enum class MethodProperty : uint32 { enum class MethodInfoCompact : uint32 { kVtabIndex, - kAddr + kPaddrData }; enum class FieldProperty : uint32 { @@ -162,7 +162,7 @@ class ReflectionAnalysis : public AnalysisResult { std::string GetArrayValue(const MapleVector &subElemVector); std::string GetAnnotationValue(const MapleVector &subElemVector, GStrIdx typeStrIdx); MIRSymbol *GenSuperClassMetaData(const Klass &klass, std::list superClassList); - void GenFieldOffsetData(const Klass &klass, std::vector> &fieldOffsetVector); + MIRSymbol *GenFieldOffsetData(const Klass &klass, std::pair &fieldInfo); MIRSymbol *GenFieldsMetaData(const Klass &klass); MIRSymbol *GenMethodsMetaData(const Klass &klass); MIRSymbol *GenFieldsMeta(const Klass &klass, std::vector> &fieldsVector, @@ -173,11 +173,14 @@ class ReflectionAnalysis : public AnalysisResult { std::unordered_map &baseNameMp, std::unordered_map &fullNameMp); void GenMethodMeta(const Klass &klass, MIRStructType &methodsInfoType, - MIRSymbol &funcSym, MIRAggConst &aggConst, + MIRSymbol &funcSym, MIRAggConst &aggConst, int idx, std::unordered_map &baseNameMp, std::unordered_map &fullNameMp); uint32 GetMethodModifier(const Klass &klass, const MIRFunction &func) const; uint32 GetMethodFlag(const MIRFunction &func) const; + void GenFieldOffsetConst(MIRAggConst &newConst, const Klass &klass, const MIRStructType &type, + std::pair &fieldInfo, uint32 metaFieldID); + MIRSymbol *GenMethodAddrData(const Klass &klass, const MIRSymbol &funcSym); static void GenMetadataType(MIRModule &mirModule); static MIRType *GetRefFieldType(); static TyIdx GenMetaStructType(MIRModule &mirModule, MIRStructType &metaType, const std::string &str); @@ -223,6 +226,7 @@ class ReflectionAnalysis : public AnalysisResult { MIRBuilder &mirBuilder; MapleVector classTab; int isLibcore = -1; + bool isLazyBindingOrDecouple = false; std::string reflectionMuidStr; static const char *klassPtrName; static TyIdx classMetadataTyIdx; @@ -233,6 +237,7 @@ class ReflectionAnalysis : public AnalysisResult { static TyIdx fieldsInfoCompactTyIdx; static TyIdx superclassMetadataTyIdx; static TyIdx fieldOffsetDataTyIdx; + static TyIdx methodAddrDataTyIdx; static std::string strTab; static std::unordered_map str2IdxMap; static std::string strTabStartHot; diff --git a/src/mpl2mpl/src/class_hierarchy.cpp b/src/mpl2mpl/src/class_hierarchy.cpp index 3b0af45410274a07f01b3d8cef1371a1a2bcaa89..6c8aa09274570d466e270a237b4713c172da2433 100644 --- a/src/mpl2mpl/src/class_hierarchy.cpp +++ b/src/mpl2mpl/src/class_hierarchy.cpp @@ -812,7 +812,8 @@ bool WKTypes::Util::MayRefString(const BaseNode &n, MIRType &type) { auto *pointType = static_cast(&type); MIRType *pointedType = pointType->GetPointedType(); if (pointedType == javaLangString || pointedType == javaLangObjectSerializable || - pointedType == javaLangComparable || pointedType == javaLangCharSequence || pointedType == javaLangObject) { + pointedType == javaLangComparable || + pointedType == javaLangCharSequence || pointedType == javaLangObject) { return true; } } diff --git a/src/mpl2mpl/src/muid_replacement.cpp b/src/mpl2mpl/src/muid_replacement.cpp index fe44ac61b3c2e7884529edda1f9366f77a33d0d5..18302b3d399f997b958ef1b9055cebb028067618 100644 --- a/src/mpl2mpl/src/muid_replacement.cpp +++ b/src/mpl2mpl/src/muid_replacement.cpp @@ -389,6 +389,22 @@ void MUIDReplacement::GenerateFuncDefTable() { } } +void MUIDReplacement::ReplaceMethodMetaFuncAddr(MIRSymbol &funcSymbol, int64 index) { + std::string symbolName = funcSymbol.GetName(); + MIRSymbol *methodAddrDataSt = GlobalTables::GetGsymTable().GetSymbolFromStrIdx( + GlobalTables::GetStrTable().GetStrIdxFromName(NameMangler::kMethodAddrDataPrefixStr + symbolName)); + CHECK_FATAL(methodAddrDataSt != nullptr, "methodAddrDataSt symbol is null."); + MIRConst *mirConst = methodAddrDataSt->GetKonst(); + MIRAggConst *aggConst = static_cast(mirConst); + MIRAggConst *agg = static_cast(aggConst->GetConstVecItem(0)); + MIRConst *elem = agg->GetConstVecItem(0); + if (elem->GetKind() == kConstAddrofFunc) { + MIRType &type = elem->GetType(); + MIRConst *constNode = GetMIRModule().GetMemPool()->New(index, type, 1); + agg->SetConstVecItem(0, *constNode); + } +} + void MUIDReplacement::GenerateDataDefTable() { // Use dataDefMap to make sure dataDefTab is sorted by an increasing order of MUID for (MIRSymbol *mirSymbol : dataDefSet) { @@ -461,6 +477,23 @@ void MUIDReplacement::GenerateDataDefTable() { } } +void MUIDReplacement::ReplaceFieldMetaStaticAddr(MIRSymbol &mirSymbol, int64 index) { + std::string symbolName = mirSymbol.GetName(); + MIRSymbol *fieldOffsetDataSt = GlobalTables::GetGsymTable().GetSymbolFromStrIdx( + GlobalTables::GetStrTable().GetStrIdxFromName(NameMangler::kFieldOffsetDataPrefixStr + symbolName)); + CHECK_FATAL(fieldOffsetDataSt != nullptr, "fieldOffsetDataSt symbol is null."); + MIRAggConst *aggConst = static_cast(fieldOffsetDataSt->GetKonst()); + MIRAggConst *agg = static_cast(aggConst->GetConstVecItem(0)); + MIRConst *elem = agg->GetConstVecItem(0); + CHECK_FATAL(elem->GetKind() == kConstAddrof, "static field must kConstAddrof."); + + MIRType &type = elem->GetType(); + int64 idx = index * 2 + 1; // add flag to indicate that it's def tab index for emit. + MIRConst *constNode = GetMIRModule().GetMemPool()->New(idx, type, 1); + agg->SetConstVecItem(0, *constNode); + (void)idx; +} + void MUIDReplacement::GenerateUnifiedUndefTable() { for (MIRFunction *mirFunc : funcUndefSet) { MUID muid = GetMUID(mirFunc->GetName()); diff --git a/src/mpl2mpl/src/reflection_analysis.cpp b/src/mpl2mpl/src/reflection_analysis.cpp index 68f0412fb81a2c7ed306dcb134fc5173afc2ebfd..12dc644cc3cf152c69ac2b3e573c7f98fa58a38e 100644 --- a/src/mpl2mpl/src/reflection_analysis.cpp +++ b/src/mpl2mpl/src/reflection_analysis.cpp @@ -34,7 +34,7 @@ using namespace maple; constexpr uint64 kMethodNotVirtual = 0x00000001; constexpr uint64 kMethodFinalize = 0x00000002; constexpr uint64 kMethodAbstract = 0x00000010; -constexpr uint64 kFieldReadOnly = 0x00000001; +constexpr uint64 kFieldOffsetIspOffset = 0x00000001; constexpr int kModPublic = 1; // 0x00000001 constexpr int kModPrivate = 2; // 0x00000002 @@ -102,6 +102,7 @@ constexpr char kFieldInfoTypeName[] = "__field_info__"; constexpr char kINFOAccessFlags[] = "INFO_access_flags"; constexpr char kSuperclassinfoStr[] = "superclassinfo"; constexpr char kFieldOffsetDataStr[] = "fieldOffsetData"; +constexpr char kMethodAddrDataStr[] = "methodAddrData"; constexpr char kAnnotationvalueStr[] = "annotationvalue"; constexpr char kMethodInfoTypeName[] = "__method_info__"; constexpr char kClinitSuffixStr[] = "_3Cclinit_3E_7C_28_29V"; @@ -112,6 +113,7 @@ constexpr char kMethodInVtabIndexStr[] = "method_in_vtab_index"; constexpr char kClassStateInitializedStr[] = "classStateInitialized"; constexpr char kSuperclassMetadataTypeName[] = "__superclass_meta__"; constexpr char kFieldOffsetDataTypeName[] = "__fieldOffsetDataType__"; +constexpr char kMethodAddrDataTypeName[] = "__methodAddrDataType__"; constexpr char kFieldInfoCompactTypeName[] = "__field_info_compact__"; constexpr char kMethodInfoCompactTypeName[] = "__method_info_compact__"; constexpr char kSuperclassOrComponentclassStr[] = "superclass_or_componentclass"; @@ -218,6 +220,7 @@ TyIdx ReflectionAnalysis::fieldsInfoTyIdx = TyIdx(0); TyIdx ReflectionAnalysis::fieldsInfoCompactTyIdx = TyIdx(0); TyIdx ReflectionAnalysis::superclassMetadataTyIdx = TyIdx(0); TyIdx ReflectionAnalysis::fieldOffsetDataTyIdx = TyIdx(0); +TyIdx ReflectionAnalysis::methodAddrDataTyIdx = TyIdx(0); TyIdx ReflectionAnalysis::invalidIdx = TyIdx(-1); uint32 ReflectionAnalysis::GetMethodModifier(const Klass &klass, const MIRFunction &func) const { @@ -728,7 +731,7 @@ uint32 ReflectionAnalysis::GetMethodFlag(const MIRFunction &func) const { } void ReflectionAnalysis::GenMethodMeta(const Klass &klass, MIRStructType &methodsInfoType, - MIRSymbol &funcSym, MIRAggConst &aggConst, + MIRSymbol &funcSym, MIRAggConst &aggConst, int idx, std::unordered_map &baseNameMp, std::unordered_map &fullNameMp) { MIRFunction &func = *funcSym.GetFunction(); @@ -740,8 +743,18 @@ void ReflectionAnalysis::GenMethodMeta(const Klass &klass, MIRStructType &method // @declaringclass MIRSymbol *dklassSt = GetOrCreateSymbol(CLASSINFO_PREFIX_STR + func.GetBaseClassName(), classMetadataTyIdx); mirBuilder.AddAddrofFieldConst(methodsInfoType, newConst, fieldID++, *dklassSt); - // @addr : Function address - mirBuilder.AddAddroffuncFieldConst(methodsInfoType, newConst, fieldID++, funcSym); + // @addr : Function address or point function addr if lazyBinding or decouple + if (isLazyBindingOrDecouple) { + MIRSymbol *methodAddrSt = GenMethodAddrData(klass, funcSym); + if (methodAddrSt != nullptr) { + mirBuilder.AddAddrofFieldConst(methodsInfoType, newConst, fieldID++, *methodAddrSt); + } else { + mirBuilder.AddIntFieldConst(methodsInfoType, newConst, fieldID++, 0); + } + } else { + mirBuilder.AddAddroffuncFieldConst(methodsInfoType, newConst, fieldID++, funcSym); + } + // @modifier uint32 mod = GetMethodModifier(klass, func); mirBuilder.AddIntFieldConst(methodsInfoType, newConst, fieldID++, mod); @@ -785,10 +798,11 @@ MIRSymbol *ReflectionAnalysis::GenMethodsMeta(const Klass &klass, MIRArrayType &arrayType = *GlobalTables::GetTypeTable().GetOrCreateArrayType(methodsInfoType, arraySize); MIRAggConst *aggConst = mirModule->GetMemPool()->New(*mirModule, arrayType); ASSERT(aggConst != nullptr, "null ptr check!"); + int idx = 0; for (auto &methodInfo : methodInfoVec) { MIRSymbol *funcSym = GlobalTables::GetGsymTable().GetSymbolFromStidx(methodInfo.first->first.Idx()); reflectionMuidStr += funcSym->GetName(); - GenMethodMeta(klass, methodsInfoType, *funcSym, *aggConst, baseNameMp, fullNameMp); + GenMethodMeta(klass, methodsInfoType, *funcSym, *aggConst, idx++, baseNameMp, fullNameMp); } MIRSymbol *methodsArraySt = GetOrCreateSymbol(NameMangler::kMethodsInfoPrefixStr + klass.GetKlassName(), arrayType.GetTypeIndex(), true); @@ -797,6 +811,27 @@ MIRSymbol *ReflectionAnalysis::GenMethodsMeta(const Klass &klass, return methodsArraySt; } +MIRSymbol *ReflectionAnalysis::GenMethodAddrData(const Klass &klass, const MIRSymbol &funcSym) { + MIRModule &module = *mirModule; + MIRStructType &methodAddrType = + static_cast(*GlobalTables::GetTypeTable().GetTypeFromTyIdx(methodAddrDataTyIdx)); + MIRArrayType &methodAddrArrayType = *GlobalTables::GetTypeTable().GetOrCreateArrayType(methodAddrType, 1); + MIRAggConst *aggconst = module.GetMemPool()->New(module, methodAddrArrayType); + MIRAggConst *newconst = module.GetMemPool()->New(module, methodAddrType); + MIRFunction *func = funcSym.GetFunction(); + MIRSymbol *methodAddrSt = nullptr; + // skip abstract func. + if (!func->IsAbstract()) { + mirBuilder.AddAddroffuncFieldConst(methodAddrType, *newconst, 1, funcSym); + aggconst->GetConstVec().push_back(newconst); + methodAddrSt = GetOrCreateSymbol(NameMangler::kMethodAddrDataPrefixStr + func->GetName(), + methodAddrArrayType.GetTypeIndex(), true); + methodAddrSt->SetStorageClass(kScFstatic); + methodAddrSt->SetKonst(aggconst); + } + return methodAddrSt; +} + MIRSymbol *ReflectionAnalysis::GenMethodsMetaData(const Klass &klass) { MIRClassType *classType = klass.GetMIRClassType(); if (classType == nullptr || classType->GetMethods().empty()) { @@ -816,51 +851,66 @@ MIRSymbol *ReflectionAnalysis::GenMethodsMetaData(const Klass &klass) { MIRSymbol *methodsArraySt = GenMethodsMeta(klass, methodinfoVec, baseNameMp, fullNameMp); return methodsArraySt; } +void ReflectionAnalysis::GenFieldOffsetConst(MIRAggConst &newConst, const Klass &klass, + const MIRStructType &type, std::pair &fieldInfo, + uint32 metaFieldID) { + bool isStaticField = (fieldInfo.second == -1); + FieldPair fieldP = fieldInfo.first; + TyIdx fieldTyidx = fieldP.second.first; + std::string originFieldname = GlobalTables::GetStrTable().GetStringFromStrIdx(fieldP.first); + if (isStaticField) { + // Offset of the static field, we fill the global var address. + const GStrIdx stridx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName( + GlobalTables::GetStrTable().GetStringFromStrIdx(fieldP.first)); + MIRSymbol *gvarSt = GetSymbol(stridx, fieldTyidx); + if (gvarSt == nullptr) { + // If this static field is not used, the symbol will not be generated, + // so we just generate a weak one here. + gvarSt = CreateSymbol(stridx, fieldTyidx); + gvarSt->SetAttr(ATTR_weak); + gvarSt->SetAttr(ATTR_static); + } + mirBuilder.AddAddrofFieldConst(type, newConst, metaFieldID, *gvarSt); + } else { + // Offset of the instance field, we fill the index of fields here and let CG to fill in. + MIRClassType *mirClassType = klass.GetMIRClassType(); + ASSERT(mirClassType != nullptr, "GetMIRClassType() returns null"); + FieldID fldID = mirBuilder.GetStructFieldIDFromNameAndTypeParentFirstFoundInChild( + *mirClassType, originFieldname.c_str(), fieldP.second.first); + // set LSB 0, and set LSB 1 in muid_replacement + fldID = fldID * 2; + mirBuilder.AddIntFieldConst(type, newConst, metaFieldID, fldID); + } +} -void ReflectionAnalysis::GenFieldOffsetData(const Klass &klass, - std::vector> &fieldOffsetVector) { - size_t size = fieldOffsetVector.size(); +MIRSymbol *ReflectionAnalysis::GenFieldOffsetData(const Klass &klass, std::pair &fieldInfo) { MIRModule &module = *mirModule; auto &fieldOffsetType = static_cast(*GlobalTables::GetTypeTable().GetTypeFromTyIdx(fieldOffsetDataTyIdx)); - MIRArrayType &fieldOffsetArrayType = *GlobalTables::GetTypeTable().GetOrCreateArrayType(fieldOffsetType, size); + MIRArrayType &fieldOffsetArrayType = *GlobalTables::GetTypeTable().GetOrCreateArrayType(fieldOffsetType, 1); MIRAggConst *aggConst = module.GetMemPool()->New(module, fieldOffsetArrayType); - ASSERT(aggConst != nullptr, "null ptr check!"); - for (auto &fieldinfo : fieldOffsetVector) { - MIRAggConst *newConst = module.GetMemPool()->New(module, fieldOffsetType); - ASSERT(newConst != nullptr, "null ptr check!"); - bool staticfield = (fieldinfo.second == -1); - FieldPair fieldP = fieldinfo.first; - TyIdx fieldTyidx = fieldP.second.first; - std::string originFieldname = GlobalTables::GetStrTable().GetStringFromStrIdx(fieldP.first); - if (staticfield) { - // Offset of the static field, we fill the global var address. - const GStrIdx stridx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName( - GlobalTables::GetStrTable().GetStringFromStrIdx(fieldP.first)); - MIRSymbol *gvarSt = GetSymbol(stridx, fieldTyidx); - if (gvarSt == nullptr) { - // If this static field is not used, the symbol will not be generated, - // so we just generate a weak one here. - gvarSt = CreateSymbol(stridx, fieldTyidx); - gvarSt->SetAttr(ATTR_weak); - gvarSt->SetAttr(ATTR_static); - } - mirBuilder.AddAddrofFieldConst(fieldOffsetType, *newConst, 1, *gvarSt); - } else { - // Offset of the instance field, we fill the index of fields here and let CG to fill in. - MIRClassType *mirClassType = klass.GetMIRClassType(); - ASSERT(mirClassType != nullptr, "GetMIRClassType() returns null"); - FieldID fldid = mirBuilder.GetStructFieldIDFromNameAndTypeParentFirstFoundInChild( - *mirClassType, originFieldname.c_str(), fieldP.second.first); - mirBuilder.AddIntFieldConst(fieldOffsetType, *newConst, 1, fldid); - } - aggConst->GetConstVec().push_back(newConst); + + MIRAggConst *newConst = module.GetMemPool()->New(module, fieldOffsetType); + constexpr uint32_t fieldId = 1; + GenFieldOffsetConst(*newConst, klass, fieldOffsetType, fieldInfo, fieldId); + aggConst->GetConstVec().push_back(newConst); + + FieldPair fieldP = fieldInfo.first; + std::string originFieldname = GlobalTables::GetStrTable().GetStringFromStrIdx(fieldP.first); + std::string fieldOffsetSymbolName = NameMangler::kFieldOffsetDataPrefixStr; + bool isStaticField = (fieldInfo.second == -1); + if (isStaticField) { + fieldOffsetSymbolName += originFieldname; + } else { + MIRClassType *mirClassType = klass.GetMIRClassType(); + FieldID fldID = mirBuilder.GetStructFieldIDFromNameAndTypeParentFirstFoundInChild( + *mirClassType, originFieldname.c_str(), fieldP.second.first); + fieldOffsetSymbolName += klass.GetKlassName() + "_FieldID_" + std::to_string(fldID); } - MIRSymbol *fieldsOffsetArraySt = GetOrCreateSymbol(NameMangler::kFieldOffsetDataPrefixStr + klass.GetKlassName(), - fieldOffsetArrayType.GetTypeIndex(), true); - // Direct access to fieldoffset is only possible within a .so. - fieldsOffsetArraySt->SetStorageClass(kScFstatic); - fieldsOffsetArraySt->SetKonst(aggConst); + MIRSymbol *fieldsOffsetSt = GetOrCreateSymbol(fieldOffsetSymbolName, fieldOffsetArrayType.GetTypeIndex(), true); + fieldsOffsetSt->SetStorageClass(kScFstatic); + fieldsOffsetSt->SetKonst(aggConst); + return fieldsOffsetSt; } MIRSymbol *ReflectionAnalysis::GenSuperClassMetaData(const Klass &klass, std::list superClassList) { @@ -907,17 +957,23 @@ void ReflectionAnalysis::GenFieldMeta(const Klass &klass, MIRStructType &fieldsI MIRAggConst *newConst = mirModule->GetMemPool()->New(*mirModule, fieldsInfoType); ASSERT(newConst != nullptr, "null ptr check!"); uint32 fieldID = 1; + uint16 hash = GetFieldHash(fieldHashVec, fieldP); + uint16 flag = (hash << kNoHashBits); // Hash 10 bit. + + // @offset or pOffset + if (isLazyBindingOrDecouple) { + flag |= kFieldOffsetIspOffset; + MIRSymbol *fieldsOffsetSt = GenFieldOffsetData(klass, fieldInfo); + mirBuilder.AddAddrofFieldConst(fieldsInfoType, *newConst, fieldID++, *fieldsOffsetSt); + } else { + GenFieldOffsetConst(*newConst, klass, fieldsInfoType, fieldInfo, fieldID++); + } - // @pOffset: - mirBuilder.AddIntFieldConst(fieldsInfoType, *newConst, fieldID++, idx); // @modifier FieldAttrs fa = fieldP.second.second; uint32 modifier = GetFieldModifier(fa); mirBuilder.AddIntFieldConst(fieldsInfoType, *newConst, fieldID++, modifier); // @flag - uint16 hash = GetFieldHash(fieldHashVec, fieldP); - uint16 flag = (hash << kNoHashBits); // Hash 10 bit. - flag |= kFieldReadOnly; mirBuilder.AddIntFieldConst(fieldsInfoType, *newConst, fieldID++, flag); // @index mirBuilder.AddIntFieldConst(fieldsInfoType, *newConst, fieldID++, idx); @@ -946,7 +1002,7 @@ void ReflectionAnalysis::GenFieldMeta(const Klass &klass, MIRStructType &fieldsI } MIRSymbol *ReflectionAnalysis::GenFieldsMeta(const Klass &klass, std::vector> &fieldsVector, - std::vector> &fieldHashvec) { + std::vector> &fieldHashVec) { size_t size = fieldsVector.size(); auto &fieldsInfoType = static_cast(*GlobalTables::GetTypeTable().GetTypeFromTyIdx(fieldsInfoTyIdx)); @@ -963,7 +1019,7 @@ MIRSymbol *ReflectionAnalysis::GenFieldsMeta(const Klass &klass, std::vectorGetName(); - GenFieldMeta(klass, fieldsInfoType, fieldInfo, *aggConst, idx++, fieldHashvec); + GenFieldMeta(klass, fieldsInfoType, fieldInfo, *aggConst, idx++, fieldHashVec); } MIRSymbol *fieldsArraySt = GetOrCreateSymbol(NameMangler::kFieldsInfoPrefixStr + klass.GetKlassName(), arraytype->GetTypeIndex(), true); @@ -1017,7 +1073,6 @@ MIRSymbol *ReflectionAnalysis::GenFieldsMetaData(const Klass &klass) { } ASSERT(i == size, "In class %s: %d fields seen, BUT %d fields declared", klass.GetKlassName().c_str(), i, size); MIRSymbol *fieldsArraySt = GenFieldsMeta(klass, fieldinfoVec, fieldHashvec); - GenFieldOffsetData(klass, fieldinfoVec); return fieldsArraySt; } @@ -1034,7 +1089,7 @@ void ReflectionAnalysis::ConvertMapleClassName(const std::string &mplClassName, void ReflectionAnalysis::AppendValueByType(std::string &annoArr, const MIRPragmaElement &elem) { std::ostringstream oss; std::string tmp; - switch(elem.GetType()) { + switch (elem.GetType()) { case kValueInt: case kValueByte: case kValueShort: @@ -1151,7 +1206,7 @@ std::string ReflectionAnalysis::GetAnnoValueNoArray(const MIRPragmaElement &anno case kValueArray: annoArray += GetArrayValue(annoElem.GetSubElemVec()); break; - case kValueAnnotation : + case kValueAnnotation: annoArray += GetAnnotationValue(annoElem.GetSubElemVec(), annoElem.GetTypeStrIdx()); break; default: { @@ -1173,13 +1228,13 @@ void ReflectionAnalysis::GenAnnotation(std::map &idxNumMap, std::strin int annoNum = 0; std::string cmpString = ""; for (MIRPragma *prag : classType.GetPragmaVec()) { - cmpString = paragKind == kPragmaVar ? NameMangler::DecodeName(GlobalTables::GetStrTable().GetStringFromStrIdx( + cmpString = (paragKind == kPragmaVar) ? NameMangler::DecodeName(GlobalTables::GetStrTable().GetStringFromStrIdx( prag->GetStrIdx())) : GlobalTables::GetStrTable().GetStringFromStrIdx(prag->GetStrIdx()); bool validTypeFlag = false; if (prag->GetTyIdxEx() == fieldTypeIdx || fieldTypeIdx == invalidIdx) { validTypeFlag = true; } - if (prag->GetKind() == paragKind && paragName == cmpString && validTypeFlag) { + if ((prag->GetKind() == paragKind) && (cmpString == paragName) && validTypeFlag) { const MapleVector &elemVector = prag->GetElementVector(); MIRSymbol *classInfo = GlobalTables::GetGsymTable().GetSymbolFromStrIdx( GlobalTables::GetTypeTable().GetTypeFromTyIdx(prag->GetTyIdx())->GetNameStrIdx()); @@ -1540,9 +1595,7 @@ TyIdx ReflectionAnalysis::GenMetaStructType(MIRModule &mirModule, MIRStructType // Global? mirModule.GetTypeNameTab()->SetGStrIdxToTyIdx(strIdx, tyIdx); mirModule.PushbackTypeDefOrder(strIdx); - const size_t globalTypeTableSize = GlobalTables::GetTypeTable().GetTypeTable().size(); - CHECK_FATAL(globalTypeTableSize > tyIdx.GetIdx(), "null ptr check"); - if (GlobalTables::GetTypeTable().GetTypeTable()[tyIdx.GetIdx()]->GetNameStrIdx() == 0) { + if (GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx.GetIdx())->GetNameStrIdx() == 0) { GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx)->SetNameStrIdx(strIdx); } return tyIdx; @@ -1662,6 +1715,10 @@ void ReflectionAnalysis::GenMetadataType(MIRModule &mirModule) { MIRStructType fieldOffsetDataType(kTypeStruct); GlobalTables::GetTypeTable().AddFieldToStructType(fieldOffsetDataType, kFieldOffsetDataStr, *typeVoidPtr); fieldOffsetDataTyIdx = GenMetaStructType(mirModule, fieldOffsetDataType, kFieldOffsetDataTypeName); + // MethodAddrDataType. + MIRStructType methodAddrDataType(kTypeStruct); + GlobalTables::GetTypeTable().AddFieldToStructType(methodAddrDataType, kMethodAddrDataStr, *typeVoidPtr); + methodAddrDataTyIdx = GenMetaStructType(mirModule, methodAddrDataType, kMethodAddrDataTypeName); } void ReflectionAnalysis::GenClassHashMetaData() { diff --git a/src/mpl2mpl/src/vtable_impl.cpp b/src/mpl2mpl/src/vtable_impl.cpp index 93eb360e52651bc0588e6eb37f7daf702116ab3a..b4ce70be27bfe289e8457cb0cb91a98ab1c42b53 100644 --- a/src/mpl2mpl/src/vtable_impl.cpp +++ b/src/mpl2mpl/src/vtable_impl.cpp @@ -18,7 +18,6 @@ #include "reflection_analysis.h" // This phase is mainly to lower interfacecall into icall - namespace { #ifdef USE_32BIT_REF constexpr char kInterfaceMethod[] = "MCC_getFuncPtrFromItab";