From a27aae43967f03595e999e0e08aa8f99c7189329 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Wed, 10 Mar 2021 18:33:39 -0800 Subject: [PATCH] Added binary export and import functionalities for code portion of MAPLE IR Binary version of .mpl file uses .bpl file suffix. Ascii version of .mplt file uses .tmpl file suffix. irbuild usage has be modified: it distinguishes input file types according to file suffices. irbuild given -b option will write output file in binary file format. Without -b, it always outputs ascii. irbuild can be controlled to only output specific functions via -dumpfunc= option. This patch causes .mplt to be incompatible because it now includes new contents to support C. Front-ends producing .mplt need to be rebuilt with this version before testing. Front-ends can continue to output .mpl as before, but they should be enhanced to output .bpl based on command-line option. Refer to maple_ir/src/driver.cpp on how to output .bpl. Maple driver has NOT been updated to handle .bpl. --- src/mapleall/maple_ipa/include/clone.h | 2 +- src/mapleall/maple_ipa/src/clone.cpp | 4 +- src/mapleall/maple_ir/BUILD.gn | 2 + .../maple_ir/include/bin_mpl_export.h | 37 +- .../maple_ir/include/bin_mpl_import.h | 25 +- src/mapleall/maple_ir/include/bin_mplt.h | 34 +- src/mapleall/maple_ir/include/mir_const.h | 6 +- src/mapleall/maple_ir/include/mir_function.h | 11 +- src/mapleall/maple_ir/include/mir_module.h | 24 +- src/mapleall/maple_ir/include/mir_nodes.h | 6 +- src/mapleall/maple_ir/include/mir_symbol.h | 16 +- src/mapleall/maple_ir/src/bin_func_export.cpp | 657 ++++++++++++++ src/mapleall/maple_ir/src/bin_func_import.cpp | 817 ++++++++++++++++++ src/mapleall/maple_ir/src/bin_mpl_export.cpp | 358 ++++++-- src/mapleall/maple_ir/src/bin_mpl_import.cpp | 242 +++++- src/mapleall/maple_ir/src/driver.cpp | 119 +-- src/mapleall/maple_ir/src/mir_module.cpp | 59 +- src/mapleall/maple_ir/src/mir_parser.cpp | 4 +- src/mapleall/maple_ir/src/parser.cpp | 3 +- src/mapleall/maple_me/include/me_ir.h | 6 +- 20 files changed, 2176 insertions(+), 256 deletions(-) create mode 100644 src/mapleall/maple_ir/src/bin_func_export.cpp create mode 100644 src/mapleall/maple_ir/src/bin_func_import.cpp diff --git a/src/mapleall/maple_ipa/include/clone.h b/src/mapleall/maple_ipa/include/clone.h index d54939e01a..2f9bb50e12 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 973ac513bd..836726affb 100644 --- a/src/mapleall/maple_ipa/src/clone.cpp +++ b/src/mapleall/maple_ipa/src/clone.cpp @@ -137,14 +137,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 daf42c2028..7eb046b85d 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 8bddf675d6..b26f249925 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_export.h +++ b/src/mapleall/maple_ir/include/bin_mpl_export.h @@ -100,10 +100,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); @@ -123,19 +125,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(); @@ -156,6 +177,10 @@ class BinaryMplExport { std::unordered_map symMark; std::unordered_map typMark; static int typeMarkOffset; // offset of mark (tag in binmplimport) resulting from duplicated function + + public: + bool not2mplt; // this export is not to an mplt file + std::unordered_map callInfoMark; }; } // namespace maple diff --git a/src/mapleall/maple_ir/include/bin_mpl_import.h b/src/mapleall/maple_ir/include/bin_mpl_import.h index dbee4494cf..0ca0b712bb 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_import.h +++ b/src/mapleall/maple_ir/include/bin_mpl_import.h @@ -68,7 +68,10 @@ class BinaryMplImport { private: void ReadContentField(); void ReadStrField(); + void ReadHeaderField(); void ReadTypeField(); + void ReadSymField(); + void ReadSymTabField(); void Jump2NextField(); void Reset(); void SkipTotalSize(); @@ -88,7 +91,7 @@ class BinaryMplImport { TyIdx ImportType(bool forPointedType = false); void ImportTypeBase(PrimType &primType, GStrIdx &strIdx, bool &nameIsLocal); void InSymTypeTable(); - void ImportTypePairs(MIRInstantVectorType &insVecType); + void ImportTypePairs(std::vector &insVecType); TypeAttrs ImportTypeAttrs(); MIRPragmaElement *ImportPragmaElement(); MIRPragma *ImportPragma(); @@ -105,6 +108,25 @@ class BinaryMplImport { void ImportInterfaceTypeData(MIRInterfaceType &type); PUIdx ImportFunction(); MIRSymbol *InSymbol(MIRFunction *func); + + void ImportInfoVector(MIRInfoVector &infovector, MapleVector &infovector_isstring); + void ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab); + void ImportFuncIdInfo(MIRFunction *func); + void ImportLocalSymbol(MIRFunction *func); + void ImportLocalSymTab(MIRFunction *func); + void ImportPregTab(MIRFunction *func); + void ImportLabelTab(MIRFunction *func); + void ImportFormalsStIdx(MIRFunction *func); + void ImportAliasMap(MIRFunction *func); + void ImportSrcPos(SrcPosition &pos); + void ImportBaseNode(Opcode &o, PrimType &typ, uint8 &numopr); + PUIdx ImportFuncViaSymName(); + BaseNode *ImportExpression(MIRFunction *func); + + void ImportReturnValues(MIRFunction *func, CallReturnVector *retv); + BlockNode *ImportBlockNode(MIRFunction *fn); + void ReadFunctionBodyField(); + void ReadFileAt(const std::string &modid, int32 offset); uint8 Read(); int64 ReadInt64(); @@ -112,6 +134,7 @@ class BinaryMplImport { int32 GetIPAFileIndex(std::string &name); bool imported = true; // used only by irbuild to convert to ascii + bool importingFromMplt; // decided based on magic number uint64 bufI = 0; std::vector buf; std::map content; diff --git a/src/mapleall/maple_ir/include/bin_mplt.h b/src/mapleall/maple_ir/include/bin_mplt.h index eed3a0642a..fbe2603baa 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 a46eb49727..82ab777269 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 02a7998f72..e1853cf6e0 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 090e71455d..c475e4014f 100644 --- a/src/mapleall/maple_ir/include/mir_module.h +++ b/src/mapleall/maple_ir/include/mir_module.h @@ -205,6 +205,10 @@ class MIRModule { return symbolSet; } + const MapleVector &GetSymbolDefOrder() const { + return symbolDefOrder; + } + Profile &GetProfile() { return profile; } @@ -230,14 +234,14 @@ class MIRModule { } void DumpGlobals(bool emitStructureType = true) const; - void Dump(bool emitStructureType = true) const; + void Dump(bool emitStructureType = true, std::unordered_set *dumpFuncSet = nullptr) const; void DumpToFile(const std::string &fileNameStr, bool emitStructureType = true) const; void DumpInlineCandidateToFile(const std::string &fileNameStr) const; const std::string &GetFileNameFromFileNum(uint32 fileNum) const; void DumpToHeaderFile(bool binaryMplt, const std::string &outputName = ""); void DumpClassToFile(const std::string &path) const; - void DumpFunctionList(bool skipBody = false) const; + void DumpFunctionList(const std::unordered_set *dumpFuncSet) const; void DumpGlobalArraySymbol() const; void Emit(const std::string &outFileName) const; uint32 GetAndIncFloatNum() { @@ -254,7 +258,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; @@ -372,7 +378,7 @@ class MIRModule { inIPA = isInIPA; } - const MIRInfoVector &GetFileInfo() const { + MIRInfoVector &GetFileInfo() { return fileInfo; } void PushFileInfoPair(MIRInfoPair pair) { @@ -382,7 +388,7 @@ class MIRModule { fileInfo = fileInf; } - const MapleVector &GetFileInfoIsString() const { + MapleVector &GetFileInfoIsString() { return fileInfoIsString; } void SetFileInfoIsString(const MapleVector &fileInfoIsStr) { @@ -417,6 +423,10 @@ class MIRModule { srcLang = sourceLanguage; } + uint16 GetID() const { + return id; + } + void SetID(uint16 num) { id = num; } @@ -449,6 +459,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 9085b86d9a..081841db4c 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 9a7df9db5a..0bf0e0647c 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(); @@ -623,6 +620,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 0000000000..7657708464 --- /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 0000000000..076470db8c --- /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 0eb7625646..4dcfa19769 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 1d84307d67..33df0108a0 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); + } } } @@ -458,7 +471,7 @@ void BinaryMplImport::Reset() { uStrTab.push_back(UStrIdx(0)); // Dummy symTab.push_back(nullptr); // Dummy funcTab.push_back(nullptr); // Dummy - for (int32 pti = 0; pti <= static_cast(PTY_agg); ++pti) { + for (int32 pti = static_cast(PTY_begin); pti < static_cast(PTY_end); ++pti) { typTab.push_back(GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(pti))); } } @@ -470,13 +483,13 @@ TypeAttrs BinaryMplImport::ImportTypeAttrs() { return ta; } -void BinaryMplImport::ImportTypePairs(MIRInstantVectorType &insVecType) { +void BinaryMplImport::ImportTypePairs(std::vector &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); } } @@ -500,8 +513,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; @@ -512,6 +523,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); @@ -526,6 +553,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) { @@ -573,6 +601,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(); @@ -609,7 +638,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: { @@ -617,7 +646,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(); } @@ -729,15 +758,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); } } } @@ -785,15 +814,30 @@ MIRSymbol *BinaryMplImport::InSymbol(MIRFunction *func) { sym->SetAttrs(ImportTypeAttrs()); sym->SetIsTmp(ReadNum() != 0); sym->SetIsImported(imported); + uint32 thepregno = 0; if (skind == kStPreg) { - CHECK_FATAL(false, "outing kStPreg"); + CHECK_FATAL(scope == kScopeLocal && func != nullptr, "Expecting kScopeLocal"); + thepregno = ReadNum(); } else if (skind == kStConst || skind == kStVar) { - CHECK_FATAL(false, "outing kStConst or kStVar"); + sym->SetKonst(ImportConst(func)); } else if (skind == kStFunc) { PUIdx puidx = ImportFunction(); - TyIdx tyidx = ImportType(); - sym->SetTyIdx(tyidx); - sym->SetFunction(GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puidx)); + if (puidx != 0) { + sym->SetFunction(GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puidx)); + } + } + if (skind == kStVar || skind == kStFunc) { + ImportSrcPos(sym->GetSrcPosition()); + } + TyIdx tyIdx = ImportType(); + sym->SetTyIdx(tyIdx); + if (skind == kStPreg) { + MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); + PregIdx pregidx = func->GetPregTab()->EnterPregNo(thepregno, mirType->GetPrimType(), mirType); + MIRPregTable *pregTab = func->GetPregTab(); + MIRPreg *preg = pregTab->PregFromPregIdx(pregidx); + preg->SetPrimType(mirType->GetPrimType()); + sym->SetPreg(preg); } return sym; } @@ -802,10 +846,16 @@ MIRSymbol *BinaryMplImport::InSymbol(MIRFunction *func) { PUIdx BinaryMplImport::ImportFunction() { int64 tag = ReadNum(); if (tag == 0) { + mod.SetCurFunction(nullptr); return 0; } else if (tag < 0) { CHECK_FATAL(static_cast(-tag) < funcTab.size(), "index out of bounds"); - return funcTab.at(-tag)->GetPuidx(); + if (-tag == funcTab.size()) { // function was exported before its symbol + return (PUIdx)0; + } + PUIdx puIdx = funcTab[-tag]->GetPuidx(); + mod.SetCurFunction(GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx)); + return puIdx; } CHECK_FATAL(tag == kBinFunction, "expecting kBinFunction"); MIRSymbol *funcSt = InSymbol(nullptr); @@ -820,16 +870,37 @@ PUIdx BinaryMplImport::ImportFunction() { funcTab.push_back(func); } funcSt->SetFunction(func); + methodSymbols.push_back(funcSt); if (mod.IsJavaModule()) { func->SetBaseClassFuncNames(funcSt->GetNameStrIdx()); } - TyIdx retType = ImportType(); - func->SetReturnTyIdx(retType); + TyIdx funcTyIdx = ImportType(); + func->SetMIRFuncType(static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcTyIdx))); func->SetStIdx(funcSt->GetStIdx()); func->SetFuncAttrs(ReadNum()); func->SetFlag(ReadNum()); - func->SetClassTyIdx(ImportType()); + /*func->SetClassTyIdx(*/ImportType(); // not set the field to mimic parser + // import formal parameter informcation + size_t size = ReadNum(); + if (func->GetFormalDefVec().size() == 0) { + for (size_t i = 0; i < size; i++) { + GStrIdx strIdx = ImportStr(); + TyIdx tyIdx = ImportType(); + FormalDef formalDef(strIdx, nullptr, tyIdx, TypeAttrs()); + formalDef.formalAttrs.SetAttrFlag(ReadNum()); + func->GetFormalDefVec().push_back(formalDef); + } + } else { + CHECK_FATAL(func->GetFormalDefVec().size() >= size, "ImportFunction: inconsistent number of formals"); + for (size_t i = 0; i < size; i++) { + func->GetFormalDefVec()[i].formalStrIdx = ImportStr(); + func->GetFormalDefVec()[i].formalTyIdx = ImportType(); + func->GetFormalDefVec()[i].formalAttrs.SetAttrFlag(ReadNum()); + } + } + + mod.SetCurFunction(func); return func->GetPuidx(); } @@ -850,6 +921,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(); @@ -862,6 +978,29 @@ void BinaryMplImport::ReadTypeField() { CHECK_FATAL(tag == ~kBinTypeStart, "pattern mismatch in Read TYPE"); } +void BinaryMplImport::ReadSymField() { + SkipTotalSize(); + int32 size = ReadInt(); + for (int64 i = 0; i < size; i++) { + InSymbol(nullptr); + } + int64 tag = ReadNum(); + CHECK_FATAL(tag == ~kBinSymStart, "pattern mismatch in Read SYM"); + return; +} + +void BinaryMplImport::ReadSymTabField() { + SkipTotalSize(); + int32 size = ReadInt(); + for (int64 i = 0; i < size; i++) { + std::string str; + ReadAsciiStr(str); + } + int64 tag = ReadNum(); + CHECK_FATAL(tag == ~kBinSymTabStart, "pattern mismatch in Read TYPE"); + return; +} + void BinaryMplImport::ReadContentField() { SkipTotalSize(); @@ -886,10 +1025,11 @@ bool BinaryMplImport::Import(const std::string &fname, bool readSymbols, bool re Reset(); ReadFileAt(fname, 0); int32 magic = ReadInt(); - if (kMpltMagicNumber != magic) { // not a binary mplt file + if (kMpltMagicNumber != magic && (kMpltMagicNumber+0x10) != magic) { buf.clear(); return false; } + importingFromMplt = kMpltMagicNumber == magic; int64 fieldID = ReadNum(); while (fieldID != kBinFinish) { switch (fieldID) { @@ -901,14 +1041,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 dcb2978ea4..7cc9a1af47 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 4efa53ac49..02144e026b 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 @@ -273,9 +272,10 @@ void MIRModule::DumpGlobals(bool emitStructureType) const { } } -void MIRModule::Dump(bool emitStructureType) const { +void MIRModule::Dump(bool emitStructureType, + std::unordered_set *dumpFuncSet) const { DumpGlobals(emitStructureType); - DumpFunctionList(); + DumpFunctionList(dumpFuncSet); } void MIRModule::DumpGlobalArraySymbol() const { @@ -304,9 +304,23 @@ void MIRModule::Emit(const std::string &outFileName) const { file.close(); } -void MIRModule::DumpFunctionList(bool skipBody) const { - for (MIRFunction *func : functionList) { - func->Dump(skipBody); +void MIRModule::DumpFunctionList(const std::unordered_set *dumpFuncSet) const { + for (MIRFunction *mirFunc : functionList) { + if (dumpFuncSet == nullptr || dumpFuncSet->empty()) { + mirFunc->Dump(); + } else { // dump only if this func matches any name in *dumpFuncSet + const std::string &name = mirFunc->GetName(); + bool matched = false; + for (std::string elem : *dumpFuncSet) { + if (name.find(elem.c_str()) != std::string::npos) { + matched = true; + break; + } + } + if (matched) { + mirFunc->Dump(); + } + } } } @@ -329,7 +343,7 @@ void MIRModule::OutputFunctionListAsciiMpl(const std::string &phaseName) { std::streambuf *backup = LogInfo::MapleLogger().rdbuf(); LogInfo::MapleLogger().rdbuf(mplFile.rdbuf()); // change cout's buffer to that of file DumpGlobalArraySymbol(); - DumpFunctionList(); + DumpFunctionList(nullptr); LogInfo::MapleLogger().rdbuf(backup); // restore cout's buffer mplFile.close(); } @@ -462,9 +476,12 @@ MIRFunction *MIRModule::FindEntryFunction() { } // given the phase name (including '.' at beginning), output the program in the -// module in ascii form to the file with either .mpl or .mmpl suffix, and file -// stem from this->fileName appended with phasename -void MIRModule::OutputAsciiMpl(const std::string &phaseName, bool emitStructureType) { +// module to the file with given file suffix, and file stem from +// this->fileName appended with phaseName +void MIRModule::OutputAsciiMpl(const char *phaseName, const char *suffix, + std::unordered_set *dumpFuncSet, + bool emitStructureType, bool binaryform) { + ASSERT(!(emitStructureType && binaryform), "Cannot emit type info in .bpl"); std::string fileStem; std::string::size_type lastDot = fileName.find_last_of('.'); if (lastDot == std::string::npos) { @@ -473,18 +490,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 0f0392eec4..173013e8d4 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 914a499b68..ef2185da5b 100644 --- a/src/mapleall/maple_ir/src/parser.cpp +++ b/src/mapleall/maple_ir/src/parser.cpp @@ -2026,6 +2026,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) { @@ -2077,7 +2078,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 60be26f98e..f4247e13e1 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; -- Gitee