diff --git a/es2panda/aot/options.cpp b/es2panda/aot/options.cpp index 03796d15cb916ccc64189c0a7ce7bca11d25e08d..03fba648ea2695e7844e11923e68c638d936896c 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 6a488c535f0a7e6b974812addcb7ff923f81c995..e9b37d6e7243dfd13df68c4675c959442fe49650 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 9a512a9809cf7b47489b3e669aeb671521898f02..c6a4fe4679493862213b27c423f65a04ab356a41 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 090eb36eaa7f894da43056b08868ac7ff28a7711..ae0b0fc03662c9fd118b3eca21183f77c33bd97f 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 06001d60ca8bd5a9b07f9af2dff5d18a9a0382eb..0a76368a3d442068cb6d6dfb11ddc6747779e288 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