diff --git a/es2panda/compiler/core/compilerContext.cpp b/es2panda/compiler/core/compilerContext.cpp index 32d6a6e3d84b1fdde3fdae79b92264a62442bb45..c9e1f96468355a8b67af0380b6afebf8679c9cf9 100644 --- a/es2panda/compiler/core/compilerContext.cpp +++ b/es2panda/compiler/core/compilerContext.cpp @@ -22,10 +22,11 @@ namespace panda::es2panda::compiler { CompilerContext::CompilerContext(binder::Binder *binder, bool isDebug, bool isDebuggerEvaluateExpressionMode, bool isMergeAbc, bool isTypeExtractorEnabled, bool isJsonInputFile, - std::string sourceFile, std::string pkgName, util::StringView recordName) + std::string sourceFile, std::string pkgName, util::StringView recordName, + util::Hotfix *hotfixHelper) : binder_(binder), isDebug_(isDebug), isDebuggerEvaluateExpressionMode_(isDebuggerEvaluateExpressionMode), isMergeAbc_(isMergeAbc), isTypeExtractorEnabled_(isTypeExtractorEnabled), isJsonInputFile_(isJsonInputFile), - sourceFile_(sourceFile), pkgName_(pkgName), recordName_(recordName), + sourceFile_(sourceFile), pkgName_(pkgName), recordName_(recordName), hotfixHelper_(hotfixHelper), emitter_(std::make_unique(this)) { } diff --git a/es2panda/compiler/core/compilerContext.h b/es2panda/compiler/core/compilerContext.h index 2cd7829f8dd53109d2a261860ca2703efd442293..a6af7ed4b069e8f402798b83740b5a4ad5747039 100644 --- a/es2panda/compiler/core/compilerContext.h +++ b/es2panda/compiler/core/compilerContext.h @@ -44,7 +44,7 @@ class CompilerContext { public: CompilerContext(binder::Binder *binder, bool isDebug, bool isDebuggerEvaluateExpressionMode, bool isMergeAbc, bool isTypeExtractorEnabled, bool isJsonInputFile, std::string sourceFile, - std::string pkgName, util::StringView recordName); + std::string pkgName, util::StringView recordName, util::Hotfix *hotfixHelper); NO_COPY_SEMANTIC(CompilerContext); NO_MOVE_SEMANTIC(CompilerContext); ~CompilerContext() = default; @@ -100,12 +100,7 @@ public: return pkgName_; } - void AddHotfixHelper(util::Hotfix *hotfixHelper) - { - hotfixHelper_ = hotfixHelper; - } - - util::Hotfix *HotfixHelper() + util::Hotfix *HotfixHelper() const { return hotfixHelper_; } @@ -147,8 +142,8 @@ private: std::string sourceFile_; std::string pkgName_; util::StringView recordName_; - std::unique_ptr emitter_; util::Hotfix *hotfixHelper_ {nullptr}; + std::unique_ptr emitter_; }; } // namespace panda::es2panda::compiler diff --git a/es2panda/compiler/core/compilerImpl.cpp b/es2panda/compiler/core/compilerImpl.cpp index ceb33745a1121e61122acf4f07a73d2f909c9b53..92ae2f4116783303ce1e0bf74477ffc0c2e995c4 100644 --- a/es2panda/compiler/core/compilerImpl.cpp +++ b/es2panda/compiler/core/compilerImpl.cpp @@ -41,11 +41,7 @@ panda::pandasm::Program *CompilerImpl::Compile(parser::Program *program, const e { CompilerContext context(program->Binder(), options.isDebug, options.isDebuggerEvaluateExpressionMode, options.mergeAbc, options.typeExtractor, false, debugInfoSourceFile, pkgName, - program->RecordName()); - - if (hotfixHelper_ != nullptr) { - context.AddHotfixHelper(hotfixHelper_); - } + program->RecordName(), hotfixHelper_); ArenaAllocator localAllocator(SpaceType::SPACE_TYPE_COMPILER, nullptr, true); diff --git a/es2panda/compiler/core/emitter/emitter.cpp b/es2panda/compiler/core/emitter/emitter.cpp index 7e179b2fb8b9df0bcf4d6bde8513bace3892f1fd..4c17c862820bf9a097e191c960592822cfdc3090 100644 --- a/es2panda/compiler/core/emitter/emitter.cpp +++ b/es2panda/compiler/core/emitter/emitter.cpp @@ -351,6 +351,9 @@ void Emitter::GenJsonContentRecord(const CompilerContext *context) jsonContentField.metadata->SetValue(panda::pandasm::ScalarValue::Create( static_cast(context->SourceFile()))); rec_->field_list.emplace_back(std::move(jsonContentField)); + if (context->HotfixHelper()) { + context->HotfixHelper()->ProcessJsonContentRecord(rec_->name, context->SourceFile()); + } } void Emitter::AddFunction(FunctionEmitter *func, CompilerContext *context) diff --git a/es2panda/es2panda.cpp b/es2panda/es2panda.cpp index d65c8ea77fd76461a842fe0dd1008dca5c007ccc..39955c6d15fab58731cfd276c1a4d0b068a69799 100644 --- a/es2panda/es2panda.cpp +++ b/es2panda/es2panda.cpp @@ -52,10 +52,10 @@ Compiler::~Compiler() delete compiler_; } -panda::pandasm::Program *createJsonContentProgram(std::string src, std::string rname) +panda::pandasm::Program *CreateJsonContentProgram(std::string src, std::string rname, util::Hotfix *hotfixHelper) { panda::es2panda::compiler::CompilerContext context(nullptr, false, false, false, false, true, - src, "", util::StringView(rname)); + src, "", util::StringView(rname), hotfixHelper); return context.GetEmitter()->Finalize(false, nullptr); } @@ -70,9 +70,6 @@ panda::pandasm::Program *Compiler::Compile(const SourceFile &input, const Compil std::string pkgName(input.pkgName); parser::ScriptKind kind(input.scriptKind); - if (fname.substr(fname.find_last_of(".") + 1) == "json") { - return createJsonContentProgram(src, rname); - } bool needDumpSymbolFile = !options.hotfixOptions.dumpSymbolTable.empty(); bool needGeneratePatch = options.hotfixOptions.generatePatch && !options.hotfixOptions.symbolTable.empty(); @@ -83,6 +80,10 @@ panda::pandasm::Program *Compiler::Compile(const SourceFile &input, const Compil compiler_->AddHotfixHelper(hotfixHelper); } + if (fname.substr(fname.find_last_of(".") + 1) == "json") { + return CreateJsonContentProgram(src, rname, hotfixHelper); + } + try { auto ast = parser_->Parse(fname, src, rname, kind); ast.Binder()->SetProgram(&ast); diff --git a/es2panda/util/hotfix.cpp b/es2panda/util/hotfix.cpp index b7aefc3c1d3a3f64d126542abac9e5c3942980c5..090eb36eaa7f894da43056b08868ac7ff28a7711 100644 --- a/es2panda/util/hotfix.cpp +++ b/es2panda/util/hotfix.cpp @@ -59,6 +59,19 @@ void Hotfix::ProcessModule(const std::string &recordName, } } +void Hotfix::ProcessJsonContentRecord(const std::string &recordName, const std::string &jsonFileContent) +{ + if (generateSymbolFile_) { + DumpJsonContentRecInfo(recordName, jsonFileContent); + return; + } + + if (generatePatch_) { + ValidateJsonContentRecInfo(recordName, jsonFileContent); + return; + } +} + void Hotfix::DumpModuleInfo(const std::string &recordName, std::vector &moduleBuffer) { @@ -88,6 +101,34 @@ void Hotfix::ValidateModuleInfo(const std::string &recordName, } } +void Hotfix::DumpJsonContentRecInfo(const std::string &recordName, const std::string &jsonFileContent) +{ + std::stringstream ss; + ss << recordName << SymbolTable::SECOND_LEVEL_SEPERATOR; + auto hash = std::hash{}(jsonFileContent); + ss << hash << std::endl; + symbolTable_->WriteSymbolTable(ss.str()); +} + +void Hotfix::ValidateJsonContentRecInfo(const std::string &recordName, const std::string &jsonFileContent) +{ + auto it = originModuleInfo_->find(recordName); + if (it == originModuleInfo_->end()) { + std::cerr << "[Patch] Found new import/require json file expression in " << recordName + << ", not supported!" << std::endl; + patchError_ = true; + return; + } + + auto hash = std::hash{}(jsonFileContent); + if (std::to_string(hash) != it->second) { + std::cerr << "[Patch] Found imported/required json file content changed in " << recordName + << ", not supported!" << std::endl; + patchError_ = true; + return; + } +} + bool Hotfix::IsAnonymousOrDuplicateNameFunction(const std::string &funcName) { return funcName.find(ANONYMOUS_OR_DUPLICATE_FUNCTION_SPECIFIER) != std::string::npos; diff --git a/es2panda/util/hotfix.h b/es2panda/util/hotfix.h index 36e06ddb51843b832ac2c105c4423a90ed3aaa7a..06001d60ca8bd5a9b07f9af2dff5d18a9a0382eb 100644 --- a/es2panda/util/hotfix.h +++ b/es2panda/util/hotfix.h @@ -63,6 +63,7 @@ public: bool IsPatchVar(uint32_t slot); void ProcessFunction(const compiler::PandaGen *pg, panda::pandasm::Function *func, LiteralBuffers &literalBuffers); void ProcessModule(const std::string &recordName, std::vector &moduleBuffer); + void ProcessJsonContentRecord(const std::string &recordName, const std::string &jsonFileContent); private: void DumpFunctionInfo(const compiler::PandaGen *pg, panda::pandasm::Function *func, LiteralBuffers &literalBuffers); @@ -72,6 +73,8 @@ private: void DumpModuleInfo(const std::string &recordName, std::vector &moduleBuffer); void ValidateModuleInfo(const std::string &recordName, std::vector &moduleBuffer); + void DumpJsonContentRecInfo(const std::string &recordName, const std::string &jsonFileContent); + void ValidateJsonContentRecInfo(const std::string &recordName, const std::string &jsonFileContent); std::string ExpandLiteral(int64_t bufferIdx, LiteralBuffers &literalBuffers); std::string ConvertLiteralToString(std::vector &literalBuffer);