diff --git a/build/config.gni b/build/config.gni index 7a75ad36047c9a672ce4ec6cc7de194829a8f7ed..f6ce51249f1f4abece5ebb9f0d23eabc69a0e79f 100644 --- a/build/config.gni +++ b/build/config.gni @@ -14,6 +14,16 @@ # # Toolchain setup +if (OLD_OS == "1") { + CLANG_PATH = "${MAPLE_ROOT}/tools/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04" +} else { + CLANG_PATH = "/usr" +} +LLVMINC = "${CLANG_PATH}/include" +LLVMLIBDIR = "${CLANG_PATH}/lib" +CFE_SRC_DIR = "${MAPLE_ROOT}/../third-party/cfe-8.0.0.src" +CFE_SRC_PATH = "${MAPLE_ROOT}/../ThirdParty/cfe-8.0.0.src" + ANDROID_GCC_PATH = "${MAPLE_ROOT}/tools/gcc" ANDROID_CLANG_PATH = "${MAPLE_ROOT}/tools/clang-r353983c" GCC_LINARO_PATH = "${MAPLE_ROOT}/tools/gcc-linaro-7.5.0" diff --git a/src/mapleall/bin/dex2mpl b/src/mapleall/bin/dex2mpl index f2b151efabab8dc18f36da84b874676ace6478f2..e862ba00779c0fdcd0f611caf3303455f2913be4 100755 Binary files a/src/mapleall/bin/dex2mpl and b/src/mapleall/bin/dex2mpl differ diff --git a/src/mapleall/bin/dex2mpl_android b/src/mapleall/bin/dex2mpl_android index 554fbcdbd929f094880512605450cac414dba35d..b29b8ebeb9af2ecc9e90b13bb0de8d0e35fb8b50 100755 Binary files a/src/mapleall/bin/dex2mpl_android and b/src/mapleall/bin/dex2mpl_android differ diff --git a/src/mapleall/bin/jbc2mpl b/src/mapleall/bin/jbc2mpl index 69d6ff51931924a2ae33192fd5497dc381cfe54d..14bb3a6a71865b0e8ca6bf2ac047c99d52136fe3 100755 Binary files a/src/mapleall/bin/jbc2mpl and b/src/mapleall/bin/jbc2mpl differ diff --git a/src/mapleall/maple_driver/include/compiler.h b/src/mapleall/maple_driver/include/compiler.h index 364816f26fb799b44e3cb8ce30420fc9ac3dba3e..542919fd33246d62e125a13834b4a336519ae848 100644 --- a/src/mapleall/maple_driver/include/compiler.h +++ b/src/mapleall/maple_driver/include/compiler.h @@ -124,12 +124,15 @@ class MplcgCompiler : public Compiler { ~MplcgCompiler() = default; ErrorCode Compile(MplOptions &options, std::unique_ptr &theModule) override; - void PrintCommand(const MplOptions &options) const override; + void PrintMplcgCommand(const MplOptions &options, const MIRModule &md) const; + void SetOutputFileName(const MplOptions &options, const MIRModule &md); + std::string GetInputFile(const MplOptions &options, const MIRModule &md) const; private: - std::string GetInputFileName(const MplOptions &options) const override; DefaultOption GetDefaultOptions(const MplOptions &options) const override; ErrorCode MakeCGOptions(const MplOptions &options); const std::string &GetBinName() const override; + std::string baseName; + std::string outputFile; }; } // namespace maple #endif // MAPLE_DRIVER_INCLUDE_COMPILER_H diff --git a/src/mapleall/maple_driver/include/driver_runner.h b/src/mapleall/maple_driver/include/driver_runner.h index 854de244256f744ee22dbb9918d2964ef549631c..6643748655572742a503d7fc5a02a2b90f98a16e 100644 --- a/src/mapleall/maple_driver/include/driver_runner.h +++ b/src/mapleall/maple_driver/include/driver_runner.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -112,6 +112,7 @@ class DriverRunner final { bool timePhases = false; bool genVtableImpl = false; bool genMeMpl = false; + bool hasDebugFlag = false; std::string printOutExe = ""; std::string baseName; std::string outputFile; diff --git a/src/mapleall/maple_driver/src/driver_runner.cpp b/src/mapleall/maple_driver/src/driver_runner.cpp index faec5eef0e316293800df7a9e46484e48b012504..6cf865b07e479de6360a828a2a9babc1df3d6465 100644 --- a/src/mapleall/maple_driver/src/driver_runner.cpp +++ b/src/mapleall/maple_driver/src/driver_runner.cpp @@ -89,8 +89,14 @@ ErrorCode DriverRunner::Run() { outputFile.append(GetPostfix()); if (mpl2mplOptions != nullptr || meOptions != nullptr) { std::string vtableImplFile = originBaseName; - vtableImplFile.append(".VtableImpl.mpl"); - originBaseName.append(".VtableImpl"); + std::string postFix = ""; + if (theModule->GetSrcLang() == kSrcLangC) { + postFix = ".me"; + } else { + postFix = ".VtableImpl"; + } + vtableImplFile.append(postFix + ".mpl"); + originBaseName.append(postFix); ProcessMpl2mplAndMePhases(outputFile, vtableImplFile); } ProcessCGPhase(outputFile, originBaseName); @@ -184,7 +190,7 @@ ErrorCode DriverRunner::ParseInput() const { LogInfo::MapleLogger() << "Starting parse " << inputInline << '\n'; bool parsed = parser.ParseInlineFuncBody(optFile); if (!parsed) { - parser.EmitError(outputFile); + parser.EmitError(actualInput); } optFile.close(); } @@ -197,6 +203,10 @@ ErrorCode DriverRunner::ParseInput() const { void DriverRunner::ProcessMpl2mplAndMePhases(const std::string &outputFile, const std::string &vtableImplFile) const { CHECK_MODULE(); theMIRModule = theModule; + if (hasDebugFlag) { + std::cout << "set up debug info " << std::endl; + theMIRModule->GetDbgInfo()->BuildDebugInfo(); + } if (mpl2mplOptions != nullptr || meOptions != nullptr) { LogInfo::MapleLogger() << "Processing maplecomb" << '\n'; diff --git a/src/mapleall/maple_driver/src/mplcg_compiler.cpp b/src/mapleall/maple_driver/src/mplcg_compiler.cpp index 6c27c878d790831c0834807cba8d98f2be26d380..f3590fb34f3ecc5a3673a0cfb2b7570dc475ed45 100644 --- a/src/mapleall/maple_driver/src/mplcg_compiler.cpp +++ b/src/mapleall/maple_driver/src/mplcg_compiler.cpp @@ -45,7 +45,7 @@ const std::string &MplcgCompiler::GetBinName() const { return kBinNameMplcg; } -std::string MplcgCompiler::GetInputFileName(const MplOptions &options) const { +std::string MplcgCompiler::GetInputFile(const MplOptions &options, const MIRModule &md) const { if (!options.GetRunningExes().empty()) { if (options.GetRunningExes()[0] == kBinNameMplcg) { return options.GetInputFiles(); @@ -57,9 +57,22 @@ std::string MplcgCompiler::GetInputFileName(const MplOptions &options) const { if (idx != std::string::npos) { outputName = options.GetOutputName().substr(0, idx); } + if (md.GetSrcLang() == kSrcLangC) { + return options.GetOutputFolder() + outputName + ".me.mpl"; + } return options.GetOutputFolder() + outputName + ".VtableImpl.mpl"; } -void MplcgCompiler::PrintCommand(const MplOptions &options) const { + +void MplcgCompiler::SetOutputFileName(const MplOptions &options, const MIRModule &md) { + if (md.GetSrcLang() == kSrcLangC) { + baseName = options.GetOutputFolder() + options.GetOutputName(); + } else { + baseName = options.GetOutputFolder() + FileUtils::GetFileName(GetInputFile(options, md), false); + } + outputFile = baseName + ".s"; +} + +void MplcgCompiler::PrintMplcgCommand(const MplOptions &options, const MIRModule &md) const { std::string runStr = "--run="; std::string optionStr = "--option=\""; std::string connectSym = ""; @@ -76,7 +89,7 @@ void MplcgCompiler::PrintCommand(const MplOptions &options) const { } optionStr += "\""; LogInfo::MapleLogger() << "Starting:" << options.GetExeFolder() << "maple " << runStr << " " << optionStr - << " --infile " << GetInputFileName(options) << '\n'; + << " --infile " << GetInputFile(options, md) << '\n'; } ErrorCode MplcgCompiler::MakeCGOptions(const MplOptions &options) { @@ -112,9 +125,7 @@ ErrorCode MplcgCompiler::Compile(MplOptions &options, std::unique_ptr if (ret != kErrorNoError) { return kErrorCompileFail; } - std::string fileName = GetInputFileName(options); - std::string baseName = options.GetOutputFolder() + FileUtils::GetFileName(fileName, false); - std::string output = baseName + ".s"; + std::string fileName = GetInputFile(options, *theModule); MemPool *optMp = memPoolCtrler.NewMemPool("maplecg mempool"); bool fileRead = true; if (theModule == nullptr) { @@ -154,16 +165,16 @@ ErrorCode MplcgCompiler::Compile(MplOptions &options, std::unique_ptr LogInfo::MapleLogger() << "Mplcg Parser consumed " << timer.ElapsedMilliseconds() << "ms\n"; CgFuncPhaseManager::parserTime = timer.ElapsedMicroseconds(); } - + SetOutputFileName(options, *theModule); LogInfo::MapleLogger() << "Starting mplcg\n"; DriverRunner runner(theModule.get(), options.GetSelectedExes(), options.GetInputFileType(), fileName, optMp, fileRead, options.HasSetTimePhases()); if (options.HasSetDebugFlag()) { - PrintCommand(options); + PrintMplcgCommand(options, *theModule); } runner.SetPrintOutExe(kBinNameMplcg); runner.SetCGInfo(&cgOption, fileName); - runner.ProcessCGPhase(output, baseName); + runner.ProcessCGPhase(outputFile, baseName); memPoolCtrler.DeleteMemPool(optMp); return kErrorNoError; diff --git a/src/mapleall/maple_ir/include/debug_info.h b/src/mapleall/maple_ir/include/debug_info.h index 4ea0aef5d052b824ae2df8efe36027b66870ee5e..5a47d80d5ff24908726ffb9ea7a186428b7caafd 100644 --- a/src/mapleall/maple_ir/include/debug_info.h +++ b/src/mapleall/maple_ir/include/debug_info.h @@ -91,7 +91,7 @@ class DBGDieAttr; class DBGExpr { public: - DBGExpr(MIRModule *m) : dwOp(0), value(kDbgDefaultVal), opnds(m->GetMPAllocator().Adapter()) {} + explicit DBGExpr(MIRModule *m) : dwOp(0), value(kDbgDefaultVal), opnds(m->GetMPAllocator().Adapter()) {} DBGExpr(MIRModule *m, DwOp op) : dwOp(op), value(kDbgDefaultVal), opnds(m->GetMPAllocator().Adapter()) {} @@ -138,7 +138,7 @@ class DBGExpr { class DBGExprLoc { public: - DBGExprLoc(MIRModule *m) : module(m), exprVec(m->GetMPAllocator().Adapter()), symLoc(nullptr) { + explicit DBGExprLoc(MIRModule *m) : module(m), exprVec(m->GetMPAllocator().Adapter()), symLoc(nullptr) { simpLoc = m->GetMemPool()->New(module); } @@ -200,7 +200,7 @@ class DBGExprLoc { class DBGDieAttr { public: uint32 SizeOf(DBGDieAttr *attr); - DBGDieAttr(DBGDieKind k) : dieKind(k), dwAttr(DW_AT_deleted), dwForm(DW_FORM_GNU_strp_alt) { + explicit DBGDieAttr(DBGDieKind k) : dieKind(k), dwAttr(DW_AT_deleted), dwForm(DW_FORM_GNU_strp_alt) { value.u = kDbgDefaultVal; } @@ -527,28 +527,28 @@ class DBGAbbrevEntryVec { class DebugInfo { public: DebugInfo(MIRModule *m) - : module(m), - compUnit(nullptr), - dummyTypeDie(nullptr), - lexer(nullptr), - maxId(1), - builder(nullptr), - mplSrcIdx(0), - debugInfoLength(0), - compileMsg(nullptr), - parentDieStack(m->GetMPAllocator().Adapter()), - idDieMap(std::less(), m->GetMPAllocator().Adapter()), - abbrevVec(m->GetMPAllocator().Adapter()), - tagAbbrevMap(std::less(), m->GetMPAllocator().Adapter()), - tyIdxDieIdMap(std::less(), m->GetMPAllocator().Adapter()), - stridxDieIdMap(std::less(), m->GetMPAllocator().Adapter()), - funcDefStrIdxDieIdMap(std::less(), m->GetMPAllocator().Adapter()), - typeDefTyIdxMap(std::less(), m->GetMPAllocator().Adapter()), - pointedPointerMap(std::less(), m->GetMPAllocator().Adapter()), - funcLstrIdxDieIdMap(std::less(), m->GetMPAllocator().Adapter()), - funcLstrIdxLabIdxMap(std::less(), m->GetMPAllocator().Adapter()), - strps(std::less(), m->GetMPAllocator().Adapter()) { - // valid entry starting from index 1 as abbrevid starting from 1 as well + : module(m), + compUnit(nullptr), + dummyTypeDie(nullptr), + lexer(nullptr), + maxId(1), + builder(nullptr), + mplSrcIdx(0), + debugInfoLength(0), + compileMsg(nullptr), + parentDieStack(m->GetMPAllocator().Adapter()), + idDieMap(std::less(), m->GetMPAllocator().Adapter()), + abbrevVec(m->GetMPAllocator().Adapter()), + tagAbbrevMap(std::less(), m->GetMPAllocator().Adapter()), + tyIdxDieIdMap(std::less(), m->GetMPAllocator().Adapter()), + stridxDieIdMap(std::less(), m->GetMPAllocator().Adapter()), + funcDefStrIdxDieIdMap(std::less(), m->GetMPAllocator().Adapter()), + typeDefTyIdxMap(std::less(), m->GetMPAllocator().Adapter()), + pointedPointerMap(std::less(), m->GetMPAllocator().Adapter()), + funcLstrIdxDieIdMap(std::less(), m->GetMPAllocator().Adapter()), + funcLstrIdxLabIdxMap(std::less(), m->GetMPAllocator().Adapter()), + strps(std::less(), m->GetMPAllocator().Adapter()) { + /* valid entry starting from index 1 as abbrevid starting from 1 as well */ abbrevVec.push_back(nullptr); InitMsg(); } diff --git a/src/mapleall/maple_ir/include/global_tables.h b/src/mapleall/maple_ir/include/global_tables.h index 3563ed0952b0eb81611be75ec4ce44b510d85028..6fdf9cd7f72a7fc2aabaecc5ab80c0e1cda6ce86 100644 --- a/src/mapleall/maple_ir/include/global_tables.h +++ b/src/mapleall/maple_ir/include/global_tables.h @@ -503,8 +503,8 @@ class FPConstTable { FPConstTable &operator=(const FPConstTable &p) = delete; ~FPConstTable(); - MIRFloatConst *GetOrCreateFloatConst(float fval, uint32 fieldID); // get the const from floatConstTable or create a new one - MIRDoubleConst *GetOrCreateDoubleConst(double fval, uint32 fieldID); // get the const from doubleConstTable or create a new one + MIRFloatConst *GetOrCreateFloatConst(float); // get the const from floatConstTable or create a new one + MIRDoubleConst *GetOrCreateDoubleConst(double); // get the const from doubleConstTable or create a new one static std::unique_ptr Create() { auto p = std::unique_ptr(new FPConstTable()); diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 2ac33c8b175d7737052f81f717c5e0501244482f..00dd9679d485d8d249cc9f3056adfd8d43d7d8cd 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -163,7 +163,7 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { } value; value.ivalue = ReadNum(); - return GlobalTables::GetFpConstTable().GetOrCreateFloatConst(value.fvalue, fieldID); + return GlobalTables::GetFpConstTable().GetOrCreateFloatConst(value.fvalue); } case kBinKindConstDouble: { union { @@ -172,7 +172,7 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { } value; value.ivalue = ReadNum(); - return GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(value.dvalue, fieldID); + return GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(value.dvalue); } case kBinKindConstAgg: { MIRAggConst *aggConst = mod.GetMemPool()->New(mod, *type, fieldID); diff --git a/src/mapleall/maple_ir/src/debug_info.cpp b/src/mapleall/maple_ir/src/debug_info.cpp index 9893f16558ea39db092b70ffe061933da7932202..ce5b8ade939a84d20d8c7abbb7c1c816b7aa9ecd 100644 --- a/src/mapleall/maple_ir/src/debug_info.cpp +++ b/src/mapleall/maple_ir/src/debug_info.cpp @@ -42,18 +42,18 @@ constexpr uint32 kStructDBGSize = 8888; // DBGDie methods DBGDie::DBGDie(MIRModule *m, DwTag tag) - : module(m), - tag(tag), - id(m->GetDbgInfo()->GetMaxId()), - withChildren(false), - sibling(nullptr), - firstChild(nullptr), - abbrevId(0), - tyIdx(0), - offset(0), - size(0), - attrVec(m->GetMPAllocator().Adapter()), - subDieVec(m->GetMPAllocator().Adapter()) { + : module(m), + tag(tag), + id(m->GetDbgInfo()->GetMaxId()), + withChildren(false), + sibling(nullptr), + firstChild(nullptr), + abbrevId(0), + tyIdx(0), + offset(0), + size(0), + attrVec(m->GetMPAllocator().Adapter()), + subDieVec(m->GetMPAllocator().Adapter()) { if (module->GetDbgInfo()->GetParentDieSize()) { parent = module->GetDbgInfo()->GetParentDie(); } else { @@ -322,7 +322,8 @@ void DebugInfo::BuildDebugInfo() { break; } default: - std::cout << "named type " << GlobalTables::GetStrTable().GetStringFromStrIdx(strIdx).c_str() << "\n"; + LogInfo::MapleLogger() << "named type " << GlobalTables::GetStrTable().GetStringFromStrIdx(strIdx).c_str() + << "\n"; break; } } @@ -635,7 +636,7 @@ DBGDie *DebugInfo::CreatePointedFuncTypeDie(MIRFuncType *ftype) { } DBGDie *DebugInfo::GetOrCreateTypeDie(MIRType *type) { - if (!type) { + if (type == nullptr) { return nullptr; } @@ -652,7 +653,7 @@ DBGDie *DebugInfo::GetOrCreateTypeDie(MIRType *type) { return idDieMap[id]; } - if (type && type->GetTypeIndex() == static_cast(type->GetPrimType())) { + if (type->GetTypeIndex() == static_cast(type->GetPrimType())) { return GetOrCreatePrimTypeDie(type->GetPrimType()); } @@ -704,7 +705,7 @@ DBGDie *DebugInfo::GetOrCreatePointTypeDie(const MIRPtrType *ptrtype) { MIRType *type = ptrtype->GetPointedType(); // for <* void> - if (type && + if ((type != nullptr) && (type->GetPrimType() == PTY_void || type->GetKind() == kTypeFunction)) { DBGDie *die = module->GetMemPool()->New(module, DW_TAG_pointer_type); die->AddAttr(DW_AT_byte_size, DW_FORM_data4, k8BitSize); @@ -733,7 +734,7 @@ DBGDie *DebugInfo::GetOrCreatePointTypeDie(const MIRPtrType *ptrtype) { // update incomplete type from stridxDieIdMap to tyIdxDieIdMap MIRStructType *stype = static_cast(type); - if (stype && stype->IsIncomplete()) { + if ((stype != nullptr) && stype->IsIncomplete()) { uint32 sid = stype->GetNameStrIdx().GetIdx(); if (stridxDieIdMap.find(sid) != stridxDieIdMap.end()) { uint32 dieid = stridxDieIdMap[sid]; @@ -860,7 +861,8 @@ DBGDie *DebugInfo::GetOrCreateStructTypeDie(const MIRType *type) { break; } default: - std::cout << "named type " << GlobalTables::GetStrTable().GetStringFromStrIdx(strIdx).c_str() << "\n"; + LogInfo::MapleLogger() << "named type " << GlobalTables::GetStrTable().GetStringFromStrIdx(strIdx).c_str() + << "\n"; break; } @@ -918,7 +920,7 @@ DBGDie *DebugInfo::CreateStructTypeDie(GStrIdx strIdx, const MIRStructType *stru // member functions decl for (auto fp : structtype->GetMethods()) { MIRSymbol *symbol = GlobalTables::GetGsymTable().GetSymbolFromStidx(fp.first.Idx()); - ASSERT(symbol && symbol->GetSKind() == kStFunc, "member function symbol not exist"); + ASSERT((symbol != nullptr) && symbol->GetSKind() == kStFunc, "member function symbol not exist"); MIRFunction *func = symbol->GetValue().mirFunc; ASSERT(func, "member function not exist"); DBGDie *fdie = GetOrCreateFuncDeclDie(func); @@ -1042,7 +1044,7 @@ void DebugInfo::BuildAbbrev() { for (uint32 i = 1; i < maxId; i++) { DBGDie *die = idDieMap[i]; if (die->GetAbbrevId() == 0) { - std::cout << "0 abbrevId i = " << i << " die->id = " << die->GetId() << std::endl; + LogInfo::MapleLogger() << "0 abbrevId i = " << i << " die->id = " << die->GetId() << std::endl; } } } @@ -1346,7 +1348,6 @@ void DBGCompileMsgInfo::SetErrPos(uint32 lnum, uint32 cnum) { } void DBGCompileMsgInfo::UpdateMsg(uint32 lnum, const char *line) { - // LogInfo::MapleLogger() << "get #" << lnum << " "<< line << std::endl; size_t size = strlen(line); if (size > MAXLINELEN - 1) { size = MAXLINELEN - 1; diff --git a/src/mapleall/maple_ir/src/global_tables.cpp b/src/mapleall/maple_ir/src/global_tables.cpp index b00ba892bb7910c780ba08a43c65389236081a1b..d8e20f082dba9492a33bb734112c528cc96118ef 100644 --- a/src/mapleall/maple_ir/src/global_tables.cpp +++ b/src/mapleall/maple_ir/src/global_tables.cpp @@ -299,11 +299,7 @@ IntConstTable::~IntConstTable() { } } -MIRFloatConst *FPConstTable::GetOrCreateFloatConst(float floatVal, uint32 fieldID) { - if (fieldID != 0) { - MIRFloatConst *fconst = new MIRFloatConst(floatVal, *GlobalTables::GetTypeTable().GetTypeFromTyIdx((TyIdx)PTY_f32), fieldID); - return fconst; - } +MIRFloatConst *FPConstTable::GetOrCreateFloatConst(float floatVal) { if (std::isnan(floatVal)) { return nanFloatConst; } @@ -345,11 +341,7 @@ MIRFloatConst *FPConstTable::DoGetOrCreateFloatConstThreadSafe(float floatVal) { return floatConst; } -MIRDoubleConst *FPConstTable::GetOrCreateDoubleConst(double doubleVal, uint32 fieldID) { - if (fieldID != 0) { - MIRDoubleConst *dconst = new MIRDoubleConst(doubleVal, *GlobalTables::GetTypeTable().GetTypeFromTyIdx((TyIdx)PTY_f64), fieldID); - return dconst; - } +MIRDoubleConst *FPConstTable::GetOrCreateDoubleConst(double doubleVal) { if (std::isnan(doubleVal)) { return nanDoubleConst; } diff --git a/src/mapleall/maple_ir/src/mir_module.cpp b/src/mapleall/maple_ir/src/mir_module.cpp index f65136bceea6b4290b5bba5af71863aa90e6ce1a..7a0a2b611ef3a32ad3d2d4198ccc6c427118bb1b 100644 --- a/src/mapleall/maple_ir/src/mir_module.cpp +++ b/src/mapleall/maple_ir/src/mir_module.cpp @@ -651,6 +651,9 @@ void MIRModule::OutputAsciiMpl(const char *phaseName, const char *suffix, std::streambuf *backup = LogInfo::MapleLogger().rdbuf(); LogInfo::MapleLogger().rdbuf(mplFile.rdbuf()); // change cout's buffer to that of file Dump(emitStructureType); + if (withDbgInfo) { + dbgInfo->Dump(0); + } LogInfo::MapleLogger().rdbuf(backup); // restore cout's buffer mplFile.close(); } diff --git a/src/mapleall/maple_ir/src/mir_parser.cpp b/src/mapleall/maple_ir/src/mir_parser.cpp index a7c5b5980145d35df759ce23e9d903a94913f8eb..351cfa0d9ab73aa24603a7251ef09a27d5e462c1 100644 --- a/src/mapleall/maple_ir/src/mir_parser.cpp +++ b/src/mapleall/maple_ir/src/mir_parser.cpp @@ -2613,14 +2613,14 @@ bool MIRParser::ParseScalarValue(MIRConstPtr &stype, MIRType &type, uint32 field Error("constant value incompatible with single-precision float type at "); return false; } - MIRFloatConst *fConst = GlobalTables::GetFpConstTable().GetOrCreateFloatConst(lexer.GetTheFloatVal(), fieldID); + MIRFloatConst *fConst = GlobalTables::GetFpConstTable().GetOrCreateFloatConst(lexer.GetTheFloatVal()); stype = fConst; } else if (ptp == PTY_f64) { if (lexer.GetTokenKind() != TK_doubleconst && lexer.GetTokenKind() != TK_intconst) { Error("constant value incompatible with double-precision float type at "); return false; } - MIRDoubleConst *dconst = GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(lexer.GetTheDoubleVal(), fieldID); + MIRDoubleConst *dconst = GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(lexer.GetTheDoubleVal()); stype = dconst; } else { return false; diff --git a/src/mapleall/mpl2mpl/src/constantfold.cpp b/src/mapleall/mpl2mpl/src/constantfold.cpp index 1c9b4bf295d4fc81f2a11cda8322a59c25d39908..42221c47c671864fc7db995b21f6bbbd6f3a4cd8 100644 --- a/src/mapleall/mpl2mpl/src/constantfold.cpp +++ b/src/mapleall/mpl2mpl/src/constantfold.cpp @@ -743,9 +743,9 @@ ConstvalNode *ConstantFold::FoldFPConstBinary(Opcode opcode, PrimType resultType break; } if (resultType == PTY_f64) { - resultConst->SetConstVal(GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(constValueDouble, 0)); + resultConst->SetConstVal(GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(constValueDouble)); } else { - resultConst->SetConstVal(GlobalTables::GetFpConstTable().GetOrCreateFloatConst(constValueFloat, 0)); + resultConst->SetConstVal(GlobalTables::GetFpConstTable().GetOrCreateFloatConst(constValueFloat)); } return resultConst; } @@ -1029,9 +1029,9 @@ ConstvalNode *ConstantFold::FoldFPConstUnary(Opcode opcode, PrimType resultType, auto *resultConst = mirModule->CurFuncCodeMemPool()->New(); resultConst->SetPrimType(resultType); if (resultType == PTY_f32) { - resultConst->SetConstVal(GlobalTables::GetFpConstTable().GetOrCreateFloatConst(constValue, 0)); + resultConst->SetConstVal(GlobalTables::GetFpConstTable().GetOrCreateFloatConst(constValue)); } else { - resultConst->SetConstVal(GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(constValue, 0)); + resultConst->SetConstVal(GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(constValue)); } return resultConst; } @@ -1261,13 +1261,13 @@ MIRConst *ConstantFold::FoldRoundMIRConst(const MIRConst &cst, PrimType fromType int64 fromValue = constValue.GetValue(); float floatValue = round(static_cast(fromValue)); if (static_cast(floatValue) == fromValue) { - return GlobalTables::GetFpConstTable().GetOrCreateFloatConst(floatValue, 0); + return GlobalTables::GetFpConstTable().GetOrCreateFloatConst(floatValue); } } else { uint64 fromValue = static_cast(constValue.GetValue()); float floatValue = round(static_cast(fromValue)); if (static_cast(floatValue) == fromValue) { - return GlobalTables::GetFpConstTable().GetOrCreateFloatConst(floatValue, 0); + return GlobalTables::GetFpConstTable().GetOrCreateFloatConst(floatValue); } } } else if (toType == PTY_f64 && IsPrimitiveInteger(fromType)) { @@ -1276,13 +1276,13 @@ MIRConst *ConstantFold::FoldRoundMIRConst(const MIRConst &cst, PrimType fromType int64 fromValue = constValue.GetValue(); double doubleValue = round(static_cast(fromValue)); if (static_cast(doubleValue) == fromValue) { - return GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(doubleValue, 0); + return GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(doubleValue); } } else { uint64 fromValue = static_cast(constValue.GetValue()); double doubleValue = round(static_cast(fromValue)); if (static_cast(doubleValue) == fromValue) { - return GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(doubleValue, 0); + return GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(doubleValue); } } } @@ -1353,14 +1353,14 @@ MIRConst *ConstantFold::FoldTypeCvtMIRConst(const MIRConst &cst, PrimType fromTy const MIRDoubleConst *fromValue = safe_cast(cst); ASSERT_NOT_NULL(fromValue); float floutValue = static_cast(fromValue->GetValue()); - MIRFloatConst *toValue = GlobalTables::GetFpConstTable().GetOrCreateFloatConst(floutValue, 0); + MIRFloatConst *toValue = GlobalTables::GetFpConstTable().GetOrCreateFloatConst(floutValue); toConst = toValue; } else { ASSERT(GetPrimTypeBitSize(toType) == 64, "We suppot F32 and F64"); const MIRFloatConst *fromValue = safe_cast(cst); ASSERT_NOT_NULL(fromValue); double doubleValue = static_cast(fromValue->GetValue()); - MIRDoubleConst *toValue = GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(doubleValue, 0); + MIRDoubleConst *toValue = GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(doubleValue); toConst = toValue; } return toConst; diff --git a/src/mplfe/BUILD.gn b/src/mplfe/BUILD.gn index 313deefbbf3e00f53ed042d3d030e4cf478a1b4a..e5eb18994f63dc3ea193dd3777603dd4e9fb9baa 100644 --- a/src/mplfe/BUILD.gn +++ b/src/mplfe/BUILD.gn @@ -20,6 +20,8 @@ if (COV_CHECK == 1) { cflags += [ "-DMIR_FEATURE_FULL=1", "-DMPLFE_FULL_INFO_DUMP=1", + "-DUSE_OPS", + "-DENABLE_MPLFE_AST", ] include_directories = [ @@ -36,6 +38,10 @@ include_directories = [ "${MAPLEALL_ROOT}/maple_me/include", "${MAPLEALL_ROOT}/mempool/include", "${MAPLE_ROOT}/third_party/bounds_checking_function/include", + "${MPLFE_ROOT}/ast_input/include", + "${MPLFE_ROOT}/ast_input/lib", + "${LLVMINC}", + "//../ThirdParty/cfe-8.0.0.src/tools", ] static_library("lib_mplfe_util") { @@ -57,6 +63,7 @@ static_library("lib_mplfe_util") { "${MPLFE_ROOT}/common/src/fe_type_manager.cpp", "${MPLFE_ROOT}/common/src/fe_utils.cpp", "${MPLFE_ROOT}/common/src/fe_utils_java.cpp", + "${MPLFE_ROOT}/common/src/fe_utils_ast.cpp", "${MPLFE_ROOT}/common/src/feir_builder.cpp", "${MPLFE_ROOT}/common/src/feir_dfg.cpp", "${MPLFE_ROOT}/common/src/feir_stmt.cpp", @@ -95,6 +102,7 @@ executable("mplfe") { ] include_dirs = include_directories deps = [ + ":lib_mplfe_ast_input", ":lib_mplfe_input", ":lib_mplfe_jbc_input", ":lib_mplfe_bc_input", @@ -107,7 +115,12 @@ executable("mplfe") { "${MAPLEALL_ROOT}/mempool:libmempool", "${MAPLEALL_ROOT}/maple_util:libmplutil", ] - ldflags = [ "-lz" ] + ldflags = [ + "-lz", + "-rdynamic", + "-L${LLVMLIBDIR}/", + "-Wl,-rpath,${LLVMLIBDIR}/", + ] } include_jbc_input_directories = [ @@ -167,6 +180,7 @@ static_library("lib_mplfe_bc_input") { "${MPLFE_ROOT}/bc_input/src/ark_annotation_map.cpp", "${MPLFE_ROOT}/bc_input/src/ark_annotation_processor.cpp", "${MPLFE_ROOT}/bc_input/src/bc_pragma.cpp", + "${MPLFE_ROOT}/bc_input/src/rc_setter.cpp", ] include_dirs = include_bc_input_directories output_dir = "${root_out_dir}/ar" @@ -234,3 +248,62 @@ static_library("lib_mplfe_dex_input") { include_dirs = include_dex_input_directories + include_dirs_libdexfile + include_dirs_dex output_dir = "${root_out_dir}/ar" } + + +static_library("lib_ast_interface") { + sources = [ "${MPLFE_ROOT}/ast_input/lib/ast_interface.cpp" ] + include_dirs = include_directories + defines = [ + "CLANG_ENABLE_ARCMT", + "CLANG_ENABLE_OBJC_REWRITER", + "CLANG_ENABLE_STATIC_ANALYZER", + "GTEST_HAS_RTTI=0", + "_DEBUG", + "_GNU_SOURCE", + "__STDC_CONSTANT_MACROS", + "__STDC_FORMAT_MACROS", + "__STDC_LIMIT_MACROS", + ] + + output_dir = "${root_out_dir}/ar" + libs = [ + "${LLVMLIBDIR}/libclang.so", + "${LLVMLIBDIR}/libclangFrontend.a", + "${LLVMLIBDIR}/libclangDriver.a", + "${LLVMLIBDIR}/libclangSerialization.a", + "${LLVMLIBDIR}/libclangParse.a", + "${LLVMLIBDIR}/libclangSema.a", + "${LLVMLIBDIR}/libclangEdit.a", + "${LLVMLIBDIR}/libclangLex.a", + "${LLVMLIBDIR}/libclangAnalysis.a", + "${LLVMLIBDIR}/libclangAST.a", + "${LLVMLIBDIR}/libclangBasic.a", + "${LLVMLIBDIR}/libLLVMDemangle.a", + "${LLVMLIBDIR}/libLLVMMCParser.a", + "${LLVMLIBDIR}/libLLVMMC.a", + "${LLVMLIBDIR}/libLLVMBitReader.a", + "${LLVMLIBDIR}/libLLVMCore.a", + "${LLVMLIBDIR}/libLLVMBinaryFormat.a", + "${LLVMLIBDIR}/libLLVMProfileData.a", + "${LLVMLIBDIR}/libLLVMOption.a", + "${LLVMLIBDIR}/libLLVMSupport.a", + ] +} + +static_library("lib_mplfe_ast_input") { + sources = [ + "${MPLFE_ROOT}/ast_input/src/ast_compiler_component.cpp", + "${MPLFE_ROOT}/ast_input/src/ast_decl.cpp", + "${MPLFE_ROOT}/ast_input/src/ast_function.cpp", + "${MPLFE_ROOT}/ast_input/src/ast_input.cpp", + "${MPLFE_ROOT}/ast_input/src/ast_parser.cpp", + "${MPLFE_ROOT}/ast_input/src/ast_struct2fe_helper.cpp", + "${MPLFE_ROOT}/ast_input/lib/ast_type.cpp", + "${MPLFE_ROOT}/ast_input/lib/ast_util.cpp", + "${MPLFE_ROOT}/ast_input/src/ast_stmt.cpp", + "${MPLFE_ROOT}/ast_input/src/ast_expr.cpp", + ] + include_dirs = include_directories + deps = [ ":lib_ast_interface" ] + output_dir = "${root_out_dir}/ar" +} diff --git a/src/mplfe/ast_input/include/ast_compiler_component.h b/src/mplfe/ast_input/include/ast_compiler_component.h new file mode 100644 index 0000000000000000000000000000000000000000..a61969375d5d5d1a681ab6c494868006724e9944 --- /dev/null +++ b/src/mplfe/ast_input/include/ast_compiler_component.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#ifndef MPLFE_AST_INPUT_INCLUDE_AST_COMPILER_COMPONENT_H +#define MPLFE_AST_INPUT_INCLUDE_AST_COMPILER_COMPONENT_H +#include "fe_macros.h" +#include "mplfe_compiler_component.h" +#include "ast_input.h" + +namespace maple { +class ASTCompilerComponent : public MPLFECompilerComponent { + public: + explicit ASTCompilerComponent(MIRModule &module); + ~ASTCompilerComponent(); + + protected: + bool ParseInputImpl() override; + bool PreProcessDeclImpl() override; + void ProcessPragmaImpl() override {} + std::unique_ptr CreatFEFunctionImpl(FEInputMethodHelper *methodHelper) override; + bool ProcessFunctionSerialImpl() override; + std::string GetComponentNameImpl() const override { + return "ASTCompilerComponent"; + } + bool ParallelableImpl() const override { + return true; + } + void DumpPhaseTimeTotalImpl() const override { + INFO(kLncInfo, "[PhaseTime] ASTCompilerComponent"); + MPLFECompilerComponent::DumpPhaseTimeTotalImpl(); + } + void ReleaseMemPoolImpl() override { + if (mp != nullptr) { + delete mp; + mp = nullptr; + } + } + + private: + MemPool *mp; + MapleAllocator allocator; + ASTInput astInput; +}; // class ASTCompilerComponent +} // namespace maple +#endif // MPLFE_AST_INPUT_INCLUDE_AST_COMPILER_COMPONENT_H diff --git a/src/mplfe/ast_input/include/ast_decl.h b/src/mplfe/ast_input/include/ast_decl.h new file mode 100644 index 0000000000000000000000000000000000000000..c631145de587095b047a6f2910aa502b7846bf95 --- /dev/null +++ b/src/mplfe/ast_input/include/ast_decl.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#ifndef MPLFE_AST_INPUT_INCLUDE_AST_DECL_H +#define MPLFE_AST_INPUT_INCLUDE_AST_DECL_H +#include +#include +#include +#include "types_def.h" +#include "ast_stmt.h" +#include "feir_var.h" +#include "fe_function.h" + +namespace maple { +class ASTDecl { + public: + ASTDecl(const std::string &srcFile, const std::string &nameIn, const std::vector &typeDescIn) + : srcFileName(srcFile), name(nameIn), typeDesc(typeDescIn) {} + virtual ~ASTDecl() = default; + const std::string &GetSrcFileName() const; + const std::string &GetName() const; + const std::vector &GetTypeDesc() const; + GenericAttrs GetGenericAttrs() const { + return genAttrs; + } + + protected: + const std::string srcFileName; + std::string name; + std::vector typeDesc; + GenericAttrs genAttrs; +}; + +class ASTField : public ASTDecl { + public: + ASTField(const std::string &srcFile, const std::string &nameIn, const std::vector &typeDescIn, + const GenericAttrs &genAttrsIn) + : ASTDecl(srcFile, nameIn, typeDescIn) { + genAttrs = genAttrsIn; + } + ~ASTField() = default; +}; + +class ASTFunc : public ASTDecl { + public: + ASTFunc(const std::string &srcFile, const std::string &nameIn, const std::vector &typeDescIn, + const GenericAttrs &genAttrsIn, const std::vector &parmNamesIn) + : ASTDecl(srcFile, nameIn, typeDescIn), compound(nullptr), parmNames(parmNamesIn) { + genAttrs = genAttrsIn; + } + ~ASTFunc() { + compound = nullptr; + } + void SetCompoundStmt(ASTStmt*); + const ASTStmt *GetCompoundStmt() const; + const std::vector &GetParmNames() const { + return parmNames; + } + std::vector> GenArgVarList() const; + std::list EmitASTStmtToFEIR() const; + + private: + // typeDesc format: [retType, arg0, arg1 ... argN] + ASTStmt *compound; // func body + std::vector parmNames; +}; + +class ASTStruct : public ASTDecl { + public: + ASTStruct(const std::string &srcFile, const std::string &nameIn, const std::vector &typeDescIn, + const GenericAttrs &genAttrsIn) + : ASTDecl(srcFile, nameIn, typeDescIn), isUnion(false) { + genAttrs = genAttrsIn; + } + ~ASTStruct() = default; + + std::string GetStructName(bool mapled) const; + + void SetField(ASTField *f) { + fields.emplace_back(f); + } + + const std::list &GetFields() const { + return fields; + } + + void SetIsUnion() { + isUnion = true; + } + + bool IsUnion() const { + return isUnion; + } + + private: + bool isUnion; + std::list fields; + std::list methods; +}; + +union VarValue { + bool b; + uint8 u8; + int8 i8; + uint16 u16; + int16 i16; + uint32 u32; + int32 i32; + float f32; + uint64 u64 = 0; + int64 i64; + double d; +}; + +class ASTVar : public ASTDecl { + public: + ASTVar(const std::string &srcFile, const std::string &nameIn, const std::vector &typeDescIn, + const GenericAttrs &genAttrsIn) + : ASTDecl(srcFile, nameIn, typeDescIn) { + genAttrs = genAttrsIn; + } + virtual ~ASTVar() = default; +}; + +class ASTPrimitiveVar : public ASTVar { + public: + ASTPrimitiveVar(const std::string &srcFile, const std::string &varName, const std::vector &typeDescIn, + VarValue value, const GenericAttrs &genAttrsIn) + : ASTVar(srcFile, varName, typeDescIn, genAttrsIn) { + val = value; + } + ~ASTPrimitiveVar() = default; + + VarValue GetVal() const { + return val; + } + + private: + VarValue val; +}; +} // namespace maple +#endif // MPLFE_AST_INPUT_INCLUDE_AST_DECL_H diff --git a/src/mplfe/ast_input/include/ast_decl_builder.h b/src/mplfe/ast_input/include/ast_decl_builder.h new file mode 100644 index 0000000000000000000000000000000000000000..012e9af00ebc19ad6759b19d4c1318ebc29fdaff --- /dev/null +++ b/src/mplfe/ast_input/include/ast_decl_builder.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#ifndef MPLFE_AST_INPUT_INCLUDE_AST_DECL_BUILDER_H +#define MPLFE_AST_INPUT_INCLUDE_AST_DECL_BUILDER_H +#include "ast_decl.h" +#include "mempool_allocator.h" + +namespace maple { +ASTDecl *ASTDeclBuilder(MapleAllocator &allocator, const std::string &srcFile, + const std::string &nameIn, const std::vector &typeDescIn) { + return allocator.GetMemPool()->New(srcFile, nameIn, typeDescIn); +} + +ASTPrimitiveVar *ASTPrimitiveVarBuilder(MapleAllocator &allocator, const std::string &srcFile, + const std::string &varName, const std::vector &desc, + VarValue val, const GenericAttrs &genAttrsIn) { + return allocator.GetMemPool()->New(srcFile, varName, desc, val, genAttrsIn); +} + +ASTFunc *ASTFuncBuilder(MapleAllocator &allocator, const std::string &srcFile, const std::string &nameIn, + const std::vector &typeDescIn, const GenericAttrs &genAttrsIn, + const std::vector &parmNamesIn) { + return allocator.GetMemPool()->New(srcFile, nameIn, typeDescIn, genAttrsIn, parmNamesIn); +} + +template +T *ASTStmtBuilder(MapleAllocator &allocator) { + return allocator.GetMemPool()->New(); +} + +template +T *ASTExprBuilder(MapleAllocator &allocator) { + return allocator.GetMemPool()->New(); +} + +ASTStruct *ASTStructBuilder(MapleAllocator &allocator, const std::string &srcFile, const std::string &nameIn, + const std::vector &typeDescIn, const GenericAttrs &genAttrsIn) { + return allocator.GetMemPool()->New(srcFile, nameIn, typeDescIn, genAttrsIn); +} + +ASTField *ASTFieldBuilder(MapleAllocator &allocator, const std::string &srcFile, const std::string &varName, + const std::vector &desc, const GenericAttrs &genAttrsIn) { + return allocator.GetMemPool()->New(srcFile, varName, desc, genAttrsIn); +} +} // namespace maple +#endif // MPLFE_AST_INPUT_INCLUDE_AST_DECL_BUILDER_H diff --git a/src/mplfe/ast_input/include/ast_expr.h b/src/mplfe/ast_input/include/ast_expr.h new file mode 100644 index 0000000000000000000000000000000000000000..f7a6ffed05180d5a93d983e92214a52e01b89836 --- /dev/null +++ b/src/mplfe/ast_input/include/ast_expr.h @@ -0,0 +1,994 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#ifndef MPLFE_AST_INPUT_INCLUDE_AST_EXPR_H +#define MPLFE_AST_INPUT_INCLUDE_AST_EXPR_H +#include "ast_op.h" +#include "feir_stmt.h" + +namespace maple { +class ASTDecl; +class ASTExpr { + public: + explicit ASTExpr(ASTOp o) : op(o) {} + virtual ~ASTExpr() = default; + UniqueFEIRExpr Emit2FEExpr() const; + + protected: + virtual UniqueFEIRExpr Emit2FEExprImpl() const = 0; + ASTOp op; +}; + +class ASTImplicitCastExpr : public ASTExpr { + public: + ASTImplicitCastExpr() : ASTExpr(kASTOpCast) {} + ~ASTImplicitCastExpr() = default; + + void SetASTExpr(ASTExpr *expr) { + child = expr; + } + + ASTExpr *GetASTExpr() const { + return child; + } + + protected: + UniqueFEIRExpr Emit2FEExprImpl() const override; + ASTExpr *child = nullptr; +}; + +class ASTRefExpr : public ASTExpr { + public: + ASTRefExpr() : ASTExpr(kASTOpRef) {} + ~ASTRefExpr() = default; + void SetASTDecl(ASTDecl *astDecl); + + ASTDecl *GetASTDecl() const { + return var; + } + + protected: + UniqueFEIRExpr Emit2FEExprImpl() const override; + ASTDecl *var = nullptr; +}; + +class ASTUnaryOperatorExpr : public ASTExpr { + public: + explicit ASTUnaryOperatorExpr(ASTOp o) : ASTExpr(o) {} + ~ASTUnaryOperatorExpr() = default; + void SetUOExpr(ASTExpr*); + + protected: + ASTExpr *expr = nullptr; +}; + +class ASTUOMinusExpr: public ASTUnaryOperatorExpr { + public: + ASTUOMinusExpr() : ASTUnaryOperatorExpr(kASTOpMinus) {} + ~ASTUOMinusExpr() = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTUONotExpr: public ASTUnaryOperatorExpr { + public: + ASTUONotExpr() : ASTUnaryOperatorExpr(kASTOpNot) {} + ~ASTUONotExpr() = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTUOLNotExpr: public ASTUnaryOperatorExpr { + public: + ASTUOLNotExpr() : ASTUnaryOperatorExpr(kASTOpLNot) {} + ~ASTUOLNotExpr() = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTUOPostIncExpr: public ASTUnaryOperatorExpr { + public: + ASTUOPostIncExpr() : ASTUnaryOperatorExpr(kASTOpPostInc) {} + ~ASTUOPostIncExpr() = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTUOPostDecExpr: public ASTUnaryOperatorExpr { + public: + ASTUOPostDecExpr() : ASTUnaryOperatorExpr(kASTOpPostDec) {} + ~ASTUOPostDecExpr() = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTUOPreIncExpr: public ASTUnaryOperatorExpr { + public: + ASTUOPreIncExpr() : ASTUnaryOperatorExpr(kASTOpPreInc) {} + ~ASTUOPreIncExpr() = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTUOPreDecExpr: public ASTUnaryOperatorExpr { + public: + ASTUOPreDecExpr() : ASTUnaryOperatorExpr(kASTOpPreDec) {} + ~ASTUOPreDecExpr() = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTUOAddrOfExpr: public ASTUnaryOperatorExpr { + public: + ASTUOAddrOfExpr() : ASTUnaryOperatorExpr(kASTOpAddrOf) {} + ~ASTUOAddrOfExpr() = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTUODerefExpr: public ASTUnaryOperatorExpr { + public: + ASTUODerefExpr() : ASTUnaryOperatorExpr(kASTOpDeref) {} + ~ASTUODerefExpr() = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTUOPlusExpr: public ASTUnaryOperatorExpr { + public: + ASTUOPlusExpr() : ASTUnaryOperatorExpr(kASTOpPlus) {} + ~ASTUOPlusExpr() = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTUORealExpr: public ASTUnaryOperatorExpr { + public: + ASTUORealExpr() : ASTUnaryOperatorExpr(kASTOpReal) {} + ~ASTUORealExpr() = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTUOImagExpr: public ASTUnaryOperatorExpr { + public: + ASTUOImagExpr() : ASTUnaryOperatorExpr(kASTOpImag) {} + ~ASTUOImagExpr() = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTUOExtensionExpr: public ASTUnaryOperatorExpr { + public: + ASTUOExtensionExpr() : ASTUnaryOperatorExpr(kASTOpExtension) {} + ~ASTUOExtensionExpr() = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTUOCoawaitExpr: public ASTUnaryOperatorExpr { + public: + ASTUOCoawaitExpr() : ASTUnaryOperatorExpr(kASTOpCoawait) {} + ~ASTUOCoawaitExpr() = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTPredefinedExpr : public ASTExpr { + public: + ASTPredefinedExpr() : ASTExpr(kASTOpPredefined) {} + ~ASTPredefinedExpr() = default; + void SetASTExpr(ASTExpr*); + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + ASTExpr *child; +}; + +class ASTOpaqueValueExpr : public ASTExpr { + public: + ASTOpaqueValueExpr() : ASTExpr(kASTOpOpaqueValue) {} + ~ASTOpaqueValueExpr() = default; + void SetASTExpr(ASTExpr*); + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + ASTExpr *child; +}; + +class ASTNoInitExpr : public ASTExpr { + public: + ASTNoInitExpr() : ASTExpr(kASTOpNoInitExpr) {} + ~ASTNoInitExpr() = default; + void SetNoInitType(MIRType *type); + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + MIRType *noInitType; +}; + +class ASTCompoundLiteralExpr : public ASTExpr { + public: + ASTCompoundLiteralExpr() : ASTExpr(kASTOpCompoundLiteralExp) {} + ~ASTCompoundLiteralExpr() = default; + void SetCompoundLiteralType(MIRType *clType); + void SetASTExpr(ASTExpr*); + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + ASTExpr *child = nullptr; + MIRType *compoundLiteralType; +}; + +class ASTOffsetOfExpr : public ASTExpr { + public: + ASTOffsetOfExpr() : ASTExpr(kASTOpOffsetOfExpr) {} + ~ASTOffsetOfExpr() = default; + void SetStructType(MIRType *stype); + void SetFieldName(std::string); + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + MIRType *structType; + std::string fieldName; +}; + +class ASTInitListExpr : public ASTExpr { + public: + ASTInitListExpr() : ASTExpr(kASTOpInitListExpr) {} + ~ASTInitListExpr() = default; + void SetFillerExprs(ASTExpr*); + void SetInitListType(MIRType *type); + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + std::vector fillers; + MIRType *initListType; +}; + +class ASTBinaryConditionalOperator : public ASTExpr { + public: + ASTBinaryConditionalOperator() : ASTExpr(kASTOpBinaryConditionalOperator) {} + ~ASTBinaryConditionalOperator() = default; + void SetRetType(MIRType *type); + void SetCondExpr(ASTExpr*); + void SetFalseExpr(ASTExpr*); + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + MIRType *retType; + ASTExpr *cExpr = nullptr; + ASTExpr *fExpr = nullptr; +}; + +class ASTBinaryOperatorExpr : public ASTExpr { + public: + explicit ASTBinaryOperatorExpr(ASTOp o) : ASTExpr(o) {} + ~ASTBinaryOperatorExpr() override = default; + + void SetRetType(MIRType *type) { + retType = type; + } + + void SetLeftExpr(ASTExpr *leftExpr) { + left = leftExpr; + } + + void SetRightExpr(ASTExpr *rightExpr) { + right = rightExpr; + } + + protected: + MIRType *retType; + ASTExpr *left = nullptr; + ASTExpr *right = nullptr; +}; + +class ASTImplicitValueInitExpr : public ASTExpr { + public: + ASTImplicitValueInitExpr() : ASTExpr(kASTImplicitValueInitExpr) {} + ~ASTImplicitValueInitExpr() = default; + + void SetType(MIRType *srcType) { + type = srcType; + } + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + MIRType *type; +}; + +class ASTStringLiteral : public ASTExpr { + public: + ASTStringLiteral() : ASTExpr(kASTStringLiteral) {} + ~ASTStringLiteral() = default; + + void SetType(MIRType *srcType) { + type = srcType; + } + + MIRType *GetType() const { + return type; + } + + void SetLength(size_t len) { + length = len; + } + + void SetCodeUnits(std::vector &units) { + codeUnits = std::move(units); + } + + const std::vector &GetCodeUnits() const { + return codeUnits; + } + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + MIRType *type; + size_t length; + std::vector codeUnits; +}; + +class ASTArraySubscriptExpr : public ASTExpr { + public: + ASTArraySubscriptExpr() : ASTExpr(kASTSubscriptExpr) {} + ~ASTArraySubscriptExpr() = default; + + void SetBaseExpr(ASTExpr *astExpr) { + baseExpr = astExpr; + } + + void SetIdxExpr(ASTExpr *astExpr) { + idxExpr = astExpr; + } + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + ASTExpr *baseExpr; + ASTExpr *idxExpr; +}; + +class ASTExprUnaryExprOrTypeTraitExpr : public ASTExpr { + public: + ASTExprUnaryExprOrTypeTraitExpr() : ASTExpr(kASTExprUnaryExprOrTypeTraitExpr) {} + ~ASTExprUnaryExprOrTypeTraitExpr() = default; + + void SetIsType(bool type) { + isType = type; + } + + void SetArgType(MIRType *type) { + argType = type; + } + + void SetArgExpr(ASTExpr *astExpr) { + argExpr = astExpr; + } + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + bool isType; + MIRType *argType; + ASTExpr *argExpr; +}; + +class ASTMemberExpr : public ASTExpr { + public: + ASTMemberExpr() : ASTExpr(kASTMemberExpr) {} + ~ASTMemberExpr() = default; + + void SetBaseExpr(ASTExpr *astExpr) { + baseExpr = astExpr; + } + + void SetMemberName(std::string name) { + memberName = std::move(name); + } + + void SetIsArrow(bool arrow) { + isArrow = arrow; + } + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + ASTExpr *baseExpr; + std::string memberName; + bool isArrow; +}; + +class ASTDesignatedInitUpdateExpr : public ASTExpr { + public: + ASTDesignatedInitUpdateExpr() : ASTExpr(kASTASTDesignatedInitUpdateExpr) {} + ~ASTDesignatedInitUpdateExpr() = default; + + void SetBaseExpr(ASTExpr *astExpr) { + baseExpr = astExpr; + } + + void SetUpdaterExpr(ASTExpr *astExpr) { + updaterExpr = astExpr; + } + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + ASTExpr *baseExpr; + ASTExpr *updaterExpr; +}; + +class ASTBOAddExpr : public ASTBinaryOperatorExpr { + public: + ASTBOAddExpr() : ASTBinaryOperatorExpr(kASTOpAdd) {} + ~ASTBOAddExpr() override = default; + + protected: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBOMulExpr : public ASTBinaryOperatorExpr { + public: + ASTBOMulExpr() : ASTBinaryOperatorExpr(kASTOpMul) {} + ~ASTBOMulExpr() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBODivExpr : public ASTBinaryOperatorExpr { + public: + ASTBODivExpr() : ASTBinaryOperatorExpr(kASTOpDiv) {} + ~ASTBODivExpr() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBORemExpr : public ASTBinaryOperatorExpr { + public: + ASTBORemExpr() : ASTBinaryOperatorExpr(kASTOpRem) {} + ~ASTBORemExpr() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBOSubExpr : public ASTBinaryOperatorExpr { + public: + ASTBOSubExpr() : ASTBinaryOperatorExpr(kASTOpSub) {} + ~ASTBOSubExpr() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBOShlExpr : public ASTBinaryOperatorExpr { + public: + ASTBOShlExpr() : ASTBinaryOperatorExpr(kASTOpShl) {} + ~ASTBOShlExpr() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBOShrExpr : public ASTBinaryOperatorExpr { + public: + ASTBOShrExpr() : ASTBinaryOperatorExpr(kASTOpShr) {} + ~ASTBOShrExpr() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBOLTExpr : public ASTBinaryOperatorExpr { + public: + ASTBOLTExpr() : ASTBinaryOperatorExpr(kASTOpLT) {} + ~ASTBOLTExpr() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBOGTExpr : public ASTBinaryOperatorExpr { + public: + ASTBOGTExpr() : ASTBinaryOperatorExpr(kASTOpGT) {} + ~ASTBOGTExpr() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBOLEExpr : public ASTBinaryOperatorExpr { + public: + ASTBOLEExpr() : ASTBinaryOperatorExpr(kASTOpLE) {} + ~ASTBOLEExpr() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBOGEExpr : public ASTBinaryOperatorExpr { + public: + ASTBOGEExpr() : ASTBinaryOperatorExpr(kASTOpGE) {} + ~ASTBOGEExpr() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBOEQExpr : public ASTBinaryOperatorExpr { + public: + ASTBOEQExpr() : ASTBinaryOperatorExpr(kASTOpEQ) {} + ~ASTBOEQExpr() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBONEExpr : public ASTBinaryOperatorExpr { + public: + ASTBONEExpr() : ASTBinaryOperatorExpr(kASTOpNE) {} + ~ASTBONEExpr() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBOAndExpr : public ASTBinaryOperatorExpr { + public: + ASTBOAndExpr() : ASTBinaryOperatorExpr(kASTOpAnd) {} + ~ASTBOAndExpr() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBOXorExpr : public ASTBinaryOperatorExpr { + public: + ASTBOXorExpr() : ASTBinaryOperatorExpr(kASTOpXor) {} + ~ASTBOXorExpr() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBOOrExpr : public ASTBinaryOperatorExpr { + public: + ASTBOOrExpr() : ASTBinaryOperatorExpr(kASTOpOr) {} + ~ASTBOOrExpr() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBOLAndExpr : public ASTBinaryOperatorExpr { + public: + ASTBOLAndExpr() : ASTBinaryOperatorExpr(kASTOpLAnd) {} + ~ASTBOLAndExpr() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBOLOrExpr : public ASTBinaryOperatorExpr { + public: + ASTBOLOrExpr() : ASTBinaryOperatorExpr(kASTOpLOr) {} + ~ASTBOLOrExpr() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBOEqExpr : public ASTBinaryOperatorExpr { + public: + ASTBOEqExpr() : ASTBinaryOperatorExpr(kASTOpEQ) {} + ~ASTBOEqExpr() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBOAssign : public ASTBinaryOperatorExpr { + public: + ASTBOAssign() : ASTBinaryOperatorExpr(kASTOpAssign) {} + ASTBOAssign(ASTOp o) : ASTBinaryOperatorExpr(o) {} + ~ASTBOAssign() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBOComma : public ASTBinaryOperatorExpr { + public: + ASTBOComma() : ASTBinaryOperatorExpr(kASTOpComma) {} + ~ASTBOComma() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBOPtrMemD : public ASTBinaryOperatorExpr { + public: + ASTBOPtrMemD() : ASTBinaryOperatorExpr(kASTOpPtrMemD) {} + ~ASTBOPtrMemD() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTBOPtrMemI : public ASTBinaryOperatorExpr { + public: + ASTBOPtrMemI() : ASTBinaryOperatorExpr(kASTOpPtrMemI) {} + ~ASTBOPtrMemI() override = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTCallExpr : public ASTExpr { + public: + ASTCallExpr() : ASTExpr(kASTOpCall) {} + ~ASTCallExpr() = default; + void SetCalleeExpr(ASTExpr *astExpr) { + calleeExpr = astExpr; + } + + ASTExpr *GetCalleeExpr() const { + return calleeExpr; + } + + void SetArgs(std::vector &argsVector){ + args = std::move(argsVector); + } + + const std::vector &GetArgsExpr() const { + return args; + } + + void SetRetType(MIRType *typeIn) { + retType = typeIn; + } + + MIRType *GetRetType() const { + return retType; + } + + void SetFuncName(const std::string &name) { + funcName = name; + } + + const std::string &GetFuncName() const { + return funcName; + } + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + + std::vector args; + ASTExpr *calleeExpr = nullptr; + MIRType *retType = nullptr; + std::string funcName; +}; + +class ASTParenExpr : public ASTExpr { + public: + ASTParenExpr() : ASTExpr(kASTParen) {} + ~ASTParenExpr() = default; + + void SetASTExpr(ASTExpr *astExpr) { + child = astExpr; + } + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + ASTExpr *child = nullptr; +}; + +class ASTIntegerLiteral : public ASTExpr { + public: + ASTIntegerLiteral() : ASTExpr(kASTIntegerLiteral) {} + ~ASTIntegerLiteral() = default; + + uint64 GetVal() const { + return val; + } + + void SetVal(uint64 valIn) { + val = valIn; + } + + void SetType(PrimType pType) { + type = pType; + } + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + + uint64 val; + PrimType type; +}; + +class ASTFloatingLiteral : public ASTExpr { + public: + ASTFloatingLiteral() : ASTExpr(kASTFloatingLiteral) {} + ~ASTFloatingLiteral() = default; + + double GetVal() const { + return val; + } + + void SetVal(double valIn) { + val = valIn; + } + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + double val; +}; + +class ASTCharacterLiteral : public ASTExpr { + public: + ASTCharacterLiteral() : ASTExpr(kASTCharacterLiteral) {} + ~ASTCharacterLiteral() = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTVAArgExpr : public ASTExpr { + public: + ASTVAArgExpr() : ASTExpr(kASTVAArgExpr) {} + ~ASTVAArgExpr() = default; + + void SetASTExpr(ASTExpr *astExpr) { + child = astExpr; + } + + private: + ASTExpr *child = nullptr; + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTCompoundAssignOperatorExpr : public ASTBinaryOperatorExpr { + public: + ASTCompoundAssignOperatorExpr() : ASTBinaryOperatorExpr(kCpdAssignOp) {} + ~ASTCompoundAssignOperatorExpr() override = default; + + protected: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + + +class ASTConstantExpr : public ASTExpr { + public: + ASTConstantExpr() : ASTExpr(kConstantExpr) {} + ~ASTConstantExpr() = default; + void SetASTExpr(ASTExpr *astExpr) { + child = astExpr; + } + + private: + ASTExpr *child = nullptr; + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTImaginaryLiteral : public ASTExpr { + public: + ASTImaginaryLiteral() : ASTExpr(kASTImaginaryLiteral) {} + ~ASTImaginaryLiteral() = default; + void SetASTExpr(ASTExpr *astExpr) { + child = astExpr; + } + + private: + ASTExpr *child = nullptr; + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTConditionalOperator : public ASTExpr { + public: + ASTConditionalOperator() : ASTExpr(kASTConditionalOperator) {} + ~ASTConditionalOperator() = default; + + void SetCondExpr(ASTExpr *astExpr) { + condExpr = astExpr; + } + + void SetTrueExpr(ASTExpr *astExpr) { + trueExpr = astExpr; + } + + void SetFalseExpr(ASTExpr *astExpr) { + falseExpr = astExpr; + } + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + ASTExpr *condExpr = nullptr; + ASTExpr *trueExpr = nullptr; + ASTExpr *falseExpr = nullptr; +}; + +class ASTCStyleCastExpr : public ASTExpr { + public: + ASTCStyleCastExpr() : ASTExpr(kASTOpCast) {} + ~ASTCStyleCastExpr() = default; + + void SetSubExpr(ASTExpr *sub) { + child = sub; + } + + void SetSrcType(MIRType *src) { + srcType = src; + } + + void SetDestType(MIRType *dest) { + destType = dest; + } + + MIRType *GetSrcType() const { + return srcType; + } + + MIRType *SetDestType() const { + return destType; + } + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + ASTExpr *child = nullptr; + MIRType *srcType; + MIRType *destType; +}; + +class ASTArrayInitLoopExpr : public ASTExpr { + public: + ASTArrayInitLoopExpr() : ASTExpr(kASTOpArrayInitLoop) {} + ~ASTArrayInitLoopExpr() = default; + + void SetCommonExpr(ASTExpr *expr) { + commonExpr = expr; + } + + const ASTExpr *GetCommonExpr() const { + return commonExpr; + } + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + ASTExpr* commonExpr = nullptr; +}; + +class ASTArrayInitIndexExpr : public ASTExpr { + public: + ASTArrayInitIndexExpr() : ASTExpr(kASTOpArrayInitLoop) {} + ~ASTArrayInitIndexExpr() = default; + + void SetPrimType(MIRType *pType) { + primType = pType; + } + + void SetValue(std::string val) { + value = val; + } + + MIRType *GetPrimeType() const { + return primType; + } + + std::string GetValue() const { + return value; + } + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + MIRType *primType; + std::string value; +}; + +class ASTExprWithCleanups : public ASTExpr { + public: + ASTExprWithCleanups() : ASTExpr(kASTOpExprWithCleanups) {} + ~ASTExprWithCleanups() = default; + + void SetSubExpr(ASTExpr *sub) { + subExpr = sub; + } + + ASTExpr *GetSubExpr() const { + return subExpr; + } + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + ASTExpr *subExpr = nullptr; +}; + +class ASTMaterializeTemporaryExpr : public ASTExpr { + public: + ASTMaterializeTemporaryExpr() : ASTExpr(kASTOpMaterializeTemporary) {} + ~ASTMaterializeTemporaryExpr() = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTSubstNonTypeTemplateParmExpr : public ASTExpr { + public: + ASTSubstNonTypeTemplateParmExpr() : ASTExpr(kASTOpSubstNonTypeTemplateParm) {} + ~ASTSubstNonTypeTemplateParmExpr() = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTDependentScopeDeclRefExpr : public ASTExpr { + public: + ASTDependentScopeDeclRefExpr() : ASTExpr(kASTOpDependentScopeDeclRef) {} + ~ASTDependentScopeDeclRefExpr() = default; + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; +}; + +class ASTAtomicExpr : public ASTExpr { + public: + ASTAtomicExpr() : ASTExpr(kASTOpAtomic) {} + ~ASTAtomicExpr() = default; + + void SetType(MIRType *ty) { + type = ty; + } + + void SetRefType(MIRType *ref) { + refType = ref; + } + + void SetAtomicOp(ASTAtomicOp op) { + atomicOp = op; + } + + MIRType *GetType() const { + return type; + } + + MIRType *GetRefType() const { + return refType; + } + + ASTAtomicOp GetAtomicOp() const { + return atomicOp; + } + + private: + UniqueFEIRExpr Emit2FEExprImpl() const override; + MIRType *type; + MIRType *refType; + ASTAtomicOp atomicOp; +}; +} +#endif //MPLFE_AST_INPUT_INCLUDE_AST_EXPR_H diff --git a/src/mplfe/ast_input/include/ast_function.h b/src/mplfe/ast_input/include/ast_function.h new file mode 100644 index 0000000000000000000000000000000000000000..130c4da3d32e38b06154a1495e354d1501fef5e3 --- /dev/null +++ b/src/mplfe/ast_input/include/ast_function.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#ifndef MPL_FE_AST_INPUT_AST_FUNTION_H +#define MPL_FE_AST_INPUT_AST_FUNTION_H +#include "fe_function.h" +#include "ast_struct2fe_helper.h" + +namespace maple { +class ASTFunction : public FEFunction { + public: + ASTFunction(const ASTFunc2FEHelper &argMethodHelper, MIRFunction &mirFunc, + const std::unique_ptr &argPhaseResultTotal); + virtual ~ASTFunction() = default; + + protected: + bool GenerateGeneralStmt(const std::string &phaseName) override { + WARN(kLncWarn, "Phase: %s may not need.", phaseName.c_str()); + return true; + } + + bool GenerateArgVarList(const std::string &phaseName) override; + bool GenerateAliasVars(const std::string &phaseName) override; + + bool PreProcessTypeNameIdx() override { + return true; + } + + void GenerateGeneralStmtFailCallBack() override {} + + void GenerateGeneralDebugInfo() override {} + + bool VerifyGeneral() override { + return true; + } + + void VerifyGeneralFailCallBack() override {} + + bool HasThis() override { + return funcHelper.HasThis(); + } + + bool IsNative() override { + return funcHelper.IsNative(); + } + + bool EmitToFEIRStmt(const std::string &phaseName) override; + + void PreProcessImpl() override; + bool ProcessImpl() override; + bool ProcessFEIRFunction() override; + void FinishImpl() override; + bool EmitToMIR(const std::string &phaseName) override; + void AppendFEIRStmts(std::list &stmts); + void InsertFEIRStmtsBefore(FEIRStmt &pos, std::list &stmts); + void SetMIRFunctionInfo(); + + const ASTFunc2FEHelper &funcHelper; + ASTFunc &astFunc; + bool error = false; +}; +} // namespace maple +#endif // MPL_FE_AST_INPUT_AST_FUNTION_H \ No newline at end of file diff --git a/src/mplfe/ast_input/include/ast_input.h b/src/mplfe/ast_input/include/ast_input.h new file mode 100644 index 0000000000000000000000000000000000000000..07ce3cc837836a5ded4fab98cc9b6512f9c7dff4 --- /dev/null +++ b/src/mplfe/ast_input/include/ast_input.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#ifndef MPLFE_AST_INPUT_INCLUDE_AST_INPUT_H +#define MPLFE_AST_INPUT_INCLUDE_AST_INPUT_H +#include +#include "mir_module.h" +#include "ast_decl.h" +#include "ast_parser.h" + +namespace maple { +class ASTInput { + public: + ASTInput(MIRModule &moduleIn, MapleAllocator &allocatorIn); + ~ASTInput() = default; + bool ReadASTFile(MapleAllocator &allocatorIn, uint32 index, const std::string &fileName); + bool ReadASTFiles(MapleAllocator &allocatorIn, const std::vector &fileNames); + const MIRModule &GetModule() const { + return module; + } + + void RegisterFileInfo(const std::string &fileName); + const MapleList &GetASTStructs() const { + return astStructs; + } + + void AddASTStruct(ASTStruct *astStruct) { + astStructs.emplace_back(astStruct); + } + + const MapleList &GetASTFuncs() const { + return astFuncs; + } + + void AddASTFunc(ASTFunc *astFunc) { + astFuncs.emplace_back(astFunc); + } + + const MapleList &GetASTVars() const { + return astVars; + } + + void AddASTPrimitiveVar(ASTPrimitiveVar *astVar) { + astVars.emplace_back(astVar); + } + + private: + MIRModule &module; + MapleAllocator &allocator; + MapleMap astParserMap; // map + + MapleList astStructs; + MapleList astFuncs; + MapleList astVars; +}; +} +#endif // MPLFE_AST_INPUT_INCLUDE_AST_INPUT_H \ No newline at end of file diff --git a/src/mplfe/ast_input/include/ast_op.h b/src/mplfe/ast_input/include/ast_op.h new file mode 100644 index 0000000000000000000000000000000000000000..20bf210b9dbf5fc47d84b8665161cfd084ec9cd5 --- /dev/null +++ b/src/mplfe/ast_input/include/ast_op.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#ifndef MPLFE_AST_INPUT_INCLUDE_AST_OP_H +#define MPLFE_AST_INPUT_INCLUDE_AST_OP_H +namespace maple { +enum ASTOp { + kASTOpNone = 0, + kASTStringLiteral, + kASTSubscriptExpr, + kASTExprUnaryExprOrTypeTraitExpr, + kASTMemberExpr, + kASTASTDesignatedInitUpdateExpr, + kASTImplicitValueInitExpr, + kASTOpRef, + + // unaryopcode + kASTOpMinus, + kASTOpNot, + kASTOpLNot, + kASTOpPostInc, + kASTOpPostDec, + kASTOpPreInc, + kASTOpPreDec, + kASTOpAddrOf, + kASTOpDeref, + kASTOpPlus, + kASTOpReal, + kASTOpImag, + kASTOpExtension, + kASTOpCoawait, + + // BinaryOperators + // [C++ 5.5] Pointer-to-member operators. + kASTOpPtrMemD, + kASTOpPtrMemI, + // [C99 6.5.5] Multiplicative operators. + kASTOpMul, + kASTOpDiv, + kASTOpRem, + // [C99 6.5.6] Additive operators. + kASTOpAdd, + kASTOpSub, + // [C99 6.5.7] Bitwise shift operators. + kASTOpShl, + kASTOpShr, + // [C99 6.5.8] Relational operators. + kASTOpLT, + kASTOpGT, + kASTOpLE, + kASTOpGE, + // [C99 6.5.9] Equality operators. + kASTOpEQ, + kASTOpNE, + // [C99 6.5.10] Bitwise AND operator. + kASTOpAnd, + // [C99 6.5.11] Bitwise XOR operator. + kASTOpXor, + // [C99 6.5.12] Bitwise OR operator. + kASTOpOr, + // [C99 6.5.13] Logical AND operator. + kASTOpLAnd, + // [C99 6.5.14] Logical OR operator. + kASTOpLOr, + // [C99 6.5.16] Assignment operators. + kASTOpAssign, + kASTOpMulAssign, + kASTOpDivAssign, + kASTOpRemAssign, + kASTOpAddAssign, + kASTOpSubAssign, + kASTOpShlAssign, + kASTOpShrAssign, + kASTOpAndAssign, + kASTOpXorAssign, + kASTOpOrAssign, + // [C99 6.5.17] Comma operator. + kASTOpComma, + // cast + kASTOpCast, + + // call + kASTOpCall, + + kASTParen, + kASTIntegerLiteral, + kASTFloatingLiteral, + kASTCharacterLiteral, + kASTConditionalOperator, + kConstantExpr, + kASTImaginaryLiteral, + kASTCallExpr, + kCpdAssignOp, + kASTVAArgExpr, + + // others + kASTOpPredefined, + kASTOpOpaqueValue, + kASTOpBinaryConditionalOperator, + kASTOpNoInitExpr, + kASTOpCompoundLiteralExp, + kASTOpOffsetOfExpr, + kASTOpInitListExpr, + kASTOpArrayInitLoop, + kASTOpArrayInitIndex, + kASTOpExprWithCleanups, + kASTOpMaterializeTemporary, + kASTOpSubstNonTypeTemplateParm, + kASTOpDependentScopeDeclRef, + kASTOpAtomic, +}; + +enum ASTStmtOp { + // branch + kASTStmtIf, + kASTStmtGoto, + + kASTStmtLabel, + + kASTStmtDo, + kASTStmtFor, + kASTStmtWhile, + kASTStmtBreak, + kASTStmtContinue, + + kASTStmtReturn, + kASTStmtBO, + kASTStmtUO, + kASTStmtCompound, + kASTStmtSwitch, + kASTStmtCase, + kASTStmtDefault, + kASTStmtNull, + kASTStmtDecl, + kASTStmtCAO, + kASTStmtImplicitCastExpr, + kASTStmtParenExpr, + kASTStmtIntegerLiteral, + kASTStmtVAArgExpr, + kASTStmtConditionalOperator, + kASTStmtCharacterLiteral, + kASTStmtStmtExpr, + kASTStmtCStyleCastExpr, + kASTStmtCallExpr, +}; + +enum ASTAtomicOp { + kAtomicBinaryOpAdd, + kAtomicBinaryOpSub, + kAtomicBinaryOpAnd, + kAtomicBinaryOpOr, + kAtomicBinaryOpXor, + kAtomicOpLoad, + kAtomicOpStore, + kAtomicOpExchange, + kAtomicOpCompareExchange, + kAtomicOpLast, +}; +} // namespace maple +#endif // MPLFE_AST_INPUT_INCLUDE_AST_OP_H diff --git a/src/mplfe/ast_input/include/ast_parser.h b/src/mplfe/ast_input/include/ast_parser.h new file mode 100644 index 0000000000000000000000000000000000000000..2947f12fddab53c486d4e39abefd3e40e029d99b --- /dev/null +++ b/src/mplfe/ast_input/include/ast_parser.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#ifndef MPLFE_AST_INPUT_INCLUDE_AST_PARSER_H +#define MPLFE_AST_INPUT_INCLUDE_AST_PARSER_H +#include +#include +#include "mempool_allocator.h" +#include "ast_decl.h" +#include "ast_interface.h" + +namespace maple { +class ASTInput; +class ASTParser { + public: + ASTParser(MapleAllocator &allocatorIn, uint32 fileIdxIn, const std::string &fileNameIn) + : fileIdx(fileIdxIn), fileName(fileNameIn), globalVarDecles(allocatorIn.Adapter()), + funcDecles(allocatorIn.Adapter()), recordDecles(allocatorIn.Adapter()) {} + virtual ~ASTParser() = default; + bool OpenFile(); + bool Verify(); + bool PreProcessAST(); + + bool RetrieveStructs(MapleAllocator &allocator, MapleList &structs); + bool RetrieveFuncs(MapleAllocator &allocator, MapleList &funcs); + bool RetrieveGlobalVars(MapleAllocator &allocator, MapleList &vars); + + const std::string &GetSourceFileName() const; + const uint32 GetFileIdx() const; + void SetAstIn(ASTInput *in) { + astIn = in; + } + // ProcessStmt + ASTStmt *ProcessStmt(MapleAllocator &allocator, const clang::Stmt &stmt); + ASTStmt *ProcessFunctionBody(MapleAllocator &allocator, const clang::CompoundStmt &cpdStmt); +#define PROCESS_STMT(CLASS) ProcessStmt##CLASS(MapleAllocator&, const clang::CLASS&) + ASTStmt *PROCESS_STMT(UnaryOperator); + ASTStmt *PROCESS_STMT(BinaryOperator); + ASTStmt *PROCESS_STMT(CompoundAssignOperator); + ASTStmt *PROCESS_STMT(ImplicitCastExpr); + ASTStmt *PROCESS_STMT(ParenExpr); + ASTStmt *PROCESS_STMT(IntegerLiteral); + ASTStmt *PROCESS_STMT(VAArgExpr); + ASTStmt *PROCESS_STMT(ConditionalOperator); + ASTStmt *PROCESS_STMT(CharacterLiteral); + ASTStmt *PROCESS_STMT(StmtExpr); + ASTStmt *PROCESS_STMT(CallExpr); + ASTStmt *PROCESS_STMT(ReturnStmt); + ASTStmt *PROCESS_STMT(IfStmt); + ASTStmt *PROCESS_STMT(ForStmt); + ASTStmt *PROCESS_STMT(WhileStmt); + ASTStmt *PROCESS_STMT(DoStmt); + ASTStmt *PROCESS_STMT(BreakStmt); + ASTStmt *PROCESS_STMT(ContinueStmt); + ASTStmt *PROCESS_STMT(CompoundStmt); + ASTStmt *PROCESS_STMT(GotoStmt); + ASTStmt *PROCESS_STMT(SwitchStmt); + ASTStmt *PROCESS_STMT(CaseStmt); + ASTStmt *PROCESS_STMT(DefaultStmt); + ASTStmt *PROCESS_STMT(NullStmt); + ASTStmt *PROCESS_STMT(CStyleCastExpr); + ASTStmt *PROCESS_STMT(DeclStmt); + bool HasDefault(const clang::Stmt &stmt); + + // ProcessExpr + const clang::Expr *PeelParen(const clang::Expr &expr); + ASTUnaryOperatorExpr *AllocUnaryOperatorExpr(MapleAllocator &allocator, const clang::UnaryOperator &expr); + ASTExpr *ProcessExpr(MapleAllocator &allocator, const clang::Expr *expr); + ASTBinaryOperatorExpr *AllocBinaryOperatorExpr(MapleAllocator &allocator, const clang::BinaryOperator bo); +#define PROCESS_EXPR(CLASS) ProcessExpr##CLASS(MapleAllocator&, const clang::CLASS&) + ASTExpr *PROCESS_EXPR(UnaryOperator); + ASTExpr *PROCESS_EXPR(NoInitExpr); + ASTExpr *PROCESS_EXPR(PredefinedExpr); + ASTExpr *PROCESS_EXPR(OpaqueValueExpr); + ASTExpr *PROCESS_EXPR(BinaryConditionalOperator); + ASTExpr *PROCESS_EXPR(CompoundLiteralExpr); + ASTExpr *PROCESS_EXPR(OffsetOfExpr); + ASTExpr *PROCESS_EXPR(InitListExpr); + ASTExpr *PROCESS_EXPR(BinaryOperator); + ASTExpr *PROCESS_EXPR(ImplicitValueInitExpr); + ASTExpr *PROCESS_EXPR(StringLiteral); + ASTExpr *PROCESS_EXPR(ArraySubscriptExpr); + ASTExpr *PROCESS_EXPR(UnaryExprOrTypeTraitExpr); + ASTExpr *PROCESS_EXPR(MemberExpr); + ASTExpr *PROCESS_EXPR(DesignatedInitUpdateExpr); + ASTExpr *PROCESS_EXPR(ImplicitCastExpr); + ASTExpr *PROCESS_EXPR(DeclRefExpr); + ASTExpr *PROCESS_EXPR(ParenExpr); + ASTExpr *PROCESS_EXPR(IntegerLiteral); + ASTExpr *PROCESS_EXPR(FloatingLiteral); + ASTExpr *PROCESS_EXPR(CharacterLiteral); + ASTExpr *PROCESS_EXPR(ConditionalOperator); + ASTExpr *PROCESS_EXPR(VAArgExpr); + ASTExpr *PROCESS_EXPR(GNUNullExpr); + ASTExpr *PROCESS_EXPR(SizeOfPackExpr); + ASTExpr *PROCESS_EXPR(UserDefinedLiteral); + ASTExpr *PROCESS_EXPR(ShuffleVectorExpr); + ASTExpr *PROCESS_EXPR(TypeTraitExpr); + ASTExpr *PROCESS_EXPR(ConstantExpr); + ASTExpr *PROCESS_EXPR(ImaginaryLiteral); + ASTExpr *PROCESS_EXPR(CallExpr); + ASTExpr *PROCESS_EXPR(CompoundAssignOperator); + ASTExpr *PROCESS_EXPR(StmtExpr); + ASTExpr *PROCESS_EXPR(CStyleCastExpr); + ASTExpr *PROCESS_EXPR(ArrayInitLoopExpr); + ASTExpr *PROCESS_EXPR(ArrayInitIndexExpr); + ASTExpr *PROCESS_EXPR(ExprWithCleanups); + ASTExpr *PROCESS_EXPR(MaterializeTemporaryExpr); + ASTExpr *PROCESS_EXPR(SubstNonTypeTemplateParmExpr); + ASTExpr *PROCESS_EXPR(DependentScopeDeclRefExpr); + ASTExpr *PROCESS_EXPR(AtomicExpr); + +ASTDecl *ProcessDecl(MapleAllocator &allocator, const clang::Decl &decl); +#define PROCESS_DECL(CLASS) ProcessDecl##CLASS##Decl(MapleAllocator &allocator, const clang::CLASS##Decl&) + ASTDecl *PROCESS_DECL(Field); + ASTDecl *PROCESS_DECL(Function); + ASTDecl *PROCESS_DECL(Record); + ASTDecl *PROCESS_DECL(Var); + + private: + void TraverseDecl(clang::Decl *decl, std::function const &functor); + VarValue GetVarInitVal(MapleAllocator &allocator, clang::VarDecl varDecl); + uint32 fileIdx; + const std::string fileName; + std::unique_ptr astFile; + AstUnitDecl *astUnitDecl = nullptr; + MapleList globalVarDecles; + MapleList funcDecles; + MapleList recordDecles; + ASTInput *astIn = nullptr; +}; +} // namespace maple +#endif // MPLFE_AST_INPUT_INCLUDE_AST_PARSER_H diff --git a/src/mplfe/ast_input/include/ast_stmt.h b/src/mplfe/ast_input/include/ast_stmt.h new file mode 100644 index 0000000000000000000000000000000000000000..c4956d554f064af93584df14a068d948bf61926f --- /dev/null +++ b/src/mplfe/ast_input/include/ast_stmt.h @@ -0,0 +1,413 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#ifndef MPLFE_AST_INPUT_INCLUDE_AST_STMT_H +#define MPLFE_AST_INPUT_INCLUDE_AST_STMT_H +#include "ast_op.h" +#include "ast_expr.h" +#include "feir_stmt.h" + +namespace maple { +class ASTDecl; +class ASTStmt { + public: + explicit ASTStmt(ASTStmtOp o) : op(o) {} + virtual ~ASTStmt() = default; + void SetASTExpr(ASTExpr* astExpr); + + std::list Emit2FEStmt() const { + return Emit2FEStmtImpl(); + } + + protected: + virtual std::list Emit2FEStmtImpl() const = 0; + ASTStmtOp op; + std::vector exprs; +}; + +class ASTCompoundStmt : public ASTStmt { + public: + ASTCompoundStmt() : ASTStmt(kASTStmtCompound) {} + ~ASTCompoundStmt() = default; + void SetASTStmt(ASTStmt*); + const std::list &GetASTStmtList() const; + + private: + std::list astStmts; // stmts + std::list Emit2FEStmtImpl() const override; +}; + +// Any other expressions or stmts should be extended here +class ASTReturnStmt : public ASTStmt { + public: + ASTReturnStmt() : ASTStmt(kASTStmtReturn) {} + ~ASTReturnStmt() = default; + + private: + std::list Emit2FEStmtImpl() const override; +}; + +class ASTIfStmt : public ASTStmt { + public: + ASTIfStmt() : ASTStmt(kASTStmtIf) {} + ~ASTIfStmt() override = default; + + void SetCondExpr(ASTExpr *astExpr) { + condExpr = astExpr; + } + + void SetThenStmt(ASTStmt *astStmt) { + thenStmt = astStmt; + } + + void SetElseStmt(ASTStmt *astStmt) { + elseStmt = astStmt; + } + + private: + std::list Emit2FEStmtImpl() const override; + ASTExpr *condExpr = nullptr; + ASTStmt *thenStmt = nullptr; + ASTStmt *elseStmt = nullptr; +}; + +class ASTForStmt : public ASTStmt { + public: + ASTForStmt() : ASTStmt(kASTStmtFor) {} + ~ASTForStmt() override = default; + + void SetInitStmt(ASTStmt *astStmt) { + initStmt = astStmt; + } + + void SetCondExpr(ASTExpr *astExpr) { + condExpr = astExpr; + } + + void SetIncExpr(ASTExpr *astExpr) { + incExpr = astExpr; + } + + void SetBodyStmt(ASTStmt *astStmt) { + bodyStmt = astStmt; + } + + private: + std::list Emit2FEStmtImpl() const override; + ASTStmt *initStmt = nullptr; + ASTExpr *condExpr = nullptr; + ASTExpr *incExpr = nullptr; + ASTStmt *bodyStmt = nullptr; +}; + +class ASTWhileStmt : public ASTStmt { + public: + ASTWhileStmt() : ASTStmt(kASTStmtWhile) {} + ~ASTWhileStmt() override = default; + + void SetCondExpr(ASTExpr *astExpr) { + condExpr = astExpr; + } + + void SetBodyStmt(ASTStmt *astStmt) { + bodyStmt = astStmt; + } + + private: + std::list Emit2FEStmtImpl() const override; + ASTExpr *condExpr = nullptr; + ASTStmt *bodyStmt = nullptr; +}; + +class ASTDoStmt : public ASTStmt { + public: + ASTDoStmt() : ASTStmt(kASTStmtDo) {} + ~ASTDoStmt() override = default; + + void SetCondExpr(ASTExpr *astExpr) { + condExpr = astExpr; + } + + void SetBodyStmt(ASTStmt *astStmt) { + bodyStmt = astStmt; + } + + private: + std::list Emit2FEStmtImpl() const override; + ASTExpr *condExpr = nullptr; + ASTStmt *bodyStmt = nullptr; +}; + +class ASTBreakStmt : public ASTStmt { + public: + ASTBreakStmt() : ASTStmt(kASTStmtBreak) {} + ~ASTBreakStmt() override = default; + + private: + std::list Emit2FEStmtImpl() const override; +}; + +class ASTContinueStmt : public ASTStmt { + public: + ASTContinueStmt() : ASTStmt(kASTStmtContinue) {} + ~ASTContinueStmt() override = default; + + private: + std::list Emit2FEStmtImpl() const override; +}; + +class ASTUnaryOperatorStmt : public ASTStmt { + public: + ASTUnaryOperatorStmt() : ASTStmt(kASTStmtUO) {} + ~ASTUnaryOperatorStmt() = default; + + private: + std::list Emit2FEStmtImpl() const override; +}; + +class ASTBinaryOperatorStmt : public ASTStmt { + public: + ASTBinaryOperatorStmt() : ASTStmt(kASTStmtBO) {} + ~ASTBinaryOperatorStmt() override = default; + + private: + std::list Emit2FEStmtImpl() const override; +}; + +class ASTGotoStmt : public ASTStmt { + public: + ASTGotoStmt() : ASTStmt(kASTStmtGoto) {} + ~ASTGotoStmt() = default; + + std::string GetLabelName() const { + return labelName; + } + + void SetLabelName(std::string name) { + labelName = name; + } + + private: + std::list Emit2FEStmtImpl() const override; + std::string labelName; +}; + +class ASTSwitchStmt : public ASTStmt { + public: + ASTSwitchStmt() : ASTStmt(kASTStmtSwitch) {} + ~ASTSwitchStmt() = default; + + void SetCondStmt(ASTStmt *cond) { + condStmt = cond; + } + + void SetBodyStmt(ASTStmt *body) { + bodyStmt = body; + } + + void SetCondExpr(ASTExpr *cond) { + condExpr = cond; + } + + const ASTStmt *GetCondStmt() const { + return condStmt; + } + + const ASTExpr *GetCondExpr() const { + return condExpr; + } + + const ASTStmt *GetBodyStmt() const { + return bodyStmt; + } + + private: + std::list Emit2FEStmtImpl() const override; + ASTStmt *condStmt; + ASTExpr *condExpr; + ASTStmt *bodyStmt; +}; + +class ASTCaseStmt : public ASTStmt { + public: + ASTCaseStmt() : ASTStmt(kASTStmtCase) {} + ~ASTCaseStmt() = default; + + void SetLHS(ASTExpr *l) { + lhs = l; + } + + void SetRHS(ASTExpr *r) { + rhs = r; + } + + void SetSubStmt(ASTStmt *sub) { + subStmt = sub; + } + + const ASTExpr *GetLHS() const { + return lhs; + } + + const ASTExpr *GetRHS() const { + return rhs; + } + + const ASTStmt *GetSubStmt() const { + return subStmt; + } + + private: + std::list Emit2FEStmtImpl() const override; + ASTExpr* lhs; + ASTExpr* rhs; + ASTStmt* subStmt; +}; + +class ASTDefaultStmt : public ASTStmt { + public: + ASTDefaultStmt() : ASTStmt(kASTStmtDefault) {} + ~ASTDefaultStmt() = default; + + void SetChildStmt(ASTStmt* ch) { + child = ch; + } + + const ASTStmt* GetChildStmt() const { + return child; + } + + private: + std::list Emit2FEStmtImpl() const override; + ASTStmt* child; +}; + +class ASTNullStmt : public ASTStmt { + public: + ASTNullStmt() : ASTStmt(kASTStmtNull) {} + ~ASTNullStmt() = default; + + private: + std::list Emit2FEStmtImpl() const override; +}; + +class ASTDeclStmt : public ASTStmt { + public: + ASTDeclStmt() : ASTStmt(kASTStmtDecl) {} + ~ASTDeclStmt() = default; + + void SetSubDecl(ASTDecl *decl) { + subDecls.emplace_back(decl); + } + + const std::list& GetSubDecls() const { + return subDecls; + } + + private: + std::list Emit2FEStmtImpl() const override; + std::list subDecls; +}; + +class ASTCompoundAssignOperatorStmt : public ASTStmt { + public: + ASTCompoundAssignOperatorStmt() : ASTStmt(kASTStmtCAO) {} + ~ASTCompoundAssignOperatorStmt() override = default; + + private: + std::list Emit2FEStmtImpl() const override; +}; + +class ASTImplicitCastExprStmt : public ASTStmt { + public: + ASTImplicitCastExprStmt() : ASTStmt(kASTStmtImplicitCastExpr) {} + ~ASTImplicitCastExprStmt() override = default; + + private: + std::list Emit2FEStmtImpl() const override; +}; + +class ASTParenExprStmt : public ASTStmt { + public: + ASTParenExprStmt() : ASTStmt(kASTStmtParenExpr) {} + ~ASTParenExprStmt() override = default; + + private: + std::list Emit2FEStmtImpl() const override; +}; + +class ASTIntegerLiteralStmt : public ASTStmt { + public: + ASTIntegerLiteralStmt() : ASTStmt(kASTStmtIntegerLiteral) {} + ~ASTIntegerLiteralStmt() override = default; + + private: + std::list Emit2FEStmtImpl() const override; +}; + +class ASTVAArgExprStmt : public ASTStmt { + public: + ASTVAArgExprStmt() : ASTStmt(kASTStmtVAArgExpr) {} + ~ASTVAArgExprStmt() override = default; + + private: + std::list Emit2FEStmtImpl() const override; +}; + +class ASTConditionalOperatorStmt : public ASTStmt { + public: + ASTConditionalOperatorStmt() : ASTStmt(kASTStmtConditionalOperator) {} + ~ASTConditionalOperatorStmt() override = default; + + private: + std::list Emit2FEStmtImpl() const override; +}; + +class ASTCharacterLiteralStmt : public ASTStmt { + public: + ASTCharacterLiteralStmt() : ASTStmt(kASTStmtCharacterLiteral) {} + ~ASTCharacterLiteralStmt() override = default; + + private: + std::list Emit2FEStmtImpl() const override; +}; + +class ASTStmtExprStmt : public ASTStmt { + public: + ASTStmtExprStmt() : ASTStmt(kASTStmtStmtExpr) {} + ~ASTStmtExprStmt() override = default; + + private: + std::list Emit2FEStmtImpl() const override; +}; + +class ASTCStyleCastExprStmt : public ASTStmt { + public: + ASTCStyleCastExprStmt() : ASTStmt(kASTStmtCStyleCastExpr) {} + ~ASTCStyleCastExprStmt() override = default; + + private: + std::list Emit2FEStmtImpl() const override; +}; + +class ASTCallExprStmt : public ASTStmt { + public: + ASTCallExprStmt() : ASTStmt(kASTStmtCallExpr) {} + ~ASTCallExprStmt() override = default; + + private: + std::list Emit2FEStmtImpl() const override; +}; +} // namespace maple +#endif // MPLFE_AST_INPUT_INCLUDE_AST_STMT_H diff --git a/src/mplfe/ast_input/include/ast_struct2fe_helper.h b/src/mplfe/ast_input/include/ast_struct2fe_helper.h new file mode 100644 index 0000000000000000000000000000000000000000..7fb4af3dabed2c939ae6a61a769befbbc663b032 --- /dev/null +++ b/src/mplfe/ast_input/include/ast_struct2fe_helper.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#ifndef MPLFE_AST_INPUT_INCLUDE_AST_STRUCT2FE_HELPER_H +#define MPLFE_AST_INPUT_INCLUDE_AST_STRUCT2FE_HELPER_H +#include "fe_input_helper.h" +#include "ast_decl.h" +#include "mempool_allocator.h" + +namespace maple { +class ASTStruct2FEHelper : public FEInputStructHelper { + public: + ASTStruct2FEHelper(MapleAllocator &allocator, const ASTStruct &structIn); + ~ASTStruct2FEHelper() = default; + + protected: + bool ProcessDeclImpl() override; + void InitFieldHelpersImpl() override; + void InitMethodHelpersImpl() override; + TypeAttrs GetStructAttributeFromInputImpl() const override; + std::string GetStructNameOrinImpl() const override; + std::string GetStructNameMplImpl() const override; + std::list GetSuperClassNamesImpl() const override; + std::vector GetInterfaceNamesImpl() const override; + std::string GetSourceFileNameImpl() const override; + MIRStructType *CreateMIRStructTypeImpl(bool &error) const override; + uint64 GetRawAccessFlagsImpl() const override; + virtual GStrIdx GetIRSrcFileSigIdxImpl() const override; + virtual bool IsMultiDefImpl() const override; + std::string GetSrcFileNameImpl() const override; + + const ASTStruct &astStruct; +}; + +class ASTGlobalVar2FEHelper : public FEInputGlobalVarHelper { + public: + ASTGlobalVar2FEHelper(MapleAllocator &allocatorIn, const ASTPrimitiveVar &varIn) + : FEInputGlobalVarHelper(allocatorIn), + astVar(varIn) {} + ~ASTGlobalVar2FEHelper() = default; + + protected: + bool ProcessDeclImpl(MapleAllocator &allocator) override; + const ASTPrimitiveVar &astVar; +}; + +class ASTStructField2FEHelper : public FEInputFieldHelper { + public: + ASTStructField2FEHelper(MapleAllocator &allocator, const ASTField &fieldIn) + : FEInputFieldHelper(allocator), + field(fieldIn) {} + ~ASTStructField2FEHelper() = default; + + protected: + bool ProcessDeclImpl(MapleAllocator &allocator) override; + bool ProcessDeclWithContainerImpl(MapleAllocator &allocator) override; + const ASTField &field; +}; + +class ASTFunc2FEHelper : public FEInputMethodHelper { + public: + ASTFunc2FEHelper(MapleAllocator &allocator, ASTFunc &funcIn) + : FEInputMethodHelper(allocator), + func(funcIn) { + srcLang = kSrcLangC; + } + ~ASTFunc2FEHelper() = default; + ASTFunc &GetMethod() const { + return func; + } + + const std::string &GetSrcFileName() const; + + protected: + bool ProcessDeclImpl(MapleAllocator &allocator) override; + void SolveReturnAndArgTypesImpl(MapleAllocator &allocator) override; + std::string GetMethodNameImpl(bool inMpl, bool full) const override; + bool IsVargImpl() const override; + bool HasThisImpl() const override; + MIRType *GetTypeForThisImpl() const override; + FuncAttrs GetAttrsImpl() const override; + bool IsStaticImpl() const override; + bool IsVirtualImpl() const override; + bool IsNativeImpl() const override; + bool HasCodeImpl() const override; + + ASTFunc &func; +}; +} // namespace maple +#endif // MPLFE_AST_INPUT_INCLUDE_AST_STRUCT2FE_HELPER_H diff --git a/src/mplfe/ast_input/lib/ast_alias.h b/src/mplfe/ast_input/lib/ast_alias.h new file mode 100644 index 0000000000000000000000000000000000000000..7b4f17b809d9e3a5d2b2e3af0cb7d85dcd2a9df3 --- /dev/null +++ b/src/mplfe/ast_input/lib/ast_alias.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#ifndef MPLFE_AST_FILE_INCLUDE_AST_ALIAS_H +#define MPLFE_AST_FILE_INCLUDE_AST_ALIAS_H +#include "clang-c/Index.h" +#include "libclang/CIndexer.h" +#include "libclang/CXTranslationUnit.h" +#include "clang/Frontend/ASTUnit.h" +#include "clang/AST/Decl.h" +#include "clang/AST/AST.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/RecordLayout.h" +#include "clang/AST/GlobalDecl.h" +#include "clang/AST/Mangle.h" +#include "clang/AST/VTableBuilder.h" +#include "clang/AST/VTTBuilder.h" +#include "clang/Lex/Lexer.h" +#include "clang/Frontend/ASTConsumers.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/AST/DeclBase.h" + +namespace maple { + using AstASTContext = clang::ASTContext; + using AstUnitDecl = clang::TranslationUnitDecl; + using AstASTUnit = clang::ASTUnit; +} // namespace maple +#endif // MPLFE_AST_FILE_INCLUDE_AST_ALIAS_H diff --git a/src/mplfe/ast_input/lib/ast_interface.cpp b/src/mplfe/ast_input/lib/ast_interface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5ace6038b89dd9a96cdd445446c4ffc1c3332c03 --- /dev/null +++ b/src/mplfe/ast_input/lib/ast_interface.cpp @@ -0,0 +1,285 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include "ast_interface.h" +#include "mpl_logging.h" +#include "ast_util.h" +#include "fe_utils.h" + +namespace maple { +bool LibAstFile::Open(const std::string &fileName, + int excludeDeclFromPCH, int displayDiagnostics) { + CXIndex index = clang_createIndex(excludeDeclFromPCH, displayDiagnostics); + CXTranslationUnit translationUnit = clang_createTranslationUnit(index, fileName.c_str()); + clang::ASTUnit *astUnit = translationUnit->TheASTUnit; + if (astUnit == nullptr) { + return false; + } + astContext = &astUnit->getASTContext(); + if (astUnit == nullptr) { + return false; + } + astUnitDecl = astContext->getTranslationUnitDecl(); + if (astUnit == nullptr) { + return false; + } + mangleContext = astContext->createMangleContext(); + if (mangleContext == nullptr) { + return false; + } + return true; +} + +const AstASTContext *LibAstFile::GetAstContext() { + return astContext; +} + +AstUnitDecl *LibAstFile::GetAstUnitDecl() { + return astUnitDecl; +} + +std::string LibAstFile::GetMangledName(const clang::NamedDecl &decl) { + std::string mangledName; + if (!mangleContext->shouldMangleDeclName(&decl)) { + mangledName = decl.getNameAsString(); + } else { + llvm::raw_string_ostream ostream(mangledName); + if (llvm::isa(&decl)) { + const auto *ctor = static_cast(&decl); + mangleContext->mangleCXXCtor(ctor, static_cast(0), ostream); + } else if (llvm::isa(&decl)) { + const auto *dtor = static_cast(&decl); + mangleContext->mangleCXXDtor(dtor, static_cast(0), ostream); + } else { + mangleContext->mangleName(&decl, ostream); + } + ostream.flush(); + } + return mangledName; +} + +void LibAstFile::GetCVRAttrs(uint32_t qualifiers, GenericAttrs &genAttrs) { + if (qualifiers & clang::Qualifiers::Const) { + genAttrs.SetAttr(GENATTR_const); + } + if (qualifiers & clang::Qualifiers::Restrict) { + genAttrs.SetAttr(GENATTR_restrict); + } + if (qualifiers & clang::Qualifiers::Volatile) { + genAttrs.SetAttr(GENATTR_volatile); + } +} + +void LibAstFile::GetSClassAttrs(const clang::StorageClass storageClass, GenericAttrs &genAttrs) const { + switch (storageClass) { + case clang::SC_Extern: + case clang::SC_PrivateExtern: + genAttrs.SetAttr(GENATTR_extern); + break; + case clang::SC_Static: + genAttrs.SetAttr(GENATTR_static); + break; + default: + break; + } +} + +void LibAstFile::GetStorageAttrs(const clang::NamedDecl &decl, GenericAttrs &genAttrs) const { + switch (decl.getKind()) { + case clang::Decl::Function: + case clang::Decl::CXXMethod: { + const auto *funcDecl = llvm::cast(&decl); + const clang::StorageClass storageClass = funcDecl->getStorageClass(); + GetSClassAttrs(storageClass, genAttrs); + break; + } + case clang::Decl::ParmVar: + case clang::Decl::Var: { + const auto *varDecl = llvm::cast(&decl); + const clang::StorageClass storageClass = varDecl->getStorageClass(); + GetSClassAttrs(storageClass, genAttrs); + break; + } + case clang::Decl::Field: + default: + break; + } + return; +} + +void LibAstFile::GetAccessAttrs(AccessKind access, GenericAttrs &genAttrs) { + switch (access) { + case kPublic: + genAttrs.SetAttr(GENATTR_public); + break; + case kProtected: + genAttrs.SetAttr(GENATTR_protected); + break; + case kPrivate: + genAttrs.SetAttr(GENATTR_private); + break; + case kNone: + break; + default: + ASSERT(false, "shouldn't reach here"); + break; + } + return; +} + +void LibAstFile::GetQualAttrs(const clang::NamedDecl &decl, GenericAttrs &genAttrs) { + switch (decl.getKind()) { + case clang::Decl::Function: + case clang::Decl::CXXMethod: + case clang::Decl::ParmVar: + case clang::Decl::Var: + case clang::Decl::Field: { + const auto *valueDecl = llvm::dyn_cast(&decl); + ASSERT(valueDecl != nullptr, "ERROR:null pointer!"); + const clang::QualType qualType = valueDecl->getType(); + uint32_t qualifiers = qualType.getCVRQualifiers(); + GetCVRAttrs(qualifiers, genAttrs); + break; + } + default: + break; + } +} + +void LibAstFile::CollectAttrs(const clang::NamedDecl &decl, GenericAttrs &genAttrs, AccessKind access) { + GetStorageAttrs(decl, genAttrs); + GetAccessAttrs(access, genAttrs); + GetQualAttrs(decl, genAttrs); + if (decl.isImplicit()) { + genAttrs.SetAttr(GENATTR_implicit); + } + if (decl.isUsed()) { + genAttrs.SetAttr(GENATTR_used); + } +} + +void LibAstFile::CollectFuncAttrs(const clang::FunctionDecl &decl, GenericAttrs &genAttrs, AccessKind access) { + CollectAttrs(decl, genAttrs, access); + if (decl.isVirtualAsWritten()) { + genAttrs.SetAttr(GENATTR_virtual); + } + if (decl.isDeletedAsWritten()) { + genAttrs.SetAttr(GENATTR_delete); + } + if (decl.isPure()) { + genAttrs.SetAttr(GENATTR_pure); + } + if (decl.isInlineSpecified()) { + genAttrs.SetAttr(GENATTR_inline); + } + if (decl.isDefaulted()) { + genAttrs.SetAttr(GENATTR_default); + } + if (decl.getKind() == clang::Decl::CXXConstructor) { + genAttrs.SetAttr(GENATTR_constructor); + } + if (decl.getKind() == clang::Decl::CXXDestructor) { + genAttrs.SetAttr(GENATTR_destructor); + } + if (decl.isVariadic()) { + genAttrs.SetAttr(GENATTR_varargs); + } +} + +void LibAstFile::EmitTypeName(const clang::QualType qualType, std::stringstream &ss) { + switch (qualType->getTypeClass()) { + case clang::Type::LValueReference: { + ss << "R"; + const clang::QualType pointeeType = qualType->castAs()->getPointeeType(); + EmitTypeName(pointeeType, ss); + break; + } + case clang::Type::Pointer: { + ss << "P"; + const clang::QualType pointeeType = qualType->castAs()->getPointeeType(); + EmitTypeName(pointeeType, ss); + break; + } + case clang::Type::Record: { + EmitTypeName(*qualType->getAs(), ss); + break; + } + default: { + EmitQualifierName(qualType, ss); + MIRType *type = CvtType(qualType); + ss << ASTUtil::GetTypeString(*type); + break; + } + } +} + +void LibAstFile::EmitQualifierName(const clang::QualType qualType, std::stringstream &ss) { + uint32_t cvrQual = qualType.getCVRQualifiers(); + if ((cvrQual & clang::Qualifiers::Const) != 0) { + ss << "K"; + } + if (cvrQual & clang::Qualifiers::Volatile) { + ss << "U"; + } +} + +const std::string LibAstFile::GetOrCreateMappedUnnamedName(uint32_t id) { + std::map::iterator it = unnamedSymbolMap.find(id); + if (it == unnamedSymbolMap.end()) { + const std::string name = FEUtils::GetSequentialName("unNamed"); + unnamedSymbolMap[id] = name; + } + return unnamedSymbolMap[id]; +} + +void LibAstFile::EmitTypeName(const clang::RecordType &recoType, std::stringstream &ss) { + clang::RecordDecl *recoDecl = recoType.getDecl(); + std::string str = recoType.desugar().getAsString(); + if (!recoDecl->isAnonymousStructOrUnion() && str.find("anonymous") == std::string::npos) { + clang::DeclContext *ctx = recoDecl->getDeclContext(); + MapleStack nsStack(module->GetMPAllocator().Adapter()); + while (!ctx->isTranslationUnit()) { + auto *primCtxNsDc = llvm::dyn_cast(ctx->getPrimaryContext()); + if (primCtxNsDc != nullptr) { + nsStack.push(primCtxNsDc); + } + auto *primCtxRecoDc = llvm::dyn_cast(ctx->getPrimaryContext()); + if (primCtxRecoDc != nullptr) { + nsStack.push(primCtxRecoDc); + } + ctx = ctx->getParent(); + } + while (!nsStack.empty()) { + auto *nsDc = llvm::dyn_cast(nsStack.top()); + if (nsDc != nullptr) { + ss << nsDc->getName().data() << "|"; + } + auto *rcDc = llvm::dyn_cast(nsStack.top()); + if (rcDc != nullptr) { + EmitTypeName(*rcDc->getTypeForDecl()->getAs(), ss); + } + nsStack.pop(); + } + const char *name = recoDecl->getName().data(); + if (strcmp(name, "") == 0) { + uint32_t id = recoType.getDecl()->getLocation().getRawEncoding(); + name = GetOrCreateMappedUnnamedName(id).c_str(); + } + ss << name; + } else { + uint32_t id = recoType.getDecl()->getLocation().getRawEncoding(); + ss << GetOrCreateMappedUnnamedName(id); + } +} +} // namespace maple diff --git a/src/mplfe/ast_input/lib/ast_interface.h b/src/mplfe/ast_input/lib/ast_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..5d0cf012e17872732a2b62eb0714f151ca9fd0a6 --- /dev/null +++ b/src/mplfe/ast_input/lib/ast_interface.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#ifndef MPLFE_AST_FILE_INCLUDE_AST_INTERFACE_H +#define MPLFE_AST_FILE_INCLUDE_AST_INTERFACE_H +#include +#include "ast_alias.h" + +#include "mir_type.h" +#include "mir_nodes.h" +#include "mpl_logging.h" + +namespace maple { +enum AccessKind { + kPublic, + kProtected, + kPrivate, + kNone +}; + +class LibAstFile { + public: + LibAstFile() = default; + ~LibAstFile() = default; + + bool Open(const std::string &fileName, + int excludeDeclFromPCH, int displayDiagnostics); + const AstASTContext *GetAstContext(); + AstUnitDecl *GetAstUnitDecl(); + std::string GetMangledName(const clang::NamedDecl &decl); + const std::string GetOrCreateMappedUnnamedName(uint32_t id); + + void EmitTypeName(const clang::QualType qualType, std::stringstream &ss); + void EmitTypeName(const clang::RecordType &qualType, std::stringstream &ss); + void EmitQualifierName(const clang::QualType qualType, std::stringstream &ss); + + void CollectBaseEltTypeAndSizesFromConstArrayDecl(const clang::QualType &qualType, MIRType *&elemType, + std::vector &operands); + + void CollectBaseEltTypeAndDimFromVariaArrayDecl(const clang::QualType &qualType, MIRType *&elemType, uint8_t &dim); + + void CollectBaseEltTypeAndDimFromDependentSizedArrayDecl(const clang::QualType qualType, MIRType *&elemType, + std::vector &operands); + + void GetCVRAttrs(uint32_t qualifiers, GenericAttrs &genAttrs); + void GetSClassAttrs(const clang::StorageClass storageClass, GenericAttrs &genAttrs) const; + void GetStorageAttrs(const clang::NamedDecl &decl, GenericAttrs &genAttrs) const; + void GetAccessAttrs(AccessKind access, GenericAttrs &genAttrs); + void GetQualAttrs(const clang::NamedDecl &decl, GenericAttrs &genAttrs); + void CollectAttrs(const clang::NamedDecl &decl, GenericAttrs &genAttrs, AccessKind access); + void CollectFuncAttrs(const clang::FunctionDecl &decl, GenericAttrs &genAttrs, AccessKind access); + MIRType *CvtPrimType(const clang::QualType qualType) const; + PrimType CvtPrimType(const clang::BuiltinType::Kind) const; + MIRType *CvtType(const clang::QualType qualType); + MIRType *CvtOtherType(const clang::QualType srcType); + MIRType *CvtArrayType(const clang::QualType srcType); + MIRType *CvtFunctionType(const clang::QualType srcType); + MIRType *CvtRecordType(const clang::QualType srcType); + MIRType *CvtFieldType(const clang::NamedDecl &decl); + + private: + using RecordDeclMap = std::map; + RecordDeclMap recordDeclMap; + std::map unnamedSymbolMap; + MIRModule *module; + + clang::ASTContext *astContext = nullptr; + clang::TranslationUnitDecl *astUnitDecl = nullptr; + clang::MangleContext *mangleContext = nullptr; +}; +} // namespace maple +#endif // MPLFE_AST_FILE_INCLUDE_AST_INTERFACE_H diff --git a/src/mplfe/ast_input/lib/ast_macros.h b/src/mplfe/ast_input/lib/ast_macros.h new file mode 100644 index 0000000000000000000000000000000000000000..2469e1e85b5b358a7ba6b65ae878a04622aaee56 --- /dev/null +++ b/src/mplfe/ast_input/lib/ast_macros.h @@ -0,0 +1,267 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef AST2MPL_INCLUDE_ASTMACROS_H +#define AST2MPL_INCLUDE_ASTMACROS_H +#include +#include + +const uint32_t kSrcFileNum = 2; + +// ast2mpl options +// these values can be use such as -o=1 at command lines +const uint32_t kCheckAssertion = 1; +const uint32_t kNoComment = 2; +const uint32_t kNoLoc = 4; + +// these values can be use such as -d=3 at command lines +const int kDebugLevelZero = 0; +const int kDebugLevelOne = 1; +const int kDebugLevelTwo = 2; +const int kDebugLevelThree = 3; + +const int kComplexRealID = 1; +const int kComplexImagID = 2; + +const int kBitToByteShift = 3; + +const uint32_t kFloat128Size = 2; +const uint32_t kInt32Width = 32; +const uint32_t kInt32Mask = 0xFFFFFFFFULL; +const int kDefaultIndent = 1; + +#define ASTDEBUG +#ifdef ASTDEBUG +#define LOCATION __func__ << "() at " << __FILE__ << ":" << __LINE__ + +#define DUMPINFO(stmtClass, s) \ + if (maple::ast2mplDebug > kDebugLevelOne) { \ + std::cout << LOCATION << '\n'; \ + s->dump(); \ + std::cout << " " << '\n'; \ + } + +#define NOTYETHANDLED(s) \ + std::cout << "\n" << LOCATION << " <<<<<<<<<<<<<<<<<< Not Yet Handled: " << s << "<<<<<<<<<<<<<<<<<<" << '\n'; \ + if (maple::ast2mplOption & kCheckAssertion) { \ + ASSERT(false, "Not yet handled"); \ + } \ +// print empty line +#define DEBUGPRINT_N(n) \ + do { \ + if (maple::ast2mplDebug >= n) { \ + std::cout << " " << '\n'; \ + } \ + } while (0); + +// print indent +#define DEBUGPRINTIND(n) \ + do { \ + if (maple::ast2mplDebug > kDebugLevelZero) { \ + PrintIndentation(n); \ + } \ + } while (0); + +// print str +#define DEBUGPRINT_S_LEVEL(str, level) \ + do { \ + if (maple::ast2mplDebug >= level) { \ + PrintIndentation(ast2mplDebugIndent); \ + std::cout << " " << str << '\n'; \ + } \ + } while (0); + +#define DEBUGPRINT_FUNC(name) \ + do { \ + int ind = maple::ast2mplDebugIndent; \ + Util::SetIndent(kDefaultIndent); \ + if (maple::ast2mplDebug > kDebugLevelZero) { \ + PrintIndentation(ast2mplDebugIndent); \ + std::cout << name << " {" << '\n'; \ + } \ + Util::SetIndent(ind); \ + } while (0); + +#define DEBUGPRINT_FUNC_END(name) \ + do { \ + int ind = maple::ast2mplDebugIndent; \ + Util::SetIndent(kDefaultIndent); \ + if (maple::ast2mplDebug > kDebugLevelZero) { \ + PrintIndentation(ast2mplDebugIndent); \ + std::cout << "}\n" << '\n'; \ + } \ + Util::SetIndent(ind); \ + } while (0); + +#define DEBUGPRINT_NODE(node, type) \ + do { \ + if (maple::ast2mplDebug > kDebugLevelOne) { \ + PrintIndentation(maple::ast2mplDebugIndent); \ + std::cout << " >> node: "; \ + static_cast(node)->Print(static_cast(module), 0); \ + std::cout << "\n"; \ + } \ + } while (0); + +// print var = val +#define DEBUGPRINT_V_LEVEL(var, level) \ + do { \ + if (maple::ast2mplDebug >= level) { \ + PrintIndentation(maple::ast2mplDebugIndent); \ + std::cout << LOCATION << " " << #var << " = " << var << '\n'; \ + } \ + } while (0); + +#define DEBUGPRINT_X_LEVEL(var, level) \ + do { \ + if (maple::ast2mplDebug >= level) { \ + PrintIndentation(maple::ast2mplDebugIndent); \ + std::cout << LOCATION << " " << #var << " = " << std::hex << "0x" << var << std::dec << '\n'; \ + } \ + } while (0); + +// print var = val +#define DEBUGPRINT_V_LEVEL_PURE(var, level) \ + do { \ + if (maple::ast2mplDebug >= level) { \ + PrintIndentation(maple::ast2mplDebugIndent); \ + std::cout << #var << " = " << var << '\n'; \ + } \ + } while (0); + +// print val0 val1 +#define DEBUGPRINT_NN_LEVEL(var0, var1, level) \ + do { \ + if (maple::ast2mplDebug >= level) { \ + PrintIndentation(maple::ast2mplDebugIndent); \ + std::cout << var0 << " " << var1; \ + } \ + } while (0); + +// print var0 = val0, var1 = val1 +#define DEBUGPRINT_VV_LEVEL(var0, var1, level) \ + do { \ + if (maple::ast2mplDebug >= level) { \ + PrintIndentation(maple::ast2mplDebugIndent); \ + std::cout << LOCATION << " " << #var0 << " = " << var0 << ", " << #var1 << " = " << var1 << '\n'; \ + } \ + } while (0); + +// print val0, var = val +#define DEBUGPRINT_SV_LEVEL(val0, var, level) \ + do { \ + if (maple::ast2mplDebug >= level) { \ + PrintIndentation(maple::ast2mplDebugIndent); \ + std::cout << LOCATION << " " << val0 << ", " << #var << " = " << var << '\n'; \ + } \ + } while (0); + +#define DEBUGPRINT_SX_LEVEL(val0, var, level) \ + do { \ + if (maple::ast2mplDebug >= level) { \ + PrintIndentation(maple::ast2mplDebugIndent); \ + std::cout << LOCATION << " " << val0 << ", " << #var << " = " << std::hex << "0x" << var << std::dec \ + << '\n'; \ + } \ + } while (0); + +// timing stmt +#define TIMEIT(message, stmt) \ + if (maple::ast2mplDebug == CHECKTIME) { \ + struct timeval start, end; \ + gettimeofday(&start, nullptr); \ + stmt; \ + gettimeofday(&end, nullptr); \ + float t = ((end.tv_sec * 1000000 + end.tv_usec) - (start.tv_sec * 1000000 + start.tv_usec)) * 1.0 / 1000000.0; \ + printf("%s: %f sec\n", message, t); \ + } else { \ + stmt; \ + } +#else + +#define DUMPINFO(stmtClass, s) +#define NOTHANDLED +#define DEBUGPRINT_N(n) +#define DEBUGPRINTIND(n) +#define DEBUGPRINT_S_LEVEL(str, level) +#define DEBUGPRINT_FUNC(name) +#define DEBUGPRINT_FUNC_END(name) +#define DEBUGPRINT_NODE(node, type) +#define DEBUGPRINT_V_LEVEL(var, level) +#define DEBUGPRINT_X_LEVEL(var, level) +#define DEBUGPRINT_V_LEVEL_PURE(var, level) +#define DEBUGPRINT_NN_LEVEL(var0, var1, level) +#define DEBUGPRINT_VV_LEVEL(var0, var1, level) +#define DEBUGPRINT_SV_LEVEL(val0, var, level) +#define TIMEIT(message, stmt) stmt +#endif + +#define DEBUGPRINT00 DEBUGPRINT_N(0) +#define DEBUGPRINT01 DEBUGPRINT_N(1) +#define DEBUGPRINT02 DEBUGPRINT_N(2) +#define DEBUGPRINT03 DEBUGPRINT_N(3) + +#define DEBUGPRINT_S(var) DEBUGPRINT_S_LEVEL(var, 1) +#define DEBUGPRINT_S2(var) DEBUGPRINT_S_LEVEL(var, 2) +#define DEBUGPRINT_S3(var) DEBUGPRINT_S_LEVEL(var, 3) +#define DEBUGPRINT_S4(var) DEBUGPRINT_S_LEVEL(var, 4) +#define DEBUGPRINT_S5(var) DEBUGPRINT_S_LEVEL(var, 5) +#define DEBUGPRINT_S6(var) DEBUGPRINT_S_LEVEL(var, 6) + +#define DEBUGPRINT0(var) DEBUGPRINT_V_LEVEL(var, 0) +#define DEBUGPRINT(var) DEBUGPRINT_V_LEVEL(var, 1) +#define DEBUGPRINT2(var) DEBUGPRINT_V_LEVEL(var, 2) +#define DEBUGPRINT3(var) DEBUGPRINT_V_LEVEL(var, 3) +#define DEBUGPRINT4(var) DEBUGPRINT_V_LEVEL(var, 4) +#define DEBUGPRINT5(var) DEBUGPRINT_V_LEVEL(var, 5) +#define DEBUGPRINT6(var) DEBUGPRINT_V_LEVEL(var, 6) + +#define DEBUGPRINT_X(var) DEBUGPRINT_X_LEVEL(var, 1) +#define DEBUGPRINT_X2(var) DEBUGPRINT_X_LEVEL(var, 2) +#define DEBUGPRINT_X3(var) DEBUGPRINT_X_LEVEL(var, 3) +#define DEBUGPRINT_X4(var) DEBUGPRINT_X_LEVEL(var, 4) +#define DEBUGPRINT_X5(var) DEBUGPRINT_X_LEVEL(var, 5) +#define DEBUGPRINT_X6(var) DEBUGPRINT_X_LEVEL(var, 6) + +#define DEBUGPRINT_PURE(var) DEBUGPRINT_V_LEVEL_PURE(var, 1) +#define DEBUGPRINT2_PURE(var) DEBUGPRINT_V_LEVEL_PURE(var, 2) +#define DEBUGPRINT3_PURE(var) DEBUGPRINT_V_LEVEL_PURE(var, 3) +#define DEBUGPRINT4_PURE(var) DEBUGPRINT_V_LEVEL_PURE(var, 4) +#define DEBUGPRINT5_PURE(var) DEBUGPRINT_V_LEVEL_PURE(var, 5) +#define DEBUGPRINT6_PURE(var) DEBUGPRINT_V_LEVEL_PURE(var, 6) + +#define DEBUGPRINT_NN(var0, var1) DEBUGPRINT_NN_LEVEL(var0, var1, 1) +#define DEBUGPRINT_NN_2(var0, var1) DEBUGPRINT_NN_LEVEL(var0, var1, 2) +#define DEBUGPRINT_NN_3(var0, var1) DEBUGPRINT_NN_LEVEL(var0, var1, 3) + +#define DEBUGPRINT_VV(var0, var1) DEBUGPRINT_VV_LEVEL(var0, var1, 1) +#define DEBUGPRINT_VV_2(var0, var1) DEBUGPRINT_VV_LEVEL(var0, var1, 2) +#define DEBUGPRINT_VV_3(var0, var1) DEBUGPRINT_VV_LEVEL(var0, var1, 3) + +#define DEBUGPRINT_SV(var0, var) DEBUGPRINT_SV_LEVEL(var0, var, 1) +#define DEBUGPRINT_SV_2(var0, var) DEBUGPRINT_SV_LEVEL(var0, var, 2) +#define DEBUGPRINT_SV_3(var0, var) DEBUGPRINT_SV_LEVEL(var0, var, 3) + +#define DEBUGPRINT_SX(var0, var) DEBUGPRINT_SX_LEVEL(var0, var, 1) +#define DEBUGPRINT_SX_2(var0, var) DEBUGPRINT_SX_LEVEL(var0, var, 2) +#define DEBUGPRINT_SX_3(var0, var) DEBUGPRINT_SX_LEVEL(var0, var, 3) + +// A: module->fileinfo, B:"filename", +// C: stridx, D:module->fileinfo_isstring, E:true; +#define SET_INFO_PAIR(a, b, c, d, e) \ + a.emplace_back(builder->GetOrCreateStringIndex(b), c); \ + d.emplace_back(e) + +#endif // AST2MPL_INCLUDE_ASTMACROS_H diff --git a/src/mplfe/ast_input/lib/ast_type.cpp b/src/mplfe/ast_input/lib/ast_type.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a0d35d8d9787be910d2acfd6e2c49befc8eb10db --- /dev/null +++ b/src/mplfe/ast_input/lib/ast_type.cpp @@ -0,0 +1,274 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include "ast_macros.h" +#include "ast_interface.h" +#include "ast_util.h" +#include "fe_manager.h" + +namespace maple { +MIRType *LibAstFile::CvtPrimType(const clang::QualType qualType) const { + clang::QualType srcType = qualType.getCanonicalType(); + if (srcType.isNull()) { + return nullptr; + } + + MIRType *destType = nullptr; + if (llvm::isa(srcType)) { + const auto *builtinType = llvm::cast(srcType); + PrimType primType = CvtPrimType(builtinType->getKind()); + destType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(primType); + } + return destType; +} + +PrimType LibAstFile::CvtPrimType(const clang::BuiltinType::Kind kind) const { + switch (kind) { + case clang::BuiltinType::Bool: + return PTY_u1; + case clang::BuiltinType::Char_U: + case clang::BuiltinType::UChar: + return PTY_u8; + case clang::BuiltinType::WChar_U: + case clang::BuiltinType::UShort: + return PTY_u16; + case clang::BuiltinType::UInt: +#ifndef AST2MPL_64 + case clang::BuiltinType::ULong: +#endif + return PTY_u32; +#ifdef AST2MPL_64 + case clang::BuiltinType::ULong: +#endif + case clang::BuiltinType::ULongLong: + return PTY_u64; + case clang::BuiltinType::UInt128: + return PTY_u64; + case clang::BuiltinType::Char_S: + case clang::BuiltinType::SChar: + return PTY_i8; + case clang::BuiltinType::WChar_S: + case clang::BuiltinType::Short: + case clang::BuiltinType::Char16: + return PTY_i16; + case clang::BuiltinType::Char32: + case clang::BuiltinType::Int: +#ifndef AST2MPL_64 + case clang::BuiltinType::Long: +#endif + return PTY_i32; +#ifdef AST2MPL_64 + case clang::BuiltinType::Long: +#endif + case clang::BuiltinType::LongLong: + case clang::BuiltinType::Int128: // pty = PTY_i128, NOTYETHANDLED + return PTY_i64; + case clang::BuiltinType::Half: // pty = PTY_f16, NOTYETHANDLED + case clang::BuiltinType::Float: + return PTY_f32; + case clang::BuiltinType::Double: + return PTY_f64; + case clang::BuiltinType::LongDouble: + case clang::BuiltinType::Float128: + return PTY_f128; + case clang::BuiltinType::NullPtr: + return kPtyInvalid; + case clang::BuiltinType::Void: + default: + return PTY_void; + } +} + +MIRType *LibAstFile::CvtType(const clang::QualType qualType) { + clang::QualType srcType = qualType.getCanonicalType(); + if (srcType.isNull()) { + return nullptr; + } + + MIRType *destType = CvtPrimType(srcType); + if (destType != nullptr) { + return destType; + } + + // handle pointer types + const clang::QualType srcPteType = srcType->getPointeeType(); + if (!srcPteType.isNull()) { + MIRType *mirPointeeType = CvtType(srcPteType); + if (mirPointeeType == nullptr) { + return nullptr; + } + return GlobalTables::GetTypeTable().GetOrCreatePointerType(*mirPointeeType); + } + + return CvtOtherType(srcType); +} + +MIRType *LibAstFile::CvtOtherType(const clang::QualType srcType) { + MIRType *destType = nullptr; + if (srcType->isArrayType()) { + destType = CvtArrayType(srcType); + } else if (srcType->isRecordType()) { + destType = CvtRecordType(srcType); + } else if (srcType->isAnyComplexType()) { + CHECK_FATAL(false, "NYI"); + } else if (srcType->isFunctionType()) { + destType = CvtFunctionType(srcType); + } else if (srcType->isEnumeralType()) { + destType = GlobalTables::GetTypeTable().GetInt32(); + } else if (srcType->isAtomicType()) { + const auto *atomicType = llvm::cast(srcType); + destType = CvtType(atomicType->getValueType()); + } + CHECK_NULL_FATAL(destType); + return destType; +} + +MIRType *LibAstFile::CvtRecordType(const clang::QualType srcType) { + const auto *recordType = llvm::cast(srcType); + clang::RecordDecl *recordDecl = recordType->getDecl(); + MIRStructType *type = nullptr; + std::stringstream ss; + EmitTypeName(srcType, ss); + std::string name(ss.str()); + if (!ASTUtil::IsValidName(name)) { + uint32_t id = recordType->getDecl()->getLocation().getRawEncoding(); + name = GetOrCreateMappedUnnamedName(id); + } + type = FEManager::GetTypeManager().GetOrCreateStructType(name); + type->SetMIRTypeKind(srcType->isUnionType() ? kTypeUnion : kTypeStruct); + return recordDecl->isLambda() ? GlobalTables::GetTypeTable().GetOrCreatePointerType(*type) : type; +} + +MIRType *LibAstFile::CvtArrayType(const clang::QualType srcType) { + MIRType *elemType = nullptr; + std::vector operands; + uint8_t dim = 0; + if (srcType->isConstantArrayType()) { + CollectBaseEltTypeAndSizesFromConstArrayDecl(srcType, elemType, operands); + ASSERT(operands.size() < kMaxArrayDim, "The max array dimension is kMaxArrayDim"); + dim = static_cast(operands.size()); + } else if (srcType->isIncompleteArrayType()) { + const auto *arrayType = llvm::cast(srcType); + CollectBaseEltTypeAndSizesFromConstArrayDecl(arrayType->getElementType(), elemType, operands); + dim = static_cast(operands.size()); + ASSERT(operands.size() < kMaxArrayDim, "The max array dimension is kMaxArrayDim"); + } else if (srcType->isVariableArrayType()) { + CollectBaseEltTypeAndDimFromVariaArrayDecl(srcType, elemType, dim); + } else if (srcType->isDependentSizedArrayType()) { + CollectBaseEltTypeAndDimFromDependentSizedArrayDecl(srcType, elemType, operands); + dim = static_cast(operands.size()); + } else { + NOTYETHANDLED(srcType.getAsString().c_str()); + } + uint32_t *sizeArray = nullptr; + uint32_t tempSizeArray[kMaxArrayDim]; + MIRType *retType = nullptr; + if (dim > 0) { + if (!srcType->isVariableArrayType()) { + for (uint8_t k = 0; k < dim; ++k) { + tempSizeArray[k] = operands[k]; + } + sizeArray = tempSizeArray; + } + retType = GlobalTables::GetTypeTable().GetOrCreateArrayType(*elemType, dim, sizeArray); + } else { + bool asFlag = srcType->isIncompleteArrayType(); + CHECK_FATAL(asFlag, "Incomplete Array Type"); + retType = elemType; + } + + if (srcType->isIncompleteArrayType()) { + // create pointer type + retType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*retType); + } + return retType; +} + +MIRType *LibAstFile::CvtFunctionType(const clang::QualType srcType) { + const auto *funcType = llvm::cast(srcType); + MIRType *retType = CvtType(funcType->getReturnType()); + std::vector argsVec; + std::vector attrsVec; + if (srcType->isFunctionProtoType()) { + const auto *funcProtoType = llvm::cast(srcType); + using ItType = clang::FunctionProtoType::param_type_iterator; + for (ItType it = funcProtoType->param_type_begin(); it != funcProtoType->param_type_end(); ++it) { + clang::QualType protoQualType = *it; + argsVec.push_back(CvtType(protoQualType)->GetTypeIndex()); + GenericAttrs genAttrs; + // collect storage class, access, and qual attributes + // ASTCompiler::GetSClassAttrs(SC_Auto, genAttrs); -- no-op + // ASTCompiler::GetAccessAttrs(genAttrs); -- no-op for params + GetCVRAttrs(protoQualType.getCVRQualifiers(), genAttrs); + attrsVec.push_back(genAttrs.ConvertToTypeAttrs()); + } + } +#ifndef USE_OPS + MIRType *mirFuncType = GlobalTables::GetTypeTable().GetOrCreateFunctionType(FEManager::GetModule(), + retType->GetTypeIndex(), argsVec, attrsVec); +#else + MIRType *mirFuncType = GlobalTables::GetTypeTable().GetOrCreateFunctionType( + retType->GetTypeIndex(), argsVec, attrsVec); +#endif + return GlobalTables::GetTypeTable().GetOrCreatePointerType(*mirFuncType); +} + + +void LibAstFile::CollectBaseEltTypeAndSizesFromConstArrayDecl(const clang::QualType &currQualType, MIRType *&elemType, + std::vector &operands) { + const clang::Type *ptrType = currQualType.getTypePtrOrNull(); + ASSERT(ptrType != nullptr, "Null type", currQualType.getAsString().c_str()); + if (ptrType->isArrayType()) { + bool asFlag = ptrType->isConstantArrayType(); + ASSERT(asFlag, "Must be a ConstantArrayType", currQualType.getAsString().c_str()); + const auto *constArrayType = llvm::cast(ptrType); + ASSERT(constArrayType != nullptr, "ERROR : null pointer!"); + llvm::APInt size = constArrayType->getSize(); + asFlag = size.getSExtValue() >= 0; + ASSERT(asFlag, "Array Size must be positive or zero", currQualType.getAsString().c_str()); + operands.push_back(size.getSExtValue()); + CollectBaseEltTypeAndSizesFromConstArrayDecl(constArrayType->getElementType(), elemType, operands); + } else { + elemType = CvtType(currQualType); + } +} + +void LibAstFile::CollectBaseEltTypeAndDimFromVariaArrayDecl(const clang::QualType &currQualType, MIRType *&elemType, + uint8_t &dim) { + const clang::Type *ptrType = currQualType.getTypePtrOrNull(); + ASSERT(ptrType != nullptr, "Null type", currQualType.getAsString().c_str()); + if (ptrType->isArrayType()) { + const auto *arrayType = llvm::cast(ptrType); + CollectBaseEltTypeAndDimFromVariaArrayDecl(arrayType->getElementType(), elemType, dim); + ++dim; + } else { + elemType = CvtType(currQualType); + } +} + +void LibAstFile::CollectBaseEltTypeAndDimFromDependentSizedArrayDecl( + const clang::QualType currQualType, MIRType *&elemType, std::vector &operands) { + const clang::Type *ptrType = currQualType.getTypePtrOrNull(); + ASSERT(ptrType != nullptr, "ERROR:null pointer!"); + if (ptrType->isArrayType()) { + const auto *arrayType = llvm::dyn_cast(ptrType); + ASSERT(arrayType != nullptr, "ERROR:null pointer!"); + // variable sized + operands.push_back(0); + CollectBaseEltTypeAndDimFromDependentSizedArrayDecl(arrayType->getElementType(), elemType, operands); + } else { + elemType = CvtType(currQualType); + } +} +} // namespace maple diff --git a/src/mplfe/ast_input/lib/ast_util.cpp b/src/mplfe/ast_input/lib/ast_util.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cc6c2afaa9d5381f13558c20f1b48d711d7bdc8b --- /dev/null +++ b/src/mplfe/ast_input/lib/ast_util.cpp @@ -0,0 +1,353 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#include "ast_util.h" +#include "clang/AST/AST.h" +#include "clang/Serialization/ASTDeserializationListener.h" +#include "mir_nodes.h" +#include "mir_builder.h" +#include "ast_macros.h" + +namespace maple { +int ast2mplDebug = 0; +int ast2mplDebugIndent = 0; +uint32_t ast2mplOption = kCheckAssertion; +const char *checkFuncName = nullptr; + +void ASTUtil::AdjIndent(int n) { + ast2mplDebugIndent += n; +} + +void ASTUtil::SetIndent(int n) { + ast2mplDebugIndent = n; +} + +bool ASTUtil::ValidInName(char c) { + return isalnum(c) || (c == '_' || c == '|' || c == ';' || c == '/' || c == '$'); +} + +bool ASTUtil::IsValidName(const std::string &name) { + for (size_t i = 0; i < name.length(); ++i) { + if (!ValidInName(name[i])) { + return false; + } + } + return true; +} + +void ASTUtil::AdjustName(std::string &name) { + for (size_t i = 0; name[i] != '\0'; ++i) { + char c = name[i]; + if (ASTUtil::ValidInName(c)) { + name[i] = c; + continue; + } + switch (c) { + case '(': + case ')': + case '<': + case '>': + case '-': + case ' ': + name[i] = '_'; + break; + case '[': + name[i] = 'A'; + break; + case ']': + name[i] = 'B'; + break; + default: + name[i] = '$'; + break; + } + } +} + +std::string ASTUtil::GetAdjustVarName(const std::string &name, uint32_t &num) { + std::stringstream ss; + ss << name << "." << num; + + DEBUGPRINT2(ss.str()); + ++num; + return ss.str(); +} + +std::string ASTUtil::GetNameWithSuffix(const std::string &origName, const std::string &suffix) { + std::stringstream ss; + ss << origName << suffix; + + return ss.str(); +} + +Opcode ASTUtil::CvtBinaryOpcode(uint32_t opcode) { + switch (opcode) { + case clang::BO_Mul: + return OP_mul; // "*" + case clang::BO_Div: + return OP_div; // "/" + case clang::BO_Rem: + return OP_rem; // "%" + case clang::BO_Add: + return OP_add; // "+" + case clang::BO_Sub: + return OP_sub; // "-" + case clang::BO_Shl: + return OP_shl; // "<<" + case clang::BO_Shr: + return OP_lshr; // ">>" + case clang::BO_LT: + return OP_lt; // "<" + case clang::BO_GT: + return OP_gt; // ">" + case clang::BO_LE: + return OP_le; // "<=" + case clang::BO_GE: + return OP_ge; // ">=" + case clang::BO_EQ: + return OP_eq; // "==" + case clang::BO_NE: + return OP_ne; // "!=" + case clang::BO_And: + return OP_band; // "&" + case clang::BO_Xor: + return OP_bxor; // "^" + case clang::BO_Or: + return OP_bior; // "|" + case clang::BO_LAnd: + return OP_land; // "&&" + case clang::BO_LOr: + return OP_lior; // "||" + default: + return OP_undef; + } +} + +// these do not have equivalent opcode in mapleir +Opcode ASTUtil::CvtBinaryAssignOpcode(uint32_t opcode) { + switch (opcode) { + case clang::BO_Assign: + return OP_eq; // "=" + case clang::BO_MulAssign: + return OP_mul; // "*=" + case clang::BO_DivAssign: + return OP_div; // "/=" + case clang::BO_RemAssign: + return OP_rem; // "%=" + case clang::BO_AddAssign: + return OP_add; // "+=" + case clang::BO_SubAssign: + return OP_sub; // "-=" + case clang::BO_ShlAssign: + return OP_shl; // "<<=" + case clang::BO_ShrAssign: + return OP_lshr; // ">>=" + case clang::BO_AndAssign: + return OP_band; // "&=" + case clang::BO_XorAssign: + return OP_bxor; // "^=" + case clang::BO_OrAssign: + return OP_bior; // "|=" + case clang::BO_Comma: + return OP_undef; // "," + case clang::BO_PtrMemD: + return OP_undef; // ".*" + case clang::BO_PtrMemI: + return OP_undef; // "->*" + default: + return OP_undef; + } +} + +Opcode ASTUtil::CvtUnaryOpcode(uint32_t opcode) { + switch (opcode) { + case clang::UO_Minus: + return OP_neg; // "-" + case clang::UO_Not: + return OP_bnot; // "~" + case clang::UO_LNot: + return OP_lnot; // "!" + case clang::UO_PostInc: + return OP_add; // "++" + case clang::UO_PostDec: + return OP_sub; // "--" + case clang::UO_PreInc: + return OP_add; // "++" + case clang::UO_PreDec: + return OP_sub; // "--" + case clang::UO_AddrOf: + return OP_addrof; // "&" + case clang::UO_Deref: + return OP_undef; // "*" + case clang::UO_Plus: + return OP_undef; // "+" + case clang::UO_Real: + return OP_undef; // "__real" + case clang::UO_Imag: + return OP_undef; // "__imag" + case clang::UO_Extension: + return OP_undef; // "__extension__" + case clang::UO_Coawait: + return OP_undef; // "co_await" + default: + CHECK_FATAL(false, "NYI ASTUtil::CvtUnaryOpcode", opcode); + } +} + +const std::string ASTUtil::Type2Label(PrimType primType) { + switch (primType) { + case PTY_u1: + return "B"; + case PTY_i8: + return "A"; + case PTY_u8: + return "C"; + case PTY_i16: + return "S"; + case PTY_u16: + return "T"; + case PTY_i32: + return "I"; + case PTY_u32: + return "M"; + case PTY_i64: + return "O"; + case PTY_u64: + return "Q"; + case PTY_f32: + return "F"; + case PTY_f64: + return "D"; + case PTY_void: + return "V"; + default: + return "R"; + } +} + +uint32 ASTUtil::GetDim(MIRType &type) { + MIRType *ptrType = &type; + if (type.GetKind() == kTypePointer) { + auto *ptr = static_cast(&type); + ptrType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptr->GetPointedTyIdx()); + } + uint32 dim = 0; + while (ptrType->GetKind() == kTypeArray) { + auto *array = static_cast(ptrType); + ptrType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(array->GetElemTyIdx()); + if (ptrType->GetKind() == kTypePointer) { + auto *ptr = static_cast(ptrType); + ptrType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptr->GetPointedTyIdx()); + } + ++dim; + } + + DEBUGPRINT2(dim); + return dim; +} + +std::string ASTUtil::GetTypeString(MIRType &type) { + std::stringstream ss; + if (ast2mplDebug > kDebugLevelThree) { + type.Dump(1); + } + switch (type.GetKind()) { + case kTypeScalar: + ss << Type2Label(type.GetPrimType()); + break; + case kTypeStruct: + case kTypeClass: + case kTypeInterface: + case kTypeBitField: + case kTypeByName: + case kTypeParam: { + ss << GlobalTables::GetStrTable().GetStringFromStrIdx(type.GetNameStrIdx()).c_str() << ";"; + break; + } + case kTypeArray: { + auto &array = static_cast(type); + MIRType *elemType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(array.GetElemTyIdx()); + uint32 dim = GetDim(type); + for (size_t i = 0; i < dim; ++i) { + ss << 'A'; + } + ss << GetTypeString(*elemType); + break; + } + case kTypePointer: { + auto &ptr = static_cast(type); + MIRType *pType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptr.GetPointedTyIdx()); + ss << "P"; + std::string str = GetTypeString(*pType); + ss << str; + break; + } + default: + break; + } + + return ss.str(); +} + +void ASTUtil::DumpMplTypes() { + uint32 size = static_cast(GlobalTables::GetTypeTable().GetTypeTableSize()); + DEBUGPRINT(size); + DEBUGPRINT_S(" dump type table "); + for (uint32 i = 1; i < size; ++i) { + MIRType *type = GlobalTables::GetTypeTable().GetTypeTable()[i]; + std::string name = GlobalTables::GetStrTable().GetStringFromStrIdx(type->GetNameStrIdx()); + (void)printf("%-4u %4u %s\n", i, type->GetNameStrIdx().GetIdx(), name.c_str()); + } + DEBUGPRINT_S(" end dump type table "); +} + +void ASTUtil::DumpMplStrings() { + size_t size = GlobalTables::GetStrTable().StringTableSize(); + DEBUGPRINT(size); + DEBUGPRINT_S(" dump string table "); + for (size_t i = 1; i < size; ++i) { + MIRType *type = GlobalTables::GetTypeTable().GetTypeTable()[i]; + const std::string &str = GlobalTables::GetStrTable().GetStringFromStrIdx(type->GetNameStrIdx()); + (void)printf("%-4d %4d %s\n", static_cast(i), static_cast(str.length()), str.c_str()); + } + DEBUGPRINT_S(" end dump string table "); +} + +bool ASTUtil::IsVoidPointerType(const TyIdx &tyIdx) { + MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); + auto *ptr = static_cast(type); + type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptr->GetPointedTyIdx()); + if (type->GetPrimType() == PTY_void) { + return true; + } + return false; +} + +std::string ASTUtil::AdjustFuncName(std::string funcName) { + std::size_t found = funcName.find('\"'); + const std::size_t offsetByTwoChar = 2; // skip the replaced char + while (found != std::string::npos) { + (void)funcName.replace(found, 1, "\\\""); + found += offsetByTwoChar; + found = funcName.find('\"', found); + } + return funcName; +} + +bool ASTUtil::InsertFuncSet(GStrIdx idx) { + static std::set funcIdxSet; + return funcIdxSet.insert(idx).second; +} +} // namespace maple diff --git a/src/mplfe/ast_input/lib/ast_util.h b/src/mplfe/ast_input/lib/ast_util.h new file mode 100644 index 0000000000000000000000000000000000000000..0fa8bb2b9b2078e5c7cf95a3c24008d0a8aed793 --- /dev/null +++ b/src/mplfe/ast_input/lib/ast_util.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#ifndef AST2MPL_INCLUDE_ASTUTIL_H +#define AST2MPL_INCLUDE_ASTUTIL_H +#include "clang/AST/AST.h" +#include "mir_type.h" +#include "ast_macros.h" + +namespace maple { +extern int ast2mplDebug; +extern int ast2mplDebugIndent; +extern uint32_t ast2mplOption; +extern const char *checkFuncName; + +class ASTUtil { + public: + static const int opcodeNameLength = 228; + static const char *opcodeName[opcodeNameLength]; + static void AdjIndent(int n); + static void SetIndent(int n); + static bool ValidInName(char c); + static bool IsValidName(const std::string &name); + static void AdjustName(std::string &name); + static std::string GetAdjustVarName(const std::string &name, uint32_t &num); + static std::string GetNameWithSuffix(const std::string &origName, const std::string &suffix); + + static void DumpMplStrings(); + static void DumpMplTypes(); + + static uint32 GetDim(MIRType &type); + static std::string GetTypeString(MIRType &type); + static const std::string Type2Label(PrimType primType); + + static MIRType *CvtPrimType(const clang::QualType type); + static Opcode CvtUnaryOpcode(uint32_t opcode); + static Opcode CvtBinaryOpcode(uint32_t opcode); + static Opcode CvtBinaryAssignOpcode(uint32_t opcode); + + static bool IsVoidPointerType(const TyIdx &tyIdx); + static std::string AdjustFuncName(std::string funcName); + static bool InsertFuncSet(GStrIdx idx); +}; +} // namespace maple +#endif // AST2MPL_INCLUDE_ASTUTIL_H_ diff --git a/src/mplfe/ast_input/src/ast_compiler_component.cpp b/src/mplfe/ast_input/src/ast_compiler_component.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e1b1b8096d0db9825d8b401e1b1baabff41b1a31 --- /dev/null +++ b/src/mplfe/ast_input/src/ast_compiler_component.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include "ast_compiler_component.h" +#include "ast_struct2fe_helper.h" +#include "ast_function.h" +#include "fe_timer.h" +#include "fe_manager.h" + +namespace maple { +#define SET_FUNC_INFO_PAIR(A, B, C, D) \ + A->PushbackMIRInfo(MIRInfoPair(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(B), C)); \ + A->PushbackIsString(D) + +ASTCompilerComponent::ASTCompilerComponent(MIRModule &module) + : MPLFECompilerComponent(module, kSrcLangC), + mp(FEUtils::NewMempool("MemPool for ASTCompilerComponent", false /* isLcalPool */)), + allocator(mp), + astInput(module, allocator) {} + +ASTCompilerComponent::~ASTCompilerComponent() { + mp = nullptr; +} + +bool ASTCompilerComponent::ParseInputImpl() { + FETimer timer; + bool success = true; + timer.StartAndDump("ASTCompilerComponent::ParseInput()"); + FE_INFO_LEVEL(FEOptions::kDumpLevelInfo, "===== Process ASTCompilerComponent::ParseInput() ====="); + std::vector inputNames = FEOptions::GetInstance().GetInputASTFiles(); + success = success && astInput.ReadASTFiles(allocator, inputNames); + CHECK_FATAL(success, "ASTCompilerComponent::ParseInput failed. Exit."); + for (auto &astStruct : astInput.GetASTStructs()) { + FEInputStructHelper *structHelper = allocator.GetMemPool()->New(allocator, *astStruct); + structHelpers.emplace_back(structHelper); + } + + for (auto &astFunc : astInput.GetASTFuncs()) { + FEInputMethodHelper *funcHelper = allocator.GetMemPool()->New(allocator, *astFunc); + globalFuncHelpers.emplace_back(funcHelper); + } + + for (auto &astVar : astInput.GetASTVars()) { + FEInputGlobalVarHelper *varHelper = allocator.GetMemPool()->New(allocator, *astVar); + globalVarHelpers.emplace_back(varHelper); + } + timer.StopAndDumpTimeMS("ASTCompilerComponent::ParseInput()"); + return success; +} + +bool ASTCompilerComponent::PreProcessDeclImpl() { + FETimer timer; + timer.StartAndDump("ASTCompilerComponent::PreProcessDecl()"); + FE_INFO_LEVEL(FEOptions::kDumpLevelInfo, "===== Process ASTCompilerComponent::PreProcessDecl() ====="); + bool success = true; + for (FEInputStructHelper *helper : structHelpers) { + ASSERT_NOT_NULL(helper); + success = helper->PreProcessDecl() ? success : false; + } + timer.StopAndDumpTimeMS("ASTCompilerComponent::PreProcessDecl()"); + return success; +} + +std::unique_ptr ASTCompilerComponent::CreatFEFunctionImpl(FEInputMethodHelper *methodHelper) { + ASTFunc2FEHelper *astFuncHelper = static_cast(methodHelper); + GStrIdx methodNameIdx = methodHelper->GetMethodNameIdx(); + bool isStatic = methodHelper->IsStatic(); + MIRFunction *mirFunc = FEManager::GetTypeManager().GetMIRFunction(methodNameIdx, isStatic); + CHECK_NULL_FATAL(mirFunc); + module.AddFunction(mirFunc); + std::unique_ptr feFunction = std::make_unique(*astFuncHelper, *mirFunc, phaseResultTotal); + feFunction->Init(); + return feFunction; +} + +bool ASTCompilerComponent::ProcessFunctionSerialImpl() { + std::stringstream ss; + ss << GetComponentName() << "::ProcessFunctionSerial()"; + FETimer timer; + timer.StartAndDump(ss.str()); + bool success = true; + FE_INFO_LEVEL(FEOptions::kDumpLevelInfo, "===== Process %s =====", ss.str().c_str()); + for (FEInputMethodHelper *methodHelper : globalFuncHelpers) { + ASSERT_NOT_NULL(methodHelper); + if (methodHelper->HasCode()) { + ASTFunc2FEHelper *astFuncHelper = static_cast(methodHelper); + std::unique_ptr feFunction = CreatFEFunction(methodHelper); + feFunction->SetSrcFileName(astFuncHelper->GetSrcFileName()); + bool processResult = feFunction->Process(); + if (!processResult) { + (void)compileFailedFEFunctions.insert(feFunction.get()); + } + success = success && processResult; + feFunction->Finish(); + } + funcSize++; + } + timer.StopAndDumpTimeMS(ss.str()); + return success; +} +} // namespace maple diff --git a/src/mplfe/ast_input/src/ast_decl.cpp b/src/mplfe/ast_input/src/ast_decl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eb7d35fe9dea7d88b7812ad2713d500c069ff519 --- /dev/null +++ b/src/mplfe/ast_input/src/ast_decl.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include "ast_decl.h" +#include "ast_parser.h" +#include "global_tables.h" +#include "ast_stmt.h" + +namespace maple { +// ---------- ASTDecl --------- +const std::string &ASTDecl::GetSrcFileName() const { + return srcFileName; +} + +const std::string &ASTDecl::GetName() const { + return name; +} + +const std::vector &ASTDecl::GetTypeDesc() const { + return typeDesc; +} + +// ---------- ASTFunc --------- +void ASTFunc::SetCompoundStmt(ASTStmt *astCompoundStmt) { + compound = astCompoundStmt; +} + +const ASTStmt *ASTFunc::GetCompoundStmt() const { + return compound; +} + +std::vector> ASTFunc::GenArgVarList() const { + std::vector> args; + return args; +} + +std::list ASTFunc::EmitASTStmtToFEIR() const { + std::list stmts; + const ASTStmt *astStmt = GetCompoundStmt(); + if (astStmt == nullptr) { + return stmts; + } + const ASTCompoundStmt *astCpdStmt = static_cast(astStmt); + const std::list &astStmtList = astCpdStmt->GetASTStmtList(); + for (auto stmtNode : astStmtList) { + std::list childStmts = stmtNode->Emit2FEStmt(); + for (auto &stmt : childStmts) { + // Link jump stmt not implemented yet + stmts.emplace_back(std::move(stmt)); + } + } + return stmts; +} +// ---------- ASTStruct ---------- +std::string ASTStruct::GetStructName(bool mapled) const { + return mapled ? namemangler::EncodeName(name) : name; +} +} // namespace maple \ No newline at end of file diff --git a/src/mplfe/ast_input/src/ast_expr.cpp b/src/mplfe/ast_input/src/ast_expr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..72a2adb42befc607c8c6e1726cb8dce43a4bbb11 --- /dev/null +++ b/src/mplfe/ast_input/src/ast_expr.cpp @@ -0,0 +1,469 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include "ast_expr.h" +#include "ast_decl.h" +#include "mpl_logging.h" +#include "feir_stmt.h" +#include "feir_builder.h" +#include "fe_utils_ast.h" + +namespace maple { +// ---------- ASTExpr ---------- +UniqueFEIRExpr ASTExpr::Emit2FEExpr() const { + return Emit2FEExprImpl(); +} + +// ---------- ASTRefExpr --------- +UniqueFEIRExpr ASTRefExpr::Emit2FEExprImpl() const { + PrimType primType = var->GetTypeDesc().front()->GetPrimType(); + // A method is required to determine whether the var is global, need to update + UniqueFEIRVar feirVar = FEIRBuilder::CreateVarName(var->GetName(), primType, true, false); + UniqueFEIRExpr feirRefExpr = FEIRBuilder::CreateExprDRead(std::move(feirVar)); + return feirRefExpr; +} + +// ---------- ASTCallExpr ---------- +UniqueFEIRExpr ASTCallExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +// ---------- ASTImplicitCastExpr ---------- +UniqueFEIRExpr ASTImplicitCastExpr::Emit2FEExprImpl() const { + const ASTExpr *childExpr = child; + CHECK_FATAL(childExpr != nullptr, "childExpr is nullptr"); + UniqueFEIRExpr feirImplicitCastExpr = childExpr->Emit2FEExpr(); + return feirImplicitCastExpr; +} + +// ---------- ASTUnaryOperatorExpr ---------- +void ASTUnaryOperatorExpr::SetUOExpr(ASTExpr *astExpr) { + expr = astExpr; +} + +UniqueFEIRExpr ASTUOMinusExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +UniqueFEIRExpr ASTUONotExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +UniqueFEIRExpr ASTUOLNotExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +UniqueFEIRExpr ASTUOPostIncExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +UniqueFEIRExpr ASTUOPostDecExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +UniqueFEIRExpr ASTUOPreIncExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +UniqueFEIRExpr ASTUOPreDecExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +UniqueFEIRExpr ASTUOAddrOfExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +UniqueFEIRExpr ASTUODerefExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +UniqueFEIRExpr ASTUOPlusExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +UniqueFEIRExpr ASTUORealExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +UniqueFEIRExpr ASTUOImagExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +UniqueFEIRExpr ASTUOExtensionExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +UniqueFEIRExpr ASTUOCoawaitExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +// ---------- ASTPredefinedExpr ---------- +UniqueFEIRExpr ASTPredefinedExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +void ASTPredefinedExpr::SetASTExpr(ASTExpr *astExpr) { + child = astExpr; +} + +// ---------- ASTOpaqueValueExpr ---------- +UniqueFEIRExpr ASTOpaqueValueExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +void ASTOpaqueValueExpr::SetASTExpr(ASTExpr *astExpr) { + child = astExpr; +} + +// ---------- ASTBinaryConditionalOperator ---------- +UniqueFEIRExpr ASTBinaryConditionalOperator::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +void ASTBinaryConditionalOperator::SetRetType(MIRType *returnType) { + retType = returnType; +} +void ASTBinaryConditionalOperator::SetCondExpr(ASTExpr *condExpr) { + cExpr = condExpr; +} +void ASTBinaryConditionalOperator::SetFalseExpr(ASTExpr *falseExpr) { + fExpr = falseExpr; +} + +// ---------- ASTNoInitExpr ---------- +UniqueFEIRExpr ASTNoInitExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +void ASTNoInitExpr::SetNoInitType(MIRType *type) { + noInitType = type; +} + +// ---------- ASTCompoundLiteralExpr ---------- +UniqueFEIRExpr ASTCompoundLiteralExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +void ASTCompoundLiteralExpr::SetCompoundLiteralType(MIRType *clType) { + compoundLiteralType = clType; +} + +void ASTCompoundLiteralExpr::SetASTExpr(ASTExpr *astExpr) { + child = astExpr; +} + +// ---------- ASTOffsetOfExpr ---------- +void ASTOffsetOfExpr::SetStructType(MIRType *stype) { + structType = stype; +} + +void ASTOffsetOfExpr::SetFieldName(std::string fName){ + fieldName = fName; +} + +UniqueFEIRExpr ASTOffsetOfExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +// ---------- ASTInitListExpr ---------- +UniqueFEIRExpr ASTInitListExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +void ASTInitListExpr::SetFillerExprs(ASTExpr *astExpr) { + fillers.emplace_back(astExpr); +} + +void ASTInitListExpr::SetInitListType(MIRType *type) { + initListType = type; +} + +// ---------- ASTBinaryOperator ---------- +std::list ASTBinaryOperatorStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +UniqueFEIRExpr ASTImplicitValueInitExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +UniqueFEIRExpr ASTStringLiteral::Emit2FEExprImpl() const { + UniqueFEIRExpr expr = std::make_unique(codeUnits); + CHECK_NULL_FATAL(expr); + return expr; +} + +UniqueFEIRExpr ASTArraySubscriptExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +UniqueFEIRExpr ASTExprUnaryExprOrTypeTraitExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +UniqueFEIRExpr ASTMemberExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +UniqueFEIRExpr ASTDesignatedInitUpdateExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +UniqueFEIRExpr ASTBOAddExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBOMulExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBODivExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBORemExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBOSubExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBOShlExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBOShrExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBOLTExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBOGTExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBOLEExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBOGEExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBOEQExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBONEExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBOAndExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBOXorExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBOOrExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBOLAndExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBOLOrExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBOEqExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBOAssign::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBOComma::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBOPtrMemD::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +UniqueFEIRExpr ASTBOPtrMemI::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +// ---------- ASTParenExpr ---------- +UniqueFEIRExpr ASTParenExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +// ---------- ASTIntegerLiteral ---------- +UniqueFEIRExpr ASTIntegerLiteral::Emit2FEExprImpl() const { + UniqueFEIRExpr constExpr = std::make_unique(val, type); + return constExpr; +} + +// ---------- ASTFloatingLiteral ---------- +UniqueFEIRExpr ASTFloatingLiteral::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +// ---------- ASTCharacterLiteral ---------- +UniqueFEIRExpr ASTCharacterLiteral::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +// ---------- ASTConditionalOperator ---------- +UniqueFEIRExpr ASTConditionalOperator::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +// ---------- ASTConstantExpr ---------- +UniqueFEIRExpr ASTConstantExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +// ---------- ASTImaginaryLiteral ---------- +UniqueFEIRExpr ASTImaginaryLiteral::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +// ---------- ASTCompoundAssignOperatorExpr ---------- +UniqueFEIRExpr ASTCompoundAssignOperatorExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +// ---------- ASTVAArgExpr ---------- +UniqueFEIRExpr ASTVAArgExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +// ---------- ASTCStyleCastExpr ---------- +UniqueFEIRExpr ASTCStyleCastExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NYI"); + return nullptr; +} + +// ---------- ASTArrayInitLoopExpr ---------- +UniqueFEIRExpr ASTArrayInitLoopExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +// ---------- ASTArrayInitIndexExpr ---------- +UniqueFEIRExpr ASTArrayInitIndexExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +// ---------- ASTExprWithCleanups ---------- +UniqueFEIRExpr ASTExprWithCleanups::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +// ---------- ASTMaterializeTemporaryExpr ---------- +UniqueFEIRExpr ASTMaterializeTemporaryExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +// ---------- ASTSubstNonTypeTemplateParmExpr ---------- +UniqueFEIRExpr ASTSubstNonTypeTemplateParmExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +// ---------- ASTDependentScopeDeclRefExpr ---------- +UniqueFEIRExpr ASTDependentScopeDeclRefExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +// ---------- ASTAtomicExpr ---------- +UniqueFEIRExpr ASTAtomicExpr::Emit2FEExprImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} +} + diff --git a/src/mplfe/ast_input/src/ast_function.cpp b/src/mplfe/ast_input/src/ast_function.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d9c1b34e69185043aa491e3ce9fabf7f21cea67d --- /dev/null +++ b/src/mplfe/ast_input/src/ast_function.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include "ast_function.h" +#include "fe_macros.h" +#include "fe_manager.h" + +namespace maple { +ASTFunction::ASTFunction(const ASTFunc2FEHelper &argMethodHelper, MIRFunction &mirFunc, + const std::unique_ptr &argPhaseResultTotal) + : FEFunction(mirFunc, argPhaseResultTotal), + funcHelper(argMethodHelper), + astFunc(funcHelper.GetMethod()) {} + +bool ASTFunction::GenerateArgVarList(const std::string &phaseName) { + phaseResult.RegisterPhaseNameAndStart(phaseName); + argVarList = astFunc.GenArgVarList(); + return phaseResult.Finish(); +} + +bool ASTFunction::GenerateAliasVars(const std::string &phaseName) { + phaseResult.RegisterPhaseNameAndStart(phaseName); + return phaseResult.Finish(true); +} + +bool ASTFunction::EmitToFEIRStmt(const std::string &phaseName) { + phaseResult.RegisterPhaseNameAndStart(phaseName); + std::list feirStmts = astFunc.EmitASTStmtToFEIR(); + AppendFEIRStmts(feirStmts); + return phaseResult.Finish(true); +} + +void ASTFunction::AppendFEIRStmts(std::list &stmts) { + ASSERT_NOT_NULL(feirStmtTail); + InsertFEIRStmtsBefore(*feirStmtTail, stmts); +} + +void ASTFunction::InsertFEIRStmtsBefore(FEIRStmt &pos, std::list &stmts) { + while (stmts.size() > 0) { + FEIRStmt *ptrFEIRStmt = RegisterFEIRStmt(std::move(stmts.front())); + stmts.pop_front(); + pos.InsertBefore(ptrFEIRStmt); + } +} + +void ASTFunction::PreProcessImpl() { + CHECK_FATAL(false, "NIY"); +} + +void ASTFunction::SetMIRFunctionInfo() { + GStrIdx idx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(astFunc.GetName()); + mirFunction.PushbackMIRInfo(MIRInfoPair(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName("INFO_fullname"), idx)); + mirFunction.PushbackIsString(true); +} + +bool ASTFunction::ProcessImpl() { + FE_INFO_LEVEL(FEOptions::kDumpLevelInfoDetail, "ASTFunction::Process() for %s", astFunc.GetName().c_str()); + bool success = true; + SetMIRFunctionInfo(); + success = success && GenerateArgVarList("gen arg var list"); + success = success && EmitToFEIRStmt("emit to feir"); + return success; +} + +bool ASTFunction::ProcessFEIRFunction() { + CHECK_FATAL(false, "NIY"); + return false; +} + +void ASTFunction::FinishImpl() { + (void)EmitToMIR("finish/emit to mir"); + (void)GenerateAliasVars("finish/generate alias vars"); +} + +bool ASTFunction::EmitToMIR(const std::string &phaseName) { + phaseResult.RegisterPhaseNameAndStart(phaseName); + mirFunction.NewBody(); + FEManager::GetMIRBuilder().SetCurrentFunction(mirFunction); + EmitToMIRStmt(); + return phaseResult.Finish(); +} +} // namespace maple diff --git a/src/mplfe/ast_input/src/ast_input.cpp b/src/mplfe/ast_input/src/ast_input.cpp new file mode 100644 index 0000000000000000000000000000000000000000..77673bcf1f2470aa772c3016528246f56c49bc4e --- /dev/null +++ b/src/mplfe/ast_input/src/ast_input.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include "ast_input.h" +#include "global_tables.h" +#include "fe_macros.h" +namespace maple { +ASTInput::ASTInput(MIRModule &moduleIn, MapleAllocator &allocatorIn) + : module(moduleIn), allocator(allocatorIn), astParserMap(allocatorIn.Adapter()), + astStructs(allocatorIn.Adapter()), astFuncs(allocatorIn.Adapter()), astVars(allocatorIn.Adapter()) {} + +bool ASTInput::ReadASTFile(MapleAllocator &allocatorIn, uint32 index, const std::string &fileName) { + ASTParser *astParser = allocator.GetMemPool()->New(allocator, index, fileName); + astParser->SetAstIn(this); + TRY_DO(astParser->OpenFile()); + TRY_DO(astParser->Verify()); + TRY_DO(astParser->PreProcessAST()); + TRY_DO(astParser->RetrieveStructs(allocatorIn, astStructs)); + TRY_DO(astParser->RetrieveFuncs(allocatorIn, astFuncs)); + TRY_DO(astParser->RetrieveGlobalVars(allocatorIn, astVars)); + astParserMap.emplace(fileName, astParser); + return true; +} + +bool ASTInput::ReadASTFiles(MapleAllocator &allocator, const std::vector &fileNames) { + bool res = true; + for (uint32 i = 0; res && i < fileNames.size(); ++i) { + res = res && ReadASTFile(allocator, i, fileNames[i]); + RegisterFileInfo(fileNames[i]); + } + return res; +} + +void ASTInput::RegisterFileInfo(const std::string &fileName) { + GStrIdx fileNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fileName); + GStrIdx fileInfoIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName("INFO_filename"); + module.PushFileInfoPair(MIRInfoPair(fileInfoIdx, fileNameIdx)); + module.PushFileInfoIsString(true); +} +} \ No newline at end of file diff --git a/src/mplfe/ast_input/src/ast_parser.cpp b/src/mplfe/ast_input/src/ast_parser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2d913aadd4f863d7bea7c99d79cfb70bc6facd51 --- /dev/null +++ b/src/mplfe/ast_input/src/ast_parser.cpp @@ -0,0 +1,1466 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include "ast_parser.h" +#include "mpl_logging.h" +#include "mir_module.h" +#include "mpl_logging.h" +#include "ast_decl_builder.h" +#include "ast_interface.h" +#include "ast_decl.h" +#include "ast_macros.h" +#include "ast_util.h" +#include "ast_input.h" +#include "fe_manager.h" + +namespace maple { +bool ASTParser::OpenFile() { + astFile = std::make_unique(); + bool res = astFile->Open(fileName, 0, 0); + if (!res) { + return false; + } + astUnitDecl = astFile->GetAstUnitDecl(); + return true; +} + +bool ASTParser::Verify() { + return true; +} + +#define BO_CASE(CLASS) \ + case clang::BO_##CLASS: \ + return ASTExprBuilder(allocator); + +#define BO_CASE_EXPR(CLASS) \ + case clang::BO_##CLASS: \ + return ASTExprBuilder(allocator); + +ASTBinaryOperatorExpr *ASTParser::AllocBinaryOperatorExpr(MapleAllocator &allocator, const clang::BinaryOperator bo) { + clang::BinaryOperator::Opcode opcode = bo.getOpcode(); + switch (opcode) { + BO_CASE(PtrMemD) // ".*" + BO_CASE(PtrMemI) // "->" + BO_CASE_EXPR(Mul) // "*" + BO_CASE_EXPR(Div) // "/" + BO_CASE_EXPR(Rem) // "%" + BO_CASE_EXPR(Add) // "+" + BO_CASE_EXPR(Sub) // "-" + BO_CASE_EXPR(Shl) // "<<" + BO_CASE_EXPR(Shr) // ">>" + BO_CASE_EXPR(LT) // "<" + BO_CASE_EXPR(GT) // ">" + BO_CASE_EXPR(LE) // "<=" + BO_CASE_EXPR(GE) // ">=" + BO_CASE_EXPR(EQ) // "==" + BO_CASE_EXPR(NE) // "!=" + BO_CASE_EXPR(And) // "&" + BO_CASE_EXPR(Xor) // "^" + BO_CASE_EXPR(Or) // "|" + BO_CASE_EXPR(LAnd) // "&&" + BO_CASE_EXPR(LOr) // "||" + BO_CASE(Assign) // "=" + BO_CASE(Comma) // "," + default: + CHECK_FATAL(false, "NIY"); + return nullptr; + } +} + +ASTStmt *ASTParser::ProcessFunctionBody(MapleAllocator &allocator, const clang::CompoundStmt &compoundStmt) { + CHECK_FATAL(false, "NIY"); + return ProcessStmtCompoundStmt(allocator, compoundStmt); +} + +ASTStmt *ASTParser::ProcessStmtCompoundStmt(MapleAllocator &allocator, const clang::CompoundStmt &cpdStmt) { + ASTCompoundStmt *astCompoundStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astCompoundStmt != nullptr, "astCompoundStmt is nullptr"); + clang::CompoundStmt::const_body_iterator it; + ASTStmt *childStmt = nullptr; + for (it = cpdStmt.body_begin(); it != cpdStmt.body_end(); ++it) { + if (llvm::isa(*it)) { + auto *tmpCpdStmt = llvm::cast(*it); + childStmt = ProcessStmtCompoundStmt(allocator, *tmpCpdStmt); + } else { + childStmt = ProcessStmt(allocator, **it); + } + if (childStmt != nullptr) { + astCompoundStmt->SetASTStmt(childStmt); + } else { + return nullptr; + } + } + return astCompoundStmt; +} + +#define STMT_CASE(CLASS) \ + case clang::Stmt::CLASS##Class: \ + return ProcessStmt##CLASS(allocator, llvm::cast(stmt)); + +ASTStmt *ASTParser::ProcessStmt(MapleAllocator &allocator, const clang::Stmt &stmt) { + switch (stmt.getStmtClass()) { + STMT_CASE(UnaryOperator); + STMT_CASE(BinaryOperator); + STMT_CASE(CompoundAssignOperator); + STMT_CASE(ImplicitCastExpr); + STMT_CASE(ParenExpr); + STMT_CASE(IntegerLiteral); + STMT_CASE(VAArgExpr); + STMT_CASE(ConditionalOperator); + STMT_CASE(CharacterLiteral); + STMT_CASE(StmtExpr); + STMT_CASE(CallExpr); + STMT_CASE(ReturnStmt); + STMT_CASE(CompoundStmt); + STMT_CASE(IfStmt); + STMT_CASE(ForStmt); + STMT_CASE(WhileStmt); + STMT_CASE(DoStmt); + STMT_CASE(BreakStmt); + STMT_CASE(ContinueStmt); + STMT_CASE(GotoStmt); + STMT_CASE(SwitchStmt); + STMT_CASE(CaseStmt); + STMT_CASE(DefaultStmt); + STMT_CASE(CStyleCastExpr); + STMT_CASE(DeclStmt); + STMT_CASE(NullStmt); + default: + CHECK_FATAL(false, "NIY"); + return nullptr; + } +} + +ASTStmt *ASTParser::ProcessStmtUnaryOperator(MapleAllocator &allocator, const clang::UnaryOperator &unaryOp) { + ASTUnaryOperatorStmt *astUOStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astUOStmt != nullptr, "astUOStmt is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, &unaryOp); + if (astExpr == nullptr) { + return nullptr; + } + astUOStmt->SetASTExpr(astExpr); + return astUOStmt; +} + +ASTStmt *ASTParser::ProcessStmtBinaryOperator(MapleAllocator &allocator, const clang::BinaryOperator &binaryOp) { + ASTBinaryOperatorStmt *astBOStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astBOStmt != nullptr, "astBOStmt is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, &binaryOp); + if (astExpr == nullptr) { + return nullptr; + } + astBOStmt->SetASTExpr(astExpr); + return astBOStmt; +} + +ASTStmt *ASTParser::ProcessStmtCallExpr(MapleAllocator &allocator, const clang::CallExpr &callExpr) { + ASTCallExprStmt *astCallExprStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astCallExprStmt != nullptr, "astCallExprStmt is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, &callExpr); + if (astExpr == nullptr) { + return nullptr; + } + astCallExprStmt->SetASTExpr(astExpr); + return astCallExprStmt; +} + +ASTStmt *ASTParser::ProcessStmtImplicitCastExpr(MapleAllocator &allocator, + const clang::ImplicitCastExpr &implicitCastExpr) { + ASTImplicitCastExprStmt *astImplicitCastExprStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astImplicitCastExprStmt != nullptr, "astImplicitCastExprStmt is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, &implicitCastExpr); + if (astExpr == nullptr) { + return nullptr; + } + astImplicitCastExprStmt->SetASTExpr(astExpr); + return astImplicitCastExprStmt; +} + +ASTStmt *ASTParser::ProcessStmtParenExpr(MapleAllocator &allocator, const clang::ParenExpr &parenExpr) { + ASTParenExprStmt *astParenExprStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astParenExprStmt != nullptr, "astCallExprStmt is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, &parenExpr); + if (astExpr == nullptr) { + return nullptr; + } + astParenExprStmt->SetASTExpr(astExpr); + return astParenExprStmt; +} + +ASTStmt *ASTParser::ProcessStmtIntegerLiteral(MapleAllocator &allocator, const clang::IntegerLiteral &integerLiteral) { + ASTIntegerLiteralStmt *astIntegerLiteralStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astIntegerLiteralStmt != nullptr, "astIntegerLiteralStmt is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, &integerLiteral); + if (astExpr == nullptr) { + return nullptr; + } + astIntegerLiteralStmt->SetASTExpr(astExpr); + return astIntegerLiteralStmt; +} + +ASTStmt *ASTParser::ProcessStmtVAArgExpr(MapleAllocator &allocator, const clang::VAArgExpr &vAArgExpr) { + ASTVAArgExprStmt *astVAArgExprStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astVAArgExprStmt != nullptr, "astVAArgExprStmt is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, &vAArgExpr); + if (astExpr == nullptr) { + return nullptr; + } + astVAArgExprStmt->SetASTExpr(astExpr); + return astVAArgExprStmt; +} + +ASTStmt *ASTParser::ProcessStmtConditionalOperator(MapleAllocator &allocator, + const clang::ConditionalOperator &conditionalOperator) { + ASTConditionalOperatorStmt *astConditionalOperatorStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astConditionalOperatorStmt != nullptr, "astConditionalOperatorStmt is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, &conditionalOperator); + if (astExpr == nullptr) { + return nullptr; + } + astConditionalOperatorStmt->SetASTExpr(astExpr); + return astConditionalOperatorStmt; +} + +ASTStmt *ASTParser::ProcessStmtCharacterLiteral(MapleAllocator &allocator, + const clang::CharacterLiteral &characterLiteral) { + ASTCharacterLiteralStmt *astCharacterLiteralStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astCharacterLiteralStmt != nullptr, "astCharacterLiteralStmt is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, &characterLiteral); + if (astExpr == nullptr) { + return nullptr; + } + astCharacterLiteralStmt->SetASTExpr(astExpr); + return astCharacterLiteralStmt; +} + +ASTStmt *ASTParser::ProcessStmtCStyleCastExpr(MapleAllocator &allocator, const clang::CStyleCastExpr &cStyleCastExpr) { + ASTCStyleCastExprStmt *astCStyleCastExprStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astCStyleCastExprStmt != nullptr, "astCStyleCastExprStmt is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, &cStyleCastExpr); + if (astExpr == nullptr) { + return nullptr; + } + astCStyleCastExprStmt->SetASTExpr(astExpr); + return astCStyleCastExprStmt; +} + +ASTStmt *ASTParser::ProcessStmtStmtExpr(MapleAllocator &allocator, const clang::StmtExpr &stmtExpr) { + ASTStmtExprStmt *astStmtExprStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astStmtExprStmt != nullptr, "astStmtExprStmt is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, &stmtExpr); + if (astExpr == nullptr) { + return nullptr; + } + astStmtExprStmt->SetASTExpr(astExpr); + return astStmtExprStmt; +} + +ASTStmt *ASTParser::ProcessStmtCompoundAssignOperator(MapleAllocator &allocator, + const clang::CompoundAssignOperator &cpdAssignOp) { + ASTCompoundAssignOperatorStmt *astCAOStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astCAOStmt != nullptr, "astCAOStmt is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, &cpdAssignOp); + if (astExpr == nullptr) { + return nullptr; + } + astCAOStmt->SetASTExpr(astExpr); + return astCAOStmt; +} + +ASTStmt *ASTParser::ProcessStmtReturnStmt(MapleAllocator &allocator, const clang::ReturnStmt &retStmt) { + ASTReturnStmt *astStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, retStmt.getRetValue()); + if (astExpr == nullptr) { + return nullptr; + } + astStmt->SetASTExpr(astExpr); + return astStmt; +} + +ASTStmt *ASTParser::ProcessStmtIfStmt(MapleAllocator &allocator, const clang::IfStmt &ifStmt) { + auto *astStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, ifStmt.getCond()); + if (astExpr == nullptr) { + return nullptr; + } + astStmt->SetCondExpr(astExpr); + ASTStmt *thenStmt = ProcessStmtCompoundStmt(allocator, *llvm::cast(ifStmt.getThen())); + if (thenStmt == nullptr) { + return nullptr; + } + astStmt->SetThenStmt(thenStmt); + if (ifStmt.hasElseStorage()) { + ASTStmt *elseStmt = ProcessStmtCompoundStmt(allocator, *llvm::cast(ifStmt.getElse())); + if (elseStmt == nullptr) { + return nullptr; + } + astStmt->SetElseStmt(elseStmt); + } + return astStmt; +} + +ASTStmt *ASTParser::ProcessStmtForStmt(MapleAllocator &allocator, const clang::ForStmt &forStmt) { + auto *astStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); + if (forStmt.getInit() != nullptr) { + ASTStmt *initStmt = ProcessStmtCompoundStmt(allocator, *llvm::cast(forStmt.getInit())); + if (initStmt == nullptr) { + return nullptr; + } + astStmt->SetInitStmt(initStmt); + } + if (forStmt.getCond() != nullptr) { + ASTExpr *condExpr = ProcessExpr(allocator, forStmt.getCond()); + if (condExpr == nullptr) { + return nullptr; + } + astStmt->SetCondExpr(condExpr); + } + if (forStmt.getInc() != nullptr) { + ASTExpr *incExpr = ProcessExpr(allocator, forStmt.getInc()); + if (incExpr == nullptr) { + return nullptr; + } + astStmt->SetIncExpr(incExpr); + } + ASTStmt *bodyStmt = ProcessStmtCompoundStmt(allocator, *llvm::cast(forStmt.getBody())); + if (bodyStmt == nullptr) { + return nullptr; + } + astStmt->SetBodyStmt(bodyStmt); + return astStmt; +} + +ASTStmt *ASTParser::ProcessStmtWhileStmt(MapleAllocator &allocator, const clang::WhileStmt &whileStmt) { + ASTWhileStmt *astStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); + ASTExpr *condExpr = ProcessExpr(allocator, whileStmt.getCond()); + if (condExpr == nullptr) { + return nullptr; + } + astStmt->SetCondExpr(condExpr); + ASTStmt *bodyStmt = ProcessStmtCompoundStmt(allocator, *llvm::cast(whileStmt.getBody())); + if (bodyStmt == nullptr) { + return nullptr; + } + astStmt->SetBodyStmt(bodyStmt); + return astStmt; +} + +ASTStmt *ASTParser::ProcessStmtGotoStmt(MapleAllocator &allocator, const clang::GotoStmt &gotoStmt) { + ASTGotoStmt *astStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); + astStmt->SetLabelName(gotoStmt.getLabel()->getNameAsString()); + return astStmt; +} + +bool ASTParser::HasDefault(const clang::Stmt &stmt) { + if (llvm::isa(stmt)) { + return true; + } else if (llvm::isa(stmt)) { + const auto *cpdStmt = llvm::cast(&stmt); + clang::CompoundStmt::const_body_iterator it; + for (it = cpdStmt->body_begin(); it != cpdStmt->body_end(); ++it) { + if (llvm::isa(*it)) { + return true; + } else if (llvm::isa(*it)) { + auto *caseStmt = llvm::cast(*it); + if (HasDefault(*caseStmt->getSubStmt())) { + return true; + } + } + } + } else if (llvm::isa(stmt)) { + const auto *caseStmt = llvm::cast(&stmt); + if (HasDefault(*caseStmt->getSubStmt())) { + return true; + } + } + return false; +} + +ASTStmt *ASTParser::ProcessStmtSwitchStmt(MapleAllocator &allocator, const clang::SwitchStmt &switchStmt) { + // if switch cond expr has var decl, we need to handle it. + ASTSwitchStmt *astStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); + ASTStmt *condStmt = switchStmt.getConditionVariableDeclStmt() == nullptr ? nullptr : + ProcessStmt(allocator, *switchStmt.getConditionVariableDeclStmt()); + astStmt->SetCondStmt(condStmt); + // switch cond expr + ASTExpr *condExpr = switchStmt.getCond() == nullptr ? nullptr : ProcessExpr(allocator, switchStmt.getCond()); + astStmt->SetCondExpr(condExpr); + // switch body stmt + ASTStmt *bodyStmt = switchStmt.getBody() == nullptr ? nullptr : + ProcessStmt(allocator, *switchStmt.getBody()); + astStmt->SetBodyStmt(bodyStmt); + return astStmt; +} + +ASTStmt *ASTParser::ProcessStmtDoStmt(MapleAllocator &allocator, const clang::DoStmt &doStmt) { + ASTDoStmt *astStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); + ASTExpr *condExpr = ProcessExpr(allocator, doStmt.getCond()); + if (condExpr == nullptr) { + return nullptr; + } + astStmt->SetCondExpr(condExpr); + ASTStmt *bodyStmt = ProcessStmtCompoundStmt(allocator, *llvm::cast(doStmt.getBody())); + if (bodyStmt == nullptr) { + return nullptr; + } + astStmt->SetBodyStmt(bodyStmt); + return astStmt; +} + +ASTStmt *ASTParser::ProcessStmtBreakStmt(MapleAllocator &allocator, const clang::BreakStmt &breakStmt) { + auto *astStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); + return astStmt; +} + +ASTStmt *ASTParser::ProcessStmtCaseStmt(MapleAllocator &allocator, const clang::CaseStmt &caseStmt) { + ASTCaseStmt *astStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); + astStmt->SetLHS(ProcessExpr(allocator, caseStmt.getLHS())); + astStmt->SetRHS(ProcessExpr(allocator, caseStmt.getRHS())); + ASTStmt* subStmt = caseStmt.getSubStmt() == nullptr ? nullptr : ProcessStmt(allocator, *caseStmt.getSubStmt()); + astStmt->SetSubStmt(subStmt); + return astStmt; +} + +ASTStmt *ASTParser::ProcessStmtDefaultStmt(MapleAllocator &allocator, const clang::DefaultStmt &defaultStmt) { + ASTDefaultStmt *astStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); + auto *subStmt = defaultStmt.getSubStmt() == nullptr ? nullptr : ProcessStmt(allocator, *defaultStmt.getSubStmt()); + astStmt->SetChildStmt(subStmt); + return astStmt; +} + +ASTStmt *ASTParser::ProcessStmtNullStmt(MapleAllocator &allocator, const clang::NullStmt &nullStmt) { + ASTNullStmt *astStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); + return astStmt; +} + +ASTStmt *ASTParser::ProcessStmtContinueStmt(MapleAllocator &allocator, const clang::ContinueStmt &continueStmt) { + auto *astStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); + return astStmt; +} + +ASTStmt *ASTParser::ProcessStmtDeclStmt(MapleAllocator &allocator, const clang::DeclStmt &declStmt) { + ASTDeclStmt *astStmt = ASTStmtBuilder(allocator); + CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); + if (declStmt.isSingleDecl()) { + const clang::Decl *decl = declStmt.getSingleDecl(); + if (decl != nullptr) { + ASTDecl *ad = ProcessDecl(allocator, *decl); + if (ad != nullptr) { + astStmt->SetSubDecl(ad); + } + } + } else { + // multiple decls + clang::DeclGroupRef declGroupRef = declStmt.getDeclGroup(); + clang::DeclGroupRef::const_iterator it; + for (it = declGroupRef.begin(); it != declGroupRef.end(); ++it) { + ASTDecl *ad = ProcessDecl(allocator, **it); + if (ad != nullptr) { + astStmt->SetSubDecl(ad); + } + } + } + return astStmt; +} + +#define EXPR_CASE(CLASS) \ + case clang::Stmt::CLASS##Class: \ + return ProcessExpr##CLASS(allocator, llvm::cast(*expr)); +ASTExpr *ASTParser::ProcessExpr(MapleAllocator &allocator, const clang::Expr *expr) { + if (expr == nullptr) { + return nullptr; + } + switch (expr->getStmtClass()) { + EXPR_CASE(UnaryOperator); + EXPR_CASE(NoInitExpr); + EXPR_CASE(PredefinedExpr); + EXPR_CASE(OpaqueValueExpr); + EXPR_CASE(BinaryConditionalOperator); + EXPR_CASE(CompoundLiteralExpr); + EXPR_CASE(OffsetOfExpr); + EXPR_CASE(InitListExpr); + EXPR_CASE(BinaryOperator); + EXPR_CASE(ImplicitValueInitExpr); + EXPR_CASE(ArraySubscriptExpr); + EXPR_CASE(UnaryExprOrTypeTraitExpr); + EXPR_CASE(MemberExpr); + EXPR_CASE(DesignatedInitUpdateExpr); + EXPR_CASE(ImplicitCastExpr); + EXPR_CASE(DeclRefExpr); + EXPR_CASE(ParenExpr); + EXPR_CASE(IntegerLiteral); + EXPR_CASE(CharacterLiteral); + EXPR_CASE(StringLiteral); + EXPR_CASE(FloatingLiteral); + EXPR_CASE(ConditionalOperator); + EXPR_CASE(VAArgExpr); + EXPR_CASE(GNUNullExpr); + EXPR_CASE(SizeOfPackExpr); + EXPR_CASE(UserDefinedLiteral); + EXPR_CASE(ShuffleVectorExpr); + EXPR_CASE(TypeTraitExpr); + EXPR_CASE(ConstantExpr); + EXPR_CASE(ImaginaryLiteral); + EXPR_CASE(CallExpr); + EXPR_CASE(CompoundAssignOperator); + EXPR_CASE(StmtExpr); + EXPR_CASE(CStyleCastExpr); + EXPR_CASE(ArrayInitLoopExpr); + EXPR_CASE(ArrayInitIndexExpr); + EXPR_CASE(ExprWithCleanups); + EXPR_CASE(MaterializeTemporaryExpr); + EXPR_CASE(SubstNonTypeTemplateParmExpr); + EXPR_CASE(DependentScopeDeclRefExpr); + EXPR_CASE(AtomicExpr); + default: + CHECK_FATAL(false, "NIY"); + return nullptr; + } +} + +ASTUnaryOperatorExpr *ASTParser::AllocUnaryOperatorExpr(MapleAllocator &allocator, const clang::UnaryOperator &expr) { + clang::UnaryOperator::Opcode clangOpCode = expr.getOpcode(); + switch (clangOpCode) { + case clang::UO_Minus: // "-" + return ASTExprBuilder(allocator); + case clang::UO_Not: // "~" + return ASTExprBuilder(allocator); + case clang::UO_LNot: // "!" + return ASTExprBuilder(allocator); + case clang::UO_PostInc: // "++" + return ASTExprBuilder(allocator); + case clang::UO_PostDec: // "--" + return ASTExprBuilder(allocator); + case clang::UO_PreInc: // "++" + return ASTExprBuilder(allocator); + case clang::UO_PreDec: // "--" + return ASTExprBuilder(allocator); + case clang::UO_AddrOf: // "&" + return ASTExprBuilder(allocator); + case clang::UO_Deref: // "*" + return ASTExprBuilder(allocator); + case clang::UO_Plus: // "+" + return ASTExprBuilder(allocator); + case clang::UO_Real: // "__real" + return ASTExprBuilder(allocator); + case clang::UO_Imag: // "__imag" + return ASTExprBuilder(allocator); + case clang::UO_Extension: // "__extension__" + return ASTExprBuilder(allocator); + case clang::UO_Coawait: // "co_await" + return ASTExprBuilder(allocator); + default: + CHECK_FATAL(false, "NYI"); + } +} + +const clang::Expr *ASTParser::PeelParen(const clang::Expr &expr) { + const clang::Expr *exprPtr = &expr; + while (llvm::isa(exprPtr) || + (llvm::isa(exprPtr) && + llvm::cast(exprPtr)->getOpcode() == clang::UO_Extension)) { + if (llvm::isa(exprPtr)) { + exprPtr = llvm::cast(exprPtr)->getSubExpr(); + } else { + exprPtr = llvm::cast(exprPtr)->getSubExpr(); + } + } + return exprPtr; +} + +ASTExpr *ASTParser::ProcessExprUnaryOperator(MapleAllocator &allocator, const clang::UnaryOperator &uo) { + ASTUnaryOperatorExpr *astUOExpr = AllocUnaryOperatorExpr(allocator, uo); + CHECK_FATAL(astUOExpr != nullptr, "astUOExpr is nullptr"); + const clang::Expr *subExpr = PeelParen(*uo.getSubExpr()); + ASTExpr *astExpr = ProcessExpr(allocator, subExpr); + if (astExpr == nullptr) { + return nullptr; + } + astUOExpr->SetUOExpr(astExpr); + return astUOExpr; +} + +ASTExpr *ASTParser::ProcessExprNoInitExpr(MapleAllocator &allocator, const clang::NoInitExpr &expr) { + ASTNoInitExpr *astNoInitExpr = ASTExprBuilder(allocator); + CHECK_FATAL(astNoInitExpr != nullptr, "astPredefinedExpr is nullptr"); + clang::QualType qualType = expr.getType(); + MIRType *noInitType = astFile->CvtType(qualType); + astNoInitExpr->SetNoInitType(noInitType); + return astNoInitExpr; +} + +ASTExpr *ASTParser::ProcessExprPredefinedExpr(MapleAllocator &allocator, const clang::PredefinedExpr &expr) { + ASTPredefinedExpr *astPredefinedExpr = ASTExprBuilder(allocator); + CHECK_FATAL(astPredefinedExpr != nullptr, "astPredefinedExpr is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, expr.getFunctionName()); + if (astExpr == nullptr) { + return nullptr; + } + astPredefinedExpr->SetASTExpr(astExpr); + return astPredefinedExpr; +} + +ASTExpr *ASTParser::ProcessExprOpaqueValueExpr(MapleAllocator &allocator, const clang::OpaqueValueExpr &expr) { + ASTOpaqueValueExpr *astOpaqueValueExpr = ASTExprBuilder(allocator); + CHECK_FATAL(astOpaqueValueExpr != nullptr, "astOpaqueValueExpr is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, expr.getSourceExpr()); + if (astExpr == nullptr) { + return nullptr; + } + astOpaqueValueExpr->SetASTExpr(astExpr); + return astOpaqueValueExpr; +} + +ASTExpr *ASTParser::ProcessExprBinaryConditionalOperator(MapleAllocator &allocator, + const clang::BinaryConditionalOperator &expr) { + ASTBinaryConditionalOperator *astBinaryConditionalOperator = ASTExprBuilder(allocator); + CHECK_FATAL(astBinaryConditionalOperator != nullptr, "astBinaryConditionalOperator is nullptr"); + ASTExpr *condExpr = ProcessExpr(allocator, expr.getCond()); + if (condExpr == nullptr) { + return nullptr; + } + astBinaryConditionalOperator->SetCondExpr(condExpr); + ASTExpr *falseExpr = ProcessExpr(allocator, expr.getFalseExpr()); + if (falseExpr == nullptr) { + return nullptr; + } + astBinaryConditionalOperator->SetFalseExpr(falseExpr); + astBinaryConditionalOperator->SetRetType(astFile->CvtType(expr.getFalseExpr()->getType())); + return astBinaryConditionalOperator; +} + +ASTExpr *ASTParser::ProcessExprCompoundLiteralExpr(MapleAllocator &allocator, + const clang::CompoundLiteralExpr &expr) { + ASTCompoundLiteralExpr *astCompoundLiteralExpr = ASTExprBuilder(allocator); + CHECK_FATAL(astCompoundLiteralExpr != nullptr, "astCompoundLiteralExpr is nullptr"); + const clang::Expr *initExpr = expr.getInitializer(); + CHECK_FATAL(initExpr != nullptr, "initExpr is nullptr"); + clang::QualType qualType = initExpr->getType(); + astCompoundLiteralExpr->SetCompoundLiteralType(astFile->CvtType(qualType)); + + const auto *initListExpr = llvm::dyn_cast(initExpr); + ASTExpr *astExpr = nullptr; + if (initListExpr != nullptr) { + astExpr = ProcessExpr(allocator, initListExpr); + } else { + astExpr = ProcessExpr(allocator, initExpr); + } + if (astExpr == nullptr) { + return nullptr; + } + astCompoundLiteralExpr->SetASTExpr(astExpr); + return astCompoundLiteralExpr; +} + +ASTExpr *ASTParser::ProcessExprInitListExpr(MapleAllocator &allocator, const clang::InitListExpr &expr) { + ASTInitListExpr *astInitListExpr = ASTExprBuilder(allocator); + CHECK_FATAL(astInitListExpr != nullptr, "ASTInitListExpr is nullptr"); + MIRType *initListType = astFile->CvtType(expr.getType()); + astInitListExpr->SetInitListType(initListType); + uint32 n = expr.getNumInits(); + clang::Expr * const *le = expr.getInits(); + for (uint32 i = 0; i < n; ++i) { + const clang::Expr *eExpr = expr.hasArrayFiller() ? expr.getArrayFiller() : le[i]; + ASTExpr *astExpr = ProcessExpr(allocator, eExpr); + if (astExpr == nullptr) { + return nullptr; + } + astInitListExpr->SetFillerExprs(astExpr); + } + return astInitListExpr; +} + +ASTExpr *ASTParser::ProcessExprOffsetOfExpr(MapleAllocator &allocator, const clang::OffsetOfExpr &expr) {\ + ASTOffsetOfExpr *astOffsetOfExpr = ASTExprBuilder(allocator); + CHECK_FATAL(astOffsetOfExpr != nullptr, "astOffsetOfExpr is nullptr"); + clang::FieldDecl *field = expr.getComponent(0).getField(); + // structType should get from global struct map, temporarily don't have + MIRType *structType = astFile->CvtType(field->getParent()->getTypeForDecl()->getCanonicalTypeInternal()); + astOffsetOfExpr->SetStructType(structType); + std::string filedName = astFile->GetMangledName(*field); + astOffsetOfExpr->SetFieldName(filedName); + return astOffsetOfExpr; +} + +ASTExpr *ASTParser::ProcessExprVAArgExpr(MapleAllocator &allocator, const clang::VAArgExpr &expr) { + ASTVAArgExpr *astVAArgExpr = ASTExprBuilder(allocator); + ASSERT(astVAArgExpr != nullptr, "astVAArgExpr is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, expr.getSubExpr()); + if (astExpr == nullptr) { + return nullptr; + } + astVAArgExpr->SetASTExpr(astExpr); + return astVAArgExpr; +} + +ASTExpr *ASTParser::ProcessExprImplicitValueInitExpr(MapleAllocator &allocator, + const clang::ImplicitValueInitExpr &expr) { + auto *astImplicitValueInitExpr = ASTExprBuilder(allocator); + CHECK_FATAL(astImplicitValueInitExpr != nullptr, "astImplicitValueInitExpr is nullptr"); + astImplicitValueInitExpr->SetType(astFile->CvtType(expr.getType())); + return astImplicitValueInitExpr; +} + +ASTExpr *ASTParser::ProcessExprStringLiteral(MapleAllocator &allocator, const clang::StringLiteral &expr) { + auto *astStringLiteral = ASTExprBuilder(allocator); + CHECK_FATAL(astStringLiteral != nullptr, "astStringLiteral is nullptr"); + astStringLiteral->SetType(astFile->CvtType(expr.getType())); + astStringLiteral->SetLength(expr.getLength()); + std::vector codeUnits; + for (size_t i = 0; i < expr.getLength(); ++i) { + codeUnits.emplace_back(expr.getCodeUnit(i)); + } + codeUnits.emplace_back(0); + astStringLiteral->SetCodeUnits(codeUnits); + return astStringLiteral; +} + +ASTExpr *ASTParser::ProcessExprArraySubscriptExpr(MapleAllocator &allocator, const clang::ArraySubscriptExpr &expr) { + auto *astArraySubscriptExpr = ASTExprBuilder(allocator); + CHECK_FATAL(astArraySubscriptExpr != nullptr, "astArraySubscriptExpr is nullptr"); + ASTExpr *baseExpr = ProcessExpr(allocator, expr.getBase()); + if (baseExpr == nullptr) { + return nullptr; + } + astArraySubscriptExpr->SetBaseExpr(baseExpr); + ASTExpr *idxExpr = ProcessExpr(allocator, expr.getIdx()); + if (idxExpr == nullptr) { + return nullptr; + } + astArraySubscriptExpr->SetIdxExpr(idxExpr); + return astArraySubscriptExpr; +} + +ASTExpr *ASTParser::ProcessExprUnaryExprOrTypeTraitExpr(MapleAllocator &allocator, + const clang::UnaryExprOrTypeTraitExpr &expr) { + auto *astExprUnaryExprOrTypeTraitExpr = ASTExprBuilder(allocator); + CHECK_FATAL(astExprUnaryExprOrTypeTraitExpr != nullptr, "astExprUnaryExprOrTypeTraitExpr is nullptr"); + if (expr.isArgumentType()) { + astExprUnaryExprOrTypeTraitExpr->SetIsType(true); + astExprUnaryExprOrTypeTraitExpr->SetArgType(astFile->CvtType(expr.getArgumentType())); + } else { + ASTExpr *argExpr = ProcessExpr(allocator, expr.getArgumentExpr()); + if (argExpr == nullptr) { + return nullptr; + } + astExprUnaryExprOrTypeTraitExpr->SetArgExpr(argExpr); + } + return astExprUnaryExprOrTypeTraitExpr; +} + +ASTExpr *ASTParser::ProcessExprMemberExpr(MapleAllocator &allocator, const clang::MemberExpr &expr) { + auto *astMemberExpr = ASTExprBuilder(allocator); + CHECK_FATAL(astMemberExpr != nullptr, "astMemberExpr is nullptr"); + ASTExpr *baseExpr = ProcessExpr(allocator, expr.getBase()); + if (baseExpr == nullptr) { + return nullptr; + } + astMemberExpr->SetBaseExpr(baseExpr); + clang::ValueDecl *memberDecl = expr.getMemberDecl(); + std::string memberName = astFile->GetMangledName(*memberDecl); + astMemberExpr->SetMemberName(memberName); + astMemberExpr->SetIsArrow(expr.isArrow()); + return astMemberExpr; +} + +ASTExpr *ASTParser::ProcessExprDesignatedInitUpdateExpr(MapleAllocator &allocator, + const clang::DesignatedInitUpdateExpr &expr) { + auto *astDesignatedInitUpdateExpr = ASTExprBuilder(allocator); + CHECK_FATAL(astDesignatedInitUpdateExpr != nullptr, "astDesignatedInitUpdateExpr is nullptr"); + ASTExpr *baseExpr = ProcessExpr(allocator, expr.getBase()); + if (baseExpr == nullptr) { + return nullptr; + } + astDesignatedInitUpdateExpr->SetBaseExpr(baseExpr); + ASTExpr *updaterExpr = ProcessExpr(allocator, expr.getUpdater()); + if (updaterExpr == nullptr) { + return nullptr; + } + astDesignatedInitUpdateExpr->SetUpdaterExpr(updaterExpr); + return astDesignatedInitUpdateExpr; +} + +ASTExpr *ASTParser::ProcessExprStmtExpr(MapleAllocator &allocator, const clang::StmtExpr &expr) { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +ASTExpr *ASTParser::ProcessExprConditionalOperator(MapleAllocator &allocator, const clang::ConditionalOperator &expr) { + ASTConditionalOperator *astConditionalOperator = ASTExprBuilder(allocator); + ASSERT(astConditionalOperator != nullptr, "astConditionalOperator is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, expr.getCond()); + if (astExpr == nullptr) { + return nullptr; + } + astConditionalOperator->SetCondExpr(astExpr); + ASTExpr *astTrueExpr = ProcessExpr(allocator, expr.getTrueExpr()); + if (astTrueExpr == nullptr) { + return nullptr; + } + astConditionalOperator->SetTrueExpr(astTrueExpr); + ASTExpr *astFalseExpr = ProcessExpr(allocator, expr.getFalseExpr()); + if (astFalseExpr == nullptr) { + return nullptr; + } + astConditionalOperator->SetFalseExpr(astFalseExpr); + return astConditionalOperator; +} + +ASTExpr *ASTParser::ProcessExprCompoundAssignOperator(MapleAllocator &allocator, + const clang::CompoundAssignOperator &expr) { + ASTCompoundAssignOperatorExpr *astCompoundAssignOperatorExpr = + ASTExprBuilder(allocator); + ASSERT(astCompoundAssignOperatorExpr != nullptr, "astCompoundAssignOperatorExpr is nullptr"); + clang::Expr *lExpr = expr.getLHS(); + if (lExpr != nullptr) { + ASTExpr *astLExpr = ProcessExpr(allocator, lExpr); + if (astLExpr != nullptr) { + astCompoundAssignOperatorExpr->SetLeftExpr(astLExpr); + } else { + return nullptr; + } + } + clang::Expr *rExpr = expr.getRHS(); + if (rExpr != nullptr) { + ASTExpr *astRExpr = ProcessExpr(allocator, rExpr); + if (astRExpr != nullptr) { + astCompoundAssignOperatorExpr->SetRightExpr(astRExpr); + } else { + return nullptr; + } + } + return astCompoundAssignOperatorExpr; +} + +ASTExpr *ASTParser::ProcessExprSizeOfPackExpr(MapleAllocator &allocator, const clang::SizeOfPackExpr &expr) { + // CXX feature + (void)allocator; + (void)expr; + return nullptr; +} + +ASTExpr *ASTParser::ProcessExprUserDefinedLiteral(MapleAllocator &allocator, const clang::UserDefinedLiteral &expr) { + // CXX feature + (void)allocator; + (void)expr; + return nullptr; +} + +ASTExpr *ASTParser::ProcessExprTypeTraitExpr(MapleAllocator &allocator, const clang::TypeTraitExpr &expr) { + // CXX feature + (void)allocator; + (void)expr; + return nullptr; +} + +ASTExpr *ASTParser::ProcessExprShuffleVectorExpr(MapleAllocator &allocator, const clang::ShuffleVectorExpr &expr) { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +ASTExpr *ASTParser::ProcessExprGNUNullExpr(MapleAllocator &allocator, const clang::GNUNullExpr &expr) { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +ASTExpr *ASTParser::ProcessExprConstantExpr(MapleAllocator &allocator, const clang::ConstantExpr &expr) { + ASTConstantExpr *astConstantExpr = ASTExprBuilder(allocator); + ASSERT(astConstantExpr != nullptr, "astConstantExpr is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, expr.getSubExpr()); + if (astExpr == nullptr) { + return nullptr; + } + astConstantExpr->SetASTExpr(astExpr); + return astConstantExpr; +} + +ASTExpr *ASTParser::ProcessExprImaginaryLiteral(MapleAllocator &allocator, const clang::ImaginaryLiteral &expr) { + ASTImaginaryLiteral *astImaginaryLiteral = ASTExprBuilder(allocator); + ASSERT(astImaginaryLiteral != nullptr, "astImaginaryLiteral is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, expr.getSubExpr()); + if (astExpr == nullptr) { + return nullptr; + } + astImaginaryLiteral->SetASTExpr(astExpr); + return astImaginaryLiteral; +} + +ASTExpr *ASTParser::ProcessExprCallExpr(MapleAllocator &allocator, const clang::CallExpr &expr) { + ASTCallExpr *astCallExpr = ASTExprBuilder(allocator); + ASSERT(astCallExpr != nullptr, "astCallExpr is nullptr"); + // callee + ASTExpr *astCallee = ProcessExpr(allocator, expr.getCallee()); + if (astCallee == nullptr) { + return nullptr; + } + astCallExpr->SetCalleeExpr(astCallee); + // return + MIRType *retType = astFile->CvtType(expr.getCallReturnType(*astFile->GetAstContext())); + astCallExpr->SetRetType(retType); + // args + std::vector args; + for (uint32_t i = 0; i < expr.getNumArgs(); ++i) { + const clang::Expr *subExpr = expr.getArg(i); + ASTExpr *arg = ProcessExpr(allocator, subExpr); + args.push_back(arg); + } + astCallExpr->SetArgs(args); + // Obtain the function name directly + const clang::FunctionDecl *funcDecl = expr.getDirectCallee(); + if (funcDecl != nullptr) { + std::string funcName = astFile->GetMangledName(*funcDecl); + if (!ASTUtil::IsValidName(funcName)) { + ASTUtil::AdjustName(funcName); + } + astCallExpr->SetFuncName(funcName); + } else { + CHECK_FATAL(false, "funcDecl is nullptr NYI."); + } + return astCallExpr; +} + +ASTExpr *ASTParser::ProcessExprParenExpr(MapleAllocator &allocator, const clang::ParenExpr &expr) { + ASTParenExpr *astParenExpr = ASTExprBuilder(allocator); + ASSERT(astParenExpr != nullptr, "astParenExpr is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, expr.getSubExpr()); + if (astExpr == nullptr) { + return nullptr; + } + astParenExpr->SetASTExpr(astExpr); + return astParenExpr; +} + +ASTExpr *ASTParser::ProcessExprCharacterLiteral(MapleAllocator &allocator, const clang::CharacterLiteral &expr) { + ASTCharacterLiteral *astCharacterLiteral = ASTExprBuilder(allocator); + ASSERT(astCharacterLiteral != nullptr, "astCharacterLiteral is nullptr"); + return astCharacterLiteral; +} + +ASTExpr *ASTParser::ProcessExprIntegerLiteral(MapleAllocator &allocator, const clang::IntegerLiteral &expr) { + ASTIntegerLiteral *astIntegerLiteral = ASTExprBuilder(allocator); + ASSERT(astIntegerLiteral != nullptr, "astIntegerLiteral is nullptr"); + uint64 val = 0; + MIRType *type; + llvm::APInt api = expr.getValue(); + if (api.getBitWidth() > kInt32Width) { + val = *api.getRawData(); + type = expr.getType()->isSignedIntegerOrEnumerationType() ? + GlobalTables::GetTypeTable().GetInt64() : GlobalTables::GetTypeTable().GetUInt64(); + } else { + val = (*api.getRawData() & kInt32Mask); + type = expr.getType()->isSignedIntegerOrEnumerationType() ? + GlobalTables::GetTypeTable().GetInt32() : GlobalTables::GetTypeTable().GetUInt32(); + } + astIntegerLiteral->SetVal(val); + astIntegerLiteral->SetType(type->GetPrimType()); + return astIntegerLiteral; +} + +ASTExpr *ASTParser::ProcessExprFloatingLiteral(MapleAllocator &allocator, const clang::FloatingLiteral &expr) { + ASTFloatingLiteral *astFloatingLiteral = ASTExprBuilder(allocator); + ASSERT(astFloatingLiteral != nullptr, "astFloatingLiteral is nullptr"); + llvm::APFloat apf = expr.getValue(); + const llvm::fltSemantics &fltSem = expr.getSemantics(); + if ((&fltSem != &llvm::APFloat::IEEEsingle()) && (&fltSem != &llvm::APFloat::IEEEdouble())) { + ASSERT(false, "unsupported floating literal"); + } + double val = ((&fltSem == &llvm::APFloat::IEEEdouble()) ? static_cast(apf.convertToDouble()) + : static_cast(apf.convertToFloat())); + astFloatingLiteral->SetVal(val); + return astFloatingLiteral; +} + +ASTExpr *ASTParser::ProcessExprImplicitCastExpr(MapleAllocator &allocator, const clang::ImplicitCastExpr &expr) { + ASTImplicitCastExpr *astImplicitCastExpr = ASTExprBuilder(allocator); + CHECK_FATAL(astImplicitCastExpr != nullptr, "astImplicitCastExpr is nullptr"); + switch (expr.getCastKind()) { + case clang::CK_NoOp: + case clang::CK_ArrayToPointerDecay: + case clang::CK_FunctionToPointerDecay: + case clang::CK_FloatingCast: + case clang::CK_LValueToRValue: { + ASTExpr *astExpr = ProcessExpr(allocator, expr.getSubExpr()); + if (astExpr == nullptr) { + return nullptr; + } + astImplicitCastExpr->SetASTExpr(astExpr); + break; + } + default: + CHECK_FATAL(false, "NIY"); + return nullptr; + } + return astImplicitCastExpr; +} + +ASTExpr *ASTParser::ProcessExprDeclRefExpr(MapleAllocator &allocator, const clang::DeclRefExpr &expr) { + ASTRefExpr *astRefExpr = ASTExprBuilder(allocator); + CHECK_FATAL(astRefExpr != nullptr, "astRefExpr is nullptr"); + switch (expr.getStmtClass()) { + case clang::Stmt::DeclRefExprClass: { + const auto *namedDecl = llvm::dyn_cast(expr.getDecl()->getCanonicalDecl()); + std::string refName = astFile->GetMangledName(*namedDecl); + clang::QualType qualType = expr.getDecl()->getType(); + MIRType *refType = astFile->CvtType(qualType); + ASTDecl *astDecl = ASTDeclBuilder(allocator, fileName, refName, std::vector{refType}); + astRefExpr->SetASTDecl(astDecl); + return astRefExpr; + } + default: + CHECK_FATAL(false, "NIY"); + return nullptr; + } + return nullptr; +} + +ASTExpr *ASTParser::ProcessExprBinaryOperator(MapleAllocator &allocator, const clang::BinaryOperator &bo) { + ASTBinaryOperatorExpr *astBinOpExpr = AllocBinaryOperatorExpr(allocator, bo); + CHECK_FATAL(astBinOpExpr != nullptr, "astBinOpExpr is nullptr"); + clang::QualType qualType = bo.getType(); + // Complex type + if (qualType->isAnyComplexType()) { + CHECK_FATAL(false, "NIY"); + } + + MIRType *retType = astFile->CvtType(qualType); + if (retType == nullptr) { + return nullptr; + } + astBinOpExpr->SetRetType(retType); + + clang::Expr *lExpr = bo.getLHS(); + if (lExpr != nullptr) { + ASTExpr *astLExpr = ProcessExpr(allocator, lExpr); + if (astLExpr != nullptr) { + astBinOpExpr->SetLeftExpr(astLExpr); + } else { + return nullptr; + } + } + clang::Expr *rExpr = bo.getRHS(); + if (rExpr != nullptr) { + ASTExpr *astRExpr = ProcessExpr(allocator, rExpr); + if (astRExpr != nullptr) { + astBinOpExpr->SetRightExpr(astRExpr); + } else { + return nullptr; + } + } + return astBinOpExpr; +} + +ASTExpr *ASTParser::ProcessExprCStyleCastExpr(MapleAllocator &allocator, const clang::CStyleCastExpr &castExpr) { + ASTCStyleCastExpr *astCastExpr = ASTExprBuilder(allocator); + CHECK_FATAL(astCastExpr != nullptr, "astCastExpr is nullptr"); + astCastExpr->SetSrcType(astFile->CvtType(castExpr.getSubExpr()->getType())); + astCastExpr->SetDestType(astFile->CvtType(castExpr.getType())); + astCastExpr->SetSubExpr(ProcessExpr(allocator, castExpr.getSubExpr())); + return astCastExpr; +} + +ASTExpr *ASTParser::ProcessExprArrayInitLoopExpr(MapleAllocator &allocator, + const clang::ArrayInitLoopExpr &arrInitLoopExpr) { + ASTArrayInitLoopExpr *astExpr = ASTExprBuilder(allocator); + CHECK_FATAL(astExpr != nullptr, "astCastExpr is nullptr"); + ASTExpr *common = arrInitLoopExpr.getCommonExpr() == nullptr ? nullptr : + ProcessExpr(allocator, arrInitLoopExpr.getCommonExpr()); + astExpr->SetCommonExpr(common); + return astExpr; +} + +ASTExpr *ASTParser::ProcessExprArrayInitIndexExpr(MapleAllocator &allocator, + const clang::ArrayInitIndexExpr &arrInitIndexExpr) { + ASTArrayInitIndexExpr *astExpr = ASTExprBuilder(allocator); + CHECK_FATAL(astExpr != nullptr, "astCastExpr is nullptr"); + astExpr->SetPrimType(astFile->CvtType(arrInitIndexExpr.getType())); + astExpr->SetValue("0"); + return astExpr; +} + +ASTExpr *ASTParser::ProcessExprAtomicExpr(MapleAllocator &allocator, + const clang::AtomicExpr &atomicExpr) { + ASTAtomicExpr *astExpr = ASTExprBuilder(allocator); + CHECK_FATAL(astExpr != nullptr, "astCastExpr is nullptr"); + astExpr->SetType(astFile->CvtType(atomicExpr.getPtr()->getType())); + astExpr->SetRefType(astFile->CvtType(atomicExpr.getPtr()->getType()->getPointeeType())); + switch (atomicExpr.getOp()) { + case clang::AtomicExpr::AO__atomic_add_fetch: + case clang::AtomicExpr::AO__atomic_fetch_add: + case clang::AtomicExpr::AO__c11_atomic_fetch_add: + astExpr->SetAtomicOp(kAtomicBinaryOpAdd); + break; + case clang::AtomicExpr::AO__atomic_sub_fetch: + case clang::AtomicExpr::AO__atomic_fetch_sub: + case clang::AtomicExpr::AO__c11_atomic_fetch_sub: + astExpr->SetAtomicOp(kAtomicBinaryOpSub); + break; + case clang::AtomicExpr::AO__atomic_and_fetch: + case clang::AtomicExpr::AO__atomic_fetch_and: + case clang::AtomicExpr::AO__c11_atomic_fetch_and: + astExpr->SetAtomicOp(kAtomicBinaryOpAnd); + break; + case clang::AtomicExpr::AO__atomic_or_fetch: + case clang::AtomicExpr::AO__atomic_fetch_or: + case clang::AtomicExpr::AO__c11_atomic_fetch_or: + astExpr->SetAtomicOp(kAtomicBinaryOpOr); + break; + case clang::AtomicExpr::AO__atomic_xor_fetch: + case clang::AtomicExpr::AO__atomic_fetch_xor: + case clang::AtomicExpr::AO__c11_atomic_fetch_xor: + astExpr->SetAtomicOp(kAtomicBinaryOpXor); + break; + case clang::AtomicExpr::AO__atomic_load_n: + case clang::AtomicExpr::AO__c11_atomic_load: + astExpr->SetAtomicOp(kAtomicOpLoad); + break; + case clang::AtomicExpr::AO__c11_atomic_store: + astExpr->SetAtomicOp(kAtomicOpStore); + break; + case clang::AtomicExpr::AO__c11_atomic_exchange: + astExpr->SetAtomicOp(kAtomicOpExchange); + break; + case clang::AtomicExpr::AO__atomic_compare_exchange_n: + case clang::AtomicExpr::AO__c11_atomic_compare_exchange_weak: + case clang::AtomicExpr::AO__c11_atomic_compare_exchange_strong: + astExpr->SetAtomicOp(kAtomicOpCompareExchange); + break; + default: + astExpr->SetAtomicOp(kAtomicOpLast); + break; + } + return astExpr; +} + +ASTExpr *ASTParser::ProcessExprExprWithCleanups(MapleAllocator &allocator, + const clang::ExprWithCleanups &cleanupsExpr) { + ASTExprWithCleanups *astExpr = ASTExprBuilder(allocator); + CHECK_FATAL(astExpr != nullptr, "astCastExpr is nullptr"); + ASTExpr *sub = cleanupsExpr.getSubExpr() == nullptr ? nullptr : ProcessExpr(allocator, cleanupsExpr.getSubExpr()); + astExpr->SetSubExpr(sub); + return astExpr; +} + +ASTExpr *ASTParser::ProcessExprMaterializeTemporaryExpr(MapleAllocator &allocator, + const clang::MaterializeTemporaryExpr &matTempExpr) { + // cxx feature + (void)allocator; + (void)matTempExpr; + return nullptr; +} + +ASTExpr *ASTParser::ProcessExprSubstNonTypeTemplateParmExpr(MapleAllocator &allocator, + const clang::SubstNonTypeTemplateParmExpr &subTempExpr) { + // cxx feature + (void)allocator; + (void)subTempExpr; + return nullptr; +} + +ASTExpr *ASTParser::ProcessExprDependentScopeDeclRefExpr(MapleAllocator &allocator, + const clang::DependentScopeDeclRefExpr &depScopeExpr) { + // cxx feature + (void)allocator; + (void)depScopeExpr; + return nullptr; +} + +bool ASTParser::PreProcessAST() { + TraverseDecl(astUnitDecl, [&](clang::Decl *child) { + switch (child->getKind()) { + case clang::Decl::Var: { + globalVarDecles.emplace_back(child); + break; + } + case clang::Decl::Function: { + funcDecles.emplace_back(child); + break; + } + case clang::Decl::Record: { + recordDecles.emplace_back(child); + break; + } + case clang::Decl::Typedef: + break; + case clang::Decl::Enum: + break; + default: { + WARN(kLncWarn, "Unsupported decl kind: %u", child->getKind()); + } + } + }); + return true; +} + +#define DECL_CASE(CLASS) \ + case clang::Decl::CLASS: \ + return ProcessDecl##CLASS##Decl(allocator, llvm::cast(decl)); +ASTDecl *ASTParser::ProcessDecl(MapleAllocator &allocator, const clang::Decl &decl) { + switch (decl.getKind()) { + DECL_CASE(Function); + DECL_CASE(Field); + DECL_CASE(Record); + DECL_CASE(Var); + default: + CHECK_FATAL(false, "NIY"); + return nullptr; + } + return nullptr; +} + +ASTDecl *ASTParser::ProcessDeclRecordDecl(MapleAllocator &allocator, const clang::RecordDecl &recDecl) { + std::stringstream recName; + clang::QualType qType = recDecl.getTypeForDecl()->getCanonicalTypeInternal(); + astFile->EmitTypeName(*qType->getAs(), recName); + MIRType *recType = astFile->CvtType(qType); + if (recType == nullptr) { + return nullptr; + } + GenericAttrs attrs; + astFile->CollectAttrs(recDecl, attrs, kPublic); + std::string structName = recName.str(); + if (structName.empty() || !ASTUtil::IsValidName(structName)) { + uint32 id = qType->getAs()->getDecl()->getLocation().getRawEncoding(); + structName = astFile->GetOrCreateMappedUnnamedName(id); + } + ASTStruct *curStructOrUnion = + ASTStructBuilder(allocator, fileName, structName, std::vector{recType}, attrs); + if (recDecl.isUnion()) { + curStructOrUnion->SetIsUnion(); + } + const auto *declContext = llvm::dyn_cast(&recDecl); + if (declContext == nullptr) { + return nullptr; + } + for (auto *loadDecl : declContext->decls()) { + if (loadDecl == nullptr) { + return nullptr; + } + auto *fieldDecl = llvm::dyn_cast(loadDecl); + if (llvm::isa(loadDecl)) { + clang::RecordDecl *subRecordDecl = llvm::cast(loadDecl->getCanonicalDecl()); + ASTStruct *sub = static_cast(ProcessDeclRecordDecl(allocator, *subRecordDecl)); + if (sub == nullptr) { + return nullptr; + } + astIn->AddASTStruct(sub); + } + + if (llvm::isa(loadDecl)) { + ASTField *af = static_cast(ProcessDeclFieldDecl(allocator, *fieldDecl)); + if (af == nullptr) { + return nullptr; + } + curStructOrUnion->SetField(af); + } + } + return curStructOrUnion; +} + +ASTDecl *ASTParser::ProcessDeclFunctionDecl(MapleAllocator &allocator, const clang::FunctionDecl &funcDecl) { + std::string funcName = astFile->GetMangledName(funcDecl); + if (funcName.empty()) { + return nullptr; + } + if (!ASTUtil::IsValidName(funcName)) { + ASTUtil::AdjustName(funcName); + } + clang::QualType qualType = funcDecl.getReturnType(); + MIRType *retType = astFile->CvtType(qualType); + if (retType == nullptr) { + return nullptr; + } + std::vector typeDescIn; + std::vector parmNamesIn; + typeDescIn.push_back(retType); + unsigned int numParam = funcDecl.getNumParams(); + for (uint32_t i = 0; i < numParam; ++i) { + const clang::ParmVarDecl *parmDecl = funcDecl.getParamDecl(i); + const clang::QualType parmQualType = parmDecl->getType(); + std::string parmName = parmDecl->getNameAsString(); + if (parmName.length() == 0) { + parmName = FEUtils::GetSequentialName0("arg|", i); + } + parmNamesIn.emplace_back(parmName); + MIRType *paramType = astFile->CvtType(parmQualType); + if (paramType == nullptr) { + return nullptr; + } + typeDescIn.push_back(paramType); + } + GenericAttrs attrs; + astFile->CollectFuncAttrs(funcDecl, attrs, kPublic); + ASTFunc *astFunc = ASTFuncBuilder(allocator, fileName, funcName, typeDescIn, attrs, parmNamesIn); + CHECK_FATAL(astFunc != nullptr, "astFunc is nullptr"); + if (funcDecl.hasBody()) { + ASTStmt *astCompoundStmt = ProcessStmtCompoundStmt(allocator, + *llvm::cast(funcDecl.getBody())); + if (astCompoundStmt != nullptr) { + astFunc->SetCompoundStmt(astCompoundStmt); + } else { + return nullptr; + } + } + return astFunc; +} + +ASTDecl *ASTParser::ProcessDeclFieldDecl(MapleAllocator &allocator, const clang::FieldDecl &decl) { + clang::QualType qualType = decl.getType(); + std::string fieldName = astFile->GetMangledName(decl); + if (fieldName.empty()) { + return nullptr; + } + MIRType *fieldType = astFile->CvtType(qualType); + if (fieldType == nullptr) { + return nullptr; + } + GenericAttrs attrs; + astFile->CollectAttrs(decl, attrs, kPublic); + return ASTFieldBuilder(allocator, fileName, fieldName, std::vector{fieldType}, attrs); +} + +ASTDecl *ASTParser::ProcessDeclVarDecl(MapleAllocator &allocator, const clang::VarDecl &varDecl) { + std::string varName = astFile->GetMangledName(varDecl); + if (varName.empty()) { + return nullptr; + } + clang::QualType qualType = varDecl.getType(); + MIRType *varType = astFile->CvtType(qualType); + if (varType == nullptr) { + return nullptr; + } + GenericAttrs attrs; + astFile->CollectAttrs(varDecl, attrs, kPublic); + VarValue val = GetVarInitVal(allocator, varDecl); + return ASTPrimitiveVarBuilder(allocator, fileName, varName, std::vector{varType}, val, attrs); +} + +bool ASTParser::RetrieveStructs(MapleAllocator &allocator, MapleList &structs) { + for (auto &decl : recordDecles) { + clang::RecordDecl *recDecl = llvm::cast(decl->getCanonicalDecl()); + if (!recDecl->isCompleteDefinition()) { + continue; + } + ASTStruct *curStructOrUnion = static_cast(ProcessDecl(allocator, *recDecl)); + if (curStructOrUnion == nullptr) { + return false; + } + structs.emplace_back(curStructOrUnion); + } + return true; +} + +bool ASTParser::RetrieveFuncs(MapleAllocator &allocator, MapleList &funcs) { + for (auto &func : funcDecles) { + clang::FunctionDecl funcDecl = llvm::cast(*func); + ASTFunc *af = static_cast(ProcessDecl(allocator, funcDecl)); + if (af == nullptr) { + return false; + } + funcs.emplace_back(af); + } + return true; +} + +VarValue ASTParser::GetVarInitVal(MapleAllocator &allocator, clang::VarDecl varDecl) { + VarValue value; + if (!varDecl.hasInit()) { + return value; + } + const clang::Expr *init = varDecl.getInit(); + init = llvm::isa(init) ? llvm::cast(init)->getSubExpr() : init; + init = llvm::isa(init) ? + llvm::cast(init)->getSubExpr() : init; + if (init->getType().getTypePtr()->isDependentType()) { + return value; + } + ASTExpr *expr = ProcessExpr(allocator, init); + switch (init->getStmtClass()) { + case clang::Stmt::IntegerLiteralClass: { + ASTIntegerLiteral *intExpr = static_cast(expr); + value.u64 = intExpr->GetVal(); + break; + } + case clang::Stmt::FloatingLiteralClass: { + ASTFloatingLiteral *floatExpr = static_cast(expr); + value.d = floatExpr->GetVal(); + break; + } + case clang::Stmt::ImplicitCastExprClass: { + ASTImplicitCastExpr *implicitCastExpr = static_cast(expr); + if (llvm::cast(init)->getCastKind() == clang::CK_FloatingCast) { + ASTFloatingLiteral *floatExpr = static_cast(implicitCastExpr->GetASTExpr()); + value.f32 = floatExpr->GetVal(); + } + break; + } + default: + break; + } + return value; +} + +// seperate MP with astparser +bool ASTParser::RetrieveGlobalVars(MapleAllocator &allocator, MapleList &vars) { + for (auto &decl : globalVarDecles) { + clang::VarDecl varDecl = llvm::cast(*decl); + ASTPrimitiveVar *val = static_cast(ProcessDecl(allocator, varDecl)); + if (val == nullptr) { + return false; + } + vars.emplace_back(val); + } + return true; +} + +const std::string &ASTParser::GetSourceFileName() const { + return fileName; +} + +const uint32 ASTParser::GetFileIdx() const { + return fileIdx; +} + +void ASTParser::TraverseDecl(clang::Decl *decl, std::function const &functor) { + uint32 srcFileNum = 2; // src files start from 2, 1 is mpl file + if (decl == nullptr) { + return; + } + // set srcfileinfo + for (auto *declRange : clang::dyn_cast(decl)->decls()) { + clang::FullSourceLoc fullLocation = astFile->GetAstContext()->getFullLoc(declRange->getBeginLoc()); + if (fullLocation.isValid() && fullLocation.isFileID()) { + const clang::FileEntry *fileEntry = fullLocation.getFileEntry(); + ASSERT_NOT_NULL(fileEntry); + GStrIdx idx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fileEntry->getName().data()); + FEManager::GetModule().PushbackFileInfo(MIRInfoPair(idx, srcFileNum++)); + break; + } + } + for (auto *child : clang::dyn_cast(decl)->decls()) { + functor(child); + } +} +} // namespace maple diff --git a/src/mplfe/ast_input/src/ast_stmt.cpp b/src/mplfe/ast_input/src/ast_stmt.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7e76e8a0cb6f33b3be64e5ea190acc3bfa440794 --- /dev/null +++ b/src/mplfe/ast_input/src/ast_stmt.cpp @@ -0,0 +1,232 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include "ast_stmt.h" +#include "ast_decl.h" +#include "mpl_logging.h" +#include "feir_stmt.h" +#include "feir_builder.h" +#include "fe_utils_ast.h" +#include "fe_manager.h" +#include "ast_util.h" + +namespace maple { +// ---------- ASTStmt ---------- +void ASTStmt::SetASTExpr(ASTExpr *astExpr) { + exprs.emplace_back(astExpr); +} + +void ASTCompoundStmt::SetASTStmt(ASTStmt *astStmt) { + astStmts.emplace_back(astStmt); +} + +const std::list &ASTCompoundStmt::GetASTStmtList() const { + return astStmts; +} + +std::list ASTCompoundStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +std::list ASTReturnStmt::Emit2FEStmtImpl() const { + std::list stmts; + auto astExpr = exprs.front(); + UniqueFEIRExpr feExpr = astExpr->Emit2FEExpr(); + UniqueFEIRStmt stmt = std::make_unique(std::move(feExpr)); + stmts.emplace_back(std::move(stmt)); + return stmts; +} + +void ASTRefExpr::SetASTDecl(ASTDecl *astDecl) { + var = astDecl; +} + +std::list ASTIfStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +std::list ASTForStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +std::list ASTWhileStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +std::list ASTDoStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +std::list ASTBreakStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +std::list ASTContinueStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +// ---------- ASTUnaryOperatorStmt ---------- +std::list ASTUnaryOperatorStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +// ---------- ASTGotoStmt ---------- +std::list ASTGotoStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +// ---------- ASTSwitchStmt ---------- +std::list ASTSwitchStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +// ---------- ASTCaseStmt ---------- +std::list ASTCaseStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +// ---------- ASTDefaultStmt ---------- +std::list ASTDefaultStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +// ---------- ASTNullStmt ---------- +std::list ASTNullStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +// ---------- ASTDeclStmt ---------- +std::list ASTDeclStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +// ---------- ASTCallExprStmt ---------- +std::list ASTCallExprStmt::Emit2FEStmtImpl() const { + std::list stmts; + ASTCallExpr *callExpr = static_cast(exprs.front()); + // callassigned &funcName + std::string funcName = callExpr->GetFuncName(); + StructElemNameIdx *nameIdx = FEManager::GetManager().GetStructElemMempool()->New(funcName); + FEStructMethodInfo *info = static_cast( + FEManager::GetTypeManager().RegisterStructMethodInfo(*nameIdx, kSrcLangC, false)); + std::unique_ptr callStmt = std::make_unique( + *info, OP_callassigned, nullptr, false); + // args + std::vector argsExprs = callExpr->GetArgsExpr(); + for (uint32 i = 0; i < argsExprs.size(); ++i) { + UniqueFEIRExpr expr = argsExprs[i]->Emit2FEExpr(); + callStmt->AddExprArgReverse(std::move(expr)); + } + // return + PrimType primType = callExpr->GetRetType()->GetPrimType(); + if (primType != PTY_void) { + const std::string &varName = FEUtils::GetSequentialName("retVar_"); + UniqueFEIRVar var = FEIRBuilder::CreateVarName(varName, primType, false, false); + callStmt->SetVar(std::move(var)); + } + stmts.emplace_back(std::move(callStmt)); + return stmts; +} + +// ---------- ASTImplicitCastExprStmt ---------- +std::list ASTImplicitCastExprStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +// ---------- ASTParenExprStmt ---------- +std::list ASTParenExprStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +// ---------- ASTIntegerLiteralStmt ---------- +std::list ASTIntegerLiteralStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +// ---------- ASTVAArgExprStmt ---------- +std::list ASTVAArgExprStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +// ---------- ASTConditionalOperatorStmt ---------- +std::list ASTConditionalOperatorStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +// ---------- ASTCharacterLiteralStmt ---------- +std::list ASTCharacterLiteralStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +// ---------- ASTStmtExprStmt ---------- +std::list ASTStmtExprStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +// ---------- ASTCStyleCastExprStmt ---------- +std::list ASTCStyleCastExprStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} + +// ---------- ASTCompoundAssignOperatorStmt ---------- +std::list ASTCompoundAssignOperatorStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(false, "NYI"); + std::list stmts; + return stmts; +} +} // namespace maple diff --git a/src/mplfe/ast_input/src/ast_struct2fe_helper.cpp b/src/mplfe/ast_input/src/ast_struct2fe_helper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..270159904334586a73ef90bdfea9c9ea6f68150d --- /dev/null +++ b/src/mplfe/ast_input/src/ast_struct2fe_helper.cpp @@ -0,0 +1,276 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include "ast_struct2fe_helper.h" +#include "fe_manager.h" +#include "fe_utils_ast.h" +#include "ast_util.h" + +namespace maple { +// ---------- ASTStruct2FEHelper ---------- +bool ASTStruct2FEHelper::ProcessDeclImpl() { + if (isSkipped) { + return true; + } + if (mirStructType == nullptr) { + return false; + } + // Process Fields + InitFieldHelpers(); + ProcessFieldDef(); + // Process Methods + InitMethodHelpers(); + ProcessMethodDef(); + return true; +} + +void ASTStruct2FEHelper::InitFieldHelpersImpl() { + MemPool *mp = allocator.GetMemPool(); + ASSERT(mp != nullptr, "mem pool is nullptr"); + for (const ASTField *field : astStruct.GetFields()) { + ASSERT(field != nullptr, "field is nullptr"); + ASTStructField2FEHelper *fieldHelper = mp->New(allocator, *field); + fieldHelpers.push_back(fieldHelper); + } +} + +void ASTStruct2FEHelper::InitMethodHelpersImpl() { +} + +TypeAttrs ASTStruct2FEHelper::GetStructAttributeFromInputImpl() const { + GenericAttrs attrs = astStruct.GetGenericAttrs(); + return attrs.ConvertToTypeAttrs(); +} + +ASTStruct2FEHelper::ASTStruct2FEHelper(MapleAllocator &allocator, const ASTStruct &structIn) + : FEInputStructHelper(allocator), astStruct(structIn) { + srcLang = kSrcLangC; +} + +std::string ASTStruct2FEHelper::GetStructNameOrinImpl() const { + return astStruct.GetStructName(false); +} + +std::string ASTStruct2FEHelper::GetStructNameMplImpl() const { + return astStruct.GetStructName(true); +} + +std::list ASTStruct2FEHelper::GetSuperClassNamesImpl() const { + CHECK_FATAL(false, "NIY"); + return std::list {}; +} + +std::vector ASTStruct2FEHelper::GetInterfaceNamesImpl() const { + CHECK_FATAL(false, "NIY"); + return std::vector {}; +} + +std::string ASTStruct2FEHelper::GetSourceFileNameImpl() const { + return astStruct.GetSrcFileName(); +} + +std::string ASTStruct2FEHelper::GetSrcFileNameImpl() const { + return astStruct.GetSrcFileName(); +} + +MIRStructType *ASTStruct2FEHelper::CreateMIRStructTypeImpl(bool &error) const { + std::string name = GetStructNameOrinImpl(); + if (name.empty()) { + error = true; + ERR(kLncErr, "class name is empty"); + return nullptr; + } + MIRStructType *type = FEManager::GetTypeManager().GetOrCreateStructType(name); + error = false; + if (astStruct.IsUnion()) { + type->SetMIRTypeKind(kTypeUnion); + } else { + type->SetMIRTypeKind(kTypeStruct); + } + return type; +} + +uint64 ASTStruct2FEHelper::GetRawAccessFlagsImpl() const { + CHECK_FATAL(false, "NIY"); + return 0; +} + +GStrIdx ASTStruct2FEHelper::GetIRSrcFileSigIdxImpl() const { + // Not implemented, just return a invalid value + return GStrIdx(0); +} + +bool ASTStruct2FEHelper::IsMultiDefImpl() const { + // Not implemented, alway return false + return false; +} + +// ---------- ASTGlobalVar2FEHelper --------- +bool ASTStructField2FEHelper::ProcessDeclImpl(MapleAllocator &allocator) { + CHECK_FATAL(false, "should not run here"); + return false; +} + +bool ASTStructField2FEHelper::ProcessDeclWithContainerImpl(MapleAllocator &allocator) { + std::string fieldName = field.GetName(); + GStrIdx idx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fieldName); + FieldAttrs attrs = field.GetGenericAttrs().ConvertToFieldAttrs(); + MIRType *fieldType = field.GetTypeDesc().front(); + ASSERT(fieldType != nullptr, "nullptr check for fieldType"); + mirFieldPair.first = idx; + mirFieldPair.second.first = fieldType->GetTypeIndex(); + mirFieldPair.second.second = attrs; + return true; +} + +// ---------- ASTGlobalVar2FEHelper --------- +bool ASTGlobalVar2FEHelper::ProcessDeclImpl(MapleAllocator &allocator) { + const std::string varName = astVar.GetName(); + MIRType *type = astVar.GetTypeDesc().front(); + MIRSymbol *mirSymbol = FEManager::GetMIRBuilder().GetOrCreateGlobalDecl(varName, *type); + if (mirSymbol == nullptr) { + return false; + } + PrimType primType = type->GetPrimType(); + if (primType != PTY_ref && primType != PTY_agg && primType != PTY_ptr) { + MIRConst *cst = nullptr; + switch (primType) { + case PTY_i32: + case PTY_u32: + case PTY_i64: + case PTY_u64: + cst = allocator.GetMemPool()->New(static_cast(astVar.GetVal().u64), *type); + break; + case PTY_f32: + cst = allocator.GetMemPool()->New(astVar.GetVal().f32, *type); + break; + case PTY_f64: + cst = allocator.GetMemPool()->New(astVar.GetVal().d, *type); + break; + default: + CHECK_FATAL(false, "unsupported type."); + break; + } + mirSymbol->SetKonst(cst); + } + mirSymbol->SetAttrs(astVar.GetGenericAttrs().ConvertToTypeAttrs()); + return true; +} + +// ---------- ASTFunc2FEHelper ---------- +bool ASTFunc2FEHelper::ProcessDeclImpl(MapleAllocator &allocator) { + MPLFE_PARALLEL_FORBIDDEN(); + ASSERT(srcLang != kSrcLangUnknown, "src lang not set"); + std::string methodShortName = GetMethodName(false, false); + CHECK_FATAL(!methodShortName.empty(), "error: method name is empty"); + if (methodShortName.compare("main") == 0) { + FEManager::GetMIRBuilder().GetMirModule().SetEntryFuncName(methodShortName); + } + methodNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(methodShortName); + if (!ASTUtil::InsertFuncSet(methodNameIdx)) { + return true; + } + SolveReturnAndArgTypes(allocator); + FuncAttrs attrs = GetAttrs(); + bool isStatic = IsStatic(); + bool isVarg = IsVarg(); + CHECK_FATAL(retMIRType != nullptr, "function must have return type"); + std::vector argsTypeIdx; + for (auto *type : argMIRTypes) { + argsTypeIdx.push_back(type->GetTypeIndex()); + } + mirFunc = FEManager::GetTypeManager().CreateFunction(methodNameIdx, retMIRType->GetTypeIndex(), + argsTypeIdx, isVarg, isStatic); +#ifndef USE_OPS + for (uint32 i = 0; i < func.GetParmNames().size(); ++i) { + MIRSymbol *sym = SymbolBuilder::Instance().GetOrCreateLocalSymbol( + *argMIRTypes[i], func.GetParmNames()[i], *mirFunc); + sym->SetStorageClass(kScFormal); + sym->SetSKind(kStVar); + mirFunc->AddFormal(sym); + } + mirMethodPair.first = mirFunc; +#else + for (uint32 i = 0; i < func.GetParmNames().size(); ++i) { + MIRSymbol *sym = FEManager::GetMIRBuilder().GetOrCreateDeclInFunc( + func.GetParmNames()[i], *argMIRTypes[i], *mirFunc); + sym->SetStorageClass(kScFormal); + sym->SetSKind(kStVar); + mirFunc->AddArgument(sym); + } + mirMethodPair.first = mirFunc->GetStIdx(); +#endif + mirMethodPair.second.first = mirFunc->GetMIRFuncType()->GetTypeIndex(); + mirMethodPair.second.second = attrs; + mirFunc->SetFuncAttrs(attrs); + return true; +} + +const std::string &ASTFunc2FEHelper::GetSrcFileName() const { + return func.GetSrcFileName(); +} + +void ASTFunc2FEHelper::SolveReturnAndArgTypesImpl(MapleAllocator &allocator) { + const std::vector &returnAndArgTypeNames = func.GetTypeDesc(); + retMIRType = returnAndArgTypeNames[0]; + argMIRTypes.insert(argMIRTypes.begin(), returnAndArgTypeNames.begin() + 1, returnAndArgTypeNames.end()); +} + +std::string ASTFunc2FEHelper::GetMethodNameImpl(bool inMpl, bool full) const { + std::string funcName = func.GetName(); + if (!full) { + return inMpl ? namemangler::EncodeName(funcName) : funcName; + } + // fullName not implemented yet + return funcName; +} + +bool ASTFunc2FEHelper::IsVargImpl() const { + return false; +} + +bool ASTFunc2FEHelper::HasThisImpl() const { + CHECK_FATAL(false, "NIY"); + return false; +} + +MIRType *ASTFunc2FEHelper::GetTypeForThisImpl() const { + CHECK_FATAL(false, "NIY"); + return nullptr; +} + +FuncAttrs ASTFunc2FEHelper::GetAttrsImpl() const { + return func.GetGenericAttrs().ConvertToFuncAttrs(); +} + +bool ASTFunc2FEHelper::IsStaticImpl() const { + return false; +} + +bool ASTFunc2FEHelper::IsVirtualImpl() const { + CHECK_FATAL(false, "NIY"); + return false; +} +bool ASTFunc2FEHelper::IsNativeImpl() const { + CHECK_FATAL(false, "NIY"); + return false; +} + +bool ASTFunc2FEHelper::HasCodeImpl() const { + if (func.GetCompoundStmt() == nullptr) { + return false; + } + return true; +} +} // namespace maple diff --git a/src/mplfe/bc_input/include/ark_annotation_map.h b/src/mplfe/bc_input/include/ark_annotation_map.h index cb3c9906948e6ca8b90e452810ca908fdfc52194..a2e9e2b42e28fbfc701859ca5e10228929f20aec 100644 --- a/src/mplfe/bc_input/include/ark_annotation_map.h +++ b/src/mplfe/bc_input/include/ark_annotation_map.h @@ -1,17 +1,17 @@ /* - * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. - * - * OpenArkCompiler is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * - * http://license.coscl.org.cn/MulanPSL2 - * - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR - * FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - */ + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ #ifndef MPLFE_BC_INPUT_INCLUDE_ARK_ANNOTATION_MAP_H #define MPLFE_BC_INPUT_INCLUDE_ARK_ANNOTATION_MAP_H #include diff --git a/src/mplfe/bc_input/include/ark_annotation_processor.h b/src/mplfe/bc_input/include/ark_annotation_processor.h index 2d3842a4424b23c2eeda7a3cc328e76320f1f24b..d77e0bfb10fe9a58c378234a5af928d87e51cdf5 100644 --- a/src/mplfe/bc_input/include/ark_annotation_processor.h +++ b/src/mplfe/bc_input/include/ark_annotation_processor.h @@ -29,6 +29,16 @@ class ArkAnnotation { bool IsFastNative(TyIdx tyIdx); bool IsCriticalNative(TyIdx tyIdx); bool IsCallerSensitive(TyIdx tyIdx); + bool IsPermanent(TyIdx tyIdx); + bool IsPermanent(const std::string &str) const; + bool IsRCUnowned(TyIdx tyIdx); + bool IsRCUnownedCap(TyIdx tyIdx); + bool IsRCUnownedCapList(TyIdx tyIdx); + bool IsRCUnownedLocal(TyIdx tyIdx); + bool IsRCUnownedLocalOld(TyIdx tyIdx); + bool IsRCUnownedThis(TyIdx tyIdx); + bool IsRCUnownedOuter(TyIdx tyIdx); + bool IsRCWeak(TyIdx tyIdx); static ArkAnnotation &GetInstance() { return instance; } @@ -46,6 +56,15 @@ class ArkAnnotation { std::set typeNameSetForFastNative; std::set typeNameSetForCriticalNative; std::set typeNameSetForCallerSensitive; + std::set typeNameSetForPermanent; + std::set typeNameSetForRCUnowned; + std::set typeNameSetForRCUnownedCap; + std::set typeNameSetForRCUnownedCapList; + std::set typeNameSetForRCUnownedLocal; + std::set typeNameSetForRCUnownedThis; + std::set typeNameSetForRCUnownedOuter; + std::set typeNameSetForRCWeak; + GStrIdx typeNameIdxForRCUnownedLocalOld; }; } // namespace bc } // namespace maple diff --git a/src/mplfe/bc_input/include/bc_class.h b/src/mplfe/bc_input/include/bc_class.h index 2b35fc93a926d6eb9c332e492daf02e4cd0a8718..fb70982f1f49d581546cc4134901cb9c9ecf06b2 100644 --- a/src/mplfe/bc_input/include/bc_class.h +++ b/src/mplfe/bc_input/include/bc_class.h @@ -26,6 +26,7 @@ #include "feir_var.h" #include "mempool.h" #include "bc_pragma.h" + namespace maple { namespace bc { using BCAttrKind = uint32; @@ -139,7 +140,7 @@ class BCClassMethod : public BCClassElem { BCClassMethod(const BCClass &klassIn, uint32 acc, bool isVirtualIn, const std::string &nameIn, const std::string &descIn) : BCClassElem(klassIn, acc, nameIn, descIn), isVirtual(isVirtualIn), - methodMp(memPoolCtrler.NewMemPool("MemPool for BCClassMethod")), + methodMp(FEUtils::NewMempool("MemPool for BCClassMethod", true /* isLcalPool */)), allocator(methodMp) {} ~BCClassMethod() { if (methodMp != nullptr) { @@ -154,6 +155,8 @@ class BCClassMethod : public BCClassElem { void SetRegisterTotalSize(uint16 size); uint16 GetRegisterTotalSize() const; void SetRegisterInsSize(uint16 size); + void SetCodeOff(uint32 off); + uint32 GetCodeOff() const; void AddMethodDepSet(const std::string &depType); bool IsVirtual() const; bool IsNative() const; @@ -182,6 +185,15 @@ class BCClassMethod : public BCClassElem { #endif } + const std::map>> *GetSrcLocalInfoPtr() const { + return srcLocals.get(); + } + + void SetSrcLocalInfo( + std::unique_ptr>>> srcLocalsIn) { + srcLocals = std::move(srcLocalsIn); + } + std::vector> GenArgVarList() const; void GenArgRegs(); std::vector GetSigTypeNames() const { @@ -191,6 +203,14 @@ class BCClassMethod : public BCClassElem { return pcBCInstructionMap != nullptr && !pcBCInstructionMap->empty(); } + bool IsRcPermanent() const { + return isPermanent; + } + + void SetIsRcPermanent(bool flag) { + isPermanent = flag; + } + const MemPool *GetMemPool() const { return methodMp; } @@ -215,20 +235,15 @@ class BCClassMethod : public BCClassElem { virtual bool IsClinitImpl() const = 0; void ProcessTryCatch(); virtual std::vector> GenArgVarListImpl() const = 0; - // This struct is used in TypeInfer only. - struct TypeInferItem { - BCReg *reg = nullptr; - std::set aliveUsedTypes; - TypeInferItem *prev = nullptr; - }; - void TypeInfer(); - void InsertPhi(const std::vector &dest, std::vector &src); - static TypeInferItem *RegisterTypeInferItem(std::list> &items, BCReg* bcReg, - TypeInferItem *prev); - static std::vector ConstructNewRegTypeMap(const std::vector ®TypeMap, - std::list> &items); + void InsertPhi(const std::vector &dom, std::vector &src); + static TypeInferItem *ConstructTypeInferItem(MapleAllocator &alloc, uint32 pos, BCReg* bcReg, TypeInferItem *prev); + static std::vector ConstructNewRegTypeMap(MapleAllocator &alloc, uint32 pos, + const std::vector ®TypeMap); std::list GenReTypeStmtsThroughArgs() const; + void Traverse(std::list>> &pcDefedRegsList, + std::vector> &dominances, + std::set &visitedSet); void PrecisifyRegType(); virtual void GenArgRegsImpl() = 0; static void LinkJumpTarget(const std::map &targetFEIRStmtMap, @@ -241,15 +256,20 @@ class BCClassMethod : public BCClassElem { #ifdef DEBUG const std::map *pSrcPosInfo = nullptr; #endif + // map>> + std::unique_ptr>>> srcLocals; std::vector> argRegs; std::vector sigTypeNames; bool isVirtual = false; uint16 registerTotalSize = UINT16_MAX; uint16 registerInsSize = UINT16_MAX; + uint32 codeOff = UINT32_MAX; const uint16 *instPos = nullptr; // method instructions start pos in bc file std::set visitedPcSet; std::set multiInDegreeSet; std::list regTypes; + // isPermanent is true means the rc annotation @Permanent is used + bool isPermanent = false; MemPool *methodMp; MapleAllocator allocator; @@ -277,6 +297,17 @@ class BCClass { } void SetSrcFileInfo(const std::string &name); + void SetIRSrcFileSigIdx(GStrIdx strIdx) { + irSrcFileSigIdx = strIdx; + } + + bool IsMultiDef() const { + return isMultiDef; + } + + void SetIsMultiDef(bool flag) { + isMultiDef = flag; + } uint32 GetSrcFileIdx() const { return srcFileIdx; @@ -307,7 +338,9 @@ class BCClass { const std::list &GetSuperClassNames() const; const std::vector &GetSuperInterfaceNames() const; std::string GetSourceFileName() const; + GStrIdx GetIRSrcFileSigIdx() const; uint32 GetAccessFlag() const; + uint32 GetFileNameHashId() const; const std::vector> &GetFields() const; std::vector> &GetMethods(); @@ -315,12 +348,14 @@ class BCClass { protected: bool isInterface = false; + bool isMultiDef = false; uint32 classIdx; uint32 srcFileIdx = 0; uint32 accFlag = 0; GStrIdx classNameOrinIdx; GStrIdx classNameMplIdx; GStrIdx srcFileNameIdx; + GStrIdx irSrcFileSigIdx; const BCParserBase &parser; std::list superClassNameList; std::vector interfaces; diff --git a/src/mplfe/bc_input/include/bc_class2fe_helper.h b/src/mplfe/bc_input/include/bc_class2fe_helper.h index 4158a554467f9719be41b49099a8767af1da81f3..7bbc12c0014bc26a6df66d21b28210bf82226a08 100644 --- a/src/mplfe/bc_input/include/bc_class2fe_helper.h +++ b/src/mplfe/bc_input/include/bc_class2fe_helper.h @@ -33,9 +33,14 @@ class BCClass2FEHelper : public FEInputStructHelper { std::string GetSourceFileNameImpl() const override; MIRStructType *CreateMIRStructTypeImpl(bool &error) const override; uint64 GetRawAccessFlagsImpl() const override; + GStrIdx GetIRSrcFileSigIdxImpl() const override; + bool IsMultiDefImpl() const override; std::string GetSrcFileNameImpl() const override; BCClass &klass; + + private: + void TryMarkMultiDefClass(MIRStructType &typeImported) const; }; class BCClassField2FEHelper : public FEInputFieldHelper { diff --git a/src/mplfe/bc_input/include/bc_compiler_component-inl.h b/src/mplfe/bc_input/include/bc_compiler_component-inl.h index 84947caa02a8d9cc7c74ed7f7e570239be102d34..009e91ae391f36bdff8c2fb00fa7301b386a7dc4 100644 --- a/src/mplfe/bc_input/include/bc_compiler_component-inl.h +++ b/src/mplfe/bc_input/include/bc_compiler_component-inl.h @@ -24,13 +24,10 @@ namespace maple { namespace bc { -#define SET_FUNC_INFO_PAIR(A, B, C, D) \ - A->PushbackMIRInfo(MIRInfoPair(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(B), C)); \ - A->PushbackIsString(D) template BCCompilerComponent::BCCompilerComponent(MIRModule &module) : MPLFECompilerComponent(module, kSrcLangJava), - mp(memPoolCtrler.NewMemPool("MemPool for BCCompilerComponent")), + mp(FEUtils::NewMempool("MemPool for BCCompilerComponent", false /* isLcalPool */)), allocator(mp), bcInput(std::make_unique>(module)) {} @@ -58,13 +55,10 @@ bool BCCompilerComponent::ParseInputImpl() { while (klass != nullptr) { if (typeid(T) == typeid(DexReader)) { FEInputStructHelper *structHelper = allocator.GetMemPool()->template New(allocator, *klass); - FEInputPragmaHelper *pragmaHelper = allocator.GetMemPool()->template New( - *(klass->GetAnnotationsDirectory())); + FEInputPragmaHelper *pragmaHelper = + allocator.GetMemPool()->template New(*(klass->GetAnnotationsDirectory())); structHelper->SetPragmaHelper(pragmaHelper); structHelper->SetStaticFieldsConstVal(klass->GetStaticFieldsConstVal()); - if (FEOptions::GetInstance().IsAOT()) { - structHelper->SetFinalStaticStringIDVec(klass->GetFinalStaticStringIDVec()); - } structHelpers.push_back(structHelper); } else { CHECK_FATAL(false, "Reader is not supported. Exit."); @@ -140,8 +134,8 @@ bool BCCompilerComponent::LoadOnDemandBCClass2FEClass( bool isEmitDepsMplt) { for (const std::unique_ptr &klass : klassList) { std::unique_ptr structHelper = std::make_unique(allocator, *klass); - FEInputPragmaHelper *pragmaHelper = allocator.GetMemPool()->template New( - *(klass->GetAnnotationsDirectory())); + FEInputPragmaHelper *pragmaHelper = + allocator.GetMemPool()->template New(*(klass->GetAnnotationsDirectory())); structHelper->SetPragmaHelper(pragmaHelper); structHelper->SetIsOnDemandLoad(true); structHelpers.push_back(std::move(structHelper)); @@ -179,8 +173,13 @@ bool BCCompilerComponent::LoadOnDemandBCClass2FEClass( FEManager::GetTypeManager().SetMirImportedTypes(FETypeFlag::kSrcMplt); break; } +#ifndef USE_OPS + for (uint32 i = 1; i < SymbolBuilder::Instance().GetSymbolTableSize(); ++i) { + MIRSymbol *symbol = SymbolBuilder::Instance().GetSymbolFromStIdx(i); +#else for (uint32 i = 1; i < GlobalTables::GetGsymTable().GetSymbolTableSize(); ++i) { MIRSymbol *symbol = GlobalTables::GetGsymTable().GetSymbol(i); +#endif if ((symbol != nullptr) && (symbol->GetSKind() == kStFunc)) { symbol->SetIsImportedDecl(true); } @@ -188,34 +187,6 @@ bool BCCompilerComponent::LoadOnDemandBCClass2FEClass( return true; } -template -bool BCCompilerComponent::PreProcessDeclImpl() { - FETimer timer; - timer.StartAndDump("BCCompilerComponent::PreProcessDecl()"); - FE_INFO_LEVEL(FEOptions::kDumpLevelInfo, "===== Process BCCompilerComponent::PreProcessDecl() ====="); - bool success = true; - for (FEInputStructHelper *helper : structHelpers) { - ASSERT_NOT_NULL(helper); - success = helper->PreProcessDecl() ? success : false; - } - timer.StopAndDumpTimeMS("BCCompilerComponent::PreProcessDecl()"); - return success; -} - -template -bool BCCompilerComponent::ProcessDeclImpl() { - FETimer timer; - timer.StartAndDump("BCCompilerComponent::ProcessDecl()"); - FE_INFO_LEVEL(FEOptions::kDumpLevelInfo, "===== Process BCCompilerComponent::ProcessDecl() ====="); - bool success = true; - for (FEInputStructHelper *helper : structHelpers) { - ASSERT_NOT_NULL(helper); - success = helper->ProcessDecl() ? success : false; - } - timer.StopAndDumpTimeMS("BCCompilerComponent::ProcessDecl()"); - return success; -} - template void BCCompilerComponent::ProcessPragmaImpl() { FETimer timer; @@ -229,48 +200,16 @@ void BCCompilerComponent::ProcessPragmaImpl() { } template -bool BCCompilerComponent::PreProcessWithoutFunctionImpl() { - return false; -} - -template -bool BCCompilerComponent::PreProcessWithFunctionImpl() { - FETimer timer; - timer.StartAndDump("BCCompilerComponent::PreProcessWithFunction()"); - FE_INFO_LEVEL(FEOptions::kDumpLevelInfo, "===== Process BCCompilerComponent::PreProcessWithFunction() ====="); - for (FEInputStructHelper *structHelper : structHelpers) { - ASSERT_NOT_NULL(structHelper); - for (FEInputMethodHelper *methodHelper : structHelper->GetMethodHelpers()) { - ASSERT_NOT_NULL(methodHelper); - BCClassMethod2FEHelper *bcMethodHelper = static_cast(methodHelper); - GStrIdx methodNameIdx = methodHelper->GetMethodNameIdx(); - bool isStatic = methodHelper->IsStatic(); - MIRFunction *mirFunc = FEManager::GetTypeManager().GetMIRFunction(methodNameIdx, isStatic); - CHECK_NULL_FATAL(mirFunc); - std::unique_ptr feFunction = std::make_unique(*bcMethodHelper, *mirFunc, - phaseResultTotal); - module.AddFunction(mirFunc); - if (FEOptions::GetInstance().IsAOT()) { - const std::unique_ptr &method = bcMethodHelper->GetMethod(); - GStrIdx idx = module.GetMIRBuilder()->GetOrCreateStringIndex(bcMethodHelper->GetMethodName(false)); - SET_FUNC_INFO_PAIR(mirFunc, "INFO_fullname", idx, true); - const std::string className = method->GetClassName(); - idx = module.GetMIRBuilder()->GetOrCreateStringIndex(className); - SET_FUNC_INFO_PAIR(mirFunc, "INFO_classname", idx, true); - const std::string methodName = method->GetName(); - idx = module.GetMIRBuilder()->GetOrCreateStringIndex(methodName); - SET_FUNC_INFO_PAIR(mirFunc, "INFO_funcname", idx, true); - SET_FUNC_INFO_PAIR(mirFunc, "INFO_methodidx", method->GetIdx(), false); - SET_FUNC_INFO_PAIR(mirFunc, "INFO_registers", method->GetRegisterTotalSize(), false); - SET_FUNC_INFO_PAIR(mirFunc, "INFO_dexthisreg", method->GetThisRegNum(), false); - } - feFunction->Init(); - feFunction->SetSrcFileName(structHelper->GetSrcFileName()); - functions.push_back(std::move(feFunction)); - } - } - timer.StopAndDumpTimeMS("BCCompilerComponent::PreProcessWithFunction()"); - return true; +std::unique_ptr BCCompilerComponent::CreatFEFunctionImpl(FEInputMethodHelper *methodHelper) { + BCClassMethod2FEHelper *bcMethodHelper = static_cast(methodHelper); + GStrIdx methodNameIdx = methodHelper->GetMethodNameIdx(); + bool isStatic = methodHelper->IsStatic(); + MIRFunction *mirFunc = FEManager::GetTypeManager().GetMIRFunction(methodNameIdx, isStatic); + CHECK_NULL_FATAL(mirFunc); + std::unique_ptr feFunction = std::make_unique(*bcMethodHelper, *mirFunc, phaseResultTotal); + module.AddFunction(mirFunc); + feFunction->Init(); + return feFunction; } template diff --git a/src/mplfe/bc_input/include/bc_compiler_component.h b/src/mplfe/bc_input/include/bc_compiler_component.h index b8b76d16c8ae7cb170f5fa745ec893730c913f95..8b4140e962e4c7180f0d84ea59f92c8b46585a95 100644 --- a/src/mplfe/bc_input/include/bc_compiler_component.h +++ b/src/mplfe/bc_input/include/bc_compiler_component.h @@ -29,11 +29,8 @@ class BCCompilerComponent : public MPLFECompilerComponent { protected: bool ParseInputImpl() override; bool LoadOnDemandTypeImpl() override; - bool PreProcessDeclImpl() override; - bool ProcessDeclImpl() override; void ProcessPragmaImpl() override; - bool PreProcessWithoutFunctionImpl() override; - bool PreProcessWithFunctionImpl() override; + std::unique_ptr CreatFEFunctionImpl(FEInputMethodHelper *methodHelper) override; std::string GetComponentNameImpl() const override; bool ParallelableImpl() const override; void DumpPhaseTimeTotalImpl() const override; diff --git a/src/mplfe/bc_input/include/bc_function.h b/src/mplfe/bc_input/include/bc_function.h index 95811635e3712e4770072025fe2c05b46a7a7ee5..3bd87a19550afbe5e3e4211d2aa83d4958c4eded 100644 --- a/src/mplfe/bc_input/include/bc_function.h +++ b/src/mplfe/bc_input/include/bc_function.h @@ -19,6 +19,10 @@ namespace maple { namespace bc { +#define SET_FUNC_INFO_PAIR(A, B, C, D) \ + A.PushbackMIRInfo(MIRInfoPair(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(B), C)); \ + A.PushbackIsString(D) + class BCFunction : public FEFunction { public: BCFunction(const BCClassMethod2FEHelper &argMethodHelper, MIRFunction &mirFunc, @@ -32,6 +36,7 @@ class BCFunction : public FEFunction { } bool GenerateArgVarList(const std::string &phaseName) override; + bool GenerateAliasVars(const std::string &phaseName) override; bool PreProcessTypeNameIdx() override { return true; @@ -58,6 +63,7 @@ class BCFunction : public FEFunction { bool EmitToFEIRStmt(const std::string &phaseName) override; void InitImpl() override; + void SetMIRFunctionInfo(); void PreProcessImpl() override; bool ProcessImpl() override; bool ProcessFEIRFunction() override; diff --git a/src/mplfe/bc_input/include/bc_input-inl.h b/src/mplfe/bc_input/include/bc_input-inl.h index ab0dccc51e4ced840d4e5d56ed117636b838e4e7..ad43262404d8c1195acf8aa971caf93165b76c38 100644 --- a/src/mplfe/bc_input/include/bc_input-inl.h +++ b/src/mplfe/bc_input/include/bc_input-inl.h @@ -113,6 +113,12 @@ bool BCInput::CollectAllDepTypeNamesOnAllBCFiles(std::unordered_set classSet; + CollectClassNamesOnAllBCFiles(classSet); + for (const auto &elem : classSet) { + (void)allDepSet.erase(elem); + } return true; } diff --git a/src/mplfe/bc_input/include/bc_instruction.h b/src/mplfe/bc_input/include/bc_instruction.h index 6e9718240ad4f3702372da3b26393d727d46ceba..713f4364ea912864abec139e16bb1c2d7b848a4f 100644 --- a/src/mplfe/bc_input/include/bc_instruction.h +++ b/src/mplfe/bc_input/include/bc_instruction.h @@ -71,13 +71,13 @@ class BCInstruction { void SetSrcPositionInfo(uint32 fileIdxIn, uint32 lineNumIn); void SetOpName(const char *name); const char *GetOpName() const; - void Parse(const BCClassMethod &method); + void Parse(BCClassMethod &method); void SetExceptionType(const GStrIdx &typeNameIdx); std::list EmitToFEIRStmts(); protected: virtual std::vector GetTargetsImpl() const; - virtual void ParseImpl(const BCClassMethod &method) = 0; + virtual void ParseImpl(BCClassMethod &method) = 0; virtual std::list EmitToFEIRStmtsImpl() = 0; void GenCommentStmt(std::list &stmts) const; UniqueFEIRStmt GenLabelStmt() const; @@ -115,30 +115,27 @@ class BCInstruction { // Forward declaration struct BCReg; +struct TypeInferItem; struct BCRegTypeItem { - BCRegTypeItem(const GStrIdx &idx, bool isPrimPtrIn = false, bool isIndeterminateIn = false) - : typeNameIdx(idx), isPrimPtr(isPrimPtrIn), isIndeterminate(isIndeterminateIn) {} + BCRegTypeItem(const GStrIdx &idx, bool isIndeterminateIn = false, bool isDefIn = false) + : typeNameIdx(idx), isIndeterminate(isIndeterminateIn), isDef(isDefIn) {} BCRegTypeItem(const BCRegTypeItem &item) - : typeNameIdx(item.typeNameIdx), isPrimPtr(item.isPrimPtr), isIndeterminate(item.isIndeterminate) {} + : typeNameIdx(item.typeNameIdx), isIndeterminate(item.isIndeterminate) {} ~BCRegTypeItem() = default; - GStrIdx typeNameIdx; - bool isPrimPtr = false; - bool isIndeterminate = false; PrimType GetPrimType() const; PrimType GetBasePrimType() const; BCRegTypeItem *Clone(const MapleAllocator &allocator) { - return allocator.GetMemPool()->New(typeNameIdx, isPrimPtr, isIndeterminate); + return allocator.GetMemPool()->New(typeNameIdx, isIndeterminate); } void Copy(const BCRegTypeItem &src) { typeNameIdx = src.typeNameIdx; - isPrimPtr = src.isPrimPtr; isIndeterminate = src.isIndeterminate; } bool operator==(const BCRegTypeItem &item) const { - return typeNameIdx == item.typeNameIdx && isPrimPtr == item.isPrimPtr; + return typeNameIdx == item.typeNameIdx; } bool IsRef() const { @@ -146,12 +143,25 @@ struct BCRegTypeItem { } bool IsMorePreciseType(const BCRegTypeItem &typeItemIn) const; + + // for debug + void DumpTypeName() const { + LogInfo::MapleLogger(kLlDbg) << GlobalTables::GetStrTable().GetStringFromStrIdx(typeNameIdx) << "\n"; + } + + void SetPos(uint32 pc) { + pos = pc; + } + + GStrIdx typeNameIdx; + bool isIndeterminate = false; + bool isDef = false; + uint32 pos = UINT32_MAX; }; class BCRegType { public: - BCRegType(MapleAllocator &allocatorIn, BCReg ®, const GStrIdx &typeNameIdxIn, - bool isPrimPtrIn = false, bool isIndeterminateIn = false); + BCRegType(MapleAllocator &allocatorIn, BCReg ®, const GStrIdx &typeNameIdxIn, bool isIndeterminateIn = false); ~BCRegType() = default; MapleAllocator &GetAllocator() { return allocator; @@ -161,10 +171,6 @@ class BCRegType { regTypeItem->typeNameIdx = idx; } - void SetIsPrimPtr(bool flag) { - regTypeItem->isPrimPtr = flag; - } - bool IsIndeterminate() const { return regTypeItem->isIndeterminate; } @@ -173,13 +179,9 @@ class BCRegType { regTypeItem->isIndeterminate = flag; } - void UpdateDefTypeFromUse(BCRegTypeItem *typeItem); - - void UpdateDefTypeThroughPhi(BCReg &defedReg, const std::set &usedTypes); - - static void InsertUniqueTypeItem(MapleVector &itemSet, BCRegTypeItem *item) { + static void InsertUniqueTypeItem(MapleList &itemSet, BCRegTypeItem *item) { for (auto &elem : itemSet) { - if (!elem->isIndeterminate && (*elem) == (*item)) { + if ((!elem->isIndeterminate && !item->isIndeterminate && (*elem) == (*item)) || elem == item) { return; } } @@ -187,11 +189,16 @@ class BCRegType { } void UpdateUsedSet(BCRegTypeItem *typeItem) { - if (regTypeItem->isIndeterminate && !typeItem->isIndeterminate && ((*regTypeItem) == (*typeItem))) { - // Make reg type determinate ASAP - regTypeItem->Copy(*typeItem); + if (typeItem->isIndeterminate) { + InsertUniqueTypeItem(fuzzyTypesUsedAs, typeItem); + } + InsertUniqueTypeItem(*typesUsedAs, typeItem); + } + + void UpdateFuzzyUsedSet(BCRegTypeItem *typeItem) { + if (typeItem->isIndeterminate) { + InsertUniqueTypeItem(fuzzyTypesUsedAs, typeItem); } - InsertUniqueTypeItem(typesUsedAs, typeItem); } void SetRegTypeItem(BCRegTypeItem *item) { @@ -202,37 +209,68 @@ class BCRegType { return regTypeItem; } - void UpdateTypeSetFromPhi(BCReg &defedReg, const std::set &usedTypes); - - MapleVector *GetUsedTypes() { - return &typesUsedAs; + MapleList *GetUsedTypes() { + return typesUsedAs; } - void PrecisifyTypes(); + void PrecisifyTypes(bool isTry = false); + + void PrecisifyRelatedTypes(BCRegTypeItem *realType); + + void PrecisifyElemTypes(BCRegTypeItem *realType); bool IsPrecisified() const { return precisified; } - static BCRegTypeItem *GetMostPreciseType(const MapleVector &types); + static BCRegTypeItem *GetMostPreciseType(const MapleList &types); void AddElemType(BCRegType *item) { elemTypes.emplace(item); } - void AddArrayType(BCRegType *regType) { - arrayTypes.emplace(regType); + void SetUsedTypes(MapleList *types) { + typesUsedAs = types; + } + + void SetPos(uint32 pc) { + pos = pc; + } + + void RegisterRelatedBCRegType(BCRegType *ty) { + relatedBCRegTypes.emplace_back(ty); + } + + void RegisterLivesInfo(uint32 pos) { + livesBegins.emplace_back(pos); + } + + bool IsBefore(uint32 pos, uint32 end) const { + for (auto p : livesBegins) { + if (p == pos) { + return true; + } + if (p == end) { + return false; + } + } + CHECK_FATAL(false, "Should not get here."); + return true; } private: - MapleAllocator allocator; + MapleAllocator &allocator; BCReg &curReg; BCRegTypeItem *regTypeItem; - // - MapleVector typesUsedAs; + MapleList *typesUsedAs = nullptr; + MapleList fuzzyTypesUsedAs; bool precisified = false; MapleSet elemTypes; - MapleSet arrayTypes; + uint32 pos = UINT32_MAX; + // `0` for args, `pc + 1` for local defs + MapleVector livesBegins; + + std::list relatedBCRegTypes; }; struct BCRegValue { @@ -240,7 +278,6 @@ struct BCRegValue { uint64 raw64 = 0; uint32 raw32; } primValue; - GStrIdx literalStrIdx = GStrIdx(0); // literal string }; struct BCReg { @@ -271,6 +308,77 @@ struct BCReg { virtual UniqueFEIRVar GenFEIRVarRegImpl() const; virtual std::unique_ptr CloneImpl() const; }; + +// for TypeInfer +struct TypeInferItem { + TypeInferItem(MapleAllocator &alloc, uint32 pos, BCReg *regIn, TypeInferItem *prev) + : beginPos(pos), + prevs(alloc.Adapter()), + aliveUsedTypes(alloc.GetMemPool()->New>(alloc.Adapter())), + reg(regIn) { + if (prev == nullptr) { + reg->regType->SetUsedTypes(aliveUsedTypes); + } else { + RegisterInPrevs(prev); + } + reg->regType->RegisterLivesInfo(pos); + } + + void RegisterInPrevs(TypeInferItem *prev) { + for (auto e : prevs) { + if (e == prev) { + return; + } + } + prevs.emplace_back(prev); + } + + void InsertUniqueAliveType(TypeInferItem *end, BCRegTypeItem *type) { + std::vector workList; + uint32 index = 0; + if (end != nullptr && end->reg == this->reg && end->reg->regType->IsBefore(this->beginPos, end->beginPos)) { + return; + } + workList.emplace_back(this); + while (index < workList.size()) { + auto currItem = workList[index++]; + currItem->isAlive = true; + bool duplicate = false; + for (auto ty : *(currItem->aliveUsedTypes)) { + if (ty == type) { + duplicate = true; + break; + } + } + if (!duplicate) { + currItem->aliveUsedTypes->emplace_back(type); + reg->regType->UpdateFuzzyUsedSet(type); + } + // insert into its prevs cyclely + for (auto prev : currItem->prevs) { + if (end != nullptr && end->reg == prev->reg && end->reg->regType->IsBefore(prev->beginPos, end->beginPos)) { + continue; + } + bool exist = false; + for (uint32 i = 0; i < workList.size(); ++i) { + if (workList[i] == prev) { + exist = true; + break; + } + } + if (!exist) { + workList.emplace_back(prev); + } + } + } + } + + uint32 beginPos; + MapleList prevs; + MapleList *aliveUsedTypes = nullptr; + BCReg *reg = nullptr; + bool isAlive = false; +}; } // namespace bc } // namespace maple #endif // MPLFE_BC_INPUT_INCLUDE_BC_INSTRUCTION_H diff --git a/src/mplfe/bc_input/include/bc_io.h b/src/mplfe/bc_input/include/bc_io.h index b7d9eb6cc29d79dc911bb90dab56005d320ac6b4..b48dd791d5ce4ed956e0ed65416817ead6c57003 100644 --- a/src/mplfe/bc_input/include/bc_io.h +++ b/src/mplfe/bc_input/include/bc_io.h @@ -78,6 +78,7 @@ class BCReader : public BCIO, public BasicIORead { ClassElem GetClassFieldFromIdx(uint32 idx) const; std::string GetSignature(uint32 idx) const; uint32 GetFileIndex() const; + std::string GetIRSrcFileSignature() const; protected: virtual std::string GetStringFromIdxImpl(uint32 idx) const = 0; @@ -87,6 +88,7 @@ class BCReader : public BCIO, public BasicIORead { virtual std::string GetSignatureImpl(uint32 idx) const = 0; virtual uint32 GetFileIndexImpl() const = 0; virtual bool RetrieveHeaderImpl(RawData &data); + std::string irSrcFileSignature; }; } // namespace bc } // namespace maple diff --git a/src/mplfe/bc_input/include/bc_pragma.h b/src/mplfe/bc_input/include/bc_pragma.h index b85076771009504222e17eef42867843d3e6e996..7dd449f60a1fc1313af1a6baa393723435a4c653 100644 --- a/src/mplfe/bc_input/include/bc_pragma.h +++ b/src/mplfe/bc_input/include/bc_pragma.h @@ -1,17 +1,17 @@ /* - * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. - * - * OpenArkCompiler is licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * - * http://license.coscl.org.cn/MulanPSL2 - * - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR - * FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v1 for more details. - */ + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ #ifndef MPLFE_BC_INPUT_INCLUDE_BC_PRAGMA_H #define MPLFE_BC_INPUT_INCLUDE_BC_PRAGMA_H #include @@ -20,11 +20,13 @@ #include "mir_module.h" #include "mir_pragma.h" #include "mempool.h" + namespace maple { namespace bc { class BCAnnotationsDirectory { public: - BCAnnotationsDirectory(MIRModule &moduleArg, MemPool &mpArg) : module(moduleArg), mp(mpArg) {} + BCAnnotationsDirectory(MIRModule &moduleArg, MemPool &mpArg) + : module(moduleArg), mp(mpArg) {} virtual ~BCAnnotationsDirectory() = default; std::vector &EmitPragmas() { return EmitPragmasImpl(); @@ -38,4 +40,4 @@ class BCAnnotationsDirectory { }; } // namespace bc } // namespace maple -#endif // MPLFE_BC_INPUT_INCLUDE_BC_PRAGMA_H +#endif // MPLFE_BC_INPUT_INCLUDE_BC_PRAGMA_H \ No newline at end of file diff --git a/src/mplfe/bc_input/include/bc_util.h b/src/mplfe/bc_input/include/bc_util.h index 3446ca1747892b7a5dbc5a51d210fc66530f96a1..4894110760e45d711e4710086966b7be5129f1ca 100644 --- a/src/mplfe/bc_input/include/bc_util.h +++ b/src/mplfe/bc_input/include/bc_util.h @@ -252,9 +252,12 @@ class BCUtil { static PrimType GetPrimType(const GStrIdx &name); static bool IsJavaReferenceType(const GStrIdx &typeNameIdx); static bool IsJavaPrimitveType(const GStrIdx &typeNameIdx); + static bool IsJavaPrimitiveTypeName(const std::string typeName); static bool IsArrayType(const GStrIdx &typeNameIdx); static std::string TrimArrayModifier(const std::string &typeName); static void AddDefaultDepSet(std::unordered_set &typeSet); + static uint32 Name2RegNum(const std::string &name); + static bool HasContainSuffix(const std::string &value, const std::string &suffix); }; // BCUtil } // namespace bc } // namespace maple diff --git a/src/mplfe/bc_input/include/rc_setter.h b/src/mplfe/bc_input/include/rc_setter.h new file mode 100644 index 0000000000000000000000000000000000000000..9bdaf2a0622eea1d8651fdc1ede6de52f224a05a --- /dev/null +++ b/src/mplfe/bc_input/include/rc_setter.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#ifndef BC_INPUT_INCLUDE_RC_SETTER_H +#define BC_INPUT_INCLUDE_RC_SETTER_H +#include +#include +#include +#include "types_def.h" +#include "bc_class.h" +#include "mir_type.h" +#include "mir_function.h" + +namespace maple { +namespace bc { +class RCSetter { + public: + static RCSetter &GetRCSetter() { + ASSERT(rcSetter != nullptr, "rcSetter is not initialize"); + return *rcSetter; + } + + static void InitRCSetter(const std::string &whiteListName) { + rcSetter = new RCSetter(whiteListName); + } + + static void ReleaseRCSetter() { + if (rcSetter != nullptr) { + delete rcSetter; + rcSetter = nullptr; + } + } + + void ProcessClassRCAnnotation(const GStrIdx &classIdx, const std::vector &pragmas); + void ProcessMethodRCAnnotation(MIRFunction &mirFunc, const std::string &className, + MIRStructType &structType, const MIRPragma &pragma); + void ProcessFieldRCAnnotation(const StructElemNameIdx &fieldElemNameIdx, + const MIRType &fieldType, const std::vector &pragmas); + void GetUnownedVarInLocalVars(const BCClassMethod &method, MIRFunction &mirFunction); + void CollectUnownedLocalFuncs(MIRFunction *func); + void CollectUnownedLocalVars(MIRFunction *func, const GStrIdx &strIdx); + void CollectInputStmtField(StmtNode *stmt, const GStrIdx &fieldName); + void SetRCFieldAttrByWhiteList(FieldAttrs &attr, const std::string &className, const std::string &fieldName); + void SetAttrRCunowned(MIRFunction &mirFunction, const std::set &unownedRegNums) const; + void MarkRCAttributes() const; + + private: + explicit RCSetter(const std::string &whiteListName) : rcFieldAttrWhiteListName(whiteListName) { + if (!rcFieldAttrWhiteListName.empty()) { + LoadRCFieldAttrWhiteList(rcFieldAttrWhiteListName); + } + } + ~RCSetter() = default; + void MarkRCUnownedForUnownedLocalFunctions() const; + void MarkRCUnownedForAnonymousClasses() const; + void MarkRCUnownedForLambdaClasses() const; + void SetRCUnownedAttributeInternalSetFieldAttrRCUnowned(size_t opnd, const MIRFunction &calledFunc) const; + void SetRCUnownedAttribute(const CallNode &callNode, MIRFunction &func, + const MIRFunction &calledFunc, const std::set &gStrIdx) const; + bool IsAnonymousInner(const MIRStructType &structType) const; + bool IsMethodEnclosing(const MIRFunction &func, const MIRStructType &structType) const; + void LoadRCFieldAttrWhiteList(const std::string &file); + + static RCSetter *rcSetter; + const std::string rcFieldAttrWhiteListName; + std::map>> rcFieldAttrWhiteListMap; + std::set unownedLocalFuncs; + std::map> unownedLocalVars; + std::map iputStmtFieldMap; +}; +} // namespace bc +} // namespace maple +#endif // BC_INPUT_INCLUDE_RC_SETTER_H \ No newline at end of file diff --git a/src/mplfe/bc_input/src/ark_annotation_map.cpp b/src/mplfe/bc_input/src/ark_annotation_map.cpp index 21087cfc64541fc6e48eae250a8ad812aba43c60..d10ec2577cef7167d76e99e10cad722f5357c3a5 100644 --- a/src/mplfe/bc_input/src/ark_annotation_map.cpp +++ b/src/mplfe/bc_input/src/ark_annotation_map.cpp @@ -1,17 +1,17 @@ /* - * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. - * - * OpenArkCompiler is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * - * http://license.coscl.org.cn/MulanPSL2 - * - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR - * FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - */ + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ #include "ark_annotation_map.h" namespace maple { diff --git a/src/mplfe/bc_input/src/ark_annotation_processor.cpp b/src/mplfe/bc_input/src/ark_annotation_processor.cpp index 659e5977a652a8e065ab37ed465d73b7b0385f34..9d11e74ecb5a40b0392f2eb5a1a28bbedd8fbe9b 100644 --- a/src/mplfe/bc_input/src/ark_annotation_processor.cpp +++ b/src/mplfe/bc_input/src/ark_annotation_processor.cpp @@ -40,6 +40,36 @@ void ArkAnnotation::Init() { typeNameSetForCriticalNative.insert(GetStrIdxFromDexName("Lark/annotation/optimization/CriticalNative;")); // CallerSensitive typeNameSetForCallerSensitive.insert(GetStrIdxFromDexName("Lsun/reflect/CallerSensitive;")); + // Permanent + typeNameSetForPermanent.insert(GetStrIdxFromDexName("Lcom/huawei/ark/annotation/Permanent;")); + typeNameSetForPermanent.insert(GetStrIdxFromDexName("Lharmonyos/annotation/Permanent;")); + typeNameSetForPermanent.insert(GetStrIdxFromDexName("Lark/annotation/Permanent;")); + // RCU + typeNameSetForRCUnowned.insert(GetStrIdxFromDexName("Ljava/lang/annotation/RCUnownedRef;")); + typeNameSetForRCUnowned.insert(GetStrIdxFromDexName("Lcom/huawei/ark/annotation/Unowned;")); + typeNameSetForRCUnowned.insert(GetStrIdxFromDexName("Lharmonyos/annotation/Unowned;")); + typeNameSetForRCUnowned.insert(GetStrIdxFromDexName("Lark/annotation/Unowned;")); + // RCUnownedCap + typeNameSetForRCUnownedCap.insert(GetStrIdxFromDexName("Ljava/lang/annotation/RCUnownedCapRef;")); + // RCUnownedCapList + typeNameSetForRCUnownedCapList.insert(GetStrIdxFromDexName("Ljava/lang/annotation/RCUnownedCapRef$List;")); + // RCUnownedLocal + typeNameSetForRCUnownedLocal.insert(GetStrIdxFromDexName("Lcom/huawei/ark/annotation/UnownedLocal;")); + typeNameSetForRCUnownedLocal.insert(GetStrIdxFromDexName("Lharmonyos/annotation/UnownedLocal;")); + typeNameSetForRCUnownedLocal.insert(GetStrIdxFromDexName("Lark/annotation/UnownedLocal;")); + // RCUnownedLocalOld + typeNameIdxForRCUnownedLocalOld = GetStrIdxFromDexName("Ljava/lang/annotation/RCLocalUnownedRef;"); + // RCUnownedThis + typeNameSetForRCUnownedThis.insert(GetStrIdxFromDexName("Ljava/lang/annotation/RCUnownedThisRef;")); + // RCUnownedOuter + typeNameSetForRCUnownedOuter.insert(GetStrIdxFromDexName("Lcom/huawei/ark/annotation/UnownedOuter;")); + typeNameSetForRCUnownedOuter.insert(GetStrIdxFromDexName("Lharmonyos/annotation/UnownedOuter;")); + typeNameSetForRCUnownedOuter.insert(GetStrIdxFromDexName("Lark/annotation/UnownedOuter;")); + // RCWeak + typeNameSetForRCWeak.insert(GetStrIdxFromDexName("Ljava/lang/annotation/RCWeakRef;")); + typeNameSetForRCWeak.insert(GetStrIdxFromDexName("Lcom/huawei/ark/annotation/Weak;")); + typeNameSetForRCWeak.insert(GetStrIdxFromDexName("Lharmonyos/annotation/Weak;")); + typeNameSetForRCWeak.insert(GetStrIdxFromDexName("Lark/annotation/Weak;")); } bool ArkAnnotation::IsFastNative(TyIdx tyIdx) { @@ -60,6 +90,71 @@ bool ArkAnnotation::IsCallerSensitive(TyIdx tyIdx) { false : typeNameSetForCallerSensitive.find(sType->GetNameStrIdx()) != typeNameSetForCallerSensitive.end(); } +bool ArkAnnotation::IsPermanent(TyIdx tyIdx) { + MIRStructType *sType = GetStructType(tyIdx); + return sType == nullptr ? + false : typeNameSetForPermanent.find(sType->GetNameStrIdx()) != typeNameSetForPermanent.end(); +} + +bool ArkAnnotation::IsPermanent(const std::string &str) const { + for (auto idx : typeNameSetForPermanent) { + std::string annoName = GlobalTables::GetStrTable().GetStringFromStrIdx(idx); + annoName = namemangler::DecodeName(annoName); + if (annoName.compare(str) == 0) { + return true; + } + } + return false; +} + +bool ArkAnnotation::IsRCUnowned(TyIdx tyIdx) { + MIRStructType *sType = GetStructType(tyIdx); + return sType == nullptr ? + false : typeNameSetForRCUnowned.find(sType->GetNameStrIdx()) != typeNameSetForRCUnowned.end(); +} + +bool ArkAnnotation::IsRCUnownedCap(TyIdx tyIdx) { + MIRStructType *sType = GetStructType(tyIdx); + return sType == nullptr ? + false : typeNameSetForRCUnownedCap.find(sType->GetNameStrIdx()) != typeNameSetForRCUnownedCap.end(); +} + +bool ArkAnnotation::IsRCUnownedCapList(TyIdx tyIdx) { + MIRStructType *sType = GetStructType(tyIdx); + return sType == nullptr ? + false : typeNameSetForRCUnownedCapList.find(sType->GetNameStrIdx()) != typeNameSetForRCUnownedCapList.end(); +} + +bool ArkAnnotation::IsRCUnownedLocal(TyIdx tyIdx) { + MIRStructType *sType = GetStructType(tyIdx); + return sType == nullptr ? + false : typeNameSetForRCUnownedLocal.find(sType->GetNameStrIdx()) != typeNameSetForRCUnownedLocal.end(); +} + +bool ArkAnnotation::IsRCUnownedLocalOld(TyIdx tyIdx) { + MIRStructType *sType = GetStructType(tyIdx); + return sType == nullptr ? + false : typeNameIdxForRCUnownedLocalOld == sType->GetNameStrIdx(); +} + +bool ArkAnnotation::IsRCUnownedThis(TyIdx tyIdx) { + MIRStructType *sType = GetStructType(tyIdx); + return sType == nullptr ? + false : typeNameSetForRCUnownedThis.find(sType->GetNameStrIdx()) != typeNameSetForRCUnownedThis.end(); +} + +bool ArkAnnotation::IsRCUnownedOuter(TyIdx tyIdx) { + MIRStructType *sType = GetStructType(tyIdx); + return sType == nullptr ? + false : typeNameSetForRCUnownedOuter.find(sType->GetNameStrIdx()) != typeNameSetForRCUnownedOuter.end(); +} + +bool ArkAnnotation::IsRCWeak(TyIdx tyIdx) { + MIRStructType *sType = GetStructType(tyIdx); + return sType == nullptr ? + false : typeNameSetForRCWeak.find(sType->GetNameStrIdx()) != typeNameSetForRCWeak.end(); +} + MIRStructType *ArkAnnotation::GetStructType(TyIdx tyIdx) { MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); if (!type->IsMIRClassType() && !type->IsMIRInterfaceType()) { diff --git a/src/mplfe/bc_input/src/bc_class.cpp b/src/mplfe/bc_input/src/bc_class.cpp index 46bc05d5b0d1b264cab26612c8fca13fc83e1c34..4c19db1e187c094256f9b35b43a191a5fa577114 100644 --- a/src/mplfe/bc_input/src/bc_class.cpp +++ b/src/mplfe/bc_input/src/bc_class.cpp @@ -91,6 +91,14 @@ uint16 BCClassMethod::GetRegisterTotalSize() const{ return registerTotalSize; } +void BCClassMethod::SetCodeOff(uint32 off) { + codeOff = off; +} + +uint32 BCClassMethod::GetCodeOff() const { + return codeOff; +} + void BCClassMethod::SetRegisterInsSize(uint16 size) { registerInsSize = size; } @@ -236,10 +244,11 @@ void BCClassMethod::ProcessTryCatch() { // Use linear scan with SSA // We insert phi behind the def in a edge before the dominance if the reg is alive under this dominance. // A reg is default dead at its definition, we mark a reg alive only when it was used. -// We transfer reg live info through shared memory, record live-interval in dominancesMap. +// And insert the reg def-type into `used alive types` if it is defined in a determinate type. +// We transfer reg live info through shared memory, record live-interval in dominancesMap and BCRegType::livesBegins. // After a multi-in pos, we create a new TypeInferItem for a new live range. +// Insert `in-edge` into dominance `prevs`, for record complete reg use in circles by one pass. void BCClassMethod::TypeInfer() { - std::list> typeInferItems; std::set visitedSet; // [pc, [regNum, TypeInferItem*]] std::list>> pcDefedRegsList; @@ -247,12 +256,23 @@ void BCClassMethod::TypeInfer() { std::vector> dominances((*pcBCInstructionMap).rbegin()->first + 1); std::vector regTypeMap(registerTotalSize, nullptr); for (auto ® : argRegs) { - regTypeMap[reg->regNum] = RegisterTypeInferItem(typeInferItems, reg.get(), nullptr); + regTypeMap[reg->regNum] = ConstructTypeInferItem(allocator, 0, reg.get(), nullptr); regTypes.emplace_back(reg->regType); } - pcDefedRegsList.emplace_front(0, regTypeMap); - dominances[0] = regTypeMap; visitedSet.emplace(0); + if (multiInDegreeSet.find(0) != multiInDegreeSet.end()) { + std::vector typeMap = ConstructNewRegTypeMap(allocator, 1, regTypeMap); + pcDefedRegsList.emplace_front(0, typeMap); + dominances[0] = typeMap; + } else { + pcDefedRegsList.emplace_front(0, regTypeMap); + } + Traverse(pcDefedRegsList, dominances, visitedSet); + PrecisifyRegType(); +} + +void BCClassMethod::Traverse(std::list>> &pcDefedRegsList, + std::vector> &dominances, std::set &visitedSet) { while (!pcDefedRegsList.empty()) { auto head = pcDefedRegsList.front(); pcDefedRegsList.pop_front(); @@ -264,24 +284,12 @@ void BCClassMethod::TypeInfer() { CHECK_FATAL(defedItem != nullptr && defedItem->reg != nullptr, "Cannot find Reg%u defination at 0x%x:0x%x in method %s", usedReg->regNum, head.first, currInst->GetOpcode(), GetFullName().c_str()); - if (usedReg->regTypeItem == nullptr) { - usedReg->regTypeItem = defedItem->reg->regTypeItem; - usedReg->regValue = defedItem->reg->regValue; - } else { - if (defedItem->reg->regTypeItem->isIndeterminate || - !(*(defedItem->reg->regTypeItem) == *(usedReg->regTypeItem))) { - defedItem->reg->regType->UpdateDefTypeFromUse(usedReg->regTypeItem); - } - } + usedReg->regValue = defedItem->reg->regValue; usedReg->regType = defedItem->reg->regType; currInst->SetRegTypeInTypeInfer(); // Make the reg alive when it used, live range [defPos, usePos] - defedItem->aliveUsedTypes.emplace(usedReg->regTypeItem); - TypeInferItem *item = defedItem->prev; - while (item != nullptr) { - item->aliveUsedTypes.emplace(usedReg->regTypeItem); - item = item->prev; - } + usedReg->regTypeItem->SetPos(currInst->GetPC()); + defedItem->InsertUniqueAliveType(nullptr, usedReg->regTypeItem); } auto defedRegs = currInst->GetDefedRegs(); auto exHandlerTargets = currInst->GetHandlerTargets(); @@ -293,18 +301,17 @@ void BCClassMethod::TypeInfer() { continue; } if ((multiInDegreeSet.find(exHandlerTarget) != multiInDegreeSet.end())) { - std::vector typeMap = ConstructNewRegTypeMap(nextRegTypeMap, typeInferItems); + std::vector typeMap = ConstructNewRegTypeMap(allocator, exHandlerTarget + 1, nextRegTypeMap); pcDefedRegsList.emplace_front(exHandlerTarget, typeMap); - if (multiInDegreeSet.find(exHandlerTarget) != multiInDegreeSet.end()) { - dominances[exHandlerTarget] = typeMap; - } + dominances[exHandlerTarget] = typeMap; } else { pcDefedRegsList.emplace_front(exHandlerTarget, nextRegTypeMap); } } for (auto defedReg : *defedRegs) { - TypeInferItem *item = RegisterTypeInferItem(typeInferItems, defedReg, nullptr); + TypeInferItem *item = ConstructTypeInferItem(allocator, currInst->GetPC() + 1, defedReg, nullptr); nextRegTypeMap[defedReg->regNum] = item; + defedReg->regType->SetPos(currInst->GetPC()); regTypes.emplace_back(defedReg->regType); } if (currInst->IsFallThru() && next <= pcBCInstructionMap->rbegin()->first) { @@ -313,11 +320,9 @@ void BCClassMethod::TypeInfer() { InsertPhi(domIt, nextRegTypeMap); } else { if (multiInDegreeSet.find(next) != multiInDegreeSet.end()) { - std::vector typeMap = ConstructNewRegTypeMap(nextRegTypeMap, typeInferItems); + std::vector typeMap = ConstructNewRegTypeMap(allocator, next + 1, nextRegTypeMap); pcDefedRegsList.emplace_front(next, typeMap); - if (multiInDegreeSet.find(next) != multiInDegreeSet.end()) { - dominances[next] = typeMap; - } + dominances[next] = typeMap; } else { pcDefedRegsList.emplace_front(next, nextRegTypeMap); } @@ -326,12 +331,12 @@ void BCClassMethod::TypeInfer() { auto normalTargets = currInst->GetTargets(); for (auto normalTarget : normalTargets) { if (visitedSet.emplace(normalTarget).second == false) { - auto domIt = dominances[normalTarget]; + auto &domIt = dominances[normalTarget]; InsertPhi(domIt, nextRegTypeMap); continue; } if (multiInDegreeSet.find(normalTarget) != multiInDegreeSet.end()) { - std::vector typeMap = ConstructNewRegTypeMap(nextRegTypeMap, typeInferItems); + std::vector typeMap = ConstructNewRegTypeMap(allocator, normalTarget + 1, nextRegTypeMap); pcDefedRegsList.emplace_front(normalTarget, typeMap); dominances[normalTarget] = typeMap; } else { @@ -339,49 +344,42 @@ void BCClassMethod::TypeInfer() { } } } - PrecisifyRegType(); } -void BCClassMethod::InsertPhi(const std::vector &dest, std::vector &src) { - for (auto &d : dest) { - if (d == nullptr || d->aliveUsedTypes.empty()) { +void BCClassMethod::InsertPhi(const std::vector &dom, std::vector &src) { + for (auto &d : dom) { + if (d == nullptr) { continue; } - auto item = src[d->reg->regNum]; - if (item != nullptr) { - for (auto aliveType : d->aliveUsedTypes) { - item->aliveUsedTypes.emplace(aliveType); - } - TypeInferItem *prevItem = item->prev; - while (prevItem != nullptr) { - for (auto aliveType : d->aliveUsedTypes) { - prevItem->aliveUsedTypes.emplace(aliveType); - } - prevItem = prevItem->prev; - } - item->reg->regType->UpdateDefTypeThroughPhi(*(d->reg), d->aliveUsedTypes); + auto srcItem = src[d->reg->regNum]; + if (srcItem == d) { + continue; + } + d->RegisterInPrevs(srcItem); + + if (d->isAlive == false) { + continue; + } + CHECK_FATAL(srcItem != nullptr, "ByteCode RA error."); + for (auto ty : *(d->aliveUsedTypes)) { + srcItem->InsertUniqueAliveType(d, ty); } } } -BCClassMethod::TypeInferItem *BCClassMethod::RegisterTypeInferItem( - std::list> &items, BCReg *bcReg, TypeInferItem *prev) { - std::unique_ptr item = std::make_unique(); - item->reg = bcReg; - item->prev = prev; - TypeInferItem *ptr = item.get(); - items.emplace_back(std::move(item)); - return ptr; +TypeInferItem *BCClassMethod::ConstructTypeInferItem( + MapleAllocator &alloc, uint32 pos, BCReg *bcReg, TypeInferItem *prev) { + TypeInferItem *item = alloc.GetMemPool()->New(alloc, pos, bcReg, prev); + return item; } -std::vector BCClassMethod::ConstructNewRegTypeMap( - const std::vector ®TypeMap, - std::list> &items) { +std::vector BCClassMethod::ConstructNewRegTypeMap(MapleAllocator &alloc, uint32 pos, + const std::vector ®TypeMap) { std::vector res(regTypeMap.size(), nullptr); size_t i = 0; for (const auto &elem : regTypeMap) { if (elem != nullptr) { - res[i] = RegisterTypeInferItem(items, elem->reg, elem); + res[i] = ConstructTypeInferItem(alloc, pos, elem->reg, elem); } ++i; } @@ -415,7 +413,8 @@ std::list BCClassMethod::EmitInstructionsToFEIR() const { uint32 typeID = UINT32_MAX; if (FEOptions::GetInstance().IsAOT()) { const std::string &mplClassName = GetBCClass().GetClassName(true); - typeID = FEManager::GetTypeManager().GetTypeIDFromMplClassName(mplClassName); + int32 dexFileHashCode = GetBCClass().GetBCParser().GetFileNameHashId(); + typeID = FEManager::GetTypeManager().GetTypeIDFromMplClassName(mplClassName, dexFileHashCode); } UniqueFEIRStmt stmt = std::make_unique(INTRN_JAVA_CLINIT_CHECK, @@ -572,6 +571,14 @@ std::string BCClass::GetSourceFileName() const { return GlobalTables::GetStrTable().GetStringFromStrIdx(srcFileNameIdx); } +GStrIdx BCClass::GetIRSrcFileSigIdx() const { + return irSrcFileSigIdx; +} + +uint32 BCClass::GetFileNameHashId() const { + return parser.GetFileNameHashId(); +} + uint32 BCClass::GetAccessFlag() const { return accFlag; } diff --git a/src/mplfe/bc_input/src/bc_class2fe_helper.cpp b/src/mplfe/bc_input/src/bc_class2fe_helper.cpp index 1d19144ce7751db1e03faef1b8af5359a312726e..47f493a6ef2c727bbd70ad9e75bbbae74d79f162 100644 --- a/src/mplfe/bc_input/src/bc_class2fe_helper.cpp +++ b/src/mplfe/bc_input/src/bc_class2fe_helper.cpp @@ -43,6 +43,26 @@ std::string BCClass2FEHelper::GetSourceFileNameImpl() const { return klass.GetSourceFileName(); } +void BCClass2FEHelper::TryMarkMultiDefClass(MIRStructType &typeImported) const { + MIRTypeKind kind = typeImported.GetKind(); + uint32 typeSrcSigIdx = 0; + static const GStrIdx keySignatureStrIdx = + GlobalTables::GetStrTable().GetStrIdxFromName("INFO_ir_srcfile_signature"); + if (kind == kTypeClass || kind == kTypeClassIncomplete) { + auto &classType = static_cast(typeImported); + typeSrcSigIdx = classType.GetInfo(keySignatureStrIdx); + } else if (kind == kTypeInterface || kind == kTypeInterfaceIncomplete) { + auto &interfaceType = static_cast(typeImported); + typeSrcSigIdx = interfaceType.GetInfo(keySignatureStrIdx); + } + // Find type definition in both dependent libraries and current compilation unit, mark the type multidef, + // and we will mark all it's methods multidef later. + // MiddleEnd will NOT inline the caller and callee with multidef attr. + if (typeSrcSigIdx != 0 && klass.GetIRSrcFileSigIdx() != typeSrcSigIdx) { + klass.SetIsMultiDef(true); + } +} + MIRStructType *BCClass2FEHelper::CreateMIRStructTypeImpl(bool &error) const { std::string classNameMpl = GetStructNameMplImpl(); if (classNameMpl.empty()) { @@ -51,8 +71,14 @@ MIRStructType *BCClass2FEHelper::CreateMIRStructTypeImpl(bool &error) const { return nullptr; } FE_INFO_LEVEL(FEOptions::kDumpLevelInfoDetail, "CreateMIRStrucType for %s", classNameMpl.c_str()); + GStrIdx nameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(classNameMpl); + MIRStructType *typeImported = FEManager::GetTypeManager().GetImportedType(nameIdx); + if (typeImported != nullptr) { + TryMarkMultiDefClass(*typeImported); + } + bool isCreate = false; - MIRStructType *type = FEManager::GetTypeManager().GetOrCreateClassOrInterfaceType(classNameMpl, klass.IsInterface(), + MIRStructType *type = FEManager::GetTypeManager().GetOrCreateClassOrInterfaceType(nameIdx, klass.IsInterface(), FETypeFlag::kSrcInput, isCreate); error = false; // fill global type name table @@ -77,6 +103,14 @@ uint64 BCClass2FEHelper::GetRawAccessFlagsImpl() const { return static_cast(klass.GetAccessFlag()); } +GStrIdx BCClass2FEHelper::GetIRSrcFileSigIdxImpl() const { + return klass.GetIRSrcFileSigIdx(); +} + +bool BCClass2FEHelper::IsMultiDefImpl() const { + return klass.IsMultiDef(); +} + std::string BCClass2FEHelper::GetSrcFileNameImpl() const { return klass.GetSourceFileName(); } @@ -200,7 +234,11 @@ bool BCClassMethod2FEHelper::ProcessDeclImpl(MapleAllocator &allocator) { elemInfo->SetFromDex(); mirFunc = FEManager::GetTypeManager().CreateFunction(methodNameIdx, mirReturnType->GetTypeIndex(), argsTypeIdx, isVarg, isStatic); +#ifndef USE_OPS + mirMethodPair.first = mirFunc; +#else mirMethodPair.first = mirFunc->GetStIdx(); +#endif mirMethodPair.second.first = mirFunc->GetMIRFuncType()->GetTypeIndex(); mirMethodPair.second.second = attrs; mirFunc->SetFuncAttrs(attrs); @@ -269,4 +307,4 @@ bool BCClassMethod2FEHelper::HasCodeImpl() const { return method->HasCode(); } } // namespace bc -} // namespace maple \ No newline at end of file +} // namespace maple diff --git a/src/mplfe/bc_input/src/bc_function.cpp b/src/mplfe/bc_input/src/bc_function.cpp index 911a331ba15713b43c47692753e775acdf9670ff..b18480468056686d76db77693645f28c7bdb996c 100644 --- a/src/mplfe/bc_input/src/bc_function.cpp +++ b/src/mplfe/bc_input/src/bc_function.cpp @@ -15,6 +15,10 @@ #include "bc_function.h" #include "fe_macros.h" #include "fe_manager.h" +#include "feir_type_helper.h" +#include "feir_builder.h" +#include "rc_setter.h" + namespace maple { namespace bc { BCFunction::BCFunction(const BCClassMethod2FEHelper &argMethodHelper, MIRFunction &mirFunc, @@ -31,6 +35,20 @@ void BCFunction::InitImpl() { FEFunction::InitImpl(); } +void BCFunction::SetMIRFunctionInfo() { + GStrIdx idx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(method->GetFullName()); + SET_FUNC_INFO_PAIR(mirFunction, "INFO_fullname", idx, true); + idx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(method->GetClassName()); + SET_FUNC_INFO_PAIR(mirFunction, "INFO_classname", idx, true); + idx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(method->GetName()); + SET_FUNC_INFO_PAIR(mirFunction, "INFO_funcname", idx, true); + SET_FUNC_INFO_PAIR(mirFunction, "INFO_methodidx", method->GetIdx(), false); + SET_FUNC_INFO_PAIR(mirFunction, "INFO_registers", method->GetRegisterTotalSize(), false); + SET_FUNC_INFO_PAIR(mirFunction, "INFO_tries_size", method->GetTriesSize(), false); + SET_FUNC_INFO_PAIR(mirFunction, "INFO_dexthisreg", method->GetThisRegNum(), false); + SET_FUNC_INFO_PAIR(mirFunction, "INFO_codeoff", method->GetCodeOff(), false); +} + bool BCFunction::ProcessImpl() { FE_INFO_LEVEL(FEOptions::kDumpLevelInfoDetail, "BCFunction::Process() for %s", method->GetFullName().c_str()); bool success = true; @@ -38,6 +56,7 @@ bool BCFunction::ProcessImpl() { method->GetBCClass().GetClassIdx(), method->GetItemIdx(), method->IsVirtual()); + SetMIRFunctionInfo(); success = success && GenerateArgVarList("gen arg var list"); success = success && EmitToFEIRStmt("emit to feir"); success = success && ProcessFEIRFunction(); @@ -48,6 +67,35 @@ bool BCFunction::ProcessImpl() { return success; } +bool BCFunction::GenerateAliasVars(const std::string &phaseName) { + phaseResult.RegisterPhaseNameAndStart(phaseName); + if (method == nullptr || method->GetSrcLocalInfoPtr() == nullptr) { + return phaseResult.Finish(true); + } + // map>> + for (auto &local : *method->GetSrcLocalInfoPtr()) { + for (auto &item : local.second) { + if (std::get<0>(item) == "this") { + continue; + } + UniqueFEIRType type = FEIRTypeHelper::CreateTypeByJavaName(std::get<1>(item), false, false); + MIRType *mirType = FEManager::GetTypeManager().GetOrCreateTypeFromName( + namemangler::EncodeName(std::get<1>(item)), FETypeFlag::kSrcUnknown, true); + UniqueFEIRVar localVar = FEIRBuilder::CreateVarReg(local.first, std::move(type)); + GStrIdx nameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName( + namemangler::EncodeName(std::get<0>(item))); + MIRAliasVars aliasVar; + aliasVar.memPoolStrIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(localVar->GetName(*mirType)); + aliasVar.tyIdx = mirType->GetTypeIndex(); + if (!std::get<2>(item).empty()) { + aliasVar.sigStrIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(std::get<2>(item)); + } + mirFunction.SetAliasVarMap(nameIdx, aliasVar); + } + } + return phaseResult.Finish(true); +} + bool BCFunction::ProcessFEIRFunction() { bool success = true; success = success && UpdateRegNum2This("fe/update reg num to this pointer"); @@ -90,6 +138,10 @@ void BCFunction::InsertFEIRStmtsBefore(FEIRStmt &pos, std::list void BCFunction::FinishImpl() { (void)UpdateFormal("finish/update formal"); (void)EmitToMIR("finish/emit to mir"); + (void)GenerateAliasVars("finish/generate alias vars"); + if (FEOptions::GetInstance().IsRC()) { + RCSetter::GetRCSetter().GetUnownedVarInLocalVars(*method, mirFunction); + } bool recordTime = FEOptions::GetInstance().IsDumpPhaseTime() || FEOptions::GetInstance().IsDumpPhaseTimeDetail(); if (phaseResultTotal != nullptr && recordTime) { phaseResultTotal->Combine(phaseResult); diff --git a/src/mplfe/bc_input/src/bc_instruction.cpp b/src/mplfe/bc_input/src/bc_instruction.cpp index f844e0b64c4528f885d6fe1c1550e7f27644c0f8..e11f40d33d7dc7de3b5d32bd0f4c9d050257b914 100644 --- a/src/mplfe/bc_input/src/bc_instruction.cpp +++ b/src/mplfe/bc_input/src/bc_instruction.cpp @@ -55,7 +55,7 @@ void BCInstruction::SetInstructionKind(BCInstructionKind kind) { instKind = static_cast(static_cast(instKind) | static_cast(kind)); } -void BCInstruction::Parse(const BCClassMethod &method) { +void BCInstruction::Parse(BCClassMethod &method) { ParseImpl(method); } @@ -290,11 +290,7 @@ const char *BCInstruction::GetOpName() const { // ========== BCRegTypeItem ========== PrimType BCRegTypeItem::GetPrimType() const { - if (isPrimPtr) { - return PTY_ref; - } else { - return GetBasePrimType(); - } + return GetBasePrimType(); } PrimType BCRegTypeItem::GetBasePrimType() const { @@ -312,7 +308,25 @@ bool BCRegTypeItem::IsMorePreciseType(const BCRegTypeItem &typeItemIn) const { uint8 dim0 = FEUtils::GetDim(name0); uint8 dim1 = FEUtils::GetDim(name1); if (dim0 == dim1) { - return name0.substr(dim0).compare(BCUtil::kJavaObjectName) != 0; + GStrIdx name0Idx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name0.substr(dim0)); + GStrIdx name1Idx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name1.substr(dim0)); + if (name0Idx == name1Idx || dim0 == 0) { + if (!isIndeterminate && typeItemIn.isIndeterminate) { + return true; + } else if (isIndeterminate && !typeItemIn.isIndeterminate) { + return false; + } else if (isIndeterminate && typeItemIn.isIndeterminate) { + return name1Idx == BCUtil::GetJavaObjectNameMplIdx(); + } else { + return isDef ? + (name0Idx == BCUtil::GetJavaObjectNameMplIdx() || name1Idx != BCUtil::GetJavaObjectNameMplIdx()) : + (name0Idx != BCUtil::GetJavaObjectNameMplIdx() || name1Idx == BCUtil::GetJavaObjectNameMplIdx()); + } + } else { + BCRegTypeItem item0(name0Idx, isIndeterminate); + BCRegTypeItem item1(name1Idx, typeItemIn.isIndeterminate); + return item0.IsMorePreciseType(item1); + } } else { return dim0 > dim1; } @@ -328,82 +342,94 @@ bool BCRegTypeItem::IsMorePreciseType(const BCRegTypeItem &typeItemIn) const { } // ========== BCRegType ========== -BCRegType::BCRegType(MapleAllocator &allocatorIn, BCReg ®, const GStrIdx &typeNameIdxIn, - bool isPrimPtrIn, bool isIndeterminateIn) +BCRegType::BCRegType(MapleAllocator &allocatorIn, BCReg ®, const GStrIdx &typeNameIdxIn, bool isIndeterminateIn) : allocator(allocatorIn), curReg(reg), - regTypeItem(allocator.GetMemPool()->New(typeNameIdxIn, isPrimPtrIn, isIndeterminateIn)), - typesUsedAs(allocator.Adapter()), + regTypeItem(allocator.GetMemPool()->New(typeNameIdxIn, isIndeterminateIn, true)), + fuzzyTypesUsedAs(allocator.Adapter()), elemTypes(allocator.Adapter()), - arrayTypes(allocator.Adapter()) { + livesBegins(allocator.Adapter()) { curReg.regTypeItem = regTypeItem; -} - -void BCRegType::UpdateDefTypeFromUse(BCRegTypeItem *typeItem) { - UpdateUsedSet(typeItem); -} - -void BCRegType::UpdateDefTypeThroughPhi(BCReg &defedReg, const std::set &usedTypes) { - UpdateTypeSetFromPhi(defedReg, usedTypes); -} - -void BCRegType::UpdateTypeSetFromPhi(BCReg &defedReg, const std::set &usedTypes) { - bool isIndeterminate = true; - for (auto &elem : usedTypes) { - if (!elem->isIndeterminate) { - isIndeterminate = false; - } - InsertUniqueTypeItem(typesUsedAs, elem); - } - if (isIndeterminate) { - defedReg.regType->UpdateUsedSet(regTypeItem); + if (isIndeterminateIn) { + fuzzyTypesUsedAs.emplace_back(regTypeItem); } } -void BCRegType::PrecisifyTypes() { +void BCRegType::PrecisifyTypes(bool isTry) { if (precisified) { return; } - precisified = true; - if (regTypeItem->isIndeterminate) { - BCRegTypeItem *realType = GetMostPreciseType(typesUsedAs); - if (realType != nullptr) { - regTypeItem->Copy(*realType); + if (!isTry) { + precisified = true; + } + if (typesUsedAs == nullptr || typesUsedAs->empty()) { + return; + } + // insert defed type into `used` + typesUsedAs->emplace_back(regTypeItem); + BCRegTypeItem *realType = nullptr; + PrecisifyRelatedTypes(realType); + if (fuzzyTypesUsedAs.size() != 0 || realType == nullptr) { + if (realType == nullptr || realType->isIndeterminate) { + realType = GetMostPreciseType(*typesUsedAs); + if (realType != nullptr) { + for (auto &elem : fuzzyTypesUsedAs) { + elem->Copy(*realType); + } + } } - if (regTypeItem->isIndeterminate) { - // Get type from array elem - for (auto elem : elemTypes) { - elem->PrecisifyTypes(); - std::string arrTypeName = "A" + GlobalTables::GetStrTable().GetStringFromStrIdx(elem->regTypeItem->typeNameIdx); - GStrIdx arrayTypeIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(arrTypeName); - regTypeItem->typeNameIdx = arrayTypeIdx; - regTypeItem->isIndeterminate = false; + } + PrecisifyElemTypes(realType); +} + +void BCRegType::PrecisifyRelatedTypes(BCRegTypeItem *realType) { + for (auto rType : relatedBCRegTypes) { + // try to get type from use first. + // if failed, get type from def. + rType->PrecisifyTypes(true); + if (rType->IsIndeterminate()) { + if (realType == nullptr) { + realType = GetMostPreciseType(*typesUsedAs); + if (realType != nullptr) { + for (auto &fuzzyTy : fuzzyTypesUsedAs) { + if (fuzzyTy->isIndeterminate) { + fuzzyTy->Copy(*realType); + } + } + } + } + if (!realType->isIndeterminate) { + rType->PrecisifyTypes(true); } } else { - const std::string &arrTypeName = GlobalTables::GetStrTable().GetStringFromStrIdx(regTypeItem->typeNameIdx); - for (auto elem : elemTypes) { - if (arrTypeName.size() > 1 && arrTypeName.at(0) == 'A') { - elem->regTypeItem->typeNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(arrTypeName.substr(1)); - elem->regTypeItem->isIndeterminate = false; + rType->precisified = true; + } + } +} + +void BCRegType::PrecisifyElemTypes(BCRegTypeItem *arrayType) { + for (auto elem : elemTypes) { + if (elem->IsIndeterminate()) { + const std::string &arrTypeName = GlobalTables::GetStrTable().GetStringFromStrIdx(arrayType->typeNameIdx); + if (arrTypeName.size() > 1 && arrTypeName.at(0) == 'A') { + GStrIdx elemTypeIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(arrTypeName.substr(1)); + if (elem->IsPrecisified()) { + for (auto &e : elem->fuzzyTypesUsedAs) { + if (e->isIndeterminate) { + e->typeNameIdx = elemTypeIdx; + e->isIndeterminate = false; + } + } } else { - INFO(kLncInfo, "Could not determine the array type thouth its USE, set by its element."); + elem->regTypeItem->typeNameIdx = elemTypeIdx; } + } else { + CHECK_FATAL(curReg.regValue != nullptr, "Not an array type or const 0"); } } } - for (auto elem : arrayTypes) { - elem->PrecisifyTypes(); - // Generally, array type could be determined by it USE. - // Otherwise, set it though its element type. - if (elem->IsIndeterminate() || !BCUtil::IsArrayType(elem->regTypeItem->typeNameIdx)) { - std::string arrayTypeName = "A" + GlobalTables::GetStrTable().GetStringFromStrIdx(regTypeItem->typeNameIdx); - GStrIdx arrayTypeIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(arrayTypeName); - elem->regTypeItem->typeNameIdx = arrayTypeIdx; - elem->regTypeItem->isIndeterminate = false; - } - } } -BCRegTypeItem *BCRegType::GetMostPreciseType(const MapleVector &types) { +BCRegTypeItem *BCRegType::GetMostPreciseType(const MapleList &types) { BCRegTypeItem *retType = nullptr; if (types.empty()) { return retType; @@ -450,11 +476,7 @@ UniqueFEIRVar BCReg::GenFEIRVarRegImpl() const { UniqueFEIRType BCReg::GenFEIRTypeImpl() const { PrimType pty = GetBasePrimType(); - if (regTypeItem->isPrimPtr && pty != PTY_ref) { - return std::make_unique(std::make_unique(pty, regTypeItem->typeNameIdx)); - } else { - return std::make_unique(pty, regTypeItem->typeNameIdx); - } + return std::make_unique(pty, regTypeItem->typeNameIdx); } std::list BCReg::GenRetypeStmtsAfterDef() const { @@ -469,16 +491,18 @@ std::list BCReg::GenRetypeStmtsAfterDef() const { PrimType ptyDef = regTypeItem->GetPrimType(); std::list unqTypeItems; - for (const auto &usedType : *(regType->GetUsedTypes())) { - bool exist = false; - for (const auto &elem : unqTypeItems) { - if ((*usedType) == (*elem)) { - exist = true; - break; + if (regType->GetUsedTypes() != nullptr) { + for (const auto &usedType : *(regType->GetUsedTypes())) { + bool exist = false; + for (const auto &elem : unqTypeItems) { + if ((*usedType) == (*elem)) { + exist = true; + break; + } + } + if (exist == false) { + unqTypeItems.emplace_back(usedType); } - } - if (exist == false) { - unqTypeItems.emplace_back(usedType); } } diff --git a/src/mplfe/bc_input/src/bc_io.cpp b/src/mplfe/bc_input/src/bc_io.cpp index 9f7fff6f320f4b6f1945a106cb52afd5a19d7ef6..bda1cec582d0182d181e4b50119ba9ff5807798f 100644 --- a/src/mplfe/bc_input/src/bc_io.cpp +++ b/src/mplfe/bc_input/src/bc_io.cpp @@ -58,5 +58,9 @@ std::string BCReader::GetSignature(uint32 idx) const { uint32 BCReader::GetFileIndex() const { return GetFileIndexImpl(); } + +std::string BCReader::GetIRSrcFileSignature() const { + return irSrcFileSignature; +} } // namespace bc } // namespace maple \ No newline at end of file diff --git a/src/mplfe/bc_input/src/bc_pragma.cpp b/src/mplfe/bc_input/src/bc_pragma.cpp index 8d432ec58cae12dba602a297b3afa69bd96c5cbd..d4f2bfb9ba77edbd3e46254ab98599db9f2ef053 100644 --- a/src/mplfe/bc_input/src/bc_pragma.cpp +++ b/src/mplfe/bc_input/src/bc_pragma.cpp @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. @@ -12,12 +12,12 @@ * FIT FOR A PARTICULAR PURPOSE. * See the Mulan PSL v2 for more details. */ -#include "bc_pragma.h" -namespace maple { -namespace bc { -std::vector &BCAnnotationsDirectory::EmitPragmasImpl() { - CHECK_FATAL(false, "this method must be overrided!!!"); - return pragmas; -} -} // namespace bc +#include "bc_pragma.h" +namespace maple { +namespace bc { +std::vector &BCAnnotationsDirectory::EmitPragmasImpl() { + CHECK_FATAL(false, "this method must be overrided!!!"); + return pragmas; +} +} // namespace bc } // namespace maple \ No newline at end of file diff --git a/src/mplfe/bc_input/src/bc_util.cpp b/src/mplfe/bc_input/src/bc_util.cpp index e948aa948ec8496565a692385b16199845f0d014..05d308f1645f5336fe959d87947b70baae960b93 100644 --- a/src/mplfe/bc_input/src/bc_util.cpp +++ b/src/mplfe/bc_input/src/bc_util.cpp @@ -70,10 +70,10 @@ bool BCUtil::IsMorePrecisePrimitiveType(const GStrIdx &name0, const GStrIdx &nam BCUtil::GetByteIdx(), BCUtil::GetCharIdx(), BCUtil::GetShortIdx(), - BCUtil::GetFloatIdx(), BCUtil::GetIntIdx(), - BCUtil::GetDoubleIdx(), - BCUtil::GetLongIdx() + BCUtil::GetFloatIdx(), + BCUtil::GetLongIdx(), + BCUtil::GetDoubleIdx() }; if (name0 == name1) { return false; @@ -135,6 +135,12 @@ bool BCUtil::IsJavaPrimitveType(const GStrIdx &typeNameIdx) { return !IsJavaReferenceType(typeNameIdx); } +bool BCUtil::IsJavaPrimitiveTypeName(const std::string typeName) { + return ((typeName == kBoolean) || (typeName == kByte) || (typeName == kBoolean) || (typeName == kShort) || + (typeName == kChar) || (typeName == kInt) || (typeName == kLong) || (typeName == kFloat) || + (typeName == kDouble)); +} + bool BCUtil::IsArrayType(const GStrIdx &typeNameIdx) { std::string typeName = GlobalTables::GetStrTable().GetStringFromStrIdx(typeNameIdx); uint8 dim = FEUtils::GetDim(typeName); @@ -176,5 +182,36 @@ void BCUtil::AddDefaultDepSet(std::unordered_set &typeTable) { typeTable.insert("Ljava/util/concurrent/atomic/AtomicInteger;"); typeTable.insert("Ljava/lang/reflect/Method;"); } + +// get the serial number in register name, for example 2 in Reg2_I +uint32 BCUtil::Name2RegNum(const std::string &name) { + const uint16 regPrefixLen = strlen("Reg"); + int numLen = name.length() - regPrefixLen; + // Nonreg names also reach here, e.g. "_this". Make sure they are not handle. + const uint16 regVarMinLen = 6; + if (numLen < regVarMinLen - regPrefixLen || name.compare(0, regPrefixLen, "Reg") != 0) { + return UINT32_MAX; + } + std::string regName = name.substr(regPrefixLen); + int i = 0; + for (; i < numLen; i++) { + if (regName[i] < '0' || regName[i] > '9') { + break; + } + } + + if (i == 0) { + return UINT32_MAX; + } + int regNum = std::stoi(regName.substr(0, i)); + return regNum; +} + +bool BCUtil::HasContainSuffix(const std::string &value, const std::string &suffix) { + if (suffix.size() > value.size()) { + return false; + } + return std::equal(suffix.rbegin(), suffix.rend(), value.rbegin()); +} } // namespace bc } // namespace maple diff --git a/src/mplfe/bc_input/src/rc_setter.cpp b/src/mplfe/bc_input/src/rc_setter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..06c59d1e983d5a834a2795b82fa482230c20276d --- /dev/null +++ b/src/mplfe/bc_input/src/rc_setter.cpp @@ -0,0 +1,454 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include "rc_setter.h" +#include +#include "ark_annotation_map.h" +#include "ark_annotation_processor.h" +#include "fe_manager.h" +#include "bc_util.h" + +namespace maple { +namespace bc { +RCSetter *RCSetter::rcSetter = nullptr; + +void RCSetter::ProcessClassRCAnnotation(const GStrIdx &classIdx, const std::vector &pragmas) { + if (pragmas.empty()) { + return; + } + MIRStructType *type = FEManager::GetTypeManager().GetStructTypeFromName(classIdx); + for (auto pragma : pragmas) { + if (pragma->GetKind() != kPragmaClass || pragma->GetStrIdx() != type->GetNameStrIdx()) { + continue; + } + if (!ArkAnnotation::GetInstance().IsRCUnownedOuter(pragma->GetTyIdx()) && + !ArkAnnotation::GetInstance().IsRCUnownedThis(pragma->GetTyIdx())) { + continue; + } + const std::string &className = type->GetName(); + MIRSymbol *jcSymbol = FEManager::GetMIRBuilder().GetOrCreateGlobalDecl(className, *type); + if (jcSymbol != nullptr) { + jcSymbol->SetAttr(ATTR_rcunownedthis); + } + for (auto &field : type->GetFields()) { + std::string fieldName = GlobalTables::GetStrTable().GetStringFromStrIdx(field.first); + const std::string prefix = "this_24"; + if (fieldName.compare(0, prefix.size(), prefix) == 0) { + field.second.second.SetAttr(FLDATTR_rcunowned); + } + } + } +} + +void RCSetter::ProcessMethodRCAnnotation(MIRFunction &mirFunc, const std::string &className, + MIRStructType &structType, const MIRPragma &pragma) { + if (ArkAnnotation::GetInstance().IsRCUnownedOuter(pragma.GetTyIdx()) || + ArkAnnotation::GetInstance().IsRCUnownedThis(pragma.GetTyIdx())) { + // set ATTR_rcunowned to the field this$n of local class + // the current function belongs to + MIRSymbol *jcSymbol = FEManager::GetMIRBuilder().GetOrCreateGlobalDecl(className, structType); + if (jcSymbol != nullptr) { + jcSymbol->SetAttr(ATTR_rcunownedthis); + } + for (auto &field : structType.GetFields()) { + const std::string &fieldName = GlobalTables::GetStrTable().GetStringFromStrIdx(field.first); + const std::string prefix = "this_24"; + if (fieldName.compare(0, prefix.size(), prefix) == 0) { + field.second.second.SetAttr(FLDATTR_rcunowned); + } + } + } else if (ArkAnnotation::GetInstance().IsRCUnownedCap(pragma.GetTyIdx()) || + ArkAnnotation::GetInstance().IsRCUnownedCapList(pragma.GetTyIdx())) { + // handle old RCUnownedCapRef annotation. + MIRPragmaElement *elem = pragma.GetElementVector()[0]; + if (ArkAnnotation::GetInstance().IsRCUnownedCap(pragma.GetTyIdx())) { + GStrIdx strIdx(elem->GetI32Val()); + CollectUnownedLocalVars(&mirFunc, strIdx); + } else if (ArkAnnotation::GetInstance().IsRCUnownedCapList(pragma.GetTyIdx())) { + for (auto eit : elem->GetSubElemVec()) { + if (eit->GetSubElemVec().empty()) { + continue; + } + MIRPragmaElement *e = eit->GetSubElemVec()[0]; + GStrIdx strIdx(e->GetI32Val()); + CollectUnownedLocalVars(&mirFunc, strIdx); + } + } + } +} + +void RCSetter::ProcessFieldRCAnnotation(const StructElemNameIdx &fieldElemNameIdx, + const MIRType &fieldType, const std::vector &pragmas) { + if (pragmas.empty()) { + return; + } + for (auto pragma : pragmas) { + if (pragma->GetKind() != kPragmaVar || + pragma->GetStrIdx() != fieldElemNameIdx.elem || + pragma->GetTyIdxEx() != fieldType.GetTypeIndex()) { + continue; + } + if (!ArkAnnotation::GetInstance().IsRCWeak(pragma->GetTyIdx()) && + !ArkAnnotation::GetInstance().IsRCUnowned(pragma->GetTyIdx())) { + continue; + } + FieldAttrKind attr; + if (ArkAnnotation::GetInstance().IsRCWeak(pragma->GetTyIdx())) { + attr = FLDATTR_rcweak; + } else if (ArkAnnotation::GetInstance().IsRCUnowned(pragma->GetTyIdx())) { + attr = FLDATTR_rcunowned; + } + MIRStructType *structType = FEManager::GetTypeManager().GetStructTypeFromName(fieldElemNameIdx.klass); + for (auto &field : structType->GetFields()) { + if (field.first == fieldElemNameIdx.elem) { + field.second.second.SetAttr(attr); + break; + } + } + } +} + +void RCSetter::GetUnownedVarInLocalVars(const BCClassMethod &method, MIRFunction &mirFunction) { + if (method.GetSrcLocalInfoPtr() == nullptr) { + return; + } + std::set unownedRegNums; + // map>> + for (auto &local : *method.GetSrcLocalInfoPtr()) { + for (auto &item : local.second) { + bool isUnowned = BCUtil::HasContainSuffix(std::get<0>(item), "$unowned"); + if (isUnowned) { + GStrIdx strIdx = FEManager::GetMIRBuilder().GetOrCreateStringIndex(namemangler::EncodeName(std::get<0>(item))); + CollectUnownedLocalVars(&mirFunction, strIdx); + (void)unownedRegNums.insert(local.first); + } + } + } + // set ATTR_rcunowned for symbols according their reg num. + SetAttrRCunowned(mirFunction, unownedRegNums); +} + +void RCSetter::SetAttrRCunowned(MIRFunction &mirFunction, const std::set &unownedRegNums) const { + if (unownedRegNums.empty()) { + return; + } + MIRSymbolTable *symTab = mirFunction.GetSymTab(); + if (symTab == nullptr) { + return; + } +#ifndef USE_OPS + for (uint32 i = 0; i < SymbolBuilder::Instance().GetSymbolTableSize(&mirFunction); ++i) { + MIRSymbol *symbol = SymbolBuilder::Instance().GetSymbolFromStIdx(i, &mirFunction); +#else + for (uint32 i = 0; i < mirFunction.GetSymTab()->GetSymbolTableSize(); ++i) { + MIRSymbol *symbol = mirFunction.GetSymTab()->GetSymbolFromStIdx(i); +#endif + if (symbol == nullptr) { + continue; + } + MIRType *ty = symbol->GetType(); + if (ty->GetPrimType() == PTY_ref || ty->GetPrimType() == PTY_ptr) { + uint32 regNum = BCUtil::Name2RegNum(symbol->GetName()); + if (unownedRegNums.find(regNum) != unownedRegNums.end()) { + symbol->SetAttr(ATTR_rcunowned); + } + } + } +} + +void RCSetter::MarkRCUnownedForUnownedLocalFunctions() const { + // mark all local variables unowned for @UnownedLocal functions. + for (auto func : unownedLocalFuncs) { +#ifndef USE_OPS + for (uint32 idx = 0; idx < SymbolBuilder::Instance().GetSymbolTableSize(func); idx++) { + MIRSymbol *sym = SymbolBuilder::Instance().GetSymbolFromStIdx(idx, func); +#else + for (uint32 idx = 0; idx < func->GetSymTab()->GetSymbolTableSize(); idx++) { + MIRSymbol *sym = func->GetSymTab()->GetSymbolFromStIdx(idx); +#endif + if (sym == nullptr) { + continue; + } + MIRType *ty = sym->GetType(); + if (ty->GetPrimType() == PTY_ref || ty->GetPrimType() == PTY_ptr) { + sym->SetAttr(ATTR_rcunowned); + } + } + } +} + +bool RCSetter::IsAnonymousInner(const MIRStructType &structType) const { + if (!(structType.GetKind() == kTypeClass || structType.GetKind() == kTypeInterface)) { + return false; + } + // inner class has annotation Ldalvik/annotation/InnerClass; + bool isCreat = false; + const std::string &className = + ArkAnnotationMap::GetArkAnnotationMap().GetAnnotationTypeName("Ldalvik_2Fannotation_2FInnerClass_3B"); + MIRStructType *inner = FEManager::GetTypeManager().GetOrCreateClassOrInterfaceType( + className, true, FETypeFlag::kSrcExtern, isCreat); + GStrIdx strIdx = FEManager::GetMIRBuilder().GetOrCreateStringIndex("name"); + unsigned tyIdx = inner->GetTypeIndex(); + if (structType.GetKind() == kTypeClass) { + const MIRClassType &classType = static_cast(structType); + for (auto it : classType.GetPragmaVec()) { + if (it->GetTyIdx() == tyIdx) { + for (auto eit : it->GetElementVector()) { + // inner class and has no name + if (eit->GetNameStrIdx() == strIdx && eit->GetI32Val() == 0) { + return true; + } + } + } + } + } else if (structType.GetKind() == kTypeInterface) { + const MIRInterfaceType &interfaceType = static_cast(structType); + for (auto it : interfaceType.GetPragmaVec()) { + if (it->GetTyIdx() == tyIdx) { + for (auto eit : it->GetElementVector()) { + // inner class and has no name + if (eit->GetNameStrIdx() == strIdx && eit->GetI32Val() == 0) { + return true; + } + } + } + } + } + return false; +} + +bool RCSetter::IsMethodEnclosing(const MIRFunction &func, const MIRStructType &structType) const { + if (!(structType.GetKind() == kTypeClass || structType.GetKind() == kTypeInterface)) { + return false; + } + bool isCreat = false; + const std::string &className = namemangler::GetInternalNameLiteral( + ArkAnnotationMap::GetArkAnnotationMap().GetAnnotationTypeName("Ldalvik_2Fannotation_2FEnclosingMethod_3B")); + MIRStructType *inner = FEManager::GetTypeManager().GetOrCreateClassOrInterfaceType( + className, true, FETypeFlag::kSrcExtern, isCreat); + unsigned tyIdx = inner->GetTypeIndex(); + if (structType.GetKind() == kTypeClass) { + const MIRClassType &classType = static_cast(structType); + for (auto it : classType.GetPragmaVec()) { + if (it->GetTyIdx() == tyIdx && !(it->GetElementVector().empty()) && + func.GetNameStrIdx() == it->GetElementVector()[0]->GetI32Val()) { + return true; + } + } + } else if (structType.GetKind() == kTypeInterface) { + const MIRInterfaceType &interfaceType = static_cast(structType); + for (auto it : interfaceType.GetPragmaVec()) { + if (it->GetTyIdx() == tyIdx && (!it->GetElementVector().empty()) && + func.GetNameStrIdx() == it->GetElementVector()[0]->GetI32Val()) { + return true; + } + } + } + return false; +} + +void RCSetter::MarkRCUnownedForAnonymousClasses() const { + // mark captured unowned fields for anonymous class. + for (auto mit : unownedLocalVars) { + MIRFunction *func = mit.first; + // check for anonymous class + // mark captured var name aaa -> val$aaa (or val_24aaa) field in anonymous class + for (auto sit : FEManager::GetTypeManager().GetStructNameTypeMap()) { + ASSERT_NOT_NULL(sit.second.first); + if (IsAnonymousInner(*(sit.second.first)) && IsMethodEnclosing(*func, *(sit.second.first))) { + for (auto &fit : sit.second.first->GetFields()) { + const std::string &fieldName = GlobalTables::GetStrTable().GetStringFromStrIdx(fit.first); + constexpr size_t prefixLength = sizeof("val_24") - 1; + if (fieldName.compare(0, prefixLength, "val_24") == 0) { + std::string nameWithSuffix = fieldName + "_24unowned"; + for (auto nit : mit.second) { + GStrIdx strIdx(nit); + const std::string &varName = GlobalTables::GetStrTable().GetStringFromStrIdx(strIdx); + if (nameWithSuffix.compare(prefixLength, varName.length(), varName) == 0 || + fieldName.compare(prefixLength, varName.length(), varName) == 0) { + fit.second.second.SetAttr(FLDATTR_rcunowned); + } + } + } + } + } + } + } +} + +void RCSetter::SetRCUnownedAttributeInternalSetFieldAttrRCUnowned(size_t opnd, const MIRFunction &calledFunc) const { + const MIRSymbol *arg = calledFunc.GetFormal(opnd); + for (const StmtNode *s = calledFunc.GetBody()->GetFirst(); s != nullptr; s = s->GetNext()) { + // 1. checking iassign statements that assign parameter arg + if (s->GetOpCode() != OP_iassign) { + continue; + } + const IassignNode *ian = static_cast(s); + const BaseNode *val = ian->GetRHS(); + if (val->GetOpCode() != OP_dread) { + continue; + } + const DreadNode *valDrn = static_cast(val); + const MIRSymbol *valSymbol = calledFunc.GetLocalOrGlobalSymbol(valDrn->GetStIdx()); + const GStrIdx &valStrIdx = valSymbol->GetNameStrIdx(); + if (valStrIdx != arg->GetNameStrIdx()) { + continue; + } + // 2. get the class fields of the iassign statement + auto it = iputStmtFieldMap.find(s); + if (it != iputStmtFieldMap.end()) { + const GStrIdx &fieldStrIdx = it->second; + // 3. set rcunwoned attribute for that field + const MIRType *type = calledFunc.GetClassType(); + CHECK_NULL_FATAL(type); + MIRType *typePtr = GlobalTables::GetTypeTable().GetTypeFromTyIdx(type->GetTypeIndex()); + MIRStructType *structType = static_cast(typePtr); + for (auto &fit : structType->GetFields()) { + if (fit.first == fieldStrIdx) { + fit.second.second.SetAttr(FLDATTR_rcunowned); + break; + } + } + } + } +} + +void RCSetter::SetRCUnownedAttribute(const CallNode &callNode, MIRFunction &func, + const MIRFunction &calledFunc, const std::set &gStrIdx) const { + for (size_t i = 0; i < callNode.NumOpnds(); ++i) { + BaseNode *bn = callNode.GetNopndAt(i); + if (bn->GetOpCode() != OP_dread) { + continue; + } + DreadNode *drn = static_cast(bn); + const MIRSymbol *symbol = func.GetLocalOrGlobalSymbol(drn->GetStIdx()); + const GStrIdx &strIdx = symbol->GetNameStrIdx(); + // checking maple name in ALIAS + for (auto als : func.GetAliasVarMap()) { + if (als.second.memPoolStrIdx != strIdx) { + continue; + } + for (auto sit : gStrIdx) { + if (sit != als.first) { + continue; + } + // now we have a link and a field need to be set rcunowned + // + // the focus is the i_th parameter arg. + // we will go through body of of the lambda class + // 1. checking iassign statements that assign parameter arg + // 2. get the class fields of the iassign statement + // 3. set rcunwoned attribute for that field + SetRCUnownedAttributeInternalSetFieldAttrRCUnowned(i, calledFunc); + } + } + } +} + +void RCSetter::MarkRCUnownedForLambdaClasses() const { + // mark captured unowned fields for lambda classes. + for (auto mit : unownedLocalVars) { + MIRFunction *func = mit.first; + // scan function body to find lambda functions used + // and set rcunowned attribute on corresponding captured fields + // of local classes for lambda functions + for (const StmtNode *stmt = func->GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { + if (stmt->GetOpCode() != OP_callassigned) { + continue; + } + const CallNode *call = static_cast(stmt); + MIRFunction *calledFunc = GlobalTables::GetFunctionTable().GetFuncTable().at(call->GetPUIdx()); + // only care calling of local classes for lambda functions + if (!(calledFunc->GetAttr(FUNCATTR_constructor) && calledFunc->GetAttr(FUNCATTR_public) && + calledFunc->GetAttr(FUNCATTR_synthetic))) { + continue; + } + // go through call arguments to find maple names with ALIAS info + // and their src names matching captured var names + SetRCUnownedAttribute(*call, *func, *calledFunc, mit.second); + } + } +} + +void RCSetter::MarkRCAttributes() const { + MarkRCUnownedForUnownedLocalFunctions(); + MarkRCUnownedForAnonymousClasses(); + MarkRCUnownedForLambdaClasses(); +} + +void RCSetter::CollectUnownedLocalFuncs(MIRFunction *func) { + (void)unownedLocalFuncs.insert(func); +} + +void RCSetter::CollectUnownedLocalVars(MIRFunction *func, const GStrIdx &strIdx) { + (void)unownedLocalVars[func].insert(strIdx); +} + +void RCSetter::CollectInputStmtField(StmtNode *stmt, const GStrIdx &fieldName) { + (void)iputStmtFieldMap.emplace(stmt, fieldName); +} + +void RCSetter::LoadRCFieldAttrWhiteList(const std::string &file) { + std::string line; + std::ifstream infile(file); + uint32 lineNum = 0; + std::vector vecItem; + std::vector vecAttr; + std::string item; + std::string className; + std::string fieldName; + CHECK_FATAL(infile.is_open(), "(ToIDEUser)RCFieldAttrWhiteList file %s open failed", file.c_str()); + while (std::getline(infile, line)) { + lineNum++; + if (line.at(0) == '#') { + continue; + } + std::stringstream ss; + ss.str(line); + vecItem.clear(); + while (std::getline(ss, item, ':')) { + vecItem.push_back(item); + } + CHECK_FATAL(vecItem.size() > 2, "(ToIDEUser)invalid line %d in RCFieldAttrWhiteList file %s", lineNum, + file.c_str()); + className = vecItem[0]; + fieldName = vecItem[1]; + vecAttr.clear(); + for (size_t i = 2; i < vecItem.size(); i++) { + std::string &strAttr = vecItem[i]; + if (strAttr.compare("RCWeak") == 0) { + vecAttr.push_back(FLDATTR_rcweak); + } else if (strAttr.compare("RCUnowned") == 0) { + vecAttr.push_back(FLDATTR_rcunowned); + } + } + rcFieldAttrWhiteListMap[className][fieldName] = vecAttr; + } + infile.close(); +} + +void RCSetter::SetRCFieldAttrByWhiteList(FieldAttrs &attr, const std::string &className, + const std::string &fieldName) { + auto itClass = rcFieldAttrWhiteListMap.find(className); + if (itClass != rcFieldAttrWhiteListMap.end()) { + auto itField = itClass->second.find(fieldName); + if (itField != itClass->second.end()) { + for (auto &attrIt : itField->second) { + attr.SetAttr(attrIt); + } + } + } +} +} // namespace bc +} // namespace maple \ No newline at end of file diff --git a/src/mplfe/common/include/base64.h b/src/mplfe/common/include/base64.h index 4f4da8073104bc82cb74689ec9eb274bde125b98..2df43f513b870b0d1fbf0229fe984f154bb7654e 100644 --- a/src/mplfe/common/include/base64.h +++ b/src/mplfe/common/include/base64.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/basic_io.h b/src/mplfe/common/include/basic_io.h index c1f8977fa4fd2870c0231c627e9b1c2c8b095dd2..c29b21b25471e36e864e48cce6394dbde95380e7 100644 --- a/src/mplfe/common/include/basic_io.h +++ b/src/mplfe/common/include/basic_io.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/fe_algorithm.h b/src/mplfe/common/include/fe_algorithm.h index 5ff6d7ff2e86168cd825df10aed74e534822e215..5a0fecd5176e7adab9a92cc4fccdd6116de442ff 100644 --- a/src/mplfe/common/include/fe_algorithm.h +++ b/src/mplfe/common/include/fe_algorithm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/fe_config_parallel.h b/src/mplfe/common/include/fe_config_parallel.h index 2e2b0ccf8111bd9c94914ea4e35d4fac3f6d4500..8c377f25d2524609edb4db35b74ceecb47755605 100644 --- a/src/mplfe/common/include/fe_config_parallel.h +++ b/src/mplfe/common/include/fe_config_parallel.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/fe_configs.h b/src/mplfe/common/include/fe_configs.h index 3318d8ea16ee9d14be760e3cf6ae07652da6fdb5..0f7a5be38e72ca92058b7c1d3970392c0b4dd6d4 100644 --- a/src/mplfe/common/include/fe_configs.h +++ b/src/mplfe/common/include/fe_configs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/fe_errno.h b/src/mplfe/common/include/fe_errno.h index 323693a61ad69dd41fc2116bcefc78aced24adab..fbe5b2c7d9f54d70c62e0567e2a96ab7bf413333 100644 --- a/src/mplfe/common/include/fe_errno.h +++ b/src/mplfe/common/include/fe_errno.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/fe_file_ops.h b/src/mplfe/common/include/fe_file_ops.h index 513e1873709f9cad92f196d8137f839f729c22ba..dc0ae6c8df5a0fbd5205e310648cb03f15b62883 100644 --- a/src/mplfe/common/include/fe_file_ops.h +++ b/src/mplfe/common/include/fe_file_ops.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/fe_file_type.h b/src/mplfe/common/include/fe_file_type.h index e615da83e2c7ff496187b499b4789d41802fd59d..89377d4cca342a57438611a1b52a174c9049b850 100644 --- a/src/mplfe/common/include/fe_file_type.h +++ b/src/mplfe/common/include/fe_file_type.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -27,6 +27,9 @@ class FEFileType { kClass, kJar, kDex, +#ifdef ENABLE_MPLFE_AST + kAST +#endif // ~/ENABLE_MPLFE_AST }; inline static FEFileType &GetInstance() { @@ -51,6 +54,9 @@ class FEFileType { static const uint32 kMagicClass = 0xBEBAFECA; static const uint32 kMagicZip = 0x04034B50; static const uint32 kMagicDex = 0x0A786564; +#ifdef ENABLE_MPLFE_AST + static const uint32 kMagicAST = 0x48435043; +#endif // ~/ENABLE_MPLFE_AST std::map mapExtNameType; std::map mapTypeMagic; std::map mapMagicType; diff --git a/src/mplfe/common/include/fe_function.h b/src/mplfe/common/include/fe_function.h index 12aa93427f47d9c398ab092137c420c0ebd718ac..1ec9461ea6def7199d1a8753e7fc227e2c175c4f 100644 --- a/src/mplfe/common/include/fe_function.h +++ b/src/mplfe/common/include/fe_function.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -84,6 +84,7 @@ class FEFunction { virtual bool LabelGeneralBBs(const std::string &phaseName); virtual bool ProcessFEIRFunction(); virtual bool GenerateArgVarList(const std::string &phaseName) = 0; + virtual bool GenerateAliasVars(const std::string &phaseName) = 0; virtual bool EmitToFEIRStmt(const std::string &phaseName) = 0; virtual bool BuildMapLabelStmt(const std::string &phaseName); virtual bool SetupFEIRStmtJavaTry(const std::string &phaseName); @@ -193,6 +194,9 @@ class FEFunction { void InsertCvtStmt(const FEIRVarTypeScatter &fromVar, const FEIRType &toType); void InsertJavaMergeStmt(const FEIRVarTypeScatter &fromVar, const FEIRType &toType); void InsertDAssignStmt4TypeCvt(const FEIRVarTypeScatter &fromVar, const FEIRType &toType, UniqueFEIRExpr expr); + bool WithFinalFieldsNeedBarrier(MIRClassType *classType, bool isStatic) const; + bool IsNeedInsertBarrier(); + std::list> genStmtList; std::list> genBBList; std::list feirStmtList; diff --git a/src/mplfe/common/include/fe_function_phase_result.h b/src/mplfe/common/include/fe_function_phase_result.h index 463f211e2e96ea22c14138af8312a0ccfe5ca537..06a2b7a3665603bb29c99404d50f8b46e02cc13f 100644 --- a/src/mplfe/common/include/fe_function_phase_result.h +++ b/src/mplfe/common/include/fe_function_phase_result.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/fe_input.h b/src/mplfe/common/include/fe_input.h index 56c04f52f8488f1ff84131284c130f88deeac900..ce03f6239a3d4e611dc0d2f42bb1a11495ec2702 100644 --- a/src/mplfe/common/include/fe_input.h +++ b/src/mplfe/common/include/fe_input.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/fe_input_helper.h b/src/mplfe/common/include/fe_input_helper.h index f22fee67fa8460173a1816853cc44123365f0715..663159fa713b4a98348bbde9ec8b7745c8f0e4a1 100644 --- a/src/mplfe/common/include/fe_input_helper.h +++ b/src/mplfe/common/include/fe_input_helper.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -22,6 +22,13 @@ #include "fe_function.h" namespace maple { +typedef struct { + std::string klass; + std::string field; + std::string type; + std::string attr; +} ExtraField; + class FEInputContainer { public: FEInputContainer() = default; @@ -47,6 +54,25 @@ class FEInputPragmaHelper { }; class FEInputStructHelper; + +class FEInputGlobalVarHelper { + public: + FEInputGlobalVarHelper(MapleAllocator &allocatorIn) : allocator(allocatorIn) {} + virtual ~FEInputGlobalVarHelper() = default; + + bool ProcessDecl() { + return ProcessDecl(allocator); + } + + bool ProcessDecl(MapleAllocator &allocator) { + return ProcessDeclImpl(allocator); + } + + protected: + MapleAllocator &allocator; + virtual bool ProcessDeclImpl(MapleAllocator &allocator) = 0; +}; + class FEInputFieldHelper { public: FEInputFieldHelper(MapleAllocator &allocator) {} @@ -67,6 +93,18 @@ class FEInputFieldHelper { return ProcessDeclWithContainerImpl(allocator); } + static void SetFieldAttribute(const std::string &name, FieldAttrs &attr) { +#define FIELD_ATTR +#define ATTR(A) \ + if (!strcmp(name.c_str(), #A)) { \ + attr.SetAttr(FLDATTR_##A); \ + return; \ + } +#include "all_attributes.def" +#undef ATTR +#undef FIELD_ATTR + } + protected: virtual bool ProcessDeclImpl(MapleAllocator &allocator) = 0; virtual bool ProcessDeclWithContainerImpl(MapleAllocator &allocator) = 0; @@ -75,18 +113,22 @@ class FEInputFieldHelper { class FEInputMethodHelper { public: - FEInputMethodHelper(MapleAllocator &allocator) - : srcLang(kSrcLangUnknown), + FEInputMethodHelper(MapleAllocator &allocatorIn) + : allocator(allocatorIn), + srcLang(kSrcLangUnknown), feFunc(nullptr), mirFunc(nullptr), retType(nullptr), argTypes(allocator.Adapter()), + retMIRType(nullptr), + argMIRTypes(allocator.Adapter()), methodNameIdx(GStrIdx(0)) {} virtual ~FEInputMethodHelper() { feFunc = nullptr; mirFunc = nullptr; retType = nullptr; + retMIRType = nullptr; } const MethodPair &GetMIRMethodPair() const { @@ -101,6 +143,10 @@ class FEInputMethodHelper { return argTypes; } + bool ProcessDecl() { + return ProcessDecl(allocator); + } + bool ProcessDecl(MapleAllocator &allocator) { return ProcessDeclImpl(allocator); } @@ -167,12 +213,16 @@ class FEInputMethodHelper { virtual MIRType *GetTypeForThisImpl() const = 0; virtual bool HasCodeImpl() const = 0; + MapleAllocator &allocator; MIRSrcLang srcLang; FEFunction *feFunc; MIRFunction *mirFunc; MethodPair mirMethodPair; FEIRType *retType; MapleVector argTypes; + // Added MIRType to support C and extended to Java later. + MIRType *retMIRType; + MapleVector argMIRTypes; GStrIdx methodNameIdx; }; @@ -185,8 +235,9 @@ class FEInputStructHelper : public FEInputContainer { fieldHelpers(allocator.Adapter()), methodHelpers(allocator.Adapter()), pragmaHelper(nullptr), + staticFieldsConstVal(allocator.Adapter()), isSkipped(false), - srcLang(kSrcLangUnknown) {} + srcLang(kSrcLangJava) {} virtual ~FEInputStructHelper() { mirStructType = nullptr; @@ -257,6 +308,14 @@ class FEInputStructHelper : public FEInputContainer { return GetRawAccessFlagsImpl(); } + GStrIdx GetIRSrcFileSigIdx() const { + return GetIRSrcFileSigIdxImpl(); + } + + bool IsMultiDef() const { + return IsMultiDefImpl(); + } + void InitFieldHelpers() { InitFieldHelpersImpl(); } @@ -270,7 +329,10 @@ class FEInputStructHelper : public FEInputContainer { } void SetStaticFieldsConstVal(const std::vector &val) { - staticFieldsConstVal = val; + staticFieldsConstVal.resize(val.size()); + for (uint32 i = 0; i < val.size(); ++i) { + staticFieldsConstVal[i] = val[i]; + } } void SetFinalStaticStringIDVec(const std::vector &stringIDVec) { @@ -296,6 +358,8 @@ class FEInputStructHelper : public FEInputContainer { virtual MIRStructType *CreateMIRStructTypeImpl(bool &error) const = 0; virtual TypeAttrs GetStructAttributeFromInputImpl() const = 0; virtual uint64 GetRawAccessFlagsImpl() const = 0; + virtual GStrIdx GetIRSrcFileSigIdxImpl() const = 0; + virtual bool IsMultiDefImpl() const = 0; virtual void InitFieldHelpersImpl() = 0; virtual void InitMethodHelpersImpl() = 0; void CreateSymbol(); @@ -306,6 +370,7 @@ class FEInputStructHelper : public FEInputContainer { void ProcessDeclDefInfoSuperNameForJava(); void ProcessDeclDefInfoImplementNameForJava(); void ProcessFieldDef(); + void ProcessExtraFields(); void ProcessMethodDef(); void ProcessStaticFields(); @@ -315,7 +380,7 @@ class FEInputStructHelper : public FEInputContainer { MapleList fieldHelpers; MapleList methodHelpers; FEInputPragmaHelper *pragmaHelper; - std::vector staticFieldsConstVal; + MapleVector staticFieldsConstVal; std::vector finalStaticStringID; bool isSkipped; MIRSrcLang srcLang; diff --git a/src/mplfe/common/include/fe_java_string_manager.h b/src/mplfe/common/include/fe_java_string_manager.h index 563724cd318ef06b8bfc571fa4866993fee55d17..000c43fcf77e9b402c132a168e126da94eb90bc7 100644 --- a/src/mplfe/common/include/fe_java_string_manager.h +++ b/src/mplfe/common/include/fe_java_string_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/fe_macros.h b/src/mplfe/common/include/fe_macros.h index 11755f759056cd00f7597aa54be7644bde0c91f7..aa1fdc72233fc99352355b400b2114fe177db03d 100644 --- a/src/mplfe/common/include/fe_macros.h +++ b/src/mplfe/common/include/fe_macros.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -58,4 +58,8 @@ } while (0) \ #define BIT_XOR(v1, v2) (((v1) && (!(v2))) || ((!(v1)) && (v2))) + +#define TRY_DO(run) do { \ + CHECK_FATAL(run, "%s", #run); \ +} while (0) #endif // ~MPLFE_INCLUDE_FE_MACROS_H \ No newline at end of file diff --git a/src/mplfe/common/include/fe_manager.h b/src/mplfe/common/include/fe_manager.h index bb865aa34a9d2298256f237ac0f55da2c6c95c51..f7f3747a3328ad9bae4efdf285857f3909019990 100644 --- a/src/mplfe/common/include/fe_manager.h +++ b/src/mplfe/common/include/fe_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -138,7 +138,7 @@ class FEManager { typeManager(module), builder(&module), javaStringManager(moduleIn, builder), - structElemMempool(memPoolCtrler.NewMemPool("MemPool for StructElemNameIdx")), + structElemMempool(FEUtils::NewMempool("MemPool for StructElemNameIdx", false /* isLcalPool */)), structElemAllocator(structElemMempool) {} ~FEManager() { if (structElemMempool != nullptr) { @@ -149,4 +149,4 @@ class FEManager { mutable std::mutex feManagerMapStructElemNameIdxMtx; }; } // namespace maple -#endif // MPLFE_INCLUDE_COMMON_FE_MANAGER_H +#endif // MPLFE_INCLUDE_COMMON_FE_MANAGER_H \ No newline at end of file diff --git a/src/mplfe/common/include/fe_options.h b/src/mplfe/common/include/fe_options.h index c2eca3d85574d627e2ec71182212ae5bdc7867ad..73046f5483ecb7feaf6516e5ed2fb2aed26d0247 100644 --- a/src/mplfe/common/include/fe_options.h +++ b/src/mplfe/common/include/fe_options.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -75,6 +75,12 @@ class FEOptions { return inputDexFiles; } +#ifdef ENABLE_MPLFE_AST + void AddInputASTFile(const std::string &fileName); + const std::vector &GetInputASTFiles() const { + return inputASTFiles; + } +#endif // ~ENABLE_MPLFE_AST void AddInputMpltFileFromSys(const std::string &fileName) { inputMpltFilesFromSys.push_back(fileName); @@ -363,6 +369,22 @@ class FEOptions { return typeInferKind; } + bool IsRC() const { + return isRC; + } + + void SetRC(bool arg) { + isRC = arg; + } + + bool IsNoBarrier() const { + return isNoBarrier; + } + + void SetNoBarrier(bool arg) { + isNoBarrier = arg; + } + bool HasJBC() const { return ((inputClassFiles.size() != 0) || (inputJarFiles.size() != 0)); } @@ -381,6 +403,9 @@ class FEOptions { std::list inputClassFiles; std::list inputJarFiles; std::vector inputDexFiles; +#ifdef ENABLE_MPLFE_AST + std::vector inputASTFiles; +#endif // ~/ENABLE_MPLFE_AST std::list inputMpltFilesFromSys; std::list inputMpltFilesFromApk; std::list inputMpltFiles; @@ -419,6 +444,10 @@ class FEOptions { std::set dumpJBCFuncNames; bool isEmitJBCLocalVarInfo = false; + // bc compiler options + bool isRC = false; + bool isNoBarrier = false; + // general stmt/bb/cfg debug options bool isDumpGenCFGGraph = false; std::string genCFGGraphFileName = ""; diff --git a/src/mplfe/common/include/fe_struct_elem_info.h b/src/mplfe/common/include/fe_struct_elem_info.h index 2c479ae8f31e422c03226bac7e09163a9a718b76..a7e8e0efedd3f28b62dc2057f6706bf94596b5e0 100644 --- a/src/mplfe/common/include/fe_struct_elem_info.h +++ b/src/mplfe/common/include/fe_struct_elem_info.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -36,12 +36,18 @@ struct StructElemNameIdx { type = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(namemangler::EncodeName(typeStr)); full = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(namemangler::EncodeName(fullName)); } + StructElemNameIdx(const std::string &funcStr) { + klass = GStrIdx(0); + elem = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(funcStr); + type = GStrIdx(0); + full = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(funcStr); + } ~StructElemNameIdx() = default; }; class FEStructElemInfo { public: - FEStructElemInfo(const StructElemNameIdx &argStructElemNameIdx, + FEStructElemInfo(MapleAllocator &allocatorIn, const StructElemNameIdx &argStructElemNameIdx, MIRSrcLang argSrcLang, bool argIsStatic); virtual ~FEStructElemInfo() = default; @@ -57,6 +63,10 @@ class FEStructElemInfo { return GlobalTables::GetStrTable().GetStringFromStrIdx(structElemNameIdx.elem); } + const GStrIdx &GetElemNameIdx() const { + return structElemNameIdx.elem; + } + const std::string &GetSignatureName() const { return GlobalTables::GetStrTable().GetStringFromStrIdx(structElemNameIdx.type); } @@ -98,30 +108,33 @@ class FEStructElemInfo { } UniqueFEIRType GetActualContainerType() const; - const std::string &GetActualContainerName() const { - return actualContainer; + const std::string GetActualContainerName() const { + return actualContainer.c_str(); } LLT_PROTECTED: virtual void PrepareImpl(MIRBuilder &mirBuilder, bool argIsStatic) = 0; - StructElemNameIdx structElemNameIdx; - MIRSrcLang srcLang : 8; bool isStatic : 1; bool isMethod : 1; bool isDefined : 1; bool isFromDex : 1; bool isPrepared : 1; - std::string actualContainer; // in maple format + MIRSrcLang srcLang : 8; + MapleAllocator &allocator; + StructElemNameIdx structElemNameIdx; + MapleString actualContainer; // in maple format }; using UniqueFEStructElemInfo = std::unique_ptr; class FEStructFieldInfo : public FEStructElemInfo { public: - FEStructFieldInfo(const StructElemNameIdx &argStructElemNameIdx, + FEStructFieldInfo(MapleAllocator &allocatorIn, const StructElemNameIdx &argStructElemNameIdx, MIRSrcLang argSrcLang, bool argIsStatic); - ~FEStructFieldInfo() = default; + ~FEStructFieldInfo() { + fieldType = nullptr; + } GStrIdx GetFieldNameIdx() const { return fieldNameIdx; } @@ -134,10 +147,14 @@ class FEStructFieldInfo : public FEStructElemInfo { fieldID = argFieldID; } - const UniqueFEIRType &GetType() const { + const FEIRType *GetType() const { return fieldType; } + bool IsVolatile() const { + return isVolatile; + } + LLT_PROTECTED: void PrepareImpl(MIRBuilder &mirBuilder, bool argIsStatic) override; @@ -151,14 +168,15 @@ class FEStructFieldInfo : public FEStructElemInfo { bool SearchStructFieldJava(const TyIdx &tyIdx, MIRBuilder &mirBuilder, bool argIsStatic, bool allowPrivate = true); bool CompareFieldType(const FieldPair &fieldPair) const; - UniqueFEIRType fieldType; + FEIRType *fieldType; GStrIdx fieldNameIdx; FieldID fieldID; + bool isVolatile; }; class FEStructMethodInfo : public FEStructElemInfo { public: - FEStructMethodInfo(const StructElemNameIdx &argStructElemNameIdx, + FEStructMethodInfo(MapleAllocator &allocatorIn, const StructElemNameIdx &argStructElemNameIdx, MIRSrcLang argSrcLang, bool argIsStatic); ~FEStructMethodInfo(); PUIdx GetPuIdx() const; @@ -186,20 +204,18 @@ class FEStructMethodInfo : public FEStructElemInfo { isJavaDynamicCall = false; } - const UniqueFEIRType &GetReturnType() const { + const FEIRType *GetReturnType() const { return retType; } - const UniqueFEIRType &GetOwnerType() const { + const FEIRType *GetOwnerType() const { return ownerType; } - const std::vector &GetArgTypes() const { + const MapleVector &GetArgTypes() const { return argTypes; } - static void InitJavaPolymorphicWhiteList(); - LLT_PROTECTED: void PrepareImpl(MIRBuilder &mirBuilder, bool argIsStatic) override; @@ -212,17 +228,16 @@ class FEStructMethodInfo : public FEStructElemInfo { bool allowPrivate = true); bool SearchStructMethodJavaInParent(MIRStructType &structType, MIRBuilder &mirBuilder, bool argIsStatic); bool SearchStructMethodJava(const TyIdx &tyIdx, MIRBuilder &mirBuilder, bool argIsStatic, bool allowPrivate = true); - bool CheckJavaPolymorphicCall() const; - std::vector argTypes; - UniqueFEIRType retType; - UniqueFEIRType ownerType; - GStrIdx methodNameIdx; - MIRFunction *mirFunc; + bool isReturnVoid; bool isConstructor; bool isJavaPolymorphicCall; bool isJavaDynamicCall; - static std::map> javaPolymorphicWhiteList; + GStrIdx methodNameIdx; + FEIRType *retType; + FEIRType *ownerType; + MIRFunction *mirFunc; + MapleVector argTypes; }; } // namespace maple #endif // MPLFE_INCLUDE_COMMON_FE_STRUCT_ELEM_INFO_H diff --git a/src/mplfe/common/include/fe_timer.h b/src/mplfe/common/include/fe_timer.h index 623761cab4aaa9f7de65713053628b3aa812206c..87e124cba73bd85e17353ede6cc77e266b581749 100644 --- a/src/mplfe/common/include/fe_timer.h +++ b/src/mplfe/common/include/fe_timer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/fe_timer_ns.h b/src/mplfe/common/include/fe_timer_ns.h index 9506c63b105c7170533f7a7aef4206454ca52824..187afa72b2c255d79765eb5810d2dc8642c6ddd4 100644 --- a/src/mplfe/common/include/fe_timer_ns.h +++ b/src/mplfe/common/include/fe_timer_ns.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/fe_type_hierarchy.h b/src/mplfe/common/include/fe_type_hierarchy.h index 0a0b0af61ecbc8eae7fcc3f61e82f647ac2beb82..1d3db47a74387daa6e784ab7ddec904874d8adb0 100644 --- a/src/mplfe/common/include/fe_type_hierarchy.h +++ b/src/mplfe/common/include/fe_type_hierarchy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/fe_type_manager.h b/src/mplfe/common/include/fe_type_manager.h index b0f11e670de1d047538f421ab2b235d7465ef665..15147af0b30abfd79b389cab458c252037cdd120 100644 --- a/src/mplfe/common/include/fe_type_manager.h +++ b/src/mplfe/common/include/fe_type_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -109,6 +109,8 @@ class FETypeManager { return CreateClassOrInterfaceType(nameIdx, isInterface, typeFlag); } + MIRStructType *GetOrCreateStructType(const std::string &name); + MIRStructType *CreateStructType(const std::string &name); MIRStructType *GetOrCreateClassOrInterfaceType(const GStrIdx &nameIdx, bool isInterface, FETypeFlag typeFlag, bool &isCreate); MIRStructType *GetOrCreateClassOrInterfaceType(const std::string &name, bool isInterface, FETypeFlag typeFlag, @@ -126,7 +128,7 @@ class FETypeManager { } - uint32 GetTypeIDFromMplClassName(const std::string &mplClassName) const; + uint32 GetTypeIDFromMplClassName(const std::string &mplClassName, int32 dexFileHashCode) const; MIRStructType *GetStructTypeFromName(const std::string &name); MIRStructType *GetStructTypeFromName(const GStrIdx &nameIdx); MIRType *GetOrCreateTypeFromName(const std::string &name, FETypeFlag typeFlag, bool usePtr); @@ -202,12 +204,29 @@ class FETypeManager { } static void SetComplete(MIRStructType &structType); static std::string TypeAttrsToString(const TypeAttrs &attrs); + bool IsImportedType(const GStrIdx &typeNameIdx) const { return structNameTypeMap.find(typeNameIdx) != structNameTypeMap.end(); } + + MIRStructType *GetImportedType(const GStrIdx &typeNameIdx) const { + auto it = structNameTypeMap.find(typeNameIdx); + if (it != structNameTypeMap.end()) { + return it->second.first; + } + return nullptr; + } + + const std::unordered_map &GetStructNameTypeMap() const { + return structNameTypeMap; + } void MarkExternStructType(); void SetMirImportedTypes(FETypeFlag flag); + void SetSrcLang(const MIRSrcLang &argSrcLang) { + srcLang = argSrcLang; + } + private: void UpdateStructNameTypeMapFromTypeTable(const std::string &mpltName, FETypeFlag flag); void UpdateNameFuncMapFromTypeTable(); @@ -216,7 +235,7 @@ class FETypeManager { // MCC function void InitFuncMCCGetOrInsertLiteral(); - void InitFuncMCCStaticField(); + using mirFuncPair = std::pair; MIRModule &module; MemPool *mp; @@ -232,8 +251,8 @@ class FETypeManager { MIRSrcLang srcLang; // ---------- class name ---> type id map info ---------- - std::unordered_map classNameTypeIDMap; - + using classNameTypeIDMapT = std::unordered_map; + std::map classNameTypeIDMapAllDex; // dexFileHashCode className classTpyeID // ---------- struct elem info ---------- std::map mapStructElemInfo; diff --git a/src/mplfe/common/include/fe_utils.h b/src/mplfe/common/include/fe_utils.h index 740e6e0e9ff006d5a7d0e6efd465d58c938c6406..51775aeb378d294b25dd730e78095fbca96eb3b6 100644 --- a/src/mplfe/common/include/fe_utils.h +++ b/src/mplfe/common/include/fe_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -20,6 +20,7 @@ #include "mpl_logging.h" #include "prim_types.h" #include "global_tables.h" +#include "mempool.h" namespace maple { class FEUtils { @@ -35,6 +36,8 @@ class FEUtils { static uint8 GetDim(const std::string &typeName); static std::string GetBaseTypeName(const std::string &typeName); static PrimType GetPrimType(const GStrIdx &typeNameIdx); + static std::string GetSequentialName0(const std::string &prefix, uint32_t num); + static std::string GetSequentialName(const std::string &prefix); static const std::string kBoolean; static const std::string kByte; @@ -45,6 +48,7 @@ class FEUtils { static const std::string kFloat; static const std::string kDouble; static const std::string kVoid; + static const std::string kThis; static const std::string kMCCStaticFieldGetBool; static const std::string kMCCStaticFieldGetByte; static const std::string kMCCStaticFieldGetChar; @@ -65,6 +69,14 @@ class FEUtils { static const std::string kMCCStaticFieldSetDouble; static const std::string kMCCStaticFieldSetObject; + static inline MemPool *NewMempool(const std::string &name, bool isLocalPool) { +#ifndef USE_OPS + return memPoolCtrler.NewMemPool(name, isLocalPool); +#else + return memPoolCtrler.NewMemPool(name); +#endif + } + static inline GStrIdx &GetBooleanIdx() { static GStrIdx booleanIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(kBoolean); return booleanIdx; @@ -110,6 +122,11 @@ class FEUtils { return voidIdx; } + static inline GStrIdx &GetThisIdx() { + static GStrIdx thisIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(kThis); + return thisIdx; + } + static inline GStrIdx &GetMCCStaticFieldGetBoolIdx() { static GStrIdx mccStaticFieldGetBoolIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(kMCCStaticFieldGetBool); diff --git a/src/mplfe/common/include/fe_utils_ast.h b/src/mplfe/common/include/fe_utils_ast.h new file mode 100644 index 0000000000000000000000000000000000000000..8c1b3a7ed4cebe91f611dac008cbabdeca2d26b6 --- /dev/null +++ b/src/mplfe/common/include/fe_utils_ast.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#ifndef MPLFE_INCLUDE_FE_UTILS_AST_H +#define MPLFE_INCLUDE_FE_UTILS_AST_H +#include +#include +#include "feir_type.h" + +namespace maple { +class FEUtilAST { + public: + static PrimType GetTypeFromASTTypeName(const std::string &typeName); + + private: + FEUtilAST() = default; + ~FEUtilAST() = default; +}; +} // namespace maple +#endif // MPLFE_INCLUDE_FE_UTILS_AST_H diff --git a/src/mplfe/common/include/fe_utils_java.h b/src/mplfe/common/include/fe_utils_java.h index b201eccce0882ace98af14b257bfb50adee39d0f..f5d75b1c9e8b9c3349139c4c1727a6e2249a65f4 100644 --- a/src/mplfe/common/include/fe_utils_java.h +++ b/src/mplfe/common/include/fe_utils_java.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/feir_bb.h b/src/mplfe/common/include/feir_bb.h index 436d6d7eee252494595e99a058b5517aebc71417..d477553c4d2a51a31870b76f08c60adcfe0d0f9f 100644 --- a/src/mplfe/common/include/feir_bb.h +++ b/src/mplfe/common/include/feir_bb.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/feir_builder.h b/src/mplfe/common/include/feir_builder.h index 7dee8cc0e9916e4a463fd483133383fe171b49d3..1f814130fd3dc081b9e71432ed77c69706c8efe7 100644 --- a/src/mplfe/common/include/feir_builder.h +++ b/src/mplfe/common/include/feir_builder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -39,6 +39,7 @@ class FEIRBuilder { bool withType = false); // Expr static UniqueFEIRExpr CreateExprDRead(UniqueFEIRVar srcVar); + static UniqueFEIRExpr CreateExprAddrof(const std::vector &array); static UniqueFEIRExpr CreateExprConstRefNull(); static UniqueFEIRExpr CreateExprConstI8(int8 val); static UniqueFEIRExpr CreateExprConstI16(int16 val); @@ -58,8 +59,11 @@ class FEIRBuilder { static UniqueFEIRExpr CreateExprCvtPrim(UniqueFEIRExpr srcExpr, PrimType dstType); static UniqueFEIRExpr CreateExprJavaNewInstance(UniqueFEIRType type); static UniqueFEIRExpr CreateExprJavaNewInstance(UniqueFEIRType type, uint32 argTypeID); + static UniqueFEIRExpr CreateExprJavaNewInstance(UniqueFEIRType type, uint32 argTypeID, bool isRcPermanent); static UniqueFEIRExpr CreateExprJavaNewArray(UniqueFEIRType type, UniqueFEIRExpr exprSize); static UniqueFEIRExpr CreateExprJavaNewArray(UniqueFEIRType type, UniqueFEIRExpr exprSize, uint32 typeID); + static UniqueFEIRExpr CreateExprJavaNewArray(UniqueFEIRType type, UniqueFEIRExpr exprSize, uint32 typeID, + bool isRcPermanent); static UniqueFEIRExpr CreateExprJavaArrayLength(UniqueFEIRExpr exprArray); // Stmt static UniqueFEIRStmt CreateStmtDAssign(UniqueFEIRVar dstVar, UniqueFEIRExpr srcExpr, bool hasException = false); @@ -67,7 +71,7 @@ class FEIRBuilder { static UniqueFEIRStmt CreateStmtCondGoto(uint32 targetLabelIdx, Opcode op, UniqueFEIRExpr expr); static UniqueFEIRStmt CreateStmtSwitch(UniqueFEIRExpr expr); static UniqueFEIRStmt CreateStmtJavaConstClass(UniqueFEIRVar dstVar, UniqueFEIRType type); - static UniqueFEIRStmt CreateStmtJavaConstString(UniqueFEIRVar dstVar, const GStrIdx &strIdx); + static UniqueFEIRStmt CreateStmtJavaConstString(UniqueFEIRVar dstVar, const std::string &strVal); static UniqueFEIRStmt CreateStmtJavaCheckCast(UniqueFEIRVar dstVar, UniqueFEIRVar srcVar, UniqueFEIRType type); static UniqueFEIRStmt CreateStmtJavaCheckCast(UniqueFEIRVar dstVar, UniqueFEIRVar srcVar, UniqueFEIRType type, uint32 argTypeID); diff --git a/src/mplfe/common/include/feir_dfg.h b/src/mplfe/common/include/feir_dfg.h index 4cc2053a50f2a84a4f5c638d4dc9dddafc017242..fb1e6bbf085c601ac9650a81cc18cd63877172f9 100644 --- a/src/mplfe/common/include/feir_dfg.h +++ b/src/mplfe/common/include/feir_dfg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/feir_node_kind.def b/src/mplfe/common/include/feir_node_kind.def index 4337b207cf7e91815c738ef89119074b70651664..667d4f3502e8d2b2a1e80ab2d74ed27381231cab 100644 --- a/src/mplfe/common/include/feir_node_kind.def +++ b/src/mplfe/common/include/feir_node_kind.def @@ -1,58 +1,59 @@ -// FEIR_NODE_KIND (kind, description) -FEIR_NODE_KIND(Stmt, "Stmt") -FEIR_NODE_KIND(FEIRStmtNary, "FEIRStmtNary") -FEIR_NODE_KIND(StmtAssign, "StmtAssign") -FEIR_NODE_KIND(StmtNonAssign, "StmtNonAssign") -FEIR_NODE_KIND(StmtPesudo, "StmtPesudo") -FEIR_NODE_KIND(StmtDAssign, "StmtDAssign") -FEIR_NODE_KIND(StmtJavaTypeCheck, "StmtJavaTypeCheck") -FEIR_NODE_KIND(StmtJavaConstClass, "StmtJavaConstClass") -FEIR_NODE_KIND(StmtJavaConstString, "StmtJavaConstString") -FEIR_NODE_KIND(StmtJavaMultiANewArray, "StmtJavaMultiANewArray") -FEIR_NODE_KIND(StmtCallAssign, "StmtCallAssign") -FEIR_NODE_KIND(StmtJavaDynamicCallAssign, "StmtJavaDynamicCallAssign") -FEIR_NODE_KIND(StmtIntrinsicCallAssign, "StmtIntrinsicCallAssign") -FEIR_NODE_KIND(StmtIAssign, "StmtIAssign") -FEIR_NODE_KIND(StmtUseOnly, "StmtUseOnly") -FEIR_NODE_KIND(StmtReturn, "StmtReturn") -FEIR_NODE_KIND(StmtBranch, "StmtBranch") -FEIR_NODE_KIND(StmtGoto, "StmtGoto") -FEIR_NODE_KIND(StmtCondGoto, "StmtCondGoto") -FEIR_NODE_KIND(StmtSwitch, "StmtSwitch") -FEIR_NODE_KIND(StmtArrayStore, "StmtArrayStore") -FEIR_NODE_KIND(StmtFieldStore, "StmtFieldStore") -FEIR_NODE_KIND(StmtFieldLoad, "StmtFieldLoad") -FEIR_NODE_KIND(Expr, "Expr") -FEIR_NODE_KIND(ExprNestable, "ExprNestable") -FEIR_NODE_KIND(ExprNonNestable, "ExprNonNestable") -FEIR_NODE_KIND(ExprConst, "ExprConst") -FEIR_NODE_KIND(ExprDRead, "ExprDRead") -FEIR_NODE_KIND(ExprRegRead, "ExprRegRead") -FEIR_NODE_KIND(ExprConvert, "ExprConvert") -FEIR_NODE_KIND(ExprIntExt, "ExprIntExt") -FEIR_NODE_KIND(ExprRetype, "ExprRetype") -FEIR_NODE_KIND(ExprCompare, "ExprCompare") -FEIR_NODE_KIND(ExprUnary, "ExprUnary") -FEIR_NODE_KIND(ExprBinary, "ExprBinary") -FEIR_NODE_KIND(ExprTernary, "ExprTernary") -FEIR_NODE_KIND(ExprNary, "ExprNary") -FEIR_NODE_KIND(ExprArray, "ExprArray") -FEIR_NODE_KIND(ExprIntrinsicop, "ExprIntrinsicop") -FEIR_NODE_KIND(FEIRExprJavaMerge, "FEIRExprJavaMerge") -FEIR_NODE_KIND(ExprTypeCvt, "ExprTypeCvt") -FEIR_NODE_KIND(ExprJavaNewInstance, "ExprJavaNewInstance") -FEIR_NODE_KIND(ExprJavaNewArray, "ExprJavaNewArray") -FEIR_NODE_KIND(ExprJavaArrayLength, "ExprJavaArrayLength") -FEIR_NODE_KIND(ExprJavaInstanceOf, "ExprJavaInstanceOf") -FEIR_NODE_KIND(ExprArrayLoad, "ExprArrayLoad") -FEIR_NODE_KIND(StmtJavaFillArrayData, "StmtJavaFillArrayData") -FEIR_NODE_KIND(StmtPesudoFuncStart, "StmtPesudoFuncStart") -FEIR_NODE_KIND(StmtPesudoFuncEnd, "StmtPesudoFuncEnd") -FEIR_NODE_KIND(StmtCheckPoint, "StmtCheckPoint") -FEIR_NODE_KIND(StmtPesudoLOC, "StmtPesudoLOC") -FEIR_NODE_KIND(StmtPesudoLabel, "StmtPesudoLabel") -FEIR_NODE_KIND(StmtPesudoJavaTry, "StmtPesudoJavaTry") -FEIR_NODE_KIND(StmtPesudoEndTry, "StmtPesudoEndTry") -FEIR_NODE_KIND(StmtPesudoJavaCatch, "StmtPesudoJavaCatch") -FEIR_NODE_KIND(StmtPesudoComment, "StmtPesudoComment") +// FEIR_NODE_KIND (kind, description) +FEIR_NODE_KIND(Stmt, "Stmt") +FEIR_NODE_KIND(FEIRStmtNary, "FEIRStmtNary") +FEIR_NODE_KIND(StmtAssign, "StmtAssign") +FEIR_NODE_KIND(StmtNonAssign, "StmtNonAssign") +FEIR_NODE_KIND(StmtPesudo, "StmtPesudo") +FEIR_NODE_KIND(StmtDAssign, "StmtDAssign") +FEIR_NODE_KIND(StmtJavaTypeCheck, "StmtJavaTypeCheck") +FEIR_NODE_KIND(StmtJavaConstClass, "StmtJavaConstClass") +FEIR_NODE_KIND(StmtJavaConstString, "StmtJavaConstString") +FEIR_NODE_KIND(StmtJavaMultiANewArray, "StmtJavaMultiANewArray") +FEIR_NODE_KIND(StmtCallAssign, "StmtCallAssign") +FEIR_NODE_KIND(StmtJavaDynamicCallAssign, "StmtJavaDynamicCallAssign") +FEIR_NODE_KIND(StmtIntrinsicCallAssign, "StmtIntrinsicCallAssign") +FEIR_NODE_KIND(StmtIAssign, "StmtIAssign") +FEIR_NODE_KIND(StmtUseOnly, "StmtUseOnly") +FEIR_NODE_KIND(StmtReturn, "StmtReturn") +FEIR_NODE_KIND(StmtBranch, "StmtBranch") +FEIR_NODE_KIND(StmtGoto, "StmtGoto") +FEIR_NODE_KIND(StmtCondGoto, "StmtCondGoto") +FEIR_NODE_KIND(StmtSwitch, "StmtSwitch") +FEIR_NODE_KIND(StmtArrayStore, "StmtArrayStore") +FEIR_NODE_KIND(StmtFieldStore, "StmtFieldStore") +FEIR_NODE_KIND(StmtFieldLoad, "StmtFieldLoad") +FEIR_NODE_KIND(Expr, "Expr") +FEIR_NODE_KIND(ExprNestable, "ExprNestable") +FEIR_NODE_KIND(ExprNonNestable, "ExprNonNestable") +FEIR_NODE_KIND(ExprConst, "ExprConst") +FEIR_NODE_KIND(ExprDRead, "ExprDRead") +FEIR_NODE_KIND(ExprRegRead, "ExprRegRead") +FEIR_NODE_KIND(ExprConvert, "ExprConvert") +FEIR_NODE_KIND(ExprIntExt, "ExprIntExt") +FEIR_NODE_KIND(ExprRetype, "ExprRetype") +FEIR_NODE_KIND(ExprCompare, "ExprCompare") +FEIR_NODE_KIND(ExprUnary, "ExprUnary") +FEIR_NODE_KIND(ExprBinary, "ExprBinary") +FEIR_NODE_KIND(ExprTernary, "ExprTernary") +FEIR_NODE_KIND(ExprNary, "ExprNary") +FEIR_NODE_KIND(ExprArray, "ExprArray") +FEIR_NODE_KIND(ExprAddrof, "ExprAddrof") +FEIR_NODE_KIND(ExprIntrinsicop, "ExprIntrinsicop") +FEIR_NODE_KIND(FEIRExprJavaMerge, "FEIRExprJavaMerge") +FEIR_NODE_KIND(ExprTypeCvt, "ExprTypeCvt") +FEIR_NODE_KIND(ExprJavaNewInstance, "ExprJavaNewInstance") +FEIR_NODE_KIND(ExprJavaNewArray, "ExprJavaNewArray") +FEIR_NODE_KIND(ExprJavaArrayLength, "ExprJavaArrayLength") +FEIR_NODE_KIND(ExprJavaInstanceOf, "ExprJavaInstanceOf") +FEIR_NODE_KIND(ExprArrayLoad, "ExprArrayLoad") +FEIR_NODE_KIND(StmtJavaFillArrayData, "StmtJavaFillArrayData") +FEIR_NODE_KIND(StmtPesudoFuncStart, "StmtPesudoFuncStart") +FEIR_NODE_KIND(StmtPesudoFuncEnd, "StmtPesudoFuncEnd") +FEIR_NODE_KIND(StmtCheckPoint, "StmtCheckPoint") +FEIR_NODE_KIND(StmtPesudoLOC, "StmtPesudoLOC") +FEIR_NODE_KIND(StmtPesudoLabel, "StmtPesudoLabel") +FEIR_NODE_KIND(StmtPesudoJavaTry, "StmtPesudoJavaTry") +FEIR_NODE_KIND(StmtPesudoEndTry, "StmtPesudoEndTry") +FEIR_NODE_KIND(StmtPesudoJavaCatch, "StmtPesudoJavaCatch") +FEIR_NODE_KIND(StmtPesudoComment, "StmtPesudoComment") FEIR_NODE_KIND(StmtPesudoCommentForInst, "StmtPesudoCommentForInst") \ No newline at end of file diff --git a/src/mplfe/common/include/feir_stmt.h b/src/mplfe/common/include/feir_stmt.h index 9d18fab07dbc094819b965f42ce83c907101de70..bda4319400284c60b96b16f4d9d5fac04c07e7ee 100644 --- a/src/mplfe/common/include/feir_stmt.h +++ b/src/mplfe/common/include/feir_stmt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -423,6 +423,21 @@ class FEIRExprRegRead : public FEIRExpr { int32 regNum; }; +// ---------- FEIRExprAddrof ---------- +class FEIRExprAddrof : public FEIRExpr { + public: + explicit FEIRExprAddrof(const std::vector &arrayIn) + : FEIRExpr(FEIRNodeKind::kExprAddrof), array(arrayIn) {} + ~FEIRExprAddrof() = default; + + protected: + std::unique_ptr CloneImpl() const override; + BaseNode *GenMIRNodeImpl(MIRBuilder &mirBuilder) const override; + + private: + std::vector array; +}; + // ---------- FEIRExprUnary ---------- class FEIRExprUnary : public FEIRExpr { public: @@ -641,8 +656,6 @@ class FEIRExprIntrinsicop : public FEIRExprNary { const std::vector> &argOpnds); FEIRExprIntrinsicop(std::unique_ptr exprType, MIRIntrinsicID argIntrinsicID, std::unique_ptr argParamType, uint32 argTypeID); - FEIRExprIntrinsicop(std::unique_ptr exprType, MIRIntrinsicID argIntrinsicID, - std::unique_ptr argParamType, uint32 argTypeID, uint32 argArraySize); FEIRExprIntrinsicop(std::unique_ptr exprType, MIRIntrinsicID argIntrinsicID, std::unique_ptr argParamType, const std::vector> &argOpnds); @@ -660,7 +673,6 @@ class FEIRExprIntrinsicop : public FEIRExprNary { MIRIntrinsicID intrinsicID; std::unique_ptr paramType; uint32 typeID = UINT32_MAX; - uint32 arraySize = UINT32_MAX; }; // class FEIRExprIntrinsicop class FEIRExprJavaMerge : public FEIRExprNary { @@ -679,12 +691,16 @@ class FEIRExprJavaNewInstance : public FEIRExpr { public: explicit FEIRExprJavaNewInstance(UniqueFEIRType argType); FEIRExprJavaNewInstance(UniqueFEIRType argType, uint32 argTypeID); + FEIRExprJavaNewInstance(UniqueFEIRType argType, uint32 argTypeID, bool argIsRcPermanent); ~FEIRExprJavaNewInstance() = default; protected: std::unique_ptr CloneImpl() const override; BaseNode *GenMIRNodeImpl(MIRBuilder &mirBuilder) const override; + uint32 typeID = UINT32_MAX; + // isRcPermanent is true means the rc annotation @Permanent is used + bool isRcPermanent = false; }; // ---------- FEIRExprJavaNewArray ---------- @@ -692,6 +708,8 @@ class FEIRExprJavaNewArray : public FEIRExpr { public: FEIRExprJavaNewArray(UniqueFEIRType argArrayType, UniqueFEIRExpr argExprSize); FEIRExprJavaNewArray(UniqueFEIRType argArrayType, UniqueFEIRExpr argExprSize, uint32 argTypeID); + FEIRExprJavaNewArray(UniqueFEIRType argArrayType, UniqueFEIRExpr argExprSize, uint32 argTypeID, + bool argIsRcPermanent); ~FEIRExprJavaNewArray() = default; void SetArrayType(UniqueFEIRType argArrayType) { CHECK_NULL_FATAL(argArrayType); @@ -714,6 +732,8 @@ class FEIRExprJavaNewArray : public FEIRExpr { UniqueFEIRType arrayType; UniqueFEIRExpr exprSize; uint32 typeID = UINT32_MAX; + // isRcPermanent is true means the rc annotation @Permanent is used + bool isRcPermanent = false; }; // ---------- FEIRExprJavaArrayLength ---------- @@ -871,9 +891,9 @@ class FEIRStmtJavaTypeCheck : public FEIRStmtAssign { bool CalculateDefs4AllUsesImpl(FEIRStmtCheckPoint &checkPoint, FEIRUseDefChain &udChain) override; std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; CheckKind checkKind; - uint32 typeID = UINT32_MAX; std::unique_ptr expr; std::unique_ptr type; + uint32 typeID = UINT32_MAX; }; // ---------- FEIRStmtJavaConstClass ---------- @@ -891,8 +911,8 @@ class FEIRStmtJavaConstClass : public FEIRStmtAssign { // ---------- FEIRStmtJavaConstString ---------- class FEIRStmtJavaConstString : public FEIRStmtAssign { public: - FEIRStmtJavaConstString(std::unique_ptr argVar, const GStrIdx &argStrIdx); - FEIRStmtJavaConstString(std::unique_ptr argVar, const GStrIdx &argStrIdx, uint32 argStringID); + FEIRStmtJavaConstString(std::unique_ptr argVar, const std::string &argStrVal, + uint32 argFileIdx, uint32 argStringID); ~FEIRStmtJavaConstString() = default; protected: @@ -900,7 +920,8 @@ class FEIRStmtJavaConstString : public FEIRStmtAssign { std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; private: - GStrIdx strIdx; + std::string strVal; + uint32 fileIdx; uint32 stringID = UINT32_MAX; }; @@ -931,10 +952,14 @@ class FEIRStmtJavaFillArrayData : public FEIRStmtAssign { // ---------- FEIRStmtJavaMultiANewArray ---------- class FEIRStmtJavaMultiANewArray : public FEIRStmtAssign { public: - FEIRStmtJavaMultiANewArray(std::unique_ptr argVar, std::unique_ptr argType); + FEIRStmtJavaMultiANewArray(std::unique_ptr argVar, std::unique_ptr argElemType, + std::unique_ptr argArrayType); ~FEIRStmtJavaMultiANewArray() = default; void AddVarSize(std::unique_ptr argVarSize); void AddVarSizeRev(std::unique_ptr argVarSize); + void SetArrayType(std::unique_ptr argArrayType) { + arrayType = std::move(argArrayType); + } protected: std::string DumpDotStringImpl() const override; @@ -948,7 +973,8 @@ class FEIRStmtJavaMultiANewArray : public FEIRStmtAssign { static const UniqueFEIRType &GetTypeAnnotation(); static FEStructMethodInfo &GetMethodInfoNewInstance(); - std::unique_ptr type; + std::unique_ptr elemType; + std::unique_ptr arrayType; std::list> exprSizes; static UniqueFEIRVar varSize; static UniqueFEIRVar varClass; @@ -1321,6 +1347,8 @@ class FEIRStmtFieldStore : public FEIRStmt { public: FEIRStmtFieldStore(UniqueFEIRVar argVarObj, UniqueFEIRVar argVarField, FEStructFieldInfo &argFieldInfo, bool argIsStatic); + FEIRStmtFieldStore(UniqueFEIRVar argVarObj, UniqueFEIRVar argVarField, FEStructFieldInfo &argFieldInfo, + bool argIsStatic, int32 argDexFileHashCode); ~FEIRStmtFieldStore() = default; protected: @@ -1334,7 +1362,8 @@ class FEIRStmtFieldStore : public FEIRStmt { void RegisterDFGNodes2CheckPointForNonStatic(FEIRStmtCheckPoint &checkPoint); bool CalculateDefs4AllUsesForStatic(FEIRStmtCheckPoint &checkPoint, FEIRUseDefChain &udChain); bool CalculateDefs4AllUsesForNonStatic(FEIRStmtCheckPoint &checkPoint, FEIRUseDefChain &udChain); - uint32 GetTypeIDForStatic() const; + bool NeedMCCForStatic(uint32 &typeID) const; + void InitPrimTypeFuncNameIdxMap (std::map &primTypeFuncNameIdxMap) const; std::list GenMIRStmtsImplForStatic(MIRBuilder &mirBuilder) const; std::list GenMIRStmtsImplForNonStatic(MIRBuilder &mirBuilder) const; @@ -1342,6 +1371,7 @@ class FEIRStmtFieldStore : public FEIRStmt { UniqueFEIRVar varField; FEStructFieldInfo &fieldInfo; bool isStatic; + int32 dexFileHashCode = -1; }; // ---------- FEIRStmtFieldLoad ---------- @@ -1349,6 +1379,8 @@ class FEIRStmtFieldLoad : public FEIRStmtAssign { public: FEIRStmtFieldLoad(UniqueFEIRVar argVarObj, UniqueFEIRVar argVarField, FEStructFieldInfo &argFieldInfo, bool argIsStatic); + FEIRStmtFieldLoad(UniqueFEIRVar argVarObj, UniqueFEIRVar argVarField, FEStructFieldInfo &argFieldInfo, + bool argIsStatic, int32 argDexFileHashCode); ~FEIRStmtFieldLoad() = default; protected: @@ -1362,13 +1394,14 @@ class FEIRStmtFieldLoad : public FEIRStmtAssign { void RegisterDFGNodes2CheckPointForNonStatic(FEIRStmtCheckPoint &checkPoint); bool CalculateDefs4AllUsesForStatic(FEIRStmtCheckPoint &checkPoint, FEIRUseDefChain &udChain); bool CalculateDefs4AllUsesForNonStatic(FEIRStmtCheckPoint &checkPoint, FEIRUseDefChain &udChain); - uint32 GetTypeIDForStatic() const; + bool NeedMCCForStatic(uint32 &typeID) const; std::list GenMIRStmtsImplForStatic(MIRBuilder &mirBuilder) const; std::list GenMIRStmtsImplForNonStatic(MIRBuilder &mirBuilder) const; UniqueFEIRVar varObj; FEStructFieldInfo &fieldInfo; bool isStatic; + int32 dexFileHashCode = -1; }; // ---------- FEIRStmtCallAssign ---------- diff --git a/src/mplfe/common/include/feir_type.h b/src/mplfe/common/include/feir_type.h index c1f1a9da349efe71eb464ed5aaa21ec82a244adf..c43462816fa1c3dcd83fd11e7a19a3061ac578f5 100644 --- a/src/mplfe/common/include/feir_type.h +++ b/src/mplfe/common/include/feir_type.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -22,6 +22,7 @@ #include "mir_type.h" #include "global_tables.h" #include "fe_configs.h" +#include "fe_utils_ast.h" namespace maple { enum FEIRTypeKind { @@ -179,6 +180,7 @@ class FEIRTypeDefault : public FEIRType { FEIRTypeDefault(const FEIRTypeDefault&) = delete; FEIRTypeDefault &operator=(const FEIRTypeDefault&) = delete; void LoadFromJavaTypeName(const std::string &typeName, bool inMpl = true); + void LoadFromASTTypeName(const std::string &typeName); MIRType *GenerateMIRTypeForPrim() const; FEIRTypeDefault &SetTypeNameIdx(const GStrIdx &argTypeNameIdx) { typeNameIdx = argTypeNameIdx; diff --git a/src/mplfe/common/include/feir_type_helper.h b/src/mplfe/common/include/feir_type_helper.h index e53cbe60d467cee532fecb582eb5b3ea1fc6085f..aae59499b219bacbc4e0b34bafba3b69ccf2cd7e 100644 --- a/src/mplfe/common/include/feir_type_helper.h +++ b/src/mplfe/common/include/feir_type_helper.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/feir_type_infer.h b/src/mplfe/common/include/feir_type_infer.h index 0afe6e11eb0c6a9139411a1caa09184965157d0d..09bb384f92b3a3bf386be946b26e04004bb82896 100644 --- a/src/mplfe/common/include/feir_type_infer.h +++ b/src/mplfe/common/include/feir_type_infer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/feir_var.h b/src/mplfe/common/include/feir_var.h index 7863bf13883cbffc866cbec00f338a31ed6981b6..e009e60f44876cebb4a3e638601584851f61c5ce 100644 --- a/src/mplfe/common/include/feir_var.h +++ b/src/mplfe/common/include/feir_var.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/feir_var_name.h b/src/mplfe/common/include/feir_var_name.h index 7c89b1849e0e5707fb0f8f576c332858e6130c88..1284b9952a6b6f1b480eb713951e200b250cdff7 100644 --- a/src/mplfe/common/include/feir_var_name.h +++ b/src/mplfe/common/include/feir_var_name.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/feir_var_reg.h b/src/mplfe/common/include/feir_var_reg.h index 82c602a416dc300140a24c2bfdd324c4c31f6cf5..35cf8934663a296d581de0808d27a834b755e925 100644 --- a/src/mplfe/common/include/feir_var_reg.h +++ b/src/mplfe/common/include/feir_var_reg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -41,6 +41,7 @@ class FEIRVarReg : public FEIRVar { protected: std::string GetNameImpl(const MIRType &mirType) const override; std::string GetNameRawImpl() const override; + MIRSymbol *GenerateLocalMIRSymbolImpl(MIRBuilder &builder) const override; std::unique_ptr CloneImpl() const override; bool EqualsToImpl(const std::unique_ptr &var) const override; size_t HashImpl() const override; diff --git a/src/mplfe/common/include/feir_var_type_scatter.h b/src/mplfe/common/include/feir_var_type_scatter.h index e4cd48eebef53a4fd76a8a6d498fe9cb73ffd97b..e0481cc7546e2abde893a24956e7f8a25756252b 100644 --- a/src/mplfe/common/include/feir_var_type_scatter.h +++ b/src/mplfe/common/include/feir_var_type_scatter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/general_bb.h b/src/mplfe/common/include/general_bb.h index cac959d9c3c073b5ec6bf624b5d3c47faf135187..b35c7f911acddad9fd76edfb94878b2961776161 100644 --- a/src/mplfe/common/include/general_bb.h +++ b/src/mplfe/common/include/general_bb.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/general_cfg.h b/src/mplfe/common/include/general_cfg.h index 038aec2ad712d309b2cbe97cf45b8986d87e72df..02fd37636878a7ea71636e752b8e3fd53d0200b5 100644 --- a/src/mplfe/common/include/general_cfg.h +++ b/src/mplfe/common/include/general_cfg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/general_stmt.h b/src/mplfe/common/include/general_stmt.h index 40563cf1c1b82da8cbafc3cf146589de1f63976e..45b79eea314dfe57c7dc41ef301e052a443499ea 100644 --- a/src/mplfe/common/include/general_stmt.h +++ b/src/mplfe/common/include/general_stmt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/mplfe_compiler.h b/src/mplfe/common/include/mplfe_compiler.h index 89fee519ba129e7655b2f5dea5850aa4fd05f106..76a86a2cbb78380b1e5ade84b353230ccba4cda0 100644 --- a/src/mplfe/common/include/mplfe_compiler.h +++ b/src/mplfe/common/include/mplfe_compiler.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -25,6 +25,9 @@ #include "bc_compiler_component.h" #include "ark_annotation_processor.h" #include "dex_reader.h" +#ifdef ENABLE_MPLFE_AST +#include "ast_compiler_component.h" +#endif // ~/ENABLE_MPLFE_AST #include "fe_errno.h" #include "mpl_timer.h" #include "mplfe_env.h" @@ -53,13 +56,14 @@ class MPLFECompiler { void PreProcessDecls(); void ProcessDecls(); void ProcessPragmas(); - void PreProcessWithFunctions(); void ProcessFunctions(); private: + void RegisterCompilerComponent(); inline void InsertImportInMpl(const std::list &mplt) const; void FindMinCompileFailedFEFunctions(); MIRModule &module; + MIRSrcLang srcLang; MemPool *mp; MapleAllocator allocator; std::string firstInputName; diff --git a/src/mplfe/common/include/mplfe_compiler_component.h b/src/mplfe/common/include/mplfe_compiler_component.h index b0f41efd38cfdf069d6fca1bd6c264dd47ce98d9..611d67587091892274aa3460c5970bdcffe36083 100644 --- a/src/mplfe/common/include/mplfe_compiler_component.h +++ b/src/mplfe/common/include/mplfe_compiler_component.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -26,7 +26,7 @@ namespace maple { class FEFunctionProcessTask : public MplTask { public: - FEFunctionProcessTask(std::unique_ptr &argFunction); + FEFunctionProcessTask(std::unique_ptr argFunction); virtual ~FEFunctionProcessTask() = default; protected: @@ -34,7 +34,7 @@ class FEFunctionProcessTask : public MplTask { int FinishImpl(MplTaskParam *param) override; private: - std::unique_ptr &function; + std::unique_ptr function; }; class FEFunctionProcessSchedular : public MplScheduler { @@ -42,7 +42,7 @@ class FEFunctionProcessSchedular : public MplScheduler { FEFunctionProcessSchedular(const std::string &name) : MplScheduler(name) {} virtual ~FEFunctionProcessSchedular() = default; - void AddFunctionProcessTask(std::unique_ptr &function); + void AddFunctionProcessTask(std::unique_ptr function); void SetDumpTime(bool arg) { dumpTime = arg; } @@ -78,12 +78,8 @@ class MPLFECompilerComponent { ProcessPragmaImpl(); } - bool PreProcessWithoutFunction() { - return PreProcessWithoutFunctionImpl(); - } - - bool PreProcessWithFunction() { - return PreProcessWithFunctionImpl(); + std::unique_ptr CreatFEFunction(FEInputMethodHelper *methodHelper) { + return CreatFEFunctionImpl(methodHelper); } bool ProcessFunctionSerial() { @@ -107,7 +103,7 @@ class MPLFECompilerComponent { } uint32 GetFunctionsSize() const { - return static_cast(functions.size()); + return funcSize; } const std::set &GetCompileFailedFEFunctions() const { @@ -120,12 +116,11 @@ class MPLFECompilerComponent { protected: virtual bool ParseInputImpl() = 0; - virtual bool LoadOnDemandTypeImpl() = 0; - virtual bool PreProcessDeclImpl() = 0; - virtual bool ProcessDeclImpl() = 0; + virtual bool LoadOnDemandTypeImpl(); + virtual bool PreProcessDeclImpl(); + virtual bool ProcessDeclImpl(); virtual void ProcessPragmaImpl() = 0; - virtual bool PreProcessWithoutFunctionImpl() = 0; - virtual bool PreProcessWithFunctionImpl() = 0; + virtual std::unique_ptr CreatFEFunctionImpl(FEInputMethodHelper *methodHelper) = 0; virtual bool ProcessFunctionSerialImpl(); virtual bool ProcessFunctionParallelImpl(uint32 nthreads); virtual std::string GetComponentNameImpl() const; @@ -133,12 +128,14 @@ class MPLFECompilerComponent { virtual void DumpPhaseTimeTotalImpl() const; virtual void ReleaseMemPoolImpl() = 0; + uint32 funcSize; MIRModule &module; MIRSrcLang srcLang; std::list> fieldHelpers; std::list> methodHelpers; std::list structHelpers; - std::list> functions; + std::list globalFuncHelpers; + std::list globalVarHelpers; std::unique_ptr phaseResultTotal; std::set compileFailedFEFunctions; }; diff --git a/src/mplfe/common/include/mplfe_env.h b/src/mplfe/common/include/mplfe_env.h index 843393b0e2bed68349d4277b829c863363c66c38..15787f44a8c70ce977ec20501b9ae5227d3891b0 100644 --- a/src/mplfe/common/include/mplfe_env.h +++ b/src/mplfe/common/include/mplfe_env.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/mplfe_options.h b/src/mplfe/common/include/mplfe_options.h index fcd727c2efddf0a8d737152a111e9d8ad5ae6d38..9dbff6ae9b6920392277369d7deb2f5b92aaed91 100644 --- a/src/mplfe/common/include/mplfe_options.h +++ b/src/mplfe/common/include/mplfe_options.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -56,6 +56,9 @@ class MPLFEOptions : public maple::MapleDriverOptionBase { bool ProcessInClass(const mapleOption::Option &opt); bool ProcessInJar(const mapleOption::Option &opt); bool ProcessInDex(const mapleOption::Option &opt); +#ifdef ENABLE_MPLFE_AST + bool ProcessInAST(const mapleOption::Option &opt); +#endif // ~/ENABLE_MPLFE_AST bool ProcessInputMplt(const mapleOption::Option &opt); bool ProcessInputMpltFromSys(const mapleOption::Option &opt); bool ProcessInputMpltFromApk(const mapleOption::Option &opt); @@ -86,6 +89,10 @@ class MPLFEOptions : public maple::MapleDriverOptionBase { bool ProcessDumpJBCFuncName(const mapleOption::Option &opt); bool ProcessEmitJBCLocalVarInfo(const mapleOption::Option &opt); + // bc compiler options + bool ProcessRC(const mapleOption::Option &opt); + bool ProcessNoBarrier(const mapleOption::Option &opt); + // general stmt/bb/cfg debug options bool ProcessDumpGeneralCFGGraph(const mapleOption::Option &opt); @@ -105,4 +112,4 @@ class MPLFEOptions : public maple::MapleDriverOptionBase { bool ProcessAOT(const mapleOption::Option &opt); }; // class MPLFEOptions } // namespace maple -#endif // MPLFE_INCLUDE_COMMON_MPLFE_OPTIONS_H \ No newline at end of file +#endif // MPLFE_INCLUDE_COMMON_MPLFE_OPTIONS_H diff --git a/src/mplfe/common/include/simple_xml.h b/src/mplfe/common/include/simple_xml.h index bd28ee29e344f697ad1ea22807fa31595a7a6375..48c36779d094443380fe8d2074bfebbe42aacda5 100644 --- a/src/mplfe/common/include/simple_xml.h +++ b/src/mplfe/common/include/simple_xml.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/include/simple_zip.h b/src/mplfe/common/include/simple_zip.h index 310182611dd89e303029097b3875b0b2153ad368..a5f5b01bb6ce74220db6e4ec12ebf6a1839bc813 100644 --- a/src/mplfe/common/include/simple_zip.h +++ b/src/mplfe/common/include/simple_zip.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/src/base64.cpp b/src/mplfe/common/src/base64.cpp index 4e1121f9a02e940e2e40eda3888ee01f30ffac1f..c84a071692028eecac0e6f5bcc8f0ab3512a8edd 100644 --- a/src/mplfe/common/src/base64.cpp +++ b/src/mplfe/common/src/base64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/src/basic_io.cpp b/src/mplfe/common/src/basic_io.cpp index cc0dcda8f1b1089606a53fdc62f74aa0c8cd83da..8701b9e20a6e5bfae9ef1cf34d33d1ab583ad0ca 100644 --- a/src/mplfe/common/src/basic_io.cpp +++ b/src/mplfe/common/src/basic_io.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/src/fe_config_parallel.cpp b/src/mplfe/common/src/fe_config_parallel.cpp index 6cbc33b787874000947e8c34812ba29b86406e3f..889adda306f987ab124843def932a89249401633 100644 --- a/src/mplfe/common/src/fe_config_parallel.cpp +++ b/src/mplfe/common/src/fe_config_parallel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/src/fe_file_ops.cpp b/src/mplfe/common/src/fe_file_ops.cpp index db72d82264b61cab5a60bf13b4606b6dea31df12..067071980a47957c9928fa98b35f550dc32b4a11 100644 --- a/src/mplfe/common/src/fe_file_ops.cpp +++ b/src/mplfe/common/src/fe_file_ops.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/src/fe_file_type.cpp b/src/mplfe/common/src/fe_file_type.cpp index e079ff515d12dc41e93a7629a04c855f92440feb..a7236411a0b29e6ed09f734a259ed344a9323312 100644 --- a/src/mplfe/common/src/fe_file_type.cpp +++ b/src/mplfe/common/src/fe_file_type.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -88,6 +88,11 @@ void FEFileType::LoadDefault() { RegisterMagicNumber(kJar, kMagicZip); RegisterExtName(kDex, "dex"); RegisterMagicNumber(kDex, kMagicDex); +#ifdef ENABLE_MPLFE_AST + RegisterExtName(kAST, "ast"); + RegisterMagicNumber(kAST, kMagicAST); +#endif // ~/ENABLE_MPLFE_AST + } void FEFileType::RegisterExtName(FileType argFileType, const std::string &extName) { @@ -145,4 +150,4 @@ std::string FEFileType::GetExtName(const std::string &pathName) { return ""; } } -} // namespace maple \ No newline at end of file +} // namespace maple diff --git a/src/mplfe/common/src/fe_function.cpp b/src/mplfe/common/src/fe_function.cpp index 806f460e207f228518daed6c6d272b8f6f7b2f4a..a37df5b9f9a1136f16af0757953e50a0569e0949 100644 --- a/src/mplfe/common/src/fe_function.cpp +++ b/src/mplfe/common/src/fe_function.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -429,7 +429,11 @@ bool FEFunction::UpdateFormal(const std::string &phaseName) { for (const std::unique_ptr &argVar : argVarList) { MIRSymbol *sym = argVar->GenerateMIRSymbol(FEManager::GetMIRBuilder()); sym->SetStorageClass(kScFormal); +#ifndef USE_OPS + mirFunction.AddFormal(sym); +#else mirFunction.AddArgument(sym); +#endif idx++; } return phaseResult.Finish(); @@ -622,9 +626,7 @@ bool FEFunction::UpdateRegNum2This(const std::string &phaseName) { } const std::unique_ptr &firstArg = argVarList.front(); std::unique_ptr varReg = firstArg->Clone(); - GStrIdx thisNameIdx = GlobalTables::GetStrTable().GetStrIdxFromName("_this"); - uint32 nameIdx = static_cast(thisNameIdx); - CHECK_FATAL((nameIdx != 0), "StringIndex for \"_this\" should has been created before this phase"); + GStrIdx thisNameIdx = FEUtils::GetThisIdx(); std::unique_ptr varThisAsParam = std::make_unique(thisNameIdx, varReg->GetType()->Clone()); if (!IsNative()) { std::unique_ptr varThisAsLocalVar = std::make_unique(thisNameIdx, varReg->GetType()->Clone()); @@ -1180,11 +1182,61 @@ FEIRStmt &FEFunction::GetStmtByDefVarTypeScatter(const FEIRVarTypeScatter &varTy return *(it->second); } +bool FEFunction::WithFinalFieldsNeedBarrier(MIRClassType *classType, bool isStatic) const { + // final field + if (isStatic) { + // final static fields with non-primitive types + // the one with primitive types are all inlined + for (auto it : classType->GetStaticFields()) { + MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(it.second.first); + if (it.second.second.GetAttr(FLDATTR_final) && type->GetPrimType() == PTY_ref) { + return true; + } + } + } else { + for (auto it : classType->GetFields()) { + if (it.second.second.GetAttr(FLDATTR_final)) { + return true; + } + } + } + return false; +} + +bool FEFunction::IsNeedInsertBarrier() { + if (mirFunction.GetAttr(FUNCATTR_constructor) || + mirFunction.GetName().find("_7Cclone_7C") != std::string::npos || + mirFunction.GetName().find("_7CcopyOf_7C") != std::string::npos) { + const std::string &className = mirFunction.GetBaseClassName(); + MIRType *type = FEManager::GetTypeManager().GetClassOrInterfaceType(className); + if (type->GetKind() == kTypeClass) { + MIRClassType *currClass = static_cast(type); + if (!mirFunction.GetAttr(FUNCATTR_constructor) || + WithFinalFieldsNeedBarrier(currClass, mirFunction.GetAttr(FUNCATTR_static))) { + return true; + } + } + } + return false; +} + void FEFunction::EmitToMIRStmt() { + bool isNeedBarrier = false; + bool isWithReturn = false; + if (!FEOptions::GetInstance().IsNoBarrier()) { + isNeedBarrier = false; // Do not insert it here. + } FELinkListNode *nodeStmt = feirStmtHead->GetNext(); while (nodeStmt != nullptr && nodeStmt != feirStmtTail) { FEIRStmt *stmt = static_cast(nodeStmt); std::list mirStmts = stmt->GenMIRStmts(FEManager::GetMIRBuilder()); + if (isNeedBarrier && stmt->GetKind() == kStmtReturn) { + isWithReturn = true; + StmtNode *barrier = mirFunction.GetAttr(FUNCATTR_constructor) ? + mirFunction.GetCodeMempool()->New(OP_membarrelease) : + mirFunction.GetCodeMempool()->New(OP_membarstorestore); + mirStmts.emplace_front(barrier); + } #ifdef DEBUG // LOC info has been recorded in FEIRStmt already, this could be removed later. AddLocForStmt(*stmt, mirStmts); @@ -1194,6 +1246,12 @@ void FEFunction::EmitToMIRStmt() { } nodeStmt = nodeStmt->GetNext(); } + if (isNeedBarrier && !isWithReturn) { + StmtNode *barrier = mirFunction.GetAttr(FUNCATTR_constructor) ? + mirFunction.GetCodeMempool()->New(OP_membarrelease) : + mirFunction.GetCodeMempool()->New(OP_membarstorestore); + FEManager::GetMIRBuilder().AddStmtInCurrentFunctionBody(*barrier); + } } void FEFunction::AddLocForStmt(const FEIRStmt &stmt, std::list &mirStmts) const { diff --git a/src/mplfe/common/src/fe_function_phase_result.cpp b/src/mplfe/common/src/fe_function_phase_result.cpp index 8c9596acba2094643151cca694d486e2b3fd381a..bb11b77f15f6cc0680034cc8c9dbb687980990bb 100644 --- a/src/mplfe/common/src/fe_function_phase_result.cpp +++ b/src/mplfe/common/src/fe_function_phase_result.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/src/fe_input_helper.cpp b/src/mplfe/common/src/fe_input_helper.cpp index 943ec2f3f0f06fca53e1585d310981406f2614dc..14efdc015d5d40eaf495f5941c7c535b280e298c 100644 --- a/src/mplfe/common/src/fe_input_helper.cpp +++ b/src/mplfe/common/src/fe_input_helper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -53,26 +53,21 @@ bool FEInputStructHelper::ProcessDeclImpl() { return false; } if (!FEOptions::GetInstance().IsGenMpltOnly() && !isOnDemandLoad) { - // Create Symbol CreateSymbol(); } - // Process SuperClass ProcessDeclSuperClass(); - // Process Interface ProcessDeclImplements(); - // Process Info ProcessDeclDefInfo(); // Process Fields InitFieldHelpers(); ProcessFieldDef(); + ProcessExtraFields(); if (!FEOptions::GetInstance().IsGenMpltOnly() && !isOnDemandLoad) { ProcessStaticFields(); } // Process Methods InitMethodHelpers(); ProcessMethodDef(); - // Process Pragma - // Process File Name return true; } @@ -95,9 +90,7 @@ void FEInputStructHelper::CreateSymbol() { } void FEInputStructHelper::ProcessDeclSuperClass() { - if (srcLang == kSrcLangJava) { - ProcessDeclSuperClassForJava(); - } + ProcessDeclSuperClassForJava(); } void FEInputStructHelper::ProcessDeclSuperClassForJava() { @@ -187,12 +180,10 @@ void FEInputStructHelper::ProcessDeclDefInfo() { std::string classNameOrig = GetStructNameOrin(); GStrIdx classNameOrigIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(classNameOrig); SET_CLASS_INFO_PAIR(mirStructType, "INFO_classnameorig", classNameOrigIdx.GetIdx(), true); - // INFO_superclassname if (srcLang == kSrcLangJava) { + // INFO_superclassname ProcessDeclDefInfoSuperNameForJava(); - } - // INFO_implements - if (srcLang == kSrcLangJava) { + // INFO_implements ProcessDeclDefInfoImplementNameForJava(); } // INFO_attribute_string @@ -202,6 +193,8 @@ void FEInputStructHelper::ProcessDeclDefInfo() { SET_CLASS_INFO_PAIR(mirStructType, "INFO_attribute_string", attrsNameIdx.GetIdx(), true); // INFO_access_flags SET_CLASS_INFO_PAIR(mirStructType, "INFO_access_flags", GetRawAccessFlags(), false); + // INFO_ir_srcfile_signature + SET_CLASS_INFO_PAIR(mirStructType, "INFO_ir_srcfile_signature", GetIRSrcFileSigIdx(), true); } void FEInputStructHelper::ProcessDeclDefInfoSuperNameForJava() { @@ -233,13 +226,17 @@ void FEInputStructHelper::ProcessDeclDefInfoImplementNameForJava() { void FEInputStructHelper::ProcessStaticFields() { uint32 i = 0; - uint32 stringIDCount = 0; FieldVector::iterator it; for (it = mirStructType->GetStaticFields().begin(); it != mirStructType->GetStaticFields().end(); ++i, ++it) { +#ifndef USE_OPS + StIdx stIdx = SymbolBuilder::Instance().GetStIdxFromStrIdx(it->first); +#else StIdx stIdx = GlobalTables::GetGsymTable().GetStIdxFromStrIdx(it->first); +#endif const std::string &fieldName = GlobalTables::GetStrTable().GetStringFromStrIdx(it->first); MIRConst *cst = nullptr; MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(it->second.first); + MapleAllocator &alloc = FEManager::GetModule().GetMPAllocator(); if (i < staticFieldsConstVal.size()) { cst = staticFieldsConstVal[i]; if (cst != nullptr && cst->GetKind() == kConstStr16Const) { @@ -249,19 +246,17 @@ void FEInputStructHelper::ProcessStaticFields() { if (literalVar == nullptr) { literalVar = FEManager::GetJavaStringManager().CreateLiteralVar(FEManager::GetMIRBuilder(), str16, true); } - if (!FEOptions::GetInstance().IsAOT()) { - AddrofNode *expr = FEManager::GetMIRBuilder().CreateExprAddrof(0, *literalVar, + AddrofNode *expr = FEManager::GetMIRBuilder().CreateExprAddrof(0, *literalVar, FEManager::GetModule().GetMemPool()); - MIRType *ptrType = GlobalTables::GetTypeTable().GetTypeTable()[PTY_ptr]; - // Judge null pointer is not required. - cst = new(std::nothrow) MIRAddrofConst(expr->GetStIdx(), expr->GetFieldID(), *ptrType); - } else { - uint32 stringID = finalStaticStringID[stringIDCount++]; - cst = new(std::nothrow) MIRIntConst(stringID, *GlobalTables::GetTypeTable().GetInt64()); - } + MIRType *ptrType = GlobalTables::GetTypeTable().GetTypeTable()[PTY_ptr]; + cst = alloc.GetMemPool()->New(expr->GetStIdx(), expr->GetFieldID(), *ptrType); } } +#ifndef USE_OPS + MIRSymbol *fieldVar = SymbolBuilder::Instance().GetSymbolFromStIdx(stIdx.Idx()); +#else MIRSymbol *fieldVar = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx()); +#endif if (fieldVar == nullptr) { fieldVar = FEManager::GetMIRBuilder().GetOrCreateGlobalDecl(fieldName, *type); fieldVar->SetAttrs(it->second.second.ConvertToTypeAttrs()); @@ -287,6 +282,38 @@ void FEInputStructHelper::ProcessFieldDef() { } } +void FEInputStructHelper::ProcessExtraFields() { + // add to this set to add extrafield into a class, in this format: classname, fieldname, type, attributes + std::vector extraFields = { + { "Lcom_2Fandroid_2Finternal_2Fos_2FBinderCallsStats_3B", "mCallSessionsPoolSize", "i32", "private" }, + { "Ljava_2Flang_2FObject_3B", "shadow_24__klass__", "Ljava_2Flang_2FClass_3B", "private transient final" }, + }; + for (auto it = extraFields.begin(); it != extraFields.end(); ++it) { + bool isCreat = false; + MIRStructType *structType = FEManager::GetTypeManager().GetOrCreateClassOrInterfaceType(it->klass, + false, FETypeFlag::kSrcUnknown, isCreat); + if (structType->IsImported()) { + continue; + } + GStrIdx fieldStrIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(it->field); + MIRType *fieldType = FEManager::GetTypeManager().GetOrCreateTypeFromName(it->type, FETypeFlag::kSrcUnknown, true); + std::vector attrs = FEUtils::Split(it->attr, ' '); + FieldAttrs typeAttrs; + for (auto ait = attrs.begin(); ait != attrs.end(); ++ait) { + FEInputFieldHelper::SetFieldAttribute(*ait, typeAttrs); + } + for (auto fit = structType->GetFields().begin(); fit != structType->GetFields().end(); ++fit) { + if (fit->first == fieldStrIdx) { + (void)structType->GetFields().erase(fit); + break; + } + } + // insert at the beginning + structType->GetFields().insert(structType->GetFields().begin(), + FieldPair(fieldStrIdx, TyIdxFieldAttrPair(fieldType->GetTypeIndex(), typeAttrs))); + } +} + void FEInputStructHelper::ProcessMethodDef() { for (FEInputMethodHelper *methodHelper : methodHelpers) { bool success = methodHelper->ProcessDecl(allocator); @@ -312,39 +339,7 @@ void FEInputStructHelper::ProcessPragma() { // ---------- FEInputMethodHelper ---------- bool FEInputMethodHelper::ProcessDeclImpl(MapleAllocator &allocator) { - MPLFE_PARALLEL_FORBIDDEN(); - ASSERT(srcLang != kSrcLangUnknown, "src lang not set"); - std::string methodShortName = GetMethodName(false, false); - std::string methodName = GetMethodName(true); - CHECK_FATAL(!methodName.empty(), "error: method name is empty"); - if (methodShortName.compare("main") == 0) { - FEManager::GetMIRBuilder().GetMirModule().SetEntryFuncName(methodName); - } - methodNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(methodName); - SolveReturnAndArgTypes(allocator); - FuncAttrs attrs = GetAttrs(); - bool isStatic = IsStatic(); - bool isVarg = IsVarg(); - CHECK_FATAL(retType != nullptr, "function must have return type"); - MIRType *mirReturnType = nullptr; - bool usePtr = (srcLang == kSrcLangJava); - if (retType->GetPrimType() == PTY_void) { - mirReturnType = retType->GenerateMIRType(srcLang, false); - } else { - mirReturnType = retType->GenerateMIRType(srcLang, usePtr); - } - ASSERT(mirReturnType != nullptr, "return type is nullptr"); - std::vector argsTypeIdx; - for (FEIRType *type : argTypes) { - MIRType *argType = type->GenerateMIRType(srcLang, usePtr); - argsTypeIdx.push_back(argType->GetTypeIndex()); - } - mirFunc = FEManager::GetTypeManager().CreateFunction(methodNameIdx, mirReturnType->GetTypeIndex(), - argsTypeIdx, isVarg, isStatic); - mirMethodPair.first = mirFunc->GetStIdx(); - mirMethodPair.second.first = mirFunc->GetMIRFuncType()->GetTypeIndex(); - mirMethodPair.second.second = attrs; - mirFunc->SetFuncAttrs(attrs); + CHECK_FATAL(false, "NYI"); return true; } diff --git a/src/mplfe/common/src/fe_java_string_manager.cpp b/src/mplfe/common/src/fe_java_string_manager.cpp index 298ca572344c064b37bc090cfd5335af539c123e..0f802342fde563a6a56f156959c66268b0114f91 100644 --- a/src/mplfe/common/src/fe_java_string_manager.cpp +++ b/src/mplfe/common/src/fe_java_string_manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -140,13 +140,15 @@ std::string FEJavaStringManager::GetLiteralGlobalName(const std::u16string &strU return literalGlobalName; } +// Valid ASCII characters are in range 1..0x7f. Zero is not considered ASCII +// because it would complicate the detection of ASCII strings in Modified-UTF8. bool FEJavaStringManager::IsAllASCII(const std::u16string &strU16) { if (strU16.length() == 0) { return false; } for (size_t i = 0; i < strU16.length(); ++i) { uint16 val = ExchangeBytesPosition(strU16[i]); - if (val >= CHAR_MAX) { + if ((val - 1u) >= 0x7fu) { return false; } } diff --git a/src/mplfe/common/src/fe_manager.cpp b/src/mplfe/common/src/fe_manager.cpp index 19ae6ed518e75e8059974d805cc994677c5dd93a..dec5dc361dbcbdc89049cedbbd6ed27228549345 100644 --- a/src/mplfe/common/src/fe_manager.cpp +++ b/src/mplfe/common/src/fe_manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/src/fe_options.cpp b/src/mplfe/common/src/fe_options.cpp index 1928b47f10ad2aa15f00097ddb2ce3c6a1e9dac9..eeb17ce6032459d9587f46c441544dacb2f7c8ac 100644 --- a/src/mplfe/common/src/fe_options.cpp +++ b/src/mplfe/common/src/fe_options.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -53,4 +53,14 @@ void FEOptions::AddInputDexFile(const std::string &fileName) { } } -} // namespace maple \ No newline at end of file +#ifdef ENABLE_MPLFE_AST +void FEOptions::AddInputASTFile(const std::string &fileName) { + FEFileType::FileType type = FEFileType::GetInstance().GetFileTypeByMagicNumber(fileName); + if (type == FEFileType::FileType::kAST) { + inputASTFiles.push_back(fileName); + } else { + WARN(kLncWarn, "invalid input AST file %s...skipped", fileName.c_str()); + } +} +#endif // ~/ENABLE_MPLFE_AST +} // namespace maple diff --git a/src/mplfe/common/src/fe_struct_elem_info.cpp b/src/mplfe/common/src/fe_struct_elem_info.cpp index 2565ac28f0d6833d7feee62725c82682b6279b8f..a1f92e259c1ccd9bda83a75c22ab5f9025934e66 100644 --- a/src/mplfe/common/src/fe_struct_elem_info.cpp +++ b/src/mplfe/common/src/fe_struct_elem_info.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -26,29 +26,32 @@ namespace maple { // ---------- FEStructElemInfo ---------- -FEStructElemInfo::FEStructElemInfo(const StructElemNameIdx &argStructElemNameIdx, +FEStructElemInfo::FEStructElemInfo(MapleAllocator &allocatorIn, const StructElemNameIdx &argStructElemNameIdx, MIRSrcLang argSrcLang, bool argIsStatic) - : structElemNameIdx(argStructElemNameIdx), - srcLang(argSrcLang), - isStatic(argIsStatic), + : isStatic(argIsStatic), isMethod(false), isDefined(false), isFromDex(false), - isPrepared(false) { + isPrepared(false), + srcLang(argSrcLang), + allocator(allocatorIn), + structElemNameIdx(argStructElemNameIdx), + actualContainer(allocator.GetMemPool()) { } UniqueFEIRType FEStructElemInfo::GetActualContainerType() const { // Invokable after prepared - return FEIRBuilder::CreateTypeByJavaName(actualContainer, true); + return FEIRBuilder::CreateTypeByJavaName(actualContainer.c_str(), true); } // ---------- FEStructFieldInfo ---------- -FEStructFieldInfo::FEStructFieldInfo(const StructElemNameIdx &argStructElemNameIdx, +FEStructFieldInfo::FEStructFieldInfo(MapleAllocator &allocatorIn, const StructElemNameIdx &argStructElemNameIdx, MIRSrcLang argSrcLang, bool argIsStatic) - : FEStructElemInfo(argStructElemNameIdx, argSrcLang, argIsStatic), + : FEStructElemInfo(allocatorIn, argStructElemNameIdx, argSrcLang, argIsStatic), fieldType(nullptr), fieldNameIdx(0), - fieldID(0) { + fieldID(0), + isVolatile(false) { isMethod = false; LoadFieldType(); } @@ -59,9 +62,10 @@ void FEStructFieldInfo::PrepareImpl(MIRBuilder &mirBuilder, bool argIsStatic) { } // Prepare actualContainer = GetStructName(); - std::string rawName = actualContainer + namemangler::kNameSplitterStr + GetElemName(); + const std::string stdActualContainer = actualContainer.c_str(); + std::string rawName = stdActualContainer + namemangler::kNameSplitterStr + GetElemName(); fieldNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(rawName); - MIRStructType *structType = FEManager::GetTypeManager().GetStructTypeFromName(actualContainer); + MIRStructType *structType = FEManager::GetTypeManager().GetStructTypeFromName(stdActualContainer); if (structType == nullptr) { isDefined = false; isPrepared = true; @@ -83,6 +87,9 @@ void FEStructFieldInfo::LoadFieldType() { case kSrcLangJava: LoadFieldTypeJava(); break; + case kSrcLangC: + WARN(kLncWarn, "kSrcLangC LoadFieldType NYI"); + break; default: WARN(kLncWarn, "unsupported language"); break; @@ -90,8 +97,8 @@ void FEStructFieldInfo::LoadFieldType() { } void FEStructFieldInfo::LoadFieldTypeJava() { - fieldType = std::make_unique(PTY_unknown); - static_cast(fieldType.get())->LoadFromJavaTypeName(GetSignatureName(), true); + fieldType = allocator.GetMemPool()->New(PTY_unknown); + static_cast(fieldType)->LoadFromJavaTypeName(GetSignatureName(), true); } void FEStructFieldInfo::PrepareStaticField(const MIRStructType &structType) { @@ -147,6 +154,7 @@ bool FEStructFieldInfo::SearchStructFieldJava(MIRStructType &structType, MIRBuil } else { PrepareNonStaticField(mirBuilder); } + isVolatile = fieldPair.second.second.GetAttr(FLDATTR_volatile); return true; } } @@ -201,34 +209,23 @@ bool FEStructFieldInfo::CompareFieldType(const FieldPair &fieldPair) const { } // ---------- FEStructMethodInfo ---------- -std::map> FEStructMethodInfo::javaPolymorphicWhiteList; - -FEStructMethodInfo::FEStructMethodInfo(const StructElemNameIdx &argStructElemNameIdx, +FEStructMethodInfo::FEStructMethodInfo(MapleAllocator &allocatorIn, const StructElemNameIdx &argStructElemNameIdx, MIRSrcLang argSrcLang, bool argIsStatic) - : FEStructElemInfo(argStructElemNameIdx, argSrcLang, argIsStatic), - methodNameIdx(argStructElemNameIdx.full), - mirFunc(nullptr), + : FEStructElemInfo(allocatorIn, argStructElemNameIdx, argSrcLang, argIsStatic), isReturnVoid(false), isJavaPolymorphicCall(false), - isJavaDynamicCall(false) { + isJavaDynamicCall(false), + methodNameIdx(argStructElemNameIdx.full), + mirFunc(nullptr), + argTypes(allocator.Adapter()) { isMethod = true; LoadMethodType(); } FEStructMethodInfo::~FEStructMethodInfo() { mirFunc = nullptr; -} - -void FEStructMethodInfo::InitJavaPolymorphicWhiteList() { - MPLFE_PARALLEL_FORBIDDEN(); - std::map> &ans = javaPolymorphicWhiteList; - StringTable &strTable = GlobalTables::GetStrTable(); - GStrIdx idxMethodHandle = bc::BCUtil::GetJavaMethodHandleNameMplIdx(); - bool success = true; - success = success && ans[idxMethodHandle].insert(strTable.GetOrCreateStrIdxFromName("invoke")).second; - success = success && ans[idxMethodHandle].insert(strTable.GetOrCreateStrIdxFromName("invokeBasic")).second; - success = success && ans[idxMethodHandle].insert(strTable.GetOrCreateStrIdxFromName("invokeExact")).second; - CHECK_FATAL(success, "error occurs"); + retType = nullptr; + ownerType = nullptr; } PUIdx FEStructMethodInfo::GetPuIdx() const { @@ -244,6 +241,8 @@ void FEStructMethodInfo::PrepareImpl(MIRBuilder &mirBuilder, bool argIsStatic) { case kSrcLangJava: PrepareImplJava(mirBuilder, argIsStatic); break; + case kSrcLangC: + break; default: CHECK_FATAL(false, "unsupported src lang"); } @@ -257,7 +256,7 @@ void FEStructMethodInfo::PrepareImplJava(MIRBuilder &mirBuilder, bool argIsStati if (!actualContainer.empty() && actualContainer[0] == 'A') { structType = FEManager::GetTypeManager().GetStructTypeFromName("Ljava_2Flang_2FObject_3B"); } else { - structType = FEManager::GetTypeManager().GetStructTypeFromName(actualContainer); + structType = FEManager::GetTypeManager().GetStructTypeFromName(actualContainer.c_str()); } isStatic = argIsStatic; isDefined = false; @@ -281,6 +280,8 @@ void FEStructMethodInfo::LoadMethodType() { case kSrcLangJava: LoadMethodTypeJava(); break; + case kSrcLangC: + break; default: WARN(kLncWarn, "unsupported language"); break; @@ -296,21 +297,21 @@ void FEStructMethodInfo::LoadMethodTypeJava() { const std::string &funcName = GetElemName(); isConstructor = (funcName.find("init_28") == 0); // return type - retType = std::make_unique(PTY_unknown); + retType = allocator.GetMemPool()->New(PTY_unknown); if (typeNames[0].compare("V") == 0) { isReturnVoid = true; } - static_cast(retType.get())->LoadFromJavaTypeName(typeNames[0], false); + static_cast(retType)->LoadFromJavaTypeName(typeNames[0], false); // argument types argTypes.clear(); for (size_t i = 1; i < typeNames.size(); i++) { - UniqueFEIRType argType = std::make_unique(PTY_unknown); - static_cast(argType.get())->LoadFromJavaTypeName(typeNames[i], false); - argTypes.push_back(std::move(argType)); + FEIRType *argType = allocator.GetMemPool()->New(PTY_unknown); + static_cast(argType)->LoadFromJavaTypeName(typeNames[i], false); + argTypes.push_back(argType); } // owner type - ownerType = std::make_unique(PTY_unknown); - static_cast(ownerType.get())->LoadFromJavaTypeName(GetStructName(), true); + ownerType = allocator.GetMemPool()->New(PTY_unknown); + static_cast(ownerType)->LoadFromJavaTypeName(GetStructName(), true); } void FEStructMethodInfo::PrepareMethod() { @@ -321,13 +322,12 @@ void FEStructMethodInfo::PrepareMethod() { std::vector> argVarList; std::vector argsTypeIdx; if (!isStatic) { - GStrIdx nameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName("_this"); - UniqueFEIRVar regVar = std::make_unique(nameIdx, ownerType->Clone(), false); + UniqueFEIRVar regVar = std::make_unique(FEUtils::GetThisIdx(), ownerType->Clone(), false); argVarList.emplace_back(std::move(regVar)); argsTypeIdx.emplace_back(ownerType->GenerateMIRType(srcLang, true)->GetTypeIndex()); } uint8 regNum = 1; - for (const UniqueFEIRType &argType : argTypes) { + for (const FEIRType *argType : argTypes) { UniqueFEIRVar regVar = FEIRBuilder::CreateVarReg(regNum, argType->Clone(), false); ++regNum; argVarList.emplace_back(std::move(regVar)); @@ -341,9 +341,15 @@ void FEStructMethodInfo::PrepareMethod() { for (const std::unique_ptr &argVar : argVarList) { MIRType *mirTy = argVar->GetType()->GenerateMIRTypeAuto(); std::string name = argVar->GetName(*mirTy); +#ifndef USE_OPS + MIRSymbol *sym = SymbolBuilder::Instance().GetOrCreateLocalSymbol(*mirTy, name, *mirFunc); + sym->SetStorageClass(kScFormal); + mirFunc->AddFormal(sym); +#else MIRSymbol *sym = FEManager::GetMIRBuilder().GetOrCreateDeclInFunc(name, *mirTy, *mirFunc); sym->SetStorageClass(kScFormal); mirFunc->AddArgument(sym); +#endif } } isPrepared = true; @@ -358,23 +364,22 @@ bool FEStructMethodInfo::SearchStructMethodJava(MIRStructType &structType, MIRBu std::string fullName = structType.GetCompactMplTypeName() + namemangler::kNameSplitterStr + GetElemName() + namemangler::kNameSplitterStr + GetSignatureName(); GStrIdx nameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName); - // PolymorphicCall Check - if (CheckJavaPolymorphicCall()) { - isJavaPolymorphicCall = true; - methodNameIdx = nameIdx; - PrepareMethod(); - return true; - } for (const MethodPair &methodPair : structType.GetMethods()) { - const MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(methodPair.first.Idx(), true); - CHECK_NULL_FATAL(sym); if (methodPair.second.second.GetAttr(FUNCATTR_private) && !allowPrivate) { continue; } if (methodPair.second.second.GetAttr(FUNCATTR_static) != argIsStatic) { continue; } +#ifndef USE_OPS + const MIRFunction *func = methodPair.first; + CHECK_NULL_FATAL(func); + if (func->GetNameStrIdx() == nameIdx) { +#else + const MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(methodPair.first.Idx(), true); + CHECK_NULL_FATAL(sym); if (sym->GetNameStrIdx() == nameIdx) { +#endif isStatic = argIsStatic; if (isStatic) { methodNameIdx = nameIdx; @@ -427,12 +432,4 @@ bool FEStructMethodInfo::SearchStructMethodJava(const TyIdx &tyIdx, MIRBuilder & return false; } } - -bool FEStructMethodInfo::CheckJavaPolymorphicCall() const { - auto it = javaPolymorphicWhiteList.find(structElemNameIdx.klass); - if (it == javaPolymorphicWhiteList.end()) { - return false; - } - return it->second.find(structElemNameIdx.elem) != it->second.end(); -} } // namespace maple diff --git a/src/mplfe/common/src/fe_timer_ns.cpp b/src/mplfe/common/src/fe_timer_ns.cpp index d592831ae1c7563d763fe15ed25618c5f26a29ec..6efff93a79b1ea5ef48cf0b21b4f758660d119eb 100644 --- a/src/mplfe/common/src/fe_timer_ns.cpp +++ b/src/mplfe/common/src/fe_timer_ns.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/src/fe_type_hierarchy.cpp b/src/mplfe/common/src/fe_type_hierarchy.cpp index c0be7113619d28c9c0aa5fc99cef69a7590b4648..c1ba9253cceee4e6fbaccd8aae709912b33b1df4 100644 --- a/src/mplfe/common/src/fe_type_hierarchy.cpp +++ b/src/mplfe/common/src/fe_type_hierarchy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/src/fe_type_manager.cpp b/src/mplfe/common/src/fe_type_manager.cpp index 2ecd786738f7a7b653e809f51ef08ca84db77b58..ee11e5b7d0123c1d8130c866396eaee940f9d100 100644 --- a/src/mplfe/common/src/fe_type_manager.cpp +++ b/src/mplfe/common/src/fe_type_manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -22,6 +22,7 @@ #include "fe_config_parallel.h" #include "feir_type_helper.h" #include "fe_macros.h" +#include "types_def.h" namespace maple { const UniqueFEIRType FETypeManager::kPrimFEIRTypeUnknown = std::make_unique(PTY_unknown); @@ -42,7 +43,7 @@ const UniqueFEIRType FETypeManager::kFEIRTypeJavaString = std::make_uniqueGetSKind() == kStFunc) { CHECK_FATAL(symbol->GetFunction(), "Function in symbol is null"); @@ -187,6 +193,31 @@ void FETypeManager::CheckSameNamePolicy() const { } } +MIRStructType *FETypeManager::CreateStructType(const std::string &name) { + MIRStructType type(kTypeStruct); + GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name); + TyIdx tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&type); + module.GetTypeNameTab()->SetGStrIdxToTyIdx(strIdx, tyIdx); + if (GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx.GetIdx())->GetNameStrIdx() == 0) { + GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx.GetIdx())->SetNameStrIdx(strIdx); + } + auto *structType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx.GetIdx())); + structNameTypeMap[strIdx] = std::make_pair(structType, FETypeFlag::kSrcInput); + return structType; +} + +MIRStructType *FETypeManager::GetOrCreateStructType(const std::string &name) { + GStrIdx nameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name); + const std::unordered_map::iterator &it = structNameTypeMap.find(nameIdx); + if (it != structNameTypeMap.end()) { + return it->second.first; + } + MIRStructType *structType = CreateStructType(name); + module.PushbackTypeDefOrder(nameIdx); + CHECK_NULL_FATAL(structType); + return structType; +} + MIRStructType *FETypeManager::GetClassOrInterfaceType(const GStrIdx &nameIdx) const { auto it = structNameTypeMap.find(nameIdx); if (it == structNameTypeMap.end()) { @@ -298,10 +329,15 @@ MIRStructType *FETypeManager::GetStructTypeFromName(const GStrIdx &nameIdx) { } } -uint32 FETypeManager::GetTypeIDFromMplClassName(const std::string &mplClassName) const { - auto const &it = classNameTypeIDMap.find(mplClassName); - if (it != classNameTypeIDMap.end()) { - return it->second; +uint32 FETypeManager::GetTypeIDFromMplClassName(const std::string &mplClassName, int32 dexFileHashCode) const { + auto const &itMap = classNameTypeIDMapAllDex.find(dexFileHashCode); + if (itMap != classNameTypeIDMapAllDex.end()) { + auto const &thisDexClassNameTypeIDMap = itMap->second; + auto const &it = thisDexClassNameTypeIDMap.find(mplClassName); + if (it != thisDexClassNameTypeIDMap.end()) { + return it->second; + } + return UINT32_MAX; } return UINT32_MAX; // some type id not in the dex file, give UINT32_MAX } @@ -357,6 +393,7 @@ MIRType *FETypeManager::GetOrCreatePointerType(const MIRType &type, PrimType pty MIRType *FETypeManager::GetOrCreateArrayType(MIRType &elemType, uint8 dim, PrimType ptyPtr) { switch (srcLang) { case kSrcLangJava: + case kSrcLangC: // Need to be optimized return GetOrCreateJArrayType(elemType, dim, ptyPtr); default: CHECK_FATAL(false, "unsupported src lang: %d", srcLang); @@ -389,7 +426,7 @@ FEStructElemInfo *FETypeManager::RegisterStructFieldInfo( if (ptrInfo != nullptr) { return ptrInfo; } - ptrInfo = mp->New(structElemNameIdx, argSrcLang, isStatic); + ptrInfo = allocator.GetMemPool()->New(allocator, structElemNameIdx, argSrcLang, isStatic); CHECK_FATAL(mapStructElemInfo.insert(std::make_pair(structElemNameIdx.full, ptrInfo)).second == true, "register struct elem info failed"); return ptrInfo; @@ -402,7 +439,7 @@ FEStructElemInfo *FETypeManager::RegisterStructMethodInfo( if (ptrInfo != nullptr) { return ptrInfo; } - ptrInfo = mp->New(structElemNameIdx, argSrcLang, isStatic); + ptrInfo = allocator.GetMemPool()->New(allocator, structElemNameIdx, argSrcLang, isStatic); CHECK_FATAL(mapStructElemInfo.insert(std::make_pair(structElemNameIdx.full, ptrInfo)).second == true, "register struct elem info failed"); return ptrInfo; @@ -443,6 +480,20 @@ MIRFunction *FETypeManager::CreateFunction(const GStrIdx &nameIdx, const TyIdx & if (mirFunc != nullptr) { return mirFunc; } +#ifndef USE_OPS + MIRSymbol *funcSymbol = SymbolBuilder::Instance().GetSymbolFromStrIdx(nameIdx); + if (funcSymbol == nullptr) { + funcSymbol = SymbolBuilder::Instance().CreateSymbol(TyIdx(), nameIdx, kStFunc, kScText); + SymbolBuilder::Instance().AddToStringSymbolMap(*funcSymbol); + } else { + mirFunc = funcSymbol->GetFunction(); + if (mirFunc != nullptr) { + return mirFunc; + } + funcSymbol->SetStorageClass(kScText); + funcSymbol->SetSKind(kStFunc); + } +#else MIRSymbol *funcSymbol = GlobalTables::GetGsymTable().CreateSymbol(kScopeGlobal); funcSymbol->SetNameStrIdx(nameIdx); bool added = GlobalTables::GetGsymTable().AddToStringSymbolMap(*funcSymbol); @@ -455,10 +506,15 @@ MIRFunction *FETypeManager::CreateFunction(const GStrIdx &nameIdx, const TyIdx & } funcSymbol->SetStorageClass(kScText); funcSymbol->SetSKind(kStFunc); +#endif MemPool *mpModule = module.GetMemPool(); ASSERT(mpModule, "mem pool is nullptr"); mirFunc = mpModule->New(&module, funcSymbol->GetStIdx()); +#ifndef USE_OPS + mirFunc->Init(); +#else mirFunc->AllocSymTab(); +#endif size_t idx = GlobalTables::GetFunctionTable().GetFuncTable().size(); CHECK_FATAL(idx < UINT32_MAX, "PUIdx is out of range"); mirFunc->SetPuidx(static_cast(idx)); @@ -469,8 +525,14 @@ MIRFunction *FETypeManager::CreateFunction(const GStrIdx &nameIdx, const TyIdx & argsAttr.emplace_back(TypeAttrs()); } mirFunc->SetBaseClassFuncNames(nameIdx); +#ifndef USE_OPS + funcSymbol->SetTyIdx(GlobalTables::GetTypeTable().GetOrCreateFunctionType(module, retTypeIdx, + argsTypeIdx, argsAttr, + isVarg)->GetTypeIndex()); +#else funcSymbol->SetTyIdx(GlobalTables::GetTypeTable().GetOrCreateFunctionType(retTypeIdx, argsTypeIdx, argsAttr, isVarg)->GetTypeIndex()); +#endif funcSymbol->SetFunction(mirFunc); MIRFuncType *functype = static_cast(funcSymbol->GetType()); mirFunc->SetMIRFuncType(functype); @@ -513,6 +575,9 @@ const FEIRType *FETypeManager::GetOrCreateFEIRTypeByName(const std::string &type case kSrcLangJava: uniType = FEIRTypeHelper::CreateTypeByJavaName(typeName, true, false); break; + case kSrcLangC: + WARN(kLncWarn, "kSrcLangC GetOrCreateFEIRTypeByName NYI"); + break; default: CHECK_FATAL(false, "unsupported language"); return nullptr; @@ -554,20 +619,18 @@ bool FETypeManager::IsStructType(const MIRType &type) { MIRTypeKind kind = type.GetKind(); return kind == kTypeStruct || kind == kTypeStructIncomplete || kind == kTypeClass || kind == kTypeClassIncomplete || - kind == kTypeInterface || kind == kTypeInterfaceIncomplete; + kind == kTypeInterface || kind == kTypeInterfaceIncomplete || + kind == kTypeUnion; } PrimType FETypeManager::GetPrimType(const std::string &name) { #define LOAD_ALGO_PRIMARY_TYPE -#define PRIMTYPE(P) - static std::unordered_map typeMap = { +#define PRIMTYPE(P) \ + if (name.compare(#P) == 0) { \ + return PTY_##P; \ + } #include "prim_types.def" - }; #undef PRIMTYPE - auto it = typeMap.find(name); - if (it != typeMap.end()) { - return it->second; - } return kPtyInvalid; } @@ -648,9 +711,8 @@ void FETypeManager::MarkExternStructType() { } void FETypeManager::InitMCCFunctions() { - InitFuncMCCGetOrInsertLiteral(); - if (FEOptions::GetInstance().IsAOT()) { - InitFuncMCCStaticField(); + if (srcLang == kSrcLangJava) { + InitFuncMCCGetOrInsertLiteral(); } } @@ -666,38 +728,6 @@ void FETypeManager::InitFuncMCCGetOrInsertLiteral() { nameMCCFuncMap[nameIdx] = funcMCCGetOrInsertLiteral; } -void FETypeManager::InitFuncMCCStaticField() { - std::map> MCCIdxFuncMap = { - { FEUtils::GetMCCStaticFieldGetBoolIdx(), std::make_pair('Z', funcMCCStaticFieldGetBool) }, - { FEUtils::GetMCCStaticFieldGetByteIdx(), std::make_pair('B', funcMCCStaticFieldGetByte) }, - { FEUtils::GetMCCStaticFieldGetShortIdx(), std::make_pair('S', funcMCCStaticFieldGetShort) }, - { FEUtils::GetMCCStaticFieldGetCharIdx(), std::make_pair('C', funcMCCStaticFieldGetChar) }, - { FEUtils::GetMCCStaticFieldGetIntIdx(), std::make_pair('I', funcMCCStaticFieldGetInt) }, - { FEUtils::GetMCCStaticFieldGetLongIdx(), std::make_pair('J', funcMCCStaticFieldGetLong) }, - { FEUtils::GetMCCStaticFieldGetFloatIdx(), std::make_pair('F', funcMCCStaticFieldGetFloat) }, - { FEUtils::GetMCCStaticFieldGetDoubleIdx(), std::make_pair('D', funcMCCStaticFieldGetDouble) }, - { FEUtils::GetMCCStaticFieldGetObjectIdx(), std::make_pair('R', funcMCCStaticFieldGetObject) }, - { FEUtils::GetMCCStaticFieldSetBoolIdx(), std::make_pair('Z', funcMCCStaticFieldSetBool) }, - { FEUtils::GetMCCStaticFieldSetByteIdx(), std::make_pair('B', funcMCCStaticFieldSetByte) }, - { FEUtils::GetMCCStaticFieldSetShortIdx(), std::make_pair('S', funcMCCStaticFieldSetShort) }, - { FEUtils::GetMCCStaticFieldSetCharIdx(), std::make_pair('C', funcMCCStaticFieldSetChar) }, - { FEUtils::GetMCCStaticFieldSetIntIdx(), std::make_pair('I', funcMCCStaticFieldSetInt) }, - { FEUtils::GetMCCStaticFieldSetLongIdx(), std::make_pair('J', funcMCCStaticFieldSetLong) }, - { FEUtils::GetMCCStaticFieldSetFloatIdx(), std::make_pair('F', funcMCCStaticFieldSetFloat) }, - { FEUtils::GetMCCStaticFieldSetDoubleIdx(), std::make_pair('D', funcMCCStaticFieldSetDouble) }, - { FEUtils::GetMCCStaticFieldSetObjectIdx(), std::make_pair('R', funcMCCStaticFieldSetObject) }, - }; - - for (auto &idxFun : MCCIdxFuncMap) { - std::vector argsType; - MIRType *typeMCC = GetMIRTypeForPrim(idxFun.second.first); - idxFun.second.second = CreateFunction(idxFun.first, typeMCC->GetTypeIndex(), argsType, false, false); - idxFun.second.second->SetAttr(FUNCATTR_pure); - idxFun.second.second->SetAttr(FUNCATTR_nosideeffect); - idxFun.second.second->SetAttr(FUNCATTR_noprivate_defeffect); - nameMCCFuncMap[idxFun.first] = idxFun.second.second; - } -} MIRFunction *FETypeManager::GetMCCFunction(const std::string &funcName) const { GStrIdx funcNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(funcName); diff --git a/src/mplfe/common/src/fe_utils.cpp b/src/mplfe/common/src/fe_utils.cpp index 7e4e3639530615dd8ffaa13da06fbcf6a5b0308d..c889feab7655f1580443e89a2c07a517074fee8c 100644 --- a/src/mplfe/common/src/fe_utils.cpp +++ b/src/mplfe/common/src/fe_utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -27,6 +27,7 @@ const std::string FEUtils::kLong = "J"; const std::string FEUtils::kFloat = "F"; const std::string FEUtils::kDouble = "D"; const std::string FEUtils::kVoid = "V"; +const std::string FEUtils::kThis = "_this"; const std::string FEUtils::kMCCStaticFieldGetBool = "MCC_StaticFieldGetBool"; const std::string FEUtils::kMCCStaticFieldGetByte = "MCC_StaticFieldGetByte"; const std::string FEUtils::kMCCStaticFieldGetShort = "MCC_StaticFieldGetShort"; @@ -179,6 +180,19 @@ PrimType FEUtils::GetPrimType(const GStrIdx &typeNameIdx) { return PTY_ref; } +std::string FEUtils::GetSequentialName0(const std::string &prefix, uint32_t num) { + std::stringstream ss; + ss << prefix << num; + return ss.str(); +} + +std::string FEUtils::GetSequentialName(const std::string &prefix) { + static uint32 unnamedSymbolIdx = 1; + std::string name = GetSequentialName0(prefix, unnamedSymbolIdx); + ++unnamedSymbolIdx; + return name; +} + // ---------- FELinkListNode ---------- FELinkListNode::FELinkListNode() : prev(nullptr), next(nullptr) {} diff --git a/src/mplfe/common/src/fe_utils_ast.cpp b/src/mplfe/common/src/fe_utils_ast.cpp new file mode 100644 index 0000000000000000000000000000000000000000..afcfe871d278c82c891d52f89526016148f23e58 --- /dev/null +++ b/src/mplfe/common/src/fe_utils_ast.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include "fe_utils_ast.h" + +namespace maple { +PrimType FEUtilAST::GetTypeFromASTTypeName(const std::string &typeName) { + const static std::map mapASTTypeNameToType = { + {"bool", PTY_u1}, + {"uint8", PTY_u8}, + {"uint16", PTY_u16}, + {"uint32", PTY_u32}, + {"uint64", PTY_u64}, + {"int8", PTY_i8}, + {"int16", PTY_i16}, + {"int32", PTY_i32}, + {"int64", PTY_i64}, + {"float", PTY_f32}, + {"double", PTY_f64}, + {"void", PTY_void} + }; + auto it = mapASTTypeNameToType.find(typeName); + CHECK_FATAL(it != mapASTTypeNameToType.end(), "Can not find typeName %s", typeName.c_str()); + return it->second; +} +} // namespace maple diff --git a/src/mplfe/common/src/fe_utils_java.cpp b/src/mplfe/common/src/fe_utils_java.cpp index ae872cd5ec10e9fcace9eefa9328093dcc20afde..4b363d9453e0697c49804f452aaa3fa188168759 100644 --- a/src/mplfe/common/src/fe_utils_java.cpp +++ b/src/mplfe/common/src/fe_utils_java.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/src/feir_builder.cpp b/src/mplfe/common/src/feir_builder.cpp index f6943f517aac293f377f697cde9e1ca6f9f09c5e..f3f9ff163cedd4a106aa5957b41ab774302ac639 100644 --- a/src/mplfe/common/src/feir_builder.cpp +++ b/src/mplfe/common/src/feir_builder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -91,6 +91,12 @@ UniqueFEIRExpr FEIRBuilder::CreateExprDRead(UniqueFEIRVar srcVar) { return expr; } +UniqueFEIRExpr FEIRBuilder::CreateExprAddrof(const std::vector &array) { + UniqueFEIRExpr expr = std::make_unique(array); + CHECK_NULL_FATAL(expr); + return expr; +} + UniqueFEIRExpr FEIRBuilder::CreateExprConstRefNull() { return std::make_unique(int64{ 0 }, PTY_ref); } @@ -180,6 +186,12 @@ UniqueFEIRExpr FEIRBuilder::CreateExprJavaNewInstance(UniqueFEIRType type, uint3 return expr; } +UniqueFEIRExpr FEIRBuilder::CreateExprJavaNewInstance(UniqueFEIRType type, uint32 argTypeID, bool isRcPermanent) { + UniqueFEIRExpr expr = std::make_unique(std::move(type), argTypeID, isRcPermanent); + CHECK_NULL_FATAL(expr); + return expr; +} + UniqueFEIRExpr FEIRBuilder::CreateExprJavaNewArray(UniqueFEIRType type, UniqueFEIRExpr exprSize) { UniqueFEIRExpr expr = std::make_unique(std::move(type), std::move(exprSize)); CHECK_NULL_FATAL(expr); @@ -192,6 +204,14 @@ UniqueFEIRExpr FEIRBuilder::CreateExprJavaNewArray(UniqueFEIRType type, UniqueFE return expr; } +UniqueFEIRExpr FEIRBuilder::CreateExprJavaNewArray(UniqueFEIRType type, UniqueFEIRExpr exprSize, uint32 typeID, + bool isRcPermanent) { + UniqueFEIRExpr expr = std::make_unique( + std::move(type), std::move(exprSize), typeID, isRcPermanent); + CHECK_NULL_FATAL(expr); + return expr; +} + UniqueFEIRExpr FEIRBuilder::CreateExprJavaArrayLength(UniqueFEIRExpr exprArray) { UniqueFEIRExpr expr = std::make_unique(std::move(exprArray)); CHECK_NULL_FATAL(expr); @@ -230,10 +250,11 @@ UniqueFEIRStmt FEIRBuilder::CreateStmtJavaConstClass(UniqueFEIRVar dstVar, Uniqu return stmt; } -UniqueFEIRStmt FEIRBuilder::CreateStmtJavaConstString(UniqueFEIRVar dstVar, const GStrIdx &strIdx) { +UniqueFEIRStmt FEIRBuilder::CreateStmtJavaConstString(UniqueFEIRVar dstVar, const std::string &strVal) { UniqueFEIRType dstType = FETypeManager::kFEIRTypeJavaString->Clone(); dstVar->SetType(std::move(dstType)); - UniqueFEIRStmt stmt = std::make_unique(std::move(dstVar), strIdx); + UniqueFEIRStmt stmt = std::make_unique(std::move(dstVar), strVal, + 0, GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(strVal)); return stmt; } diff --git a/src/mplfe/common/src/feir_dfg.cpp b/src/mplfe/common/src/feir_dfg.cpp index bec402d9fa9a514fac6bb927a1881bca4ac37e05..468c22671b2beb83c157f88fc13b3da6ea8c1134 100644 --- a/src/mplfe/common/src/feir_dfg.cpp +++ b/src/mplfe/common/src/feir_dfg.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/src/feir_stmt.cpp b/src/mplfe/common/src/feir_stmt.cpp index 6dbe555d6613d9e4d8bf658aca9c297c406ac3e1..d03f63361993927fd465b5bb0f927fa7e94c96eb 100644 --- a/src/mplfe/common/src/feir_stmt.cpp +++ b/src/mplfe/common/src/feir_stmt.cpp @@ -23,7 +23,9 @@ #include "mplfe_env.h" #include "feir_var_type_scatter.h" #include "fe_options.h" +#include "feir_type_helper.h" #include "bc_util.h" +#include "rc_setter.h" namespace maple { std::string GetFEIRNodeKindDescription(FEIRNodeKind kindArg) { @@ -211,7 +213,7 @@ std::list FEIRStmtNary::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const BaseNode *node = arg->GenMIRNode(mirBuilder); args.push_back(node); } - stmt = mirBuilder.CreateStmtNary(op, args); + stmt = mirBuilder.CreateStmtNary(op, std::move(args)); } else if (argExprs.size() == 1) { BaseNode *node = argExprs.front()->GenMIRNode(mirBuilder); stmt = mirBuilder.CreateStmtNary(op, node); @@ -312,9 +314,9 @@ FEIRStmtJavaTypeCheck::FEIRStmtJavaTypeCheck(std::unique_ptr argVar, st uint32 argTypeID) : FEIRStmtAssign(FEIRNodeKind::kStmtJavaTypeCheck, std::move(argVar)), checkKind(argCheckKind), - typeID(argTypeID), expr(std::move(argExpr)), - type(std::move(argType)) {} + type(std::move(argType)), + typeID(argTypeID) {} void FEIRStmtJavaTypeCheck::RegisterDFGNodes2CheckPointImpl(FEIRStmtCheckPoint &checkPoint) { expr->RegisterDFGNodes2CheckPoint(checkPoint); @@ -335,13 +337,16 @@ std::list FEIRStmtJavaTypeCheck::GenMIRStmtsImpl(MIRBuilder &mirBuild MIRType *mirPtrType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*mirType, PTY_ref); MapleVector arguments(mirBuilder.GetCurrentFuncCodeMpAllocator()->Adapter()); arguments.push_back(objNode); + if (FEOptions::GetInstance().IsAOT()) { + arguments.push_back(mirBuilder.CreateIntConst(typeID, PTY_i32)); + } if (checkKind == kCheckCast) { - StmtNode *callStmt = mirBuilder.CreateStmtIntrinsicCallAssigned(INTRN_JAVA_CHECK_CAST, arguments, ret, + StmtNode *callStmt = mirBuilder.CreateStmtIntrinsicCallAssigned(INTRN_JAVA_CHECK_CAST, std::move(arguments), ret, mirPtrType->GetTypeIndex()); ans.push_back(callStmt); } else { BaseNode *instanceOf = mirBuilder.CreateExprIntrinsicop(INTRN_JAVA_INSTANCE_OF, OP_intrinsicopwithtype, *mirPtrType, - arguments); + std::move(arguments)); instanceOf->SetPrimType(PTY_u1); DassignNode *stmt = mirBuilder.CreateStmtDassign(*ret, 0, instanceOf); ans.push_back(stmt); @@ -372,21 +377,17 @@ std::list FEIRStmtJavaConstClass::GenMIRStmtsImpl(MIRBuilder &mirBuil MapleVector args(mirBuilder.GetCurrentFuncCodeMpAllocator()->Adapter()); MIRType *ptrType = type->GenerateMIRTypeAuto(kSrcLangJava); BaseNode *expr = - mirBuilder.CreateExprIntrinsicop(INTRN_JAVA_CONST_CLASS, OP_intrinsicopwithtype, *ptrType, args); + mirBuilder.CreateExprIntrinsicop(INTRN_JAVA_CONST_CLASS, OP_intrinsicopwithtype, *ptrType, std::move(args)); StmtNode *stmt = mirBuilder.CreateStmtDassign(*varSym, 0, expr); ans.push_back(stmt); return ans; } // ---------- FEIRStmtJavaConstString ---------- -FEIRStmtJavaConstString::FEIRStmtJavaConstString(std::unique_ptr argVar, const GStrIdx &argStrIdx) - : FEIRStmtAssign(FEIRNodeKind::kStmtJavaConstString, std::move(argVar)), - strIdx(argStrIdx) {} - -FEIRStmtJavaConstString::FEIRStmtJavaConstString(std::unique_ptr argVar, const GStrIdx &argStrIdx, - uint32 argStringID) +FEIRStmtJavaConstString::FEIRStmtJavaConstString(std::unique_ptr argVar, const std::string &argStrVal, + uint32 argFileIdx, uint32 argStringID) : FEIRStmtAssign(FEIRNodeKind::kStmtJavaConstString, std::move(argVar)), - strIdx(argStrIdx), stringID(argStringID) {} + strVal(argStrVal), fileIdx(argFileIdx), stringID(argStringID) {} void FEIRStmtJavaConstString::RegisterDFGNodes2CheckPointImpl(FEIRStmtCheckPoint &checkPoint) { var->SetDef(true); @@ -395,27 +396,31 @@ void FEIRStmtJavaConstString::RegisterDFGNodes2CheckPointImpl(FEIRStmtCheckPoint std::list FEIRStmtJavaConstString::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { std::list ans; - const std::string &str = GlobalTables::GetStrTable().GetStringFromStrIdx(strIdx); - MIRSymbol *literalVal = FEManager::GetJavaStringManager().GetLiteralVar(str); + MIRSymbol *literalVal = FEManager::GetJavaStringManager().GetLiteralVar(strVal); if (literalVal == nullptr) { - literalVal = FEManager::GetJavaStringManager().CreateLiteralVar(mirBuilder, str, false); + literalVal = FEManager::GetJavaStringManager().CreateLiteralVar(mirBuilder, strVal, false); } MIRSymbol *literalValPtr = FEManager::GetJavaStringManager().GetLiteralPtrVar(literalVal); if (literalValPtr == nullptr) { - std::string localStrName = kLocalStringPrefix + std::to_string(static_cast(strIdx)); + std::string localStrName = kLocalStringPrefix + std::to_string(fileIdx) + "_" + std::to_string(stringID); MIRType *typeString = FETypeManager::kFEIRTypeJavaString->GenerateMIRTypeAuto(kSrcLangJava); +#ifndef USE_OPS + MIRSymbol *symbolLocal = SymbolBuilder::Instance().GetOrCreateLocalSymbol(*typeString, localStrName, + *mirBuilder.GetCurrentFunction()); +#else MIRSymbol *symbolLocal = mirBuilder.GetOrCreateLocalDecl(localStrName.c_str(), *typeString); +#endif if (!FEOptions::GetInstance().IsAOT()) { MapleVector args(mirBuilder.GetCurrentFuncCodeMpAllocator()->Adapter()); args.push_back(mirBuilder.CreateExprAddrof(0, *literalVal)); StmtNode *stmtCreate = mirBuilder.CreateStmtCallAssigned( - FEManager::GetTypeManager().GetPuIdxForMCCGetOrInsertLiteral(), args, symbolLocal, OP_callassigned); + FEManager::GetTypeManager().GetPuIdxForMCCGetOrInsertLiteral(), std::move(args), symbolLocal, + OP_callassigned); ans.push_back(stmtCreate); } literalValPtr = symbolLocal; } - (void)stringID; MIRSymbol *varDst = var->GenerateLocalMIRSymbol(mirBuilder); AddrofNode *node = mirBuilder.CreateDread(*literalValPtr, PTY_ptr); StmtNode *stmt = mirBuilder.CreateStmtDassign(*varDst, 0, node); @@ -453,7 +458,7 @@ std::list FEIRStmtJavaFillArrayData::GenMIRStmtsImpl(MIRBuilder &mirB uint64 val = elemPrimTypeSize * size; BaseNode *nodebytes = mirBuilder.CreateIntConst(val, PTY_i32); args.push_back(nodebytes); - StmtNode *stmt = mirBuilder.CreateStmtIntrinsicCallAssigned(INTRN_JAVA_ARRAY_FILL, args, nullptr); + StmtNode *stmt = mirBuilder.CreateStmtIntrinsicCallAssigned(INTRN_JAVA_ARRAY_FILL, std::move(args), nullptr); ans.push_back(stmt); return ans; } @@ -539,9 +544,11 @@ UniqueFEIRType FEIRStmtJavaMultiANewArray::typeAnnotation = nullptr; FEStructMethodInfo *FEIRStmtJavaMultiANewArray::methodInfoNewInstance = nullptr; FEIRStmtJavaMultiANewArray::FEIRStmtJavaMultiANewArray(std::unique_ptr argVar, - std::unique_ptr argType) + std::unique_ptr argElemType, + std::unique_ptr argArrayType) : FEIRStmtAssign(FEIRNodeKind::kStmtJavaMultiANewArray, std::move(argVar)), - type(std::move(argType)) {} + elemType(std::move(argElemType)), + arrayType(std::move(argArrayType)) {} void FEIRStmtJavaMultiANewArray::RegisterDFGNodes2CheckPointImpl(FEIRStmtCheckPoint &checkPoint) { for (const UniqueFEIRExpr &expr : exprSizes) { @@ -580,25 +587,26 @@ std::list FEIRStmtJavaMultiANewArray::GenMIRStmtsImpl(MIRBuilder &mir argsSizeArrayFill.push_back(node); } MIRSymbol *symSize = GetVarSize()->GenerateLocalMIRSymbol(mirBuilder); - StmtNode *stmtSizeArrayFill = mirBuilder.CreateStmtIntrinsicCallAssigned(INTRN_JAVA_ARRAY_FILL, argsSizeArrayFill, - symSize, TyIdx(PTY_i32)); + StmtNode *stmtSizeArrayFill = mirBuilder.CreateStmtIntrinsicCallAssigned(INTRN_JAVA_FILL_NEW_ARRAY, + std::move(argsSizeArrayFill), symSize, TyIdx(PTY_i32)); ans.push_back(stmtSizeArrayFill); - // class annotation - FEIRStmtJavaConstClass feStmtConstClass(GetVarClass()->Clone(), GetTypeAnnotation()->Clone()); + // const class + FEIRStmtJavaConstClass feStmtConstClass(GetVarClass()->Clone(), elemType->Clone()); std::list stmtsConstClass = feStmtConstClass.GenMIRStmts(mirBuilder); (void)ans.insert(ans.end(), stmtsConstClass.begin(), stmtsConstClass.end()); // invoke newInstance UniqueFEIRVar varRetCall = var->Clone(); varRetCall->SetType(FETypeManager::kFEIRTypeJavaObject->Clone()); - FEIRStmtCallAssign feStmtCall(GetMethodInfoNewInstance(), OP_call, varRetCall->Clone(), true); + FEIRStmtCallAssign feStmtCall(GetMethodInfoNewInstance(), OP_callassigned, varRetCall->Clone(), true); feStmtCall.AddExprArg(FEIRBuilder::CreateExprDRead(GetVarClass()->Clone())); feStmtCall.AddExprArg(FEIRBuilder::CreateExprDRead(GetVarSize()->Clone())); std::list stmtsCall = feStmtCall.GenMIRStmts(mirBuilder); (void)ans.insert(ans.end(), stmtsCall.begin(), stmtsCall.end()); // check cast - var->SetType(type->Clone()); + var->SetType(arrayType->Clone()); UniqueFEIRExpr expr = std::make_unique(std::move(varRetCall)); - FEIRStmtJavaTypeCheck feStmtCheck(var->Clone(), std::move(expr), type->Clone(), FEIRStmtJavaTypeCheck::kCheckCast); + FEIRStmtJavaTypeCheck feStmtCheck(var->Clone(), std::move(expr), arrayType->Clone(), + FEIRStmtJavaTypeCheck::kCheckCast); std::list stmtsCheck = feStmtCheck.GenMIRStmts(mirBuilder); (void)ans.insert(ans.end(), stmtsCheck.begin(), stmtsCheck.end()); return ans; @@ -711,7 +719,7 @@ std::list FEIRStmtReturn::GenMIRStmtsImpl(MIRBuilder &mirBuilder) con BaseNode *srcNode = expr->GenMIRNode(mirBuilder); mirStmt = mirBuilder.CreateStmtReturn(srcNode); } - ans.push_back(mirStmt); + ans.emplace_back(mirStmt); return ans; } @@ -950,6 +958,14 @@ FEIRStmtFieldStore::FEIRStmtFieldStore(UniqueFEIRVar argVarObj, UniqueFEIRVar ar varField(std::move(argVarField)), fieldInfo(argFieldInfo), isStatic(argIsStatic) {} +FEIRStmtFieldStore::FEIRStmtFieldStore(UniqueFEIRVar argVarObj, UniqueFEIRVar argVarField, + FEStructFieldInfo &argFieldInfo, bool argIsStatic, int32 argDexFileHashCode) + : FEIRStmt(FEIRNodeKind::kStmtFieldStore), + varObj(std::move(argVarObj)), + varField(std::move(argVarField)), + fieldInfo(argFieldInfo), + isStatic(argIsStatic), + dexFileHashCode(argDexFileHashCode) {} void FEIRStmtFieldStore::RegisterDFGNodes2CheckPointImpl(FEIRStmtCheckPoint &checkPoint) { if (isStatic) { @@ -1000,12 +1016,40 @@ std::list FEIRStmtFieldStore::GenMIRStmtsImpl(MIRBuilder &mirBuilder) } } -uint32 FEIRStmtFieldStore::GetTypeIDForStatic() const { +bool FEIRStmtFieldStore::NeedMCCForStatic(uint32 &typeID) const { + // check type first const std::string &actualContainerName = fieldInfo.GetActualContainerName(); - uint32 typeID = FEManager::GetTypeManager().GetTypeIDFromMplClassName(actualContainerName); - return typeID; + typeID = FEManager::GetTypeManager().GetTypeIDFromMplClassName(actualContainerName, dexFileHashCode); + if(typeID == UINT32_MAX) { + return true; + } + + // check type field second + const std::string &fieldName = GlobalTables::GetStrTable().GetStringFromStrIdx(fieldInfo.GetFieldNameIdx()); + MIRStructType *currStructType = FEManager::GetTypeManager().GetStructTypeFromName(actualContainerName); + const auto &fields = currStructType->GetStaticFields(); + for (auto f : fields) { + const std::string &fieldNameIt = GlobalTables::GetStrTable().GetStringFromStrIdx(f.first); + if(fieldName.compare(fieldNameIt) == 0) { + return false; + } + } + return true; } +void FEIRStmtFieldStore::InitPrimTypeFuncNameIdxMap (std::map &primTypeFuncNameIdxMap) const { + primTypeFuncNameIdxMap = { + { PTY_u1, FEUtils::GetMCCStaticFieldSetBoolIdx() }, + { PTY_i8, FEUtils::GetMCCStaticFieldSetByteIdx() }, + { PTY_i16, FEUtils::GetMCCStaticFieldSetShortIdx() }, + { PTY_u16, FEUtils::GetMCCStaticFieldSetCharIdx() }, + { PTY_i32, FEUtils::GetMCCStaticFieldSetIntIdx() }, + { PTY_i64, FEUtils::GetMCCStaticFieldSetLongIdx() }, + { PTY_f32, FEUtils::GetMCCStaticFieldSetFloatIdx() }, + { PTY_f64, FEUtils::GetMCCStaticFieldSetDoubleIdx() }, + { PTY_ref, FEUtils::GetMCCStaticFieldSetObjectIdx() }, + }; +} std::list FEIRStmtFieldStore::GenMIRStmtsImplForStatic(MIRBuilder &mirBuilder) const { CHECK_FATAL(fieldInfo.GetFieldNameIdx() != 0, "invalid name idx"); std::list mirStmts; @@ -1015,43 +1059,45 @@ std::list FEIRStmtFieldStore::GenMIRStmtsImplForStatic(MIRBuilder &mi UniqueFEIRExpr exprDRead = FEIRBuilder::CreateExprDRead(varField->Clone()); UniqueFEIRStmt stmtDAssign = FEIRBuilder::CreateStmtDAssign(std::move(varTarget), std::move(exprDRead)); mirStmts = stmtDAssign->GenMIRStmts(mirBuilder); + if (!FEOptions::GetInstance().IsNoBarrier() && fieldInfo.IsVolatile()) { + StmtNode *barrier = mirBuilder.GetMirModule().CurFuncCodeMemPool()->New(OP_membarrelease); + mirStmts.emplace_front(barrier); + barrier = mirBuilder.GetMirModule().CurFuncCodeMemPool()->New(OP_membarstoreload); + mirStmts.emplace_back(barrier); + } TyIdx containerTyIdx = fieldInfo.GetActualContainerType()->GenerateMIRType()->GetTypeIndex(); if (!mirBuilder.GetCurrentFunction()->IsClinit() || mirBuilder.GetCurrentFunction()->GetClassTyIdx() != containerTyIdx) { MapleVector args(mirBuilder.GetCurrentFuncCodeMpAllocator()->Adapter()); - uint32 typeID = UINT32_MAX; + bool needMCCForStatic = false; if (FEOptions::GetInstance().IsAOT()) { - typeID = GetTypeIDForStatic(); - if (typeID != UINT32_MAX) { + needMCCForStatic = NeedMCCForStatic(typeID); + if (!needMCCForStatic) { BaseNode *argNumExpr = mirBuilder.CreateIntConst(static_cast(typeID), PTY_i32); args.push_back(argNumExpr); } else { const auto &pt = fieldInfo.GetType()->GetPrimType(); - std::map primTypeFuncNameIdxMap = { - { PTY_u1, FEUtils::GetMCCStaticFieldSetBoolIdx() }, - { PTY_i8, FEUtils::GetMCCStaticFieldSetByteIdx() }, - { PTY_i16, FEUtils::GetMCCStaticFieldSetShortIdx() }, - { PTY_u16, FEUtils::GetMCCStaticFieldSetCharIdx() }, - { PTY_i32, FEUtils::GetMCCStaticFieldSetIntIdx() }, - { PTY_i64, FEUtils::GetMCCStaticFieldSetLongIdx() }, - { PTY_f32, FEUtils::GetMCCStaticFieldSetFloatIdx() }, - { PTY_f64, FEUtils::GetMCCStaticFieldSetDoubleIdx() }, - { PTY_ref, FEUtils::GetMCCStaticFieldSetObjectIdx() }, - }; + std::map primTypeFuncNameIdxMap; + InitPrimTypeFuncNameIdxMap(primTypeFuncNameIdxMap); const auto &itorFunc = primTypeFuncNameIdxMap.find(pt); CHECK_FATAL(itorFunc != primTypeFuncNameIdxMap.end(), "java type not support %d", pt); args.push_back(mirBuilder.CreateIntConst(static_cast(fieldInfo.GetFieldID()), PTY_i32)); BaseNode *nodeSrc = mirBuilder.CreateExprDread(*symSrc); args.push_back(nodeSrc); + MIRSymbol *retVarSym = nullptr; + retVarSym = varField->GenerateLocalMIRSymbol(mirBuilder); StmtNode *stmtMCC = mirBuilder.CreateStmtCallAssigned( - FEManager::GetTypeManager().GetMCCFunction(itorFunc->second)->GetPuidx(), args, nullptr, OP_callassigned); + FEManager::GetTypeManager().GetMCCFunction(itorFunc->second)->GetPuidx(), MapleVector(args), + retVarSym, + OP_callassigned); + mirStmts.clear(); mirStmts.emplace_front(stmtMCC); } } - - if (!FEOptions::GetInstance().IsAOT() || typeID != UINT32_MAX) { - StmtNode *stmtClinitCheck = mirBuilder.CreateStmtIntrinsicCall(INTRN_JAVA_CLINIT_CHECK, args, containerTyIdx); + if (!needMCCForStatic) { + StmtNode *stmtClinitCheck = mirBuilder.CreateStmtIntrinsicCall(INTRN_JAVA_CLINIT_CHECK, std::move(args), + containerTyIdx); mirStmts.emplace_front(stmtClinitCheck); } } @@ -1061,7 +1107,7 @@ std::list FEIRStmtFieldStore::GenMIRStmtsImplForStatic(MIRBuilder &mi std::list FEIRStmtFieldStore::GenMIRStmtsImplForNonStatic(MIRBuilder &mirBuilder) const { std::list ans; FieldID fieldID = fieldInfo.GetFieldID(); - CHECK_FATAL(fieldID != 0, "invalid field ID"); + ASSERT(fieldID != 0, "invalid field ID"); MIRStructType *structType = FEManager::GetTypeManager().GetStructTypeFromName(fieldInfo.GetStructName()); CHECK_NULL_FATAL(structType); MIRType *ptrStructType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*structType, PTY_ref); @@ -1070,7 +1116,16 @@ std::list FEIRStmtFieldStore::GenMIRStmtsImplForNonStatic(MIRBuilder BaseNode *nodeObj = exprDReadObj->GenMIRNode(mirBuilder); BaseNode *nodeField = exprDReadField->GenMIRNode(mirBuilder); StmtNode *stmt = mirBuilder.CreateStmtIassign(*ptrStructType, fieldID, nodeObj, nodeField); - ans.push_back(stmt); + if (FEOptions::GetInstance().IsRC()) { + bc::RCSetter::GetRCSetter().CollectInputStmtField(stmt, fieldInfo.GetElemNameIdx()); + } + ans.emplace_back(stmt); + if (!FEOptions::GetInstance().IsNoBarrier() && fieldInfo.IsVolatile()) { + StmtNode *barrier = mirBuilder.GetMirModule().CurFuncCodeMemPool()->New(OP_membarrelease); + ans.emplace_front(barrier); + barrier = mirBuilder.GetMirModule().CurFuncCodeMemPool()->New(OP_membarstoreload); + ans.emplace_back(barrier); + } return ans; } @@ -1088,6 +1143,15 @@ FEIRStmtFieldLoad::FEIRStmtFieldLoad(UniqueFEIRVar argVarObj, UniqueFEIRVar argV fieldInfo(argFieldInfo), isStatic(argIsStatic) {} +FEIRStmtFieldLoad::FEIRStmtFieldLoad(UniqueFEIRVar argVarObj, UniqueFEIRVar argVarField, + FEStructFieldInfo &argFieldInfo, + bool argIsStatic, int32 argDexFileHashCode) + : FEIRStmtAssign(FEIRNodeKind::kStmtFieldLoad, std::move(argVarField)), + varObj(std::move(argVarObj)), + fieldInfo(argFieldInfo), + isStatic(argIsStatic), + dexFileHashCode(argDexFileHashCode) {} + void FEIRStmtFieldLoad::RegisterDFGNodes2CheckPointImpl(FEIRStmtCheckPoint &checkPoint) { if (isStatic) { RegisterDFGNodes2CheckPointForStatic(checkPoint); @@ -1128,25 +1192,46 @@ std::list FEIRStmtFieldLoad::GenMIRStmtsImpl(MIRBuilder &mirBuilder) } } -uint32 FEIRStmtFieldLoad::GetTypeIDForStatic() const { +bool FEIRStmtFieldLoad::NeedMCCForStatic(uint32 &typeID) const { + // check type first const std::string &actualContainerName = fieldInfo.GetActualContainerName(); - uint32 typeID = FEManager::GetTypeManager().GetTypeIDFromMplClassName(actualContainerName); - return typeID; + typeID = FEManager::GetTypeManager().GetTypeIDFromMplClassName(actualContainerName, dexFileHashCode); + if(typeID == UINT32_MAX) { + return true; + } + + // check type field second + const std::string &fieldName = GlobalTables::GetStrTable().GetStringFromStrIdx(fieldInfo.GetFieldNameIdx()); + MIRStructType *currStructType = FEManager::GetTypeManager().GetStructTypeFromName(actualContainerName); + if (currStructType == nullptr) { + return true; + } + const auto &fields = currStructType->GetStaticFields(); + if (fields.size() == 0) { + return true; + } + for (auto f : fields) { + const std::string &fieldNameIt = GlobalTables::GetStrTable().GetStringFromStrIdx(f.first); + if(fieldName.compare(fieldNameIt) == 0) { + return false; + } + } + return true; } std::list FEIRStmtFieldLoad::GenMIRStmtsImplForStatic(MIRBuilder &mirBuilder) const { - std::list mirStmts; UniqueFEIRVar varTarget = std::make_unique(fieldInfo.GetFieldNameIdx(), fieldInfo.GetType()->Clone()); varTarget->SetGlobal(true); UniqueFEIRExpr exprDRead = FEIRBuilder::CreateExprDRead(std::move(varTarget)); UniqueFEIRStmt stmtDAssign = FEIRBuilder::CreateStmtDAssign(var->Clone(), std::move(exprDRead)); - mirStmts = stmtDAssign->GenMIRStmts(mirBuilder); + std::list mirStmts = stmtDAssign->GenMIRStmts(mirBuilder); MapleVector args(mirBuilder.GetCurrentFuncCodeMpAllocator()->Adapter()); - uint32 typeID = UINT32_MAX; + bool needMCCForStatic = false; if (FEOptions::GetInstance().IsAOT()) { - typeID = GetTypeIDForStatic(); - if (typeID != UINT32_MAX) { + uint32 typeID = UINT32_MAX; + needMCCForStatic = NeedMCCForStatic(typeID); + if (!needMCCForStatic) { BaseNode *argNumExpr = mirBuilder.CreateIntConst(static_cast(typeID), PTY_i32); args.push_back(argNumExpr); } else { @@ -1165,26 +1250,35 @@ std::list FEIRStmtFieldLoad::GenMIRStmtsImplForStatic(MIRBuilder &mir auto itorFunc = primTypeFuncNameIdxMap.find(pt); CHECK_FATAL(itorFunc != primTypeFuncNameIdxMap.end(), "java type not support %d", pt); args.push_back(mirBuilder.CreateIntConst(static_cast(fieldInfo.GetFieldID()), PTY_i32)); + MIRSymbol *retVarSym = nullptr; + retVarSym = var->GenerateLocalMIRSymbol(mirBuilder); StmtNode *stmtMCC = mirBuilder.CreateStmtCallAssigned( - FEManager::GetTypeManager().GetMCCFunction(itorFunc->second)->GetPuidx(), args, nullptr, OP_callassigned); + FEManager::GetTypeManager().GetMCCFunction(itorFunc->second)->GetPuidx(), MapleVector(args), + retVarSym, OP_callassigned); + mirStmts.clear(); mirStmts.emplace_front(stmtMCC); } } - if (!FEOptions::GetInstance().IsAOT() || typeID != UINT32_MAX) { + if (!needMCCForStatic) { TyIdx containerTyIdx = fieldInfo.GetActualContainerType()->GenerateMIRType()->GetTypeIndex(); if (!mirBuilder.GetCurrentFunction()->IsClinit() || mirBuilder.GetCurrentFunction()->GetClassTyIdx() != containerTyIdx) { - StmtNode *stmtClinitCheck = mirBuilder.CreateStmtIntrinsicCall(INTRN_JAVA_CLINIT_CHECK, args, containerTyIdx); + StmtNode *stmtClinitCheck = mirBuilder.CreateStmtIntrinsicCall(INTRN_JAVA_CLINIT_CHECK, std::move(args), + containerTyIdx); mirStmts.emplace_front(stmtClinitCheck); } } + if (!FEOptions::GetInstance().IsNoBarrier() && fieldInfo.IsVolatile()) { + StmtNode *barrier = mirBuilder.GetMirModule().CurFuncCodeMemPool()->New(OP_membaracquire); + mirStmts.emplace_back(barrier); + } return mirStmts; } std::list FEIRStmtFieldLoad::GenMIRStmtsImplForNonStatic(MIRBuilder &mirBuilder) const { std::list ans; FieldID fieldID = fieldInfo.GetFieldID(); - CHECK_FATAL(fieldID != 0, "invalid field ID"); + ASSERT(fieldID != 0, "invalid field ID"); MIRStructType *structType = FEManager::GetTypeManager().GetStructTypeFromName(fieldInfo.GetStructName()); CHECK_NULL_FATAL(structType); MIRType *ptrStructType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*structType, PTY_ref); @@ -1194,7 +1288,11 @@ std::list FEIRStmtFieldLoad::GenMIRStmtsImplForNonStatic(MIRBuilder & BaseNode *nodeVal = mirBuilder.CreateExprIread(*fieldType, *ptrStructType, fieldID, nodeObj); MIRSymbol *valRet = var->GenerateLocalMIRSymbol(mirBuilder); StmtNode *stmt = mirBuilder.CreateStmtDassign(*valRet, 0, nodeVal); - ans.push_back(stmt); + ans.emplace_back(stmt); + if (!FEOptions::GetInstance().IsNoBarrier() && fieldInfo.IsVolatile()) { + StmtNode *barrier = mirBuilder.GetMirModule().CurFuncCodeMemPool()->New(OP_membaracquire); + ans.emplace_back(barrier); + } return ans; } @@ -1255,10 +1353,12 @@ std::list FEIRStmtCallAssign::GenMIRStmtsImpl(MIRBuilder &mirBuilder) // If the struct is a class, we check it if external type directly. // If the struct is a array type, we check its baseType if external type. // FEUtils::GetBaseTypeName returns a class type itself or an arrayType's base type. - std::string baseStructName = FEUtils::GetBaseTypeName(methodInfo.GetStructName()); - bool isCreate = false; - (void)FEManager::GetTypeManager().GetOrCreateClassOrInterfaceType( - baseStructName, false, FETypeFlag::kSrcExtern, isCreate); + if (methodInfo.GetSrcLang() == kSrcLangJava) { + std::string baseStructName = FEUtils::GetBaseTypeName(methodInfo.GetStructName()); + bool isCreate = false; + (void)FEManager::GetTypeManager().GetOrCreateClassOrInterfaceType( + baseStructName, false, FETypeFlag::kSrcExtern, isCreate); + } std::list ans; StmtNode *stmtCall = nullptr; // prepare and find root @@ -1267,6 +1367,7 @@ std::list FEIRStmtCallAssign::GenMIRStmtsImpl(MIRBuilder &mirBuilder) return GenMIRStmtsUseZeroReturn(mirBuilder); } MapleVector args(mirBuilder.GetCurrentFuncCodeMpAllocator()->Adapter()); + args.reserve(exprArgs.size()); for (const UniqueFEIRExpr &exprArg : exprArgs) { BaseNode *node = exprArg->GenMIRNode(mirBuilder); args.push_back(node); @@ -1276,7 +1377,7 @@ std::list FEIRStmtCallAssign::GenMIRStmtsImpl(MIRBuilder &mirBuilder) if (!methodInfo.IsReturnVoid() && var != nullptr) { retVarSym = var->GenerateLocalMIRSymbol(mirBuilder); } - stmtCall = mirBuilder.CreateStmtCallAssigned(puIdx, args, retVarSym, mirOp); + stmtCall = mirBuilder.CreateStmtCallAssigned(puIdx, std::move(args), retVarSym, mirOp); ans.push_back(stmtCall); return ans; } @@ -1286,7 +1387,7 @@ std::list FEIRStmtCallAssign::GenMIRStmtsUseZeroReturn(MIRBuilder &mi if (methodInfo.IsReturnVoid()) { return ans; } - const UniqueFEIRType &retType = methodInfo.GetReturnType(); + const FEIRType *retType = methodInfo.GetReturnType(); MIRType *mirRetType = retType->GenerateMIRTypeAuto(kSrcLangJava); MIRSymbol *mirRetSym = var->GenerateLocalMIRSymbol(mirBuilder); BaseNode *nodeZero; @@ -1415,7 +1516,8 @@ std::list FEIRStmtIntrinsicCallAssign::GenMIRStmtsImpl(MIRBuilder &mi args.push_back(argNumExpr); } stmtCall = - mirBuilder.CreateStmtIntrinsicCall(INTRN_JAVA_CLINIT_CHECK, args, type->GenerateMIRType()->GetTypeIndex()); + mirBuilder.CreateStmtIntrinsicCall(INTRN_JAVA_CLINIT_CHECK, std::move(args), + type->GenerateMIRType()->GetTypeIndex()); } else if (intrinsicId == INTRN_JAVA_FILL_NEW_ARRAY) { MapleVector args(mirBuilder.GetCurrentFuncCodeMpAllocator()->Adapter()); if (exprList != nullptr) { @@ -1428,7 +1530,7 @@ std::list FEIRStmtIntrinsicCallAssign::GenMIRStmtsImpl(MIRBuilder &mi if ((var != nullptr) && (var.get() != nullptr)) { retVarSym = var->GenerateLocalMIRSymbol(mirBuilder); } - stmtCall = mirBuilder.CreateStmtIntrinsicCallAssigned(INTRN_JAVA_FILL_NEW_ARRAY, args, retVarSym, + stmtCall = mirBuilder.CreateStmtIntrinsicCallAssigned(INTRN_JAVA_FILL_NEW_ARRAY, std::move(args), retVarSym, type->GenerateMIRType(true)->GetTypeIndex()); } else if (intrinsicId == INTRN_JAVA_POLYMORPHIC_CALL) { return GenMIRStmtsForInvokePolyMorphic(mirBuilder); @@ -1459,7 +1561,7 @@ std::list FEIRStmtIntrinsicCallAssign::GenMIRStmtsForInvokePolyMorphi } MapleVector args(mirBuilder.GetCurrentFuncCodeMpAllocator()->Adapter()); ConstructArgsForInvokePolyMorphic(mirBuilder, args); - stmtCall = mirBuilder.CreateStmtIntrinsicCallAssigned(INTRN_JAVA_POLYMORPHIC_CALL, args, retVarSym); + stmtCall = mirBuilder.CreateStmtIntrinsicCallAssigned(INTRN_JAVA_POLYMORPHIC_CALL, std::move(args), retVarSym); ans.emplace_back(stmtCall); if (needRetypeRet) { UniqueFEIRStmt retypeStmt = FEIRBuilder::CreateStmtRetype(var->Clone(), std::move(tmpVar)); @@ -1499,8 +1601,7 @@ void FEIRStmtIntrinsicCallAssign::ConstructArgsForInvokePolyMorphic(MIRBuilder & if (isInStaticFunc) { intrnCallargs.push_back(mirBuilder.CreateIntConst(static_cast(callerClassTypeID), PTY_i32)); } else { - GStrIdx thisNameIdx = GlobalTables::GetStrTable().GetStrIdxFromName("_this"); - std::unique_ptr varThisAsLocalVar = std::make_unique(thisNameIdx, + std::unique_ptr varThisAsLocalVar = std::make_unique(FEUtils::GetThisIdx(), FEIRTypeDefault(PTY_ref).Clone()); intrnCallargs.push_back(mirBuilder.CreateExprDread(*(varThisAsLocalVar->GenerateMIRSymbol(mirBuilder)))); } @@ -1671,6 +1772,30 @@ std::vector FEIRExprDRead::GetVarUsesImpl() const { return std::vector({ varSrc.get() }); } +// ---------- FEIRExprAddrof ---------- +std::unique_ptr FEIRExprAddrof::CloneImpl() const { + std::unique_ptr expr = std::make_unique(array); + return expr; +} + +BaseNode *FEIRExprAddrof::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { + std::string arrayName = FEUtils::GetSequentialName("const_array_"); + MIRType *elemType = GlobalTables::GetTypeTable().GetPrimType(PTY_u8); + MIRType *arrayTypeWithSize = GlobalTables::GetTypeTable().GetOrCreateArrayType(*elemType, array.size()); + MIRSymbol *arrayVar = mirBuilder.GetOrCreateGlobalDecl(arrayName, *arrayTypeWithSize); + arrayVar->SetAttr(ATTR_readonly); + arrayVar->SetStorageClass(kScFstatic); + MIRModule &module = mirBuilder.GetMirModule(); + MIRAggConst *val = module.GetMemPool()->New(module, *arrayTypeWithSize); + for (uint32 i = 0; i < array.size(); ++i) { + MIRConst *cst = module.GetMemPool()->New(array[i], *elemType); + val->PushBack(cst); + } + arrayVar->SetKonst(val); + BaseNode *nodeAddrof = mirBuilder.CreateExprAddrof(0, *arrayVar); + return nodeAddrof; +} + // ---------- FEIRExprRegRead ---------- FEIRExprRegRead::FEIRExprRegRead(PrimType pty, int32 regNumIn) : FEIRExpr(FEIRNodeKind::kExprRegRead), prmType(pty), regNum(regNumIn) {} @@ -2316,16 +2441,6 @@ FEIRExprIntrinsicop::FEIRExprIntrinsicop(std::unique_ptr exprType, MIR paramType = std::move(argParamType); } -FEIRExprIntrinsicop::FEIRExprIntrinsicop(std::unique_ptr exprType, MIRIntrinsicID argIntrinsicID, - std::unique_ptr argParamType, uint32 argTypeID, uint32 argArraySize) - : FEIRExprNary(OP_intrinsicopwithtype), - intrinsicID(argIntrinsicID), - typeID(argTypeID), - arraySize(argArraySize) { - kind = FEIRNodeKind::kExprIntrinsicop; - SetType(std::move(exprType)); - paramType = std::move(argParamType); -} std::unique_ptr FEIRExprIntrinsicop::CloneImpl() const { if (op == OP_intrinsicop) { @@ -2342,11 +2457,10 @@ BaseNode *FEIRExprIntrinsicop::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { BaseNode *node = e->GenMIRNode(mirBuilder); args.emplace_back(node); } - (void)arraySize; (void)typeID; MIRType *ptrType = GlobalTables::GetTypeTable().GetOrCreatePointerType( *(type->GenerateMIRType()), paramType->IsRef() ? PTY_ref : PTY_ptr); - BaseNode *expr = mirBuilder.CreateExprIntrinsicop(intrinsicID, op, *ptrType, args); + BaseNode *expr = mirBuilder.CreateExprIntrinsicop(intrinsicID, op, *ptrType, std::move(args)); return expr; } @@ -2400,6 +2514,7 @@ bool FEIRExprJavaMerge::CalculateDefs4AllUsesImpl(FEIRStmtCheckPoint &checkPoint BaseNode *FEIRExprJavaMerge::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { MapleVector args(mirBuilder.GetCurrentFuncCodeMpAllocator()->Adapter()); + args.reserve(opnds.size()); for (const auto &e : opnds) { BaseNode *node = e->GenMIRNode(mirBuilder); args.emplace_back(node); @@ -2407,7 +2522,7 @@ BaseNode *FEIRExprJavaMerge::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { // (intrinsicop u1 JAVA_MERGE (dread i32 %Reg0_I)) IntrinDesc *intrinDesc = &IntrinDesc::intrinTable[INTRN_JAVA_MERGE]; MIRType *retType = intrinDesc->GetReturnType(); - BaseNode *intr = mirBuilder.CreateExprIntrinsicop(INTRN_JAVA_MERGE, op, *retType, args); + BaseNode *intr = mirBuilder.CreateExprIntrinsicop(INTRN_JAVA_MERGE, op, *retType, std::move(args)); intr->SetPrimType(type->GetPrimType()); return intr; } @@ -2423,6 +2538,11 @@ FEIRExprJavaNewInstance::FEIRExprJavaNewInstance(UniqueFEIRType argType, uint32 SetType(std::move(argType)); } +FEIRExprJavaNewInstance::FEIRExprJavaNewInstance(UniqueFEIRType argType, uint32 argTypeID, bool argIsRcPermanent) + : FEIRExpr(FEIRNodeKind::kExprJavaNewInstance), typeID(argTypeID), isRcPermanent(argIsRcPermanent) { + SetType(std::move(argType)); +} + std::unique_ptr FEIRExprJavaNewInstance::CloneImpl() const { std::unique_ptr expr = std::make_unique(type->Clone()); CHECK_NULL_FATAL(expr); @@ -2432,9 +2552,9 @@ std::unique_ptr FEIRExprJavaNewInstance::CloneImpl() const { BaseNode *FEIRExprJavaNewInstance::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { MIRType *mirType = type->GenerateMIRType(kSrcLangJava, false); BaseNode *expr = nullptr; - (void)typeID; MIRType *ptrType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*mirType, PTY_ref); - expr = mirBuilder.CreateExprGCMalloc(OP_gcmalloc, *ptrType, *mirType); + Opcode opMalloc = isRcPermanent ? OP_gcpermalloc : OP_gcmalloc; + expr = mirBuilder.CreateExprGCMalloc(opMalloc, *ptrType, *mirType); CHECK_NULL_FATAL(expr); return expr; } @@ -2452,6 +2572,13 @@ FEIRExprJavaNewArray::FEIRExprJavaNewArray(UniqueFEIRType argArrayType, UniqueFE SetExprSize(std::move(argExprSize)); } +FEIRExprJavaNewArray::FEIRExprJavaNewArray(UniqueFEIRType argArrayType, UniqueFEIRExpr argExprSize, uint32 argTypeID, + bool argIsRcPermanent) + : FEIRExpr(FEIRNodeKind::kExprJavaNewArray), typeID(argTypeID), isRcPermanent(argIsRcPermanent) { + SetArrayType(std::move(argArrayType)); + SetExprSize(std::move(argExprSize)); +} + std::unique_ptr FEIRExprJavaNewArray::CloneImpl() const { std::unique_ptr expr = std::make_unique(arrayType->Clone(), exprSize->Clone()); CHECK_NULL_FATAL(expr); @@ -2473,7 +2600,8 @@ BaseNode *FEIRExprJavaNewArray::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { MIRType *mirType = arrayType->GenerateMIRType(kSrcLangJava, false); MIRType *ptrType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*mirType, PTY_ref); BaseNode *sizeNode = exprSize->GenMIRNode(mirBuilder); - BaseNode *expr = mirBuilder.CreateExprJarrayMalloc(OP_gcmallocjarray, *ptrType, *jarrayType, sizeNode); + Opcode opMalloc = isRcPermanent ? OP_gcpermallocjarray : OP_gcmallocjarray; + BaseNode *expr = mirBuilder.CreateExprJarrayMalloc(opMalloc, *ptrType, *jarrayType, sizeNode); CHECK_NULL_FATAL(expr); return expr; } @@ -2507,7 +2635,7 @@ BaseNode *FEIRExprJavaArrayLength::GenMIRNodeImpl(MIRBuilder &mirBuilder) const MapleVector args(mirBuilder.GetCurrentFuncCodeMpAllocator()->Adapter()); args.push_back(arrayNode); MIRType *retType = GlobalTables::GetTypeTable().GetInt32(); - return mirBuilder.CreateExprIntrinsicop(INTRN_JAVA_ARRAY_LENGTH, OP_intrinsicop, *retType, args); + return mirBuilder.CreateExprIntrinsicop(INTRN_JAVA_ARRAY_LENGTH, OP_intrinsicop, *retType, std::move(args)); } void FEIRExprJavaArrayLength::RegisterDFGNodes2CheckPointImpl(FEIRStmtCheckPoint &checkPoint) { @@ -2747,7 +2875,7 @@ std::list FEIRStmtPesudoCatch2::GenMIRStmtsImpl(MIRBuilder &mirBuilde void FEIRStmtPesudoCatch2::AddCatchTypeNameIdx(GStrIdx typeNameIdx) { UniqueFEIRType type; if (typeNameIdx == FEUtils::GetVoidIdx()) { - type = std::make_unique(std::make_unique(PTY_void, typeNameIdx)); + type = std::make_unique(PTY_ref, bc::BCUtil::GetJavaThrowableNameMplIdx()); } else { type = std::make_unique(PTY_ref, typeNameIdx); } diff --git a/src/mplfe/common/src/feir_type.cpp b/src/mplfe/common/src/feir_type.cpp index 20e1c0958fd4b496bbcef1a7d9272683c13f5076..c26f42290216f165b4a89a00deb817ac39dfe57e 100644 --- a/src/mplfe/common/src/feir_type.cpp +++ b/src/mplfe/common/src/feir_type.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -60,6 +60,7 @@ std::unique_ptr FEIRType::NewType(FEIRTypeKind argKind) { std::map> FEIRType::InitLangConfig() { std::map> ans; ans[kSrcLangJava] = std::make_tuple(true, PTY_ref); + ans[kSrcLangC] = std::make_tuple(true, PTY_ref); return ans; } @@ -220,8 +221,36 @@ void FEIRTypeDefault::LoadFromJavaTypeName(const std::string &typeName, bool inM } } +void FEIRTypeDefault::LoadFromASTTypeName(const std::string &typeName) { + const static std::map mapASTTypeNameToType = { + {"bool", PTY_u1}, + {"uint8", PTY_u8}, + {"uint16", PTY_u16}, + {"uint32", PTY_u32}, + {"uint64", PTY_u64}, + {"int8", PTY_i8}, + {"int16", PTY_i16}, + {"int32", PTY_i32}, + {"int64", PTY_i64}, + {"float", PTY_f32}, + {"double", PTY_f64}, + {"void", PTY_void} + }; + auto it = mapASTTypeNameToType.find(typeName); + if (it != mapASTTypeNameToType.end()) { + primType = it->second; + } else { + primType = PTY_ref; + typeNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(typeName); + } +} + MIRType *FEIRTypeDefault::GenerateMIRTypeForPrim() const { switch (primType) { + case PTY_i8: + return GlobalTables::GetTypeTable().GetInt8(); + case PTY_i16: + return GlobalTables::GetTypeTable().GetInt16(); case PTY_i32: return GlobalTables::GetTypeTable().GetInt32(); case PTY_i64: @@ -232,12 +261,14 @@ MIRType *FEIRTypeDefault::GenerateMIRTypeForPrim() const { return GlobalTables::GetTypeTable().GetDouble(); case PTY_u1: return GlobalTables::GetTypeTable().GetUInt1(); - case PTY_i8: - return GlobalTables::GetTypeTable().GetInt8(); - case PTY_i16: - return GlobalTables::GetTypeTable().GetInt16(); + case PTY_u8: + return GlobalTables::GetTypeTable().GetUInt8(); case PTY_u16: return GlobalTables::GetTypeTable().GetUInt16(); + case PTY_u32: + return GlobalTables::GetTypeTable().GetUInt32(); + case PTY_u64: + return GlobalTables::GetTypeTable().GetUInt64(); case PTY_void: return GlobalTables::GetTypeTable().GetVoid(); case PTY_a32: diff --git a/src/mplfe/common/src/feir_type_helper.cpp b/src/mplfe/common/src/feir_type_helper.cpp index d6b7570c812e2e9e53c4c20f3438d1f8885dcd34..6adf7baa95a0ed34b9959d7c25c511c43e585c03 100644 --- a/src/mplfe/common/src/feir_type_helper.cpp +++ b/src/mplfe/common/src/feir_type_helper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/src/feir_type_infer.cpp b/src/mplfe/common/src/feir_type_infer.cpp index 14e19c79264dacbb960480d4bf94dabe07d58d47..8f6bc0cf7cf7fbf355dfaaae68f13d2762e2c0de 100644 --- a/src/mplfe/common/src/feir_type_infer.cpp +++ b/src/mplfe/common/src/feir_type_infer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/src/feir_var.cpp b/src/mplfe/common/src/feir_var.cpp index 8d27b1256b9e6f0e0260456c0421356926be525d..959d27bd4858f003991fca140df12fc368a00ac1 100644 --- a/src/mplfe/common/src/feir_var.cpp +++ b/src/mplfe/common/src/feir_var.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -121,7 +121,7 @@ MIRSymbol *FEIRVar::GenerateGlobalMIRSymbolImpl(MIRBuilder &builder) const { t.SetAttr(ATTR_static); gSymbol->AddAttrs(t); } - for (auto &field : mirContainer->GetStaticFields()) { + for (auto field : mirContainer->GetStaticFields()) { if (field.first == nameIdx) { gSymbol->AddAttrs(field.second.second.ConvertToTypeAttrs()); } @@ -136,7 +136,11 @@ MIRSymbol *FEIRVar::GenerateLocalMIRSymbolImpl(MIRBuilder &builder) const { MPLFE_PARALLEL_FORBIDDEN(); MIRType *mirType = type->GenerateMIRTypeAuto(); std::string name = GetName(*mirType); +#ifndef USE_OPS + return SymbolBuilder::Instance().GetOrCreateLocalSymbol(*mirType, name, *builder.GetCurrentFunction()); +#else return builder.GetOrCreateLocalDecl(name, *mirType); +#endif } MIRSymbol *FEIRVar::GenerateMIRSymbolImpl(MIRBuilder &builder) const { diff --git a/src/mplfe/common/src/feir_var_name.cpp b/src/mplfe/common/src/feir_var_name.cpp index 656ddb84eeb228ca3caa543f8a5a2571f06d1ce9..b06eb79cc3e3730f8122d5e0e79fe6f149154068 100644 --- a/src/mplfe/common/src/feir_var_name.cpp +++ b/src/mplfe/common/src/feir_var_name.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/src/feir_var_reg.cpp b/src/mplfe/common/src/feir_var_reg.cpp index 1aa55cbc710598b14fe4413c7f805a0aec9bf9bf..0cbc4a00cb60afc0b58263e51ba9a69a8f20a135 100644 --- a/src/mplfe/common/src/feir_var_reg.cpp +++ b/src/mplfe/common/src/feir_var_reg.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -13,6 +13,7 @@ * See the Mulan PSL v2 for more details. */ #include "feir_var_reg.h" +#include "fe_options.h" #include #include #include "mir_type.h" @@ -43,6 +44,21 @@ std::string FEIRVarReg::GetNameRawImpl() const { return ss.str(); } +MIRSymbol *FEIRVarReg::GenerateLocalMIRSymbolImpl(MIRBuilder &builder) const { + MPLFE_PARALLEL_FORBIDDEN(); + MIRType *mirType = type->GenerateMIRTypeAuto(); + std::string name = GetName(*mirType); +#ifndef USE_OPS + MIRSymbol *ret = SymbolBuilder::Instance().GetOrCreateLocalSymbol(*mirType, name, *builder.GetCurrentFunction()); + if (FEOptions::GetInstance().IsAOT()) { + ret->SetVregNo(regNum); + } +#else + MIRSymbol *ret = builder.GetOrCreateLocalDecl(name, *mirType); +#endif + return ret; +} + std::unique_ptr FEIRVarReg::CloneImpl() const { std::unique_ptr var = std::make_unique(regNum, type->Clone()); return var; diff --git a/src/mplfe/common/src/feir_var_type_scatter.cpp b/src/mplfe/common/src/feir_var_type_scatter.cpp index 083bb721df3d8074bbbc050643653fc39aad77ab..e2716520287c86c243e4eec8d39fc4e3efae1236 100644 --- a/src/mplfe/common/src/feir_var_type_scatter.cpp +++ b/src/mplfe/common/src/feir_var_type_scatter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -69,7 +69,11 @@ MIRSymbol *FEIRVarTypeScatter::GenerateLocalMIRSymbolImpl(MIRBuilder &builder) c MPLFE_PARALLEL_FORBIDDEN(); MIRType *mirType = var->GetType()->GenerateMIRTypeAuto(); std::string name = GetName(*mirType); +#ifndef USE_OPS + return SymbolBuilder::Instance().GetOrCreateLocalSymbol(*mirType, name, *builder.GetCurrentFunction()); +#else return builder.GetOrCreateLocalDecl(name, *mirType); +#endif } MIRSymbol *FEIRVarTypeScatter::GenerateMIRSymbolImpl(MIRBuilder &builder) const { diff --git a/src/mplfe/common/src/general_bb.cpp b/src/mplfe/common/src/general_bb.cpp index f1295fe76822aa6f858ab35a56d6ffa9ceb39e94..f107605364add24f34c5be74732adb57674515ad 100644 --- a/src/mplfe/common/src/general_bb.cpp +++ b/src/mplfe/common/src/general_bb.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/src/general_cfg.cpp b/src/mplfe/common/src/general_cfg.cpp index 0af5a53751d6d865f607133f3c7740ba9089f15c..cddb122efe5068c677b820ec7ef0dcbd79f52b75 100644 --- a/src/mplfe/common/src/general_cfg.cpp +++ b/src/mplfe/common/src/general_cfg.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/src/general_stmt.cpp b/src/mplfe/common/src/general_stmt.cpp index 9024e6a783df09a36656e1cb60ead34c40e9f36f..811d650c1cac4ac02922eaf136c5de08ed050b46 100644 --- a/src/mplfe/common/src/general_stmt.cpp +++ b/src/mplfe/common/src/general_stmt.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/src/mplfe.cpp b/src/mplfe/common/src/mplfe.cpp index fc4e71ee6a5898170434aaaa92bb0fd73e95864b..fe1c999b9002167d3cf7db6afc51649e38324413 100644 --- a/src/mplfe/common/src/mplfe.cpp +++ b/src/mplfe/common/src/mplfe.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -26,6 +26,12 @@ int main(int argc, char **argv) { MIRModule module; MPLFECompiler compiler(module); compiler.Run(); + // The MIRModule destructor does not release the pragma memory, add releasing for front-end debugging. + MemPool *pragmaMemPoolPtr = module.GetPragmaMemPool(); + if (pragmaMemPoolPtr != nullptr) { + delete pragmaMemPoolPtr; + pragmaMemPoolPtr = nullptr; + } timer.Stop(); if (FEOptions::GetInstance().IsDumpTime()) { INFO(kLncInfo, "mplfe time: %.2lfms", timer.ElapsedMilliseconds() / 1.0); diff --git a/src/mplfe/common/src/mplfe_compiler.cpp b/src/mplfe/common/src/mplfe_compiler.cpp index 91745e2fbdaf58a0d9db0f8583b1834e70a094c6..7eb776b5ced3eb5b1969706273811e8e7a2d46a0 100644 --- a/src/mplfe/common/src/mplfe_compiler.cpp +++ b/src/mplfe/common/src/mplfe_compiler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -17,11 +17,13 @@ #include "fe_manager.h" #include "fe_file_type.h" #include "fe_timer.h" +#include "rc_setter.h" namespace maple { MPLFECompiler::MPLFECompiler(MIRModule &argModule) : module(argModule), - mp(memPoolCtrler.NewMemPool("MemPool for MPLFECompiler")), + srcLang(kSrcLangJava), + mp(FEUtils::NewMempool("MemPool for MPLFECompiler", false /* isLcalPool */)), allocator(mp) {} MPLFECompiler::~MPLFECompiler() { @@ -30,11 +32,11 @@ MPLFECompiler::~MPLFECompiler() { void MPLFECompiler::Init() { FEManager::Init(module); - FEStructMethodInfo::InitJavaPolymorphicWhiteList(); module.SetFlavor(maple::kFeProduced); - // The default language is Java. - module.SetSrcLang(maple::kSrcLangJava); module.GetImportFiles().clear(); + if (FEOptions::GetInstance().IsRC()) { + bc::RCSetter::InitRCSetter(""); + } } void MPLFECompiler::Release() { @@ -49,41 +51,28 @@ void MPLFECompiler::Run() { bool success = true; Init(); CheckInput(); + RegisterCompilerComponent(); success = success && LoadMplt(); SetupOutputPathAndName(); - if (FEOptions::GetInstance().HasJBC()) { - FEOptions::GetInstance().SetTypeInferKind(FEOptions::TypeInferKind::kNo); - std::unique_ptr jbcCompilerComp = std::make_unique(module); - RegisterCompilerComponent(std::move(jbcCompilerComp)); - } - if (FEOptions::GetInstance().GetInputDexFiles().size() != 0) { - bc::ArkAnnotationProcessor::Process(); - std::unique_ptr bcCompilerComp = - std::make_unique>(module); - RegisterCompilerComponent(std::move(bcCompilerComp)); - } ParseInputs(); if (!FEOptions::GetInstance().GetXBootClassPath().empty()) { LoadOnDemandTypes(); } - FEManager::GetJavaStringManager().GenStringMetaClassVar(); PreProcessDecls(); ProcessDecls(); ProcessPragmas(); if (!FEOptions::GetInstance().IsGenMpltOnly()) { - FEManager::GetTypeManager().InitMCCFunctions(); - PreProcessWithFunctions(); FETypeHierarchy::GetInstance().InitByGlobalTable(); ProcessFunctions(); + if (FEOptions::GetInstance().IsRC()) { + bc::RCSetter::GetRCSetter().MarkRCAttributes(); + } } + bc::RCSetter::ReleaseRCSetter(); FEManager::GetManager().ReleaseStructElemMempool(); CHECK_FATAL(success, "Compile Error"); - if (!FEOptions::GetInstance().IsNoMplFile()) { - ExportMpltFile(); - if (!FEOptions::GetInstance().IsGenMpltOnly()) { - ExportMplFile(); - } - } + ExportMpltFile(); + ExportMplFile(); MPLFEEnv::GetInstance().Finish(); Release(); } @@ -119,6 +108,16 @@ void MPLFECompiler::CheckInput() { } } +#ifdef ENABLE_MPLFE_AST + // check input ast files + const std::vector &inputASTNames = FEOptions::GetInstance().GetInputASTFiles(); + if (!inputASTNames.empty()) { + nInput += inputASTNames.size(); + if (firstInputName.empty()) { + firstInputName = inputASTNames[0]; + } + } +#endif // ~/ENABLE_MPLFE_AST CHECK_FATAL(nInput > 0, "Error occurs: no inputs. exit."); } @@ -188,17 +187,31 @@ bool MPLFECompiler::LoadMplt() { } void MPLFECompiler::ExportMpltFile() { - FETimer timer; - timer.StartAndDump("Output mplt"); - module.DumpToHeaderFile(!FEOptions::GetInstance().IsGenAsciiMplt()); - timer.StopAndDumpTimeMS("Output mplt"); + if (!FEOptions::GetInstance().IsNoMplFile()) { + FETimer timer; + timer.StartAndDump("Output mplt"); + module.DumpToHeaderFile(!FEOptions::GetInstance().IsGenAsciiMplt()); + timer.StopAndDumpTimeMS("Output mplt"); + } } void MPLFECompiler::ExportMplFile() { - FETimer timer; - timer.StartAndDump("Output mpl"); - module.OutputAsciiMpl("", ".mpl", nullptr, false, false); - timer.StopAndDumpTimeMS("Output mpl"); + if (!FEOptions::GetInstance().IsNoMplFile() && !FEOptions::GetInstance().IsGenMpltOnly()) { + FETimer timer; + timer.StartAndDump("Output mpl"); + bool emitStructureType = false; + // Currently, struct types cannot be dumped to mplt. + // After mid-end interfaces are optimized, the judgment can be deleted. + if (srcLang == kSrcLangC) { + emitStructureType = true; + } +#ifndef USE_OPS + module.OutputAsciiMpl("", emitStructureType); +#else + module.OutputAsciiMpl("", ".mpl", nullptr, false, false); +#endif + timer.StopAndDumpTimeMS("Output mpl"); + } } void MPLFECompiler::RegisterCompilerComponent(std::unique_ptr comp) { @@ -231,7 +244,6 @@ void MPLFECompiler::LoadOnDemandTypes() { void MPLFECompiler::PreProcessDecls() { FETimer timer; timer.StartAndDump("MPLFECompiler::PreProcessDecls()"); - (void)GlobalTables::GetStrTable().GetOrCreateStrIdxFromName("_this"); for (const std::unique_ptr &comp : components) { ASSERT(comp != nullptr, "nullptr check"); bool success = comp->PreProcessDecl(); @@ -261,18 +273,6 @@ void MPLFECompiler::ProcessPragmas() { timer.StopAndDumpTimeMS("MPLFECompiler::ProcessPragmas()"); } -void MPLFECompiler::PreProcessWithFunctions() { - FETimer timer; - timer.StartAndDump("MPLFECompiler::PreProcessWithFunctions()"); - (void)GlobalTables::GetStrTable().GetOrCreateStrIdxFromName("_this"); - for (const std::unique_ptr &comp : components) { - ASSERT(comp != nullptr, "nullptr check"); - bool success = comp->PreProcessWithFunction(); - CHECK_FATAL(success, "Error occurs in MPLFECompiler::PreProcessWithFunctions(). exit."); - } - timer.StopAndDumpTimeMS("MPLFECompiler::PreProcessWithFunctions()"); -} - void MPLFECompiler::ProcessFunctions() { FETimer timer; bool success = true; @@ -280,15 +280,8 @@ void MPLFECompiler::ProcessFunctions() { uint32 funcSize = 0; for (const std::unique_ptr &comp : components) { ASSERT(comp != nullptr, "nullptr check"); + success = comp->ProcessFunctionSerial() && success; funcSize += comp->GetFunctionsSize(); - uint32 nthreads = FEOptions::GetInstance().GetNThreads(); - if (comp->Parallelable() && nthreads > 0) { - FEConfigParallel::GetInstance().EnableParallel(); - success = comp->ProcessFunctionParallel(nthreads) && success; - FEConfigParallel::GetInstance().DisableParallel(); - } else { - success = comp->ProcessFunctionSerial() && success; - } if (!success) { const std::set &failedFEFunctions = comp->GetCompileFailedFEFunctions(); compileFailedFEFunctions.insert(failedFEFunctions.begin(), failedFEFunctions.end()); @@ -305,6 +298,29 @@ void MPLFECompiler::ProcessFunctions() { CHECK_FATAL(success, "ProcessFunction error"); } +void MPLFECompiler::RegisterCompilerComponent() { + if (FEOptions::GetInstance().HasJBC()) { + FEOptions::GetInstance().SetTypeInferKind(FEOptions::TypeInferKind::kNo); + std::unique_ptr jbcCompilerComp = std::make_unique(module); + RegisterCompilerComponent(std::move(jbcCompilerComp)); + } + if (FEOptions::GetInstance().GetInputDexFiles().size() != 0) { + bc::ArkAnnotationProcessor::Process(); + std::unique_ptr bcCompilerComp = + std::make_unique>(module); + RegisterCompilerComponent(std::move(bcCompilerComp)); + } +#ifdef ENABLE_MPLFE_AST + if (FEOptions::GetInstance().GetInputASTFiles().size() != 0) { + srcLang = kSrcLangC; + std::unique_ptr astCompilerComp = std::make_unique(module); + RegisterCompilerComponent(std::move(astCompilerComp)); + } +#endif // ~/ENABLE_MPLFE_AST + module.SetSrcLang(srcLang); + FEManager::GetTypeManager().SetSrcLang(srcLang); +} + void MPLFECompiler::FindMinCompileFailedFEFunctions() { if (compileFailedFEFunctions.size() == 0) { return; diff --git a/src/mplfe/common/src/mplfe_compiler_component.cpp b/src/mplfe/common/src/mplfe_compiler_component.cpp index f77c60c205ac2c1ae0b930d1ec225a0aa4cfc808..0843063bb7377e69745eb55b0ea7ef057c421aaf 100644 --- a/src/mplfe/common/src/mplfe_compiler_component.cpp +++ b/src/mplfe/common/src/mplfe_compiler_component.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -17,11 +17,12 @@ #include "fe_macros.h" #include "fe_timer.h" #include "fe_config_parallel.h" +#include "fe_manager.h" namespace maple { // ---------- FEFunctionProcessTask ---------- -FEFunctionProcessTask::FEFunctionProcessTask(std::unique_ptr &argFunction) - : function(argFunction) {} +FEFunctionProcessTask::FEFunctionProcessTask(std::unique_ptr argFunction) + : function(std::move(argFunction)) {} int FEFunctionProcessTask::RunImpl(MplTaskParam *param) { bool success = function->Process(); @@ -34,14 +35,12 @@ int FEFunctionProcessTask::RunImpl(MplTaskParam *param) { int FEFunctionProcessTask::FinishImpl(MplTaskParam *param) { function->Finish(); - FEFunction *funPtr = function.release(); - delete funPtr; return 0; } // ---------- FEFunctionProcessSchedular ---------- -void FEFunctionProcessSchedular::AddFunctionProcessTask(std::unique_ptr &function) { - std::unique_ptr task = std::make_unique(function); +void FEFunctionProcessSchedular::AddFunctionProcessTask(std::unique_ptr function) { + std::unique_ptr task = std::make_unique(std::move(function)); AddTask(task.get()); tasks.push_back(std::move(task)); } @@ -56,10 +55,51 @@ void FEFunctionProcessSchedular::CallbackThreadMainStart() { // ---------- MPLFECompilerComponent ---------- MPLFECompilerComponent::MPLFECompilerComponent(MIRModule &argModule, MIRSrcLang argSrcLang) - : module(argModule), + : funcSize(0), + module(argModule), srcLang(argSrcLang), phaseResultTotal(std::make_unique(true)) {} +bool MPLFECompilerComponent::LoadOnDemandTypeImpl() { + return false; +} + +bool MPLFECompilerComponent::PreProcessDeclImpl() { + FETimer timer; + timer.StartAndDump("MPLFECompilerComponent::PreProcessDecl()"); + FE_INFO_LEVEL(FEOptions::kDumpLevelInfo, "===== Process MPLFECompilerComponent::PreProcessDecl() ====="); + bool success = true; + FEManager::GetJavaStringManager().GenStringMetaClassVar(); + for (FEInputStructHelper *helper : structHelpers) { + ASSERT_NOT_NULL(helper); + success = helper->PreProcessDecl() ? success : false; + } + FEManager::GetTypeManager().InitMCCFunctions(); + timer.StopAndDumpTimeMS("MPLFECompilerComponent::PreProcessDecl()"); + return success; +} + +bool MPLFECompilerComponent::ProcessDeclImpl() { + FETimer timer; + timer.StartAndDump("MPLFECompilerComponent::ProcessDecl()"); + FE_INFO_LEVEL(FEOptions::kDumpLevelInfo, "===== Process MPLFECompilerComponent::ProcessDecl() ====="); + bool success = true; + for (FEInputStructHelper *helper : structHelpers) { + ASSERT_NOT_NULL(helper); + success = helper->ProcessDecl() ? success : false; + } + for (FEInputMethodHelper *helper : globalFuncHelpers) { + ASSERT_NOT_NULL(helper); + success = helper->ProcessDecl() ? success : false; + } + for (FEInputGlobalVarHelper *helper : globalVarHelpers) { + ASSERT_NOT_NULL(helper); + success = helper->ProcessDecl() ? success : false; + } + timer.StopAndDumpTimeMS("MPLFECompilerComponent::ProcessDecl()"); + return success; +} + bool MPLFECompilerComponent::ProcessFunctionSerialImpl() { std::stringstream ss; ss << GetComponentName() << "::ProcessFunctionSerial()"; @@ -67,14 +107,20 @@ bool MPLFECompilerComponent::ProcessFunctionSerialImpl() { timer.StartAndDump(ss.str()); bool success = true; FE_INFO_LEVEL(FEOptions::kDumpLevelInfo, "===== Process %s =====", ss.str().c_str()); - for (auto it = functions.begin(); it != functions.end();) { - bool processResult = (*it)->Process(); - if (!processResult) { - (void)compileFailedFEFunctions.insert((*it).get()); + for (FEInputStructHelper *structHelper : structHelpers) { + ASSERT_NOT_NULL(structHelper); + for (FEInputMethodHelper *methodHelper : structHelper->GetMethodHelpers()) { + ASSERT_NOT_NULL(methodHelper); + std::unique_ptr feFunction = CreatFEFunction(methodHelper); + feFunction->SetSrcFileName(structHelper->GetSrcFileName()); + bool processResult = feFunction->Process(); + if (!processResult) { + (void)compileFailedFEFunctions.insert(feFunction.get()); + } + success = success && processResult; + feFunction->Finish(); + funcSize++; } - success = success && processResult; - (*it)->Finish(); - it = functions.erase(it); } timer.StopAndDumpTimeMS(ss.str()); return success; @@ -88,8 +134,15 @@ bool MPLFECompilerComponent::ProcessFunctionParallelImpl(uint32 nthreads) { FE_INFO_LEVEL(FEOptions::kDumpLevelInfo, "===== Process %s =====", ss.str().c_str()); FEFunctionProcessSchedular schedular(ss.str()); schedular.Init(); - for (std::unique_ptr &function : functions) { - schedular.AddFunctionProcessTask(function); + for (FEInputStructHelper *structHelper : structHelpers) { + ASSERT_NOT_NULL(structHelper); + for (FEInputMethodHelper *methodHelper : structHelper->GetMethodHelpers()) { + ASSERT_NOT_NULL(methodHelper); + std::unique_ptr feFunction = CreatFEFunction(methodHelper); + feFunction->SetSrcFileName(structHelper->GetSrcFileName()); + schedular.AddFunctionProcessTask(std::move(feFunction)); + funcSize++; + } } schedular.SetDumpTime(FEOptions::GetInstance().IsDumpThreadTime()); (void)schedular.RunTask(nthreads, true); diff --git a/src/mplfe/common/src/mplfe_env.cpp b/src/mplfe/common/src/mplfe_env.cpp index 1f7f3abe6eb75caf9a8ad82c3904248277683866..14d89a5a6c454f48419dab3ce44d143442ea4dfa 100644 --- a/src/mplfe/common/src/mplfe_env.cpp +++ b/src/mplfe/common/src/mplfe_env.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/src/mplfe_options.cpp b/src/mplfe/common/src/mplfe_options.cpp index 3cb3142552fa5eea8b784e64ae146988c693a10b..938eebab2a27ff56ea19f119fe5afe1c37c1143b 100644 --- a/src/mplfe/common/src/mplfe_options.cpp +++ b/src/mplfe/common/src/mplfe_options.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -32,6 +32,9 @@ enum OptionIndex : uint32 { kInClass, kInJar, kInDex, +#ifdef ENABLE_MPLFE_AST + kInAST, +#endif // ~/ENABLE_MPLFE_AST // output control options kOutputPath, kOutputName, @@ -46,6 +49,9 @@ enum OptionIndex : uint32 { kDumpLOC, kDumpPhaseTime, kDumpPhaseTimeDetail, + // bc bytecode compile options + kRC, + kNoBarrier, // java bytecode compile options kJavaStaticFieldName, kJBCInfoUsePathName, @@ -110,6 +116,12 @@ const Descriptor kUsage[] = { kBuildTypeAll, kArgCheckPolicyRequired, " --in-dex file1.dex,file2.dex\n" " : input dex files", "mplfe", {} }, +#ifdef ENABLE_MPLFE_AST + { kInAST, 0, "", "in-ast", + kBuildTypeAll, kArgCheckPolicyRequired, + " --in-ast file1.ast,file2.ast\n" + " : input ast files", "mplfe", {} }, +#endif // ~/ENABLE_MPLFE_AST // output control options { kUnknown, 0, "", "", @@ -161,6 +173,16 @@ const Descriptor kUsage[] = { kBuildTypeAll, kArgCheckPolicyNone, " --dump-phase-time-detail" " : dump phase time for each method", "mplfe", {} }, + // bc bytecode compile options + { kUnknown, 0, "", "", + kBuildTypeAll, kArgCheckPolicyUnknown, + "========== BC Bytecode Compile Options ==========", "mplfe", {} }, + { kRC, 0, "", "rc", + kBuildTypeAll, kArgCheckPolicyNone, + " --rc : enable rc", "mplfe", {} }, + { kNoBarrier, 0, "", "nobarrier", + kBuildTypeAll, kArgCheckPolicyNone, + " --nobarrier : no barrier", "mplfe", {} }, // java bytecode compile options { kUnknown, 0, "", "", kBuildTypeAll, kArgCheckPolicyUnknown, @@ -282,6 +304,10 @@ bool MPLFEOptions::InitFactory() { &MPLFEOptions::ProcessInJar); RegisterFactoryFunction(kInDex, &MPLFEOptions::ProcessInDex); +#ifdef ENABLE_MPLFE_AST + RegisterFactoryFunction(kInAST, + &MPLFEOptions::ProcessInAST); +#endif // ~/ENABLE_MPLFE_AST // output control options RegisterFactoryFunction(kOutputPath, @@ -337,6 +363,10 @@ bool MPLFEOptions::InitFactory() { RegisterFactoryFunction(kDumpThreadTime, &MPLFEOptions::ProcessDumpThreadTime); + RegisterFactoryFunction(kRC, + &MPLFEOptions::ProcessRC); + RegisterFactoryFunction(kNoBarrier, + &MPLFEOptions::ProcessNoBarrier); // On Demand Type Creation RegisterFactoryFunction(kXBootClassPath, &MPLFEOptions::ProcessXbootclasspath); @@ -437,6 +467,15 @@ bool MPLFEOptions::ProcessInDex(const Option &opt) { return true; } +#ifdef ENABLE_MPLFE_AST +bool MPLFEOptions::ProcessInAST(const Option &opt) { + std::list listFiles = SplitByComma(opt.Args()); + for (const std::string &fileName : listFiles) { + FEOptions::GetInstance().AddInputASTFile(fileName); + } + return true; +} +#endif // ~/ENABLE_MPLFE_AST bool MPLFEOptions::ProcessInputMplt(const Option &opt) { std::list listFiles = SplitByComma(opt.Args()); @@ -584,6 +623,17 @@ bool MPLFEOptions::ProcessEmitJBCLocalVarInfo(const Option &opt) { return true; } +// bc compiler options +bool MPLFEOptions::ProcessRC(const Option &opt) { + FEOptions::GetInstance().SetRC(true); + return true; +} + +bool MPLFEOptions::ProcessNoBarrier(const Option &opt) { + FEOptions::GetInstance().SetNoBarrier(true); + return true; +} + // general stmt/bb/cfg debug options bool MPLFEOptions::ProcessDumpGeneralCFGGraph(const Option &opt) { FEOptions::GetInstance().SetIsDumpGeneralCFGGraph(true); @@ -623,6 +673,12 @@ void MPLFEOptions::ProcessInputFiles(const std::vector &inputs) { FE_INFO_LEVEL(FEOptions::kDumpLevelInfoDetail, "DEX file detected: %s", inputName.c_str()); FEOptions::GetInstance().AddInputDexFile(inputName); break; +#ifdef ENABLE_MPLFE_AST + case FEFileType::kAST: + FE_INFO_LEVEL(FEOptions::kDumpLevelInfoDetail, "AST file detected: %s", inputName.c_str()); + FEOptions::GetInstance().AddInputASTFile(inputName); + break; +#endif // ~/ENABLE_MPLFE_AST default: WARN(kLncErr, "unsupported file format (%s)", inputName.c_str()); break; diff --git a/src/mplfe/common/src/simple_xml.cpp b/src/mplfe/common/src/simple_xml.cpp index edc88931548d690ae5de5c726bce1454ccd743cc..ecb6bab9345b227354ed71d2f688274ea50543ec 100644 --- a/src/mplfe/common/src/simple_xml.cpp +++ b/src/mplfe/common/src/simple_xml.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/common/src/simple_zip.cpp b/src/mplfe/common/src/simple_zip.cpp index 82b63161a6a3dfc7af8eeeb3fba980e7151e650a..4b6d15c512316b25dcd510c31f7307b2175f47b0 100644 --- a/src/mplfe/common/src/simple_zip.cpp +++ b/src/mplfe/common/src/simple_zip.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/dex_input/include/dex_op.h b/src/mplfe/dex_input/include/dex_op.h index bb0b28efecaee11b263b8277adc5736500595926..ba1c965d73105c03302599ced2ba7af2431cbb0f 100644 --- a/src/mplfe/dex_input/include/dex_op.h +++ b/src/mplfe/dex_input/include/dex_op.h @@ -36,7 +36,7 @@ class DexOp : public BCInstruction { static std::string GetArrayElementTypeFromArrayType(const std::string &typeName); protected: - void ParseImpl(const BCClassMethod &method) override {} + void ParseImpl(BCClassMethod &method) override {} // Should be removed after all instruction impled std::list EmitToFEIRStmtsImpl() override { return std::list(); @@ -113,7 +113,7 @@ class DexOpReturn : public DexOp { protected: void SetVAImpl(uint32 num) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; std::list EmitToFEIRStmtsImpl() override; DexReg vA; bool isReturnVoid = false; @@ -130,8 +130,9 @@ class DexOpConst : public DexOp { void SetVBImpl(uint32 num) override; void SetWideVBImpl(uint64 num) override; std::list EmitToFEIRStmtsImpl() override; + + private: DexReg vA; - DexReg vAtmp; }; // 0x1a ~ 0x1b @@ -143,9 +144,11 @@ class DexOpConstString : public DexOp { protected: void SetVAImpl(uint32 num) override; void SetVBImpl(uint32 num) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; std::list EmitToFEIRStmtsImpl() override; + uint32 fileIdx; DexReg vA; + MapleString strValue; }; // 0x1c @@ -157,11 +160,11 @@ class DexOpConstClass : public DexOp { protected: void SetVAImpl(uint32 num) override; void SetVBImpl(uint32 num) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; std::list EmitToFEIRStmtsImpl() override; DexReg vA; uint32 dexTypeIdx; - std::string typeName; + GStrIdx mplTypeNameIdx; }; // 0x1d ~ 0x1e @@ -185,7 +188,7 @@ class DexOpCheckCast : public DexOp { protected: void SetVAImpl(uint32 num) override; void SetVBImpl(uint32 num) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; std::list EmitToFEIRStmtsImpl() override; DexReg vA; DexReg vDef; @@ -203,7 +206,7 @@ class DexOpInstanceOf : public DexOp { void SetVAImpl(uint32 num) override; void SetVBImpl(uint32 num) override; void SetVCImpl(uint32 num) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; std::list EmitToFEIRStmtsImpl() override; DexReg vA; DexReg vB; @@ -234,10 +237,12 @@ class DexOpNewInstance : public DexOp { private: void SetVAImpl(uint32 num) override; void SetVBImpl(uint32 num) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; std::list EmitToFEIRStmtsImpl() override; DexReg vA; bool isSkipNewString = false; + // isRcPermanent is true means the rc annotation @Permanent is used + bool isRcPermanent = false; }; // 0x23 @@ -250,10 +255,12 @@ class DexOpNewArray : public DexOp { void SetVAImpl(uint32 num) override; void SetVBImpl(uint32 num) override; void SetVCImpl(uint32 num) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; std::list EmitToFEIRStmtsImpl() override; DexReg vA; DexReg vB; + // isRcPermanent is true means the rc annotation @Permanent is used + bool isRcPermanent = false; }; // 0x24 ~ 0x25 @@ -270,13 +277,12 @@ class DexOpFilledNewArray : public DexOp { void SetVAImpl(uint32 num) override; void SetVBImpl(uint32 num) override; void SetArgsImpl(const MapleList &args) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; bool isRange = false; uint32 argsSize = 0; uint32 dexArrayTypeIdx = UINT32_MAX; GStrIdx arrayTypeNameIdx; GStrIdx elemTypeNameIdx; - std::string typeName; MapleList argRegs; MapleVector vRegs; }; @@ -290,7 +296,7 @@ class DexOpFillArrayData : public DexOp { private: void SetVAImpl(uint32 num) override; void SetVBImpl(uint32 num) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; std::list EmitToFEIRStmtsImpl() override; DexReg vA; const int8 *arrayData = nullptr; @@ -319,7 +325,7 @@ class DexOpGoto : public DexOp { private: std::vector GetTargetsImpl() const override; void SetVAImpl(uint32 num) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; std::list EmitToFEIRStmtsImpl() override; int32 offset; uint32 target; @@ -334,13 +340,13 @@ class DexOpSwitch : public DexOp { private: void SetVAImpl(uint32 num) override; void SetVBImpl(uint32 num) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; std::vector GetTargetsImpl() const override; std::list EmitToFEIRStmtsImpl() override; bool isPacked = false; int32 offset; DexReg vA; - std::map> keyTargetOPpcMap; + MapleMap> keyTargetOPpcMap; }; // 0x2d ~ 0x31 @@ -371,7 +377,7 @@ class DexOpIfTest : public DexOp { void SetVAImpl(uint32 num) override; void SetVBImpl(uint32 num) override; void SetVCImpl(uint32 num) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; std::list EmitToFEIRStmtsImpl() override; DexReg vA; DexReg vB; @@ -389,7 +395,7 @@ class DexOpIfTestZ : public DexOp { std::vector GetTargetsImpl() const override; void SetVAImpl(uint32 num) override; void SetVBImpl(uint32 num) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; std::list EmitToFEIRStmtsImpl() override; DexReg vA; int32 offset = 0; @@ -413,7 +419,7 @@ class DexOpAget : public DexOp { void SetVAImpl(uint32 num) override; void SetVBImpl(uint32 num) override; void SetVCImpl(uint32 num) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; void SetRegTypeInTypeInferImpl() override; std::list EmitToFEIRStmtsImpl() override; DexReg vA; @@ -431,7 +437,7 @@ class DexOpAput : public DexOp { void SetVAImpl(uint32 num) override; void SetVBImpl(uint32 num) override; void SetVCImpl(uint32 num) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; void SetRegTypeInTypeInferImpl() override; std::list EmitToFEIRStmtsImpl() override; DexReg vA; @@ -449,7 +455,7 @@ class DexOpIget : public DexOp { void SetVAImpl(uint32 num) override; void SetVBImpl(uint32 num) override; void SetVCImpl(uint32 num) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; std::list EmitToFEIRStmtsImpl() override; DexReg vA; DexReg vB; @@ -466,7 +472,7 @@ class DexOpIput : public DexOp { void SetVAImpl(uint32 num) override; void SetVBImpl(uint32 num) override; void SetVCImpl(uint32 num) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; std::list EmitToFEIRStmtsImpl() override; DexReg vA; DexReg vB; @@ -482,11 +488,12 @@ class DexOpSget : public DexOp { private: void SetVAImpl(uint32 num) override; void SetVBImpl(uint32 num) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; std::list EmitToFEIRStmtsImpl() override; uint32 index = UINT32_MAX; GStrIdx containerNameIdx; DexReg vA; + int32 dexFileHashCode = -1; }; // 0x67 ~ 0x6d @@ -498,10 +505,11 @@ class DexOpSput : public DexOp { private: void SetVAImpl(uint32 num) override; void SetVBImpl(uint32 num) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; std::list EmitToFEIRStmtsImpl() override; DexReg vA; uint32 index = UINT32_MAX; + int32 dexFileHashCode = -1; }; class DexOpInvoke : public DexOp { @@ -515,7 +523,7 @@ class DexOpInvoke : public DexOp { void SetVBImpl(uint32 num) override; void SetVCImpl(uint32 num) override; void SetArgsImpl(const MapleList &args) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; void PrepareInvokeParametersAndReturn(const FEStructMethodInfo &feMethodInfo, FEIRStmtCallAssign &stmt) const; std::list EmitToFEIRStmtsImpl() override; bool IsStatic() const; @@ -648,7 +656,7 @@ class DexOpInvokePolymorphic: public DexOpInvoke { protected: void SetVHImpl(uint32 num) override; - void ParseImpl(const BCClassMethod &method) override; + void ParseImpl(BCClassMethod &method) override; std::list EmitToFEIRStmtsImpl() override; bool isStatic = false; uint32 protoIdx; diff --git a/src/mplfe/dex_input/include/dex_pragma.h b/src/mplfe/dex_input/include/dex_pragma.h index 825e0fc69d3c39ee6c8ab0fcf225e4cdc651e844..3041c0aa75ebf80a0a59b62db2a183a5b4eb832e 100644 --- a/src/mplfe/dex_input/include/dex_pragma.h +++ b/src/mplfe/dex_input/include/dex_pragma.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/dex_input/include/dex_reader.h b/src/mplfe/dex_input/include/dex_reader.h index f69345c09426401a6309bc6182eba90743782146..6cb7fcda51a1db296e2c0f060b8591d1f2bdd615 100644 --- a/src/mplfe/dex_input/include/dex_reader.h +++ b/src/mplfe/dex_input/include/dex_reader.h @@ -48,6 +48,8 @@ class DexReader : public BCReader { std::unique_ptr>> ResolveTryInfos(const IDexMethodItem* dexMethodItem) const; void ResovleSrcPositionInfo(const IDexMethodItem* dexMethodItem, std::map &srcPosInfo) const; + std::unique_ptr>>> ResovleSrcLocalInfo( + const IDexMethodItem &dexMethodItem) const; bool ReadAllDepTypeNames(std::unordered_set &depSet); bool ReadMethodDepTypeNames(std::unordered_set &depSet, uint32 classIdx, uint32 methodItemx, bool isVirtual) const; @@ -60,6 +62,7 @@ class DexReader : public BCReader { const uint16 *GetMethodInstOffset(const IDexMethodItem* dexMethodItem) const; uint16 GetClassMethodRegisterTotalSize(const IDexMethodItem* dexMethodItem) const; uint16 GetClassMethodRegisterInSize(const IDexMethodItem* dexMethodItem) const; + uint32 GetCodeOff(const IDexMethodItem* dexMethodItem) const; private: std::string GetStringFromIdxImpl(uint32 idx) const override; diff --git a/src/mplfe/dex_input/include/dexfile_factory.h b/src/mplfe/dex_input/include/dexfile_factory.h index 7633aba3f85d0cf68280e4b2b80d7737391afb72..3e30a88b1a94f75c3efeb81587266980184d58da 100644 --- a/src/mplfe/dex_input/include/dexfile_factory.h +++ b/src/mplfe/dex_input/include/dexfile_factory.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/dex_input/include/dexfile_interface.h b/src/mplfe/dex_input/include/dexfile_interface.h index 58bfd99ef4b24f6daee878c9f4fb400c78761333..788501da13f0bd5545577d140300e8cafd4d059d 100644 --- a/src/mplfe/dex_input/include/dexfile_interface.h +++ b/src/mplfe/dex_input/include/dexfile_interface.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -463,6 +463,8 @@ class IDexMethodItem { std::map> &pcInstructionMap) const; void GetTryItems(const IDexFile &dexFile, std::vector &tryItems) const; void GetSrcPositionInfo(const IDexFile &dexFile, std::map &srcPosInfo) const; + void GetSrcLocalInfo(const IDexFile &dexFile, + std::map>> &srcLocal) const; private: uint32_t methodIdx; // input parameter @@ -621,6 +623,7 @@ class IDexHeader { static const IDexHeader *GetInstance(const IDexFile &dexFile); uint8_t GetMagic(uint32_t index) const; uint32_t GetChecksum() const; + std::string GetSignature() const; uint32_t GetFileSize() const; uint32_t GetHeaderSize() const; uint32_t GetEndianTag() const; diff --git a/src/mplfe/dex_input/include/dexfile_libdexfile.h b/src/mplfe/dex_input/include/dexfile_libdexfile.h index d0465f2d2240c94dbcda5d9e56f4c9b1c544dfc2..bc023da9f2d234afb1650609d5812afdea061ea6 100644 --- a/src/mplfe/dex_input/include/dexfile_libdexfile.h +++ b/src/mplfe/dex_input/include/dexfile_libdexfile.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/dex_input/src/class_linker.cpp b/src/mplfe/dex_input/src/class_linker.cpp index caf5847f8ae979a7fdea5582a08653d9a161ff43..f613b045766865408ddc2fbe3205fc2752ec12c4 100644 --- a/src/mplfe/dex_input/src/class_linker.cpp +++ b/src/mplfe/dex_input/src/class_linker.cpp @@ -100,6 +100,9 @@ void ClassLinker::FindClass(const std::string &className, ClassLoaderInfo *class GStrIdx nameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(className); auto it = processedClassName.find(nameIdx); if (it != processedClassName.end()) { + if (isDefClass) { + FE_INFO_LEVEL(FEOptions::kDumpLevelInfo, "Same class is existed: %s", className.c_str()); + } return; } // Find in bootclasspath diff --git a/src/mplfe/dex_input/src/dex_op.cpp b/src/mplfe/dex_input/src/dex_op.cpp index 286e5b25ec76cad5e97fdd38ef7f9f744991b82b..e6cff02fe4f1084d49a7f540bbefef7366363ecc 100644 --- a/src/mplfe/dex_input/src/dex_op.cpp +++ b/src/mplfe/dex_input/src/dex_op.cpp @@ -25,6 +25,7 @@ #include "dex_strfac.h" #include "fe_options.h" #include "feir_var_name.h" +#include "ark_annotation_processor.h" namespace maple { namespace bc { @@ -71,20 +72,28 @@ DexOpMove::DexOpMove(MapleAllocator &allocatorIn, uint32 pcIn, DexOpCode opcodeI void DexOpMove::SetVAImpl(uint32 num) { vA.regNum = num; vA.isDef = true; - vA.regType = allocator.GetMemPool()->New(allocator, vA, GStrIdx(0), false, true); + GStrIdx typeNameIdx; + if (kDexOpMove <= opcode && opcode <= kDexOpMove16) { + typeNameIdx = BCUtil::GetIntIdx(); + } else if (kDexOpMoveWide <= opcode && opcode <= kDexOpMoveWide16) { + typeNameIdx = BCUtil::GetLongIdx(); + } else if (kDexOpMoveObject <= opcode && opcode <= kDexOpMoveObject16) { + typeNameIdx = BCUtil::GetJavaObjectNameMplIdx(); + } else { + CHECK_FATAL(false, "invalid opcode: %x in `DexOpMove`", opcode); + } + vA.regType = allocator.GetMemPool()->New(allocator, vA, typeNameIdx, true); defedRegs.emplace_back(&vA); } void DexOpMove::SetVBImpl(uint32 num) { vB.regNum = num; + vB.regTypeItem = vA.regTypeItem; usedRegs.emplace_back(&vB); } void DexOpMove::SetRegTypeInTypeInferImpl() { - vA.regTypeItem = vB.regTypeItem; - vA.regType->SetRegTypeItem(vB.regTypeItem); - vA.regType->UpdateUsedSet(vB.regTypeItem); - vA.regValue = vB.regValue; + vB.regType->RegisterRelatedBCRegType(vA.regType); } std::list DexOpMove::EmitToFEIRStmtsImpl() { @@ -144,12 +153,14 @@ void DexOpMoveException::SetBCRegTypeImpl(const BCInstruction &inst) { GStrIdx exceptionTypeNameIdx = *(catchedExTypeNamesIdx.begin()); vA.regType = allocator.GetMemPool()->New(allocator, vA, exceptionTypeNameIdx); // If exception type is primitive type, it should be <* void> - vA.regTypeItem->isPrimPtr = (vA.GetBasePrimType() != PTY_ref); + if (vA.GetBasePrimType() != PTY_ref) { + vA.regTypeItem->typeNameIdx = BCUtil::GetJavaThrowableNameMplIdx(); + } } std::list DexOpMoveException::EmitToFEIRStmtsImpl() { std::list stmts; - std::unique_ptr readExpr = std::make_unique(PTY_ptr, -kSregThrownval); + std::unique_ptr readExpr = std::make_unique(PTY_ref, -kSregThrownval); UniqueFEIRStmt stmt = std::make_unique(vA.GenFEIRVarReg(), std::move(readExpr)); stmts.emplace_back(std::move(stmt)); return stmts; @@ -168,7 +179,7 @@ void DexOpReturn::SetVAImpl(uint32 num) { usedRegs.emplace_back(&vA); } -void DexOpReturn::ParseImpl(const BCClassMethod &method) { +void DexOpReturn::ParseImpl(BCClassMethod &method) { GStrIdx usedTypeNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(namemangler::EncodeName(method.GetSigTypeNames().at(0))); vA.regTypeItem = allocator.GetMemPool()->New(usedTypeNameIdx); @@ -194,19 +205,8 @@ DexOpConst::DexOpConst(MapleAllocator &allocatorIn, uint32 pcIn, DexOpCode opcod void DexOpConst::SetVAImpl(uint32 num) { vA.regNum = num; - GStrIdx typeNameIdx; - if (isWide) { - typeNameIdx = BCUtil::GetLongIdx(); - } else { - typeNameIdx = BCUtil::GetIntIdx(); - } - vA.regType = allocator.GetMemPool()->New(allocator, vA, typeNameIdx, false, true); - vA.regValue = allocator.GetMemPool()->New(); vA.isDef = true; - - vAtmp.regNum = num; - vAtmp.regType = allocator.GetMemPool()->New(allocator, vAtmp, typeNameIdx, false, true); - vAtmp.regValue = vA.regValue; + vA.regValue = allocator.GetMemPool()->New(); defedRegs.emplace_back(&vA); } @@ -214,17 +214,32 @@ void DexOpConst::SetVBImpl(uint32 num) { if (opcode != kDexOpConstWide) { vA.regValue->primValue.raw32 = num; } + if (!isWide) { + vA.regType = allocator.GetMemPool()->New(allocator, vA, BCUtil::GetIntIdx()); + } } void DexOpConst::SetWideVBImpl(uint64 num) { if (opcode == kDexOpConstWide) { vA.regValue->primValue.raw64 = num; } + if (isWide) { + vA.regType = allocator.GetMemPool()->New(allocator, vA, BCUtil::GetLongIdx()); + } } std::list DexOpConst::EmitToFEIRStmtsImpl() { std::list ans; UniqueFEIRExpr expr; + DexReg vATmp; + vATmp.regNum = vA.regNum; + GStrIdx typeNameIdx; + if (isWide) { + typeNameIdx = BCUtil::GetLongIdx(); + } else { + typeNameIdx = BCUtil::GetIntIdx(); + } + vATmp.regType = allocator.GetMemPool()->New(allocator, vATmp, typeNameIdx, true); switch (opcode) { case kDexOpConst4: { expr = FEIRBuilder::CreateExprConstI8(static_cast(vA.regValue->primValue.raw32)); @@ -273,10 +288,10 @@ std::list DexOpConst::EmitToFEIRStmtsImpl() { break; } } - UniqueFEIRStmt stmt = FEIRBuilder::CreateStmtDAssign(vAtmp.GenFEIRVarReg(), std::move(expr)); + UniqueFEIRStmt stmt = FEIRBuilder::CreateStmtDAssign(vATmp.GenFEIRVarReg(), std::move(expr)); ans.emplace_back(std::move(stmt)); - if (!(*vA.regTypeItem == *vAtmp.regTypeItem)) { - stmt = FEIRBuilder::CreateStmtRetype(vA.GenFEIRVarReg(), vAtmp.GenFEIRVarReg()); + if (!(*vA.regTypeItem == *vATmp.regTypeItem)) { + stmt = FEIRBuilder::CreateStmtRetype(vA.GenFEIRVarReg(), vATmp.GenFEIRVarReg()); ans.emplace_back(std::move(stmt)); } return ans; @@ -284,12 +299,11 @@ std::list DexOpConst::EmitToFEIRStmtsImpl() { // ========== DexOpConstString ========== DexOpConstString::DexOpConstString(MapleAllocator &allocatorIn, uint32 pcIn, DexOpCode opcodeIn) - : DexOp(allocatorIn, pcIn, opcodeIn) {} + : DexOp(allocatorIn, pcIn, opcodeIn), strValue(allocator.GetMemPool()) {} void DexOpConstString::SetVAImpl(uint32 num) { vA.regNum = num; vA.regType = allocator.GetMemPool()->New(allocator, vA, BCUtil::GetJavaStringNameMplIdx()); - vA.regValue = allocator.GetMemPool()->New(); vA.isDef = true; defedRegs.emplace_back(&vA); } @@ -298,16 +312,22 @@ void DexOpConstString::SetVBImpl(uint32 num) { vA.dexLitStrIdx = num; } -void DexOpConstString::ParseImpl(const BCClassMethod &method) { - const std::string &literalString = method.GetBCClass().GetBCParser().GetReader()->GetStringFromIdx(vA.dexLitStrIdx); - vA.regValue->literalStrIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(literalString); +void DexOpConstString::ParseImpl(BCClassMethod &method) { + fileIdx = method.GetBCClass().GetBCParser().GetReader()->GetFileIndex(); + strValue = method.GetBCClass().GetBCParser().GetReader()->GetStringFromIdx(vA.dexLitStrIdx); + if (FEOptions::GetInstance().IsRC() && !method.IsRcPermanent() && + ArkAnnotation::GetInstance().IsPermanent(strValue.c_str())) { + // "Lcom/huawei/ark/annotation/Permanent;" and "Lark/annotation/Permanent;" + // indicates next new-instance / new-array Permanent object + method.SetIsRcPermanent(true); + } } std::list DexOpConstString::EmitToFEIRStmtsImpl() { std::list stmts; UniqueFEIRVar dstVar = vA.GenFEIRVarReg(); - UniqueFEIRStmt stmt = std::make_unique(std::move(dstVar), vA.regValue->literalStrIdx, - vA.dexLitStrIdx); + UniqueFEIRStmt stmt = std::make_unique(std::move(dstVar), strValue.c_str(), + fileIdx, vA.dexLitStrIdx); stmts.emplace_back(std::move(stmt)); return stmts; } @@ -327,15 +347,15 @@ void DexOpConstClass::SetVBImpl(uint32 num) { dexTypeIdx = num; } -void DexOpConstClass::ParseImpl(const BCClassMethod &method) { - typeName = method.GetBCClass().GetBCParser().GetReader()->GetTypeNameFromIdx(dexTypeIdx); +void DexOpConstClass::ParseImpl(BCClassMethod &method) { + const std::string &typeName = method.GetBCClass().GetBCParser().GetReader()->GetTypeNameFromIdx(dexTypeIdx); + const std::string &mplTypeName = namemangler::EncodeName(typeName); + mplTypeNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(mplTypeName); } std::list DexOpConstClass::EmitToFEIRStmtsImpl() { std::list stmts; UniqueFEIRVar dstVar = vA.GenFEIRVarReg(); - const std::string &mplTypeName = namemangler::EncodeName(typeName); - GStrIdx mplTypeNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(mplTypeName); UniqueFEIRType refType = std::make_unique(BCUtil::GetPrimType(mplTypeNameIdx), mplTypeNameIdx); UniqueFEIRExpr expr = std::make_unique(std::move(refType), INTRN_JAVA_CONST_CLASS, std::make_unique(PTY_ref), dexTypeIdx); @@ -350,6 +370,7 @@ DexOpMonitor::DexOpMonitor(MapleAllocator &allocatorIn, uint32 pcIn, DexOpCode o void DexOpMonitor::SetVAImpl(uint32 num) { vA.regNum = num; + vA.regTypeItem = allocator.GetMemPool()->New(BCUtil::GetJavaObjectNameMplIdx(), true); usedRegs.emplace_back(&vA); } @@ -374,6 +395,7 @@ DexOpCheckCast::DexOpCheckCast(MapleAllocator &allocatorIn, uint32 pcIn, DexOpCo void DexOpCheckCast::SetVAImpl(uint32 num) { vA.regNum = num; + vA.regTypeItem = allocator.GetMemPool()->New(BCUtil::GetJavaObjectNameMplIdx(), true); usedRegs.emplace_back(&vA); // use vA to gen vDef vDef.regNum = num; vDef.isDef = true; @@ -384,7 +406,7 @@ void DexOpCheckCast::SetVBImpl(uint32 num) { targetDexTypeIdx = num; } -void DexOpCheckCast::ParseImpl(const BCClassMethod &method) { +void DexOpCheckCast::ParseImpl(BCClassMethod &method) { const std::string &typeName = method.GetBCClass().GetBCParser().GetReader()->GetTypeNameFromIdx(targetDexTypeIdx); targetTypeNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(namemangler::EncodeName(typeName)); vDef.regType = allocator.GetMemPool()->New(allocator, vDef, targetTypeNameIdx); @@ -422,6 +444,7 @@ void DexOpInstanceOf::SetVAImpl(uint32 num) { void DexOpInstanceOf::SetVBImpl(uint32 num) { vB.regNum = num; + vB.regTypeItem = allocator.GetMemPool()->New(BCUtil::GetJavaObjectNameMplIdx(), true); usedRegs.emplace_back(&vB); } @@ -429,7 +452,7 @@ void DexOpInstanceOf::SetVCImpl(uint32 num) { targetDexTypeIdx = num; } -void DexOpInstanceOf::ParseImpl(const BCClassMethod &method) { +void DexOpInstanceOf::ParseImpl(BCClassMethod &method) { typeName = method.GetBCClass().GetBCParser().GetReader()->GetTypeNameFromIdx(targetDexTypeIdx); } @@ -440,6 +463,8 @@ std::list DexOpInstanceOf::EmitToFEIRStmtsImpl() { FEIRBuilder::CreateTypeByJavaName(targetTypeName, true), targetDexTypeIdx); stmts.emplace_back(std::move(stmt)); + typeName.clear(); + typeName.shrink_to_fit(); return stmts; } @@ -456,10 +481,14 @@ void DexOpArrayLength::SetVAImpl(uint32 num) { void DexOpArrayLength::SetVBImpl(uint32 num) { vB.regNum = num; + vB.regTypeItem = allocator.GetMemPool()->New(BCUtil::GetABooleanIdx(), true); usedRegs.emplace_back(&vB); } std::list DexOpArrayLength::EmitToFEIRStmtsImpl() { + CHECK_FATAL(BCUtil::IsArrayType(vB.regTypeItem->typeNameIdx), + "Invalid array type: %s in DexOpArrayLength", + GlobalTables::GetStrTable().GetStringFromStrIdx(vB.regTypeItem->typeNameIdx).c_str()); std::list stmts; UniqueFEIRStmt stmt = FEIRBuilder::CreateStmtArrayLength(vA.GenFEIRVarReg(), vB.GenFEIRVarReg()); stmts.emplace_back(std::move(stmt)); @@ -479,7 +508,7 @@ void DexOpNewInstance::SetVBImpl(uint32 num) { vA.dexTypeIdx = num; } -void DexOpNewInstance::ParseImpl(const BCClassMethod &method) { +void DexOpNewInstance::ParseImpl(BCClassMethod &method) { const std::string &typeName = method.GetBCClass().GetBCParser().GetReader()->GetTypeNameFromIdx(vA.dexTypeIdx); // we should register vA in defs, even if it was new-instance java.lang.String. // Though new-instance java.lang.String would be replaced by StringFactory at following java.lang.String., @@ -488,6 +517,10 @@ void DexOpNewInstance::ParseImpl(const BCClassMethod &method) { vA.regType = allocator.GetMemPool()->New(allocator, vA, GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(namemangler::EncodeName(typeName))); defedRegs.emplace_back(&vA); + if (method.IsRcPermanent()) { + isRcPermanent = true; + method.SetIsRcPermanent(false); + } } std::list DexOpNewInstance::EmitToFEIRStmtsImpl() { @@ -499,7 +532,8 @@ std::list DexOpNewInstance::EmitToFEIRStmtsImpl() { INTRN_JAVA_CLINIT_CHECK, std::make_unique(PTY_ref, vA.regTypeItem->typeNameIdx), nullptr, vA.dexTypeIdx); stmts.emplace_back(std::move(stmtCall)); - UniqueFEIRExpr exprJavaNewInstance = FEIRBuilder::CreateExprJavaNewInstance(vA.GenFEIRType(), vA.dexTypeIdx); + UniqueFEIRExpr exprJavaNewInstance = FEIRBuilder::CreateExprJavaNewInstance( + vA.GenFEIRType(), vA.dexTypeIdx, isRcPermanent); UniqueFEIRStmt stmt = FEIRBuilder::CreateStmtDAssign(vA.GenFEIRVarReg(), std::move(exprJavaNewInstance)); stmts.emplace_back(std::move(stmt)); return stmts; @@ -525,17 +559,21 @@ void DexOpNewArray::SetVCImpl(uint32 num) { vA.dexTypeIdx = num; } -void DexOpNewArray::ParseImpl(const BCClassMethod &method) { +void DexOpNewArray::ParseImpl(BCClassMethod &method) { const std::string &typeName = method.GetBCClass().GetBCParser().GetReader()->GetTypeNameFromIdx(vA.dexTypeIdx); vA.regType = allocator.GetMemPool()->New(allocator, vA, GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(namemangler::EncodeName(typeName))); + if (method.IsRcPermanent()) { + isRcPermanent = true; + method.SetIsRcPermanent(false); + } } std::list DexOpNewArray::EmitToFEIRStmtsImpl() { std::list stmts; UniqueFEIRExpr exprSize = FEIRBuilder::CreateExprDRead(vB.GenFEIRVarReg()); UniqueFEIRExpr exprJavaNewArray = FEIRBuilder::CreateExprJavaNewArray(vA.GenFEIRType(), std::move(exprSize), - vA.dexTypeIdx); + vA.dexTypeIdx, isRcPermanent); UniqueFEIRStmt stmt = FEIRBuilder::CreateStmtDAssign(vA.GenFEIRVarReg(), std::move(exprJavaNewArray)); stmts.emplace_back(std::move(stmt)); return stmts; @@ -563,8 +601,8 @@ GStrIdx DexOpFilledNewArray::GetReturnType() const { return arrayTypeNameIdx; } -void DexOpFilledNewArray::ParseImpl(const BCClassMethod &method) { - typeName = method.GetBCClass().GetBCParser().GetReader()->GetTypeNameFromIdx(dexArrayTypeIdx); +void DexOpFilledNewArray::ParseImpl(BCClassMethod &method) { + const std::string &typeName = method.GetBCClass().GetBCParser().GetReader()->GetTypeNameFromIdx(dexArrayTypeIdx); const std::string &typeNameMpl = namemangler::EncodeName(typeName); arrayTypeNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(typeNameMpl); const std::string &elemTypeName = GetArrayElementTypeFromArrayType(typeNameMpl); @@ -608,6 +646,7 @@ DexOpFillArrayData::DexOpFillArrayData(MapleAllocator &allocatorIn, uint32 pcIn, void DexOpFillArrayData::SetVAImpl(uint32 num) { vA.regNum = num; + vA.regTypeItem = allocator.GetMemPool()->New(BCUtil::GetVoidIdx(), true); usedRegs.emplace_back(&vA); } @@ -615,18 +654,25 @@ void DexOpFillArrayData::SetVBImpl(uint32 num) { offset = static_cast(num); // signed value in unsigned data buffer } -void DexOpFillArrayData::ParseImpl(const BCClassMethod &method) { +void DexOpFillArrayData::ParseImpl(BCClassMethod &method) { const uint16 *data = method.GetInstPos() + pc + offset; size = *(reinterpret_cast(&data[2])); arrayData = reinterpret_cast(&data[4]); } std::list DexOpFillArrayData::EmitToFEIRStmtsImpl() { + CHECK_FATAL(BCUtil::IsArrayType(vA.regTypeItem->typeNameIdx), + "Invalid array type: %s in DexOpFillArrayData", + GlobalTables::GetStrTable().GetStringFromStrIdx(vA.regTypeItem->typeNameIdx).c_str()); std::list stmts; thread_local static std::stringstream ss(""); ss.str(""); ss << "const_array_" << funcNameIdx << "_" << pc; UniqueFEIRVar arrayReg = vA.GenFEIRVarReg(); + const std::string &arrayTypeName = GlobalTables::GetStrTable().GetStringFromStrIdx(vA.regTypeItem->typeNameIdx); + CHECK_FATAL(arrayTypeName.size() > 1 && arrayTypeName.at(0) == 'A' && + BCUtil::IsJavaPrimitveType(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(arrayTypeName.substr(1))), + "Invalid type %s", arrayTypeName.c_str()); UniqueFEIRStmt stmt = FEIRBuilder::CreateStmtJavaFillArrayData(std::move(arrayReg), arrayData, size, ss.str()); stmts.emplace_back(std::move(stmt)); return stmts; @@ -638,24 +684,27 @@ DexOpThrow::DexOpThrow(MapleAllocator &allocatorIn, uint32 pcIn, DexOpCode opcod void DexOpThrow::SetVAImpl(uint32 num) { vA.regNum = num; + vA.regTypeItem = allocator.GetMemPool()->New(BCUtil::GetJavaThrowableNameMplIdx(), true); usedRegs.emplace_back(&vA); } std::list DexOpThrow::EmitToFEIRStmtsImpl() { std::list stmts; - DexReg vATmp; - vATmp.regNum = vA.regNum; - if (vA.GetPrimType() != PTY_ref) { - // avoid type degraded, cast const 0 to Throwable as default. - vATmp.regTypeItem = allocator.GetMemPool()->New(BCUtil::GetJavaThrowableNameMplIdx(), false, true); - UniqueFEIRStmt stmtRetype = FEIRBuilder::CreateStmtRetype(vATmp.GenFEIRVarReg(), vA.GenFEIRVarReg()); - stmts.emplace_back(std::move(stmtRetype)); + if (BCUtil::IsJavaReferenceType(vA.regTypeItem->typeNameIdx)) { + UniqueFEIRExpr expr = FEIRBuilder::CreateExprDRead(vA.GenFEIRVarReg()); + UniqueFEIRStmt stmt = std::make_unique(OP_throw, std::move(expr)); + stmts.emplace_back(std::move(stmt)); } else { - vATmp.regTypeItem = vA.regTypeItem; + CHECK_FATAL(vA.regValue != nullptr && vA.regValue->primValue.raw32 == 0, "only null or ref can be thrown."); + DexReg vAtmp; + vAtmp.regNum = vA.regNum; + vAtmp.regType = allocator.GetMemPool()->New(allocator, vAtmp, BCUtil::GetJavaThrowableNameMplIdx()); + UniqueFEIRStmt retypeStmt = FEIRBuilder::CreateStmtRetype(vAtmp.GenFEIRVarReg(), vA.GenFEIRVarReg()); + stmts.emplace_back(std::move(retypeStmt)); + UniqueFEIRExpr expr = FEIRBuilder::CreateExprDRead(vAtmp.GenFEIRVarReg()); + UniqueFEIRStmt stmt = std::make_unique(OP_throw, std::move(expr)); + stmts.emplace_back(std::move(stmt)); } - UniqueFEIRExpr expr = FEIRBuilder::CreateExprDRead(vATmp.GenFEIRVarReg()); - UniqueFEIRStmt stmt = std::make_unique(OP_throw, std::move(expr)); - stmts.emplace_back(std::move(stmt)); return stmts; } @@ -673,7 +722,7 @@ std::vector DexOpGoto::GetTargetsImpl() const { return res; } -void DexOpGoto::ParseImpl(const BCClassMethod &method) { +void DexOpGoto::ParseImpl(BCClassMethod &method) { target = offset + pc; } @@ -686,7 +735,7 @@ std::list DexOpGoto::EmitToFEIRStmtsImpl() { // ========== DexOpSwitch ========= DexOpSwitch::DexOpSwitch(MapleAllocator &allocatorIn, uint32 pcIn, DexOpCode opcodeIn) - : DexOp(allocatorIn, pcIn, opcodeIn) { + : DexOp(allocatorIn, pcIn, opcodeIn), keyTargetOPpcMap(allocator.Adapter()) { isPacked = (opcode == kDexOpPackedSwitch); } @@ -700,7 +749,7 @@ void DexOpSwitch::SetVBImpl(uint32 num) { offset = static_cast(num); } -void DexOpSwitch::ParseImpl(const BCClassMethod &method) { +void DexOpSwitch::ParseImpl(BCClassMethod &method) { const uint16 *data = method.GetInstPos() + pc + offset; if (isPacked) { uint16 size = data[1]; @@ -800,11 +849,13 @@ DexOpIfTest::DexOpIfTest(MapleAllocator &allocatorIn, uint32 pcIn, DexOpCode opc void DexOpIfTest::SetVAImpl(uint32 num) { vA.regNum = num; + vA.regTypeItem = allocator.GetMemPool()->New(BCUtil::GetIntIdx(), true); usedRegs.emplace_back(&vA); } void DexOpIfTest::SetVBImpl(uint32 num) { vB.regNum = num; + vB.regTypeItem = allocator.GetMemPool()->New(BCUtil::GetIntIdx(), true); usedRegs.emplace_back(&vB); } @@ -818,7 +869,7 @@ std::vector DexOpIfTest::GetTargetsImpl() const { return res; } -void DexOpIfTest::ParseImpl(const BCClassMethod &method) { +void DexOpIfTest::ParseImpl(BCClassMethod &method) { target = offset + pc; } @@ -870,6 +921,7 @@ DexOpIfTestZ::DexOpIfTestZ(MapleAllocator &allocatorIn, uint32 pcIn, DexOpCode o void DexOpIfTestZ::SetVAImpl(uint32 num) { vA.regNum = num; + vA.regTypeItem = allocator.GetMemPool()->New(BCUtil::GetIntIdx(), true); usedRegs.emplace_back(&vA); } @@ -883,7 +935,7 @@ std::vector DexOpIfTestZ::GetTargetsImpl() const { return res; } -void DexOpIfTestZ::ParseImpl(const BCClassMethod &method) { +void DexOpIfTestZ::ParseImpl(BCClassMethod &method) { target = offset + pc; } @@ -922,16 +974,16 @@ void DexOpAget::SetVAImpl(uint32 num) { void DexOpAget::SetVBImpl(uint32 num) { vB.regNum = num; - usedRegs.emplace_front(&vB); + usedRegs.emplace_back(&vB); } void DexOpAget::SetVCImpl(uint32 num) { vC.regNum = num; vC.regTypeItem = allocator.GetMemPool()->New(BCUtil::GetIntIdx()); - usedRegs.emplace_back(&vC); + usedRegs.emplace_front(&vC); } -void DexOpAget::ParseImpl(const BCClassMethod &method) { +void DexOpAget::ParseImpl(BCClassMethod &method) { GStrIdx elemTypeNameIdx; GStrIdx usedTypeNameIdx; bool isIndeterminateType = false; @@ -980,29 +1032,34 @@ void DexOpAget::ParseImpl(const BCClassMethod &method) { break; } } - vA.regType = allocator.GetMemPool()->New(allocator, vA, elemTypeNameIdx, false, isIndeterminateType); - if (!vA.regType->IsIndeterminate()) { - vB.regTypeItem = allocator.GetMemPool()->New(usedTypeNameIdx); - } + vA.regType = allocator.GetMemPool()->New(allocator, vA, elemTypeNameIdx, isIndeterminateType); + vB.regTypeItem = allocator.GetMemPool()->New(usedTypeNameIdx, isIndeterminateType); } void DexOpAget::SetRegTypeInTypeInferImpl() { - if (vB.regTypeItem->isIndeterminate) { + if (vB.regType != nullptr && vC.regType != nullptr) { vB.regType->AddElemType(vA.regType); - } else { - std::string arrayTypeName = GlobalTables::GetStrTable().GetStringFromStrIdx(vB.regTypeItem->typeNameIdx); - if (arrayTypeName.size() > 1 && arrayTypeName.at(0) == 'A') { - vA.regType->SetTypeNameIdx(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(arrayTypeName.substr(1))); - vA.regType->SetIsIndeterminate(false); - } else { - CHECK_FATAL(false, "Invalid array type %s", arrayTypeName.c_str()); - } } } std::list DexOpAget::EmitToFEIRStmtsImpl() { - std::list stmts = FEIRBuilder::CreateStmtArrayLoad(vA.GenFEIRVarReg(), vB.GenFEIRVarReg(), + DexReg vAtmp; + vAtmp.regNum = vA.regNum; + const std::string arrayTypeName = GlobalTables::GetStrTable().GetStringFromStrIdx(vB.regTypeItem->typeNameIdx); + if (arrayTypeName.size() > 1 && arrayTypeName.at(0) == 'A') { + vAtmp.regTypeItem = allocator.GetMemPool()->New( + GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(arrayTypeName.substr(1))); + } else { + CHECK_FATAL(false, "Invalid array type %s", arrayTypeName.c_str()); + } + std::list stmts = FEIRBuilder::CreateStmtArrayLoad(vAtmp.GenFEIRVarReg(), vB.GenFEIRVarReg(), vC.GenFEIRVarReg()); + + if (!((*vAtmp.regTypeItem) == (*vA.regTypeItem))) { + UniqueFEIRStmt retypeStmt = + FEIRBuilder::CreateStmtRetype(vA.GenFEIRVarReg(), vAtmp.GenFEIRVarReg()); + stmts.emplace_back(std::move(retypeStmt)); + } return stmts; } @@ -1017,7 +1074,7 @@ void DexOpAput::SetVAImpl(uint32 num) { void DexOpAput::SetVBImpl(uint32 num) { vB.regNum = num; - usedRegs.emplace_front(&vB); // Determine array type first + usedRegs.emplace_back(&vB); } void DexOpAput::SetVCImpl(uint32 num) { @@ -1026,7 +1083,7 @@ void DexOpAput::SetVCImpl(uint32 num) { usedRegs.emplace_back(&vC); } -void DexOpAput::ParseImpl(const BCClassMethod &method) { +void DexOpAput::ParseImpl(BCClassMethod &method) { GStrIdx elemTypeNameIdx; GStrIdx usedTypeNameIdx; bool isIndeterminate = false; @@ -1075,29 +1132,13 @@ void DexOpAput::ParseImpl(const BCClassMethod &method) { break; } } - if (isIndeterminate) { - return; - } - vA.regTypeItem = allocator.GetMemPool()->New(elemTypeNameIdx, false, isIndeterminate); - vB.regTypeItem = allocator.GetMemPool()->New(usedTypeNameIdx, false, isIndeterminate); + vA.regTypeItem = allocator.GetMemPool()->New(elemTypeNameIdx, isIndeterminate); + vB.regTypeItem = allocator.GetMemPool()->New(usedTypeNameIdx, isIndeterminate); } void DexOpAput::SetRegTypeInTypeInferImpl() { - if (vA.regType == nullptr && vB.regType != nullptr) { - if (!vB.regTypeItem->isIndeterminate) { - const std::string &arrayTypeName = GlobalTables::GetStrTable().GetStringFromStrIdx(vB.regTypeItem->typeNameIdx); - if (arrayTypeName.size() > 1 && arrayTypeName.at(0) == 'A') { - vA.regTypeItem = allocator.GetMemPool()->New( - GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(arrayTypeName.substr(1))); - } else { - CHECK_FATAL(false, "Invalid array type %s", arrayTypeName.c_str()); - } - } - } else if (vA.regType != nullptr && vB.regType != nullptr) { - if (vB.regTypeItem->isIndeterminate) { - vA.regType->AddArrayType(vB.regType); - vB.regType->AddElemType(vA.regType); - } + if (vA.regType != nullptr && vB.regType != nullptr && vC.regType != nullptr) { + vB.regType->AddElemType(vA.regType); } } @@ -1140,7 +1181,7 @@ void DexOpIget::SetVCImpl(uint32 num) { index = num; } -void DexOpIget::ParseImpl(const BCClassMethod &method) { +void DexOpIget::ParseImpl(BCClassMethod &method) { BCReader::ClassElem field = method.GetBCClass().GetBCParser().GetReader()->GetClassFieldFromIdx(index); uint64 mapIdx = (static_cast(method.GetBCClass().GetBCParser().GetReader()->GetFileIndex()) << 32) | index; structElemNameIdx = FEManager::GetManager().GetFieldStructElemNameIdx(mapIdx); @@ -1180,7 +1221,7 @@ void DexOpIput::SetVCImpl(uint32 num) { index = num; } -void DexOpIput::ParseImpl(const BCClassMethod &method) { +void DexOpIput::ParseImpl(BCClassMethod &method) { BCReader::ClassElem field = method.GetBCClass().GetBCParser().GetReader()->GetClassFieldFromIdx(index); uint64 mapIdx = (static_cast(method.GetBCClass().GetBCParser().GetReader()->GetFileIndex()) << 32) | index; structElemNameIdx = FEManager::GetManager().GetFieldStructElemNameIdx(mapIdx); @@ -1216,7 +1257,7 @@ void DexOpSget::SetVBImpl(uint32 num) { index = num; } -void DexOpSget::ParseImpl(const BCClassMethod &method) { +void DexOpSget::ParseImpl(BCClassMethod &method) { BCReader::ClassElem field = method.GetBCClass().GetBCParser().GetReader()->GetClassFieldFromIdx(index); uint64 mapIdx = (static_cast(method.GetBCClass().GetBCParser().GetReader()->GetFileIndex()) << 32) | index; structElemNameIdx = FEManager::GetManager().GetFieldStructElemNameIdx(mapIdx); @@ -1226,6 +1267,7 @@ void DexOpSget::ParseImpl(const BCClassMethod &method) { FEManager::GetManager().SetFieldStructElemNameIdx(mapIdx, *structElemNameIdx); } vA.regType = allocator.GetMemPool()->New(allocator, vA, structElemNameIdx->type); + dexFileHashCode = method.GetBCClass().GetBCParser().GetFileNameHashId(); } std::list DexOpSget::EmitToFEIRStmtsImpl() { @@ -1235,7 +1277,7 @@ std::list DexOpSget::EmitToFEIRStmtsImpl() { CHECK_NULL_FATAL(fieldInfo); fieldInfo->SetFieldID(index); UniqueFEIRVar var = vA.GenFEIRVarReg(); - UniqueFEIRStmt stmt = std::make_unique(nullptr, std::move(var), *fieldInfo, true); + UniqueFEIRStmt stmt = std::make_unique(nullptr, std::move(var), *fieldInfo, true, dexFileHashCode); ans.emplace_back(std::move(stmt)); return ans; } @@ -1253,7 +1295,7 @@ void DexOpSput::SetVBImpl(uint32 num) { index = num; } -void DexOpSput::ParseImpl(const BCClassMethod &method) { +void DexOpSput::ParseImpl(BCClassMethod &method) { BCReader::ClassElem field = method.GetBCClass().GetBCParser().GetReader()->GetClassFieldFromIdx(index); uint64 mapIdx = (static_cast(method.GetBCClass().GetBCParser().GetReader()->GetFileIndex()) << 32) | index; structElemNameIdx = FEManager::GetManager().GetFieldStructElemNameIdx(mapIdx); @@ -1263,6 +1305,7 @@ void DexOpSput::ParseImpl(const BCClassMethod &method) { FEManager::GetManager().SetFieldStructElemNameIdx(mapIdx, *structElemNameIdx); } vA.regTypeItem = allocator.GetMemPool()->New(structElemNameIdx->type); + dexFileHashCode = method.GetBCClass().GetBCParser().GetFileNameHashId(); } std::list DexOpSput::EmitToFEIRStmtsImpl() { @@ -1272,7 +1315,8 @@ std::list DexOpSput::EmitToFEIRStmtsImpl() { CHECK_NULL_FATAL(fieldInfo); UniqueFEIRVar var = vA.GenFEIRVarReg(); fieldInfo->SetFieldID(index); - UniqueFEIRStmt stmt = std::make_unique(nullptr, std::move(var), *fieldInfo, true); + UniqueFEIRStmt stmt = std::make_unique(nullptr, std::move(var), *fieldInfo, true, + dexFileHashCode); stmts.emplace_back(std::move(stmt)); return stmts; } @@ -1325,7 +1369,7 @@ bool DexOpInvoke::ReplaceStringFactory(BCReader::ClassElem &methodInfo, MapleLis return true; } -void DexOpInvoke::ParseImpl(const BCClassMethod &method) { +void DexOpInvoke::ParseImpl(BCClassMethod &method) { MapleList &argRegNums = argRegs; uint64 mapIdx = (static_cast(method.GetBCClass().GetBCParser().GetReader()->GetFileIndex()) << 32) | methodIdx; @@ -1366,7 +1410,7 @@ void DexOpInvoke::ParseImpl(const BCClassMethod &method) { void DexOpInvoke::PrepareInvokeParametersAndReturn(const FEStructMethodInfo &feMethodInfo, FEIRStmtCallAssign &stmt) const { - const std::vector &argTypes = feMethodInfo.GetArgTypes(); + const MapleVector &argTypes = feMethodInfo.GetArgTypes(); for (size_t i = argTypes.size(); i > 0; --i) { UniqueFEIRVar var = argVRegs[i - 1 + (IsStatic() ? 0 : 1)].GenFEIRVarReg(); UniqueFEIRExpr expr = FEIRBuilder::CreateExprDRead(std::move(var)); @@ -1534,7 +1578,11 @@ void DexOpBinaryOp::SetVBImpl(uint32 num) { void DexOpBinaryOp::SetVCImpl(uint32 num) { vC.regNum = num; - vC.regTypeItem = allocator.GetMemPool()->New(*(vA.regTypeItem)); + if (kDexOpShlLong <= opcode && opcode <= kDexOpUshrLong) { + vC.regTypeItem = allocator.GetMemPool()->New(BCUtil::GetIntIdx()); + } else { + vC.regTypeItem = allocator.GetMemPool()->New(*(vA.regTypeItem)); + } usedRegs.emplace_back(&vC); } @@ -1571,21 +1619,36 @@ void DexOpBinaryOp2Addr::SetVAImpl(uint32 num) { vA.regNum = num; defedRegs.emplace_back(&vDef); usedRegs.emplace_back(&vA); - GStrIdx typeNameIdx; // typeName of A, B are same + // typeName of A, B are same, except `shl-long/2addr` ~ `ushr-long/2addr` + GStrIdx typeNameAIdx; + GStrIdx typeNameBIdx; if (kDexOpAddInt2Addr <= opcode && opcode <= kDexOpUshrInt2Addr) { - typeNameIdx = BCUtil::GetIntIdx(); - } else if (kDexOpAddLong2Addr <= opcode && opcode <= kDexOpUshrLong2Addr) { - typeNameIdx = BCUtil::GetLongIdx(); + typeNameAIdx = BCUtil::GetIntIdx(); + typeNameBIdx = typeNameAIdx; + } else if (kDexOpAddLong2Addr <= opcode && opcode <= kDexOpXorLong2Addr) { + typeNameAIdx = BCUtil::GetLongIdx(); + typeNameBIdx = typeNameAIdx; + } else if (kDexOpShlLong2Addr <= opcode && opcode <= kDexOpUshrLong2Addr) { + typeNameAIdx = BCUtil::GetLongIdx(); + typeNameBIdx = BCUtil::GetIntIdx(); } else if (kDexOpAddFloat2Addr <= opcode && opcode <= kDexOpRemFloat2Addr) { - typeNameIdx = BCUtil::GetFloatIdx(); + typeNameAIdx = BCUtil::GetFloatIdx(); + typeNameBIdx = typeNameAIdx; } else if (kDexOpAddDouble2Addr <= opcode && opcode <= kDexOpRemDouble2Addr) { - typeNameIdx = BCUtil::GetDoubleIdx(); + typeNameAIdx = BCUtil::GetDoubleIdx(); + typeNameBIdx = typeNameAIdx; } else { CHECK_FATAL(false, "Invalid opcode: 0x%x in DexOpBinaryOp2Addr", opcode); } - vDef.regType = allocator.GetMemPool()->New(allocator, vDef, typeNameIdx); - vA.regTypeItem = allocator.GetMemPool()->New(typeNameIdx); - vB.regTypeItem = allocator.GetMemPool()->New(typeNameIdx); + vDef.regType = allocator.GetMemPool()->New(allocator, vDef, typeNameAIdx); + vA.regTypeItem = allocator.GetMemPool()->New(typeNameAIdx); + vB.regTypeItem = allocator.GetMemPool()->New(typeNameBIdx); +} + +void DexOpBinaryOp2Addr::SetVBImpl(uint32 num) { + vB.regNum = num; + // type is set in SetVAImpl + usedRegs.emplace_back(&vB); } Opcode DexOpBinaryOp2Addr::GetOpcodeFromDexIns(void) const { @@ -1610,12 +1673,6 @@ std::list DexOpBinaryOp2Addr::EmitToFEIRStmtsImpl() { return stmts; } -void DexOpBinaryOp2Addr::SetVBImpl(uint32 num) { - vB.regNum = num; - // type is set in SetVAImpl - usedRegs.emplace_back(&vB); -} - // ========== DexOpBinaryOpLit ========= DexOpBinaryOpLit::DexOpBinaryOpLit(MapleAllocator &allocatorIn, uint32 pcIn, DexOpCode opcodeIn) : DexOp(allocatorIn, pcIn, opcodeIn) { @@ -1675,14 +1732,15 @@ void DexOpInvokePolymorphic::SetVHImpl(uint32 num) { protoIdx = num; } -void DexOpInvokePolymorphic::ParseImpl(const BCClassMethod &method) { +void DexOpInvokePolymorphic::ParseImpl(BCClassMethod &method) { isStatic = method.IsStatic(); const BCReader::ClassElem &methodInfo = method.GetBCClass().GetBCParser().GetReader()->GetClassMethodFromIdx(methodIdx); const std::string &funcName = methodInfo.className + "|" + methodInfo.elemName + "|" + methodInfo.typeName; if (FEOptions::GetInstance().IsAOT()) { std::string callerClassName = method.GetBCClass().GetClassName(true); - callerClassID = FEManager::GetTypeManager().GetTypeIDFromMplClassName(callerClassName); + int32 dexFileHashCode = method.GetBCClass().GetBCParser().GetFileNameHashId(); + callerClassID = FEManager::GetTypeManager().GetTypeIDFromMplClassName(callerClassName, dexFileHashCode); } fullNameMpl = namemangler::EncodeName(funcName); protoName = method.GetBCClass().GetBCParser().GetReader()->GetSignature(protoIdx); diff --git a/src/mplfe/dex_input/src/dex_parser.cpp b/src/mplfe/dex_input/src/dex_parser.cpp index ecd5b557e179dd3b053419084fb62621f8bf5375..b2d3919e09ef596b1083a3d1c0cd99d64e54e5dd 100644 --- a/src/mplfe/dex_input/src/dex_parser.cpp +++ b/src/mplfe/dex_input/src/dex_parser.cpp @@ -115,6 +115,8 @@ void DexParser::ProcessDexClassDef(std::unique_ptr &dexClass) { dexClass->SetClassName(className); dexClass->SetIsInterface(reader->IsInterface(classIdx)); dexClass->SetSuperClasses(reader->GetSuperClasses(classIdx)); + GStrIdx irSrcFileSigIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(reader->GetIRSrcFileSignature()); + dexClass->SetIRSrcFileSigIdx(irSrcFileSigIdx); ProcessDexClassInterfaceParent(dexClass); } @@ -153,6 +155,7 @@ void DexParser::ProcessMethodBodyImpl(BCClassMethod &method, method.SetMethodInstOffset(reader->GetMethodInstOffset(dexMethodItem.get())); method.SetPCBCInstructionMap( reader->ResolveInstructions(method.GetAllocator(), dexMethodItem.get())); + method.SetSrcLocalInfo(reader->ResovleSrcLocalInfo(*dexMethodItem)); method.SetTryInfos(reader->ResolveTryInfos(dexMethodItem.get())); #ifdef DEBUG std::map srcPosInfo; @@ -177,6 +180,7 @@ void DexParser::ProcessDexClassMethod(std::unique_ptr &dexClass, } method->SetRegisterTotalSize(reader->GetClassMethodRegisterTotalSize(dexMethodItem.get())); method->SetRegisterInsSize(reader->GetClassMethodRegisterInSize(dexMethodItem.get())); + method->SetCodeOff(reader->GetCodeOff(dexMethodItem.get())); dexClass->SetMethod(std::move(method)); } diff --git a/src/mplfe/dex_input/src/dex_pragma.cpp b/src/mplfe/dex_input/src/dex_pragma.cpp index d7931697b4fa04f2a46489027794a3c5511d2e8a..4cdcceec1c1070d5fa0fe416f1e8d47b7175c8ca 100644 --- a/src/mplfe/dex_input/src/dex_pragma.cpp +++ b/src/mplfe/dex_input/src/dex_pragma.cpp @@ -19,6 +19,8 @@ #include "bc_util.h" #include "fe_manager.h" #include "ark_annotation_processor.h" +#include "rc_setter.h" + namespace maple { namespace bc { // ---------- DexBCAnnotationElement ---------- @@ -360,7 +362,12 @@ std::vector &DexBCFieldAnnotations::EmitPragmas() { uint64 mapIdx = (static_cast(iDexFile.GetFileIdx()) << 32) | iDexFieldAnnotations->GetFieldIdx(); StructElemNameIdx *structElemNameIdx = FEManager::GetManager().GetFieldStructElemNameIdx(mapIdx); ASSERT(structElemNameIdx != nullptr, "structElemNameIdx is nullptr."); - return annotationSet->EmitPragmas(kPragmaVar, structElemNameIdx->elem, -1, fieldType->GetTypeIndex()); + std::vector &pragmas = + annotationSet->EmitPragmas(kPragmaVar, structElemNameIdx->elem, -1, fieldType->GetTypeIndex()); + if (FEOptions::GetInstance().IsRC()) { + RCSetter::GetRCSetter().ProcessFieldRCAnnotation(*structElemNameIdx, *fieldType, pragmas); + } + return pragmas; } // ---------- DexBCMethodAnnotations ---------- @@ -392,26 +399,42 @@ void DexBCMethodAnnotations::SetupFuncAttrs() { void DexBCMethodAnnotations::SetupFuncAttrWithPragma(MIRFunction &mirFunc, MIRPragma &pragma) { FuncAttrKind attr; + bool isAttrSet = true; if (ArkAnnotation::GetInstance().IsFastNative(pragma.GetTyIdx())) { attr = FUNCATTR_fast_native; } else if (ArkAnnotation::GetInstance().IsCriticalNative(pragma.GetTyIdx())) { attr = FUNCATTR_critical_native; } else if (ArkAnnotation::GetInstance().IsCallerSensitive(pragma.GetTyIdx())) { attr = FUNCATTR_callersensitive; + } else if (FEOptions::GetInstance().IsRC() && + (ArkAnnotation::GetInstance().IsRCUnownedLocal(pragma.GetTyIdx()) || + (ArkAnnotation::GetInstance().IsRCUnownedLocalOld(pragma.GetTyIdx()) && + pragma.GetElementVector().empty()))) { + attr = FUNCATTR_rclocalunowned; + RCSetter::GetRCSetter().CollectUnownedLocalFuncs(&mirFunc); } else { - return; + isAttrSet = false; // empty, for codedex cleanup } - mirFunc.SetAttr(attr); - // update method attribute in structure type as well const char *definingClassName = methodID->GetDefiningClassName(iDexFile); std::string mplClassName = namemangler::EncodeName(definingClassName); MIRStructType *currStructType = FEManager::GetTypeManager().GetStructTypeFromName(mplClassName); - for (auto &mit : currStructType->GetMethods()) { - if (mit.first == mirFunc.GetStIdx()) { - mit.second.second.SetAttr(attr); - break; + if (isAttrSet) { + mirFunc.SetAttr(attr); + // update method attribute in structure type as well + for (auto &mit : currStructType->GetMethods()) { +#ifndef USE_OPS + if (mit.first->GetStIdx() == mirFunc.GetStIdx()) { +#else + if (mit.first == mirFunc.GetStIdx()) { +#endif + mit.second.second.SetAttr(attr); + break; + } } } + if (FEOptions::GetInstance().IsRC()) { + RCSetter::GetRCSetter().ProcessMethodRCAnnotation(mirFunc, mplClassName, *currStructType, pragma); + } } MIRFunction *DexBCMethodAnnotations::GetMIRFunction(const GStrIdx &nameIdx) const { @@ -496,6 +519,9 @@ std::vector &DexBCAnnotationsDirectory::EmitPragmasImpl() { if (classAnnotationSet != nullptr) { const GStrIdx &strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(namemangler::EncodeName(className)); pragmasInner = classAnnotationSet->EmitPragmas(kPragmaClass, strIdx); + if (FEOptions::GetInstance().IsRC()) { + RCSetter::GetRCSetter().ProcessClassRCAnnotation(strIdx, pragmasInner); + } pragmas.insert(pragmas.end(), pragmasInner.begin(), pragmasInner.end()); } for (const std::unique_ptr &fieldAnnotations : fieldAnnotationsItems) { diff --git a/src/mplfe/dex_input/src/dex_reader.cpp b/src/mplfe/dex_input/src/dex_reader.cpp index 10b784fbdd4671c07d3ffa641e8e1b928a9a975e..1e05ec271e8931e2b83bb785102373b9dd7b810f 100644 --- a/src/mplfe/dex_input/src/dex_reader.cpp +++ b/src/mplfe/dex_input/src/dex_reader.cpp @@ -31,6 +31,7 @@ bool DexReader::OpenAndMap() { return false; } iDexFile->SetFileIdx(fileIdx); + irSrcFileSignature = iDexFile->GetHeader()->GetSignature(); return true; } @@ -145,6 +146,9 @@ uint16 DexReader::GetClassMethodRegisterInSize(const IDexMethodItem* dexMethodIt return dexMethodItem->GetInsSize(*iDexFile); } +uint32 DexReader::GetCodeOff(const IDexMethodItem* dexMethodItem) const { + return dexMethodItem->GetCodeOff(); +} BCReader::ClassElem DexReader::GetClassMethodFromIdxImpl(uint32 idx) const { ClassElem elem; @@ -172,6 +176,14 @@ void DexReader::ResovleSrcPositionInfo( dexMethodItem->GetSrcPositionInfo(GetIDexFile(), srcPosInfo); } + +std::unique_ptr>>> + DexReader::ResovleSrcLocalInfo(const IDexMethodItem &dexMethodItem) const { + auto srcLocals = std::make_unique>>>(); + dexMethodItem.GetSrcLocalInfo(GetIDexFile(), *srcLocals); + return srcLocals; +} + MapleMap *DexReader::ResolveInstructions( MapleAllocator &allocator, const IDexMethodItem* dexMethodItem, bool mapled) const { std::map> pcInstMap; @@ -297,7 +309,6 @@ std::unique_ptr>> DexReader::ConstructBCC } bool DexReader::ReadAllDepTypeNames(std::unordered_set &depSet) { - bool isSuccess = true; for (uint32 i = 0; i < iDexFile->GetHeader()->GetTypeIdsSize(); ++i) { std::string typeName = iDexFile->GetStringByTypeIndex(i); std::string trimmedTypeName = BCUtil::TrimArrayModifier(typeName); @@ -305,13 +316,7 @@ bool DexReader::ReadAllDepTypeNames(std::unordered_set &depSet) { depSet.insert(trimmedTypeName); } } - std::unordered_set classSet; - isSuccess = isSuccess && ReadAllClassNames(classSet); - BCUtil::AddDefaultDepSet(depSet); // DepSet = DefaultTypeSet + TypeSet - ClassSet; - for (const auto &elem : classSet) { - depSet.erase(elem); - } - return isSuccess; + return true; } bool DexReader::ReadAllClassNames(std::unordered_set &classSet) const { @@ -363,8 +368,6 @@ bool DexReader::ReadMethodDepTypeNames(std::unordered_set &depSet, AddDepTypeName(depSet, iDexFile->GetStringByTypeIndex(inst->GetVRegC()), true); } else if (op == kOpNewInstance) { AddDepTypeName(depSet, iDexFile->GetStringByTypeIndex(inst->GetVRegB()), false); - } else if (op == kOpThrow) { - AddDepTypeName(depSet, iDexFile->GetStringByTypeIndex(inst->GetVRegA()), true); } ReadMethodTryCatchDepTypeNames(depSet, *method); } diff --git a/src/mplfe/dex_input/src/dexfile_factory.cpp b/src/mplfe/dex_input/src/dexfile_factory.cpp index 77cf86e9e4fea8aaba05533580157a4f79924604..d30e355b7326f26fdbd526c189260c5fc04695de 100644 --- a/src/mplfe/dex_input/src/dexfile_factory.cpp +++ b/src/mplfe/dex_input/src/dexfile_factory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/dex_input/src/dexfile_interface.cpp b/src/mplfe/dex_input/src/dexfile_interface.cpp index aee8d6bc80e372dbcf0ccf9911e018b5d749c4f2..3027b0ce7182ba0c657d0a355e66b1dc1ab9fce6 100644 --- a/src/mplfe/dex_input/src/dexfile_interface.cpp +++ b/src/mplfe/dex_input/src/dexfile_interface.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/dex_input/src/dexfile_libdexfile.cpp b/src/mplfe/dex_input/src/dexfile_libdexfile.cpp index 0afd44ef62592fcd102cc706706da32da966e14d..6be0242852e0f887bad48bbdab0a9100754988a9 100644 --- a/src/mplfe/dex_input/src/dexfile_libdexfile.cpp +++ b/src/mplfe/dex_input/src/dexfile_libdexfile.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -647,6 +647,23 @@ void IDexMethodItem::GetSrcPositionInfo(const IDexFile &dexFile, std::map>> &srcLocal) const { + const art::dex::CodeItem *artCodeItem = GetDexFile(dexFile)->GetCodeItem(GetMethodCodeOff(this)); + if (artCodeItem == nullptr) { + return; + } + art::CodeItemDebugInfoAccessor accessor(*GetDexFile(dexFile), artCodeItem, this->GetMethodIdx()); + (void)accessor.DecodeDebugLocalInfo(this->IsStatic(), this->GetMethodIdx(), + [&](const art::DexFile::LocalInfo &entry) { + if (entry.name_ != nullptr && entry.descriptor_ != nullptr) { + std::string signature = entry.signature_ != nullptr ? entry.signature_ : ""; + auto item = std::make_tuple(entry.name_, entry.descriptor_, signature); + srcLocal[entry.reg_].insert(item); + } + }); +} // =====IDexMethodItem end========== // =====IDexFieldIdItem start======= const art::dex::FieldId *GetFieldId(const IDexFieldIdItem *item) { @@ -1089,6 +1106,20 @@ uint32_t IDexHeader::GetChecksum() const { return GetDexFile(this)->GetHeader().checksum_; } +std::string IDexHeader::GetSignature() const { + static const char *kHex = "0123456789abcdef"; + static constexpr size_t kHexNum = 16; + static constexpr size_t kSignatureSize = 20; + const uint8_t *signature = GetDexFile(this)->GetHeader().signature_; + std::string result; + for (size_t i = 0; i < kSignatureSize; ++i) { + uint8_t value = signature[i]; + result.push_back(kHex[value / kHexNum]); + result.push_back(kHex[value % kHexNum]); + } + return result; +} + uint32_t IDexHeader::GetFileSize() const { return GetDexFile(this)->GetHeader().file_size_; } diff --git a/src/mplfe/jbc_input/include/jbc_attr.def b/src/mplfe/jbc_input/include/jbc_attr.def index 7e4747ed2e6f40aa162568ed775581522d37786b..4fe4da2e62a49bb97ac696d9897181e4a2eb36bf 100644 --- a/src/mplfe/jbc_input/include/jbc_attr.def +++ b/src/mplfe/jbc_input/include/jbc_attr.def @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/include/jbc_attr_item.h b/src/mplfe/jbc_input/include/jbc_attr_item.h index 174f6bb226b705f99ffa01adee36791fc760825d..ea1b2cd4e15cafe0bc5a2fd1ae5c0a63d4eb8a99 100644 --- a/src/mplfe/jbc_input/include/jbc_attr_item.h +++ b/src/mplfe/jbc_input/include/jbc_attr_item.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/include/jbc_bb.h b/src/mplfe/jbc_input/include/jbc_bb.h index 54f94e38a9e741a12ca103ea25e07998ee9fc3de..99853d90208731f7b19b4ed4b83a082bf253e7b9 100644 --- a/src/mplfe/jbc_input/include/jbc_bb.h +++ b/src/mplfe/jbc_input/include/jbc_bb.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/include/jbc_class.h b/src/mplfe/jbc_input/include/jbc_class.h index 7fc7e54ec7059489b4ab7f91d8a68a97ce7b332c..1ad06a4757fb8f95e5e8b3fcb1c2e55788e956c9 100644 --- a/src/mplfe/jbc_input/include/jbc_class.h +++ b/src/mplfe/jbc_input/include/jbc_class.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/include/jbc_class2fe_helper.h b/src/mplfe/jbc_input/include/jbc_class2fe_helper.h index b6ab4b5e7c66279d7b90b9e2573532f91a8154de..eba9349173632fa219d2698c24feefcc275f0067 100644 --- a/src/mplfe/jbc_input/include/jbc_class2fe_helper.h +++ b/src/mplfe/jbc_input/include/jbc_class2fe_helper.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -41,6 +41,8 @@ class JBCClass2FEHelper : public FEInputStructHelper { MIRStructType *CreateMIRStructTypeImpl(bool &error) const override; TypeAttrs GetStructAttributeFromInputImpl() const override; uint64 GetRawAccessFlagsImpl() const override; + GStrIdx GetIRSrcFileSigIdxImpl() const override; + bool IsMultiDefImpl() const override; void InitFieldHelpersImpl() override; void InitMethodHelpersImpl() override; std::string GetSrcFileNameImpl() const override; diff --git a/src/mplfe/jbc_input/include/jbc_class_access.h b/src/mplfe/jbc_input/include/jbc_class_access.h index b1922d921df0765ce79c0e788b3c2872214b0042..ecf90e96aaf9cbfc3ebd3114ee82387f5556ca2a 100644 --- a/src/mplfe/jbc_input/include/jbc_class_access.h +++ b/src/mplfe/jbc_input/include/jbc_class_access.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/include/jbc_class_builder.h b/src/mplfe/jbc_input/include/jbc_class_builder.h index aef8820774438fd96d09f2595af4bc23b15763f1..98a4298222b71896420007efd0988bf7944c0f4b 100644 --- a/src/mplfe/jbc_input/include/jbc_class_builder.h +++ b/src/mplfe/jbc_input/include/jbc_class_builder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/include/jbc_class_const.def b/src/mplfe/jbc_input/include/jbc_class_const.def index 925c5231ed14e7dfaae00e2f7a241570a2af41b3..49ef783b5ef68f320d45bf65488ca09cf4864f13 100644 --- a/src/mplfe/jbc_input/include/jbc_class_const.def +++ b/src/mplfe/jbc_input/include/jbc_class_const.def @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/include/jbc_class_const.h b/src/mplfe/jbc_input/include/jbc_class_const.h index 1c808d55d5856a505d4d636f62e7bd67b2c0960b..d17e19d6b99a1177c5188ad75d797b05c7dc8508 100644 --- a/src/mplfe/jbc_input/include/jbc_class_const.h +++ b/src/mplfe/jbc_input/include/jbc_class_const.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/include/jbc_class_const_pool.h b/src/mplfe/jbc_input/include/jbc_class_const_pool.h index f8cd3f487a85a418fc977fc1de39539ef15e472c..e243704e288af1072dd2c87184c4758607bc4315 100644 --- a/src/mplfe/jbc_input/include/jbc_class_const_pool.h +++ b/src/mplfe/jbc_input/include/jbc_class_const_pool.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/include/jbc_class_header.h b/src/mplfe/jbc_input/include/jbc_class_header.h index af8d2d72e145100d4efe281a0577d61f92dfe50b..40fc61c208c13baa740c3a027900587737884344 100644 --- a/src/mplfe/jbc_input/include/jbc_class_header.h +++ b/src/mplfe/jbc_input/include/jbc_class_header.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/include/jbc_compiler_component.h b/src/mplfe/jbc_input/include/jbc_compiler_component.h index 5ac34222f699ec3ccf0e9ba2b8c9e9041636471d..49ed2c972b118f75df47cb1a56b7caf5035519fb 100644 --- a/src/mplfe/jbc_input/include/jbc_compiler_component.h +++ b/src/mplfe/jbc_input/include/jbc_compiler_component.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -28,11 +28,8 @@ class JBCCompilerComponent : public MPLFECompilerComponent { protected: bool ParseInputImpl() override; bool LoadOnDemandTypeImpl() override; - bool PreProcessDeclImpl() override; - bool ProcessDeclImpl() override; void ProcessPragmaImpl() override; - bool PreProcessWithoutFunctionImpl() override; - bool PreProcessWithFunctionImpl() override; + std::unique_ptr CreatFEFunctionImpl(FEInputMethodHelper *methodHelper) override; std::string GetComponentNameImpl() const override; bool ParallelableImpl() const override; void DumpPhaseTimeTotalImpl() const override; diff --git a/src/mplfe/jbc_input/include/jbc_function.h b/src/mplfe/jbc_input/include/jbc_function.h index 8483ace3382efa56a8ac27d62f12c49bf0b528e2..320786c6601f90823bf1defdff923fe1174fdf89 100644 --- a/src/mplfe/jbc_input/include/jbc_function.h +++ b/src/mplfe/jbc_input/include/jbc_function.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -69,6 +69,7 @@ class JBCFunction : public FEFunction { bool LabelLabelIdx(const std::string &phaseName); bool CheckJVMStack(const std::string &phaseName); bool GenerateArgVarList(const std::string &phaseName) override; + bool GenerateAliasVars(const std::string &phaseName) override; bool ProcessFunctionArgs(const std::string &phaseName); bool EmitLocalVarInfo(const std::string &phaseName); bool EmitToFEIRStmt(const std::string &phaseName) override; diff --git a/src/mplfe/jbc_input/include/jbc_function_context.h b/src/mplfe/jbc_input/include/jbc_function_context.h index 8c18a2395ec49e23412a3b7e9b482b69d42a7613..4daed344d2c18a4c59b2acb0eafc44dbdbdf54e8 100644 --- a/src/mplfe/jbc_input/include/jbc_function_context.h +++ b/src/mplfe/jbc_input/include/jbc_function_context.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/include/jbc_input.h b/src/mplfe/jbc_input/include/jbc_input.h index 0c3cd2628777950c66c941d6f040fd6fffa85454..b73ea5c091e3e1aea737522e6149eafc14651716 100644 --- a/src/mplfe/jbc_input/include/jbc_input.h +++ b/src/mplfe/jbc_input/include/jbc_input.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/include/jbc_opcode.def b/src/mplfe/jbc_input/include/jbc_opcode.def index ce0a729c753a1f4deda3c31d7ac157b9898e1c70..ede7d7eb28cd409b1e2d44dfb52a4fa5e63e2e11 100644 --- a/src/mplfe/jbc_input/include/jbc_opcode.def +++ b/src/mplfe/jbc_input/include/jbc_opcode.def @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/include/jbc_opcode.h b/src/mplfe/jbc_input/include/jbc_opcode.h index 56efdbbc4b148dee717b0b0296e24779e887b9fe..d3fa959171dcf621b379ab56e045d370ceead39a 100644 --- a/src/mplfe/jbc_input/include/jbc_opcode.h +++ b/src/mplfe/jbc_input/include/jbc_opcode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/include/jbc_opcode_helper.h b/src/mplfe/jbc_input/include/jbc_opcode_helper.h index 9302d0b0c97128f7b6a30a87db16f552ba816f76..9758f4e320a78c7155a7b7e0c8b30cc5a179c798 100644 --- a/src/mplfe/jbc_input/include/jbc_opcode_helper.h +++ b/src/mplfe/jbc_input/include/jbc_opcode_helper.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/include/jbc_opcode_kind.def b/src/mplfe/jbc_input/include/jbc_opcode_kind.def index 55e1edd988054fd034e893855c8aaae3a1864527..5e0bda7e42f79799cf0b12bf04eb74c4cb4bc7d7 100644 --- a/src/mplfe/jbc_input/include/jbc_opcode_kind.def +++ b/src/mplfe/jbc_input/include/jbc_opcode_kind.def @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/include/jbc_stack2fe_helper.h b/src/mplfe/jbc_input/include/jbc_stack2fe_helper.h index 895830d8afc83b9fac8cc0287b39823a8a032ebf..795ef6b3e7b5cb4b63c971e67c0ceed959691bba 100644 --- a/src/mplfe/jbc_input/include/jbc_stack2fe_helper.h +++ b/src/mplfe/jbc_input/include/jbc_stack2fe_helper.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/include/jbc_stack_helper.h b/src/mplfe/jbc_input/include/jbc_stack_helper.h index 53afe0ed0d64b08f0fb3a0902fcf7c8fcbb62160..0da39e9e463f0a412c65dd30d76edeac6f727a95 100644 --- a/src/mplfe/jbc_input/include/jbc_stack_helper.h +++ b/src/mplfe/jbc_input/include/jbc_stack_helper.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/include/jbc_stmt.h b/src/mplfe/jbc_input/include/jbc_stmt.h index bfbbf6394bfc8ee019c6fc34b2fb56021951678f..024482ab2dd2c5e3adc8c40142f456aa0d4cadee 100644 --- a/src/mplfe/jbc_input/include/jbc_stmt.h +++ b/src/mplfe/jbc_input/include/jbc_stmt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/include/jbc_util.h b/src/mplfe/jbc_input/include/jbc_util.h index 55c356808c43b8ebeadb7a11d58c32d53e43dec2..6981b93e7db0700e0f79a9bac2eb8c7f57e62ea6 100644 --- a/src/mplfe/jbc_input/include/jbc_util.h +++ b/src/mplfe/jbc_input/include/jbc_util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/src/jbc_attr_item.cpp b/src/mplfe/jbc_input/src/jbc_attr_item.cpp index df9b28a902af9c2a47b3196289557293922fb660..b4266913200845c7f026760d516f9cf4d25bb0d8 100644 --- a/src/mplfe/jbc_input/src/jbc_attr_item.cpp +++ b/src/mplfe/jbc_input/src/jbc_attr_item.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/src/jbc_bb.cpp b/src/mplfe/jbc_input/src/jbc_bb.cpp index 9a2c630510f736f8d7d929de4da78775155f8fdf..53168107d51a2bbbffcdfc7d00c816a3a61f8b6d 100644 --- a/src/mplfe/jbc_input/src/jbc_bb.cpp +++ b/src/mplfe/jbc_input/src/jbc_bb.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/src/jbc_class.cpp b/src/mplfe/jbc_input/src/jbc_class.cpp index 18136ab9350313aa509ef726901d41e18b115888..c071c57ab32577c854b18b2ff726ec5c92380240 100644 --- a/src/mplfe/jbc_input/src/jbc_class.cpp +++ b/src/mplfe/jbc_input/src/jbc_class.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/src/jbc_class2fe_helper.cpp b/src/mplfe/jbc_input/src/jbc_class2fe_helper.cpp index bee98708488fe7f51b0cec9571a39bd1792f8e8a..06b2b4731bcb1e2926bbd5d0f0c669bfb12afdad 100644 --- a/src/mplfe/jbc_input/src/jbc_class2fe_helper.cpp +++ b/src/mplfe/jbc_input/src/jbc_class2fe_helper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -111,6 +111,16 @@ uint64 JBCClass2FEHelper::GetRawAccessFlagsImpl() const { return uint64{ klass.GetAccessFlag() }; } +GStrIdx JBCClass2FEHelper::GetIRSrcFileSigIdxImpl() const { + // Not implemented, just return a invalid value + return GStrIdx(0); +} + +bool JBCClass2FEHelper::IsMultiDefImpl() const { + // Not implemented, alway return false + return false; +} + void JBCClass2FEHelper::InitFieldHelpersImpl() { MemPool *mp = allocator.GetMemPool(); ASSERT(mp != nullptr, "mem pool is nullptr"); diff --git a/src/mplfe/jbc_input/src/jbc_class_const.cpp b/src/mplfe/jbc_input/src/jbc_class_const.cpp index 19d95c10458966ba796f25db719156d14038f0aa..8dc5dd3839a590a9dcdba50793e3eec43970cea8 100644 --- a/src/mplfe/jbc_input/src/jbc_class_const.cpp +++ b/src/mplfe/jbc_input/src/jbc_class_const.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/src/jbc_class_const_pool.cpp b/src/mplfe/jbc_input/src/jbc_class_const_pool.cpp index ccc0453b062098e707c29046d94245fcfddd2e31..3aeeb437db91bfd639126833e534d23c197d82de 100644 --- a/src/mplfe/jbc_input/src/jbc_class_const_pool.cpp +++ b/src/mplfe/jbc_input/src/jbc_class_const_pool.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/src/jbc_compiler_component.cpp b/src/mplfe/jbc_input/src/jbc_compiler_component.cpp index 901afbfef9abae5002c4ace6e8ae472ab4cddaee..07f9b6b470293061237aa6c7d627f12a74687e4d 100644 --- a/src/mplfe/jbc_input/src/jbc_compiler_component.cpp +++ b/src/mplfe/jbc_input/src/jbc_compiler_component.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -21,7 +21,7 @@ namespace maple { JBCCompilerComponent::JBCCompilerComponent(MIRModule &module) : MPLFECompilerComponent(module, kSrcLangJava), - mp(memPoolCtrler.NewMemPool("MemPool for JBCCompilerComponent")), + mp(FEUtils::NewMempool("MemPool for JBCCompilerComponent", false /* isLocalPool */)), allocator(mp), jbcInput(module) {} @@ -60,61 +60,18 @@ bool JBCCompilerComponent::LoadOnDemandTypeImpl() { return false; } -bool JBCCompilerComponent::PreProcessDeclImpl() { - FETimer timer; - timer.StartAndDump("JBCCompilerComponent::PreProcessDecl()"); - FE_INFO_LEVEL(FEOptions::kDumpLevelInfo, "===== Process JBCCompilerComponent::PreProcessDecl() ====="); - bool success = true; - for (FEInputStructHelper *helper : structHelpers) { - ASSERT(helper != nullptr, "nullptr check"); - success = helper->PreProcessDecl() ? success : false; - } - timer.StopAndDumpTimeMS("JBCCompilerComponent::PreProcessDecl()"); - return success; -} - -bool JBCCompilerComponent::ProcessDeclImpl() { - FETimer timer; - timer.StartAndDump("JBCCompilerComponent::ProcessDecl()"); - FE_INFO_LEVEL(FEOptions::kDumpLevelInfo, "===== Process JBCCompilerComponent::ProcessDecl() ====="); - bool success = true; - for (FEInputStructHelper *helper : structHelpers) { - ASSERT(helper != nullptr, "nullptr check"); - success = helper->ProcessDecl() ? success : false; - } - timer.StopAndDumpTimeMS("JBCCompilerComponent::ProcessDecl()"); - return success; -} - void JBCCompilerComponent::ProcessPragmaImpl() {} -bool JBCCompilerComponent::PreProcessWithoutFunctionImpl() { - return false; -} - -bool JBCCompilerComponent::PreProcessWithFunctionImpl() { - FETimer timer; - timer.StartAndDump("JBCCompilerComponent::PreProcessWithFunction()"); - FE_INFO_LEVEL(FEOptions::kDumpLevelInfo, "===== Process JBCCompilerComponent::PreProcessWithFunction() ====="); - for (FEInputStructHelper *structHelper : structHelpers) { - ASSERT(structHelper != nullptr, "nullptr check"); - for (FEInputMethodHelper *methodHelper : structHelper->GetMethodHelpers()) { - ASSERT(methodHelper != nullptr, "nullptr check"); - JBCClassMethod2FEHelper *jbcMethodHelper = static_cast(methodHelper); - GStrIdx methodNameIdx = methodHelper->GetMethodNameIdx(); - bool isStatic = methodHelper->IsStatic(); - MIRFunction *mirFunc = FEManager::GetTypeManager().GetMIRFunction(methodNameIdx, isStatic); - CHECK_NULL_FATAL(mirFunc); - std::unique_ptr feFunction = std::make_unique(*jbcMethodHelper, *mirFunc, - phaseResultTotal); - module.AddFunction(mirFunc); - feFunction->Init(); - feFunction->SetSrcFileName(structHelper->GetSrcFileName()); - functions.push_back(std::move(feFunction)); - } - } - timer.StopAndDumpTimeMS("JBCCompilerComponent::PreProcessWithFunction()"); - return true; +std::unique_ptr JBCCompilerComponent::CreatFEFunctionImpl(FEInputMethodHelper *methodHelper) { + JBCClassMethod2FEHelper *jbcMethodHelper = static_cast(methodHelper); + GStrIdx methodNameIdx = methodHelper->GetMethodNameIdx(); + bool isStatic = methodHelper->IsStatic(); + MIRFunction *mirFunc = FEManager::GetTypeManager().GetMIRFunction(methodNameIdx, isStatic); + CHECK_NULL_FATAL(mirFunc); + std::unique_ptr feFunction = std::make_unique(*jbcMethodHelper, *mirFunc, phaseResultTotal); + module.AddFunction(mirFunc); + feFunction->Init(); + return feFunction; } std::string JBCCompilerComponent::GetComponentNameImpl() const { diff --git a/src/mplfe/jbc_input/src/jbc_function.cpp b/src/mplfe/jbc_input/src/jbc_function.cpp index 0ca30351c3bafc2838c280126e280d116e09f5d1..e66fc0ea4d3f5a0b7afc10341bff63f6a5f49171 100644 --- a/src/mplfe/jbc_input/src/jbc_function.cpp +++ b/src/mplfe/jbc_input/src/jbc_function.cpp @@ -142,6 +142,10 @@ bool JBCFunction::VerifyGeneral() { void JBCFunction::VerifyGeneralFailCallBack() { } +bool JBCFunction::GenerateAliasVars(const std::string &phaseName) { + return true; +} + bool JBCFunction::GenerateArgVarList(const std::string &phaseName) { phaseResult.RegisterPhaseNameAndStart(phaseName); InitStack2FEHelper(); diff --git a/src/mplfe/jbc_input/src/jbc_function_context.cpp b/src/mplfe/jbc_input/src/jbc_function_context.cpp index aeb6b76cd67160003f5811c3c4043fe37828f8ae..3016320a192a1f4dc8fd0ed5278a658808a2fd3a 100644 --- a/src/mplfe/jbc_input/src/jbc_function_context.cpp +++ b/src/mplfe/jbc_input/src/jbc_function_context.cpp @@ -80,4 +80,4 @@ const FEIRType *JBCFunctionContext::GetSlotType(uint16 slotIdx) const { const jbc::JavaAttrLocalVariableInfoItem &info = localVarInfo.GetItemByStart(slotIdx, startPC); return info.feirType; } -} // namespace maple +} // namespace maple \ No newline at end of file diff --git a/src/mplfe/jbc_input/src/jbc_input.cpp b/src/mplfe/jbc_input/src/jbc_input.cpp index b193506c4917515cba3ebbddfde6b1cc354cfb47..8958ebf4396eb35a29991d6aa3fea2fc1fcd73d5 100644 --- a/src/mplfe/jbc_input/src/jbc_input.cpp +++ b/src/mplfe/jbc_input/src/jbc_input.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -18,6 +18,7 @@ #include "fe_macros.h" #include "fe_options.h" #include "mplfe_env.h" +#include "fe_manager.h" namespace maple { namespace jbc { @@ -29,7 +30,7 @@ const uint32 kJarMetaInfLength = 8; } JBCInput::JBCInput(MIRModule &moduleIn) : module(moduleIn), - mp(memPoolCtrler.NewMemPool("mempool for JBC Input Helper")), + mp(FEUtils::NewMempool("mempool for JBC Input Helper", false /* isLocalPool */)), allocator(mp), klassList(allocator.Adapter()) { itKlass = klassList.end(); diff --git a/src/mplfe/jbc_input/src/jbc_opcode.cpp b/src/mplfe/jbc_input/src/jbc_opcode.cpp index cd6dc2bdead449edf023045b537b31c445198395..946d0999833d6dce864e42bb15a963053e1cc006 100644 --- a/src/mplfe/jbc_input/src/jbc_opcode.cpp +++ b/src/mplfe/jbc_input/src/jbc_opcode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/src/jbc_opcode_helper.cpp b/src/mplfe/jbc_input/src/jbc_opcode_helper.cpp index c6458e1da430130712a7c679a840a78dc2a54058..2a5fec151b45671a3911120112142746b8d55e82 100644 --- a/src/mplfe/jbc_input/src/jbc_opcode_helper.cpp +++ b/src/mplfe/jbc_input/src/jbc_opcode_helper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/src/jbc_stack2fe_helper.cpp b/src/mplfe/jbc_input/src/jbc_stack2fe_helper.cpp index 9cfbec1798bd78a6af0f9e2568a7f21752599564..be0dc49fd9c00dddaa0873a900bf94816bf3f1b4 100644 --- a/src/mplfe/jbc_input/src/jbc_stack2fe_helper.cpp +++ b/src/mplfe/jbc_input/src/jbc_stack2fe_helper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/src/jbc_stack_helper.cpp b/src/mplfe/jbc_input/src/jbc_stack_helper.cpp index 4c8bab32ba72f3f6d974188f60e94d2062cdaca9..326b089027d22a68cc2a6a22af24aa15e9527853 100644 --- a/src/mplfe/jbc_input/src/jbc_stack_helper.cpp +++ b/src/mplfe/jbc_input/src/jbc_stack_helper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/jbc_input/src/jbc_stmt.cpp b/src/mplfe/jbc_input/src/jbc_stmt.cpp index 4d322f8331ed26debf01386b0973c54b40e02839..69ca00785f77ccc9e4e5bca3a17c5c85c51bbf43 100644 --- a/src/mplfe/jbc_input/src/jbc_stmt.cpp +++ b/src/mplfe/jbc_input/src/jbc_stmt.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -357,7 +357,7 @@ std::list JBCStmtInst::EmitToFEIRForOpLdc(JBCFunctionContext &co case jbc::kConstString: { const jbc::JBCConstString *constString = static_cast(constRaw); UniqueFEIRVar varDst = stack2feHelper.PushItem(PTY_ref); - stmtDAssign = FEIRBuilder::CreateStmtJavaConstString(std::move(varDst), constString->GetStrIdx()); + stmtDAssign = FEIRBuilder::CreateStmtJavaConstString(std::move(varDst), constString->GetString()); break; } case jbc::kConstClass: { @@ -655,7 +655,7 @@ std::list JBCStmtInst::EmitToFEIRForOpStaticFieldOpr(JBCFunction const jbc::JBCConstRef *constRef = static_cast(constRaw); FEStructFieldInfo *fieldInfo = static_cast(constRef->GetFEStructElemInfo()); CHECK_NULL_FATAL(fieldInfo); - const UniqueFEIRType &fieldType = fieldInfo->GetType(); + const FEIRType *fieldType = fieldInfo->GetType(); PrimType pty = fieldType->IsScalar() ? fieldType->GetPrimType() : PTY_ref; pty = JBCStack2FEHelper::SimplifyPrimType(pty); if (op.GetOpcode() == jbc::kOpGetStatic) { @@ -681,7 +681,7 @@ std::list JBCStmtInst::EmitToFEIRForOpFieldOpr(JBCFunctionContex const jbc::JBCConstRef *constRef = static_cast(constRaw); FEStructFieldInfo *fieldInfo = static_cast(constRef->GetFEStructElemInfo()); CHECK_NULL_FATAL(fieldInfo); - const UniqueFEIRType &fieldType = fieldInfo->GetType(); + const FEIRType *fieldType = fieldInfo->GetType(); PrimType pty = fieldType->IsScalar() ? fieldType->GetPrimType() : PTY_ref; pty = JBCStack2FEHelper::SimplifyPrimType(pty); if (op.GetOpcode() == jbc::kOpGetField) { @@ -721,9 +721,9 @@ void JBCStmtInst::PrepareInvokeParametersAndReturn(JBCStack2FEHelper &stack2feHe const FEStructMethodInfo &info, FEIRStmtCallAssign &callStmt, bool isStatic) const { - const std::vector &argTypes = info.GetArgTypes(); + const MapleVector &argTypes = info.GetArgTypes(); for (size_t i = argTypes.size(); i > 0; --i) { - const UniqueFEIRType &argType = argTypes[static_cast(i - 1)]; + const FEIRType *argType = argTypes[static_cast(i - 1)]; PrimType pty = argType->GetPrimType(); UniqueFEIRVar var = stack2feHelper.PopItem(JBCStack2FEHelper::SimplifyPrimType(pty)); UniqueFEIRExpr expr = FEIRBuilder::CreateExprDRead(std::move(var)); @@ -731,14 +731,14 @@ void JBCStmtInst::PrepareInvokeParametersAndReturn(JBCStack2FEHelper &stack2feHe } if (!isStatic) { // push this - const UniqueFEIRType &thisType = info.GetOwnerType(); + const FEIRType *thisType = info.GetOwnerType(); PrimType pty = thisType->GetPrimType(); UniqueFEIRVar var = stack2feHelper.PopItem(JBCStack2FEHelper::SimplifyPrimType(pty)); UniqueFEIRExpr expr = FEIRBuilder::CreateExprDRead(std::move(var)); callStmt.AddExprArgReverse(std::move(expr)); } if (!info.IsReturnVoid()) { - const UniqueFEIRType &retType = info.GetReturnType(); + const FEIRType *retType = info.GetReturnType(); PrimType pty = retType->GetPrimType(); UniqueFEIRVar var = stack2feHelper.PushItem(JBCStack2FEHelper::SimplifyPrimType(pty)); callStmt.SetVar(std::move(var)); @@ -901,9 +901,11 @@ std::list JBCStmtInst::EmitToFEIRForOpMultiANewArray(JBCFunction return ans; } const jbc::JBCConstClass *constClass = static_cast(constRaw); - UniqueFEIRStmt stmt = std::make_unique(nullptr, constClass->GetFEIRType()->Clone()); + UniqueFEIRStmt stmt = std::make_unique(nullptr, constClass->GetFEIRType()->Clone(), + nullptr); std::vector stackInTypes = op.GetInputTypesFromStack(constPool); std::reverse(stackInTypes.begin(), stackInTypes.end()); + FEIRStmtJavaMultiANewArray *javaMultiANewArray = static_cast(stmt.get()); for (jbc::JBCPrimType popType : stackInTypes) { PrimType pty = JBCStack2FEHelper::JBCStackItemTypeToPrimType(popType); UniqueFEIRVar var = stack2feHelper.PopItem(pty); @@ -911,7 +913,7 @@ std::list JBCStmtInst::EmitToFEIRForOpMultiANewArray(JBCFunction success = false; return ans; } - static_cast(stmt.get())->AddVarSizeRev(std::move(var)); + javaMultiANewArray->AddVarSizeRev(std::move(var)); } jbc::JBCPrimType stackOutType = op.GetOutputTypesToStack(constPool); if (stackOutType == jbc::JBCPrimType::kTypeDefault) { @@ -920,7 +922,8 @@ std::list JBCStmtInst::EmitToFEIRForOpMultiANewArray(JBCFunction } PrimType pty = JBCStack2FEHelper::JBCStackItemTypeToPrimType(stackOutType); UniqueFEIRVar varRet = stack2feHelper.PushItem(pty); - static_cast(stmt.get())->SetVar(std::move(varRet)); + javaMultiANewArray->SetArrayType(varRet->GetType()->Clone()); + javaMultiANewArray->SetVar(std::move(varRet)); ans.push_back(std::move(stmt)); return ans; } diff --git a/src/mplfe/jbc_input/src/jbc_util.cpp b/src/mplfe/jbc_input/src/jbc_util.cpp index 9af4834432eedf836f731bdfd3d5281dcb762821..fff2612fecea2fc3f2fd38e5d5b2ed29421cd3cf 100644 --- a/src/mplfe/jbc_input/src/jbc_util.cpp +++ b/src/mplfe/jbc_input/src/jbc_util.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mplfe/test/fe_function_test.cpp b/src/mplfe/test/fe_function_test.cpp index 15c7643add87fc844167ac311924c2e04e390d76..24c3efbe3924f4baee56f2db3a1dd60b2f977746 100644 --- a/src/mplfe/test/fe_function_test.cpp +++ b/src/mplfe/test/fe_function_test.cpp @@ -73,6 +73,10 @@ class FEFunctionDemo : public FEFunction { return true; } + bool GenerateAliasVars(const std::string &phaseName) override { + return true; + } + void LoadGenStmtDemo1(); void LoadGenStmtDemo2(); void LoadGenStmtDemo3(); @@ -117,7 +121,7 @@ class FEFunctionTest : public testing::Test, public RedirectBuffer { ~FEFunctionTest() = default; static void SetUpTestCase() { - mp = memPoolCtrler.NewMemPool("MemPool for FEFunctionTest", false /* isLocalPool */); + mp = FEUtils::NewMempool("MemPool for FEFunctionTest", false /* isLocalPool */); } static void TearDownTestCase() { diff --git a/src/mplfe/test/fe_struct_elem_info_test.cpp b/src/mplfe/test/fe_struct_elem_info_test.cpp index 72d8054c46482174f5a553380893fa2b23b9f6df..b2c1d54f8771b4c6667e69cb8ca4d400e66a91da 100644 --- a/src/mplfe/test/fe_struct_elem_info_test.cpp +++ b/src/mplfe/test/fe_struct_elem_info_test.cpp @@ -34,7 +34,7 @@ class FEStructFieldInfoTest : public testing::Test, public RedirectBuffer { TEST_F(FEStructFieldInfoTest, FEStructFieldInfo) { StructElemNameIdx *structElemNameIdx = new StructElemNameIdx("Ljava/lang/Integer;", "MIN_VALUE", "I"); - FEStructFieldInfo info(*structElemNameIdx, kSrcLangJava, true); + FEStructFieldInfo info(mirBuilder.GetMirModule().GetMPAllocator(), *structElemNameIdx, kSrcLangJava, true); std::string structName = GlobalTables::GetStrTable().GetStringFromStrIdx(structElemNameIdx->klass); std::string elemName = GlobalTables::GetStrTable().GetStringFromStrIdx(structElemNameIdx->elem); std::string signatureName = GlobalTables::GetStrTable().GetStringFromStrIdx(structElemNameIdx->type); @@ -47,7 +47,7 @@ TEST_F(FEStructFieldInfoTest, FEStructFieldInfo) { TEST_F(FEStructFieldInfoTest, SearchStructFieldJava) { StructElemNameIdx *structElemNameIdx = new StructElemNameIdx("Ljava/lang/Integer;", "MIN_VALUE", "I"); - FEStructFieldInfo info(*structElemNameIdx, kSrcLangJava, true); + FEStructFieldInfo info(mirBuilder.GetMirModule().GetMPAllocator(), *structElemNameIdx, kSrcLangJava, true); MIRStructType *structType = FEManager::GetTypeManager().GetStructTypeFromName(namemangler::EncodeName("Ljava/lang/Integer;")); delete structElemNameIdx; diff --git a/src/mplfe/test/feir_stmt_bb_test.cpp b/src/mplfe/test/feir_stmt_bb_test.cpp index 9fcaf6533aaefeb695e33f502870c864f82af256..e3550fd12a0b92362463977f8e485368733d92e1 100644 --- a/src/mplfe/test/feir_stmt_bb_test.cpp +++ b/src/mplfe/test/feir_stmt_bb_test.cpp @@ -45,7 +45,7 @@ class FEIRStmtBBTest : public FEIRTestBase { jbcFunction(jbcMethodHelper, mirFunction, std::make_unique(true)) {} virtual ~FEIRStmtBBTest() = default; static void SetUpTestCase() { - mp = memPoolCtrler.NewMemPool("MemPool for FEIRStmtBBTest", false /* isLcalPool */); + mp = FEUtils::NewMempool("MemPool for FEIRStmtBBTest", false /* isLcalPool */); } static void TearDownTestCase() { diff --git a/src/mplfe/test/feir_stmt_loc_test.cpp b/src/mplfe/test/feir_stmt_loc_test.cpp index 694087d7687960d8cf7035eaf7a0575cf91ba61a..2b63dd13944bdf5838d18e8b7b2864a65232f114 100644 --- a/src/mplfe/test/feir_stmt_loc_test.cpp +++ b/src/mplfe/test/feir_stmt_loc_test.cpp @@ -45,7 +45,7 @@ class FEIRStmtLOCTest : public FEIRTestBase { ~FEIRStmtLOCTest() = default; static void SetUpTestCase() { - mp = memPoolCtrler.NewMemPool("MemPool for FEIRStmtLOCTest", false /* isLcalPool */); + mp = FEUtils::NewMempool("MemPool for FEIRStmtLOCTest", false /* isLcalPool */); } static void TearDownTestCase() { diff --git a/src/mplfe/test/feir_stmt_test.cpp b/src/mplfe/test/feir_stmt_test.cpp index 9bc7921e85431097376449f4f2fb782a75adce21..c2dc761f8de5db7611aa18fda278621cf4c039cf 100644 --- a/src/mplfe/test/feir_stmt_test.cpp +++ b/src/mplfe/test/feir_stmt_test.cpp @@ -385,1334 +385,4 @@ TEST_F(FEIRStmtTest, FEIRStmtJavaFillArrayData) { EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); RestoreCout(); } - -class DexOpConstClassUT : public bc::DexOpConstClass { - public: - DexOpConstClassUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpConstClass(allocatorIn, pcIn, opcodeIn) {} - ~DexOpConstClassUT() = default; - void SetRegTypeInUT(const std::string &name) { - typeName = name; - std::string refTypeName = bc::BCUtil::kJavaClassName; - vA.regType = allocator.GetMemPool()->New(allocator, vA, - GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(namemangler::EncodeName(refTypeName))); - } -}; - -class DexOpMoveExceptionUT : public bc::DexOpMoveException { - public: - DexOpMoveExceptionUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpMoveException(allocatorIn, pcIn, opcodeIn) { - instKind = bc::kCatch; - } - ~DexOpMoveExceptionUT() = default; - void SetRegTypeInUT(const std::string &name) { - vA.regType = allocator.GetMemPool()->New(allocator, vA, - GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(namemangler::EncodeName(name))); - } -}; - -class DexOpMoveUT : public bc::DexOpMove { - public: - DexOpMoveUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpMove(allocatorIn, pcIn, opcodeIn) {} - ~DexOpMoveUT() = default; - void SetRegTypeInUT(const std::string &name) { - vB.regType = allocator.GetMemPool()->New(allocator, vB, - GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(namemangler::EncodeName(name))); - vA.regTypeItem = vB.regTypeItem; - } -}; -// ---------- FEIRStmtDAssign-DexOpMove ---------- -TEST_F(FEIRStmtTest, FEIRStmtDAssignDexOpMove) { - std::unique_ptr dexOp = std::make_unique(allocator, 1, bc::kDexOpMove); - dexOp->SetVA(0); - dexOp->SetVB(1); - dexOp->SetRegTypeInUT(bc::BCUtil::kInt); - std::list feStmts = dexOp->EmitToFEIRStmts(); - ASSERT_EQ(feStmts.size(), 1); - std::list mirNodes = feStmts.front()->GenMIRStmts(mirBuilder); - ASSERT_EQ(mirNodes.size(), 1); - RedirectCout(); - mirNodes.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string pattern = std::string("dassign %Reg0_I") + " 0 \\(dread i32 %Reg1_I" + "\\)" + - MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - RestoreCout(); -} - -// ---------- FEIRStmtDAssign-DexOpMoveException ---------- -TEST_F(FEIRStmtTest, FEIRStmtDAssignDexOpMoveException) { - std::unique_ptr dexOp = - std::make_unique(allocator, 1, bc::kDexOpMoveException); - dexOp->SetVA(0); - dexOp->SetRegTypeInUT("Ljava/lang/Exception;"); - std::list feStmts = dexOp->EmitToFEIRStmts(); - ASSERT_EQ(feStmts.size(), 2); - ASSERT_EQ(feStmts.front()->GetKind(), kStmtPesudoLabel); - std::list mirNodes = feStmts.back()->GenMIRStmts(mirBuilder); - ASSERT_EQ(mirNodes.size(), 1); - RedirectCout(); - mirNodes.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string pattern = std::string("dassign %Reg0_") + MPLFEUTRegx::RefIndex(MPLFEUTRegx::kAnyNumber) + - " 0 \\(regread ptr %%thrownval" + "\\)" + MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - RestoreCout(); -} - -// ---------- FEIRStmtDAssign-DexOpConstClass ---------- -TEST_F(FEIRStmtTest, FEIRStmtDAssignDexOpConstClass) { - std::unique_ptr dexOp = std::make_unique(allocator, 1, bc::kDexOpConstClass); - dexOp->SetVA(0); - dexOp->SetRegTypeInUT("Ljava/lang/String;"); - std::list feStmts = dexOp->EmitToFEIRStmts(); - ASSERT_EQ(feStmts.size(), 1); - std::list mirNodes = feStmts.front()->GenMIRStmts(mirBuilder); - ASSERT_EQ(mirNodes.size(), 1); - RedirectCout(); - mirNodes.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string pattern = "dassign %Reg0_" + MPLFEUTRegx::RefIndex(MPLFEUTRegx::kAnyNumber) + - " 0 \\(intrinsicopwithtype ref \\<\\* \\<\\$Ljava_2Flang_2FString_3B\\>\\> " - "JAVA_CONST_CLASS \\(\\)\\)" + MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - RestoreCout(); -} - -// ---------- FEIRStmt-DexOpMonitor ---------- -class DexOpMonitorUT : public bc::DexOpMonitor { - public: - DexOpMonitorUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpMonitor(allocatorIn, pcIn, opcodeIn) {} - ~DexOpMonitorUT() = default; - void SetRegTypeInUT(const std::string &name) { - vA.regType = allocator.GetMemPool()->New(allocator, vA, - GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(namemangler::EncodeName(name))); - } -}; -TEST_F(FEIRStmtTest, FEIRStmtDexOpMonitor) { - std::unique_ptr dexOp = std::make_unique(allocator, 1, bc::kDexOpMonitorEnter); - dexOp->SetVA(0); - dexOp->SetRegTypeInUT(bc::BCUtil::kInt); - std::list feStmts = dexOp->EmitToFEIRStmts(); - ASSERT_EQ(feStmts.size(), 1); - std::list mirNodes = feStmts.front()->GenMIRStmts(mirBuilder); - ASSERT_EQ(mirNodes.size(), 1); - RedirectCout(); - mirNodes.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string pattern = "syncenter \\(dread i32 %Reg0_I, constval i32 2\\)" + MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - RestoreCout(); - dexOp = std::make_unique(allocator, 1, bc::kDexOpMonitorExit); - dexOp->SetVA(0); - dexOp->SetRegTypeInUT(bc::BCUtil::kInt); - feStmts = dexOp->EmitToFEIRStmts(); - ASSERT_EQ(feStmts.size(), 1); - mirNodes = feStmts.front()->GenMIRStmts(mirBuilder); - ASSERT_EQ(mirNodes.size(), 1); - RedirectCout(); - mirNodes.front()->Dump(); - dumpStr = GetBufferString(); - EXPECT_EQ(dumpStr.find("syncexit (dread i32 %Reg0_I)"), 0); - RestoreCout(); -} - -// ---------- FEIRStmt-DexOpIfTest ---------- -class DexOpIfTestUT : public bc::DexOpIfTest { - public: - DexOpIfTestUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpIfTest(allocatorIn, pcIn, opcodeIn) {} - ~DexOpIfTestUT() = default; - void SetType(const std::string &name) { - vA.regType = allocator.GetMemPool()->New(allocator, vA, - GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(namemangler::EncodeName(name))); - vB.regType = vA.regType; - vB.regTypeItem = vA.regTypeItem; - } - - void SetFuncNameIdx(uint32 idx) { - funcNameIdx = idx; - } -}; - -TEST_F(FEIRStmtTest, FEIRStmtDexOpIfTest) { - std::unique_ptr dexOp = std::make_unique(allocator, 1, bc::kDexOpIfLt); - dexOp->SetVA(0); - dexOp->SetVB(1); - dexOp->SetType("I"); - dexOp->SetFuncNameIdx(111); - std::list feStmts = dexOp->EmitToFEIRStmts(); - ASSERT_EQ(feStmts.size(), 1); - std::list mirNodes = feStmts.front()->GenMIRStmts(mirBuilder); - ASSERT_EQ(mirNodes.size(), 1); - RedirectCout(); - mirNodes.front()->Dump(); - std::string dumpStr = GetBufferString(); - RestoreCout(); - EXPECT_EQ(dumpStr.find("brtrue @L111_0 (lt u1 i32 (dread i32 %Reg0_I, dread i32 %Reg1_I))"), 0); -} - -// ---------- FEIRStmt-DexOpIfTestZ ---------- -class DexOpIfTestZUT : public bc::DexOpIfTestZ { - public: - DexOpIfTestZUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpIfTestZ(allocatorIn, pcIn, opcodeIn) {} - ~DexOpIfTestZUT() = default; - void SetType(const std::string &name) { - vA.regType = allocator.GetMemPool()->New(allocator, vA, - GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(namemangler::EncodeName(name))); - } - void SetFuncNameIdx(uint32 idx) { - funcNameIdx = idx; - } -}; - -TEST_F(FEIRStmtTest, FEIRStmtDexOpIfTestZ) { - RedirectCout(); - std::unique_ptr dexOpI = std::make_unique(allocator, 1, bc::kDexOpIfEqZ); - dexOpI->SetVA(0); - dexOpI->SetType("I"); - dexOpI->SetFuncNameIdx(111); - std::list feStmts = dexOpI->EmitToFEIRStmts(); - ASSERT_EQ(feStmts.size(), 1); - std::list mirNodes = feStmts.front()->GenMIRStmts(mirBuilder); - ASSERT_EQ(mirNodes.size(), 1); - mirNodes.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string pattern = std::string("brtrue @L111_0 \\(eq u1 i32 \\(dread i32 %Reg0_I, constval i32 0\\)\\)") + - MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - std::unique_ptr dexOpZ = std::make_unique(allocator, 1, bc::kDexOpIfEqZ); - dexOpZ->SetVA(0); - dexOpZ->SetType("Z"); - dexOpZ->SetFuncNameIdx(222); - dexOpZ->EmitToFEIRStmts().front()->GenMIRStmts(mirBuilder).front()->Dump(); - dumpStr = GetBufferString(); - pattern = std::string("brfalse @L222_0 \\(dread u1 %Reg0_Z\\)") + MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - RestoreCout(); -} - -// ---------- FEIRStmt-DexOpInvoke ---------- -class DexOpInvokeUT : public bc::DexOpInvoke { - public: - DexOpInvokeUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpInvoke(allocatorIn, pcIn, opcodeIn) {} - ~DexOpInvokeUT() = default; - - void ParseImplUT(const bc::BCReader::ClassElem &elem) { - bc::BCReader::ClassElem methodInfo = elem; - retArgsTypeNames = FEUtilJava::SolveMethodSignature(methodInfo.typeName); - bc::DexReg reg; - MapleList argRegNums = argRegs; - ReplaceStringFactory(methodInfo, argRegNums); - structElemNameIdx = allocator.New( - methodInfo.className, methodInfo.elemName, methodInfo.typeName); - - std::string typeName; - if (!IsStatic()) { - reg.regNum = argRegNums.front(); - argRegNums.pop_front(); - typeName = methodInfo.className; - typeName = namemangler::EncodeName(typeName); - reg.regType = allocator.GetMemPool()->New(allocator, reg, - GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(typeName)); - argVRegs.emplace_back(reg); - } - for (size_t i = 1; i < retArgsTypeNames.size(); ++i) { - reg.regNum = argRegNums.front(); - argRegNums.pop_front(); - typeName = retArgsTypeNames[i]; - typeName = namemangler::EncodeName(typeName); - reg.regType = allocator.GetMemPool()->New(allocator, reg, - GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(typeName)); - argVRegs.emplace_back(reg); - } - } -}; - -TEST_F(FEIRStmtTest, FEIRStmtDexOpInvoke) { - RedirectCout(); - std::unique_ptr dexOp = std::make_unique(allocator, 1, bc::kDexOpInvokeVirtual); - dexOp->SetVA(3); - dexOp->SetVC(6); - MapleList argVRegNums({6, 7, 8}, allocator.Adapter()); - dexOp->SetArgs(argVRegNums); - bc::BCReader::ClassElem elem; - elem.className = "LTestClass;"; - elem.elemName = "funcName"; - elem.typeName = "(Ljava/lang/String;I)V"; - dexOp->ParseImplUT(elem); - std::list feStmts = dexOp->EmitToFEIRStmts(); - ASSERT_EQ(feStmts.size(), 1); - std::list mirNodes = feStmts.front()->GenMIRStmts(mirBuilder); - ASSERT_EQ(mirNodes.size(), 1); - mirNodes.front()->Dump(); - std::string dumpStr = GetBufferString(); - RestoreCout(); - EXPECT_EQ(dumpStr.find( - "virtualcallassigned <estClass_3B_7CfuncName_7C_28Ljava_2Flang_2FString_3BI_29V (dread ref %Reg6_R"), 0); - EXPECT_EQ(dumpStr.find(", dread ref %Reg7_R", 99) != std::string::npos, true); - EXPECT_EQ(dumpStr.find(", dread i32 %Reg8_I) {}", 99) != std::string::npos, true); -} - -TEST_F(FEIRStmtTest, FEIRStmtDexOpInvoke_StrFac) { - RedirectCout(); - std::unique_ptr dexOp = std::make_unique(allocator, 1, bc::kDexOpInvokeDirect); - dexOp->SetVA(3); - dexOp->SetVC(6); - MapleList argVRegNums({6, 7}, allocator.Adapter()); - dexOp->SetArgs(argVRegNums); - bc::BCReader::ClassElem elem; - elem.className = "Ljava/lang/String;"; - elem.elemName = ""; - elem.typeName = "(Ljava/lang/String;)V"; - dexOp->ParseImplUT(elem); - std::list feStmts = dexOp->EmitToFEIRStmts(); - ASSERT_EQ(feStmts.size(), 1); - std::list mirNodes = feStmts.front()->GenMIRStmts(mirBuilder); - ASSERT_EQ(mirNodes.size(), 1); - mirNodes.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string pattern = std::string("callassigned &Ljava_2Flang_2FStringFactory_3B_7CnewStringFromString_7C_28Ljava_" - "2Flang_2FString_3B_29Ljava_2Flang_2FString_3B \\(dread ref %Reg7_") + - MPLFEUTRegx::RefIndex(MPLFEUTRegx::kAnyNumber) + - std::string("\\) \\{ dassign %Reg6_") + MPLFEUTRegx::RefIndex(MPLFEUTRegx::kAnyNumber) + - std::string(" 0 \\}") + MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - RestoreCout(); -} - -// ---------- FEIRStmt-DexOpCheckCast ---------- -class DexOpCheckCastUT : public bc::DexOpCheckCast { - public: - DexOpCheckCastUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpCheckCast(allocatorIn, pcIn, opcodeIn) {} - ~DexOpCheckCastUT() = default; - void SetRegType(const std::string &name) { - targetTypeNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(namemangler::EncodeName(name)); - vA.regType = allocator.GetMemPool()->New(allocator, vA, targetTypeNameIdx); - vDef.regType = allocator.GetMemPool()->New(allocator, vDef, targetTypeNameIdx); - } -}; - -TEST_F(FEIRStmtTest, FEIRStmtDexOpCheckCast) { - std::unique_ptr dexOp = std::make_unique(allocator, 1, bc::kDexOpCheckCast); - dexOp->SetVA(0); - dexOp->SetRegType("Ljava/lang/String;"); - std::list feStmts = dexOp->EmitToFEIRStmts(); - ASSERT_EQ(feStmts.size(), 1); - std::list mirNodes = feStmts.front()->GenMIRStmts(mirBuilder); - ASSERT_EQ(mirNodes.size(), 1); - RedirectCout(); - mirNodes.front()->Dump(); - std::string dumpStr = GetBufferString(); - RestoreCout(); - EXPECT_EQ(dumpStr.find( - "intrinsiccallwithtypeassigned <* <$Ljava_2Flang_2FString_3B>> JAVA_CHECK_CAST (dread ref %Reg0_R") != - std::string::npos, true); - EXPECT_EQ(dumpStr.find(") { dassign %Reg0_R", 96) != std::string::npos, true); -} - -// ---------- FEIRStmt-DexOpInstanceOf ---------- -class DexOpInstanceOfUT : public bc::DexOpInstanceOf { - public: - DexOpInstanceOfUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpInstanceOf(allocatorIn, pcIn, opcodeIn) {} - ~DexOpInstanceOfUT() = default; - void SetVBType(const std::string &name) { - vB.regType = allocator.GetMemPool()->New(allocator, vB, - GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(namemangler::EncodeName(name))); - } - - void SetTargetType(const std::string &name) { - typeName = name; - } -}; - -TEST_F(FEIRStmtTest, FEIRStmtDexOpInstanceOf) { - std::unique_ptr dexOp = std::make_unique(allocator, 1, bc::kDexOpInstanceOf); - dexOp->SetVA(0); - dexOp->SetVB(1); - dexOp->SetVBType("Ljava/lang/Object;"); - dexOp->SetTargetType("Ljava/lang/String;"); - std::list feStmts = dexOp->EmitToFEIRStmts(); - ASSERT_EQ(feStmts.size(), 1); - std::list mirNodes = feStmts.front()->GenMIRStmts(mirBuilder); - ASSERT_EQ(mirNodes.size(), 1); - RedirectCout(); - mirNodes.front()->Dump(); - std::string dumpStr = GetBufferString(); - RestoreCout(); - EXPECT_EQ(dumpStr.find("dassign %Reg0_Z 0 (intrinsicopwithtype u1 <* <$Ljava_2Flang_2FString_3B>> JAVA_INSTANCE_OF " - "(dread ref %Reg1_R") != std::string::npos, true); -} - -// ---------- FEIRStmt-DexOpArrayLength ---------- -class DexOpArrayLengthUT : public bc::DexOpArrayLength { - public: - DexOpArrayLengthUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpArrayLength(allocatorIn, pcIn, opcodeIn) {} - ~DexOpArrayLengthUT() = default; - - void SetVBType(const std::string &name) { - vB.regType = allocator.GetMemPool()->New(allocator, vB, - GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(namemangler::EncodeName(name))); - } - - void SetFuncNameIdx(uint32 idx) { - funcNameIdx = idx; - } -}; - -TEST_F(FEIRStmtTest, FEIRStmtDexOpArrayLength) { - std::unique_ptr dexOp = std::make_unique(allocator, 1, bc::kDexOpArrayLength); - dexOp->SetVA(0); - dexOp->SetVB(1); - dexOp->SetVBType("[Ljava/lang/Object;"); - std::list feStmts = dexOp->EmitToFEIRStmts(); - ASSERT_EQ(feStmts.size(), 1); - std::list mirNodes = feStmts.front()->GenMIRStmts(mirBuilder); - ASSERT_EQ(mirNodes.size(), 1); - RedirectCout(); - mirNodes.front()->Dump(); - std::string dumpStr = GetBufferString(); - RestoreCout(); - EXPECT_EQ(dumpStr.find("dassign %Reg0_I 0 (intrinsicop i32 JAVA_ARRAY_LENGTH (dread ref %Reg1_R") == 0, true); -} - -// ---------- FEIRStmt-DexOpArrayLengthWithCatch ---------- -TEST_F(FEIRStmtTest, FEIRStmtDexOpArrayLengthWithCatch) { - std::unique_ptr dexOp = std::make_unique(allocator, 1, bc::kDexOpArrayLength); - dexOp->SetVA(0); - dexOp->SetVB(1); - dexOp->SetVBType("[Ljava/lang/Object;"); - dexOp->SetExceptionType(bc::BCUtil::GetJavaExceptionNameMplIdx()); - dexOp->SetInstructionKind(bc::kCatch); - dexOp->SetFuncNameIdx(111); - std::list feStmts = dexOp->EmitToFEIRStmts(); - ASSERT_EQ(feStmts.size(), 2); - std::list mirNodes = feStmts.front()->GenMIRStmts(mirBuilder); - ASSERT_EQ(mirNodes.size(), 2); - RedirectCout(); - mirNodes.front()->Dump(); - std::string dumpStr1 = GetBufferString(); - mirNodes.back()->Dump(); - std::string dumpStr2 = GetBufferString(); - RestoreCout(); - EXPECT_EQ(dumpStr1.find("@L111_1") == 0, true); - EXPECT_EQ(dumpStr2.find("catch { <* <$Ljava_2Flang_2FException_3B>> }") == 0, true); -} - -// ---------- FEIRStmtDAssign-DexOpNewInstance ---------- -class DexOpNewInstanceUT : public bc::DexOpNewInstance { - public: - DexOpNewInstanceUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpNewInstance(allocatorIn, pcIn, opcodeIn) {} - ~DexOpNewInstanceUT() = default; - void SetVAType(const std::string &name) { - vA.regType = allocator.GetMemPool()->New(allocator, vA, - GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(namemangler::EncodeName(name))); - } -}; - -TEST_F(FEIRStmtTest, DexOpNewInstance) { - std::unique_ptr dexOp = std::make_unique(allocator, 0, bc::kDexOpNewInstance); - dexOp->SetVA(0); - dexOp->SetVAType("Ljava/lang/String;"); - dexOp->SetVB(1); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string pattern = std::string( - "intrinsiccallwithtype <\\$Ljava_2Flang_2FString_3B> JAVA_CLINIT_CHECK \\(\\)") + - MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - EXPECT_EQ(mirStmts.size(), 1); - RestoreCout(); - mirStmts = stmts.back()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.back()->Dump(); - dumpStr = GetBufferString(); - pattern = std::string( - "dassign %Reg0_") + MPLFEUTRegx::RefIndex(MPLFEUTRegx::kAnyNumber) + - std::string(" 0 \\(gcmalloc ref <\\$Ljava_2Flang_2FString_3B>\\)") + - MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - EXPECT_EQ(mirStmts.size(), 1); - RestoreCout(); -} - -// ---------- FEIRStmt-DexOpConst ---------- -class DexOpConstUT : public bc::DexOpConst { - public: - DexOpConstUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpConst(allocatorIn, pcIn, opcodeIn) {} - ~DexOpConstUT() = default; - - void SetWideAndVReg(bool isWideIn) { - isWide = isWideIn; - SetVAImpl(0); // reg num - SetVBImpl(123); // const value - SetWideVBImpl(static_cast(-1)); // wide const value - } -}; - -TEST_F(FEIRStmtTest, DexOpConst) { - RedirectCout(); - // const/4 - std::unique_ptr dexOpConst4 = std::make_unique(allocator, 1, bc::kDexOpConst4); - dexOpConst4->SetWideAndVReg(false); - std::list feStmts = dexOpConst4->EmitToFEIRStmts(); - ASSERT_EQ(feStmts.size(), 1); - std::list mirNodes = feStmts.front()->GenMIRStmts(mirBuilder); - ASSERT_EQ(mirNodes.size(), 1); - mirNodes.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string pattern = std::string("dassign %Reg0_I 0 \\(cvt i32 i8 \\(constval i8 123\\)\\)") + MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - // const/16 - std::unique_ptr dexOpConst16 = std::make_unique(allocator, 1, bc::kDexOpConst16); - dexOpConst16->SetWideAndVReg(false); - dexOpConst16->EmitToFEIRStmts().front()->GenMIRStmts(mirBuilder).front()->Dump(); - dumpStr = GetBufferString(); - pattern = std::string("dassign %Reg0_I 0 \\(cvt i32 i16 \\(constval i16 123\\)\\)") + MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - // const - std::unique_ptr dexOpConst = std::make_unique(allocator, 1, bc::kDexOpConst); - dexOpConst->SetWideAndVReg(false); - dexOpConst->EmitToFEIRStmts().front()->GenMIRStmts(mirBuilder).front()->Dump(); - dumpStr = GetBufferString(); - pattern = std::string("dassign %Reg0_I 0 \\(constval i32 123\\)") + MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - // const/high16 - std::unique_ptr dexOpConstHigh16 = std::make_unique(allocator, 1, bc::kDexOpConstHigh16); - dexOpConstHigh16->SetWideAndVReg(false); - dexOpConstHigh16->EmitToFEIRStmts().front()->GenMIRStmts(mirBuilder).front()->Dump(); - dumpStr = GetBufferString(); - auto pos = dumpStr.find("dassign %Reg0_I 0 (shl i32 ("); - EXPECT_EQ(pos, 0); - pos = dumpStr.find(" cvt i32 i16 (constval i16 123),", 28); - EXPECT_EQ(pos, 29); - pos = dumpStr.find(" constval i32 16))", 65); - EXPECT_EQ(pos, 65); - RestoreCout(); -} - -TEST_F(FEIRStmtTest, DexOpConstWide) { - RedirectCout(); - // const-wide/16 - std::unique_ptr dexOpConstWide16 = std::make_unique(allocator, 1, bc::kDexOpConstWide16); - dexOpConstWide16->SetWideAndVReg(true); - std::list feStmts = dexOpConstWide16->EmitToFEIRStmts(); - ASSERT_EQ(feStmts.size(), 1); - std::list mirNodes = feStmts.front()->GenMIRStmts(mirBuilder); - ASSERT_EQ(mirNodes.size(), 1); - mirNodes.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string pattern = std::string("dassign %Reg0_J 0 \\(cvt i64 i16 \\(constval i16 123\\)\\)") + MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - // const-wide/32 - std::unique_ptr dexOpConstWide32 = std::make_unique(allocator, 1, bc::kDexOpConstWide32); - dexOpConstWide32->SetWideAndVReg(true); - dexOpConstWide32->EmitToFEIRStmts().front()->GenMIRStmts(mirBuilder).front()->Dump(); - dumpStr = GetBufferString(); - pattern = std::string("dassign %Reg0_J 0 \\(cvt i64 i32 \\(constval i32 123\\)\\)") + MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - // const-wide - std::unique_ptr dexOpConstWide = std::make_unique(allocator, 1, bc::kDexOpConstWide); - dexOpConstWide->SetWideAndVReg(true); - dexOpConstWide->EmitToFEIRStmts().front()->GenMIRStmts(mirBuilder).front()->Dump(); - pattern = std::string("dassign %Reg0_J 0 \\(constval i64 -1\\)") + MPLFEUTRegx::Any(); - dumpStr = GetBufferString(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - // const-wide/high16 - std::unique_ptr dexOpConstWideHigh16 = - std::make_unique(allocator, 1, bc::kDexOpConstWideHigh16); - dexOpConstWideHigh16->SetWideAndVReg(true); - dexOpConstWideHigh16->EmitToFEIRStmts().front()->GenMIRStmts(mirBuilder).front()->Dump(); - dumpStr = GetBufferString(); - auto pos = dumpStr.find("dassign %Reg0_J 0 (shl i64 ("); - EXPECT_EQ(pos, 0); - pos = dumpStr.find(" cvt i64 i16 (constval i16 123),", 29); - EXPECT_EQ(pos, 29); - pos = dumpStr.find(" constval i32 48))", 65); - EXPECT_EQ(pos, 65); - RestoreCout(); -} - -// ---------- FEIRStmtDAssign-DexOpNewArray ---------- -class DexOpNewArrayUT : public bc::DexOpNewArray { - public: - DexOpNewArrayUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpNewArray(allocatorIn, pcIn, opcodeIn) {} - ~DexOpNewArrayUT() = default; - void SetVAType(const std::string &name) { - vA.regType = allocator.GetMemPool()->New(allocator, vA, - GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(namemangler::EncodeName(name))); - vB.regType = allocator.GetMemPool()->New(allocator, vB, - GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(bc::BCUtil::kInt)); - } -}; - -TEST_F(FEIRStmtTest, DexOpNewArrayUT) { - std::unique_ptr dexOp = std::make_unique(allocator, 1, bc::kDexOpNewArray); - dexOp->SetVA(0); - dexOp->SetVAType("[Ljava/lang/Object;"); - dexOp->SetVB(1); - dexOp->SetVC(2); - std::list feStmts = dexOp->EmitToFEIRStmts(); - ASSERT_EQ(feStmts.size(), 1); - std::list mirNodes = feStmts.front()->GenMIRStmts(mirBuilder); - ASSERT_EQ(mirNodes.size(), 1); - RedirectCout(); - mirNodes.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string pattern = std::string( - "dassign %Reg0_") + MPLFEUTRegx::RefIndex(MPLFEUTRegx::kAnyNumber) + - std::string(" 0 \\(gcmallocjarray ref <\\[\\] <\\* <\\$Ljava_2Flang_2FObject_3B>>> ") + - std::string("\\(dread i32 %Reg1_I\\)\\)") + - MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - RestoreCout(); -} - -// ---------- FEIRExprBinary - binop/2addr ---------- -class DexOpBinaryOp2AddrUT : public bc::DexOpBinaryOp2Addr { - public: - DexOpBinaryOp2AddrUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpBinaryOp2Addr(allocatorIn, pcIn, opcodeIn) {} - ~DexOpBinaryOp2AddrUT() = default; - void SetVAImpl(uint32 num) { - vDef.regNum = num; - vDef.isDef = true; - vA.regNum = num; - defedRegs.emplace_back(&vDef); - usedRegs.emplace_back(&vA); - std::string typeName; // typeName of A, B are same - if (bc::kDexOpAddInt2Addr <= opcode && opcode <= bc::kDexOpUshrInt2Addr) { - typeName = bc::BCUtil::kInt; - } else if (bc::kDexOpAddLong2Addr <= opcode && opcode <= bc::kDexOpUshrLong2Addr) { - typeName = bc::BCUtil::kLong; - } else if (bc::kDexOpAddFloat2Addr <= opcode && opcode <= bc::kDexOpRemFloat2Addr) { - typeName = bc::BCUtil::kFloat; - } else if (bc::kDexOpAddDouble2Addr <= opcode && opcode <= bc::kDexOpRemDouble2Addr) { - typeName = bc::BCUtil::kDouble; - } else { - CHECK_FATAL(false, "Invalid opcode: 0x%x in DexOpBinaryOp2Addr", opcode); - } - GStrIdx usedTypeNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(typeName); - vDef.regType = allocator.GetMemPool()->New(allocator, vDef, usedTypeNameIdx); - vA.regType = allocator.GetMemPool()->New(allocator, vA, usedTypeNameIdx); - vB.regType = allocator.GetMemPool()->New(allocator, vB, usedTypeNameIdx); - } -}; - -TEST_F(FEIRStmtTest, DexOpBinaryOp2AddrIntAdd) { - std::unique_ptr dexOp = - std::make_unique(allocator, 0, bc::kDexOpAddInt2Addr); - dexOp->SetVA(0); - dexOp->SetVB(1); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string expectedStr = "dassign %Reg0_I 0 (add i32 (dread i32 %Reg0_I, dread i32 %Reg1_I))"; - EXPECT_EQ(dumpStr.find(expectedStr) != std::string::npos, true); - RestoreCout(); -} - -TEST_F(FEIRStmtTest, FEIRExprBinaryOf2AddrIntSub) { - std::unique_ptr dexOp = - std::make_unique(allocator, 0, bc::kDexOpSubInt2Addr); - dexOp->SetVA(0); - dexOp->SetVB(1); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string expectedStr = "dassign %Reg0_I 0 (sub i32 (dread i32 %Reg0_I, dread i32 %Reg1_I))"; - EXPECT_EQ(dumpStr.find(expectedStr) != std::string::npos, true); - RestoreCout(); -} - -TEST_F(FEIRStmtTest, FEIRExprBinaryOf2AddrIntShr) { - std::unique_ptr dexOp = - std::make_unique(allocator, 0, bc::kDexOpShrInt2Addr); - dexOp->SetVA(0); - dexOp->SetVB(1); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string expectedStr = "dassign %Reg0_I 0 (ashr i32 (dread i32 %Reg0_I, dread i32 %Reg1_I))"; - EXPECT_EQ(dumpStr.find(expectedStr) != std::string::npos, true); - RestoreCout(); -} - -TEST_F(FEIRStmtTest, FEIRExprBinaryOf2AddrLongXor) { - std::unique_ptr dexOp = - std::make_unique(allocator, 0, bc::kDexOpXorLong2Addr); - dexOp->SetVA(0); - dexOp->SetVB(1); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string expectedStr = "dassign %Reg0_J 0 (bxor i64 (dread i64 %Reg0_J, dread i64 %Reg1_J))"; - EXPECT_EQ(dumpStr.find(expectedStr) != std::string::npos, true); - RestoreCout(); -} - -TEST_F(FEIRStmtTest, FEIRExprBinaryOf2AddrFloatSub) { - std::unique_ptr dexOp = - std::make_unique(allocator, 0, bc::kDexOpSubFloat2Addr); - dexOp->SetVA(0); - dexOp->SetVB(1); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string expectedStr = ""; - EXPECT_EQ(dumpStr.find(expectedStr) != std::string::npos, true); - RestoreCout(); -} - -TEST_F(FEIRStmtTest, FEIRExprBinaryOf2AddrDoubleMul) { - std::unique_ptr dexOp = - std::make_unique(allocator, 0, bc::kDexOpMulDouble2Addr); - dexOp->SetVA(0); - dexOp->SetVB(1); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string expectedStr = "dassign %Reg0_D 0 (mul f64 (dread f64 %Reg0_D, dread f64 %Reg1_D))"; - EXPECT_EQ(dumpStr.find(expectedStr) != std::string::npos, true); - RestoreCout(); -} - -TEST_F(FEIRStmtTest, FEIRExprBinaryOf2AddrDoubleDiv) { - std::unique_ptr dexOp = - std::make_unique(allocator, 0, bc::kDexOpDivDouble2Addr); - dexOp->SetVA(0); - dexOp->SetVB(1); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string expectedStr = "dassign %Reg0_D 0 (div f64 (dread f64 %Reg0_D, dread f64 %Reg1_D))"; - EXPECT_EQ(dumpStr.find(expectedStr) != std::string::npos, true); - RestoreCout(); -} - -TEST_F(FEIRStmtTest, FEIRExprBinaryOf2AddrDoubleRem) { - std::unique_ptr dexOp = - std::make_unique(allocator, 0, bc::kDexOpRemDouble2Addr); - dexOp->SetVA(0); - dexOp->SetVB(1); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string expectedStr = "dassign %Reg0_D 0 (rem f64 (dread f64 %Reg0_D, dread f64 %Reg1_D))"; - EXPECT_EQ(dumpStr.find(expectedStr) != std::string::npos, true); - RestoreCout(); -} - -// ---------- FEIRExprUnary - unop ---------- -class DexOpUnaryOpUT : public bc::DexOpUnaryOp { - public: - DexOpUnaryOpUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpUnaryOp(allocatorIn, pcIn, opcodeIn) {} - ~DexOpUnaryOpUT() = default; - void SetVAImpl(uint32 num) { - vA.regNum = num; - vA.isDef = true; - defedRegs.emplace_back(&vA); - auto it = GetOpcodeMapForUnary().find(opcode); - CHECK_FATAL(it != GetOpcodeMapForUnary().end(), "Invalid opcode: %u in DexOpUnaryOp", opcode); - mirOp = std::get<0>(it->second); - vA.regType = allocator.GetMemPool()->New(allocator, vA, std::get<1>(it->second)); - vB.regType = allocator.GetMemPool()->New(allocator, vB, std::get<2>(it->second)); - } -}; - -TEST_F(FEIRStmtTest, DexOpunaryOp) { - RedirectCout(); - // OP_cvt - std::unique_ptr dexOp1 = std::make_unique(allocator, 0, bc::kDexOpFloatToInt); - dexOp1->SetVA(0); - dexOp1->SetVB(1); - std::list stmts = dexOp1->EmitToFEIRStmts(); - ASSERT_EQ(stmts.size(), 1); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string pattern = std::string("dassign %Reg0_I 0 \\(cvt i32 f32 \\(dread f32 %Reg1_F\\)\\)") + MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - // OP_sext - std::unique_ptr dexOp2 = std::make_unique(allocator, 0, bc::kDexOpIntToByte); - dexOp2->SetVA(0); - dexOp2->SetVB(1); - dexOp2->EmitToFEIRStmts().front()->GenMIRStmts(mirBuilder).front()->Dump(); - dumpStr = GetBufferString(); - pattern = std::string("dassign %Reg0_B 0 \\(sext i8 8 \\(dread i32 %Reg1_I\\)\\)") + MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - // OP_zext - std::unique_ptr dexOp3 = std::make_unique(allocator, 0, bc::kDexOpIntToChar); - dexOp3->SetVA(0); - dexOp3->SetVB(1); - dexOp3->EmitToFEIRStmts().front()->GenMIRStmts(mirBuilder).front()->Dump(); - dumpStr = GetBufferString(); - pattern = std::string("dassign %Reg0_C 0 \\(zext u16 16 \\(dread i32 %Reg1_I\\)\\)") + MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - // OP_neg - std::unique_ptr dexOp4 = std::make_unique(allocator, 0, bc::kDexOpNegInt); - dexOp4->SetVA(0); - dexOp4->SetVB(1); - dexOp4->EmitToFEIRStmts().front()->GenMIRStmts(mirBuilder).front()->Dump(); - dumpStr = GetBufferString(); - pattern = std::string("dassign %Reg0_I 0 \\(neg i32 \\(dread i32 %Reg1_I\\)\\)") + MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - // OP_bnot - std::unique_ptr dexOp5 = std::make_unique(allocator, 0, bc::kDexOpNotLong); - dexOp5->SetVA(0); - dexOp5->SetVB(1); - dexOp5->EmitToFEIRStmts().front()->GenMIRStmts(mirBuilder).front()->Dump(); - dumpStr = GetBufferString(); - pattern = std::string("dassign %Reg0_J 0 \\(bnot i64 \\(dread i64 %Reg1_J\\)\\)") + MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - RestoreCout(); -} - -// ---------- FEIRExprBinary - binop ---------- -class DexOpBinaryOpUT : public bc::DexOpBinaryOp { - public: - DexOpBinaryOpUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpBinaryOp(allocatorIn, pcIn, opcodeIn) {} - ~DexOpBinaryOpUT() = default; - void SetVBImpl(uint32 num) { - vB.regNum = num; - vB.regTypeItem = vA.regTypeItem; - vB.regType = vA.regType; - usedRegs.emplace_back(&vB); - } - - void SetVCImpl(uint32 num) { - vC.regNum = num; - vC.regTypeItem = vA.regTypeItem; - vC.regType = vA.regType; - usedRegs.emplace_back(&vC); - } -}; - -TEST_F(FEIRStmtTest, DexOpBinaryOpOfDoubleRem) { - std::unique_ptr dexOp = std::make_unique(allocator, 0, bc::kDexOpRemDouble); - dexOp->SetVA(0); - dexOp->SetVB(1); - dexOp->SetVC(2); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string expectedStr = "dassign %Reg0_D 0 (rem f64 (dread f64 %Reg1_D, dread f64 %Reg2_D))"; - EXPECT_EQ(dumpStr.find(expectedStr) != std::string::npos, true); - RestoreCout(); -} - -// ---------- FEIRExprBinary - binop/Lit ---------- -class DexOpBinaryOpLitUT : public bc::DexOpBinaryOpLit { - public: - DexOpBinaryOpLitUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpBinaryOpLit(allocatorIn, pcIn, opcodeIn) {} - ~DexOpBinaryOpLitUT() = default; - void SetVBImpl(uint32 num) { - vB.regNum = num; - std::string typeName = bc::BCUtil::kInt; - GStrIdx usedTypeNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(typeName); - vB.regType = allocator.GetMemPool()->New(allocator, vB, usedTypeNameIdx); - usedRegs.emplace_back(&vB); - } -}; - -TEST_F(FEIRStmtTest, DexOpBinaryOpLiOfRemIntLit16) { - std::unique_ptr dexOp = - std::make_unique(allocator, 0, bc::kDexOpRemIntLit16); - dexOp->SetVA(0); - dexOp->SetVB(1); - dexOp->SetVC(20); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string expectedStr = "dassign %Reg0_I 0 (rem i32 (\n dread i32 %Reg1_I,\n cvt i32 i16 (constval i16 20)))"; - EXPECT_EQ(dumpStr.find(expectedStr) != std::string::npos, true); - RestoreCout(); -} - -TEST_F(FEIRStmtTest, DexOpBinaryOpLiOfRemIntLit8) { - std::unique_ptr dexOp = - std::make_unique(allocator, 0, bc::kDexOpRemIntLit8); - dexOp->SetVA(0); - dexOp->SetVB(1); - dexOp->SetVC(20); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string expectedStr = "dassign %Reg0_I 0 (rem i32 (\n dread i32 %Reg1_I,\n cvt i32 i8 (constval i8 20)))"; - EXPECT_EQ(dumpStr.find(expectedStr) != std::string::npos, true); - RestoreCout(); -} - -TEST_F(FEIRStmtTest, DexOpBinaryOpLiOfRsubIntLit8) { - std::unique_ptr dexOp = - std::make_unique(allocator, 0, bc::kDexOpRsubIntLit8); - dexOp->SetVA(0); - dexOp->SetVB(1); - dexOp->SetVC(20); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string expectedStr = "dassign %Reg0_I 0 (sub i32 (\n cvt i32 i8 (constval i8 20),\n dread i32 %Reg1_I))"; - EXPECT_EQ(dumpStr.find(expectedStr) != std::string::npos, true); - RestoreCout(); -} - -class DexOpSputUT : public bc::DexOpSput { - public: - DexOpSputUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpSput(allocatorIn, pcIn, opcodeIn) {} - ~DexOpSputUT() = default; - std::map opcodeTypeMap = { - {bc::BCUtil::kChar, "C"}, - {bc::BCUtil::kByte, "B"}, - {bc::BCUtil::kShort, "S"}, - {bc::BCUtil::kInt, "I"}, - {bc::BCUtil::kFloat, "F"}, - {bc::BCUtil::kLong, "J"}, - {bc::BCUtil::kDouble, "D"}, - {bc::BCUtil::kJavaObjectName, "Ljava/lang/Object;"}, - }; - - std::map opcodeMirMap = { - {bc::BCUtil::kChar, "u16"}, - {bc::BCUtil::kByte, "i8"}, - {bc::BCUtil::kShort, "i16"}, - {bc::BCUtil::kInt, "i32"}, - {bc::BCUtil::kFloat, "f32"}, - {bc::BCUtil::kLong, "i64"}, - {bc::BCUtil::kDouble, "f64"}, - {bc::BCUtil::kDouble, "D"}, - {bc::BCUtil::kJavaObjectName, "ref"}, - }; - - void SetFieldInfoArg(std::string typeNameIn) { - bc::BCReader::ClassElem fieldInfo; - fieldInfo.className = "Landroid/icu/text/CurrencyMetaInfo;"; - fieldInfo.elemName = "hasData"; - fieldInfo.typeName = typeNameIn; - structElemNameIdx = allocator.New(fieldInfo.className, fieldInfo.elemName, fieldInfo.typeName); - vA.regType = allocator.GetMemPool()->New(allocator, vA, structElemNameIdx->type); - } -}; - -TEST_F(FEIRStmtTest, DexOpSput) { - std::unique_ptr dexOp = std::make_unique(allocator, 0, bc::kDexOpSput); - dexOp->SetVA(3); - for (std::map::iterator it = dexOp->opcodeTypeMap.begin(); - it != dexOp->opcodeTypeMap.end(); ++it) { - auto mirOp = dexOp->opcodeMirMap.find(it->first); - CHECK_FATAL(mirOp != dexOp->opcodeMirMap.end(), "Invalid opcode"); - - dexOp->SetFieldInfoArg(it->second); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string pattern = std::string( - "intrinsiccallwithtype <\\$Ljava_2Flang_2FObject_3B> JAVA_CLINIT_CHECK \\(\\)") + - MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - EXPECT_EQ(mirStmts.size(), 2); - RestoreCout(); - - mirStmts = stmts.back()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.back()->Dump(); - dumpStr = GetBufferString(); - if (it->first != bc::BCUtil::kJavaObjectName) { - pattern = std::string( - "dassign \\$Landroid_2Ficu_2Ftext_2FCurrencyMetaInfo_3B_7ChasData 0 \\(dread ") + - std::string(mirOp->second) + std::string(" %Reg3_") + it->second + std::string("\\)") + MPLFEUTRegx::Any(); - } else { - pattern = std::string( - "dassign \\$Landroid_2Ficu_2Ftext_2FCurrencyMetaInfo_3B_7ChasData 0 \\(dread ") + std::string(mirOp->second) + - std::string(" %Reg3_") + MPLFEUTRegx::RefIndex(MPLFEUTRegx::kAnyNumber) + - std::string("\\)") + MPLFEUTRegx::Any(); - } - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - EXPECT_EQ(mirStmts.size(), 2); - RestoreCout(); - } -} - -TEST_F(FEIRStmtTest, DexOpSputAOT) { - FEOptions::GetInstance().SetIsAOT(true); - FEManager::GetTypeManager().InitMCCFunctions(); - std::unique_ptr dexOp = std::make_unique(allocator, 0, bc::kDexOpSput); - dexOp->SetVA(3); - dexOp->SetFieldInfoArg("B"); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string pattern = std::string("hexpc : 0 callassigned &MCC_StaticFieldSetByte \\(constval i32 -1, dread i8 ") + - std::string("\\$Landroid_2Ficu_2Ftext_2FCurrencyMetaInfo_3B_7ChasData\\) \\{\\}") + MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - RestoreCout(); - FEOptions::GetInstance().SetIsAOT(false); -} - -class DexOpCompareUT : public bc::DexOpCompare { - public: - DexOpCompareUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpCompare(allocatorIn, pcIn, opcodeIn) {} - ~DexOpCompareUT() = default; - void SetRegNum() { - int mockReg0 = 0; - int mockReg1 = 1; - int mockReg2 = 2; - SetVA(mockReg0); - SetVB(mockReg1); - SetVC(mockReg2); - } - - void SetVBImpl(uint32 num) { - vB.regNum = num; - std::string typeName; - if (opcode == bc::kDexOpCmplFloat || opcode == bc::kDexOpCmpgFloat) { - typeName = bc::BCUtil::kFloat; - } else if (opcode == bc::kDexOpCmplDouble || opcode == bc::kDexOpCmpgDouble) { - typeName = bc::BCUtil::kDouble; - } else { - // kDexOpCmpLong - typeName = bc::BCUtil::kLong; - } - GStrIdx usedTypeNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(typeName); - vB.regType = allocator.GetMemPool()->New(allocator, vB, usedTypeNameIdx); - usedRegs.emplace_back(&vB); - } - - void SetVCImpl(uint32 num) { - vC = vB; - vC.regNum = num; - vC.regType = vB.regType; - usedRegs.emplace_back(&vC); - } -}; - -TEST_F(FEIRStmtTest, FEIRStmtDexOpCmp) { - RedirectCout(); - std::unique_ptr dexOpCmpLong = std::make_unique(allocator, 1, bc::kDexOpCmpLong); - dexOpCmpLong->SetRegNum(); - std::list feStmts = dexOpCmpLong->EmitToFEIRStmts(); - ASSERT_EQ(feStmts.size(), 1); - std::list mirNodes = feStmts.front()->GenMIRStmts(mirBuilder); - ASSERT_EQ(mirNodes.size(), 1); - mirNodes.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string pattern = std::string("dassign %Reg0_I 0 \\(cmp i32 i64 \\(dread i64 %Reg1_J, dread i64 %Reg2_J\\)\\)") + - MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - - std::unique_ptr dexOpCmplFloat = std::make_unique(allocator, 1, bc::kDexOpCmplFloat); - dexOpCmplFloat->SetRegNum(); - dexOpCmplFloat->EmitToFEIRStmts().front()->GenMIRStmts(mirBuilder).front()->Dump(); - dumpStr = GetBufferString(); - pattern = std::string("dassign %Reg0_I 0 \\(cmpl i32 f32 \\(dread f32 %Reg1_F, dread f32 %Reg2_F\\)\\)") + - MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - - std::unique_ptr dexOpCmpgFloat = std::make_unique(allocator, 1, bc::kDexOpCmpgFloat); - dexOpCmpgFloat->SetRegNum(); - dexOpCmpgFloat->EmitToFEIRStmts().front()->GenMIRStmts(mirBuilder).front()->Dump(); - dumpStr = GetBufferString(); - pattern = std::string("dassign %Reg0_I 0 \\(cmpg i32 f32 \\(dread f32 %Reg1_F, dread f32 %Reg2_F\\)\\)") + - MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - - std::unique_ptr dexOpCmplDouble = - std::make_unique(allocator, 1, bc::kDexOpCmplDouble); - dexOpCmplDouble->SetRegNum(); - dexOpCmplDouble->EmitToFEIRStmts().front()->GenMIRStmts(mirBuilder).front()->Dump(); - dumpStr = GetBufferString(); - pattern = std::string("dassign %Reg0_I 0 \\(cmpl i32 f64 \\(dread f64 %Reg1_D, dread f64 %Reg2_D\\)\\)") + - MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - - std::unique_ptr dexOpCmpgDouble = - std::make_unique(allocator, 1, bc::kDexOpCmpgDouble); - dexOpCmpgDouble->SetRegNum(); - dexOpCmpgDouble->EmitToFEIRStmts().front()->GenMIRStmts(mirBuilder).front()->Dump(); - dumpStr = GetBufferString(); - pattern = std::string("dassign %Reg0_I 0 \\(cmpg i32 f64 \\(dread f64 %Reg1_D, dread f64 %Reg2_D\\)\\)") + - MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - RestoreCout(); -} -class DexOpThrowUT : public bc::DexOpThrow { - public: - DexOpThrowUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpThrow(allocatorIn, pcIn, opcodeIn) {} - ~DexOpThrowUT() = default; - - void SetVA(uint32 num) { - vA.regNum = num; - std::string typeName = bc::BCUtil::kAggregate; - vA.regType = allocator.GetMemPool()->New(allocator, vA, - GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(typeName)); - } -}; - -// ---------- FEIRExprBinary - DexOpThrow ---------- -TEST_F(FEIRStmtTest, DexOpThrow) { - std::unique_ptr dexOp = std::make_unique(allocator, 0, bc::kDexOpThrow); - dexOp->SetVA(3); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string pattern = std::string( - "throw \\(dread ref %Reg3_") + MPLFEUTRegx::RefIndex(MPLFEUTRegx::kAnyNumber) + std::string("\\)") + - MPLFEUTRegx::Any(); - EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); - EXPECT_EQ(mirStmts.size(), 1); - RestoreCout(); -} - -// ---------- FEIRExprBinary - DexOpAget ---------- -class DexOpAgetUT : public bc::DexOpAget { - public: - DexOpAgetUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpAget(allocatorIn, pcIn, opcodeIn) {} - ~DexOpAgetUT() = default; - void SetType(bc::DexOpCode opcode) { - std::string elemTypeName; - switch (opcode) { - case bc::kDexOpAget: { - elemTypeName = bc::BCUtil::kInt; - break; - } - case bc::kDexOpAgetWide: { - elemTypeName = bc::BCUtil::kWide; - break; - } - case bc::kDexOpAgetObject: { - elemTypeName = bc::BCUtil::kJavaObjectName; - break; - } - case bc::kDexOpAgetBoolean: { - elemTypeName = bc::BCUtil::kBoolean; - break; - } - case bc::kDexOpAgetByte: { - elemTypeName = bc::BCUtil::kByte; - break; - } - case bc::kDexOpAgetChar: { - elemTypeName = bc::BCUtil::kChar; - break; - } - case bc::kDexOpAgetShort: { - elemTypeName = bc::BCUtil::kShort; - break; - } - default: { - CHECK_FATAL(false, "Invalid opcode : 0x%x in DexOpAget", opcode); - break; - } - } - - std::string arrayTypeName = "[" + elemTypeName; - elemTypeName = namemangler::EncodeName(elemTypeName); - arrayTypeName = namemangler::EncodeName(arrayTypeName); - vA.regType = allocator.GetMemPool()->New(allocator, vA, - GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(elemTypeName)); - vB.regType = allocator.GetMemPool()->New(allocator, vB, - GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(arrayTypeName)); - - GStrIdx usedTypeNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(bc::BCUtil::kInt); - vC.regType = allocator.GetMemPool()->New(allocator, vC, usedTypeNameIdx); - } -}; - -TEST_F(FEIRStmtTest, DexOpAgetObject) { - std::unique_ptr dexOp = std::make_unique(allocator, 0, bc::kDexOpAgetObject); - dexOp->SetVA(0); - dexOp->SetVB(1); - dexOp->SetVC(2); - dexOp->SetType(bc::kDexOpAgetObject); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string expect1 = std::string("dassign %Reg0_"); - std::string expect2 = std::string(" 0 (iread ref <* <* <$Ljava_2Flang_2FObject_3B>>> 0 " - "(array 1 ptr <* <[] <* <$Ljava_2Flang_2FObject_3B>>>> (dread ref %Reg1_"); - std::string expect3 = std::string(", dread i32 %Reg2_I"); - EXPECT_EQ(dumpStr.find(expect1) != std::string::npos, true); - EXPECT_EQ(dumpStr.find(expect2) != std::string::npos, true); - EXPECT_EQ(dumpStr.find(expect3) != std::string::npos, true); - EXPECT_EQ(mirStmts.size(), 1); - RestoreCout(); -} - -TEST_F(FEIRStmtTest, DexOpAgetBoolean) { - std::unique_ptr dexOp = std::make_unique(allocator, 0, bc::kDexOpAgetBoolean); - dexOp->SetVA(0); - dexOp->SetVB(1); - dexOp->SetVC(2); - dexOp->SetType(bc::kDexOpAgetBoolean); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - - std::string expect1 = std::string("dassign %Reg0_Z"); - std::string expect2 = std::string("0 (iread u1 <* u1> 0 (array 1 ptr <* <[] u1>> (dread ref %Reg1_"); - std::string expect3 = std::string(", dread i32 %Reg2_I"); - EXPECT_EQ(dumpStr.find(expect1) != std::string::npos, true); - EXPECT_EQ(dumpStr.find(expect2) != std::string::npos, true); - EXPECT_EQ(dumpStr.find(expect3) != std::string::npos, true); - - EXPECT_EQ(mirStmts.size(), 1); - RestoreCout(); -} - -// ---------- FEIRExprBinary - DexOpAput ---------- -class DexOpAputUT : public bc::DexOpAput { - public: - DexOpAputUT(MapleAllocator &allocatorIn, uint32 pcIn, bc::DexOpCode opcodeIn) - : bc::DexOpAput(allocatorIn, pcIn, opcodeIn) {} - ~DexOpAputUT() = default; - void SetType(bc::DexOpCode opcode) { - std::string elemTypeName; - switch (opcode) { - case bc::kDexOpAput: { - elemTypeName = bc::BCUtil::kInt; - break; - } - case bc::kDexOpAputWide: { - elemTypeName = bc::BCUtil::kWide; - break; - } - case bc::kDexOpAputObject: { - elemTypeName = bc::BCUtil::kJavaObjectName; - break; - } - case bc::kDexOpAputBoolean: { - elemTypeName = bc::BCUtil::kBoolean; - break; - } - case bc::kDexOpAputByte: { - elemTypeName = bc::BCUtil::kByte; - break; - } - case bc::kDexOpAputChar: { - elemTypeName = bc::BCUtil::kChar; - break; - } - case bc::kDexOpAputShort: { - elemTypeName = bc::BCUtil::kShort; - break; - } - default: { - CHECK_FATAL(false, "Invalid opcode : 0x%x in DexOpAget", opcode); - break; - } - } - - std::string arrayTypeName = "[" + elemTypeName; - elemTypeName = namemangler::EncodeName(elemTypeName); - arrayTypeName = namemangler::EncodeName(arrayTypeName); - vA.regType = allocator.GetMemPool()->New(allocator, vA, - GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(elemTypeName)); - vB.regType = allocator.GetMemPool()->New(allocator, vB, - GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(arrayTypeName)); - GStrIdx usedTypeNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(bc::BCUtil::kInt); - vC.regType = allocator.GetMemPool()->New(allocator, vC, usedTypeNameIdx); - } -}; - -TEST_F(FEIRStmtTest, kDexOpAputBoolean) { - std::unique_ptr dexOp = std::make_unique(allocator, 0, bc::kDexOpAputBoolean); - dexOp->SetVA(0); - dexOp->SetVB(1); - dexOp->SetVC(2); - dexOp->SetType(bc::kDexOpAputBoolean); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - EXPECT_EQ(mirStmts.size(), 1); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string expect1 = std::string("iassign <* u1> 0 ("); - std::string expect2 = std::string("array 1 ptr <* <[] u1>> (dread ref %Reg1_R"); - std::string expect3 = std::string(", dread i32 %Reg2_I), "); - std::string expect4 = std::string(" dread u1 %Reg0_Z)"); - EXPECT_EQ(dumpStr.find(expect1) != std::string::npos, true); - EXPECT_EQ(dumpStr.find(expect2) != std::string::npos, true); - EXPECT_EQ(dumpStr.find(expect3) != std::string::npos, true); - EXPECT_EQ(dumpStr.find(expect4) != std::string::npos, true); - RestoreCout(); -} - -TEST_F(FEIRStmtTest, DexOpAputObject) { - std::unique_ptr dexOp = std::make_unique(allocator, 0, bc::kDexOpAputObject); - dexOp->SetVA(0); - dexOp->SetVB(1); - dexOp->SetVC(2); - dexOp->SetType(bc::kDexOpAputObject); - std::list stmts = dexOp->EmitToFEIRStmts(); - std::list mirStmts = stmts.front()->GenMIRStmts(mirBuilder); - EXPECT_EQ(mirStmts.size(), 1); - RedirectCout(); - mirStmts.front()->Dump(); - std::string dumpStr = GetBufferString(); - std::string expect1 = std::string("iassign <* <* <$Ljava_2Flang_2FObject_3B>>> 0 ("); - std::string expect2 = std::string("array 1 ptr <* <[] <* <$Ljava_2Flang_2FObject_3B>>>> (dread ref %Reg1_R"); - std::string expect3 = std::string(", dread i32 %Reg2_I), "); - std::string expect4 = std::string(" dread ref %Reg0_R"); - EXPECT_EQ(dumpStr.find(expect1) != std::string::npos, true); - EXPECT_EQ(dumpStr.find(expect2) != std::string::npos, true); - EXPECT_EQ(dumpStr.find(expect3) != std::string::npos, true); - EXPECT_EQ(dumpStr.find(expect4) != std::string::npos, true); - RestoreCout(); -} -#endif } // namespace maple diff --git a/src/mplfe/test/feir_test_base.cpp b/src/mplfe/test/feir_test_base.cpp index 1abe34ea328d3ddc08152c8800df6bc2074618ca..fc3baf833df0f38f18ab12e7ed8ffe53b6eca429 100644 --- a/src/mplfe/test/feir_test_base.cpp +++ b/src/mplfe/test/feir_test_base.cpp @@ -14,6 +14,7 @@ */ #include "feir_test_base.h" #include "mplfe_ut_environment.h" +#include "fe_utils.h" namespace maple { MemPool *FEIRTestBase::mp = nullptr; @@ -23,11 +24,12 @@ FEIRTestBase::FEIRTestBase() mirBuilder(&MPLFEUTEnvironment::GetMIRModule()), func(&MPLFEUTEnvironment::GetMIRModule(), StIdx(0, 0)) { func.Init(); + func.NewBody(); mirBuilder.SetCurrentFunction(func); } void FEIRTestBase::SetUpTestCase() { - mp = memPoolCtrler.NewMemPool("MemPool for FEIRTestBase", false /* isLocalPool */); + mp = FEUtils::NewMempool("MemPool for FEIRTestBase", false /* isLocalPool */); } void FEIRTestBase::TearDownTestCase() { diff --git a/src/mplfe/test/jbc_class2fe_helper_test.cpp b/src/mplfe/test/jbc_class2fe_helper_test.cpp index 7117b62f16a0089bdb01cd465f072cd482545ba0..a93b4b55db293e7fee0ad2f23baf226ff6067da9 100644 --- a/src/mplfe/test/jbc_class2fe_helper_test.cpp +++ b/src/mplfe/test/jbc_class2fe_helper_test.cpp @@ -31,7 +31,7 @@ class JBCClass2FEHelperTest : public testing::Test, public RedirectBuffer { ~JBCClass2FEHelperTest() = default; static void SetUpTestCase() { - mp = memPoolCtrler.NewMemPool("MemPool for JBCClass2FEHelperTest", false /* isLcalPool */); + mp = FEUtils::NewMempool("MemPool for JBCClass2FEHelperTest", false /* isLcalPool */); } static void TearDownTestCase() { @@ -52,7 +52,7 @@ class JBCClassField2FEHelperTest : public testing::Test, public RedirectBuffer { ~JBCClassField2FEHelperTest() = default; static void SetUpTestCase() { - mp = memPoolCtrler.NewMemPool("MemPool for JBCClassField2FEHelperTest", false /* isLocalPool */); + mp = FEUtils::NewMempool("MemPool for JBCClassField2FEHelperTest", false /* isLocalPool */); } static void TearDownTestCase() { diff --git a/src/mplfe/test/jbc_class_test.cpp b/src/mplfe/test/jbc_class_test.cpp index fc58f6136de797fe2bfddf5c042b6900c9cd7809..10c3c9fd01f6a8951083f17a0699582106c6febb 100644 --- a/src/mplfe/test/jbc_class_test.cpp +++ b/src/mplfe/test/jbc_class_test.cpp @@ -16,6 +16,7 @@ #include #include "base64.h" #include "jbc_class.h" +#include "fe_utils.h" namespace maple { namespace jbc { @@ -62,7 +63,7 @@ class JBCClassTest : public testing::Test { BasicIORead *ioJBC0001; static void SetUpTestCase() { - mp = memPoolCtrler.NewMemPool("MemPool for JBCClassTest", false /* isLocalPool */); + mp = FEUtils::NewMempool("MemPool for JBCClassTest", false /* isLocalPool */); } static void TearDownTestCase() { diff --git a/src/mplfe/test/jbc_function_test.cpp b/src/mplfe/test/jbc_function_test.cpp index 8d8e1281a284141bd55e22ae9bd084bd0cc5e202..85c1222dde26a9f8a83681e937b795032fe80993 100644 --- a/src/mplfe/test/jbc_function_test.cpp +++ b/src/mplfe/test/jbc_function_test.cpp @@ -38,7 +38,7 @@ class JBCFunctionTest : public testing::Test, public RedirectBuffer { ~JBCFunctionTest() = default; static void SetUpTestCase() { - mp = memPoolCtrler.NewMemPool("MemPool for JBCFunctionTest", false /* isLcalPool */); + mp = FEUtils::NewMempool("MemPool for JBCFunctionTest", false /* isLcalPool */); } static void TearDownTestCase() { diff --git a/src/mplfe/test/jbc_opcode_helper_test.cpp b/src/mplfe/test/jbc_opcode_helper_test.cpp index 24b8576c042516046a7087b7f619aa223caa5d40..d0886f349bb85bda7e34ffea0139abf089098460 100644 --- a/src/mplfe/test/jbc_opcode_helper_test.cpp +++ b/src/mplfe/test/jbc_opcode_helper_test.cpp @@ -22,6 +22,7 @@ #include "jbc_opcode.h" #include "jbc_opcode_helper.h" #include "redirect_buffer.h" +#include "fe_utils.h" namespace maple { class JBCOpcodeHelperTest : public testing::Test, public RedirectBuffer { @@ -34,7 +35,7 @@ class JBCOpcodeHelperTest : public testing::Test, public RedirectBuffer { ~JBCOpcodeHelperTest() = default; static void SetUpTestCase() { - mp = memPoolCtrler.NewMemPool("MemPool for JBCOpcodeHelperTest", false /* isLcalPool */); + mp = FEUtils::NewMempool("MemPool for JBCOpcodeHelperTest", false /* isLcalPool */); } static void TearDownTestCase() { diff --git a/src/mrt/deplibs/libcore-static-binding-jni-qemu.a b/src/mrt/deplibs/libcore-static-binding-jni-qemu.a index 8d997bdce8189c87ee3a4ac4bd9d1e077c0a448c..054bcd96a98437ca3c078326bfb0961b5539c7e1 100644 Binary files a/src/mrt/deplibs/libcore-static-binding-jni-qemu.a and b/src/mrt/deplibs/libcore-static-binding-jni-qemu.a differ diff --git a/tools/setup_tools.sh b/tools/setup_tools.sh index 3d2a9eef7b3ba06d540da86baa6925c086cf8fa8..2583de33fe5bdf730537e8e63307487074254322 100755 --- a/tools/setup_tools.sh +++ b/tools/setup_tools.sh @@ -181,3 +181,13 @@ else ln -s -f ${MAPLE_ROOT}/tools/qemu/package/usr/bin/qemu-aarch64 ${TOOL_BIN_PATH}/qemu-aarch64 fi ln -s -f ${MAPLE_ROOT}/tools/open64_prebuilt/x86/aarch64/bin/clangfe ${TOOL_BIN_PATH}/clangfe + +if [ ! -d $MAPLE_ROOT/../ThirdParty ]; then + cd $MAPLE_ROOT/../ + git clone https://gitee.com/openarkcompiler/ThirdParty.git + cd - +else + cd $MAPLE_ROOT/../ThirdParty + git pull origin master + cd - +fi