diff --git a/.gitee/PULL_REQUEST_TEMPLATE.en.md b/.gitee/PULL_REQUEST_TEMPLATE.en.md new file mode 100644 index 0000000000000000000000000000000000000000..22132a108f93576803d5029642f287fd6e591b6c --- /dev/null +++ b/.gitee/PULL_REQUEST_TEMPLATE.en.md @@ -0,0 +1,18 @@ +### 1. Issue + + +### 2. Description + + +### 3. Check list + +If PR has one of the following changes, then PR needs the approval of @qiuyu22. + +- [ ] PR changes file format (such as addition, deletion or modification of the file structures) +- [ ] PR changes bytecode set (such as addition, deletion or modification of the current bytecode set) +- [ ] PR changes file items (such as addition, deletion or modification of the field, annotation, literalarray) +- [ ] PR introduces unstable data structures that can cause inconsistency of abc files +- [ ] PR supports new feature so that some new test262 tests should be enabled +- [ ] PR changes the format of cache files + +### 4. Test Results diff --git a/es2panda/aot/emitFiles.cpp b/es2panda/aot/emitFiles.cpp index 462708ae154de485035f100c6a789f68aab4c18d..dbf01af2393ecd3ca88ce27453e40908ec44ab7a 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()); // generate abcs if (mergeAbc_) { - auto emitMergedAbcJob = new EmitMergedAbcJob(options_->CompilerOutput(), progsInfo_); + auto emitMergedAbcJob = new EmitMergedAbcJob(options_->CompilerOutput(), progsInfo_, targetApi); jobs_.push_back(emitMergedAbcJob); jobsCount_++; } else { @@ -36,7 +37,8 @@ void EmitFileQueue::Schedule() try { 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) { @@ -65,7 +67,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()); } @@ -79,7 +81,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..ba6356038098b0d2089fe51fcc7881ec39c1bff8 100644 --- a/es2panda/aot/main.cpp +++ b/es2panda/aot/main.cpp @@ -185,6 +185,11 @@ int Run(int argc, const char **argv) return 0; } + if (options->CompilerOptions().supportedApi) { + panda::panda_file::PrintSupportedApi(); + 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 ec8d03070c9e46b2e809f72cc2b1b5e2ecc8d005..f97e98bb635e53e6b4cd0c16e3d162500c0ed162 100644 --- a/es2panda/aot/options.cpp +++ b/es2panda/aot/options.cpp @@ -226,6 +226,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"); // hotfix && hotreload panda::PandArg opDumpSymbolTable("dump-symbol-table", "", "dump symbol table to file"); @@ -234,8 +235,10 @@ bool Options::Parse(int argc, const char **argv) panda::PandArg opHotReload("hot-reload", false, "compile as hot-reload 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"); // tail arguments panda::PandArg inputFile("input", "", "input file"); @@ -271,6 +274,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); @@ -279,6 +283,7 @@ bool Options::Parse(int argc, const char **argv) argparser_->Add(&bcVersion); argparser_->Add(&bcMinVersion); + argparser_->Add(&supportedApi); argparser_->PushBackTail(&inputFile); argparser_->EnableTail(); @@ -286,9 +291,10 @@ bool Options::Parse(int argc, const char **argv) bool parseStatus = argparser_->Parse(argc, argv); - if (parseStatus && (bcVersion.GetValue() || bcMinVersion.GetValue())) { + if (parseStatus && (bcVersion.GetValue() || bcMinVersion.GetValue() || supportedApi.GetValue())) { compilerOptions_.bcVersion = bcVersion.GetValue(); compilerOptions_.bcMinVersion = bcMinVersion.GetValue(); + compilerOptions_.supportedApi = supportedApi.GetValue(); return true; } @@ -429,6 +435,8 @@ bool Options::Parse(int argc, const char **argv) options_ |= OptionFlags::SIZE_STAT; } + targetApiVersion_ = opTargetApiVersion.GetValue(); + compilerOptions_.dumpAsm = opDumpAssembly.GetValue(); compilerOptions_.dumpAst = opDumpAst.GetValue(); compilerOptions_.dumpTransformedAst = opDumpTransformedAst.GetValue(); @@ -448,6 +456,7 @@ bool Options::Parse(int argc, const char **argv) base64Output.GetValue()) ? 0 : opOptLevel.GetValue(); compilerOptions_.sourceFiles = sourceFiles_; compilerOptions_.mergeAbc = opMergeAbc.GetValue(); + compilerOptions_.targetApiVersion = targetApiVersion_; compilerOptions_.hotfixOptions.dumpSymbolTable = opDumpSymbolTable.GetValue(); compilerOptions_.hotfixOptions.symbolTable = opInputSymbolTable.GetValue(); 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 48083b4c093b3906f88797c50915516d388ffda2..2808005a726b7e923309be379cf3401b2d8b54d6 100644 --- a/es2panda/compiler/core/compileQueue.cpp +++ b/es2panda/compiler/core/compileQueue.cpp @@ -103,7 +103,9 @@ void CompileFileJob::Run() if (src_->scriptKind != parser::ScriptKind::COMMONJS && options_->optLevel != 0) { // common-js files has hidden parameters which cause optimizer abort, skip optimizing them. - util::Helpers::OptimizeProgram(prog, src_->fileName); + if (!util::Helpers::OptimizeProgram(prog, src_->fileName, options_->targetApiVersion)) { + return; + } } { diff --git a/es2panda/es2panda.h b/es2panda/es2panda.h index 28e8fbae687b6daa5883bee971e457a8395195f0..1a2da20c11f848ee1ffad23ee627b9bb749153e4 100644 --- a/es2panda/es2panda.h +++ b/es2panda/es2panda.h @@ -93,6 +93,8 @@ struct CompilerOptions { bool bcVersion {false}; bool bcMinVersion {false}; std::unordered_map cacheFiles; + int targetApiVersion {0}; + bool supportedApi {false}; }; enum class ErrorType { diff --git a/es2panda/util/helpers.cpp b/es2panda/util/helpers.cpp index ee9c5277f7e09f8751bc5be9e0c9dc371ba6d3da..c5ec35aad367c50b4adb4f45d81a0a031f2c05b8 100644 --- a/es2panda/util/helpers.cpp +++ b/es2panda/util/helpers.cpp @@ -486,7 +486,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; @@ -507,12 +507,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 6ba2b9559da6f8e06d1612fcaad321b6d102c059..ededa44d70bc423bbada58fb2c2fb3bd6fc68531 100644 --- a/es2panda/util/helpers.h +++ b/es2panda/util/helpers.h @@ -87,7 +87,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 diff --git a/ts2panda/src/cmdOptions.ts b/ts2panda/src/cmdOptions.ts index ff02ad83b28dcce341b9126eb024f3734da9b7d7..62c3e3d470c6b44c500c8f9955514997dd627330 100644 --- a/ts2panda/src/cmdOptions.ts +++ b/ts2panda/src/cmdOptions.ts @@ -56,7 +56,8 @@ export const ts2pandaOptions = [ { name: 'output-proto', type: Boolean, defaultValue: false, description: "Output protoBin file. Default: false" }, { name: 'merge-abc', type: Boolean, defaultValue: false, description: "Compile as merge abc" }, { name: 'input-file', type: String, defaultValue: "", description: "A file containing a list of source files to be compiled. Each line of this file should be constructed in such format: fileName;recordName;moduleType;sourceFile;packageName" }, - { name: 'oh-modules', type: Boolean, defaultValue: false, description: "Set oh-modules as typescript compiler's package manager type. Default: false" } + { name: 'oh-modules', type: Boolean, defaultValue: false, description: "Set oh-modules as typescript compiler's package manager type. Default: false" }, + { name: 'target-api-version', type: Number, defaultValue: 0, description: "Specify the target api version for compilation" } ] @@ -376,6 +377,13 @@ export class CmdOptions { return this.options["oh-modules"] } + static getTargetApiVersion(): number { + if (!this.options) { + return 0; + } + return this.options["target-api-version"]; + } + // @ts-ignore static parseUserCmd(args: string[]): ts.ParsedCommandLine | undefined { this.options = commandLineArgs(ts2pandaOptions, { partial: true }); diff --git a/ts2panda/src/ts2panda.ts b/ts2panda/src/ts2panda.ts index ebd5130d632e0f1d8468a7a8226a28f32e94912e..22a8d5629a98c40eefd8cbb760b91ea5f1c04cda 100644 --- a/ts2panda/src/ts2panda.ts +++ b/ts2panda/src/ts2panda.ts @@ -253,7 +253,8 @@ export class Ts2Panda { "is_dts_file": isGlobalDeclare(), "output-proto": CmdOptions.isOutputproto(), "record_type": enableRecordType, - "input-file": CmdOptions.getCompileFilesList() + "input-file": CmdOptions.getCompileFilesList(), + "target-api-version": CmdOptions.getTargetApiVersion() }; let jsonOpt = JSON.stringify(options, null, 2); jsonOpt = "$" + jsonOpt.replace(dollarSign, '#$') + "$"; diff --git a/ts2panda/ts2abc/ts2abc.cpp b/ts2panda/ts2abc/ts2abc.cpp index d4a612e2a253444956e233fd8c9dd22a349681b3..9035ac07c20079da9fcb6f0e50a94188a9a78606 100644 --- a/ts2panda/ts2abc/ts2abc.cpp +++ b/ts2panda/ts2abc/ts2abc.cpp @@ -69,6 +69,7 @@ std::unordered_map g_opcodeMap = { #undef OPLIST {-1, panda::pandasm::Opcode::INVALID}, }; +int g_targetApiVersion = 0; // pandasm helpers static panda::pandasm::Record MakeRecordDefinition(const std::string &name) @@ -1034,6 +1035,13 @@ static void ParseCompilerOutputProto(const Json::Value &rootValue) } } +static void ParseTargetApiVersion(const Json::Value &rootValue) +{ + if (rootValue.isMember("target-api-version") && rootValue["target-api-version"].isInt()) { + g_targetApiVersion = rootValue["target-api-version"].asInt(); + } +} + static void ReplaceAllDistinct(std::string &str, const std::string &oldValue, const std::string &newValue) { for (std::string::size_type pos(0); pos != std::string::npos; pos += newValue.length()) { @@ -1060,6 +1068,7 @@ static void ParseOptions(const Json::Value &rootValue, panda::pandasm::Program & ParseIsDtsFile(rootValue); ParseEnableTypeInfo(rootValue); ParseCompilerOutputProto(rootValue); + ParseTargetApiVersion(rootValue); } static void ParseSingleFunc(const Json::Value &rootValue, panda::pandasm::Program &prog) @@ -1459,7 +1468,8 @@ static bool EmitProgram(const std::string &output, int optLevel, std::string opt panda::pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps {}; panda::pandasm::AsmEmitter::PandaFileToPandaAsmMaps* mapsp = &maps; - if (!panda::pandasm::AsmEmitter::Emit(convertedFilePath, prog, statp, mapsp, emitDebugInfo)) { + if (!panda::pandasm::AsmEmitter::Emit(convertedFilePath, prog, statp, mapsp, emitDebugInfo, nullptr, + g_targetApiVersion)) { std::cerr << "Failed to emit binary data: " << panda::pandasm::AsmEmitter::GetLastError() << std::endl; return false; } @@ -1471,7 +1481,8 @@ static bool EmitProgram(const std::string &output, int optLevel, std::string opt return true; } - if (!panda::pandasm::AsmEmitter::Emit(convertedFilePath, prog, statp, mapsp, emitDebugInfo)) { + if (!panda::pandasm::AsmEmitter::Emit(convertedFilePath, prog, statp, mapsp, emitDebugInfo, nullptr, + g_targetApiVersion)) { std::cerr << "Failed to emit binary data: " << panda::pandasm::AsmEmitter::GetLastError() << std::endl; return false; } @@ -1483,7 +1494,8 @@ static bool EmitProgram(const std::string &output, int optLevel, std::string opt return true; } - if (!panda::pandasm::AsmEmitter::Emit(convertedFilePath, prog, nullptr)) { + if (!panda::pandasm::AsmEmitter::Emit(convertedFilePath, prog, nullptr, nullptr, true, nullptr, + g_targetApiVersion)) { std::cerr << "Failed to emit binary data: " << panda::pandasm::AsmEmitter::GetLastError() << std::endl; return false; } @@ -1600,6 +1612,9 @@ bool GenerateProgram([[maybe_unused]] const std::string &data, const std::string std::string optLogLevel = options.GetOptLogLevelArg(); panda::pandasm::Program prog = panda::pandasm::Program(); prog.lang = panda::pandasm::extensions::Language::ECMASCRIPT; + if (options.WasSetTargetApiVersion()) { + g_targetApiVersion = options.GetTargetApiVersion(); + } if (isParsingFromPipe) { if (!ReadFromPipe(prog, options)) { diff --git a/ts2panda/ts2abc/ts2abc_options.h b/ts2panda/ts2abc/ts2abc_options.h index e08e66ac0ad959155b17f18b8c10780c325aaee8..d1687c6ddcbd0322983d387c390aadb8fc390ace 100755 --- a/ts2panda/ts2abc/ts2abc_options.h +++ b/ts2panda/ts2abc/ts2abc_options.h @@ -42,6 +42,7 @@ namespace panda::ts2abc { parser->Add(&compile_npm_entries_); parser->Add(&compiler_output_proto_); parser->Add(&multi_programs_pipe_); + parser->Add(&target_api_version_); parser->EnableTail(); parser->PushBackTail(&Tail_Arg1_arg_); parser->PushBackTail(&Tail_Arg2_arg_); @@ -187,6 +188,21 @@ namespace panda::ts2abc { return multi_programs_pipe_.GetValue(); } + int GetTargetApiVersion() const + { + return target_api_version_.GetValue(); + } + + void SetTargetApiVersion(int value) + { + target_api_version_.SetValue(value); + } + + bool WasSetTargetApiVersion() const + { + return target_api_version_.WasSet(); + } + std::string GetTailArg1() const { return Tail_Arg1_arg_.GetValue(); @@ -251,6 +267,8 @@ namespace panda::ts2abc { R"(Output protoBin file)"}; panda::PandArg multi_programs_pipe_{ "multi-programs-pipe", false, R"(Genrate programs by single pipe)"}; + panda::PandArg target_api_version_{ "target-api-version", 0, + R"(Specify the target api version for compilation)"}; panda::PandArg Tail_Arg1_arg_{ "ARG_1", "", R"(Path to input(json file) or path to output(ark bytecode)" " when 'compile-by-pipe' enabled)"};