diff --git a/src/mapleall/bin/dex2mpl b/src/mapleall/bin/dex2mpl index 6b10930c2a4fe2dcf571c5793810c08b6b9f1d23..a2f83999f33a175f9168671a6659f8999e3712ae 100755 Binary files a/src/mapleall/bin/dex2mpl and b/src/mapleall/bin/dex2mpl differ diff --git a/src/mapleall/maple_driver/include/compiler.h b/src/mapleall/maple_driver/include/compiler.h index e33f59b9aa6a4180433af5bd020f2465ef195223..58502442d04536952c643f0d85ded540ce19a049 100644 --- a/src/mapleall/maple_driver/include/compiler.h +++ b/src/mapleall/maple_driver/include/compiler.h @@ -23,6 +23,7 @@ #include "option.h" #include "mir_module.h" #include "mir_parser.h" +#include "bin_mplt.h" namespace maple { const std::string kBinNameNone = ""; diff --git a/src/mapleall/maple_driver/include/driver_runner.h b/src/mapleall/maple_driver/include/driver_runner.h index 087c311d14992591c1c17726771970f4490a4a5e..8f51e14c506e576ba5cf25f6ea06965319bd0a76 100644 --- a/src/mapleall/maple_driver/include/driver_runner.h +++ b/src/mapleall/maple_driver/include/driver_runner.h @@ -32,7 +32,7 @@ extern const std::string mplME; class DriverRunner final { public: - DriverRunner(MIRModule *theModule, const std::vector &exeNames, Options *mpl2mplOptions, + DriverRunner(MIRModule *theModule, const std::vector &exeNames, InputFileType inpFileType, Options *mpl2mplOptions, std::string mpl2mplInput, MeOption *meOptions, const std::string &meInput, std::string actualInput, MemPool *optMp, bool fileParsed = false, bool timePhases = false, bool genVtableImpl = false, bool genMeMpl = false) @@ -47,11 +47,12 @@ class DriverRunner final { fileParsed(fileParsed), timePhases(timePhases), genVtableImpl(genVtableImpl), - genMeMpl(genMeMpl) {} + genMeMpl(genMeMpl), + inputFileType(inpFileType) {} - DriverRunner(MIRModule *theModule, const std::vector &exeNames, std::string actualInput, MemPool *optMp, + DriverRunner(MIRModule *theModule, const std::vector &exeNames, InputFileType inpFileType, std::string actualInput, MemPool *optMp, bool fileParsed = false, bool timePhases = false, bool genVtableImpl = false, bool genMeMpl = false) - : DriverRunner(theModule, exeNames, nullptr, "", nullptr, "", actualInput, optMp, fileParsed, timePhases, + : DriverRunner(theModule, exeNames, inpFileType, nullptr, "", nullptr, "", actualInput, optMp, fileParsed, timePhases, genVtableImpl, genMeMpl) {} ~DriverRunner() = default; @@ -93,6 +94,7 @@ class DriverRunner final { bool timePhases = false; bool genVtableImpl = false; bool genMeMpl = false; + InputFileType inputFileType; std::string printOutExe; }; } // namespace maple diff --git a/src/mapleall/maple_driver/include/mpl_options.h b/src/mapleall/maple_driver/include/mpl_options.h index abf4477f6ff313d3b54a6e227d1f282039e8705b..2b2ac9da7c5f6f1f22a884a3573dfebdc6f20b0a 100644 --- a/src/mapleall/maple_driver/include/mpl_options.h +++ b/src/mapleall/maple_driver/include/mpl_options.h @@ -35,6 +35,7 @@ enum InputFileType { kFileTypeMpl, kFileTypeVtableImplMpl, kFileTypeS, + kFileTypeBpl, }; enum OptimizationLevel { diff --git a/src/mapleall/maple_driver/src/driver_runner.cpp b/src/mapleall/maple_driver/src/driver_runner.cpp index 0151575a75075c4965001d86f0844d3b1c405392..2f09c44aabc250c3930659946cd0c53dc96a1e63 100644 --- a/src/mapleall/maple_driver/src/driver_runner.cpp +++ b/src/mapleall/maple_driver/src/driver_runner.cpp @@ -12,6 +12,7 @@ * FIT FOR A PARTICULAR PURPOSE. * See the Mulan PSL v2 for more details. */ +#include "compiler.h" #include "driver_runner.h" #include #include @@ -129,19 +130,34 @@ ErrorCode DriverRunner::ParseInput(const std::string &outputFile, const std::str MPLTimer timer; timer.Start(); - MIRParser parser(*theModule); ErrorCode ret = kErrorNoError; - bool parsed; if (!fileParsed) { - MPLTimer parseMirTimer; - parseMirTimer.Start(); - parsed = parser.ParseMIR(0, 0, false, true); - parseMirTimer.Stop(); - InterleavedManager::interleavedTimer.emplace_back( - std::pair("parseMpl", parseMirTimer.ElapsedMicroseconds())); - if (!parsed) { - ret = kErrorExit; - parser.EmitError(outputFile); + if (inputFileType != kFileTypeBpl) { + MIRParser parser(*theModule); + MPLTimer parseMirTimer; + parseMirTimer.Start(); + bool parsed = parser.ParseMIR(0, 0, false, true); + parseMirTimer.Stop(); + InterleavedManager::interleavedTimer.emplace_back( + std::pair("parseMpl", parseMirTimer.ElapsedMicroseconds())); + if (!parsed) { + ret = kErrorExit; + parser.EmitError(outputFile); + } + } else { + BinaryMplImport binMplt(*theModule); + binMplt.SetImported(false); + std::string modid = theModule->GetFileName(); + MPLTimer importMirTimer; + importMirTimer.Start(); + bool imported = binMplt.Import(modid, true); + importMirTimer.Stop(); + InterleavedManager::interleavedTimer.emplace_back( + std::pair("parseMpl", importMirTimer.ElapsedMicroseconds())); + if (!imported) { + ret = kErrorExit; + LogInfo::MapleLogger() << "Cannot open .bpl file: %s" << modid << '\n'; + } } } timer.Stop(); @@ -340,7 +356,9 @@ void DriverRunner::RunCGFunctions(CG &cg, CgFuncPhaseManager &cgfpm, std::vector mirLowerer.Init(); CGLowerer theLowerer(*theModule, *beCommon, cg.GenerateExceptionHandlingCode(), cg.GenerateVerboseCG()); theLowerer.RegisterBuiltIns(); - theLowerer.InitArrayClassCacheTableIndex(); + if (JAVALANG) { + theLowerer.InitArrayClassCacheTableIndex(); + } theLowerer.RegisterExternalLibraryFunctions(); theLowerer.SetCheckLoadStore(CGOptions::IsCheckArrayStore()); timer.Stop(); diff --git a/src/mapleall/maple_driver/src/maple_comb_compiler.cpp b/src/mapleall/maple_driver/src/maple_comb_compiler.cpp index 0e4eafc6e7cb8ce43515f4d1a44f325f5d9cebd5..eeee8c07a864b990b0fed7f193c4a0622a36ed62 100644 --- a/src/mapleall/maple_driver/src/maple_comb_compiler.cpp +++ b/src/mapleall/maple_driver/src/maple_comb_compiler.cpp @@ -154,7 +154,7 @@ ErrorCode MapleCombCompiler::Compile(const MplOptions &options, std::unique_ptr< LogInfo::MapleLogger() << "Starting mpl2mpl&mplme\n"; PrintCommand(options); - DriverRunner runner(theModule.get(), options.GetRunningExes(), &mpl2mplOptions, fileName, &meOptions, + DriverRunner runner(theModule.get(), options.GetRunningExes(), options.GetInputFileType(), &mpl2mplOptions, fileName, &meOptions, fileName, fileName, optMp, fileParsed, options.HasSetTimePhases(), options.HasSetGenVtableImpl(), options.HasSetGenMeMpl()); ErrorCode nErr = runner.Run(); diff --git a/src/mapleall/maple_driver/src/mpl_options.cpp b/src/mapleall/maple_driver/src/mpl_options.cpp index 466b0632501dd51654d999ca91c83991c3f08af2..337c0511998feb9e09c69afb9a44a132218f88fd 100644 --- a/src/mapleall/maple_driver/src/mpl_options.cpp +++ b/src/mapleall/maple_driver/src/mpl_options.cpp @@ -324,9 +324,9 @@ bool MplOptions::Init(const std::string &inputFile) { } else if (extensionName == "jar") { inputFileType = InputFileType::kFileTypeJar; - } else if (extensionName == "mpl") { + } else if (extensionName == "mpl" || extensionName == "bpl") { if (firstInputFile.find("VtableImpl") == std::string::npos) { - inputFileType = InputFileType::kFileTypeMpl; + inputFileType = extensionName == "mpl" ? InputFileType::kFileTypeMpl : InputFileType::kFileTypeBpl; } else { inputFileType = InputFileType::kFileTypeVtableImplMpl; } diff --git a/src/mapleall/maple_driver/src/mplcg_compiler.cpp b/src/mapleall/maple_driver/src/mplcg_compiler.cpp index 7b82094eecf1c31ac7737009128e1fd933a869ff..7b3e188f39d60e787d8dada12ff2677505b50d51 100644 --- a/src/mapleall/maple_driver/src/mplcg_compiler.cpp +++ b/src/mapleall/maple_driver/src/mplcg_compiler.cpp @@ -107,29 +107,39 @@ ErrorCode MplcgCompiler::Compile(const MplOptions &options, std::unique_ptr theParser; - bool fileparsed = true; + bool fileread = true; if (theModule == nullptr) { MPLTimer timer; timer.Start(); - fileparsed = false; + fileread = false; theModule = std::make_unique(fileName); theModule->SetWithMe( std::find(options.GetRunningExes().begin(), options.GetRunningExes().end(), kBinNameMe) != options.GetRunningExes().end()); - theParser.reset(new MIRParser(*theModule)); - parsed = theParser->ParseMIR(0, cgOption.GetParserOption()); - if (parsed) { - if (!cgOption.IsQuiet() && theParser->GetWarning().size()) { - theParser->EmitWarning(fileName); + if (options.GetInputFileType() != kFileTypeBpl) { + std::unique_ptr theParser; + theParser.reset(new MIRParser(*theModule)); + bool parsed = theParser->ParseMIR(0, cgOption.GetParserOption()); + if (parsed) { + if (!cgOption.IsQuiet() && theParser->GetWarning().size()) { + theParser->EmitWarning(fileName); + } + } else { + if (theParser != nullptr) { + theParser->EmitError(fileName); + } + memPoolCtrler.DeleteMemPool(optMp); + return kErrorCompileFail; } } else { - if (theParser != nullptr) { - theParser->EmitError(fileName); + BinaryMplImport binMplt(*theModule); + binMplt.SetImported(false); + std::string modid = theModule->GetFileName(); + bool imported = binMplt.Import(modid, true); + if (!imported) { + memPoolCtrler.DeleteMemPool(optMp); + return kErrorCompileFail; } - memPoolCtrler.DeleteMemPool(optMp); - return kErrorCompileFail; } timer.Stop(); LogInfo::MapleLogger() << "Mplcg Parser consumed " << timer.ElapsedMilliseconds() << "ms\n"; @@ -137,8 +147,8 @@ ErrorCode MplcgCompiler::Compile(const MplOptions &options, std::unique_ptr *dumpFuncSet); void WriteNum(int64 x); void Write(uint8 b); - void OutputType(TyIdx tyIdx); + void OutputType(TyIdx tyIdx, bool canUseTypename); + void OutputTypeViaTypeName(TyIdx tidx) { OutputType(tidx, true); } + void WriteFunctionBodyField(uint64 contentIdx, std::unordered_set *dumpFuncSet); void OutputConst(MIRConst *c); void OutputConstBase(const MIRConst &c); void OutputTypeBase(const MIRType &type); @@ -125,17 +127,36 @@ class BinaryMplExport { void OutputClassTypeData(const MIRClassType &type); void OutputSymbol(const MIRSymbol *sym); void OutputFunction(PUIdx puIdx); - void OutWords(uint8 &typeTagged, int64 targetTag, uint16 size); void OutputInterfaceTypeData(const MIRInterfaceType &type); + void OutputSrcPos(const SrcPosition &pos); + void OutputAliasMap(MapleMap &aliasVarMap); + void OutputInfoVector(const MIRInfoVector &infovector, const MapleVector &infovector_isstring); + void OutputFuncIdInfo(MIRFunction *func); + void OutputLocalSymbol(MIRSymbol *sym); + void OutputLocalSymTab(const MIRFunction *func); + void OutputPregTab(const MIRFunction *func); + void OutputLabelTab(const MIRFunction *func); + void OutputLocalTypeNameTab(const MIRTypeNameTable *tnametab); + void OutputFormalsStIdx(MIRFunction *func); + void OutputFuncViaSymName(PUIdx puIdx); + void OutputExpression(BaseNode *e); + void OutputBaseNode(const BaseNode *b); + void OutputReturnValues(const CallReturnVector *retv); + void OutputBlockNode(BlockNode *block); + const MIRModule &GetMIRModule() const { return mod; } private: - void WriteContentField(int fieldNum, uint64 *fieldStartP); + void WriteContentField4mplt(int fieldNum, uint64 *fieldStartP); + void WriteContentField4nonmplt(int fieldNum, uint64 *fieldStartP); + void WriteContentField4nonJava(int fieldNum, uint64 *fieldStartP); void WriteStrField(uint64 contentIdx); - void WriteTypeField(uint64 contentIdx); + void WriteHeaderField(uint64 contentIdx); + void WriteTypeField(uint64 contentIdx, bool useClassList = true); void Init(); + void WriteSymField(uint64 contentIdx); void WriteInt(int32 x); uint8 Read(); int32 ReadInt(); @@ -156,6 +177,10 @@ class BinaryMplExport { std::unordered_map symMark; std::unordered_map typMark; static int typeMarkOffset; // offset of mark (tag in binmplimport) resulting from duplicated function + + public: + bool not2mplt; // this export is not to an mplt file + std::unordered_map callInfoMark; }; } // namespace maple diff --git a/src/mapleall/maple_ir/include/bin_mpl_import.h b/src/mapleall/maple_ir/include/bin_mpl_import.h index dbee4494cfe5fed8cbc5b6719436dc79c941a6a1..d3410e8637727748a35d1dd5a7e406871c804be3 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_import.h +++ b/src/mapleall/maple_ir/include/bin_mpl_import.h @@ -68,7 +68,10 @@ class BinaryMplImport { private: void ReadContentField(); void ReadStrField(); + void ReadHeaderField(); void ReadTypeField(); + void ReadSymField(); + void ReadSymTabField(); void Jump2NextField(); void Reset(); void SkipTotalSize(); @@ -88,7 +91,7 @@ class BinaryMplImport { TyIdx ImportType(bool forPointedType = false); void ImportTypeBase(PrimType &primType, GStrIdx &strIdx, bool &nameIsLocal); void InSymTypeTable(); - void ImportTypePairs(MIRInstantVectorType &insVecType); + void ImportTypePairs(std::vector &tpairs); TypeAttrs ImportTypeAttrs(); MIRPragmaElement *ImportPragmaElement(); MIRPragma *ImportPragma(); @@ -105,6 +108,25 @@ class BinaryMplImport { void ImportInterfaceTypeData(MIRInterfaceType &type); PUIdx ImportFunction(); MIRSymbol *InSymbol(MIRFunction *func); + + void ImportInfoVector(MIRInfoVector &infovector, MapleVector &infovector_isstring); + void ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab); + void ImportFuncIdInfo(MIRFunction *func); + void ImportLocalSymbol(MIRFunction *func); + void ImportLocalSymTab(MIRFunction *func); + void ImportPregTab(MIRFunction *func); + void ImportLabelTab(MIRFunction *func); + void ImportFormalsStIdx(MIRFunction *func); + void ImportAliasMap(MIRFunction *func); + void ImportSrcPos(SrcPosition &pos); + void ImportBaseNode(Opcode &o, PrimType &typ, uint8 &numopr); + PUIdx ImportFuncViaSymName(); + BaseNode *ImportExpression(MIRFunction *func); + + void ImportReturnValues(MIRFunction *func, CallReturnVector *retv); + BlockNode *ImportBlockNode(MIRFunction *fn); + void ReadFunctionBodyField(); + void ReadFileAt(const std::string &modid, int32 offset); uint8 Read(); int64 ReadInt64(); @@ -112,6 +134,7 @@ class BinaryMplImport { int32 GetIPAFileIndex(std::string &name); bool imported = true; // used only by irbuild to convert to ascii + bool importingFromMplt; // decided based on magic number uint64 bufI = 0; std::vector buf; std::map content; diff --git a/src/mapleall/maple_ir/include/bin_mplt.h b/src/mapleall/maple_ir/include/bin_mplt.h index fcc5230af56720e1b4423992a87f55652c11e57e..fbe2603baa9924e74d39b01e77c0f82fc752b8e4 100644 --- a/src/mapleall/maple_ir/include/bin_mplt.h +++ b/src/mapleall/maple_ir/include/bin_mplt.h @@ -29,8 +29,8 @@ class BinaryMplt { virtual ~BinaryMplt() = default; - void Export(const std::string &suffix) { - binExport.Export(suffix); + void Export(const std::string &suffix, std::unordered_set *dumpFuncSet = nullptr) { + binExport.Export(suffix, dumpFuncSet); } bool Import(const std::string &modID, bool readCG = false, bool readSE = false) { @@ -50,10 +50,14 @@ class BinaryMplt { return binExport; } - const std::string &GetImportFileName() const { + std::string &GetImportFileName() { return importFileName; } + void SetImportFileName(std::string fileName) { + importFileName = fileName; + } + private: MIRModule &mirModule; BinaryMplImport binImport; diff --git a/src/mapleall/maple_ir/include/global_tables.h b/src/mapleall/maple_ir/include/global_tables.h index da6a5dd9117cd4e61580bcb532d266b704a6a0c3..6e4b1db14fbfaeeae0695f6d3cfd6ed9566510d2 100644 --- a/src/mapleall/maple_ir/include/global_tables.h +++ b/src/mapleall/maple_ir/include/global_tables.h @@ -31,6 +31,8 @@ using TyIdxFieldAttrPair = std::pair; using FieldPair = std::pair; using FieldVector = std::vector; +class BinaryMplImport; + // to facilitate the use of unordered_map class TyIdxHash { public: @@ -80,6 +82,7 @@ class IntConstCmp { }; class TypeTable { + friend BinaryMplImport; public: static MIRType *voidPtrType; @@ -116,6 +119,8 @@ class TypeTable { void SetTypeWithTyIdx(const TyIdx &tyIdx, MIRType &type); + MIRType *GetOrCreateMIRTypeNode(MIRType &ptype); + TyIdx GetOrCreateMIRType(MIRType *pType) { return GetOrCreateMIRTypeNode(*pType)->GetTypeIndex(); } @@ -359,7 +364,6 @@ class TypeTable { } MIRType *CreateAndUpdateMirTypeNode(MIRType &pType); - MIRType *GetOrCreateMIRTypeNode(MIRType &ptype); MIRType *GetOrCreateStructOrUnion(const std::string &name, const FieldVector &fields, const FieldVector &printFields, MIRModule &module, bool forStruct = true); MIRType *GetOrCreateClassOrInterface(const std::string &name, MIRModule &module, bool forClass); @@ -371,6 +375,8 @@ class TypeTable { std::unordered_map ptrTypeMap; std::unordered_map refTypeMap; std::vector typeTable; + public: + TyIdx lastDefaultTyIdx; }; class StrPtrHash { diff --git a/src/mapleall/maple_ir/include/intrinsic_js_eng.def b/src/mapleall/maple_ir/include/intrinsic_js_eng.def index 5af255782944ce97d2492eb926769f16d84b90e3..dcfbc55947fd0ace4a4ed161e092eb1ff7ee5e9f 100644 --- a/src/mapleall/maple_ir/include/intrinsic_js_eng.def +++ b/src/mapleall/maple_ir/include/intrinsic_js_eng.def @@ -32,3 +32,10 @@ DEF_MIR_INTRINSIC(JS_GET_URIERROR_OBJECT,\ "__jsobj_get_or_create_uriError", INTRNISJS | INTRNISPURE, kArgTySimpleobj, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) DEF_MIR_INTRINSIC(JSOP_ASSERTVALUE, "__jsop_assert_value", INTRNISJS, kArgTyDynany, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) +DEF_MIR_INTRINSIC(JS_ISNAN,\ + "NULL", INTRNISJS | INTRNISPURE | INTRNNOSIDEEFFECT, kArgTyDynany, kArgTyDynany, kArgTyDynany, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) +DEF_MIR_INTRINSIC(JS_DATE,\ + "NULL", INTRNISJS | INTRNISPURE | INTRNNOSIDEEFFECT, kArgTyDynany, kArgTyDynany, kArgTyDynany, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) +DEF_MIR_INTRINSIC(JS_REGEXP,\ + "NULL", INTRNISJS | INTRNISPURE | INTRNNOSIDEEFFECT, kArgTyDynany, kArgTyDynany, kArgTyDynany, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) + diff --git a/src/mapleall/maple_ir/include/intrinsic_misc.def b/src/mapleall/maple_ir/include/intrinsic_misc.def new file mode 100644 index 0000000000000000000000000000000000000000..b3173cb6bcfb658f627e16e11c3b8f006d555f68 --- /dev/null +++ b/src/mapleall/maple_ir/include/intrinsic_misc.def @@ -0,0 +1,45 @@ +/* + * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. + * You can use this software according to the terms and conditions of the MulanPSL - 2.0. + * You may obtain a copy of MulanPSL - 2.0 at: + * + * https://opensource.org/licenses/MulanPSL-2.0 + * + * 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 MulanPSL - 2.0 for more details. + */ + +// DEF_MIR_INTRINSIC(STR, NAME, INTRN_CLASS, RETURN_TYPE, ARG0, ARG1, ARG2, ARG3, ARG4, ARG5) + +DEF_MIR_INTRINSIC(MCCCleanupLocalStackRefNaiveRCFast,\ + "MCC_CleanupLocalStackRef_NaiveRCFast", INTRNISRC | INTRNNOSIDEEFFECT, kArgTyVoid, kArgTyA64, kArgTyU64) +DEF_MIR_INTRINSIC(MCCCleanupLocalStackRefSkip,\ + "MCC_CleanupLocalStackRefSkip", INTRNISRC | INTRNNOSIDEEFFECT, kArgTyVoid, kArgTyA64, kArgTyU64, kArgTyU64) +DEF_MIR_INTRINSIC(MCCCleanupLocalStackRefSkipNaiveRCFast,\ + "MCC_CleanupLocalStackRefSkip_NaiveRCFast", INTRNISRC | INTRNNOSIDEEFFECT, kArgTyVoid, kArgTyA64, kArgTyU64, kArgTyU64) +DEF_MIR_INTRINSIC(MCCCleanupNonEscapedVar,\ + "MCC_CleanupNonescapedVar", INTRNISRC | INTRNNOSIDEEFFECT, kArgTyVoid, kArgTyRef) +DEF_MIR_INTRINSIC(MCCInitializeLocalStackRef,\ + "MCC_InitializeLocalStackRef", INTRNISRC | INTRNNOSIDEEFFECT, kArgTyVoid, kArgTyA64, kArgTyU64) +DEF_MIR_INTRINSIC(MCCReflectCheckArrayStore,\ + "MCC_Reflect_Check_Arraystore", INTRNISRC | INTRNNOSIDEEFFECT, kArgTyVoid, kArgTyRef, kArgTyRef) +DEF_MIR_INTRINSIC(MCCReflectThrowInstantiationError,\ + "MCC_Reflect_ThrowInstantiationError", INTRNISRC | INTRNNEVERRETURN, kArgTyRef) +DEF_MIR_INTRINSIC(MCCRethrowException,\ + "MCC_RethrowException", INTRNISRC | INTRNNEVERRETURN, kArgTyVoid, kArgTyRef) +DEF_MIR_INTRINSIC(MCCSetRiskyUnwindContext,\ + "MCC_SetRiskyUnwindContext", INTRNISRC | INTRNNEVERRETURN, kArgTyVoid, kArgTyU32, kArgTyA64) +DEF_MIR_INTRINSIC(MCCThrowException,\ + "MCC_ThrowException", INTRNISRC | INTRNNOSIDEEFFECT | INTRNNEVERRETURN, kArgTyVoid, kArgTyRef) +DEF_MIR_INTRINSIC(MCCThrowPendingException,\ + "MCC_ThrowPendingException", INTRNISRC | INTRNNOSIDEEFFECT | INTRNNEVERRETURN, kArgTyVoid) +DEF_MIR_INTRINSIC(MCCThrowArrayIndexOutOfBoundException,\ + "MCC_ThrowArrayIndexOutOfBoundsException", INTRNISRC | INTRNNOSIDEEFFECT | INTRNNEVERRETURN, kArgTyVoid) +DEF_MIR_INTRINSIC(MCCThrowNullPointerException,\ + "MCC_ThrowNullPointerException", INTRNISRC | INTRNNOSIDEEFFECT | INTRNNEVERRETURN, kArgTyVoid) +DEF_MIR_INTRINSIC(MCCCheckObjMem,\ + "MCC_CheckObjMem", INTRNISRC | INTRNNOSIDEEFFECT, kArgTyVoid, kArgTyA64) diff --git a/src/mapleall/maple_ir/include/intrinsics.def b/src/mapleall/maple_ir/include/intrinsics.def index fca1fae5c76a4e5a079b6aeeaaa641e7ab9c6c60..594d155cc37d64434397cd794ccf7331264342c4 100644 --- a/src/mapleall/maple_ir/include/intrinsics.def +++ b/src/mapleall/maple_ir/include/intrinsics.def @@ -134,6 +134,7 @@ DEF_MIR_INTRINSIC(MCCSaveProf,\ #include "intrinsic_java.def" #include "simplifyintrinsics.def" +#include "intrinsic_misc.def" #include "intrinsic_c.def" #include "intrinsic_js.def" #include "intrinsic_js_eng.def" diff --git a/src/mapleall/maple_ir/include/mir_const.h b/src/mapleall/maple_ir/include/mir_const.h index 29ff8b35db0ecbe744bf027e8ba139a17de607a3..50751a9789d890adb6a47c8a66fb9ea202cf0c04 100644 --- a/src/mapleall/maple_ir/include/mir_const.h +++ b/src/mapleall/maple_ir/include/mir_const.h @@ -51,7 +51,7 @@ class MIRConst { } void SetFieldID(uint32 fieldIdx) { - DoSetFieldID(fieldIdx); + fieldID = fieldIdx; } virtual bool IsZero() const { @@ -87,13 +87,13 @@ class MIRConst { return type; } + void SetType(MIRType &t) { + type = t; + } + private: MIRType &type; MIRConstKind kind; - virtual void DoSetFieldID(uint32 fieldIdx) { - CHECK_FATAL(kind != kConstInt, "must be"); - fieldID = fieldIdx; - } protected: uint32 fieldID; @@ -158,10 +158,6 @@ class MIRIntConst : public MIRConst { private: int64 value; - void DoSetFieldID(uint32 fieldIdx) override { - CHECK_FATAL(false, "Can't Use This Interface in This Object"); - (void)fieldIdx; - } }; class MIRAddrofConst : public MIRConst { diff --git a/src/mapleall/maple_ir/include/mir_function.h b/src/mapleall/maple_ir/include/mir_function.h index 21cd2509a8d4b2c0dc376a010970e21db247f15a..71b6e7b2bea028c4aad44f7210b80eef6b139486 100644 --- a/src/mapleall/maple_ir/include/mir_function.h +++ b/src/mapleall/maple_ir/include/mir_function.h @@ -442,8 +442,11 @@ class MIRFunction { symbolTableIdx = stIdx; } + MIRFuncType *GetFuncType() const { + return funcType; + } - MIRFuncType *GetMIRFuncType() { + MIRFuncType *GetMIRFuncType() const { return funcType; } void SetMIRFuncType(MIRFuncType *type) { @@ -458,6 +461,10 @@ class MIRFunction { inferredReturnTyIdx = tyIdx; } + MIRTypeNameTable *GetTypeNameTab() const { + return typeNameTab; + } + void AllocTypeNameTab() { if (typeNameTab == nullptr) { typeNameTab = module->GetMemPool()->New(module->GetMPAllocator()); @@ -555,6 +562,9 @@ class MIRFunction { const MIRInfoVector &GetInfoVector() const { return info; } + MIRInfoVector &GetInfoVector() { + return info; + } const MIRInfoPair &GetInfoPair(size_t i) const { return info.at(i); @@ -571,6 +581,11 @@ class MIRFunction { const MapleVector &InfoIsString() const { return infoIsString; } + + MapleVector &InfoIsString() { + return infoIsString; + } + void PushbackIsString(bool isString) { infoIsString.push_back(isString); } @@ -579,7 +594,7 @@ class MIRFunction { return aliasVarMap != nullptr; } - const MapleMap &GetAliasVarMap() { + MapleMap &GetAliasVarMap() { if (aliasVarMap == nullptr) { aliasVarMap = module->GetMemPool()->New>(module->GetMPAllocator().Adapter()); } @@ -731,7 +746,7 @@ class MIRFunction { MIRSymbol *GetSymbolTabItem(uint32 idx, bool checkFirst = false) const { return symTab->GetSymbolFromStIdx(idx, checkFirst); } - const MIRSymbolTable *GetSymTab() const { + MIRSymbolTable *GetSymTab() const { return symTab; } MIRSymbolTable *GetSymTab() { diff --git a/src/mapleall/maple_ir/include/mir_module.h b/src/mapleall/maple_ir/include/mir_module.h index 9ff7221bef0466f2b48aeb83a981aaaddd87f909..4ca256e5b95b3e4dcb4ab28d04f090f63a0f3d3d 100644 --- a/src/mapleall/maple_ir/include/mir_module.h +++ b/src/mapleall/maple_ir/include/mir_module.h @@ -168,7 +168,7 @@ class MIRModule { return compilationList; } - const MapleVector &GetImportedMplt() const { + MapleVector &GetImportedMplt() { return importedMplt; } void PushbackImportedMplt(const std::string &importFileName) { @@ -201,6 +201,10 @@ class MIRModule { return symbolSet; } + const MapleVector &GetSymbolDefOrder() const { + return symbolDefOrder; + } + Profile &GetProfile() { return profile; } @@ -226,14 +230,14 @@ class MIRModule { } void DumpGlobals(bool emitStructureType = true) const; - void Dump(bool emitStructureType = true) const; + void Dump(bool emitStructureType = true, std::unordered_set *dumpFuncSet = nullptr) const; void DumpToFile(const std::string &fileNameStr, bool emitStructureType = true) const; void DumpInlineCandidateToFile(const std::string &fileNameStr) const; const std::string &GetFileNameFromFileNum(uint32 fileNum) const; void DumpToHeaderFile(bool binaryMplt, const std::string &outputName = ""); void DumpClassToFile(const std::string &path) const; - void DumpFunctionList(bool skipBody = false) const; + void DumpFunctionList(const std::unordered_set *dumpFuncSet) const; void DumpGlobalArraySymbol() const; void Emit(const std::string &outFileName) const; uint32 GetAndIncFloatNum() { @@ -250,7 +254,9 @@ class MIRModule { MIRFunction *FindEntryFunction(); uint32 GetFileinfo(GStrIdx strIdx) const; - void OutputAsciiMpl(const std::string &phaseName, bool emitStructureType = true); + void OutputAsciiMpl(const char *phaseName, const char *suffix, + std::unordered_set *dumpFuncSet = nullptr, + bool emitStructureType = true, bool binaryform = false); void OutputFunctionListAsciiMpl(const std::string &phaseName); const std::string &GetFileName() const { return fileName; @@ -327,7 +333,7 @@ class MIRModule { return mirBuilder; } - const std::string &GetEntryFuncName() const { + std::string &GetEntryFuncName() { return entryFuncName; } void SetEntryFuncName(const std::string &entryFunctionName) { @@ -368,7 +374,7 @@ class MIRModule { inIPA = isInIPA; } - const MIRInfoVector &GetFileInfo() const { + MIRInfoVector &GetFileInfo() { return fileInfo; } void PushFileInfoPair(MIRInfoPair pair) { @@ -378,7 +384,7 @@ class MIRModule { fileInfo = fileInf; } - const MapleVector &GetFileInfoIsString() const { + MapleVector &GetFileInfoIsString() { return fileInfoIsString; } void SetFileInfoIsString(const MapleVector &fileInfoIsStr) { @@ -413,6 +419,10 @@ class MIRModule { srcLang = sourceLanguage; } + uint16 GetID() const { + return id; + } + void SetID(uint16 num) { id = num; } @@ -445,6 +455,10 @@ class MIRModule { globalWordsRefCounted = counted; } + uint32 GetNumFuncs() const { + return numFuncs; + } + void SetNumFuncs(uint32 numFunc) { numFuncs = numFunc; } diff --git a/src/mapleall/maple_ir/include/mir_nodes.h b/src/mapleall/maple_ir/include/mir_nodes.h index cba529ad39813693dd7f390688ec3fd2f37c8bbc..9172ce7338bcdba2224a590450f3979315228ef1 100644 --- a/src/mapleall/maple_ir/include/mir_nodes.h +++ b/src/mapleall/maple_ir/include/mir_nodes.h @@ -1565,10 +1565,14 @@ class TryNode : public StmtNode { public: explicit TryNode(MapleAllocator &allocator) : StmtNode(OP_try), offsets(allocator.Adapter()) {} + explicit TryNode(MapleAllocator &allocator, Opcode o) : StmtNode(o), offsets(allocator.Adapter()) {} + explicit TryNode(const MapleVector &offsets) : StmtNode(OP_try), offsets(offsets) {} explicit TryNode(const MIRModule &mod) : TryNode(mod.GetCurFuncCodeMPAllocator()) {} + explicit TryNode(const MIRModule &mod, Opcode o) : TryNode(mod.GetCurFuncCodeMPAllocator(), o) {} + TryNode(TryNode &node) = delete; TryNode &operator=(const TryNode &node) = delete; virtual ~TryNode() = default; @@ -1576,6 +1580,10 @@ class TryNode : public StmtNode { void Dump(int32 indent) const override; void Dump() const; + MapleVector &GetOffsets() { + return offsets; + } + LabelIdx GetOffset(size_t i) const { ASSERT(i < offsets.size(), "array index out of range"); return offsets.at(i); @@ -1773,6 +1781,10 @@ class SwitchNode : public StmtNode { defaultLabel = idx; } + CaseVector &GetSwitchTable() { + return switchTable; + } + const CaseVector &GetSwitchTable() const { return switchTable; } diff --git a/src/mapleall/maple_ir/include/mir_parser.h b/src/mapleall/maple_ir/include/mir_parser.h index b244a02c9bccf4694777d3f55868535f9c9c2012..d11c2c25398c2afedf9db4f47dc9fee3197bbf95 100644 --- a/src/mapleall/maple_ir/include/mir_parser.h +++ b/src/mapleall/maple_ir/include/mir_parser.h @@ -184,6 +184,7 @@ class MIRParser { bool ParseIntrinsicId(IntrinsicopNode&); void Error(const std::string&); void Warning(const std::string&); + void FixForwardReferencedTypeForOneAgg(MIRType *ty); void FixupForwardReferencedTypeByMap(); const std::string &GetError(); diff --git a/src/mapleall/maple_ir/include/mir_symbol.h b/src/mapleall/maple_ir/include/mir_symbol.h index a43666031dc335f4605598796ca6b6a3f381d175..bce413e0457137c6125f69a0ad4961905f05834c 100644 --- a/src/mapleall/maple_ir/include/mir_symbol.h +++ b/src/mapleall/maple_ir/include/mir_symbol.h @@ -307,6 +307,10 @@ class MIRSymbol { this->value = value; } + const SrcPosition &GetSrcPosition() const { + return srcPosition; + } + SrcPosition &GetSrcPosition() { return srcPosition; } @@ -477,6 +481,10 @@ class MIRSymbolTable { return st; } + void PushNullSymbol() { + symbolTable.push_back(nullptr); + } + // add sym from other symbol table, happens in inline bool AddStOutside(MIRSymbol *sym) { if (sym == nullptr) { @@ -586,7 +594,7 @@ class MIRLabelTable { labelTable[idx] = strIdx; } - MapleVector GetLabelTable() { + MapleVector GetLabelTable() const { return labelTable; } @@ -602,6 +610,7 @@ class MIRLabelTable { MapleAllocator mAllocator; MapleMap strIdxToLabIdxMap; MapleVector labelTable; // map label idx to label name + public: MapleUnorderedSet addrTakenLabels; // those appeared in addroflabel or MIRLblConst }; } // namespace maple diff --git a/src/mapleall/maple_ir/include/mir_type.h b/src/mapleall/maple_ir/include/mir_type.h index dad4cf9fcd1fac296d23989f8c51ccbf5722078b..b2e95dd9ea4774991e50ab59e9c65384878dab7a 100755 --- a/src/mapleall/maple_ir/include/mir_type.h +++ b/src/mapleall/maple_ir/include/mir_type.h @@ -631,6 +631,18 @@ class MIRArrayType : public MIRType { this->dim = dim; } + TypeAttrs GetTypeAttrs() const { + return typeAttrs; + } + + TypeAttrs& GetTypeAttrs() { + return typeAttrs; + } + + void SetTypeAttrs(TypeAttrs attrs) { + typeAttrs = attrs; + } + MIRType *GetElemType() const; MIRType *CopyMIRTypeNode() const override { @@ -845,6 +857,14 @@ class MIRStructType : public MIRType { isUsed = flag; } + bool IsCPlusPlus() const { + return isCPlusPlus; + } + + void SetIsCPlusPlus(bool flag) { + isCPlusPlus = flag; + } + GStrIdx GetFieldGStrIdx(FieldID id) const { const FieldPair &fieldPair = TraverseToField(id); return fieldPair.first; @@ -1633,6 +1653,10 @@ class MIRInstantVectorType : public MIRType { return instantVec; } + GenericInstantVector &GetInstantVec() { + return instantVec; + } + void AddInstant(TypePair typePair) { instantVec.push_back(typePair); } diff --git a/src/mapleall/maple_ir/include/opcodes.def b/src/mapleall/maple_ir/include/opcodes.def index 9ae6410bbd7fdb77255c9629ea987230649444b1..1b10eea485ddc3600fc5a61d885c7a9734f36320 100644 --- a/src/mapleall/maple_ir/include/opcodes.def +++ b/src/mapleall/maple_ir/include/opcodes.def @@ -15,7 +15,6 @@ // Stmt & Notmmpl // storage access opcodes OPCODE(dassign, DassignNode, (OPCODEISSTMT | OPCODENOTMMPL | OPCODEHASSSADEF), 8) - OPCODE(piassign, PiassignNode, (OPCODEISSTMT | OPCODENOTMMPL | OPCODEHASSSADEF), 8) OPCODE(maydassign, DassignNode, (OPCODEISSTMT | OPCODENOTMMPL | OPCODEHASSSADEF), 8) OPCODE(iassign, IassignNode, (OPCODEISSTMT | OPCODENOTMMPL | OPCODEHASSSADEF), 12) // hierarchical control flow opcodes @@ -42,7 +41,6 @@ OPCODE(addrof, AddrofNode, OPCODENOTMMPL, 12) OPCODE(iaddrof, IreadNode, OPCODENOTMMPL, 12) OPCODE(sizeoftype, SizeoftypeNode, OPCODENOTMMPL, 8) - OPCODE(fieldsdist, FieldsDistNode, OPCODENOTMMPL, 8) // N-ary expression opcodes OPCODE(array, ArrayNode, (OPCODEISVARSIZE | OPCODENOTMMPL | OPCODEMAYTHROWEXCEPTION), 8) // Stmt @@ -91,14 +89,15 @@ OPCODE(interfacecallinstant, CallinstantNode, (OPCODEISSTMT | OPCODEISVARSIZE | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALL), 0) OPCODE(interfacecallinstantassigned, CallinstantNode, (OPCODEISSTMT | OPCODEISVARSIZE | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALL | OPCODEISCALLASSIGNED), 0) // exception handling - OPCODE(jstry, JsTryNode, OPCODEISSTMT, 8) OPCODE(try, TryNode, (OPCODEISSTMT | OPCODENOTMMPL), 8) + OPCODE(jstry, JsTryNode, OPCODEISSTMT, 8) + OPCODE(javatry, TryNode, (OPCODEISSTMT | OPCODENOTMMPL), 8) OPCODE(cpptry, TryNode, (OPCODEISSTMT | OPCODENOTMMPL), 8) OPCODE(throw, UnaryStmtNode, (OPCODEISSTMT | OPCODEHASSSAUSE), 0) - - OPCODE(jscatch, StmtNode, OPCODEISSTMT, 4) OPCODE(catch, CatchNode, OPCODEISSTMT, 8) + OPCODE(jscatch, StmtNode, OPCODEISSTMT, 4) + OPCODE(javacatch, CatchNode, OPCODEISSTMT, 8) OPCODE(cppcatch, CppCatchNode, OPCODEISSTMT, 8) OPCODE(finally, StmtNode, OPCODEISSTMT, 6) @@ -192,6 +191,7 @@ // Other expression opcodes OPCODE(extractbits, ExtractbitsNode, 0, 8) OPCODE(depositbits, DepositbitsNode, 0, 8) + OPCODE(fieldsdist, FieldsDistNode, OPCODENOTMMPL, 8) // storage access OPCODE(iassignpcoff, IassignPCoffNode, OPCODEISSTMT, 0) OPCODE(ireadpcoff, IreadPCoffNode, 0, 0) @@ -200,3 +200,4 @@ // leaf node OPCODE(addroffpc, AddroffPCNode, 0, 0) OPCODE(igoto, UnaryStmtNode, OPCODEISSTMT, 0) + OPCODE(piassign, PiassignNode, (OPCODEISSTMT | OPCODENOTMMPL | OPCODEHASSSADEF), 8) diff --git a/src/mapleall/maple_ir/include/prim_types.def b/src/mapleall/maple_ir/include/prim_types.def index 886b32f2378d2758f02e4221d9feb2d5bbd407bb..5ef8ea3d6509df710f73d4324b743b90b13e81f9 100644 --- a/src/mapleall/maple_ir/include/prim_types.def +++ b/src/mapleall/maple_ir/include/prim_types.def @@ -52,6 +52,12 @@ PRIMTYPE(gen) PRIMTYPE(agg) PRIMTYPE(unknown) + PRIMTYPE(v2i64) + PRIMTYPE(v4i32) + PRIMTYPE(v8i16) + PRIMTYPE(v16i8) + PRIMTYPE(v2f64) + PRIMTYPE(v4f32) #endif // ~LOAD_ALGO_PRIMARY_TYPE @@ -104,8 +110,8 @@ static const PrimitiveTypeProperty PTProperty_u32 = { }; static const PrimitiveTypeProperty PTProperty_u64 = { - /*type=*/PTY_u64, /*isInteger=*/true, /*isUnsigned=*/true, /*isAddress=*/false, /*isFloat=*/false, - /*isPointer=*/false, /*isSimple=*/false, /*isDynamic=*/false, /*isDynamicAny=*/false, /*isDynamicNone=*/false + /*type=*/PTY_u64, /*isInteger=*/true, /*isUnsigned=*/true, /*isAddress=*/true, /*isFloat=*/false, + /*isPointer=*/true, /*isSimple=*/false, /*isDynamic=*/false, /*isDynamicAny=*/false, /*isDynamicNone=*/false }; static const PrimitiveTypeProperty PTProperty_u1 = { @@ -240,6 +246,36 @@ static const PrimitiveTypeProperty PTProperty_unknown = { /*isPointer=*/false, /*isSimple=*/false, /*isDynamic=*/false, /*isDynamicAny=*/false, /*isDynamicNone=*/false }; +static const PrimitiveTypeProperty PTProperty_v2i64 = { + /*type=*/PTY_v2i64, /*isInteger=*/true, /*isUnsigned=*/false, /*isAddress=*/false, /*isFloat=*/false, + /*isPointer=*/false, /*isSimple=*/false, /*isDynamic=*/false, /*isDynamicAny=*/false, /*isDynamicNone=*/false +}; + +static const PrimitiveTypeProperty PTProperty_v4i32 = { + /*type=*/PTY_v4i32, /*isInteger=*/true, /*isUnsigned=*/false, /*isAddress=*/false, /*isFloat=*/false, + /*isPointer=*/false, /*isSimple=*/false, /*isDynamic=*/false, /*isDynamicAny=*/false, /*isDynamicNone=*/false +}; + +static const PrimitiveTypeProperty PTProperty_v8i16 = { + /*type=*/PTY_v8i16, /*isInteger=*/true, /*isUnsigned=*/false, /*isAddress=*/false, /*isFloat=*/false, + /*isPointer=*/false, /*isSimple=*/false, /*isDynamic=*/false, /*isDynamicAny=*/false, /*isDynamicNone=*/false +}; + +static const PrimitiveTypeProperty PTProperty_v16i8 = { + /*type=*/PTY_v16i8, /*isInteger=*/true, /*isUnsigned=*/false, /*isAddress=*/false, /*isFloat=*/false, + /*isPointer=*/false, /*isSimple=*/false, /*isDynamic=*/false, /*isDynamicAny=*/false, /*isDynamicNone=*/false +}; + +static const PrimitiveTypeProperty PTProperty_v2f64 = { + /*type=*/PTY_v2f64, /*isInteger=*/false, /*isUnsigned=*/false, /*isAddress=*/false, /*isFloat=*/true, + /*isPointer=*/false, /*isSimple=*/false, /*isDynamic=*/false, /*isDynamicAny=*/false, /*isDynamicNone=*/false +}; + +static const PrimitiveTypeProperty PTProperty_v4f32 = { + /*type=*/PTY_v4f32, /*isInteger=*/false, /*isUnsigned=*/false, /*isAddress=*/false, /*isFloat=*/true, + /*isPointer=*/false, /*isSimple=*/false, /*isDynamic=*/false, /*isDynamicAny=*/false, /*isDynamicNone=*/false +}; + static const PrimitiveTypeProperty PTProperty_end = { /*type=*/PTY_end, /*isInteger=*/false, /*isUnsigned=*/false, /*isAddress=*/false, /*isFloat=*/false, /*isPointer=*/false, /*isSimple=*/false, /*isDynamic=*/false, /*isDynamicAny=*/false, /*isDynamicNone=*/false diff --git a/src/mapleall/maple_ir/include/types_def.h b/src/mapleall/maple_ir/include/types_def.h index af8bcaf1f771634c8814403d0b7b059adacdb2e9..f5b1ddc2cd86835e9192a91cfb01e82d93987efd 100644 --- a/src/mapleall/maple_ir/include/types_def.h +++ b/src/mapleall/maple_ir/include/types_def.h @@ -52,6 +52,10 @@ class StIdx { // scope nesting level + symbol table index u.scopeIdx.idx = i; } + StIdx(uint32 fidx) { + u.fullIdx = fidx; + } + ~StIdx() = default; uint32 Idx() const { @@ -66,6 +70,10 @@ class StIdx { // scope nesting level + symbol table index return u.scopeIdx.scope; } + void SetScope(uint32 scpe) { + u.scopeIdx.scope = scpe; + } + uint32 FullIdx() const { return u.fullIdx; } diff --git a/src/mapleall/maple_ir/src/bin_func_export.cpp b/src/mapleall/maple_ir/src/bin_func_export.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d4531c848bc585ee6f63ed94e1efb33997ff9297 --- /dev/null +++ b/src/mapleall/maple_ir/src/bin_func_export.cpp @@ -0,0 +1,656 @@ +/* + * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. + * You can use this software according to the terms and conditions of the MulanPSL - 2.0. + * You may obtain a copy of MulanPSL - 2.0 at: + * + * https://opensource.org/licenses/MulanPSL-2.0 + * + * 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 MulanPSL - 2.0 for more details. + */ + + +#include "mir_function.h" +#include "opcode_info.h" +#include "mir_pragma.h" +#include "mir_builder.h" +#include "bin_mplt.h" + +#include +#include + +using namespace std; +namespace maple { + +void BinaryMplExport::OutputInfoVector(const MIRInfoVector &infovector, const MapleVector &infovector_isstring) { + WriteNum(infovector.size()); + for (uint32 i = 0; i < infovector.size(); i++) { + OutputStr(infovector[i].first); + WriteNum(infovector_isstring[i]); + if (!infovector_isstring[i]) { + WriteNum(infovector[i].second); + } else { + OutputStr(GStrIdx(infovector[i].second)); + } + } +} + +void BinaryMplExport::OutputFuncIdInfo(MIRFunction *func) { + WriteNum(kBinFuncIdInfoStart); + WriteNum(func->GetPuidxOrigin()); // the funcid + OutputInfoVector(func->GetInfoVector(), func->InfoIsString()); + WriteNum(~kBinFuncIdInfoStart); +} + +void BinaryMplExport::OutputBaseNode(const BaseNode *b) { + WriteNum(b->GetOpCode()); + WriteNum(b->GetPrimType()); + WriteNum(b->GetNumOpnds()); +} + +void BinaryMplExport::OutputLocalSymbol(MIRSymbol *sym) { + if (sym == nullptr) { + WriteNum(0); + return; + } + WriteNum(kBinSymbol); + WriteNum(sym->GetStIndex()); // preserve original st index + OutputStr(sym->GetNameStrIdx()); + WriteNum(sym->GetSKind()); + WriteNum(sym->GetStorageClass()); + OutputTypeAttrs(sym->GetAttrs()); + WriteNum(sym->GetIsTmp()); + if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) { + OutputSrcPos(sym->GetSrcPosition()); + } + OutputTypeViaTypeName(sym->GetTyIdx()); + if (sym->GetSKind() == kStPreg) { + WriteNum(sym->GetPreg()->GetPregNo()); + } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) { + OutputConst(sym->GetKonst()); + } else if (sym->GetSKind() == kStFunc) { + OutputFuncViaSymName(sym->GetFunction()->GetPuidx()); + OutputTypeViaTypeName(sym->GetTyIdx()); + } else { + CHECK_FATAL(false, "should not used"); + } +} + +void BinaryMplExport::OutputLocalSymTab(const MIRFunction *func) { + WriteNum(kBinSymStart); + uint64 outsymSizeIdx = buf.size(); + ExpandFourBuffSize(); /// size of OutSym + int32 size = 0; + + for (uint32 i = 1; i < func->GetSymTab()->GetSymbolTableSize(); i++) { + MIRSymbol *s = func->GetSymTab()->GetSymbolFromStIdx(i); + if (s->IsDeleted()) { + s = nullptr; + } + OutputLocalSymbol(s); + size++; + } + + Fixup(outsymSizeIdx, size); + WriteNum(~kBinSymStart); +} + +void BinaryMplExport::OutputPregTab(const MIRFunction *func) { + WriteNum(kBinPregStart); + uint64 outRegSizeIdx = buf.size(); + ExpandFourBuffSize(); /// size of OutReg + int32 size = 0; + + for (uint32 i = 1; i < func->GetPregTab()->Size(); i++) { + MIRPreg *mirpreg = func->GetPregTab()->PregFromPregIdx(i); + if (mirpreg == nullptr) { + WriteNum(0); + continue; + } + WriteNum(kBinPreg); + WriteNum(mirpreg->GetPregNo()); + TyIdx tyIdx = (mirpreg->GetMIRType() == nullptr) ? TyIdx(0) : mirpreg->GetMIRType()->GetTypeIndex(); + OutputTypeViaTypeName(tyIdx); + WriteNum(mirpreg->GetPrimType()); + size++; + } + + Fixup(outRegSizeIdx, size); + WriteNum(~kBinPregStart); +} + +void BinaryMplExport::OutputLabelTab(const MIRFunction *func) { + WriteNum(kBinLabelStart); + WriteNum(func->GetLabelTab()->Size()-1); // entry 0 is skipped + for (uint32 i = 1; i < func->GetLabelTab()->Size(); i++) { + OutputStr(func->GetLabelTab()->GetLabelTable()[i]); + } + WriteNum(~kBinLabelStart); +} + +void BinaryMplExport::OutputLocalTypeNameTab(const MIRTypeNameTable *tnametab) { + WriteNum(kBinTypenameStart); + WriteNum(tnametab->Size()); + for (std::pair it : tnametab->GetGStrIdxToTyIdxMap()) { + OutputStr(it.first); + OutputTypeViaTypeName(it.second); + } + WriteNum(~kBinTypenameStart); +} + +void BinaryMplExport::OutputFormalsStIdx(MIRFunction *func) { + WriteNum(kBinFormalStart); + WriteNum(func->GetFormalDefVec().size()); + for (FormalDef formalDef : func->GetFormalDefVec()) { + WriteNum(formalDef.formalSym->GetStIndex()); + } + WriteNum(~kBinFormalStart); +} + +void BinaryMplExport::OutputAliasMap(MapleMap &aliasVarMap) { + WriteNum(kBinAliasMapStart); + WriteInt(aliasVarMap.size()); + for (std::pair it : aliasVarMap) { + OutputStr(it.first); + OutputStr(it.second.memPoolStrIdx); + OutputTypeViaTypeName(it.second.tyIdx); + OutputStr(it.second.sigStrIdx); + } + WriteNum(~kBinAliasMapStart); +} + +void BinaryMplExport::OutputFuncViaSymName(PUIdx puIdx) { + MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); + MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); + WriteNum(kBinKindFuncViaSymname); + OutputStr(funcSt->GetNameStrIdx()); +} + +void BinaryMplExport::OutputExpression(BaseNode *e) { + WriteNum(kBinOpExpression); + OutputBaseNode(e); + switch (e->GetOpCode()) { + // leaf + case OP_constval: { + MIRConst *constVal = static_cast(e)->GetConstVal(); + OutputConst(constVal); + return; + } + case OP_conststr: { + UStrIdx strIdx = static_cast(e)->GetStrIdx(); + OutputUsrStr(strIdx); + return; + } + case OP_addroflabel: { + AddroflabelNode *lNode = static_cast(e); + WriteNum(lNode->GetOffset()); + return; + } + case OP_addroffunc: { + AddroffuncNode *addrNode = static_cast(e); + OutputFuncViaSymName(addrNode->GetPUIdx()); + return; + } + case OP_sizeoftype: { + SizeoftypeNode *sot = static_cast(e); + OutputTypeViaTypeName(sot->GetTyIdx()); + return; + } + case OP_addrof: + case OP_dread: { + AddrofNode *drNode = static_cast(e); + WriteNum(drNode->GetFieldID()); + WriteNum(drNode->GetStIdx().Scope()); + if (drNode->GetStIdx().Islocal()) { + WriteNum(drNode->GetStIdx().Idx()); // preserve original st index + } else { + MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(drNode->GetStIdx().Idx()); + WriteNum(kBinKindSymViaSymname); + OutputStr(sym->GetNameStrIdx()); + } + return; + } + case OP_regread: { + RegreadNode *regreadNode = static_cast(e); + WriteNum(regreadNode->GetRegIdx()); + return; + } + case OP_gcmalloc: + case OP_gcpermalloc: + case OP_stackmalloc: { + GCMallocNode *gcNode = static_cast(e); + OutputTypeViaTypeName(gcNode->GetTyIdx()); + return; + } + // unary + case OP_ceil: + case OP_cvt: + case OP_floor: + case OP_trunc: { + TypeCvtNode *typecvtNode = static_cast(e); + WriteNum(typecvtNode->FromType()); + break; + } + case OP_retype: { + RetypeNode *retypeNode = static_cast(e); + OutputTypeViaTypeName(retypeNode->GetTyIdx()); + break; + } + case OP_iread: + case OP_iaddrof: { + IreadNode *irNode = static_cast(e); + OutputTypeViaTypeName(irNode->GetTyIdx()); + WriteNum(irNode->GetFieldID()); + break; + } + case OP_sext: + case OP_zext: + case OP_extractbits: { + ExtractbitsNode *extNode = static_cast(e); + WriteNum(extNode->GetBitsOffset()); + WriteNum(extNode->GetBitsSize()); + break; + } + case OP_gcmallocjarray: + case OP_gcpermallocjarray: { + JarrayMallocNode *gcNode = static_cast(e); + OutputTypeViaTypeName(gcNode->GetTyIdx()); + break; + } + // binary + case OP_sub: + case OP_mul: + case OP_div: + case OP_rem: + case OP_ashr: + case OP_lshr: + case OP_shl: + case OP_max: + case OP_min: + case OP_band: + case OP_bior: + case OP_bxor: + case OP_cand: + case OP_cior: + case OP_land: + case OP_lior: + case OP_add: { + break; + } + case OP_eq: + case OP_ne: + case OP_lt: + case OP_gt: + case OP_le: + case OP_ge: + case OP_cmpg: + case OP_cmpl: + case OP_cmp: { + CompareNode *cmpNode = static_cast(e); + WriteNum(cmpNode->GetOpndType()); + break; + } + case OP_resolveinterfacefunc: + case OP_resolvevirtualfunc: { + ResolveFuncNode *rsNode = static_cast(e); + OutputFuncViaSymName(rsNode->GetPuIdx()); + break; + } + // ternary + case OP_select: { + break; + } + // nary + case OP_array: { + ArrayNode *arrNode = static_cast(e); + OutputTypeViaTypeName(arrNode->GetTyIdx()); + WriteNum(arrNode->GetBoundsCheck()); + WriteNum(arrNode->NumOpnds()); + break; + } + case OP_intrinsicop: { + IntrinsicopNode *intrnNode = static_cast(e); + WriteNum(intrnNode->GetIntrinsic()); + WriteNum(intrnNode->NumOpnds()); + break; + } + case OP_intrinsicopwithtype: { + IntrinsicopNode *intrnNode = static_cast(e); + WriteNum(intrnNode->GetIntrinsic()); + OutputTypeViaTypeName(intrnNode->GetTyIdx()); + WriteNum(intrnNode->NumOpnds()); + break; + } + default: + break; + } + for (int32 i = 0; i < e->NumOpnds(); i++) { + OutputExpression(e->Opnd(i)); + } +} + +static SrcPosition lastOutputSrcPosition; + +void BinaryMplExport::OutputSrcPos(const SrcPosition &pos) { + if (pos.FileNum() == 0 || pos.LineNum() == 0) { // error case, so output 0 + WriteNum(lastOutputSrcPosition.RawData()); + WriteNum(lastOutputSrcPosition.LineNum()); + return; + } + WriteNum(pos.RawData()); + WriteNum(pos.LineNum()); + lastOutputSrcPosition = pos; +} + +void BinaryMplExport::OutputReturnValues(const CallReturnVector *retv) { + WriteNum(kBinReturnvals); + WriteNum(retv->size()); + for (uint32 i = 0; i < retv->size(); i++) { + WriteNum((*retv)[i].first.Idx()); + WriteNum((*retv)[i].second.GetFieldID()); + WriteNum((*retv)[i].second.GetPregIdx()); + } +} + +void BinaryMplExport::OutputBlockNode(BlockNode *block) { + WriteNum(kBinNodeBlock); + if (!block->GetStmtNodes().empty()) { + OutputSrcPos(block->GetSrcPos()); + } else { + OutputSrcPos(SrcPosition()); // output 0 + } + int32 num = 0; + uint64 idx = buf.size(); + ExpandFourBuffSize(); // place holder, Fixup later + for (StmtNode *s = block->GetFirst(); s; s = s->GetNext()) { + bool doneWithOpnds = false; + WriteNum(kBinOpStatement); + OutputSrcPos(s->GetSrcPos()); + WriteNum(s->GetOpCode()); + switch (s->GetOpCode()) { + case OP_dassign: { + DassignNode *dass = static_cast(s); + WriteNum(dass->GetFieldID()); + WriteNum(dass->GetStIdx().Scope()); + if (dass->GetStIdx().Islocal()) { + WriteNum(dass->GetStIdx().Idx()); // preserve original st index + } else { + MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(dass->GetStIdx().Idx()); + WriteNum(kBinKindSymViaSymname); + OutputStr(sym->GetNameStrIdx()); + } + break; + } + case OP_regassign: { + RegassignNode *rass = static_cast(s); + WriteNum(rass->GetPrimType()); + WriteNum(rass->GetRegIdx()); + break; + } + case OP_iassign: { + IassignNode *iass = static_cast(s); + OutputTypeViaTypeName(iass->GetTyIdx()); + WriteNum(iass->GetFieldID()); + break; + } + case OP_call: + case OP_virtualcall: + case OP_virtualicall: + case OP_superclasscall: + case OP_interfacecall: + case OP_interfaceicall: + case OP_customcall: + case OP_polymorphiccall: { + CallNode *callnode = static_cast(s); + OutputFuncViaSymName(callnode->GetPUIdx()); + if (s->GetOpCode() == OP_polymorphiccall) { + OutputTypeViaTypeName(static_cast(callnode)->GetTyIdx()); + } + WriteNum(s->NumOpnds()); + break; + } + case OP_callassigned: + case OP_virtualcallassigned: + case OP_virtualicallassigned: + case OP_superclasscallassigned: + case OP_interfacecallassigned: + case OP_interfaceicallassigned: + case OP_customcallassigned: { + CallNode *callnode = static_cast(s); + OutputFuncViaSymName(callnode->GetPUIdx()); + OutputReturnValues(&callnode->GetReturnVec()); + WriteNum(s->NumOpnds()); + break; + } + case OP_polymorphiccallassigned: { + CallNode *callnode = static_cast(s); + OutputFuncViaSymName(callnode->GetPUIdx()); + OutputTypeViaTypeName(callnode->GetTyIdx()); + OutputReturnValues(&callnode->GetReturnVec()); + WriteNum(s->NumOpnds()); + break; + } + case OP_icall: { + IcallNode *icallnode = static_cast(s); + OutputTypeViaTypeName(icallnode->GetRetTyIdx()); + WriteNum(s->NumOpnds()); + break; + } + case OP_icallassigned: { + IcallNode *icallnode = static_cast(s); + OutputTypeViaTypeName(icallnode->GetRetTyIdx()); + OutputReturnValues(&icallnode->GetReturnVec()); + WriteNum(s->NumOpnds()); + break; + } + case OP_intrinsiccall: + case OP_xintrinsiccall: { + IntrinsiccallNode *intrnNode = static_cast(s); + WriteNum(intrnNode->GetIntrinsic()); + WriteNum(s->NumOpnds()); + break; + } + case OP_intrinsiccallassigned: + case OP_xintrinsiccallassigned: { + IntrinsiccallNode *intrnNode = static_cast(s); + WriteNum(intrnNode->GetIntrinsic()); + OutputReturnValues(&intrnNode->GetReturnVec()); + WriteNum(s->NumOpnds()); + break; + } + case OP_intrinsiccallwithtype: { + IntrinsiccallNode *intrnNode = static_cast(s); + WriteNum(intrnNode->GetIntrinsic()); + OutputTypeViaTypeName(intrnNode->GetTyIdx()); + WriteNum(s->NumOpnds()); + break; + } + case OP_intrinsiccallwithtypeassigned: { + IntrinsiccallNode *intrnNode = static_cast(s); + WriteNum(intrnNode->GetIntrinsic()); + OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputReturnValues(&intrnNode->GetReturnVec()); + WriteNum(s->NumOpnds()); + break; + } + case OP_syncenter: + case OP_syncexit: + case OP_return: { + WriteNum(s->NumOpnds()); + break; + } + case OP_jscatch: + case OP_cppcatch: + case OP_finally: + case OP_endtry: + case OP_cleanuptry: + case OP_retsub: + case OP_membaracquire: + case OP_membarrelease: + case OP_membarstorestore: + case OP_membarstoreload: { + break; + } + case OP_eval: + case OP_throw: + case OP_free: + case OP_decref: + case OP_incref: + case OP_decrefreset: + case OP_assertnonnull: + case OP_igoto: { + break; + } + case OP_label: { + LabelNode *lNode = static_cast(s); + WriteNum(lNode->GetLabelIdx()); + break; + } + case OP_goto: + case OP_gosub: { + GotoNode *gtoNode = static_cast(s); + WriteNum(gtoNode->GetOffset()); + break; + } + case OP_brfalse: + case OP_brtrue: { + CondGotoNode *cgotoNode = static_cast(s); + WriteNum(cgotoNode->GetOffset()); + break; + } + case OP_switch: { + SwitchNode *swNode = static_cast(s); + WriteNum(swNode->GetDefaultLabel()); + WriteNum(swNode->GetSwitchTable().size()); + for (CasePair cpair : swNode->GetSwitchTable()) { + WriteNum(cpair.first); + WriteNum(cpair.second); + } + break; + } + case OP_jstry: { + JsTryNode *tryNode = static_cast(s); + WriteNum(tryNode->GetCatchOffset()); + WriteNum(tryNode->GetFinallyOffset()); + break; + } + case OP_cpptry: + case OP_try: { + TryNode *tryNode = static_cast(s); + WriteNum(tryNode->GetOffsetsCount()); + for (LabelIdx lidx : tryNode->GetOffsets()) { + WriteNum(lidx); + } + break; + } + case OP_catch: { + CatchNode *catchNode = static_cast(s); + WriteNum(catchNode->GetExceptionTyIdxVec().size()); + for (TyIdx tidx : catchNode->GetExceptionTyIdxVec()) { + OutputTypeViaTypeName(tidx); + } + break; + } + case OP_comment: { + string str(static_cast(s)->GetComment().c_str()); + WriteAsciiStr(str); + break; + } + case OP_dowhile: + case OP_while: { + WhileStmtNode *whileNode = static_cast(s); + OutputBlockNode(whileNode->GetBody()); + OutputExpression(whileNode->Opnd()); + doneWithOpnds = true; + break; + } + case OP_if: { + IfStmtNode *ifNode = static_cast(s); + bool hasElsePart = ifNode->GetElsePart() != nullptr; + WriteNum(hasElsePart); + OutputBlockNode(ifNode->GetThenPart()); + if (hasElsePart) { + OutputBlockNode(ifNode->GetElsePart()); + } + OutputExpression(ifNode->Opnd()); + doneWithOpnds = true; + break; + } + case OP_block: { + BlockNode *blockNode = static_cast(s); + OutputBlockNode(blockNode); + doneWithOpnds = true; + break; + } + default: + CHECK_FATAL(false, "Unhandled opcode %d", s->GetOpCode()); + break; + } + num++; + if (!doneWithOpnds) { + for (int32 i = 0; i < s->NumOpnds(); i++) { + OutputExpression(s->Opnd(i)); + } + } + } + Fixup(idx, num); +} + +void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_set *dumpFuncSet) { + Fixup(contentIdx, buf.size()); + // LogInfo::MapleLogger() << "Write FunctionBody Field " << std::endl; + WriteNum(kBinFunctionBodyStart); + uint64 totalSizeIdx = buf.size(); + ExpandFourBuffSize(); /// total size of this field to ~BIN_FUNCTIONBODY_START + uint64 outFunctionBodySizeIdx = buf.size(); + ExpandFourBuffSize(); /// size of outFunctionBody + int32 size = 0; + + if (not2mplt) { + for (MIRFunction *func : GetMIRModule().GetFunctionList()) { + if (func->GetAttr(FUNCATTR_optimized)) { + continue; + } + if (func->GetCodeMemPool() == nullptr || func->GetBody() == nullptr) { + continue; + } + if (dumpFuncSet != nullptr && !dumpFuncSet->empty()) { + // output only if this func matches any name in *dumpFuncSet + const std::string &name = func->GetName(); + bool matched = false; + for (std::string elem : *dumpFuncSet) { + if (name.find(elem.c_str()) != string::npos) { + matched = true; + break; + } + } + if (!matched) { + continue; + } + } + OutputFunction(func->GetPuidx()); + CHECK_FATAL(func->GetBody() != nullptr, "WriteFunctionBodyField: no function body"); + OutputFuncIdInfo(func); + OutputLocalSymTab(func); + OutputPregTab(func); + OutputLabelTab(func); + OutputLocalTypeNameTab(func->GetTypeNameTab()); + OutputFormalsStIdx(func); + OutputAliasMap(func->GetAliasVarMap()); + lastOutputSrcPosition = SrcPosition(); + OutputBlockNode(func->GetBody()); + size++; + } + } + + Fixup(totalSizeIdx, buf.size() - totalSizeIdx); + Fixup(outFunctionBodySizeIdx, size); + WriteNum(~kBinFunctionBodyStart); + return; +} + +} // namespace maple diff --git a/src/mapleall/maple_ir/src/bin_func_import.cpp b/src/mapleall/maple_ir/src/bin_func_import.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0c11135b8265db727a259f97d528bdec9b91f954 --- /dev/null +++ b/src/mapleall/maple_ir/src/bin_func_import.cpp @@ -0,0 +1,817 @@ +/* + * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. + * You can use this software according to the terms and conditions of the MulanPSL - 2.0. + * You may obtain a copy of MulanPSL - 2.0 at: + * + * https://opensource.org/licenses/MulanPSL-2.0 + * + * 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 MulanPSL - 2.0 for more details. + */ + +#include "bin_mpl_export.h" +#include "bin_mpl_import.h" +#include "mir_function.h" +#include "opcode_info.h" +#include "mir_pragma.h" +#include "mir_builder.h" + +#include +#include +#include +using namespace std; + +namespace maple { + +void BinaryMplImport::ImportInfoVector(MIRInfoVector &infovector, MapleVector &infovector_isstring) { + int64 size = ReadNum(); + for (int64 i = 0; i < size; i++) { + GStrIdx gStrIdx = ImportStr(); + bool isstring = ReadNum(); + infovector_isstring.push_back(isstring); + if (isstring) { + GStrIdx fieldval = ImportStr(); + infovector.push_back(MIRInfoPair(gStrIdx, fieldval.GetIdx())); + } else { + uint32 fieldval = ReadNum(); + infovector.push_back(MIRInfoPair(gStrIdx, fieldval)); + } + } +} + +void BinaryMplImport::ImportFuncIdInfo(MIRFunction *func) { + int64 tag = ReadNum(); + CHECK_FATAL(tag == kBinFuncIdInfoStart, "kBinFuncIdInfoStart expected"); + func->SetPuidxOrigin(ReadNum()); + ImportInfoVector(func->GetInfoVector(), func->InfoIsString()); + tag = ReadNum(); + CHECK_FATAL(tag == ~kBinFuncIdInfoStart, "pattern mismatch in ImportFuncIdInfo()"); +} + +void BinaryMplImport::ImportBaseNode(Opcode &o, PrimType &typ, uint8 &numopr) { + o = (Opcode)ReadNum(); + typ = (PrimType)ReadNum(); + numopr = ReadNum(); +} + +void BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { + int64 tag = ReadNum(); + if (tag == 0) { + func->GetSymTab()->PushNullSymbol(); + return; + } + CHECK_FATAL(tag == kBinSymbol, "expecting kBinSymbol in ImportLocalSymbol()"); + uint32 indx = ReadNum(); + CHECK_FATAL(indx == func->GetSymTab()->GetSymbolTableSize(), "inconsistant local stIdx"); + MIRSymbol *sym = func->GetSymTab()->CreateSymbol(kScopeLocal); + sym->SetNameStrIdx(ImportStr()); + func->GetSymTab()->AddToStringSymbolMap(*sym); + sym->SetSKind((MIRSymKind)ReadNum()); + sym->SetStorageClass((MIRStorageClass)ReadNum()); + sym->SetAttrs(ImportTypeAttrs()); + sym->SetIsTmp(ReadNum()); + if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) { + ImportSrcPos(sym->GetSrcPosition()); + } + sym->SetTyIdx(ImportType()); + if (sym->GetSKind() == kStPreg) { + uint32 thepregno = ReadNum(); + MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); + PregIdx pregidx = func->GetPregTab()->EnterPregNo(thepregno, mirType->GetPrimType(), mirType); + MIRPregTable *pregTab = func->GetPregTab(); + MIRPreg *preg = pregTab->PregFromPregIdx(pregidx); + preg->SetPrimType(mirType->GetPrimType()); + sym->SetPreg(preg); + } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) { + sym->SetKonst(ImportConst(func)); + } else if (sym->GetSKind() == kStFunc) { + PUIdx puIdx = ImportFuncViaSymName(); + TyIdx tyIdx = ImportType(); + sym->SetTyIdx(tyIdx); + sym->SetFunction(GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx)); + } +} + +void BinaryMplImport::ImportLocalSymTab(MIRFunction *func) { + int64 tag = ReadNum(); + CHECK_FATAL(tag == kBinSymStart, "kBinSymStart expected in ImportLocalSymTab()"); + int32 size = ReadInt(); + for (int64 i = 0; i < size; i++) { + ImportLocalSymbol(func); + } + tag = ReadNum(); + CHECK_FATAL(tag == ~kBinSymStart, "pattern mismatch in ImportLocalSymTab()"); +} + +void BinaryMplImport::ImportPregTab(MIRFunction *func) { + int64 tag = ReadNum(); + CHECK_FATAL(tag == kBinPregStart, "kBinPregStart expected in ImportPregTab()"); + int32 size = ReadInt(); + for (int64 i = 0; i < size; i++) { + int64 tag = ReadNum(); + if (tag == 0) { + func->GetPregTab()->GetPregTable().push_back(nullptr); + continue; + } + CHECK_FATAL(tag == kBinPreg, "expecting kBinPreg in ImportPregTab()"); + int32 pregNo = ReadNum(); + TyIdx tyIdx = ImportType(); + MIRType *ty = (tyIdx == 0) ? nullptr : GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); + PrimType primType = (PrimType)ReadNum(); + CHECK_FATAL(ty == nullptr || primType == ty->GetPrimType(), "ImportPregTab: inconsistent primitive type"); + func->GetPregTab()->EnterPregNo(pregNo, primType, ty); + } + tag = ReadNum(); + CHECK_FATAL(tag == ~kBinPregStart, "pattern mismatch in ImportPregTab()"); +} + +void BinaryMplImport::ImportLabelTab(MIRFunction *func) { + int64 tag = ReadNum(); + CHECK_FATAL(tag == kBinLabelStart, "kBinLabelStart expected in ImportLabelTab()"); + int32 size = ReadNum(); + for (int64 i = 0; i < size; i++) { + GStrIdx gStrIdx = ImportStr(); + func->GetLabelTab()->AddLabel(gStrIdx); + } + tag = ReadNum(); + CHECK_FATAL(tag == ~kBinLabelStart, "pattern mismatch in ImportLabelTab()"); +} + +void BinaryMplImport::ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab) { + int64 tag = ReadNum(); + CHECK_FATAL(tag == kBinTypenameStart, "kBinTypenameStart expected in ImportLocalTypeNameTable()"); + int32 size = ReadNum(); + for (int64 i = 0; i < size; i++) { + GStrIdx strIdx = ImportStr(); + TyIdx tyIdx = ImportType(); + typeNameTab->SetGStrIdxToTyIdx(strIdx, tyIdx); + } + tag = ReadNum(); + CHECK_FATAL(tag == ~kBinTypenameStart, "pattern mismatch in ImportTypenametab()"); +} + +void BinaryMplImport::ImportFormalsStIdx(MIRFunction *func) { + int64 tag = ReadNum(); + CHECK_FATAL(tag == kBinFormalStart, "kBinFormalStart expected in ImportFormalsStIdx()"); + int32 size = ReadNum(); + for (int64 i = 0; i < size; i++) { + uint32 indx = ReadNum(); + func->GetFormalDefVec()[i].formalSym = func->GetSymTab()->GetSymbolFromStIdx(indx); + } + tag = ReadNum(); + CHECK_FATAL(tag == ~kBinFormalStart, "pattern mismatch in ImportFormalsStIdx()"); +} + +void BinaryMplImport::ImportAliasMap(MIRFunction *func) { + int64 tag = ReadNum(); + CHECK_FATAL(tag == kBinAliasMapStart, "kBinAliasMapStart expected in ImportAliasMap()"); + int32 size = ReadInt(); + for (int32 i = 0; i < size; i++) { + MIRAliasVars aliasvars; + GStrIdx strIdx = ImportStr(); + aliasvars.memPoolStrIdx = ImportStr(); + aliasvars.tyIdx = ImportType(); + /* aliasvars.sigStrIdx = */ ImportStr(); // not assigning to mimic parser + func->GetAliasVarMap()[strIdx] = aliasvars; + } + tag = ReadNum(); + CHECK_FATAL(tag == ~kBinAliasMapStart, "pattern mismatch in ImportAliasMap()"); +} + +PUIdx BinaryMplImport::ImportFuncViaSymName() { + int64 tag = ReadNum(); + CHECK_FATAL(tag == kBinKindFuncViaSymname, "kBinKindFuncViaSymname expected"); + GStrIdx strIdx = ImportStr(); + MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); + MIRFunction *func = sym->GetFunction(); + return func->GetPuidx(); +} + +BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { + int64 tag = ReadNum(); + CHECK_FATAL(tag == kBinOpExpression, "kBinOpExpression expected"); + Opcode op; + PrimType typ; + uint8 numopr; + ImportBaseNode(op, typ, numopr); + switch (op) { + // leaf + case OP_constval: { + MIRConst *constv = ImportConst(func); + ConstvalNode *constNode = mod.CurFuncCodeMemPool()->New(constv); + constNode->SetPrimType(typ); + return constNode; + } + case OP_conststr: { + UStrIdx strIdx = ImportUsrStr(); + ConststrNode *constNode = mod.CurFuncCodeMemPool()->New(typ, strIdx); + constNode->SetPrimType(typ); + return constNode; + } + case OP_addroflabel: { + AddroflabelNode *alabNode = mod.CurFuncCodeMemPool()->New(); + alabNode->SetOffset(ReadNum()); + alabNode->SetPrimType(typ); + func->GetLabelTab()->addrTakenLabels.insert(alabNode->GetOffset()); + return alabNode; + } + case OP_addroffunc: { + PUIdx puIdx = ImportFuncViaSymName(); + AddroffuncNode *addrNode = mod.CurFuncCodeMemPool()->New(typ, puIdx); + return addrNode; + } + case OP_sizeoftype: { + TyIdx tidx = ImportType(); + SizeoftypeNode *sot = mod.CurFuncCodeMemPool()->New(tidx); + return sot; + } + case OP_addrof: + case OP_dread: { + AddrofNode *drNode = mod.CurFuncCodeMemPool()->New(op); + drNode->SetPrimType(typ); + drNode->SetFieldID(ReadNum()); + StIdx stIdx; + stIdx.SetScope(ReadNum()); + if (stIdx.Islocal()) { + stIdx.SetIdx(ReadNum()); + } else { + int32 stag = ReadNum(); + CHECK_FATAL(stag == kBinKindSymViaSymname, "kBinKindSymViaSymname expected"); + GStrIdx strIdx = ImportStr(); + MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); + stIdx.SetIdx(sym->GetStIdx().Idx()); + } + drNode->SetStIdx(stIdx); + return drNode; + } + case OP_regread: { + RegreadNode *regreadNode = mod.CurFuncCodeMemPool()->New(); + regreadNode->SetRegIdx(ReadNum()); + regreadNode->SetPrimType(typ); + return regreadNode; + } + case OP_gcmalloc: + case OP_gcpermalloc: + case OP_stackmalloc: { + TyIdx tyIdx = ImportType(); + GCMallocNode *gcNode = mod.CurFuncCodeMemPool()->New(op, typ, tyIdx); + return gcNode; + } + // unary + case OP_abs: + case OP_bnot: + case OP_lnot: + case OP_neg: + case OP_recip: + case OP_sqrt: + case OP_alloca: + case OP_malloc: { + CHECK_FATAL(numopr == 1, "expected numOpnds to be 1"); + UnaryNode *unNode = mod.CurFuncCodeMemPool()->New(op, typ); + unNode->SetOpnd(ImportExpression(func), 0); + return unNode; + } + case OP_ceil: + case OP_cvt: + case OP_floor: + case OP_trunc: { + CHECK_FATAL(numopr == 1, "expected numOpnds to be 1"); + TypeCvtNode *typecvtNode = mod.CurFuncCodeMemPool()->New(op, typ); + typecvtNode->SetFromType((PrimType)ReadNum()); + typecvtNode->SetOpnd(ImportExpression(func), 0); + return typecvtNode; + } + case OP_retype: { + CHECK_FATAL(numopr == 1, "expected numOpnds to be 1"); + RetypeNode *retypeNode = mod.CurFuncCodeMemPool()->New(typ); + retypeNode->SetTyIdx(ImportType()); + retypeNode->SetOpnd(ImportExpression(func), 0); + return retypeNode; + } + case OP_iread: + case OP_iaddrof: { + CHECK_FATAL(numopr == 1, "expected numOpnds to be 1"); + IreadNode *irNode = mod.CurFuncCodeMemPool()->New(op, typ); + irNode->SetTyIdx(ImportType()); + irNode->SetFieldID(ReadNum()); + irNode->SetOpnd(ImportExpression(func), 0); + return irNode; + } + case OP_sext: + case OP_zext: + case OP_extractbits: { + CHECK_FATAL(numopr == 1, "expected numOpnds to be 1"); + ExtractbitsNode *extNode = mod.CurFuncCodeMemPool()->New(op, typ); + extNode->SetBitsOffset(ReadNum()); + extNode->SetBitsSize(ReadNum()); + extNode->SetOpnd(ImportExpression(func), 0); + return extNode; + } + case OP_gcmallocjarray: + case OP_gcpermallocjarray: { + CHECK_FATAL(numopr == 1, "expected numOpnds to be 1"); + JarrayMallocNode *gcNode = mod.CurFuncCodeMemPool()->New(op, typ); + gcNode->SetTyIdx(ImportType()); + gcNode->SetOpnd(ImportExpression(func), 0); + return gcNode; + } + // binary + case OP_sub: + case OP_mul: + case OP_div: + case OP_rem: + case OP_ashr: + case OP_lshr: + case OP_shl: + case OP_max: + case OP_min: + case OP_band: + case OP_bior: + case OP_bxor: + case OP_cand: + case OP_cior: + case OP_land: + case OP_lior: + case OP_add: { + CHECK_FATAL(numopr == 2, "expected numOpnds to be 2"); + BinaryNode *binNode = mod.CurFuncCodeMemPool()->New(op, typ); + binNode->SetOpnd(ImportExpression(func), 0); + binNode->SetOpnd(ImportExpression(func), 1); + return binNode; + } + case OP_eq: + case OP_ne: + case OP_lt: + case OP_gt: + case OP_le: + case OP_ge: + case OP_cmpg: + case OP_cmpl: + case OP_cmp: { + CHECK_FATAL(numopr == 2, "expected numOpnds to be 2"); + CompareNode *cmpNode = mod.CurFuncCodeMemPool()->New(op, typ); + cmpNode->SetOpndType((PrimType)ReadNum()); + cmpNode->SetOpnd(ImportExpression(func), 0); + cmpNode->SetOpnd(ImportExpression(func), 1); + return cmpNode; + } + case OP_resolveinterfacefunc: + case OP_resolvevirtualfunc: { + CHECK_FATAL(numopr == 2, "expected numOpnds to be 2"); + ResolveFuncNode *rsNode = mod.CurFuncCodeMemPool()->New(op, typ); + rsNode->SetPUIdx(ImportFuncViaSymName()); + rsNode->SetOpnd(ImportExpression(func), 0); + rsNode->SetOpnd(ImportExpression(func), 1); + return rsNode; + } + // ternary + case OP_select: { + CHECK_FATAL(numopr == 3, "expected numOpnds to be 3"); + TernaryNode *tNode = mod.CurFuncCodeMemPool()->New(op, typ); + tNode->SetOpnd(ImportExpression(func), 0); + tNode->SetOpnd(ImportExpression(func), 1); + tNode->SetOpnd(ImportExpression(func), 2); + return tNode; + } + // nary + case OP_array: { + TyIdx tidx = ImportType(); + uint32 bchk = ReadNum(); + ArrayNode *arrNode = mod.CurFuncCodeMemPool()->New(func->GetCodeMPAllocator(), typ, tidx, bchk); + uint32 n = ReadNum(); + for (uint32 i = 0; i < n; i++) { + arrNode->GetNopnd().push_back(ImportExpression(func)); + } + arrNode->SetNumOpnds(arrNode->GetNopnd().size()); + return arrNode; + } + case OP_intrinsicop: { + IntrinsicopNode *intrnNode = mod.CurFuncCodeMemPool()->New(func->GetCodeMPAllocator(), op, typ); + intrnNode->SetIntrinsic((MIRIntrinsicID)ReadNum()); + uint32 n = ReadNum(); + for (uint32 i = 0; i < n; i++) { + intrnNode->GetNopnd().push_back(ImportExpression(func)); + } + intrnNode->SetNumOpnds(intrnNode->GetNopnd().size()); + return intrnNode; + } + case OP_intrinsicopwithtype: { + IntrinsicopNode *intrnNode = mod.CurFuncCodeMemPool()->New(func->GetCodeMPAllocator(), OP_intrinsicopwithtype, typ); + intrnNode->SetIntrinsic((MIRIntrinsicID)ReadNum()); + intrnNode->SetTyIdx(ImportType()); + uint32 n = ReadNum(); + for (uint32 i = 0; i < n; i++) { + intrnNode->GetNopnd().push_back(ImportExpression(func)); + } + intrnNode->SetNumOpnds(intrnNode->GetNopnd().size()); + return intrnNode; + } + default: + CHECK_FATAL(false, "Unhandled op %d", tag); + break; + } +} + +void BinaryMplImport::ImportSrcPos(SrcPosition &pos) { + pos.SetRawData(ReadNum()); + pos.SetLineNum(ReadNum()); +} + +void BinaryMplImport::ImportReturnValues(MIRFunction *func, CallReturnVector *retv) { + int64 tag = ReadNum(); + CHECK_FATAL(tag == kBinReturnvals, "expecting return values"); + uint32 size = ReadNum(); + for (uint32 i = 0; i < size; i++) { + CallReturnPair crPair; + uint32 idx = ReadNum(); + FieldID fid = ReadNum(); + PregIdx16 ridx = ReadNum(); + retv->push_back(std::make_pair(StIdx(kScopeLocal, idx), RegFieldPair(fid,ridx))); + if (idx == 0) { + continue; + } + MIRSymbol *lsym = func->GetSymTab()->GetSymbolFromStIdx(idx, 0); + if (lsym->GetName().find("L_STR") == 0) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(lsym->GetTyIdx()); + CHECK_FATAL(ty->GetKind() == kTypePointer, "Pointer type expected for L_STR prefix"); + MIRPtrType tempType(static_cast(ty)->GetPointedTyIdx(), PTY_ptr); + TyIdx newTyidx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&tempType); + lsym->SetTyIdx(newTyidx); + } + } +} + +BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { + int64 tag = ReadNum(); + ASSERT(tag == kBinNodeBlock, "expecting a BlockNode"); + + BlockNode *block = func->GetCodeMemPool()->New(); + Opcode op; + uint8 numopr; + ImportSrcPos(block->GetSrcPos()); + int32 size = ReadInt(); + for (int32 i = 0; i < size; i++) { + tag = ReadNum(); + CHECK_FATAL(tag == kBinOpStatement, "kBinOpStatement expected"); + SrcPosition thesrcPosition; + ImportSrcPos(thesrcPosition); + op = (Opcode)ReadNum(); + StmtNode *stmt = nullptr; + switch (op) { + case OP_dassign: { + DassignNode *s = func->GetCodeMemPool()->New(); + s->SetFieldID(ReadNum()); + StIdx stIdx; + stIdx.SetScope(ReadNum()); + if (stIdx.Islocal()) { + stIdx.SetIdx(ReadNum()); + } else { + int32 stag = ReadNum(); + CHECK_FATAL(stag == kBinKindSymViaSymname, "kBinKindSymViaSymname expected"); + GStrIdx strIdx = ImportStr(); + MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); + stIdx.SetIdx(sym->GetStIdx().Idx()); + } + s->SetStIdx(stIdx); + s->SetOpnd(ImportExpression(func), 0); + stmt = s; + break; + } + case OP_regassign: { + RegassignNode *s = func->GetCodeMemPool()->New(); + s->SetPrimType((PrimType)ReadNum()); + s->SetRegIdx(ReadNum()); + s->SetOpnd(ImportExpression(func), 0); + stmt = s; + break; + } + case OP_iassign: { + IassignNode *s = func->GetCodeMemPool()->New(); + s->SetTyIdx(ImportType()); + s->SetFieldID(ReadNum()); + s->SetAddrExpr(ImportExpression(func)); + s->SetRHS(ImportExpression(func)); + stmt = s; + break; + } + case OP_call: + case OP_virtualcall: + case OP_virtualicall: + case OP_superclasscall: + case OP_interfacecall: + case OP_interfaceicall: + case OP_customcall: { + CallNode *s = func->GetCodeMemPool()->New(mod, op); + s->SetPUIdx(ImportFuncViaSymName()); + numopr = ReadNum(); + s->SetNumOpnds(numopr); + for (int32 i = 0; i < numopr; i++) { + s->GetNopnd().push_back(ImportExpression(func)); + } + stmt = s; + break; + } + case OP_callassigned: + case OP_virtualcallassigned: + case OP_virtualicallassigned: + case OP_superclasscallassigned: + case OP_interfacecallassigned: + case OP_interfaceicallassigned: + case OP_customcallassigned: { + CallNode *s = func->GetCodeMemPool()->New(mod, op); + s->SetPUIdx(ImportFuncViaSymName()); + ImportReturnValues(func, &s->GetReturnVec()); + numopr = ReadNum(); + s->SetNumOpnds(numopr); + for (int32 i = 0; i < numopr; i++) { + s->GetNopnd().push_back(ImportExpression(func)); + } + stmt = s; + break; + } + case OP_polymorphiccall: { + CallNode *s = func->GetCodeMemPool()->New(mod, op); + s->SetPUIdx(ImportFuncViaSymName()); + s->SetTyIdx(ImportType()); + numopr = ReadNum(); + s->SetNumOpnds(numopr); + for (int32 i = 0; i < numopr; i++) { + s->GetNopnd().push_back(ImportExpression(func)); + } + stmt = s; + break; + } + case OP_polymorphiccallassigned: { + CallNode *s = func->GetCodeMemPool()->New(mod, op); + s->SetPUIdx(ImportFuncViaSymName()); + s->SetTyIdx(ImportType()); + ImportReturnValues(func, &s->GetReturnVec()); + numopr = ReadNum(); + s->SetNumOpnds(numopr); + for (int32 i = 0; i < numopr; i++) { + s->GetNopnd().push_back(ImportExpression(func)); + } + stmt = s; + break; + } + case OP_icall: { + IcallNode *s = func->GetCodeMemPool()->New(mod, op); + s->SetRetTyIdx(ImportType()); + numopr = ReadNum(); + s->SetNumOpnds(numopr); + for (int32 i = 0; i < numopr; i++) { + s->GetNopnd().push_back(ImportExpression(func)); + } + stmt = s; + break; + } + case OP_icallassigned: { + IcallNode *s = func->GetCodeMemPool()->New(mod, op); + s->SetRetTyIdx(ImportType()); + ImportReturnValues(func, &s->GetReturnVec()); + numopr = ReadNum(); + s->SetNumOpnds(numopr); + for (int32 i = 0; i < numopr; i++) { + s->GetNopnd().push_back(ImportExpression(func)); + } + stmt = s; + break; + } + case OP_intrinsiccall: + case OP_xintrinsiccall: { + IntrinsiccallNode *s = func->GetCodeMemPool()->New(mod, op); + s->SetIntrinsic((MIRIntrinsicID)ReadNum()); + numopr = ReadNum(); + s->SetNumOpnds(numopr); + for (int32 i = 0; i < numopr; i++) { + s->GetNopnd().push_back(ImportExpression(func)); + } + stmt = s; + break; + } + case OP_intrinsiccallassigned: + case OP_xintrinsiccallassigned: { + IntrinsiccallNode *s = func->GetCodeMemPool()->New(mod, op); + s->SetIntrinsic((MIRIntrinsicID)ReadNum()); + ImportReturnValues(func, &s->GetReturnVec()); + numopr = ReadNum(); + s->SetNumOpnds(numopr); + for (int32 i = 0; i < numopr; i++) { + s->GetNopnd().push_back(ImportExpression(func)); + } + if (s->GetReturnVec().size() == 1 && s->GetReturnVec()[0].first.Idx() != 0) { + MIRSymbol *retsymbol = func->GetSymTab()->GetSymbolFromStIdx(s->GetReturnVec()[0].first.Idx()); + MIRType *rettype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(retsymbol->GetTyIdx()); + CHECK_FATAL(rettype != nullptr, "rettype is null in MIRParser::ParseStmtIntrinsiccallAssigned"); + s->SetPrimType(rettype->GetPrimType()); + } + stmt = s; + break; + } + case OP_intrinsiccallwithtype: { + IntrinsiccallNode *s = func->GetCodeMemPool()->New(mod, op); + s->SetIntrinsic((MIRIntrinsicID)ReadNum()); + s->SetTyIdx(ImportType()); + numopr = ReadNum(); + s->SetNumOpnds(numopr); + for (int32 i = 0; i < numopr; i++) { + s->GetNopnd().push_back(ImportExpression(func)); + } + stmt = s; + break; + } + case OP_intrinsiccallwithtypeassigned: { + IntrinsiccallNode *s = func->GetCodeMemPool()->New(mod, op); + s->SetIntrinsic((MIRIntrinsicID)ReadNum()); + s->SetTyIdx(ImportType()); + ImportReturnValues(func, &s->GetReturnVec()); + numopr = ReadNum(); + s->SetNumOpnds(numopr); + for (int32 i = 0; i < numopr; i++) { + s->GetNopnd().push_back(ImportExpression(func)); + } + if (s->GetReturnVec().size() == 1 && s->GetReturnVec()[0].first.Idx() != 0) { + MIRSymbol *retsymbol = func->GetSymTab()->GetSymbolFromStIdx(s->GetReturnVec()[0].first.Idx()); + MIRType *rettype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(retsymbol->GetTyIdx()); + CHECK_FATAL(rettype != nullptr, "rettype is null in MIRParser::ParseStmtIntrinsiccallAssigned"); + s->SetPrimType(rettype->GetPrimType()); + } + stmt = s; + break; + } + case OP_syncenter: + case OP_syncexit: + case OP_return: { + NaryStmtNode *s = func->GetCodeMemPool()->New(mod, op); + numopr = ReadNum(); + s->SetNumOpnds(numopr); + for (int32 i = 0; i < numopr; i++) { + s->GetNopnd().push_back(ImportExpression(func)); + } + stmt = s; + break; + } + case OP_jscatch: + case OP_cppcatch: + case OP_finally: + case OP_endtry: + case OP_cleanuptry: + case OP_retsub: + case OP_membaracquire: + case OP_membarrelease: + case OP_membarstorestore: + case OP_membarstoreload: { + stmt = mod.CurFuncCodeMemPool()->New(op); + break; + } + case OP_eval: + case OP_throw: + case OP_free: + case OP_decref: + case OP_incref: + case OP_decrefreset: + case OP_assertnonnull: + case OP_igoto: { + UnaryStmtNode *s = mod.CurFuncCodeMemPool()->New(op); + s->SetOpnd(ImportExpression(func), 0); + stmt = s; + break; + } + case OP_label: { + LabelNode *s = mod.CurFuncCodeMemPool()->New(); + s->SetLabelIdx(ReadNum()); + stmt = s; + break; + } + case OP_goto: + case OP_gosub: { + GotoNode *s = mod.CurFuncCodeMemPool()->New(op); + s->SetOffset(ReadNum()); + stmt = s; + break; + } + case OP_brfalse: + case OP_brtrue: { + CondGotoNode *s = mod.CurFuncCodeMemPool()->New(op); + s->SetOffset(ReadNum()); + s->SetOpnd(ImportExpression(func), 0); + stmt = s; + break; + } + case OP_switch: { + SwitchNode *s = mod.CurFuncCodeMemPool()->New(mod); + s->SetDefaultLabel(ReadNum()); + uint32 size = ReadNum(); + for (uint32 i = 0; i < size; i++) { + int32 casetag = ReadNum(); + LabelIdx lidx(ReadNum()); + CasePair cpair = std::make_pair(casetag, lidx); + s->GetSwitchTable().push_back(cpair); + } + s->SetSwitchOpnd(ImportExpression(func)); + stmt = s; + break; + } + case OP_jstry: { + JsTryNode *s = mod.CurFuncCodeMemPool()->New(); + s->SetCatchOffset(ReadNum()); + s->SetFinallyOffset(ReadNum()); + stmt = s; + break; + } + case OP_cpptry: + case OP_try: { + TryNode *s = mod.CurFuncCodeMemPool()->New(mod, op); + uint32 numLabels = ReadNum(); + for (uint32 i = 0; i < numLabels; i++) { + s->GetOffsets().push_back(ReadNum()); + } + stmt = s; + break; + } + case OP_catch: { + CatchNode *s = mod.CurFuncCodeMemPool()->New(mod); + uint32 numTys = ReadNum(); + for (uint32 i = 0; i < numTys; i++) { + s->PushBack(ImportType()); + } + stmt = s; + break; + } + case OP_comment: { + CommentNode *s = mod.CurFuncCodeMemPool()->New(mod); + string str; + ReadAsciiStr(str); + s->SetComment(str); + stmt = s; + break; + } + case OP_dowhile: + case OP_while: { + WhileStmtNode *s = mod.CurFuncCodeMemPool()->New(op); + s->SetBody(ImportBlockNode(func)); + s->SetOpnd(ImportExpression(func), 0); + stmt = s; + break; + } + case OP_if: { + IfStmtNode *s = mod.CurFuncCodeMemPool()->New(); + bool hasElsePart = ReadNum(); + s->SetThenPart(ImportBlockNode(func)); + if (hasElsePart) { + s->SetElsePart(ImportBlockNode(func)); + } + s->SetOpnd(ImportExpression(func), 0); + stmt = s; + break; + } + case OP_block: { + stmt = ImportBlockNode(func); + break; + } + default: + CHECK_FATAL(false, "Unhandled opcode tag %d", tag); + break; + } + stmt->SetSrcPos(thesrcPosition); + block->AddStatement(stmt); + } + if (func != nullptr) { + func->SetBody(block); + } + return block; +} + +void BinaryMplImport::ReadFunctionBodyField() { + ReadInt(); /// skip total size + int32 size = ReadInt(); + for (int64 i = 0; i < size; i++) { + PUIdx puIdx = ImportFunction(); + MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); + mod.SetCurFunction(fn); + + fn->AllocSymTab(); + fn->AllocPregTab(); + fn->AllocTypeNameTab(); + fn->AllocLabelTab(); + + ImportFuncIdInfo(fn); + ImportLocalSymTab(fn); + ImportPregTab(fn); + ImportLabelTab(fn); + ImportLocalTypeNameTable(fn->GetTypeNameTab()); + ImportFormalsStIdx(fn); + ImportAliasMap(fn); + ImportBlockNode(fn); + mod.AddFunction(fn); + } + int64 tag = ReadNum(); + CHECK_FATAL(tag == ~kBinFunctionBodyStart, "pattern mismatch in Read FunctionBody"); + return; +} + +} // namespace maple diff --git a/src/mapleall/maple_ir/src/bin_mpl_export.cpp b/src/mapleall/maple_ir/src/bin_mpl_export.cpp index 0eb7625646b82e6b29903618148ccf92081fa0e3..2afcde6feef956bf84db796a35163bf946a02a93 100755 --- a/src/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -26,7 +26,7 @@ namespace { using namespace maple; using OutputConstFactory = FunctionFactory; -using OutputTypeFactory = FunctionFactory; +using OutputTypeFactory = FunctionFactory; void OutputConstInt(const MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstInt); @@ -35,11 +35,20 @@ void OutputConstInt(const MIRConst &constVal, BinaryMplExport &mplExport) { } void OutputConstAddrof(const MIRConst &constVal, BinaryMplExport &mplExport) { - mplExport.WriteNum(kBinKindConstAddrof); + const MIRAddrofConst &addrof = static_cast(constVal); + if (addrof.GetSymbolIndex().IsGlobal()) { + mplExport.WriteNum(kBinKindConstAddrof); + } else { + mplExport.WriteNum(kBinKindConstAddrofLocal); + } mplExport.OutputConstBase(constVal); - const auto &addrof = static_cast(constVal); - mplExport.OutputSymbol(mplExport.GetMIRModule().CurFunction()->GetLocalOrGlobalSymbol(addrof.GetSymbolIndex())); + if (addrof.GetSymbolIndex().IsGlobal()) { + mplExport.OutputSymbol(mplExport.GetMIRModule().CurFunction()->GetLocalOrGlobalSymbol(addrof.GetSymbolIndex())); + } else { + mplExport.WriteNum(addrof.GetSymbolIndex().FullIdx()); + } mplExport.WriteNum(addrof.GetFieldID()); + mplExport.WriteNum(addrof.GetOffset()); } void OutputConstAddrofFunc(const MIRConst &constVal, BinaryMplExport &mplExport) { @@ -49,8 +58,12 @@ void OutputConstAddrofFunc(const MIRConst &constVal, BinaryMplExport &mplExport) mplExport.OutputFunction(newConst.GetValue()); } -void OutputConstLbl(const MIRConst&, BinaryMplExport&) { - ASSERT(false, "NYI"); +void OutputConstLbl(const MIRConst &constVal, BinaryMplExport &mplExport) { + mplExport.WriteNum(kBinKindConstAddrofLabel); + mplExport.OutputConstBase(constVal); + const MIRLblConst &lblConst = static_cast(constVal); + mplExport.WriteNum(lblConst.GetValue()); // LabelIdx + // not needed to output puIdx } void OutputConstStr(const MIRConst &constVal, BinaryMplExport &mplExport) { @@ -75,12 +88,14 @@ void OutputConstStr16(const MIRConst &constVal, BinaryMplExport &mplExport) { void OutputConstFloat(const MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstFloat); + mplExport.OutputConstBase(constVal); const auto &newConst = static_cast(constVal); mplExport.WriteNum(newConst.GetIntValue()); } void OutputConstDouble(const MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstDouble); + mplExport.OutputConstBase(constVal); const auto &newConst = static_cast(constVal); mplExport.WriteNum(newConst.GetIntValue()); } @@ -126,39 +141,39 @@ static bool InitOutputConstFactory() { return true; } -void OutputTypeScalar(const MIRType &ty, BinaryMplExport &mplExport) { +void OutputTypeScalar(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { mplExport.WriteNum(kBinKindTypeScalar); mplExport.OutputTypeBase(ty); } -void OutputTypePointer(const MIRType &ty, BinaryMplExport &mplExport) { +void OutputTypePointer(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypePointer); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetPointedTyIdx()); + mplExport.OutputType(type.GetPointedTyIdx(), canUseTypename); + mplExport.OutputTypeAttrs(type.GetTypeAttrs()); } -void OutputTypeByName(const MIRType &ty, BinaryMplExport &mplExport) { - const auto &type = static_cast(ty); +void OutputTypeByName(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { mplExport.WriteNum(kBinKindTypeByName); - mplExport.OutputTypeBase(type); + mplExport.OutputTypeBase(ty); } -void OutputTypeFArray(const MIRType &ty, BinaryMplExport &mplExport) { +void OutputTypeFArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeFArray); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetElemTyIdx()); + mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); } -void OutputTypeJArray(const MIRType &ty, BinaryMplExport &mplExport) { +void OutputTypeJArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeJarray); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetElemTyIdx()); + mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); } -void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport) { +void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeArray); mplExport.OutputTypeBase(type); @@ -166,19 +181,20 @@ void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport) { for (uint16 i = 0; i < type.GetDim(); ++i) { mplExport.WriteNum(type.GetSizeArrayItem(i)); } - mplExport.OutputType(type.GetElemTyIdx()); + mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputTypeAttrs(type.GetTypeAttrs()); } -void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport) { +void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeFunction); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetRetTyIdx()); + mplExport.OutputType(type.GetRetTyIdx(), canUseTypename); mplExport.WriteNum(type.IsVarargs()); size_t size = type.GetParamTypeList().size(); mplExport.WriteNum(size); for (size_t i = 0; i < size; ++i) { - mplExport.OutputType(type.GetNthParamType(i)); + mplExport.OutputType(type.GetNthParamType(i), canUseTypename); } size = type.GetParamAttrsList().size(); mplExport.WriteNum(size); @@ -187,13 +203,13 @@ void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport) { } } -void OutputTypeParam(const MIRType &ty, BinaryMplExport &mplExport) { +void OutputTypeParam(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeParam); mplExport.OutputTypeBase(type); } -void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport) { +void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeInstantVector); mplExport.OutputTypeBase(type); @@ -201,15 +217,15 @@ void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport) { mplExport.OutputTypePairs(type); } -void OutputTypeGenericInstant(const MIRType &ty, BinaryMplExport &mplExport) { +void OutputTypeGenericInstant(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeGenericInstant); mplExport.OutputTypeBase(type); mplExport.OutputTypePairs(type); - mplExport.OutputType(type.GetGenericTyIdx()); + mplExport.OutputType(type.GetGenericTyIdx(), canUseTypename); } -void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport) { +void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeBitField); mplExport.OutputTypeBase(type); @@ -217,7 +233,7 @@ void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport) { } // for Struct/StructIncomplete/Union -void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport) { +void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeStruct); mplExport.OutputTypeBase(type); @@ -232,7 +248,7 @@ void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport) { } } -void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport) { +void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeClass); mplExport.OutputTypeBase(type); @@ -247,7 +263,7 @@ void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport) { } } -void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport) { +void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeInterface); mplExport.OutputTypeBase(type); @@ -262,7 +278,9 @@ void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport) { } } -void OutputTypeConstString(const MIRType&, BinaryMplExport&) {} +void OutputTypeConstString(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { + ASSERT(false, "Type's kind not yet implemented: %d", ty.GetKind()); +} static bool InitOutputTypeFactory() { RegisterFactoryFunction(kTypeScalar, OutputTypeScalar); @@ -292,9 +310,11 @@ namespace maple { int BinaryMplExport::typeMarkOffset = 0; BinaryMplExport::BinaryMplExport(MIRModule &md) : mod(md) { + bufI = 0; Init(); (void)InitOutputConstFactory(); (void)InitOutputTypeFactory(); + not2mplt = false; } uint8 BinaryMplExport::Read() { @@ -329,6 +349,8 @@ void BinaryMplExport::ExpandFourBuffSize() { } void BinaryMplExport::Fixup(size_t i, int32 x) { + constexpr int fixupCount = 4; + CHECK(i <= buf.size() - fixupCount, "Index out of bound in BinaryMplImport::Fixup()"); buf[i] = static_cast(static_cast(x) & 0xFF); buf[i + 1] = static_cast((static_cast(x) >> 8) & 0xFF); buf[i + 2] = static_cast((static_cast(x) >> 16) & 0xFF); @@ -351,10 +373,10 @@ void BinaryMplExport::WriteNum(int64 x) { } void BinaryMplExport::WriteAsciiStr(const std::string &str) { + WriteNum(str.size()); for (size_t i = 0; i < str.size(); ++i) { Write(static_cast(str[i])); } - Write(0); } void BinaryMplExport::DumpBuf(const std::string &name) { @@ -373,7 +395,7 @@ void BinaryMplExport::DumpBuf(const std::string &name) { void BinaryMplExport::OutputConstBase(const MIRConst &constVal) { WriteNum(constVal.GetKind()); - OutputType(constVal.GetType().GetTypeIndex()); + OutputTypeViaTypeName(constVal.GetType().GetTypeIndex()); WriteNum(constVal.GetFieldId()); } @@ -447,8 +469,8 @@ void BinaryMplExport::OutputPragma(const MIRPragma &p) { WriteNum(p.GetKind()); WriteNum(p.GetVisibility()); OutputStr(p.GetStrIdx()); - OutputType(p.GetTyIdx()); - OutputType(p.GetTyIdxEx()); + OutputType(p.GetTyIdx(), false); + OutputType(p.GetTyIdxEx(), false); WriteNum(p.GetParamNum()); size_t size = p.GetElementVector().size(); WriteNum(size); @@ -465,7 +487,7 @@ void BinaryMplExport::OutputTypeBase(const MIRType &type) { void BinaryMplExport::OutputFieldPair(const FieldPair &fp) { OutputStr(fp.first); // GStrIdx - OutputType(fp.second.first); // TyIdx + OutputType(fp.second.first, false); // TyIdx FieldAttrs fa = fp.second.second; WriteNum(fa.GetAttrFlag()); WriteNum(fa.GetAlignValue()); @@ -476,6 +498,7 @@ void BinaryMplExport::OutputFieldPair(const FieldPair &fp) { if ((fieldVar != nullptr) && (fieldVar->GetKonst() != nullptr) && (fieldVar->GetKonst()->GetKind() == kConstStr16Const)) { WriteNum(kBinInitConst); + fieldVar->GetKonst()->SetType(*fieldVar->GetType()); OutputConst(fieldVar->GetKonst()); } else { WriteNum(0); @@ -488,7 +511,7 @@ void BinaryMplExport::OutputMethodPair(const MethodPair &memPool) { MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(memPool.first.Idx()); CHECK_FATAL(funcSt != nullptr, "Pointer funcSt is nullptr, can't get symbol! Check it!"); WriteAsciiStr(GlobalTables::GetStrTable().GetStringFromStrIdx(funcSt->GetNameStrIdx())); - OutputType(memPool.second.first); // TyIdx + OutputType(memPool.second.first, false); // TyIdx WriteNum(memPool.second.second.GetAttrFlag()); // FuncAttrs } @@ -516,7 +539,7 @@ void BinaryMplExport::OutputStructTypeData(const MIRStructType &type) { void BinaryMplExport::OutputImplementedInterfaces(const std::vector &interfaces) { WriteNum(interfaces.size()); for (const TyIdx &tyIdx : interfaces) { - OutputType(tyIdx); + OutputType(tyIdx, false); } } @@ -548,7 +571,7 @@ void BinaryMplExport::OutputPragmaVec(const std::vector &pragmaVec) } void BinaryMplExport::OutputClassTypeData(const MIRClassType &type) { - OutputType(type.GetParentTyIdx()); + OutputType(type.GetParentTyIdx(), false); OutputImplementedInterfaces(type.GetInterfaceImplemented()); OutputInfoIsString(type.GetInfoIsString()); OutputInfo(type.GetInfo(), type.GetInfoIsString()); @@ -563,17 +586,11 @@ void BinaryMplExport::OutputInterfaceTypeData(const MIRInterfaceType &type) { } void BinaryMplExport::Init() { - BinaryMplExport::typeMarkOffset = 0; - gStrMark.clear(); - uStrMark.clear(); - symMark.clear(); - funcMark.clear(); - typMark.clear(); gStrMark[GStrIdx(0)] = 0; uStrMark[UStrIdx(0)] = 0; symMark[nullptr] = 0; funcMark[nullptr] = 0; - for (uint32 pti = 0; pti <= static_cast(PTY_agg); ++pti) { + for (uint32 pti = static_cast(PTY_begin); pti < static_cast(PTY_end); ++pti) { typMark[GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(pti))] = pti; } } @@ -590,7 +607,6 @@ void BinaryMplExport::OutputSymbol(const MIRSymbol *sym) { return; } - ASSERT(sym->GetSKind() == kStFunc, "Should not be used"); WriteNum(kBinSymbol); WriteNum(sym->GetScopeIdx()); OutputStr(sym->GetNameStrIdx()); @@ -600,16 +616,39 @@ void BinaryMplExport::OutputSymbol(const MIRSymbol *sym) { symMark[sym] = mark; OutputTypeAttrs(sym->GetAttrs()); WriteNum(sym->GetIsTmp() ? 1 : 0); - OutputFunction(sym->GetFunction()->GetPuidx()); - OutputType(sym->GetTyIdx()); + if (sym->GetSKind() == kStPreg) { + WriteNum(sym->GetPreg()->GetPregNo()); + } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) { + if (sym->GetKonst() != nullptr) { + sym->GetKonst()->SetType(*sym->GetType()); + } + OutputConst(sym->GetKonst()); + } else if (sym->GetSKind() == kStFunc) { + OutputFunction(sym->GetFunction()->GetPuidx()); + } else if (sym->GetSKind() == kStJavaClass || sym->GetSKind() == kStJavaInterface) { + } else { + CHECK_FATAL(false, "should not used"); + } + if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) { + OutputSrcPos(sym->GetSrcPosition()); + } + OutputTypeViaTypeName(sym->GetTyIdx()); } void BinaryMplExport::OutputFunction(PUIdx puIdx) { if (puIdx == 0) { WriteNum(0); + mod.SetCurFunction(nullptr); return; } MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); + CHECK_FATAL(func != nullptr, "Cannot get MIRFunction."); + auto it = funcMark.find(func); + if (it != funcMark.end()) { + WriteNum(-it->second); + mod.SetCurFunction(func); + return; + } size_t mark = funcMark.size(); funcMark[func] = mark; MIRFunction *savedFunc = mod.CurFunction(); @@ -619,10 +658,18 @@ void BinaryMplExport::OutputFunction(PUIdx puIdx) { MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); CHECK_FATAL(funcSt != nullptr, "Pointer funcSt is nullptr, cannot get symbol! Check it!"); OutputSymbol(funcSt); - OutputType(func->GetReturnTyIdx()); + OutputTypeViaTypeName(func->GetFuncType()->GetTypeIndex()); WriteNum(func->GetFuncAttrs().GetAttrFlag()); WriteNum(func->GetFlag()); - OutputType(func->GetClassTyIdx()); + OutputTypeViaTypeName(func->GetClassTyIdx()); + // output formal parameter information + WriteNum(func->GetFormalDefVec().size()); + for (FormalDef formalDef : func->GetFormalDefVec()) { + OutputStr(formalDef.formalStrIdx); + OutputType(formalDef.formalTyIdx, false); + WriteNum(formalDef.formalAttrs.GetAttrFlag()); + } + mod.SetCurFunction(savedFunc); } @@ -647,7 +694,35 @@ void BinaryMplExport::WriteStrField(uint64 contentIdx) { WriteNum(~kBinStrStart); } -void BinaryMplExport::WriteTypeField(uint64 contentIdx) { +void BinaryMplExport::WriteHeaderField(uint64 contentIdx) { + Fixup(contentIdx, buf.size()); + WriteNum(kBinHeaderStart); + size_t totalSizeIdx = buf.size(); + ExpandFourBuffSize(); /// total size of this field to ~BIN_IMPORT_START + WriteNum(mod.GetFlavor()); + WriteNum(mod.GetSrcLang()); + WriteNum(mod.GetID()); + WriteNum(mod.GetNumFuncs()); + WriteAsciiStr(mod.GetEntryFuncName()); + OutputInfoVector(mod.GetFileInfo(), mod.GetFileInfoIsString()); + + WriteNum(mod.GetSrcFileInfo().size()); + for (uint32 i = 0; i < mod.GetSrcFileInfo().size(); i++) { + OutputStr(mod.GetSrcFileInfo()[i].first); + WriteNum(mod.GetSrcFileInfo()[i].second); + } + + WriteNum(mod.GetImportFiles().size()); + for (GStrIdx strIdx : mod.GetImportFiles()) { + OutputStr(strIdx); + } + + Fixup(totalSizeIdx, buf.size() - totalSizeIdx); + WriteNum(~kBinHeaderStart); + return; +} + +void BinaryMplExport::WriteTypeField(uint64 contentIdx, bool useClassList) { Fixup(contentIdx, buf.size()); WriteNum(kBinTypeStart); size_t totalSizeIdx = buf.size(); @@ -655,26 +730,69 @@ void BinaryMplExport::WriteTypeField(uint64 contentIdx) { size_t outTypeSizeIdx = buf.size(); ExpandFourBuffSize(); // size of OutputType int32 size = 0; - for (uint32 tyIdx : mod.GetClassList()) { - TyIdx curTyidx(tyIdx); - MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(curTyidx); - CHECK_FATAL(type != nullptr, "Pointer type is nullptr, cannot get type, check it!"); - if (type->GetKind() == kTypeClass || type->GetKind() == kTypeInterface) { - auto *structType = static_cast(type); - // skip imported class/interface and incomplete types - if (!structType->IsImported() && !structType->IsIncomplete()) { - OutputType(curTyidx); - ++size; + if (useClassList) { + for (uint32 tyIdx : mod.GetClassList()) { + TyIdx curTyidx(tyIdx); + MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(curTyidx); + CHECK_FATAL(type != nullptr, "Pointer type is nullptr, cannot get type, check it!"); + if (type->GetKind() == kTypeClass || type->GetKind() == kTypeInterface) { + auto *structType = static_cast(type); + // skip imported class/interface and incomplete types + if (!structType->IsImported() && !structType->IsIncomplete()) { + OutputType(curTyidx, false); + ++size; + } } } + } else { + uint32 idx = GlobalTables::GetTypeTable().lastDefaultTyIdx.GetIdx(); + for (idx = idx + 1; idx < GlobalTables::GetTypeTable().GetTypeTableSize(); idx++) { + OutputType(TyIdx(idx), false); + size++; + } } Fixup(totalSizeIdx, buf.size() - totalSizeIdx); Fixup(outTypeSizeIdx, size); WriteNum(~kBinTypeStart); } +void BinaryMplExport::WriteSymField(uint64 contentIdx) { + Fixup(contentIdx, buf.size()); + // LogInfo::MapleLogger() << "Write SYM Field " << std::endl; + WriteNum(kBinSymStart); + uint64 totalSizeIdx = buf.size(); + ExpandFourBuffSize(); /// total size of this field to ~BIN_SYM_START + uint64 outsymSizeIdx = buf.size(); + ExpandFourBuffSize(); /// size of OutSym + int32 size = 0; + + if (not2mplt) { + for (auto sit = GetMIRModule().GetSymbolDefOrder().begin(); sit != GetMIRModule().GetSymbolDefOrder().end(); sit++) { + MIRSymbol *s = GlobalTables::GetGsymTable().GetSymbolFromStidx((*sit).Idx()); + // Verify: all wpofake variables should have been deleted from globaltable + ASSERT(!(s->IsWpoFakeParm() || s->IsWpoFakeRet()) || s->IsDeleted(), "wpofake var not deleted"); + MIRStorageClass storageClass = s->GetStorageClass(); + MIRSymKind sKind = s->GetSKind(); + + if (s->IsDeleted() || + storageClass == kScUnused || + (s->GetIsImported() && !s->GetAppearsInCode()) || + (storageClass == kScExtern && sKind == kStFunc)) { + continue; + } + // printf("EXPORT Writing symbol %s\n", s->GetName().c_str()); + OutputSymbol(s); + size++; + } + } + + Fixup(totalSizeIdx, buf.size() - totalSizeIdx); + Fixup(outsymSizeIdx, size); + WriteNum(~kBinSymStart); + return; +} -void BinaryMplExport::WriteContentField(int fieldNum, uint64 *fieldStartP) { +void BinaryMplExport::WriteContentField4mplt(int fieldNum, uint64 *fieldStartP) { WriteNum(kBinContentStart); size_t totalSizeIdx = buf.size(); ExpandFourBuffSize(); // total size of this field to ~BIN_SYM_START @@ -697,15 +815,87 @@ void BinaryMplExport::WriteContentField(int fieldNum, uint64 *fieldStartP) { WriteNum(~kBinContentStart); } -void BinaryMplExport::Export(const std::string &fname) { - constexpr int fieldNum = 3; - uint64 fieldStartPoint[fieldNum]; - WriteInt(kMpltMagicNumber); - WriteContentField(fieldNum, fieldStartPoint); - WriteStrField(fieldStartPoint[0]); - WriteTypeField(fieldStartPoint[1]); +void BinaryMplExport::WriteContentField4nonmplt(int fieldNum, uint64 *fieldStartP) { + CHECK_FATAL(fieldStartP != nullptr, "fieldStartP is null."); + WriteNum(kBinContentStart); + size_t totalSizeIdx = buf.size(); + ExpandFourBuffSize(); /// total size of this field to ~BIN_SYM_START + + WriteInt(fieldNum); /// size of Content item + + WriteNum(kBinHeaderStart); + fieldStartP[0] = buf.size(); + ExpandFourBuffSize(); + + WriteNum(kBinSymStart); + fieldStartP[1] = buf.size(); + ExpandFourBuffSize(); + + WriteNum(kBinFunctionBodyStart); + fieldStartP[2] = buf.size(); + ExpandFourBuffSize(); + + Fixup(totalSizeIdx, buf.size() - totalSizeIdx); + WriteNum(~kBinContentStart); +} + +void BinaryMplExport::WriteContentField4nonJava(int fieldNum, uint64 *fieldStartP) { + CHECK_FATAL(fieldStartP != nullptr, "fieldStartP is null."); + WriteNum(kBinContentStart); + size_t totalSizeIdx = buf.size(); + ExpandFourBuffSize(); /// total size of this field to ~BIN_SYM_START + + WriteInt(fieldNum); /// size of Content item + + WriteNum(kBinHeaderStart); + fieldStartP[0] = buf.size(); + ExpandFourBuffSize(); + + WriteNum(kBinStrStart); + fieldStartP[1] = buf.size(); + ExpandFourBuffSize(); + + WriteNum(kBinTypeStart); + fieldStartP[2] = buf.size(); + ExpandFourBuffSize(); + + WriteNum(kBinSymStart); + fieldStartP[3] = buf.size(); + ExpandFourBuffSize(); + + WriteNum(kBinFunctionBodyStart); + fieldStartP[4] = buf.size(); + ExpandFourBuffSize(); + + Fixup(totalSizeIdx, buf.size() - totalSizeIdx); + WriteNum(~kBinContentStart); +} + +void BinaryMplExport::Export(const std::string &fname, std::unordered_set *dumpFuncSet) { + uint64 fieldStartPoint[5]; + if (!not2mplt) { + WriteInt(kMpltMagicNumber); + WriteContentField4mplt(3, fieldStartPoint); + WriteStrField(fieldStartPoint[0]); + WriteTypeField(fieldStartPoint[1]); + importFileName = fname; + } else { + WriteInt(kMpltMagicNumber+0x10); + if (mod.IsJavaModule()) { + WriteContentField4nonmplt(3, fieldStartPoint); + WriteHeaderField(fieldStartPoint[0]); + WriteSymField(fieldStartPoint[1]); + WriteFunctionBodyField(fieldStartPoint[2], dumpFuncSet); + } else { + WriteContentField4nonJava(5, fieldStartPoint); + WriteHeaderField(fieldStartPoint[0]); + WriteStrField(fieldStartPoint[1]); + WriteTypeField(fieldStartPoint[2], false/*useClassList*/); + WriteSymField(fieldStartPoint[3]); + WriteFunctionBodyField(fieldStartPoint[4], dumpFuncSet); + } + } WriteNum(kBinFinish); - importFileName = fname; DumpBuf(fname); } @@ -729,8 +919,8 @@ void BinaryMplExport::OutputTypePairs(const MIRInstantVectorType &type) { size_t size = type.GetInstantVec().size(); WriteNum(size); for (const TypePair &typePair : type.GetInstantVec()) { - OutputType(typePair.first); - OutputType(typePair.second); + OutputType(typePair.first, false); + OutputType(typePair.second, false); } } @@ -739,12 +929,12 @@ void BinaryMplExport::OutputTypeAttrs(const TypeAttrs &ta) { WriteNum(ta.GetAlignValue()); } -void BinaryMplExport::OutputType(TyIdx tyIdx) { - MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); +void BinaryMplExport::OutputType(TyIdx tyIdx, bool canUseTypename) { if (tyIdx == 0u) { WriteNum(0); return; } + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); CHECK_FATAL(ty != nullptr, "If gets nulltype, should have been returned!"); auto it = typMark.find(ty); if (it != typMark.end()) { @@ -752,15 +942,19 @@ void BinaryMplExport::OutputType(TyIdx tyIdx) { WriteNum(-(it->second)); return; } - ++BinaryMplExport::typeMarkOffset; - } else { - size_t mark = typMark.size() + BinaryMplExport::typeMarkOffset; - typMark[ty] = mark; + } + size_t mark = typMark.size(); + typMark[ty] = mark; + + if (canUseTypename && !ty->IsNameIsLocal() && ty->GetNameStrIdx() != GStrIdx(0)) { + WriteNum(kBinKindTypeViaTypename); + OutputStr(ty->GetNameStrIdx()); + return; } auto func = CreateProductFunction(ty->GetKind()); if (func != nullptr) { - func(*ty, *this); + func(*ty, *this, canUseTypename); } else { ASSERT(false, "Type's kind not yet implemented: %d", ty->GetKind()); } diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 0b554d3c16fa024e76c141f4e5f612e0f7d4988f..a43763f636f4178cb6df9dcee74ad7dbd1efe0d9 100755 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -17,7 +17,7 @@ #include #include #include -#include "bin_mpl_export.h" +#include "bin_mplt.h" #include "mir_function.h" #include "namemangler.h" #include "opcode_info.h" @@ -61,13 +61,11 @@ int64 BinaryMplImport::ReadNum() { } void BinaryMplImport::ReadAsciiStr(std::string &str) { - uint8 ch = Read(); - std::ostringstream strStream(str); - while (ch != '\0') { - strStream << ch; - ch = Read(); + int64 n = ReadNum(); + for (int64 i = 0; i < n; i++) { + uint8 ch = Read(); + str.push_back(static_cast(ch)); } - str = strStream.str(); } void BinaryMplImport::ReadFileAt(const std::string &name, int32 offset) { @@ -112,29 +110,39 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { uint32 fieldID; MemPool *memPool = (func == nullptr) ? mod.GetMemPool() : func->GetCodeMempool(); + ImportConstBase(kind, type, fieldID); switch (tag) { case kBinKindConstInt: - ImportConstBase(kind, type, fieldID); return GlobalTables::GetIntConstTable().GetOrCreateIntConst(ReadNum(), *type, fieldID); case kBinKindConstAddrof: { - ImportConstBase(kind, type, fieldID); MIRSymbol *sym = InSymbol(func); CHECK_FATAL(sym != nullptr, "null ptr check"); FieldID fi = ReadNum(); - return memPool->New(sym->GetStIdx(), fi, *type); + int32 ofst = ReadNum(); + return memPool->New(sym->GetStIdx(), fi, *type, ofst, fieldID); + } + case kBinKindConstAddrofLocal: { + uint32 fullidx = ReadNum(); + FieldID fi = ReadNum(); + int32 ofst = ReadNum(); + return memPool->New(StIdx(fullidx), fi, *type, ofst, fieldID); } case kBinKindConstAddrofFunc: { - ImportConstBase(kind, type, fieldID); PUIdx puIdx = ImportFunction(); return memPool->New(puIdx, *type, fieldID); } + case kBinKindConstAddrofLabel: { + LabelIdx lidx = ReadNum(); + PUIdx puIdx = func->GetPuidx(); + MIRLblConst *lblConst = memPool->New(lidx, puIdx, *type, fieldID); + func->GetLabelTab()->addrTakenLabels.insert(lidx); + return lblConst; + } case kBinKindConstStr: { - ImportConstBase(kind, type, fieldID); UStrIdx ustr = ImportUsrStr(); return memPool->New(ustr, *type, fieldID); } case kBinKindConstStr16: { - ImportConstBase(kind, type, fieldID); Conststr16Node *cs; cs = memPool->New(); cs->SetPrimType(type->GetPrimType()); @@ -146,7 +154,7 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { std::u16string str16; (void)namemangler::UTF8ToUTF16(str16, ostr.str()); cs->SetStrIdx(GlobalTables::GetU16StrTable().GetOrCreateStrIdxFromName(str16)); - return memPool->New(cs->GetStrIdx(), *type); + return memPool->New(cs->GetStrIdx(), *type, fieldID); } case kBinKindConstFloat: { union { @@ -167,8 +175,7 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { return GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(value.dvalue); } case kBinKindConstAgg: { - ImportConstBase(kind, type, fieldID); - MIRAggConst *aggConst = mod.GetMemPool()->New(mod, *type); + MIRAggConst *aggConst = mod.GetMemPool()->New(mod, *type, fieldID); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { aggConst->PushBack(ImportConst(func)); @@ -176,8 +183,7 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { return aggConst; } case kBinKindConstSt: { - ImportConstBase(kind, type, fieldID); - MIRStConst *stConst = mod.GetMemPool()->New(mod, *type); + MIRStConst *stConst = mod.GetMemPool()->New(mod, *type, fieldID); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { stConst->PushbackSymbolToSt(InSymbol(func)); @@ -324,6 +330,13 @@ void BinaryMplImport::UpdateMethodSymbols() { auto *funcType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx())); fn->SetMIRFuncType(funcType); fn->SetReturnStruct(*GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx())); + if (fn->GetFormalDefVec().size() != 0) { + continue; // already updated in ImportFunction() + } + for (size_t i = 0; i < funcType->GetParamTypeList().size(); i++ ) { + FormalDef formalDef(nullptr, funcType->GetParamTypeList()[i], funcType->GetParamAttrsList()[i]); + fn->GetFormalDefVec().push_back(formalDef); + } } } @@ -458,7 +471,7 @@ void BinaryMplImport::Reset() { uStrTab.push_back(UStrIdx(0)); // Dummy symTab.push_back(nullptr); // Dummy funcTab.push_back(nullptr); // Dummy - for (int32 pti = 0; pti <= static_cast(PTY_agg); ++pti) { + for (int32 pti = static_cast(PTY_begin); pti < static_cast(PTY_end); ++pti) { typTab.push_back(GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(pti))); } } @@ -470,13 +483,13 @@ TypeAttrs BinaryMplImport::ImportTypeAttrs() { return ta; } -void BinaryMplImport::ImportTypePairs(MIRInstantVectorType &insVecType) { +void BinaryMplImport::ImportTypePairs(std::vector &tpairs) { int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { TyIdx t0 = ImportType(); TyIdx t1 = ImportType(); TypePair tp(t0, t1); - insVecType.AddInstant(tp); + tpairs.push_back(tp); } } @@ -500,11 +513,7 @@ void BinaryMplImport::CompleteAggInfo(TyIdx tyIdx) { } TyIdx BinaryMplImport::ImportType(bool forPointedType) { - PrimType primType = (PrimType)0; - GStrIdx strIdx(0); int64 tag = ReadNum(); - static MIRType *typeNeedsComplete = nullptr; - static int ptrLev = 0; if (tag == 0) { return TyIdx(0); } @@ -512,6 +521,24 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { CHECK_FATAL(static_cast(-tag) < typTab.size(), "index out of bounds"); return typTab.at(-tag)->GetTypeIndex(); } + if (tag == kBinKindTypeViaTypename) { + GStrIdx typenameStrIdx = ImportStr(); + TyIdx tyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(typenameStrIdx); + if (tyIdx != 0) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); + typTab.push_back(ty); + return tyIdx; + } + MIRTypeByName ltype(typenameStrIdx); + ltype.SetNameIsLocal(false); + MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); + typTab.push_back(type); + return type->GetTypeIndex(); + } + static MIRType *typeNeedsComplete = nullptr; + static int ptrLev = 0; + PrimType primType = (PrimType)0; + GStrIdx strIdx(0); bool nameIsLocal = false; ImportTypeBase(primType, strIdx, nameIsLocal); @@ -519,162 +546,176 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { case kBinKindTypeScalar: return TyIdx(primType); case kBinKindTypePointer: { - MIRPtrType type(primType, strIdx); - type.SetNameIsLocal(nameIsLocal); + MIRPtrType *type = new MIRPtrType(primType, strIdx); + type->SetPrimType(mod.IsJavaModule() ? PTY_ref : PTY_ptr); + type->SetNameIsLocal(nameIsLocal); size_t idx = typTab.size(); typTab.push_back(nullptr); ++ptrLev; - type.SetPointedTyIdx(ImportType(true)); + type->SetPointedTyIdx(ImportType(true)); --ptrLev; - MIRType *origType = &InsertInTypeTables(type); - typTab[idx] = origType; + type->SetTypeAttrs(ImportTypeAttrs()); + type = static_cast(&InsertInTypeTables(*type)); + typTab[idx] = type; if (typeNeedsComplete != nullptr && ptrLev == 0) { TyIdx tyIdxNeedsComplete = typeNeedsComplete->GetTypeIndex(); typeNeedsComplete = nullptr; CompleteAggInfo(tyIdxNeedsComplete); } - return origType->GetTypeIndex(); + return type->GetTypeIndex(); } case kBinKindTypeByName: { - MIRTypeByName type(strIdx); - type.SetNameIsLocal(nameIsLocal); - MIRType *origType = &InsertInTypeTables(type); - typTab.push_back(origType); - return origType->GetTypeIndex(); + MIRTypeByName ltype(strIdx); + ltype.SetPrimType(primType); + ltype.SetNameIsLocal(nameIsLocal); + MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); + typTab.push_back(type); + return type->GetTypeIndex(); } case kBinKindTypeFArray: { - MIRFarrayType type(strIdx); - type.SetNameIsLocal(nameIsLocal); + MIRFarrayType *type = new MIRFarrayType(strIdx); + type->SetPrimType(primType); + type->SetNameIsLocal(nameIsLocal); size_t idx = typTab.size(); typTab.push_back(nullptr); - type.SetElemtTyIdx(ImportType(forPointedType)); - MIRType *origType = &InsertInTypeTables(type); - typTab[idx] = origType; - return origType->GetTypeIndex(); + type->SetElemtTyIdx(ImportType(forPointedType)); + type = static_cast(&InsertInTypeTables(*type)); + typTab[idx] = type; + return type->GetTypeIndex(); } case kBinKindTypeJarray: { - MIRJarrayType type(strIdx); - type.SetNameIsLocal(nameIsLocal); + MIRJarrayType *type = new MIRJarrayType(strIdx); + type->SetPrimType(primType); + type->SetNameIsLocal(nameIsLocal); size_t idx = typTab.size(); typTab.push_back(nullptr); - type.SetElemtTyIdx(ImportType(forPointedType)); - MIRType *origType = &InsertInTypeTables(type); - typTab[idx] = origType; - return origType->GetTypeIndex(); + type->SetElemtTyIdx(ImportType(forPointedType)); + type = static_cast(&InsertInTypeTables(*type)); + typTab[idx] = type; + return type->GetTypeIndex(); } case kBinKindTypeArray: { - MIRArrayType type(strIdx); - type.SetNameIsLocal(nameIsLocal); - type.SetDim(ReadNum()); - CHECK_FATAL(type.GetDim() < kMaxArrayDim, "array index out of range"); - for (uint16 i = 0; i < type.GetDim(); ++i) { - type.SetSizeArrayItem(i, ReadNum()); + MIRArrayType *type = new MIRArrayType(strIdx); + type->SetPrimType(primType); + type->SetNameIsLocal(nameIsLocal); + type->SetDim(ReadNum()); + for (uint16 i = 0; i < type->GetDim(); ++i) { + type->SetSizeArrayItem(i, ReadNum()); } size_t idx = typTab.size(); typTab.push_back(nullptr); - type.SetElemTyIdx(ImportType(forPointedType)); - MIRType *origType = &InsertInTypeTables(type); - typTab[idx] = origType; - return origType->GetTypeIndex(); + type->SetElemTyIdx(ImportType(forPointedType)); + type->SetTypeAttrs(ImportTypeAttrs()); + type = static_cast(&InsertInTypeTables(*type)); + typTab[idx] = type; + return type->GetTypeIndex(); } case kBinKindTypeFunction: { - MIRFuncType type(strIdx, mod.GetMPAllocator()); - type.SetNameIsLocal(nameIsLocal); + MIRFuncType *type = new MIRFuncType(strIdx, mod.GetMPAllocator()); + type->SetPrimType(primType); + type->SetNameIsLocal(nameIsLocal); size_t idx = typTab.size(); typTab.push_back(nullptr); - type.SetRetTyIdx(ImportType()); - type.SetVarArgs(ReadNum()); + type->SetRetTyIdx(ImportType()); + type->SetVarArgs(ReadNum()); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { - type.GetParamTypeList().push_back(ImportType()); + type->GetParamTypeList().push_back(ImportType()); } size = ReadNum(); for (int64 i = 0; i < size; ++i) { - type.GetParamAttrsList().push_back(ImportTypeAttrs()); + type->GetParamAttrsList().push_back(ImportTypeAttrs()); } - MIRType *origType = &InsertInTypeTables(type); - typTab[idx] = origType; - return origType->GetTypeIndex(); + type = static_cast(&InsertInTypeTables(*type)); + typTab[idx] = type; + return type->GetTypeIndex(); } case kBinKindTypeParam: { - MIRTypeParam type(strIdx); - type.SetNameIsLocal(nameIsLocal); - MIRType *origType = &InsertInTypeTables(type); - typTab.push_back(origType); - return origType->GetTypeIndex(); + MIRTypeParam ltype(strIdx); + ltype.SetPrimType(primType); + ltype.SetNameIsLocal(nameIsLocal); + MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); + typTab.push_back(type); + return type->GetTypeIndex(); } case kBinKindTypeInstantVector: { - auto kind = static_cast(ReadNum()); - MIRInstantVectorType type(kind, strIdx); - type.SetNameIsLocal(nameIsLocal); - auto *origType = static_cast(&InsertInTypeTables(type)); - typTab.push_back(origType); - ImportTypePairs(*origType); - return origType->GetTypeIndex(); + MIRTypeKind kind = static_cast(ReadNum()); + MIRInstantVectorType *type = new MIRInstantVectorType(kind, strIdx); + type->SetPrimType(primType); + type->SetNameIsLocal(nameIsLocal); + type = static_cast(&InsertInTypeTables(*type)); + typTab.push_back(type); + ImportTypePairs(type->GetInstantVec()); + return type->GetTypeIndex(); } case kBinKindTypeGenericInstant: { - MIRGenericInstantType type(strIdx); - type.SetNameIsLocal(nameIsLocal); - auto *origType = static_cast(&InsertInTypeTables(type)); - typTab.push_back(origType); - ImportTypePairs(*origType); - origType->SetGenericTyIdx(ImportType()); - return origType->GetTypeIndex(); + MIRGenericInstantType *type = new MIRGenericInstantType(strIdx); + type->SetPrimType(primType); + type->SetNameIsLocal(nameIsLocal); + ImportTypePairs(type->GetInstantVec()); + type = static_cast(&InsertInTypeTables(*type)); + typTab.push_back(type); + type->SetGenericTyIdx(ImportType()); + return type->GetTypeIndex(); } case kBinKindTypeBitField: { uint8 fieldSize = ReadNum(); - MIRBitFieldType type(fieldSize, primType, strIdx); - type.SetNameIsLocal(nameIsLocal); - MIRType *origType = &InsertInTypeTables(type); - typTab.push_back(origType); - return origType->GetTypeIndex(); + MIRBitFieldType ltype(fieldSize, primType, strIdx); + ltype.SetPrimType(primType); + ltype.SetNameIsLocal(nameIsLocal); + MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); + typTab.push_back(type); + return type->GetTypeIndex(); } case kBinKindTypeStruct: { auto kind = static_cast(ReadNum()); - MIRStructType type(kind, strIdx); - type.SetNameIsLocal(nameIsLocal); - auto &origType = static_cast(InsertInTypeTables(type)); - typTab.push_back(&origType); + MIRStructType *type = new MIRStructType(kind, strIdx); + if (mod.GetSrcLang() == kSrcLangCPlusPlus) { + type->SetIsCPlusPlus(true); + } + type->SetNameIsLocal(nameIsLocal); + type = static_cast(&InsertInTypeTables(*type)); + typTab.push_back(type); if (kind != kTypeStructIncomplete) { if (forPointedType) { - typeNeedsComplete = &origType; + typeNeedsComplete = type; } else { - ImportStructTypeData(origType); + ImportStructTypeData(*type); } } - return origType.GetTypeIndex(); + return type->GetTypeIndex(); } case kBinKindTypeClass: { auto kind = static_cast(ReadNum()); - MIRClassType type(kind, strIdx); - type.SetNameIsLocal(nameIsLocal); - auto &origType = static_cast(InsertInTypeTables(type)); - typTab.push_back(&origType); + MIRClassType *type = new MIRClassType(kind, strIdx); + type->SetNameIsLocal(nameIsLocal); + type = static_cast(&InsertInTypeTables(*type)); + typTab.push_back(type); if (kind != kTypeClassIncomplete) { if (forPointedType) { - typeNeedsComplete = &origType; + typeNeedsComplete = type; } else { - ImportStructTypeData(origType); - ImportClassTypeData(origType); + ImportStructTypeData(*type); + ImportClassTypeData(*type); } } - return origType.GetTypeIndex(); + return type->GetTypeIndex(); } case kBinKindTypeInterface: { - auto kind = static_cast(ReadNum()); - MIRInterfaceType type(kind, strIdx); - type.SetNameIsLocal(nameIsLocal); - auto &origType = static_cast(InsertInTypeTables(type)); - typTab.push_back(&origType); + MIRTypeKind kind = static_cast(ReadNum()); + MIRInterfaceType *type = new MIRInterfaceType(kind, strIdx); + type->SetNameIsLocal(nameIsLocal); + type = static_cast(&InsertInTypeTables(*type)); + typTab.push_back(type); if (kind != kTypeInterfaceIncomplete) { if (forPointedType) { - typeNeedsComplete = &origType; + typeNeedsComplete = type; } else { - ImportStructTypeData(origType); - ImportInterfaceTypeData(origType); + ImportStructTypeData(*type); + ImportInterfaceTypeData(*type); } } - return origType.GetTypeIndex(); + return type->GetTypeIndex(); } default: CHECK_FATAL(false, "Unexpected binary kind"); @@ -716,8 +757,8 @@ MIRType &BinaryMplImport::InsertInTypeTables(MIRType &type) { // New definition wins type.SetTypeIndex(prevTyIdx); CHECK_FATAL(GlobalTables::GetTypeTable().GetTypeTable().empty() == false, "container check"); - GlobalTables::GetTypeTable().SetTypeWithTyIdx(prevTyIdx, *type.CopyMIRTypeNode()); - resultTypePtr = GlobalTables::GetTypeTable().GetTypeFromTyIdx(prevTyIdx); + GlobalTables::GetTypeTable().SetTypeWithTyIdx(prevTyIdx, type); + resultTypePtr = &type; if (!IsIncomplete(*resultTypePtr)) { GlobalTables::GetTypeNameTable().SetGStrIdxToTyIdx(resultTypePtr->GetNameStrIdx(), resultTypePtr->GetTypeIndex()); @@ -728,16 +769,14 @@ MIRType &BinaryMplImport::InsertInTypeTables(MIRType &type) { TyIdx tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&type); resultTypePtr = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); if (tyIdx + 1 == GlobalTables::GetTypeTable().GetTypeTable().size() && !resultTypePtr->IsNameIsLocal()) { - GStrIdx stridx = resultTypePtr->GetNameStrIdx(); - if (IsObject(*resultTypePtr)) { - mod.GetTypeNameTab()->SetGStrIdxToTyIdx(stridx, tyIdx); - mod.AddClass(tyIdx); - mod.PushbackTypeDefOrder(stridx); - if (!IsIncomplete(*resultTypePtr)) { - GlobalTables::GetTypeNameTable().SetGStrIdxToTyIdx(stridx, tyIdx); + GStrIdx strIdx = resultTypePtr->GetNameStrIdx(); + if (!resultTypePtr->IsNameIsLocal() && strIdx != 0) { + mod.GetTypeNameTab()->SetGStrIdxToTyIdx(strIdx, tyIdx); + mod.PushbackTypeDefOrder(strIdx); + GlobalTables::GetTypeNameTable().SetGStrIdxToTyIdx(strIdx, tyIdx); + if (IsObject(*resultTypePtr)) { + mod.AddClass(tyIdx); } - } else if (resultTypePtr->GetKind() == kTypeByName) { - mod.GetTypeNameTab()->SetGStrIdxToTyIdx(stridx, tyIdx); } } } @@ -785,15 +824,30 @@ MIRSymbol *BinaryMplImport::InSymbol(MIRFunction *func) { sym->SetAttrs(ImportTypeAttrs()); sym->SetIsTmp(ReadNum() != 0); sym->SetIsImported(imported); + uint32 thepregno = 0; if (skind == kStPreg) { - CHECK_FATAL(false, "outing kStPreg"); + CHECK_FATAL(scope == kScopeLocal && func != nullptr, "Expecting kScopeLocal"); + thepregno = ReadNum(); } else if (skind == kStConst || skind == kStVar) { - CHECK_FATAL(false, "outing kStConst or kStVar"); + sym->SetKonst(ImportConst(func)); } else if (skind == kStFunc) { PUIdx puidx = ImportFunction(); - TyIdx tyidx = ImportType(); - sym->SetTyIdx(tyidx); - sym->SetFunction(GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puidx)); + if (puidx != 0) { + sym->SetFunction(GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puidx)); + } + } + if (skind == kStVar || skind == kStFunc) { + ImportSrcPos(sym->GetSrcPosition()); + } + TyIdx tyIdx = ImportType(); + sym->SetTyIdx(tyIdx); + if (skind == kStPreg) { + MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); + PregIdx pregidx = func->GetPregTab()->EnterPregNo(thepregno, mirType->GetPrimType(), mirType); + MIRPregTable *pregTab = func->GetPregTab(); + MIRPreg *preg = pregTab->PregFromPregIdx(pregidx); + preg->SetPrimType(mirType->GetPrimType()); + sym->SetPreg(preg); } return sym; } @@ -802,10 +856,16 @@ MIRSymbol *BinaryMplImport::InSymbol(MIRFunction *func) { PUIdx BinaryMplImport::ImportFunction() { int64 tag = ReadNum(); if (tag == 0) { + mod.SetCurFunction(nullptr); return 0; } else if (tag < 0) { CHECK_FATAL(static_cast(-tag) < funcTab.size(), "index out of bounds"); - return funcTab.at(-tag)->GetPuidx(); + if (-tag == funcTab.size()) { // function was exported before its symbol + return (PUIdx)0; + } + PUIdx puIdx = funcTab[-tag]->GetPuidx(); + mod.SetCurFunction(GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx)); + return puIdx; } CHECK_FATAL(tag == kBinFunction, "expecting kBinFunction"); MIRSymbol *funcSt = InSymbol(nullptr); @@ -820,16 +880,37 @@ PUIdx BinaryMplImport::ImportFunction() { funcTab.push_back(func); } funcSt->SetFunction(func); + methodSymbols.push_back(funcSt); if (mod.IsJavaModule()) { func->SetBaseClassFuncNames(funcSt->GetNameStrIdx()); } - TyIdx retType = ImportType(); - func->SetReturnTyIdx(retType); + TyIdx funcTyIdx = ImportType(); + func->SetMIRFuncType(static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcTyIdx))); func->SetStIdx(funcSt->GetStIdx()); func->SetFuncAttrs(ReadNum()); func->SetFlag(ReadNum()); - func->SetClassTyIdx(ImportType()); + /*func->SetClassTyIdx(*/ImportType(); // not set the field to mimic parser + // import formal parameter informcation + size_t size = ReadNum(); + if (func->GetFormalDefVec().size() == 0) { + for (size_t i = 0; i < size; i++) { + GStrIdx strIdx = ImportStr(); + TyIdx tyIdx = ImportType(); + FormalDef formalDef(strIdx, nullptr, tyIdx, TypeAttrs()); + formalDef.formalAttrs.SetAttrFlag(ReadNum()); + func->GetFormalDefVec().push_back(formalDef); + } + } else { + CHECK_FATAL(func->GetFormalDefVec().size() >= size, "ImportFunction: inconsistent number of formals"); + for (size_t i = 0; i < size; i++) { + func->GetFormalDefVec()[i].formalStrIdx = ImportStr(); + func->GetFormalDefVec()[i].formalTyIdx = ImportType(); + func->GetFormalDefVec()[i].formalAttrs.SetAttrFlag(ReadNum()); + } + } + + mod.SetCurFunction(func); return func->GetPuidx(); } @@ -850,6 +931,49 @@ void BinaryMplImport::ReadStrField() { CHECK_FATAL(tag == ~kBinStrStart, "pattern mismatch in Read STR"); } +void BinaryMplImport::ReadHeaderField() { + SkipTotalSize(); + mod.SetFlavor((MIRFlavor)ReadNum()); + mod.SetSrcLang((MIRSrcLang)ReadNum()); + mod.SetID(ReadNum()); + mod.SetNumFuncs(ReadNum()); + ReadAsciiStr(mod.GetEntryFuncName()); + ImportInfoVector(mod.GetFileInfo(), mod.GetFileInfoIsString()); + + int32 size = ReadNum(); + MIRInfoPair infopair; + for (int32 i = 0; i < size; i++) { + infopair.first = ImportStr(); + infopair.second = ReadNum(); + mod.PushbackFileInfo(infopair); + } + + size = ReadNum(); + for (int32 i = 0; i < size; i++) { + GStrIdx gStrIdx = ImportStr(); + mod.GetImportFiles().push_back(gStrIdx); + std::string importfilename = GlobalTables::GetStrTable().GetStringFromStrIdx(gStrIdx); + // record the imported file for later reading summary info, if exists + mod.GetImportedMplt().push_back(importfilename); + BinaryMplt *binMplt = new BinaryMplt(mod); + binMplt->GetBinImport().imported = true; + + INFO(kLncInfo, "importing %s", importfilename.c_str()); + if (!binMplt->GetBinImport().Import(importfilename, false)) { // not a binary mplt + FATAL(kLncFatal, "cannot open binary MPLT file: %s\n", importfilename.c_str()); + } else { + INFO(kLncInfo, "finished import of %s", importfilename.c_str()); + } + if (i == 0) { + binMplt->SetImportFileName(importfilename); + mod.SetBinMplt(binMplt); + } + } + int32 tag = ReadNum(); + CHECK_FATAL(tag == ~kBinHeaderStart, "pattern mismatch in Read Import"); + return; +} + void BinaryMplImport::ReadTypeField() { SkipTotalSize(); @@ -862,6 +986,29 @@ void BinaryMplImport::ReadTypeField() { CHECK_FATAL(tag == ~kBinTypeStart, "pattern mismatch in Read TYPE"); } +void BinaryMplImport::ReadSymField() { + SkipTotalSize(); + int32 size = ReadInt(); + for (int64 i = 0; i < size; i++) { + InSymbol(nullptr); + } + int64 tag = ReadNum(); + CHECK_FATAL(tag == ~kBinSymStart, "pattern mismatch in Read SYM"); + return; +} + +void BinaryMplImport::ReadSymTabField() { + SkipTotalSize(); + int32 size = ReadInt(); + for (int64 i = 0; i < size; i++) { + std::string str; + ReadAsciiStr(str); + } + int64 tag = ReadNum(); + CHECK_FATAL(tag == ~kBinSymTabStart, "pattern mismatch in Read TYPE"); + return; +} + void BinaryMplImport::ReadContentField() { SkipTotalSize(); @@ -886,10 +1033,11 @@ bool BinaryMplImport::Import(const std::string &fname, bool readSymbols, bool re Reset(); ReadFileAt(fname, 0); int32 magic = ReadInt(); - if (kMpltMagicNumber != magic) { // not a binary mplt file + if (kMpltMagicNumber != magic && (kMpltMagicNumber+0x10) != magic) { buf.clear(); return false; } + importingFromMplt = kMpltMagicNumber == magic; int64 fieldID = ReadNum(); while (fieldID != kBinFinish) { switch (fieldID) { @@ -901,14 +1049,34 @@ bool BinaryMplImport::Import(const std::string &fname, bool readSymbols, bool re ReadStrField(); break; } + case kBinHeaderStart: { + ReadHeaderField(); + break; + } case kBinTypeStart: { ReadTypeField(); break; } + case kBinSymStart: { + if (readSymbols) { + ReadSymField(); + } else { + Jump2NextField(); + } + break; + } + case kBinSymTabStart: { + ReadSymTabField(); + break; + } case kBinCgStart: { Jump2NextField(); break; } + case kBinFunctionBodyStart: { + ReadFunctionBodyField(); + break; + } default: CHECK_FATAL(false, "should not run here"); } diff --git a/src/mapleall/maple_ir/src/driver.cpp b/src/mapleall/maple_ir/src/driver.cpp index dcb2978ea4edf3a1bf5cf36e266c9ddc96cf79f3..7cc9a1af47da82da36901f703f3c39d357cd7b26 100644 --- a/src/mapleall/maple_ir/src/driver.cpp +++ b/src/mapleall/maple_ir/src/driver.cpp @@ -22,69 +22,90 @@ #include "mir_type.h" using namespace maple; + +std::unordered_set dumpFuncSet = {}; + #if MIR_FEATURE_FULL -void ConstantFoldModule(MIRModule &module) { - MapleVector &funcList = module.GetFunctionList(); - for (auto it = funcList.begin(); it != funcList.end(); ++it) { - MIRFunction *curFunc = *it; - module.SetCurFunction(curFunc); - } -} -// hello.mpl -// flavor 1 -// srclang 3 -// type $person }> -// var $BOB i32 = 8 int main(int argc, char **argv) { constexpr int judgeNumber = 2; if (argc < judgeNumber) { (void)MIR_PRINTF( - "usage: ./irbuild [i|e] \n\n" - "The optional 'i' flag will convert the binary mplt input file to ascii\n\n" - "The optional 'e' flag will convert the textual mplt input file to binary\n"); + "usage: ./irbuild [-b] [-dumpfunc=] [-srclang=] \n" + " By default, the files are converted to corresponding ascii format.\n" + " If -b is specified, output is binary format instead.\n" +// " If -fold is specified, constant folding is performed before outputing the IR.\n" + " If -dumpfunc= is specified, only functions with name containing the string is output.\n" + " -dumpfunc= can be specified multiple times to give multiple strings.\n" + " -srclang specifies the source language that produces the mpl file. \n" + " Each output file has .irb added after its file stem.\n"); exit(1); } - char flag = '\0'; - int32 i = 1; - if (argv[1][0] == 'i' && argv[1][1] == '\0') { - flag = 'i'; - i = judgeNumber; - } else if (argv[1][0] == 'e' && argv[1][1] == '\0') { - flag = 'e'; - i = judgeNumber; + std::vector themodule(argc, nullptr); + bool useBinary = false; + bool doConstantFold = false; + MIRSrcLang srcLang = kSrcLangUnknown; + // process the options which must come first + maple::int32 i = 1; + while (argv[i][0] == '-' ) { + if (argv[i][1] == 'b' && argv[i][2] == '\0') { + useBinary = true; + } else if (strcmp(argv[i], "-fold") == 0) { + doConstantFold = true; + } else if (strncmp(argv[i], "-dumpfunc=", 10) == 0 && strlen(argv[i]) > 10) { + std::string funcName(&argv[i][10]); + dumpFuncSet.insert(funcName); + } else if (strcmp(argv[i], "-srclang=java") == 0 ) { + srcLang = kSrcLangJava; + } else if (strcmp(argv[i], "-srclang=c") == 0 ) { + srcLang = kSrcLangC; + } else if (strcmp(argv[i], "-srclang=c++") == 0 ) { + srcLang = kSrcLangCPlusPlus; + } else { + ERR(kLncErr, "irbuild: unrecognized command line option"); + return 1; + } + i++; } + // process the input files while (i < argc) { - MIRModule module{ argv[i] }; - if (flag == '\0') { - MIRParser theParser(module); - if (theParser.ParseMIR()) { - ConstantFoldModule(module); - module.OutputAsciiMpl(".irb"); - } else { - theParser.EmitError(module.GetFileName()); + themodule[i] = new maple::MIRModule(argv[i]); + themodule[i]->SetSrcLang(srcLang); + std::string::size_type lastdot = themodule[i]->GetFileName().find_last_of("."); + bool ismplt = themodule[i]->GetFileName().compare(lastdot, 5, ".mplt") == 0; + bool istmpl = themodule[i]->GetFileName().compare(lastdot, 5, ".tmpl") == 0; + bool ismpl = themodule[i]->GetFileName().compare(lastdot, 5, ".mpl\0") == 0; + bool isbpl = themodule[i]->GetFileName().compare(lastdot, 5, ".bpl\0") == 0; + if (!ismplt && !istmpl && !ismpl && !isbpl) { + ERR(kLncErr, "irbuild: input must be .mplt or .mpl or .bpl or .tmpl file"); + return 1; + } + // input the file + if (ismpl || istmpl) { + maple::MIRParser theparser(*themodule[i]); + if (!theparser.ParseMIR()) { + theparser.EmitError(themodule[i]->GetFileName().c_str()); return 1; } - } else if (flag == 'e') { - MIRParser theParser(module); - if (theParser.ParseMIR()) { - ConstantFoldModule(module); - BinaryMplt binMplt(module); - const std::string &modID = module.GetFileName(); - binMplt.Export("bin." + modID); - } else { - theParser.EmitError(module.GetFileName()); + } else { + BinaryMplImport binMplt(*themodule[i]); + binMplt.SetImported(false); + std::string modid = themodule[i]->GetFileName(); + if (!binMplt.Import(modid, true)) { + ERR(kLncErr, "irbuild: cannot open .mplt or .bpl file: %s", modid.c_str()); return 1; } - } else if (flag == 'i') { - module.SetFlavor(kFeProduced); - module.SetSrcLang(kSrcLangJava); - BinaryMplImport binMplt(module); - binMplt.SetImported(false); - const std::string &modID = module.GetFileName(); - (void)binMplt.Import(modID, true); - module.OutputAsciiMpl(".irb"); + } + + // output the file + if (!useBinary) { + themodule[i]->OutputAsciiMpl(".irb", (ismpl || isbpl) ? ".mpl" : ".tmpl", &dumpFuncSet, true, false); + } else { + BinaryMplt binMplt(*themodule[i]); + std::string modid = themodule[i]->GetFileName(); + binMplt.GetBinExport().not2mplt = ismpl || isbpl; + std::string filestem = modid.substr(0, lastdot); + binMplt.Export(filestem + ((ismpl || isbpl) ? ".irb.bpl" : ".irb.mplt"), &dumpFuncSet); } ++i; } diff --git a/src/mapleall/maple_ir/src/global_tables.cpp b/src/mapleall/maple_ir/src/global_tables.cpp index f24c65c6b1d6572baa3b9669d3dec53fc17ce847..e37e5369312681387ef3914fbdd3d2e78877aef9 100755 --- a/src/mapleall/maple_ir/src/global_tables.cpp +++ b/src/mapleall/maple_ir/src/global_tables.cpp @@ -31,12 +31,14 @@ TypeTable::TypeTable() { // enter the primitve types in type_table_ typeTable.push_back(static_cast(nullptr)); ASSERT(typeTable.size() == static_cast(PTY_void), "use PTY_void as the first index to type table"); - for (auto primTypeIdx = static_cast(PTY_void); primTypeIdx <= static_cast(PTY_agg); ++primTypeIdx) { + uint32 primTypeIdx; + for (primTypeIdx = static_cast(PTY_begin)+1; primTypeIdx <= static_cast(PTY_end); ++primTypeIdx) { MIRType *type = CreateMirType(primTypeIdx); type->SetTypeIndex(TyIdx{ primTypeIdx }); typeTable.push_back(type); PutToHashTable(type); } + lastDefaultTyIdx.SetIdx(primTypeIdx); if (voidPtrType == nullptr) { voidPtrType = GetOrCreatePointerType(*GetVoid(), PTY_ptr); } @@ -48,7 +50,9 @@ void TypeTable::SetTypeWithTyIdx(const TyIdx &tyIdx, MIRType &type) { typeTable.at(tyIdx) = &type; if (oldType != nullptr && oldType != &type) { (void)typeHashTable.erase(oldType); +#if 0 // cannot delete because typTab in BinaryMplImport is still pointing to it delete oldType; +#endif } } diff --git a/src/mapleall/maple_ir/src/mir_module.cpp b/src/mapleall/maple_ir/src/mir_module.cpp index fb3f815f6fc1fa4dba9577b35a5ff46b94324e07..24819687a766b4caa83546cf78a4c391b6206cde 100644 --- a/src/mapleall/maple_ir/src/mir_module.cpp +++ b/src/mapleall/maple_ir/src/mir_module.cpp @@ -12,7 +12,6 @@ * FIT FOR A PARTICULAR PURPOSE. * See the Mulan PSL v2 for more details. */ -#include "mir_module.h" #include #include #include @@ -20,6 +19,7 @@ #include #include #include "mir_const.h" +#include "mir_module.h" #include "mir_preg.h" #include "mir_function.h" #include "mir_builder.h" @@ -273,9 +273,10 @@ void MIRModule::DumpGlobals(bool emitStructureType) const { } } -void MIRModule::Dump(bool emitStructureType) const { +void MIRModule::Dump(bool emitStructureType, + std::unordered_set *dumpFuncSet) const { DumpGlobals(emitStructureType); - DumpFunctionList(); + DumpFunctionList(dumpFuncSet); } void MIRModule::DumpGlobalArraySymbol() const { @@ -304,9 +305,23 @@ void MIRModule::Emit(const std::string &outFileName) const { file.close(); } -void MIRModule::DumpFunctionList(bool skipBody) const { - for (MIRFunction *func : functionList) { - func->Dump(skipBody); +void MIRModule::DumpFunctionList(const std::unordered_set *dumpFuncSet) const { + for (MIRFunction *mirFunc : functionList) { + if (dumpFuncSet == nullptr || dumpFuncSet->empty()) { + mirFunc->Dump(); + } else { // dump only if this func matches any name in *dumpFuncSet + const std::string &name = mirFunc->GetName(); + bool matched = false; + for (std::string elem : *dumpFuncSet) { + if (name.find(elem.c_str()) != std::string::npos) { + matched = true; + break; + } + } + if (matched) { + mirFunc->Dump(); + } + } } } @@ -329,7 +344,7 @@ void MIRModule::OutputFunctionListAsciiMpl(const std::string &phaseName) { std::streambuf *backup = LogInfo::MapleLogger().rdbuf(); LogInfo::MapleLogger().rdbuf(mplFile.rdbuf()); // change cout's buffer to that of file DumpGlobalArraySymbol(); - DumpFunctionList(); + DumpFunctionList(nullptr); LogInfo::MapleLogger().rdbuf(backup); // restore cout's buffer mplFile.close(); } @@ -462,9 +477,12 @@ MIRFunction *MIRModule::FindEntryFunction() { } // given the phase name (including '.' at beginning), output the program in the -// module in ascii form to the file with either .mpl or .mmpl suffix, and file -// stem from this->fileName appended with phasename -void MIRModule::OutputAsciiMpl(const std::string &phaseName, bool emitStructureType) { +// module to the file with given file suffix, and file stem from +// this->fileName appended with phaseName +void MIRModule::OutputAsciiMpl(const char *phaseName, const char *suffix, + std::unordered_set *dumpFuncSet, + bool emitStructureType, bool binaryform) { + ASSERT(!(emitStructureType && binaryform), "Cannot emit type info in .bpl"); std::string fileStem; std::string::size_type lastDot = fileName.find_last_of('.'); if (lastDot == std::string::npos) { @@ -473,18 +491,20 @@ void MIRModule::OutputAsciiMpl(const std::string &phaseName, bool emitStructureT fileStem = fileName.substr(0, lastDot).append(phaseName); } std::string outfileName; - if (flavor >= kMmpl) { - outfileName = fileStem.append(".mmpl"); + outfileName = fileStem + suffix; + if (!binaryform) { + std::ofstream mplFile; + mplFile.open(outfileName, std::ios::trunc); + std::streambuf *backup = LogInfo::MapleLogger().rdbuf(); + LogInfo::MapleLogger().rdbuf(mplFile.rdbuf()); // change LogInfo::MapleLogger()'s buffer to that of file + Dump(emitStructureType, dumpFuncSet); + LogInfo::MapleLogger().rdbuf(backup); // restore LogInfo::MapleLogger()'s buffer + mplFile.close(); } else { - outfileName = fileStem.append(".mpl"); + BinaryMplt binMplt(*this); + binMplt.GetBinExport().not2mplt = true; + binMplt.Export(outfileName); } - std::ofstream mplFile; - mplFile.open(outfileName, std::ios::trunc); - std::streambuf *backup = LogInfo::MapleLogger().rdbuf(); - LogInfo::MapleLogger().rdbuf(mplFile.rdbuf()); // change cout's buffer to that of file - Dump(emitStructureType); - LogInfo::MapleLogger().rdbuf(backup); // restore cout's buffer - mplFile.close(); } uint32 MIRModule::GetFileinfo(GStrIdx strIdx) const { diff --git a/src/mapleall/maple_ir/src/parser.cpp b/src/mapleall/maple_ir/src/parser.cpp index 332ae41f6ee8f34d464e8b63b4d5d80a4903aacf..6586f298418a67d286b35f4887a805e65ce4a700 100755 --- a/src/mapleall/maple_ir/src/parser.cpp +++ b/src/mapleall/maple_ir/src/parser.cpp @@ -311,6 +311,10 @@ bool MIRParser::ParseArrayType(TyIdx &arrayTyIdx) { } ASSERT(tyIdx != 0u, "something wrong with parsing element type "); MIRArrayType arrayType(tyIdx, vec); + if (!ParseTypeAttrs(arrayType.GetTypeAttrs())) { + Error("bad type attribute in pointer type specification"); + return false; + } arrayTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&arrayType); return true; } @@ -795,21 +799,20 @@ bool MIRParser::ParseStructType(TyIdx &styIdx) { return false; } MIRStructType structType(tkind); + if (mod.GetSrcLang() == kSrcLangCPlusPlus) { + structType.SetIsCPlusPlus(true); + } if (!ParseFields(structType)) { return false; } if (styIdx != 0u) { MIRType *prevType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(styIdx); - if (prevType->GetKind() != kTypeByName) { - ASSERT(prevType->GetKind() == kTypeStruct || prevType->GetKind() == kTypeStructIncomplete, - "type kind should be consistent."); - if (static_cast(prevType)->IsIncomplete() && !(structType.IsIncomplete())) { - structType.SetNameStrIdx(prevType->GetNameStrIdx()); - structType.SetTypeIndex(styIdx); - GlobalTables::GetTypeTable().SetTypeWithTyIdx(styIdx, *structType.CopyMIRTypeNode()); - } - } else { - styIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&structType); + ASSERT(prevType->GetKind() == kTypeStruct || prevType->GetKind() == kTypeStructIncomplete, + "type kind should be consistent."); + if (static_cast(prevType)->IsIncomplete() && !(structType.IsIncomplete())) { + structType.SetNameStrIdx(prevType->GetNameStrIdx()); + structType.SetTypeIndex(styIdx); + GlobalTables::GetTypeTable().SetTypeWithTyIdx(styIdx, *structType.CopyMIRTypeNode()); } } else { styIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&structType); @@ -836,8 +839,6 @@ bool MIRParser::ParseClassType(TyIdx &styidx) { MIRType *prevType = nullptr; if (styidx != 0u) { prevType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(styidx); - } - if (prevType != nullptr && prevType->GetKind() != kTypeByName) { ASSERT(prevType->GetKind() == kTypeClass || prevType->GetKind() == kTypeClassIncomplete, "type kind should be consistent."); if (static_cast(prevType)->IsIncomplete() && !(classType.IsIncomplete())) { @@ -1345,63 +1346,79 @@ bool MIRParser::ParseDerivedType(TyIdx &tyIdx, MIRTypeKind kind) { return true; } -void MIRParser::FixupForwardReferencedTypeByMap() { - for (size_t i = 1; i < GlobalTables::GetTypeTable().GetTypeTable().size(); ++i) { - MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(i)); - if (type->GetKind() == kTypePointer) { - auto *ptrType = static_cast(type); - std::map::iterator it = typeDefIdxMap.find(ptrType->GetPointedTyIdx()); +void MIRParser::FixForwardReferencedTypeForOneAgg(MIRType *type) { + if (type->GetKind() == kTypePointer) { + auto *ptrType = static_cast(type); + std::map::iterator it = typeDefIdxMap.find(ptrType->GetPointedTyIdx()); + if (it != typeDefIdxMap.end()) { + ptrType->SetPointedTyIdx(it->second); + } + } else if (type->GetKind() == kTypeArray) { + MIRArrayType *arrayType = static_cast(type); + std::map::iterator it = typeDefIdxMap.find(arrayType->GetElemTyIdx()); + if (it != typeDefIdxMap.end()) { + arrayType->SetElemTyIdx(it->second); + } + } else if (type->GetKind() == kTypeFArray || type->GetKind() == kTypeJArray) { + MIRFarrayType *arrayType = static_cast(type); + std::map::iterator it = typeDefIdxMap.find(arrayType->GetElemTyIdx()); + if (it != typeDefIdxMap.end()) { + arrayType->SetElemtTyIdx(it->second); + } + } else if (type->GetKind() == kTypeStruct || type->GetKind() == kTypeStructIncomplete || + type->GetKind() == kTypeUnion || type->GetKind() == kTypeClass || + type->GetKind() == kTypeClassIncomplete || type->GetKind() == kTypeInterface || + type->GetKind() == kTypeInterfaceIncomplete) { + if (type->GetKind() == kTypeClass || type->GetKind() == kTypeClassIncomplete) { + auto *classType = static_cast(type); + std::map::iterator it = typeDefIdxMap.find(classType->GetParentTyIdx()); if (it != typeDefIdxMap.end()) { - ptrType->SetPointedTyIdx(it->second); - } - } else if (type->GetKind() == kTypeStruct || type->GetKind() == kTypeStructIncomplete || - type->GetKind() == kTypeUnion || type->GetKind() == kTypeClass || - type->GetKind() == kTypeClassIncomplete || type->GetKind() == kTypeInterface || - type->GetKind() == kTypeInterfaceIncomplete) { - if (type->GetKind() == kTypeClass || type->GetKind() == kTypeClassIncomplete) { - auto *classType = static_cast(type); - std::map::iterator it = typeDefIdxMap.find(classType->GetParentTyIdx()); - if (it != typeDefIdxMap.end()) { - classType->SetParentTyIdx(it->second); - } - for (size_t j = 0; j < classType->GetInterfaceImplemented().size(); ++j) { - std::map::iterator it2 = typeDefIdxMap.find(classType->GetNthInterfaceImplemented(j)); - if (it2 != typeDefIdxMap.end()) { - classType->SetNthInterfaceImplemented(j, it2->second); - } - } - } else if (type->GetKind() == kTypeInterface || type->GetKind() == kTypeInterfaceIncomplete) { - auto *interfaceType = static_cast(type); - for (uint32 j = 0; j < interfaceType->GetParentsTyIdx().size(); ++j) { - std::map::iterator it = typeDefIdxMap.find(interfaceType->GetParentsElementTyIdx(j)); - if (it != typeDefIdxMap.end()) { - interfaceType->SetParentsElementTyIdx(j, it->second); - } - } + classType->SetParentTyIdx(it->second); } - auto *structType = static_cast(type); - for (uint32 j = 0; j < structType->GetFieldsSize(); ++j) { - TyIdx fieldTyIdx = structType->GetElemTyIdx(j); - std::map::iterator it = typeDefIdxMap.find(fieldTyIdx); - if (it != typeDefIdxMap.end()) { - structType->SetElemtTyIdx(j, it->second); + for (size_t j = 0; j < classType->GetInterfaceImplemented().size(); ++j) { + std::map::iterator it2 = typeDefIdxMap.find(classType->GetNthInterfaceImplemented(j)); + if (it2 != typeDefIdxMap.end()) { + classType->SetNthInterfaceImplemented(j, it2->second); } } - for (size_t j = 0; j < structType->GetStaticFields().size(); ++j) { - TyIdx fieldTyIdx = structType->GetStaticElemtTyIdx(j); - std::map::iterator it = typeDefIdxMap.find(fieldTyIdx); + } else if (type->GetKind() == kTypeInterface || type->GetKind() == kTypeInterfaceIncomplete) { + auto *interfaceType = static_cast(type); + for (uint32 j = 0; j < interfaceType->GetParentsTyIdx().size(); ++j) { + std::map::iterator it = typeDefIdxMap.find(interfaceType->GetParentsElementTyIdx(j)); if (it != typeDefIdxMap.end()) { - structType->SetStaticElemtTyIdx(j, it->second); + interfaceType->SetParentsElementTyIdx(j, it->second); } } - for (size_t j = 0; j < structType->GetMethods().size(); ++j) { - TyIdx methodTyIdx = structType->GetMethodsElement(j).second.first; - std::map::iterator it = typeDefIdxMap.find(methodTyIdx); - if (it != typeDefIdxMap.end()) { - structType->SetMethodTyIdx(j, it->second); - } + } + auto *structType = static_cast(type); + for (uint32 j = 0; j < structType->GetFieldsSize(); ++j) { + TyIdx fieldTyIdx = structType->GetElemTyIdx(j); + std::map::iterator it = typeDefIdxMap.find(fieldTyIdx); + if (it != typeDefIdxMap.end()) { + structType->SetElemtTyIdx(j, it->second); } } + for (size_t j = 0; j < structType->GetStaticFields().size(); ++j) { + TyIdx fieldTyIdx = structType->GetStaticElemtTyIdx(j); + std::map::iterator it = typeDefIdxMap.find(fieldTyIdx); + if (it != typeDefIdxMap.end()) { + structType->SetStaticElemtTyIdx(j, it->second); + } + } + for (size_t j = 0; j < structType->GetMethods().size(); ++j) { + TyIdx methodTyIdx = structType->GetMethodsElement(j).second.first; + std::map::iterator it = typeDefIdxMap.find(methodTyIdx); + if (it != typeDefIdxMap.end()) { + structType->SetMethodTyIdx(j, it->second); + } + } + } +} + +void MIRParser::FixupForwardReferencedTypeByMap() { + for (size_t i = 1; i < GlobalTables::GetTypeTable().GetTypeTable().size(); ++i) { + MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(i)); + FixForwardReferencedTypeForOneAgg(type); } } @@ -1433,7 +1450,7 @@ bool MIRParser::ParseTypedef() { if (!mod.IsCModule()) { CHECK_FATAL(prevType->IsStructType(), "type error"); } - prevStructType = static_cast(prevType); + prevStructType = dynamic_cast(prevType); if ((prevType->GetKind() != kTypeByName) && (prevStructType && !prevStructType->IsIncomplete())) { // allow duplicated type def if kKeepFirst is set which is the default if (options & kKeepFirst) { @@ -1458,7 +1475,8 @@ bool MIRParser::ParseTypedef() { prevTyIdx = mod.CurFunction()->GetTyIdxFromGStrIdx(strIdx); if (prevTyIdx != 0u) { MIRType *prevType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(prevTyIdx); - if ((prevType->GetKind() != kTypeByName) && (prevType->IsStructType() && !prevType->IsIncomplete())) { + prevStructType = dynamic_cast(prevType); + if ((prevType->GetKind() != kTypeByName) && (prevStructType && !prevStructType->IsIncomplete())) { Error("redefined local type name "); return false; } @@ -1467,7 +1485,7 @@ bool MIRParser::ParseTypedef() { // at this point,if prev_tyidx is not zero, this type name has been // forward-referenced tokenKind = lexer.NextToken(); - tyIdx = prevTyIdx; + tyIdx = TyIdx(0); if (IsPrimitiveType(tokenKind)) { if (!ParsePrimType(tyIdx)) { Error("expect primitive type after typedef but get "); @@ -1477,14 +1495,6 @@ bool MIRParser::ParseTypedef() { Error("error passing derived type at "); return false; } - if (prevTyIdx != 0u) { - MIRType *prevType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(prevTyIdx); - MIRType *newType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); - MIRStructType *newStructType = dynamic_cast(newType); - if (prevType->GetKind() != kTypeByName || newStructType == nullptr){ - return true; - } - } // for class/interface types, prev_tyidx could also be set during processing // so we check again right before SetGStrIdxToTyIdx if (isLocal) { @@ -1504,6 +1514,14 @@ bool MIRParser::ParseTypedef() { GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx)->SetNameStrIdx(strIdx); } } + + if (prevTyIdx != TyIdx(0) && prevTyIdx != tyIdx) { + // replace all uses of prev_tyidx by tyIdx in typeTable + typeDefIdxMap[prevTyIdx] = tyIdx; // record the real tydix + // remove prev_tyidx from classlist + mod.RemoveClass(prevTyIdx); + } + // Merge class or interface type at the cross-module level ASSERT(GlobalTables::GetTypeTable().GetTypeTable().empty() == false, "container check"); MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); @@ -1983,6 +2001,7 @@ bool MIRParser::ParseInitValue(MIRConstPtr &theConst, TyIdx tyIdx, bool allowEmp } theConst = mirConst; } else { // aggregates + FixForwardReferencedTypeForOneAgg(&type); if (type.GetKind() == kTypeArray) { auto &arrayType = static_cast(type); MIRType *elemType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(arrayType.GetElemTyIdx()); @@ -2019,14 +2038,18 @@ bool MIRParser::ParseInitValue(MIRConstPtr &theConst, TyIdx tyIdx, bool allowEmp return false; } } else { - std::vector sizeSubArray; - ASSERT(arrayType.GetDim() > 1, "array dim must large then 1"); - for (uint16 i = 1; i < arrayType.GetDim(); ++i) { - sizeSubArray.push_back(arrayType.GetSizeArrayItem(i)); + TyIdx elemTyIdx; + if (arrayType.GetDim() == 1) { + elemTyIdx = elemType->GetTypeIndex(); + } else { + std::vector sizeSubArray; + for (uint16 i = 1; i < arrayType.GetDim(); ++i) { + sizeSubArray.push_back(arrayType.GetSizeArrayItem(i)); + } + MIRArrayType subArrayType(elemType->GetTypeIndex(), sizeSubArray); + elemTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&subArrayType); } - MIRArrayType subArrayType(elemType->GetTypeIndex(), sizeSubArray); - TyIdx arrayTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&subArrayType); - if (!ParseInitValue(subConst, arrayTyIdx)) { + if (!ParseInitValue(subConst, elemTyIdx)) { Error("initializaton value wrong when parsing sub array "); return false; } @@ -2047,11 +2070,12 @@ bool MIRParser::ParseInitValue(MIRConstPtr &theConst, TyIdx tyIdx, bool allowEmp } } while (tokenKind != TK_rbrack); lexer.NextToken(); - } else if (type.GetKind() == kTypeStruct) { + } else if (type.GetKind() == kTypeStruct || type.GetKind() == kTypeUnion) { MIRAggConst *newConst = mod.GetMemPool()->New(mod, type); - uint32 theFieldID; + uint32 theFieldIdx; TyIdx fieldTyIdx; theConst = newConst; + MapleVector &constvec = newConst->GetConstVec(); tokenKind = lexer.NextToken(); if (tokenKind == TK_rbrack) { if (allowEmpty) { @@ -2067,12 +2091,13 @@ bool MIRParser::ParseInitValue(MIRConstPtr &theConst, TyIdx tyIdx, bool allowEmp Error("expect field ID in struct initialization but get "); return false; } - theFieldID = lexer.GetTheIntVal(); + theFieldIdx = lexer.GetTheIntVal(); if (lexer.NextToken() != TK_eqsign) { Error("expect = after field ID in struct initialization but get "); return false; } - fieldTyIdx = static_cast(type).GetFieldTyIdx(theFieldID); + FieldPair thepair = static_cast(type).GetFields()[theFieldIdx-1]; + fieldTyIdx = thepair.second.first; if (fieldTyIdx == 0u) { Error("field ID out of range at struct initialization at "); return false; @@ -2100,13 +2125,8 @@ bool MIRParser::ParseInitValue(MIRConstPtr &theConst, TyIdx tyIdx, bool allowEmp return false; } ASSERT(subConst != nullptr, "subConst is null in MIRParser::ParseInitValue"); - if (subConst->GetKind() == kConstInt) { - subConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst( - static_cast(subConst)->GetValue(), subConst->GetType(), theFieldID); - } else { - subConst->SetFieldID(theFieldID); - } - newConst->PushBack(subConst); + subConst->SetFieldID(theFieldIdx); + constvec.push_back(subConst); tokenKind = lexer.GetTokenKind(); // parse comma or rbrack if (tokenKind == TK_coma) { diff --git a/src/mplfe/common/src/mplfe_compiler.cpp b/src/mplfe/common/src/mplfe_compiler.cpp index c3df826d2526d81ac2ec24eee31b627dcaadf6ec..f4fed73a6b576e4cbe51b90b44d539f110a5cd09 100644 --- a/src/mplfe/common/src/mplfe_compiler.cpp +++ b/src/mplfe/common/src/mplfe_compiler.cpp @@ -119,7 +119,7 @@ void MPLFECompiler::ExportMpltFile() { void MPLFECompiler::ExportMplFile() { FETimer timer; timer.StartAndDump("Output mpl"); - module.OutputAsciiMpl("", false); + module.OutputAsciiMpl("", ".mpl", nullptr, false, false); timer.StopAndDumpTimeMS("Output mpl"); } @@ -203,4 +203,4 @@ void MPLFECompiler::ProcessFunctions() { timer.StopAndDumpTimeMS("MPLFECompiler::ProcessFunctions()"); CHECK_FATAL(success, "ProcessFunction error"); } -} // namespace maple \ No newline at end of file +} // namespace maple