From 203a8cb410b4ac48d496fa4155f66cb319602221 Mon Sep 17 00:00:00 2001 From: gavin1012_hw Date: Mon, 6 Feb 2023 11:56:28 +0800 Subject: [PATCH] Enhance reload ability for IDE compiling Issue: I6D2D4 Signed-off-by: gavin1012_hw Change-Id: I9a6cad4dee43f0b4e401bc09e1af988c8cba60d2 --- es2panda/aot/options.cpp | 5 ++++- es2panda/es2panda.cpp | 6 ++++-- es2panda/es2panda.h | 3 ++- es2panda/util/hotfix.cpp | 24 +++++++++++++++++------- es2panda/util/hotfix.h | 7 +++++-- 5 files changed, 32 insertions(+), 13 deletions(-) diff --git a/es2panda/aot/options.cpp b/es2panda/aot/options.cpp index 03796d15cb9..03fba648ea2 100644 --- a/es2panda/aot/options.cpp +++ b/es2panda/aot/options.cpp @@ -167,10 +167,11 @@ bool Options::Parse(int argc, const char **argv) panda::PandArg opNpmModuleEntryList("npm-module-entry-list", "", "entry list file for module compile"); panda::PandArg opMergeAbc("merge-abc", false, "Compile as merge abc"); - // hotfix + // hotfix && hotreload panda::PandArg opDumpSymbolTable("dump-symbol-table", "", "dump symbol table to file"); panda::PandArg opInputSymbolTable("input-symbol-table", "", "input symbol table file"); panda::PandArg opGeneratePatch("generate-patch", false, "generate patch abc"); + panda::PandArg opHotReload("hot-reload", false, "compile as hot-reload mode"); // version panda::PandArg bcVersion("bc-version", false, "Print ark bytecode version"); @@ -214,6 +215,7 @@ bool Options::Parse(int argc, const char **argv) argparser_->Add(&opDumpSymbolTable); argparser_->Add(&opInputSymbolTable); argparser_->Add(&opGeneratePatch); + argparser_->Add(&opHotReload); argparser_->Add(&bcVersion); argparser_->Add(&bcMinVersion); @@ -393,6 +395,7 @@ bool Options::Parse(int argc, const char **argv) compilerOptions_.hotfixOptions.dumpSymbolTable = opDumpSymbolTable.GetValue(); compilerOptions_.hotfixOptions.symbolTable = opInputSymbolTable.GetValue(); compilerOptions_.hotfixOptions.generatePatch = opGeneratePatch.GetValue(); + compilerOptions_.hotfixOptions.hotReload = opHotReload.GetValue(); return true; } diff --git a/es2panda/es2panda.cpp b/es2panda/es2panda.cpp index 6a488c535f0..e9b37d6e724 100644 --- a/es2panda/es2panda.cpp +++ b/es2panda/es2panda.cpp @@ -123,9 +123,11 @@ util::Hotfix *Compiler::InitHotfixHelper(const SourceFile &input, const Compiler { bool needDumpSymbolFile = !options.hotfixOptions.dumpSymbolTable.empty(); bool needGeneratePatch = options.hotfixOptions.generatePatch && !options.hotfixOptions.symbolTable.empty(); + bool isHotReload = options.hotfixOptions.hotReload; util::Hotfix *hotfixHelper = nullptr; - if (symbolTable && (needDumpSymbolFile || needGeneratePatch)) { - hotfixHelper = new util::Hotfix(needDumpSymbolFile, needGeneratePatch, input.recordName, symbolTable); + if (symbolTable && (needDumpSymbolFile || needGeneratePatch || isHotReload)) { + hotfixHelper = new util::Hotfix(needDumpSymbolFile, needGeneratePatch, isHotReload, + input.recordName, symbolTable); parser_->AddHotfixHelper(hotfixHelper); compiler_->AddHotfixHelper(hotfixHelper); } diff --git a/es2panda/es2panda.h b/es2panda/es2panda.h index 9a512a9809c..c6a4fe46794 100644 --- a/es2panda/es2panda.h +++ b/es2panda/es2panda.h @@ -65,6 +65,7 @@ struct HotfixOptions { std::string dumpSymbolTable {}; std::string symbolTable {}; bool generatePatch {false}; + bool hotReload {false}; }; struct CompilerOptions { @@ -203,7 +204,7 @@ private: util::Hotfix *InitHotfixHelper(const SourceFile &input, const CompilerOptions &options, util::SymbolTable *symbolTable); static void CleanHotfixHelper(const util::Hotfix *hotfixHelper); - + parser::ParserImpl *parser_; compiler::CompilerImpl *compiler_; std::unique_ptr transformer_ {nullptr}; diff --git a/es2panda/util/hotfix.cpp b/es2panda/util/hotfix.cpp index 090eb36eaa7..ae0b0fc0366 100644 --- a/es2panda/util/hotfix.cpp +++ b/es2panda/util/hotfix.cpp @@ -39,7 +39,7 @@ void Hotfix::ProcessFunction(const compiler::PandaGen *pg, panda::pandasm::Funct return; } - if (generatePatch_) { + if (generatePatch_ || hotReload_) { HandleFunction(pg, func, literalBuffers); return; } @@ -53,7 +53,7 @@ void Hotfix::ProcessModule(const std::string &recordName, return; } - if (generatePatch_) { + if (generatePatch_ || hotReload_) { ValidateModuleInfo(recordName, moduleBuffer); return; } @@ -66,7 +66,7 @@ void Hotfix::ProcessJsonContentRecord(const std::string &recordName, const std:: return; } - if (generatePatch_) { + if (generatePatch_ || hotReload_) { ValidateJsonContentRecInfo(recordName, jsonFileContent); return; } @@ -252,7 +252,7 @@ void Hotfix::CollectClassMemberFunctions(const std::string &className, int64_t b bool Hotfix::IsScopeValidToPatchLexical(binder::VariableScope *scope) const { - if (!generatePatch_) { + if (!generatePatch_ && !hotReload_) { return false; } @@ -398,7 +398,7 @@ void Hotfix::CreateFunctionPatchMain0AndMain1(panda::pandasm::Function &patchFun void Hotfix::Finalize(panda::pandasm::Program **prog) { - if (!generatePatch_) { + if (!generatePatch_ && !hotReload_) { return; } @@ -410,6 +410,10 @@ void Hotfix::Finalize(panda::pandasm::Program **prog) return; } + if (hotReload_) { + return; + } + panda::pandasm::Function patchFuncMain0(patchMain0_, SRC_LANG); panda::pandasm::Function patchFuncMain1(patchMain1_, SRC_LANG); CreateFunctionPatchMain0AndMain1(patchFuncMain0, patchFuncMain1); @@ -433,14 +437,16 @@ bool Hotfix::CompareLexenv(const std::string &funcName, const compiler::PandaGen auto varName = std::string(variable.second.first); auto lexenvIter = lexenv.find(varName); if (lexenvIter == lexenv.end()) { - std::cerr << "[Patch] Found new lex env added, not supported!" << std::endl; + std::cerr << "[Patch] Found new lex env added in function " << funcName << ", not supported!" + << std::endl; patchError_ = true; return false; } auto &lexInfo = lexenvIter->second; if (variable.first != lexInfo.first || variable.second.second != lexInfo.second) { - std::cerr << "[Patch] Found new lex env changed(slot or type), not supported!" << std::endl; + std::cerr << "[Patch] Found new lex env changed(slot or type) in function " << funcName + << ", not supported!" << std::endl; patchError_ = true; return false; } @@ -494,6 +500,10 @@ void Hotfix::HandleFunction(const compiler::PandaGen *pg, panda::pandasm::Functi return; } + if (hotReload_) { + return; + } + auto funcHash = std::to_string(hashList.back().second); if (funcHash == bytecodeInfo.funcHash || funcName == funcMain0_) { func->metadata->SetAttribute(EXTERNAL_ATTRIBUTE); diff --git a/es2panda/util/hotfix.h b/es2panda/util/hotfix.h index 06001d60ca8..0a76368a3d4 100644 --- a/es2panda/util/hotfix.h +++ b/es2panda/util/hotfix.h @@ -38,8 +38,10 @@ class Hotfix { using LiteralBuffers = ArenaVector>>; public: - Hotfix(bool generateSymbolFile, bool generatePatch, const std::string &recordName, util::SymbolTable *symbolTable) - : generateSymbolFile_(generateSymbolFile), generatePatch_(generatePatch), recordName_(recordName), + Hotfix(bool generateSymbolFile, bool generatePatch, bool hotReload, const std::string &recordName, + util::SymbolTable *symbolTable) + : generateSymbolFile_(generateSymbolFile), generatePatch_(generatePatch), hotReload_(hotReload), + recordName_(recordName), symbolTable_(symbolTable), allocator_(SpaceType::SPACE_TYPE_COMPILER, nullptr, true), topScopeLexEnvs_(allocator_.Adapter()), @@ -97,6 +99,7 @@ private: bool patchError_ {false}; bool generateSymbolFile_ {false}; bool generatePatch_ {false}; + bool hotReload_ {false}; std::string recordName_; std::string funcMain0_; std::string patchMain0_; // stores newly added function define ins, runtime will execute -- Gitee