diff --git a/es2panda/aot/options.cpp b/es2panda/aot/options.cpp index 43aa8e3122b723ab486bf577a5a71ea77694a9aa..5ba41776c957e8af0fab4a9f1bffe7cc3f204395 100644 --- a/es2panda/aot/options.cpp +++ b/es2panda/aot/options.cpp @@ -273,6 +273,57 @@ void Options::ParseUpdateVersionInfo(nlohmann::json &compileContextInfoJson) } } +void Options::ParseAbcCompileContextInfo(const std::string compileAbcContextInfoPath) +{ + std::stringstream ss; + std::string buffer; + if (!util::Helpers::ReadFileToBuffer(compileAbcContextInfoPath, ss)) { + return; + } + + buffer = ss.str(); + if (buffer.empty() || !nlohmann::json::accept(buffer)) { + std::cerr << "The input file '" << compileAbcContextInfoPath <<"' is incomplete format of json" << std::endl; + return; + } + // Parser compile context info base on the input json file. + nlohmann::json compileContextInfoJson = nlohmann::json::parse(buffer); + + if (compileContextInfoJson.contains("packageName") && + compileContextInfoJson["packageName"].is_string()) { + compilerOptions_.compileAbcContextInfo.packageName = compileContextInfoJson["packageName"]; + } + if (compileContextInfoJson.contains("originVersion") && + compileContextInfoJson["originVersion"].is_string()) { + compilerOptions_.compileAbcContextInfo.originVersion = compileContextInfoJson["originVersion"]; + } + if (compileContextInfoJson.contains("targetVersion") && + compileContextInfoJson["targetVersion"].is_string()) { + compilerOptions_.compileAbcContextInfo.targetVersion = compileContextInfoJson["targetVersion"]; + } + if (compileContextInfoJson.contains("updateVersionInfo") && + compileContextInfoJson["updateVersionInfo"].is_object()) { + std::unordered_map> updateVersionInfo {}; + std::map pkgContextMap {}; + + for (const auto& [pkgName, version] : compileContextInfoJson["updateVersionInfo"].items()) { + PkgInfo pkgInfo; + pkgInfo.version = version; + pkgInfo.packageName = pkgName; + pkgContextMap[pkgName] = pkgInfo; + } + updateVersionInfo[compilerOptions_.compileAbcContextInfo.packageName] = pkgContextMap; + compilerOptions_.compileAbcContextInfo.updateVersionInfo = updateVersionInfo; + } + + std::cerr << "[DEBUG] Parsed packageName = " << compilerOptions_.compileAbcContextInfo.packageName << std::endl; + std::cerr << "[DEBUG] updateVersionInfo contains keys: "; + for (const auto& [key, _] : compilerOptions_.compileAbcContextInfo.updateVersionInfo) { + std::cerr << key << " "; + } + std::cerr << std::endl; +} + void Options::ParseCompileContextInfo(const std::string compileContextInfoPath) { std::stringstream ss; @@ -439,6 +490,8 @@ bool Options::Parse(int argc, const char **argv) // compile entries and pkg context info panda::PandArg compileContextInfoPath("compile-context-info", "", "The path to compile context"\ "info file"); + panda::PandArg compileAbcContextInfoPath("compile-abc-context-info", "", "The path to compile abc"\ + "context info file"); panda::PandArg opDumpDepsInfo("dump-deps-info", false, "Dump all dependency files and records "\ "including source files and bytecode files"); panda::PandArg opRemoveRedundantFile("remove-redundant-file", false, "Remove redundant info"\ @@ -519,6 +572,7 @@ bool Options::Parse(int argc, const char **argv) argparser_->Add(&enableAnnotations); argparser_->Add(&compileContextInfoPath); + argparser_->Add(&compileAbcContextInfoPath); argparser_->Add(&opDumpDepsInfo); argparser_->Add(&opRemoveRedundantFile); argparser_->Add(&opDumpString); @@ -725,6 +779,10 @@ bool Options::Parse(int argc, const char **argv) if (!compileContextInfoPath.GetValue().empty()) { ParseCompileContextInfo(compileContextInfoPath.GetValue()); } + compilerOptions_.compileAbcContextInfoPath = compileAbcContextInfoPath.GetValue(); + if (!compileAbcContextInfoPath.GetValue().empty()) { + ParseAbcCompileContextInfo(compileAbcContextInfoPath.GetValue()); + } compilerOptions_.dumpDepsInfo = opDumpDepsInfo.GetValue(); compilerOptions_.updatePkgVersionForAbcInput = compilerOptions_.enableAbcInput && (!compilerOptions_.compileContextInfo.pkgContextInfo.empty() || diff --git a/es2panda/aot/options.h b/es2panda/aot/options.h index 6f2291732cebde73f29f8a83d4eb3fde758a3fcc..d729fda1ad1b946a0d714c4fe58bd90762b70c73 100644 --- a/es2panda/aot/options.h +++ b/es2panda/aot/options.h @@ -149,6 +149,7 @@ public: bool CollectInputFilesFromFileDirectory(const std::string &input, const std::string &extension); void ParseCacheFileOption(const std::string &cacheInput); void ParseCompileContextInfo(const std::string compileContextInfoPath); + void ParseAbcCompileContextInfo(const std::string compileAbcContextInfoPath); bool NeedCollectDepsRelation(); bool NeedRemoveRedundantRecord(); diff --git a/es2panda/compiler/core/compileQueue.cpp b/es2panda/compiler/core/compileQueue.cpp index 46739bbe065190ecd939991800ede55b94b031b8..75d47b35fdec0e146bb3683c8f5e5bd43b648025 100644 --- a/es2panda/compiler/core/compileQueue.cpp +++ b/es2panda/compiler/core/compileQueue.cpp @@ -237,6 +237,18 @@ void CompileAbcClassJob::Run() if (!options_.modifiedPkgName.empty()) { UpdatePkgNameOfImportOhmurl(program, options_); } + + if (!options_.compileAbcContextInfoPath.empty()) { + UpdateAbcImportOhmurl(program, options_); + if (hasOhmurlBeenChanged_) { + program->strings.clear(); + for (const auto &[_, function] : program->function_table) { + const auto &funcStringSet = function.CollectStringsFromFunctionInsns(); + program->strings.insert(funcStringSet.begin(), funcStringSet.end()); + } + } + } + // Update ohmurl for abc input when needed if (options_.compileContextInfo.needModifyRecord || (options_.updatePkgVersionForAbcInput && pkgVersionUpdateRequiredInAbc_)) { @@ -333,6 +345,26 @@ void CompileAbcClassJob::UpdateImportOhmurl(panda::pandasm::Program *prog, // Replace for dynamic import UpdateDynamicImport(prog, pkgContextInfo); } + +void CompileAbcClassJob::UpdateAbcImportOhmurl(panda::pandasm::Program *prog, + const panda::es2panda::CompilerOptions &options) +{ + const auto &updateVersionInfo = options.compileAbcContextInfo.updateVersionInfo; + const std::string &pkgName = options.compileAbcContextInfo.packageName; + + auto it = updateVersionInfo.find(pkgName); + if (it == updateVersionInfo.end()) { + std::cerr << "Error: package name not found in updateVersionInfo: " << pkgName << std::endl; + return; + } + + const auto &pkgContextInfo = it->second; + // Replace for esm module static import + UpdateStaticImport(prog, pkgContextInfo); + // Replace for dynamic import + UpdateDynamicImport(prog, pkgContextInfo); +} + /** * Need to modify the package name of the original package to the package name of the target package when * you merging two packages. diff --git a/es2panda/compiler/core/compileQueue.h b/es2panda/compiler/core/compileQueue.h index d0bd89cce4b308ab012d8f554966ca7d1cf7818a..2f99cc0f61eb826a7dfcce7128398c7a828d501c 100644 --- a/es2panda/compiler/core/compileQueue.h +++ b/es2panda/compiler/core/compileQueue.h @@ -122,6 +122,7 @@ public: hasOhmurlBeenChanged_ = hasOhmurlBeenChanged; } void UpdatePkgNameOfImportOhmurl(panda::pandasm::Program *prog, const panda::es2panda::CompilerOptions &options); + void UpdateAbcImportOhmurl(panda::pandasm::Program *prog, const panda::es2panda::CompilerOptions &options); NO_COPY_SEMANTIC(CompileAbcClassJob); NO_MOVE_SEMANTIC(CompileAbcClassJob); diff --git a/es2panda/es2panda.cpp b/es2panda/es2panda.cpp index ddd62b5d9ed6c5e269071188dafac115873cdcd9..d7c492b0ab696dff2894d0a91a8b1fe8adc59bd1 100644 --- a/es2panda/es2panda.cpp +++ b/es2panda/es2panda.cpp @@ -111,6 +111,10 @@ void Compiler::CompileAbcFileInParallel(SourceFile *src, const CompilerOptions & if (!options.modifiedPkgName.empty()) { abcToAsmCompiler_->SetModifyPkgName(options.modifiedPkgName); } + if (!options.compileAbcContextInfoPath.empty()) { + abcToAsmCompiler_->SetFixOriginVersion(options.compileAbcContextInfo.originVersion); + abcToAsmCompiler_->SetFixTargetVersion(options.compileAbcContextInfo.targetVersion); + } auto *compileAbcClassQueue = new compiler::CompileAbcClassQueue(options.abcClassThreadCount, options, diff --git a/es2panda/es2panda.h b/es2panda/es2panda.h index f8150524b96f08c20f934713fd3a97b72a564428..5b5522b9544c7ec503673d05682c2bc069b40be7 100644 --- a/es2panda/es2panda.h +++ b/es2panda/es2panda.h @@ -117,6 +117,8 @@ struct CompilerOptions { bool requireGlobalOptimization {false}; std::string compileContextInfoPath {}; CompileContextInfo compileContextInfo {}; + std::string compileAbcContextInfoPath {}; + CompileAbcContextInfo compileAbcContextInfo {}; bool dumpDepsInfo {false}; bool updatePkgVersionForAbcInput {false}; bool removeRedundantFile {false}; diff --git a/es2panda/util/helpers.h b/es2panda/util/helpers.h index 3be95c36ddd3be614db19e529a5157302fbb4810..7bc39c2549a5d229ceec1881391ac31b8a9f8c47 100644 --- a/es2panda/util/helpers.h +++ b/es2panda/util/helpers.h @@ -61,6 +61,13 @@ struct CompileContextInfo { bool needModifyRecord {false}; std::string bundleName {}; }; + +struct CompileAbcContextInfo { + std::string packageName {}; + std::string originVersion {}; + std::string targetVersion {}; + std::unordered_map> updateVersionInfo {}; +}; } // namespace panda::es2panda namespace panda::es2panda::binder {