diff --git a/src/mapleall/maple_ipa/include/clone.h b/src/mapleall/maple_ipa/include/clone.h index d54939e01aa298dabea80cfbaa8195f37ad15584..2f9bb50e12341a30f5c0bccbc33200160f69f76d 100644 --- a/src/mapleall/maple_ipa/include/clone.h +++ b/src/mapleall/maple_ipa/include/clone.h @@ -70,7 +70,7 @@ class Clone : public AnalysisResult { MIRType *returnType = nullptr) const; MIRFunction *CloneFunctionNoReturn(MIRFunction &originalFunction); void DoClone(); - void CopyFuncInfo(const MIRFunction &originalFunction, MIRFunction &newFunc) const; + void CopyFuncInfo(MIRFunction &originalFunction, MIRFunction &newFunc) const; void UpdateFuncInfo(MIRFunction &newFunc); void CloneArgument(MIRFunction &originalFunction, ArgVector &argument) const; ReplaceRetIgnored *GetReplaceRetIgnored() const { diff --git a/src/mapleall/maple_ipa/src/clone.cpp b/src/mapleall/maple_ipa/src/clone.cpp index 9b69e6ec6345253db048140492e908fba22eb0fb..f694e60b156daf948f21ee24374d556e158c6ae1 100644 --- a/src/mapleall/maple_ipa/src/clone.cpp +++ b/src/mapleall/maple_ipa/src/clone.cpp @@ -140,14 +140,14 @@ void Clone::CloneArgument(MIRFunction &originalFunction, ArgVector &argument) co } } -void Clone::CopyFuncInfo(const MIRFunction &originalFunction, MIRFunction &newFunc) const { +void Clone::CopyFuncInfo(MIRFunction &originalFunction, MIRFunction &newFunc) const { auto funcNameIdx = newFunc.GetBaseFuncNameStrIdx(); auto fullNameIdx = newFunc.GetNameStrIdx(); auto classNameIdx = newFunc.GetBaseClassNameStrIdx(); auto metaFullNameIdx = mirBuilder.GetOrCreateStringIndex(kFullNameStr); auto metaClassNameIdx = mirBuilder.GetOrCreateStringIndex(kClassNameStr); auto metaFuncNameIdx = mirBuilder.GetOrCreateStringIndex(kFuncNameStr); - const MIRInfoVector &fnInfo = originalFunction.GetInfoVector(); + MIRInfoVector &fnInfo = originalFunction.GetInfoVector(); const MapleVector &infoIsString = originalFunction.InfoIsString(); size_t size = fnInfo.size(); for (size_t i = 0; i < size; ++i) { diff --git a/src/mapleall/maple_ir/BUILD.gn b/src/mapleall/maple_ir/BUILD.gn index daf42c2028f4962dcc66d45b953805b0f70b4638..7eb046b85d00507db4ac39192afc397b84f288b6 100755 --- a/src/mapleall/maple_ir/BUILD.gn +++ b/src/mapleall/maple_ir/BUILD.gn @@ -48,6 +48,8 @@ src_libmplir = [ "src/printing.cpp", "src/bin_mpl_import.cpp", "src/bin_mpl_export.cpp", + "src/bin_func_export.cpp", + "src/bin_func_import.cpp", ] src_irbuild = [ "src/driver.cpp" ] diff --git a/src/mapleall/maple_ir/include/bin_mpl_export.h b/src/mapleall/maple_ir/include/bin_mpl_export.h index 36bbb967febcca9ee959301e3216a96959b0a23b..82ff9bfeefb8a271d9acaff2c501f73f05143693 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_export.h +++ b/src/mapleall/maple_ir/include/bin_mpl_export.h @@ -102,10 +102,12 @@ class BinaryMplExport { explicit BinaryMplExport(MIRModule &md); virtual ~BinaryMplExport() = default; - void Export(const std::string &fname); + void Export(const std::string &fname, std::unordered_set *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,19 +127,38 @@ class BinaryMplExport { void OutputInfo(const std::vector &info, const std::vector &infoIsString); void OutputPragmaVec(const std::vector &pragmaVec); void OutputClassTypeData(const MIRClassType &type); - void OutputSymbol(const MIRSymbol *sym); + void OutputSymbol(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(); @@ -158,6 +179,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 43bb2fb77d5a8a19dc4e2ac8eac9d53c0479074a..fcd1ba11a7e5475cde1f1433504dcc8236c8de57 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_import.h +++ b/src/mapleall/maple_ir/include/bin_mpl_import.h @@ -69,7 +69,10 @@ class BinaryMplImport { private: void ReadContentField(); void ReadStrField(); + void ReadHeaderField(); void ReadTypeField(); + void ReadSymField(); + void ReadSymTabField(); void ReadCgField(); EAConnectionGraph *ReadEaCgField(); void ReadEaField(); @@ -102,7 +105,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 &insVecType); TypeAttrs ImportTypeAttrs(); MIRPragmaElement *ImportPragmaElement(); MIRPragma *ImportPragma(); @@ -119,6 +122,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(); @@ -128,6 +150,7 @@ class BinaryMplImport { bool inCG = false; bool inIPA = false; 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 eed3a0642ac7505f9ff51133256897a6bd642511..fbe2603baa9924e74d39b01e77c0f82fc752b8e4 100644 --- a/src/mapleall/maple_ir/include/bin_mplt.h +++ b/src/mapleall/maple_ir/include/bin_mplt.h @@ -24,40 +24,16 @@ namespace maple { class BinaryMplt { public: - std::vector seUsage = { - "out/soong/.intermediates/vendor/huawei/maple/Lib/core/libmaplecore-all/android_arm64_armv8-a_core_shared/obj/classes.mpl", - "out/soong/.intermediates/vendor/huawei/maple/Lib/services/libmapleservices/android_arm64_armv8-a_core_shared/obj/classes.mrg.mpl", - "out/target/product/generic_a15/obj/SHARED_LIBRARIES/libmaplehwServices_intermediates/classes.mpl", - "out/soong/.intermediates/vendor/huawei/maple/Lib/frameworks/libmapleframework/android_arm64_armv8-a_core_shared/obj/classes.mrg.mpl", - "libcore-all.mpl", - "./libcore-all.mpl" - }; explicit BinaryMplt(MIRModule &md) : mirModule(md), binImport(md), binExport(md) {} 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) { - bool found = true; - for (size_t i = 0; i < seUsage.size(); ++i) { - if (seUsage[i] == mirModule.GetFileName()) { - found = true; - break; - } - } - readSE = readSE && found; -#ifdef MPLT_DEBUG - if (readCG) { - LogInfo::MapleLogger() << "READING CG mpl file : " << _mod.fileName << '\n'; - } - if (readSE) { - LogInfo::MapleLogger() << "READING SE mpl file : " << _mod.fileName << '\n'; - } -#endif importFileName = modID; return binImport.Import(modID, readCG, readSE); } @@ -74,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/mir_const.h b/src/mapleall/maple_ir/include/mir_const.h index a46eb49727a522a030d32f0b67cfd01a830828e8..82ab7772692bb1922d5225ac6548a499e42ac4be 100644 --- a/src/mapleall/maple_ir/include/mir_const.h +++ b/src/mapleall/maple_ir/include/mir_const.h @@ -163,8 +163,8 @@ class MIRIntConst : public MIRConst { class MIRAddrofConst : public MIRConst { public: - MIRAddrofConst(StIdx sy, FieldID fi, MIRType &ty) - : MIRConst(ty, kConstAddrof), stIdx(sy), fldID(fi), offset(0) {} + MIRAddrofConst(StIdx sy, FieldID fi, MIRType &ty, uint32 fieldID = 0) + : MIRConst(ty, kConstAddrof, fieldID), stIdx(sy), fldID(fi), offset(0) {} MIRAddrofConst(StIdx sy, FieldID fi, MIRType &ty, int32 ofst, uint32 fieldID = 0) : MIRConst(ty, kConstAddrof, fieldID), stIdx(sy), fldID(fi), offset(ofst) {} @@ -548,7 +548,7 @@ class MIRStConst : public MIRConst { stVec.push_back(sym); } - const MIRSymbol *GetStVecItem(size_t index) const { + MIRSymbol *GetStVecItem(size_t index) { CHECK_FATAL(index < stVec.size(), "array index out of range"); return stVec[index]; } diff --git a/src/mapleall/maple_ir/include/mir_function.h b/src/mapleall/maple_ir/include/mir_function.h index 02a7998f72fca219cfca0d93e922f516b87f4c87..e1853cf6e03e55ac235081ff338b416fef094372 100644 --- a/src/mapleall/maple_ir/include/mir_function.h +++ b/src/mapleall/maple_ir/include/mir_function.h @@ -577,7 +577,7 @@ class MIRFunction { return GetFuncSymbol()->GetSrcPosition(); } - void SetSrcPosition(const SrcPosition &position) { + void SetSrcPosition(SrcPosition &position) { GetFuncSymbol()->SetSrcPosition(position); } @@ -609,7 +609,7 @@ class MIRFunction { fileIndex = newFileIndex; } - const MIRInfoVector &GetInfoVector() const { + MIRInfoVector &GetInfoVector() { return info; } @@ -625,9 +625,10 @@ class MIRFunction { info[idx].second = num; } - const MapleVector &InfoIsString() const { + MapleVector &InfoIsString() { return infoIsString; } + void PushbackIsString(bool isString) { infoIsString.push_back(isString); } @@ -636,7 +637,7 @@ class MIRFunction { return aliasVarMap != nullptr; } - const MapleMap &GetAliasVarMap() { + MapleMap &GetAliasVarMap() { if (aliasVarMap == nullptr) { aliasVarMap = module->GetMemPool()->New>(module->GetMPAllocator().Adapter()); } @@ -851,7 +852,7 @@ class MIRFunction { symTab = module->GetMemPool()->New(module->GetMPAllocator()); } } - const MIRLabelTable *GetLabelTab() const { + MIRLabelTable *GetLabelTab() const { CHECK_FATAL(labelTab != nullptr, "must be"); return labelTab; } diff --git a/src/mapleall/maple_ir/include/mir_module.h b/src/mapleall/maple_ir/include/mir_module.h index 57cd8157a706b6c61b732aa715208b41ba0bfc69..657bcfd6377036cfd52009ea226ff907cc5277a1 100644 --- a/src/mapleall/maple_ir/include/mir_module.h +++ b/src/mapleall/maple_ir/include/mir_module.h @@ -214,6 +214,10 @@ class MIRModule { return symbolSet; } + const MapleVector &GetSymbolDefOrder() const { + return symbolDefOrder; + } + Profile &GetProfile() { return profile; } @@ -245,7 +249,7 @@ 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; @@ -253,7 +257,7 @@ class MIRModule { void DumpToHeaderFile(bool binaryMplt, const std::string &outputName = ""); void DumpToCxxHeaderFile(std::set &leafClasses, const std::string &pathToOutf) const; 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() { @@ -270,7 +274,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; @@ -404,7 +410,7 @@ class MIRModule { inIPA = isInIPA; } - const MIRInfoVector &GetFileInfo() const { + MIRInfoVector &GetFileInfo() { return fileInfo; } void PushFileInfoPair(MIRInfoPair pair) { @@ -414,7 +420,7 @@ class MIRModule { fileInfo = fileInf; } - const MapleVector &GetFileInfoIsString() const { + MapleVector &GetFileInfoIsString() { return fileInfoIsString; } void SetFileInfoIsString(const MapleVector &fileInfoIsStr) { @@ -449,6 +455,10 @@ class MIRModule { srcLang = sourceLanguage; } + uint16 GetID() const { + return id; + } + void SetID(uint16 num) { id = num; } @@ -481,6 +491,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 9085b86d9a8d22521bc78d95c12156e82af33686..081841db4c4603cd9e33a730a2c537b21ded0be6 100644 --- a/src/mapleall/maple_ir/include/mir_nodes.h +++ b/src/mapleall/maple_ir/include/mir_nodes.h @@ -1615,6 +1615,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); @@ -1812,7 +1816,7 @@ class SwitchNode : public StmtNode { defaultLabel = idx; } - const CaseVector &GetSwitchTable() const { + CaseVector &GetSwitchTable() { return switchTable; } diff --git a/src/mapleall/maple_ir/include/mir_symbol.h b/src/mapleall/maple_ir/include/mir_symbol.h index cac9f5f996aa853f2d8a993a4c32bf10617aa059..02eb665173d5ec5d10a2bf237b910004ebf9ffca 100644 --- a/src/mapleall/maple_ir/include/mir_symbol.h +++ b/src/mapleall/maple_ir/include/mir_symbol.h @@ -313,7 +313,7 @@ class MIRSymbol { return srcPosition; } - void SetSrcPosition(const SrcPosition &position) { + void SetSrcPosition(SrcPosition &position) { srcPosition = position; } @@ -473,16 +473,13 @@ class MIRSymbolTable { return idx < symbolTable.size(); } - const MIRSymbol *GetSymbolFromStIdx(uint32 idx, bool checkFirst = false) const { + MIRSymbol *GetSymbolFromStIdx(uint32 idx, bool checkFirst = false) const { if (checkFirst && idx >= symbolTable.size()) { return nullptr; } CHECK_FATAL(IsValidIdx(idx), "symbol table index out of range"); return symbolTable[idx]; } - MIRSymbol *GetSymbolFromStIdx(uint32 idx, bool checkFirst = false) { - return const_cast(const_cast(this)->GetSymbolFromStIdx(idx, checkFirst)); - } MIRSymbol *CreateSymbol(uint8 scopeID) { auto *st = mAllocator.GetMemPool()->New(symbolTable.size(), scopeID); @@ -490,6 +487,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) { @@ -518,10 +519,6 @@ class MIRSymbolTable { return GetSymbolFromStIdx(GetStIdxFromStrIdx(idx).Idx(), checkFirst); } - const MIRSymbol *GetSymbolFromStrIdx(GStrIdx idx, bool checkFirst = false) const { - return GetSymbolFromStIdx(GetStIdxFromStrIdx(idx).Idx(), checkFirst); - } - void Dump(bool isLocal, int32 indent = 0, bool printDeleted = false) const; size_t GetSymbolTableSize() const { return symbolTable.size(); @@ -636,6 +633,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/src/bin_func_export.cpp b/src/mapleall/maple_ir/src/bin_func_export.cpp new file mode 100644 index 0000000000000000000000000000000000000000..76577084642146e4556f92ed0ab9adfbe880d29a --- /dev/null +++ b/src/mapleall/maple_ir/src/bin_func_export.cpp @@ -0,0 +1,657 @@ +/* + * 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()) { + OutputLocalSymbol(nullptr); + } else { + 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..076470db8c8d7e5709fdd7b1ee8cb31b0283926a --- /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); + 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..4dcfa1976943afe7a736101465bd0ff7c9156f4a 100644 --- 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()); } @@ -96,10 +111,10 @@ void OutputConstAgg(const MIRConst &constVal, BinaryMplExport &mplExport) { } } -void OutputConstSt(const MIRConst &constVal, BinaryMplExport &mplExport) { +void OutputConstSt(MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstSt); mplExport.OutputConstBase(constVal); - const auto &stConst = static_cast(constVal); + MIRStConst &stConst = static_cast(constVal); size_t size = stConst.GetStVec().size(); mplExport.WriteNum(size); for (size_t i = 0; i < size; ++i) { @@ -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()); @@ -573,12 +596,12 @@ void BinaryMplExport::Init() { 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; } } -void BinaryMplExport::OutputSymbol(const MIRSymbol *sym) { +void BinaryMplExport::OutputSymbol(MIRSymbol *sym) { if (sym == nullptr) { WriteNum(0); return; @@ -590,7 +613,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 +622,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 +664,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->GetMIRFuncType()->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 +700,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 +736,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; -void BinaryMplExport::WriteContentField(int fieldNum, uint64 *fieldStartP) { + 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::WriteContentField4mplt(int fieldNum, uint64 *fieldStartP) { WriteNum(kBinContentStart); size_t totalSizeIdx = buf.size(); ExpandFourBuffSize(); // total size of this field to ~BIN_SYM_START @@ -697,15 +821,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 +925,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,28 +935,30 @@ 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()) { - if (ty->GetKind() != kTypeFunction) { - WriteNum(-(it->second)); - return; - } - ++BinaryMplExport::typeMarkOffset; - } else { - size_t mark = typMark.size() + BinaryMplExport::typeMarkOffset; - typMark[ty] = mark; + WriteNum(-(it->second)); + return; + } + 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 3efc116928f2bbabb8e7e29d97efb809ed602dd3..67c91533ac980d722aa97298daee644d2fdb225a 100644 --- 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); + } } } @@ -462,7 +475,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))); } } @@ -474,13 +487,13 @@ TypeAttrs BinaryMplImport::ImportTypeAttrs() { return ta; } -void BinaryMplImport::ImportTypePairs(MIRInstantVectorType &insVecType) { +void BinaryMplImport::ImportTypePairs(std::vector &insVecType) { int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { TyIdx t0 = ImportType(); TyIdx t1 = ImportType(); TypePair tp(t0, t1); - insVecType.AddInstant(tp); + insVecType.push_back(tp); } } @@ -504,8 +517,6 @@ 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; @@ -516,6 +527,22 @@ 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(); + } + PrimType primType = (PrimType)0; + GStrIdx strIdx(0); bool nameIsLocal = false; ImportTypeBase(primType, strIdx, nameIsLocal); @@ -530,6 +557,7 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { ++ptrLev; type.SetPointedTyIdx(ImportType(true)); --ptrLev; + type.SetTypeAttrs(ImportTypeAttrs()); MIRType *origType = &InsertInTypeTables(type); typTab[idx] = origType; if (typeNeedsComplete != nullptr && ptrLev == 0) { @@ -577,6 +605,7 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { size_t idx = typTab.size(); typTab.push_back(nullptr); type.SetElemTyIdx(ImportType(forPointedType)); + type.SetTypeAttrs(ImportTypeAttrs()); MIRType *origType = &InsertInTypeTables(type); typTab[idx] = origType; return origType->GetTypeIndex(); @@ -613,7 +642,7 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { type.SetNameIsLocal(nameIsLocal); auto *origType = static_cast(&InsertInTypeTables(type)); typTab.push_back(origType); - ImportTypePairs(*origType); + ImportTypePairs(origType->GetInstantVec()); return origType->GetTypeIndex(); } case kBinKindTypeGenericInstant: { @@ -621,7 +650,7 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { type.SetNameIsLocal(nameIsLocal); auto *origType = static_cast(&InsertInTypeTables(type)); typTab.push_back(origType); - ImportTypePairs(*origType); + ImportTypePairs(origType->GetInstantVec()); origType->SetGenericTyIdx(ImportType()); return origType->GetTypeIndex(); } @@ -733,15 +762,15 @@ MIRType &BinaryMplImport::InsertInTypeTables(MIRType &type) { resultTypePtr = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); if (tyIdx + 1 == GlobalTables::GetTypeTable().GetTypeTable().size() && !resultTypePtr->IsNameIsLocal()) { GStrIdx stridx = resultTypePtr->GetNameStrIdx(); - if (IsObject(*resultTypePtr)) { + if (stridx != 0) { mod.GetTypeNameTab()->SetGStrIdxToTyIdx(stridx, tyIdx); - mod.AddClass(tyIdx); mod.PushbackTypeDefOrder(stridx); - if (!IsIncomplete(*resultTypePtr)) { - GlobalTables::GetTypeNameTable().SetGStrIdxToTyIdx(stridx, tyIdx); + if (IsObject(*resultTypePtr)) { + mod.AddClass(tyIdx); + if (!IsIncomplete(*resultTypePtr)) { + GlobalTables::GetTypeNameTable().SetGStrIdxToTyIdx(stridx, tyIdx); + } } - } else if (resultTypePtr->GetKind() == kTypeByName) { - mod.GetTypeNameTab()->SetGStrIdxToTyIdx(stridx, tyIdx); } } } @@ -793,15 +822,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; } @@ -810,10 +854,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); @@ -828,16 +878,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(); } @@ -858,6 +929,51 @@ 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()); + std::string inStr; + ReadAsciiStr(inStr); + mod.SetEntryFuncName(inStr); + 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.PushbackImportedMplt(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(); @@ -870,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(); @@ -894,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) { @@ -909,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/mir_module.cpp b/src/mapleall/maple_ir/src/mir_module.cpp index a08a1d489e7978f24b9d32a61439aabac6c5f242..909670fd18a00a64c2a8877dcd359e9449dc5e91 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 @@ -277,9 +276,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 { @@ -308,9 +308,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(); + } + } } } @@ -333,7 +347,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(); } @@ -602,9 +616,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) { @@ -613,18 +630,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/mir_parser.cpp b/src/mapleall/maple_ir/src/mir_parser.cpp index 0f0392eec4ebf63cd70345ce143fd2b1e9e5a62c..173013e8d49adadc45bdb53e700771db55896531 100644 --- a/src/mapleall/maple_ir/src/mir_parser.cpp +++ b/src/mapleall/maple_ir/src/mir_parser.cpp @@ -876,7 +876,7 @@ bool MIRParser::ParseStmtIntrinsiccall(StmtNodePtr &stmt, bool isAssigned) { : OP_xintrinsiccallassigned); auto *intrnCallNode = mod.CurFuncCodeMemPool()->New(mod, o); lexer.NextToken(); - if (o == (!isAssigned ? OP_intrinsiccall : OP_intrinsiccallassigned)) { + if (o == !isAssigned ? OP_intrinsiccall : OP_intrinsiccallassigned) { intrnCallNode->SetIntrinsic(GetIntrinsicID(lexer.GetTokenKind())); } else { intrnCallNode->SetIntrinsic(static_cast(lexer.GetTheIntVal())); @@ -2606,7 +2606,7 @@ bool MIRParser::ParseScalarValue(MIRConstPtr &stype, MIRType &type) { Error("constant value incompatible with integer type at "); return false; } - stype = GlobalTables::GetIntConstTable().GetOrCreateIntConst(lexer.GetTheIntVal(), type); + stype = mod.GetMemPool()->New(lexer.GetTheIntVal(), type); } else if (ptp == PTY_f32) { if (lexer.GetTokenKind() != TK_floatconst) { Error("constant value incompatible with single-precision float type at "); diff --git a/src/mapleall/maple_ir/src/parser.cpp b/src/mapleall/maple_ir/src/parser.cpp index 88d66168ea80c28144695004787cb4848102e156..26e45b925b9b04a11c0e88375ed7c9a04e539500 100644 --- a/src/mapleall/maple_ir/src/parser.cpp +++ b/src/mapleall/maple_ir/src/parser.cpp @@ -2029,6 +2029,7 @@ bool MIRParser::ParseInitValue(MIRConstPtr &theConst, TyIdx tyIdx, bool allowEmp MIRType *elemType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(arrayType.GetElemTyIdx()); MIRAggConst *newConst = mod.GetMemPool()->New(mod, type); theConst = newConst; + MapleVector &constvec = newConst->GetConstVec(); tokenKind = lexer.NextToken(); if (tokenKind == TK_rbrack) { if (allowEmpty) { @@ -2080,7 +2081,7 @@ bool MIRParser::ParseInitValue(MIRConstPtr &theConst, TyIdx tyIdx, bool allowEmp Error("expect const value or group of const values but get "); return false; } - newConst->PushBack(subConst); + constvec.push_back(subConst); // parse comma or rbrack tokenKind = lexer.GetTokenKind(); if (tokenKind == TK_coma) { diff --git a/src/mapleall/maple_me/include/me_ir.h b/src/mapleall/maple_me/include/me_ir.h index 60be26f98ec41718282b571691f45c3aaa8f4043..f4247e13e1349934460dab0ccf287cd35560358e 100644 --- a/src/mapleall/maple_me/include/me_ir.h +++ b/src/mapleall/maple_me/include/me_ir.h @@ -2521,11 +2521,11 @@ class CatchMeStmt : public MeStmt { class SwitchMeStmt : public UnaryMeStmt { public: - SwitchMeStmt(MapleAllocator *alloc, const StmtNode *stt) + SwitchMeStmt(MapleAllocator *alloc, StmtNode *stt) : UnaryMeStmt(stt), - defaultLabel(static_cast(stt)->GetDefaultLabel()), + defaultLabel(static_cast(stt)->GetDefaultLabel()), switchTable(alloc->Adapter()) { - switchTable = static_cast(stt)->GetSwitchTable(); + switchTable = static_cast(stt)->GetSwitchTable(); } ~SwitchMeStmt() = default;