diff --git a/es2panda/aot/emitFiles.cpp b/es2panda/aot/emitFiles.cpp index 2066486b77ed1c7db718b60ab0860330748bf80b..5aee2d725542b8bc89087475df57f31b21aff43e 100644 --- a/es2panda/aot/emitFiles.cpp +++ b/es2panda/aot/emitFiles.cpp @@ -25,10 +25,11 @@ void EmitFileQueue::Schedule() { ASSERT(jobsCount_ == 0); std::unique_lock lock(m_); + auto targetApi = static_cast(options_->TargetApiVersion()); if (mergeAbc_) { // generate merged abc - auto emitMergedAbcJob = new EmitMergedAbcJob(options_->CompilerOutput(), progsInfo_); + auto emitMergedAbcJob = new EmitMergedAbcJob(options_->CompilerOutput(), progsInfo_, targetApi); for (const auto &info: progsInfo_) { // generate cache protoBins and set dependencies if (!info.second->needUpdateCache) { @@ -51,7 +52,8 @@ void EmitFileQueue::Schedule() // generate multi abcs auto outputFileName = options_->OutputFiles().empty() ? options_->CompilerOutput() : options_->OutputFiles().at(info.first); - auto emitSingleAbcJob = new EmitSingleAbcJob(outputFileName, &(info.second->program), statp_); + auto emitSingleAbcJob = new EmitSingleAbcJob(outputFileName, &(info.second->program), statp_, + targetApi); jobs_.push_back(emitSingleAbcJob); jobsCount_++; } catch (std::exception &error) { @@ -67,7 +69,7 @@ void EmitFileQueue::Schedule() void EmitSingleAbcJob::Run() { if (!panda::pandasm::AsmEmitter::Emit(panda::os::file::File::GetExtendedFilePath(outputFileName_), *prog_, statp_, - nullptr, true)) { + nullptr, true, nullptr, targetApiVersion_)) { throw Error(ErrorType::GENERIC, "Failed to emit " + outputFileName_ + ", error: " + panda::pandasm::AsmEmitter::GetLastError()); } @@ -84,7 +86,7 @@ void EmitMergedAbcJob::Run() progs.push_back(&(info.second->program)); } if (!panda::pandasm::AsmEmitter::EmitPrograms(panda::os::file::File::GetExtendedFilePath(outputFileName_), progs, - true)) { + true, targetApiVersion_)) { throw Error(ErrorType::GENERIC, "Failed to emit " + outputFileName_ + ", error: " + panda::pandasm::AsmEmitter::GetLastError()); } diff --git a/es2panda/aot/emitFiles.h b/es2panda/aot/emitFiles.h index 808393ecad222c55f84675cab893af092d7e9a6d..ee58996d1bf0a8a7471a6733aed4f471d394c874 100644 --- a/es2panda/aot/emitFiles.h +++ b/es2panda/aot/emitFiles.h @@ -25,8 +25,8 @@ namespace panda::es2panda::aot { class EmitSingleAbcJob : public util::WorkerJob { public: explicit EmitSingleAbcJob(const std::string &outputFileName, panda::pandasm::Program *prog, - std::map *statp) - : outputFileName_(outputFileName), prog_(prog), statp_(statp) {}; + std::map *statp, uint8_t targetApi) + : outputFileName_(outputFileName), prog_(prog), statp_(statp), targetApiVersion_(targetApi) {}; NO_COPY_SEMANTIC(EmitSingleAbcJob); NO_MOVE_SEMANTIC(EmitSingleAbcJob); ~EmitSingleAbcJob() override = default; @@ -36,13 +36,15 @@ private: std::string outputFileName_; panda::pandasm::Program *prog_; std::map *statp_; + uint8_t targetApiVersion_ = 0; }; class EmitMergedAbcJob : public util::WorkerJob { public: explicit EmitMergedAbcJob(const std::string &outputFileName, - const std::map &progsInfo) - : outputFileName_(outputFileName), progsInfo_(progsInfo) {}; + const std::map &progsInfo, + uint8_t targetApi) + : outputFileName_(outputFileName), progsInfo_(progsInfo), targetApiVersion_(targetApi) {}; NO_COPY_SEMANTIC(EmitMergedAbcJob); NO_MOVE_SEMANTIC(EmitMergedAbcJob); ~EmitMergedAbcJob() override = default; @@ -51,6 +53,7 @@ public: private: std::string outputFileName_; const std::map &progsInfo_; + uint8_t targetApiVersion_ = 0; }; class EmitCacheJob : public util::WorkerJob { diff --git a/es2panda/aot/main.cpp b/es2panda/aot/main.cpp index ecb6860511592287dc95f7c440c779c4b0558519..b88738551ca737d09bf20fcbf8ce431d18357047 100644 --- a/es2panda/aot/main.cpp +++ b/es2panda/aot/main.cpp @@ -185,6 +185,21 @@ int Run(int argc, const char **argv) return 0; } + if (options->CompilerOptions().supportedApi) { + panda::panda_file::PrintSupportedApi(); + return 0; + } + + if (options->CompilerOptions().targetArkVersion) { + if (options->CompilerOptions().targetApiVersion != 0) { + panda::panda_file::PrintArkVersionOfTargetApi(options->TargetApiVersion()); + return 0; + } + + std::cout << panda::panda_file::GetVersion(panda::panda_file::version) << std::endl; + return 0; + } + std::map programsInfo; size_t expectedProgsCount = options->CompilerOptions().sourceFiles.size(); panda::ArenaAllocator allocator(panda::SpaceType::SPACE_TYPE_COMPILER, nullptr, true); diff --git a/es2panda/aot/options.cpp b/es2panda/aot/options.cpp index 95085c90674b020d4236b8a1e6ed23ff22511fc8..7f7b5e04bb202f064041bfd6c0f51cc6c188ff5e 100644 --- a/es2panda/aot/options.cpp +++ b/es2panda/aot/options.cpp @@ -227,6 +227,7 @@ bool Options::Parse(int argc, const char **argv) panda::PandArg opCacheFile("cache-file", "", "cache file for incremental compile"); panda::PandArg opNpmModuleEntryList("npm-module-entry-list", "", "entry list file for module compile"); panda::PandArg opMergeAbc("merge-abc", false, "Compile as merge abc"); + panda::PandArg opTargetApiVersion("target-api-version", 0, "Specify the target api version for compilation"); // patchfix && hotreload panda::PandArg opDumpSymbolTable("dump-symbol-table", "", "dump symbol table to file"); @@ -237,8 +238,12 @@ bool Options::Parse(int argc, const char **argv) panda::PandArg opColdFix("cold-fix", false, "generate patch abc as cold-fix mode"); // version - panda::PandArg bcVersion("bc-version", false, "Print ark bytecode version"); + panda::PandArg bcVersion("bc-version", false, "Print ark bytecode maximum supported version"); panda::PandArg bcMinVersion("bc-min-version", false, "Print ark bytecode minimum supported version"); + panda::PandArg supportedApi("supported-api", false, + "Print supported apis and corresponding bytecode versions"); + panda::PandArg targetArkVersion("target-ark-version", false, + "Print ark version of the corresponding target api"); // tail arguments panda::PandArg inputFile("input", "", "input file"); @@ -274,6 +279,7 @@ bool Options::Parse(int argc, const char **argv) argparser_->Add(&opCacheFile); argparser_->Add(&opNpmModuleEntryList); argparser_->Add(&opMergeAbc); + argparser_->Add(&opTargetApiVersion); argparser_->Add(&opDumpSymbolTable); argparser_->Add(&opInputSymbolTable); @@ -283,6 +289,8 @@ bool Options::Parse(int argc, const char **argv) argparser_->Add(&bcVersion); argparser_->Add(&bcMinVersion); + argparser_->Add(&supportedApi); + argparser_->Add(&targetArkVersion); argparser_->PushBackTail(&inputFile); argparser_->EnableTail(); @@ -290,9 +298,15 @@ bool Options::Parse(int argc, const char **argv) bool parseStatus = argparser_->Parse(argc, argv); - if (parseStatus && (bcVersion.GetValue() || bcMinVersion.GetValue())) { + targetApiVersion_ = opTargetApiVersion.GetValue(); + compilerOptions_.targetApiVersion = targetApiVersion_; + + if (parseStatus && (bcVersion.GetValue() || bcMinVersion.GetValue() || + supportedApi.GetValue() || targetArkVersion.GetValue())) { compilerOptions_.bcVersion = bcVersion.GetValue(); compilerOptions_.bcMinVersion = bcMinVersion.GetValue(); + compilerOptions_.supportedApi = supportedApi.GetValue(); + compilerOptions_.targetArkVersion = targetArkVersion.GetValue(); return true; } diff --git a/es2panda/aot/options.h b/es2panda/aot/options.h index 00a2b7cf99dababad808859fec6b9f7ede398e16..e2c7fe81cbbd75863b672796d181555614ecaa31 100644 --- a/es2panda/aot/options.h +++ b/es2panda/aot/options.h @@ -128,6 +128,13 @@ public: } bool CollectInputFilesFromFileList(const std::string &input, const std::string &inputExtension); + + int TargetApiVersion() const + { + return targetApiVersion_; + } + + bool CollectInputFilesFromFileList(const std::string &input); bool CollectInputFilesFromFileDirectory(const std::string &input, const std::string &extension); void ParseCacheFileOption(const std::string &cacheInput); @@ -149,6 +156,7 @@ private: std::string npmModuleEntryList_; std::vector sourceFiles_; std::unordered_map outputFiles_; + int targetApiVersion_ {0}; }; } // namespace panda::es2panda::aot diff --git a/es2panda/compiler/core/compileQueue.cpp b/es2panda/compiler/core/compileQueue.cpp index b35a7c0c174930717058e672b1833fc121346627..961bedba9eb6fac7b2a63345592df56987bed1b9 100644 --- a/es2panda/compiler/core/compileQueue.cpp +++ b/es2panda/compiler/core/compileQueue.cpp @@ -102,7 +102,7 @@ void CompileFileJob::Run() } if (options_->optLevel != 0) { - util::Helpers::OptimizeProgram(prog, src_->fileName); + util::Helpers::OptimizeProgram(prog, src_->fileName, options_->targetApiVersion); } { diff --git a/es2panda/es2panda.h b/es2panda/es2panda.h index a1778653f5c8e369929059fe08b43f1989e707e6..64f841fc20e0b2827d34a82ade414372ee87608a 100644 --- a/es2panda/es2panda.h +++ b/es2panda/es2panda.h @@ -94,6 +94,9 @@ struct CompilerOptions { bool bcVersion {false}; bool bcMinVersion {false}; std::unordered_map cacheFiles; + int targetApiVersion {0}; + bool supportedApi {false}; + bool targetArkVersion {false}; }; enum class ErrorType { diff --git a/es2panda/scripts/ts2abc.js b/es2panda/scripts/ts2abc.js index 310b6a6577907b15d4654ac5be3c5384109c3f78..350b66f58f198f4c589c6ade231f4027924231e1 100755 --- a/es2panda/scripts/ts2abc.js +++ b/es2panda/scripts/ts2abc.js @@ -31,17 +31,17 @@ if (fs.existsSync(path.join(arkDir, 'build-win'))) { throw Error('find build fail').message; } -let js2abc; +let frontendCompiler; if (isWin) { - js2abc = path.join(arkDir, 'build-win', 'bin', 'es2abc.exe'); + frontendCompiler = path.join(arkDir, 'build-win', 'bin', 'es2abc.exe'); } else if (isMac) { - js2abc = path.join(arkDir, 'build-mac', 'bin', 'es2abc'); + frontendCompiler = path.join(arkDir, 'build-mac', 'bin', 'es2abc'); } else { - js2abc = path.join(arkDir, 'build', 'bin', 'es2abc'); + frontendCompiler = path.join(arkDir, 'build', 'bin', 'es2abc'); } function callEs2abc(args) { - let proc = spawn(`${js2abc}`, args); + let proc = spawn(`${frontendCompiler}`, args); proc.stderr.on('data', (data) => { throw Error(`${data}`).message; @@ -53,22 +53,12 @@ function callEs2abc(args) { } let args = process.argv.splice(2); -// keep bc-version to be compatible with old IDE versions -if (args.length == 1 && args[0] == "--bc-version") { +if (args.length == 1 && args[0] == "--bc-version") { // keep bc-version to be compatible with old IDE versions callEs2abc(args); return; } -// hard-coded for now, will be modified later if (args[0] == "--target-api-version") { - if (args[1] == "8") { - process.stdout.write("0.0.0.2"); - } else if (args[1] == "9") { - process.stdout.write("9.0.0.0"); - } else if (args[1] == "10") { - process.stdout.write("9.0.0.0"); - } else { - args = ["--bc-version"]; - callEs2abc(args); - } + args.push("--target-ark-version"); + callEs2abc(args); } diff --git a/es2panda/test/base64/inputFile/expected.txt b/es2panda/test/base64/inputFile/expected.txt index 486c8cb8c615771b786e1364bec9fcf8cc56197e..6cd3f0b089ab56edf37d35dcbb30ea0fd797b4ae 100644 --- a/es2panda/test/base64/inputFile/expected.txt +++ b/es2panda/test/base64/inputFile/expected.txt @@ -11,4 +11,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -UEFOREEAAAAAAAAACQAAAKQBAACMAAAAFQAAAAQAAAA8AAAAAQAAAKABAAAAAAAATAAAAAEAAABMAAAAuwAAAIwAAADhAAAADQEAAIwAAACkAQAAAgAAAHQAAAADAAAAfAAAAAAAAACIAAAAAQAAAIgAAAC7AAAADQEAAKEAAACvAAAAtgAAAD4BAAAnTF9FU1R5cGVBbm5vdGF0aW9uOwAZaGVsbG8gd29ybGQhAAtwcmludAAHc3RyADNMX0VTU2xvdE51bWJlckFubm90YXRpb247AAAAAACAQAAAAgAAJ0xfRVNUeXBlSW5mb1JlY29yZDsAAAAAAAEAAAIAABdmdW5jX21haW5fMAATTF9HTE9CQUw7AAAAAAABAAECAAABAAAAAAEAAIgCAWUBAAACAAWRAQAABlgBAAAA7u4AABFpbnB1dC5qcwAVU2xvdE51bWJlcgAAAAEATAEAAAUAAAA3BwMhAERwRIFEkj4AAEgAAAIAPwEBAGEFPwICAGEGYAUqAwYAZQkLAQIQiQD/////DwAFwgIABhAAAACKAQAA +UEFOREEAAAAAAAAACgAAAKQBAACMAAAAFQAAAAQAAAA8AAAAAQAAAKABAAAAAAAATAAAAAEAAABMAAAAuwAAAIwAAADhAAAADQEAAIwAAACkAQAAAgAAAHQAAAADAAAAfAAAAAAAAACIAAAAAQAAAIgAAAC7AAAADQEAAKEAAACvAAAAtgAAAD4BAAAnTF9FU1R5cGVBbm5vdGF0aW9uOwAZaGVsbG8gd29ybGQhAAtwcmludAAHc3RyADNMX0VTU2xvdE51bWJlckFubm90YXRpb247AAAAAACAQAAAAgAAJ0xfRVNUeXBlSW5mb1JlY29yZDsAAAAAAAEAAAIAABdmdW5jX21haW5fMAATTF9HTE9CQUw7AAAAAAABAAECAAABAAAAAAEAAIgCAWUBAAACAAWRAQAABlgBAAAA7u4AABFpbnB1dC5qcwAVU2xvdE51bWJlcgAAAAEATAEAAAUAAAA3BwMhAERwRIFEkj4AAEgAAAIAPwEBAGEFPwICAGEGYAUqAwYAZQkLAQIQiQD/////DwAFwgIABhAAAACKAQAA diff --git a/es2panda/test/base64/inputString/expected.txt b/es2panda/test/base64/inputString/expected.txt index eba80a89df8635b5713e76dc0d038b5b45de20d7..205f88e37d45781082b4a94ff36e718d846501b3 100644 --- a/es2panda/test/base64/inputString/expected.txt +++ b/es2panda/test/base64/inputString/expected.txt @@ -11,4 +11,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -UEFOREEAAAAAAAAACQAAAJQBAACMAAAAFQAAAAQAAAA8AAAAAQAAAJABAAAAAAAATAAAAAEAAABMAAAAuwAAAIwAAADhAAAADQEAAIwAAACUAQAAAgAAAHQAAAADAAAAfAAAAAAAAACIAAAAAQAAAIgAAAC7AAAADQEAAKEAAACvAAAAtgAAAD4BAAAnTF9FU1R5cGVBbm5vdGF0aW9uOwAZaGVsbG8gd29ybGQhAAtwcmludAAHc3RyADNMX0VTU2xvdE51bWJlckFubm90YXRpb247AAAAAACAQAAAAgAAJ0xfRVNUeXBlSW5mb1JlY29yZDsAAAAAAAEAAAIAABdmdW5jX21haW5fMAATTF9HTE9CQUw7AAAAAAABAAECAAABAAAAAAEAAIgCAVsBAAACAAWEAQAABk4BAAAA7u4AABVTbG90TnVtYmVyAAAAAQBCAQAABQAAADcHAyEARHBEgUSSPgAASAAAAgA/AQEAYQU/AgIAYQZgBSoDBgBlC2uJAP////8PAAEAAAAAAIABAAA= +UEFOREEAAAAAAAAACgAAAJQBAACMAAAAFQAAAAQAAAA8AAAAAQAAAJABAAAAAAAATAAAAAEAAABMAAAAuwAAAIwAAADhAAAADQEAAIwAAACUAQAAAgAAAHQAAAADAAAAfAAAAAAAAACIAAAAAQAAAIgAAAC7AAAADQEAAKEAAACvAAAAtgAAAD4BAAAnTF9FU1R5cGVBbm5vdGF0aW9uOwAZaGVsbG8gd29ybGQhAAtwcmludAAHc3RyADNMX0VTU2xvdE51bWJlckFubm90YXRpb247AAAAAACAQAAAAgAAJ0xfRVNUeXBlSW5mb1JlY29yZDsAAAAAAAEAAAIAABdmdW5jX21haW5fMAATTF9HTE9CQUw7AAAAAAABAAECAAABAAAAAAEAAIgCAVsBAAACAAWEAQAABk4BAAAA7u4AABVTbG90TnVtYmVyAAAAAQBCAQAABQAAADcHAyEARHBEgUSSPgAASAAAAgA/AQEAYQU/AgIAYQZgBSoDBgBlC2uJAP////8PAAEAAAAAAIABAAA= diff --git a/es2panda/util/helpers.cpp b/es2panda/util/helpers.cpp index 3a8f02885759eb47c8ac9e10b23caded35c32825..1897be84a250cb651dd0173b2a99e6a3c2832f08 100644 --- a/es2panda/util/helpers.cpp +++ b/es2panda/util/helpers.cpp @@ -630,7 +630,7 @@ SignedNumberLiteral Helpers::GetSignedNumberLiteral(const ir::Expression *expr) return SignedNumberLiteral::UNRECOGNIZED; } -void Helpers::OptimizeProgram(panda::pandasm::Program *prog, const std::string &inputFile) +bool Helpers::OptimizeProgram(panda::pandasm::Program *prog, const std::string &inputFile, int targetApiVersion) { std::map stat; std::map *statp = &stat; @@ -651,12 +651,15 @@ void Helpers::OptimizeProgram(panda::pandasm::Program *prog, const std::string #endif const std::string outputSuffix = ".unopt.abc"; std::string tempOutput = panda::os::file::File::GetExtendedFilePath(inputFile + pid + outputSuffix); - if (panda::pandasm::AsmEmitter::Emit(tempOutput, *prog, statp, mapsp, true)) { + if (panda::pandasm::AsmEmitter::Emit(tempOutput, *prog, statp, mapsp, true, nullptr, targetApiVersion)) { panda::bytecodeopt::OptimizeBytecode(prog, mapsp, tempOutput, true, true); + } else { + return false; } std::remove(tempOutput.c_str()); #endif + return true; } bool Helpers::ReadFileToBuffer(const std::string &file, std::stringstream &ss) diff --git a/es2panda/util/helpers.h b/es2panda/util/helpers.h index dc746454cbfb3e3d77c2e0d5287ab96f7a391f53..43992198497ba286b81b85af13257c7aa4e0fe56 100644 --- a/es2panda/util/helpers.h +++ b/es2panda/util/helpers.h @@ -95,7 +95,7 @@ public: static bool IsObjectPropertyValue(const ArenaVector &properties, const ir::AstNode *ident); static SignedNumberLiteral GetSignedNumberLiteral(const ir::Expression *expr); - static void OptimizeProgram(panda::pandasm::Program *prog, const std::string &inputFile); + static bool OptimizeProgram(panda::pandasm::Program *prog, const std::string &inputFile, int targetApiVersion); template static T BaseName(T const &path, T const &delims = std::string(panda::os::file::File::GetPathDelim())); static bool ReadFileToBuffer(const std::string &file, std::stringstream &ss); diff --git a/merge_abc/src/main.cpp b/merge_abc/src/main.cpp index 6df5188f8fe5387071f1a5af4d8ba7dc7bd40cfb..b661d4388557771ea585a530d18e6ab1c4966780 100644 --- a/merge_abc/src/main.cpp +++ b/merge_abc/src/main.cpp @@ -80,8 +80,9 @@ int Run(int argc, const char **argv) std::string outputFileName = outputFilePath.append(panda::os::file::File::GetPathDelim()). append(options->outputFileName()); + auto targetApi = static_cast(options->TargetApiVersion()); if (!panda::pandasm::AsmEmitter::EmitPrograms(panda::os::file::File::GetExtendedFilePath(outputFileName), programs, - true)) { + true, targetApi)) { return 1; } diff --git a/merge_abc/src/options.cpp b/merge_abc/src/options.cpp index 0745e103d66f06311922fb3a96e6148794193bde..907fc91d6a3654741e5aed7c5b8c8131d9cd90c3 100644 --- a/merge_abc/src/options.cpp +++ b/merge_abc/src/options.cpp @@ -36,12 +36,14 @@ bool Options::Parse(int argc, const char **argv) panda::PandArg protoBinSuffix("suffix", "", "suffix of proto bin file"); panda::PandArg outputFileName("output", "", "name of merged panda file"); panda::PandArg outputFilePath("outputFilePath", "", "output path for merged panda file"); + panda::PandArg targetApiVersion("target-api-version", 0, "Specify the target api version for compilation"); argparser_->Add(&opHelp); argparser_->Add(&protoPathInput); argparser_->Add(&protoBinSuffix); argparser_->Add(&outputFileName); argparser_->Add(&outputFilePath); + argparser_->Add(&targetApiVersion); if (!argparser_->Parse(argc, argv) || opHelp.GetValue() || protoPathInput.GetValue().empty()) { std::stringstream ss; @@ -68,6 +70,9 @@ bool Options::Parse(int argc, const char **argv) if (!outputFilePath.GetValue().empty()) { outputFilePath_ = outputFilePath.GetValue(); } + if (targetApiVersion.GetValue()) { + targetApiVersion_ = targetApiVersion.GetValue(); + } return true; } diff --git a/merge_abc/src/options.h b/merge_abc/src/options.h index 8475ab1d20515beba5af1d11809f3a69c6b172cd..be8c181e41c5dea5f5425e3e6feb00eb2b4d12cb 100644 --- a/merge_abc/src/options.h +++ b/merge_abc/src/options.h @@ -55,6 +55,10 @@ public: return errorMsg_; } + int TargetApiVersion() const + { + return targetApiVersion_; + } private: panda::PandArgParser *argparser_; std::string errorMsg_; @@ -62,6 +66,7 @@ private: std::string protoPathInput_; std::string outputFileName_ {"modules.abc"}; std::string outputFilePath_; + int targetApiVersion_ {0}; }; } // panda::proto #endif