diff --git a/es2panda/aot/main.cpp b/es2panda/aot/main.cpp index 6b0f618d48360e24550ba4bfe0b5790057e17d44..3b936d39182e819f2c13d8819e79432662309b57 100644 --- a/es2panda/aot/main.cpp +++ b/es2panda/aot/main.cpp @@ -80,37 +80,61 @@ static void DumpPandaFileSizeStatistic(std::map &stat) std::cout << "total: " << totalSize << std::endl; } -static bool GenerateProgram(std::vector &progs, - std::unique_ptr &options) +static bool GenerateMultiProgram(const std::unordered_map &programs, + const std::unique_ptr &options) +{ + if (options->CompilerOptions().mergeAbc) { + std::vector progs; + for (auto &prog: programs) { + progs.push_back(prog.first); + } + + auto output = programs.begin()->second; + if (!panda::pandasm::AsmEmitter::EmitPrograms(output, progs, true)) { + std::cerr << "Failed to emit merged program, error: " << + panda::pandasm::AsmEmitter::GetLastError() << std::endl; + return false; + } + } else { + for (auto &prog: programs) { + if (!panda::pandasm::AsmEmitter::Emit(prog.second, *(prog.first), nullptr, nullptr, true)) { + std::cout << "Failed to emit single program, error: " << + panda::pandasm::AsmEmitter::GetLastError() << std::endl; + return false; + } + } + } + return true; +} + +static bool GenerateProgram(const std::unordered_map &programs, + const std::unique_ptr &options) { int optLevel = options->OptLevel(); bool dumpSize = options->SizeStat(); - const std::string output = options->CompilerOutput(); const es2panda::CompilerOptions compilerOptions = options->CompilerOptions(); if (compilerOptions.dumpAsm || compilerOptions.dumpLiteralBuffer) { - for (auto *prog : progs) { + for (auto &prog : programs) { if (compilerOptions.dumpAsm) { - es2panda::Compiler::DumpAsm(prog); + es2panda::Compiler::DumpAsm(prog.first); } if (compilerOptions.dumpLiteralBuffer) { - panda::es2panda::util::Dumper::DumpLiterals(prog->literalarray_table); + panda::es2panda::util::Dumper::DumpLiterals(prog.first->literalarray_table); } } } - if (progs.size() > 1) { - if (!panda::pandasm::AsmEmitter::EmitPrograms(output, progs, true)) { - std::cerr << "Failed to emit merged program " << std::endl; - return false; - } + if (programs.size() > 1) { + return GenerateMultiProgram(programs, options); } else { - auto *prog = progs[0]; + auto *prog = programs.begin()->first; std::map stat; std::map *statp = optLevel != 0 ? &stat : nullptr; panda::pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps {}; panda::pandasm::AsmEmitter::PandaFileToPandaAsmMaps *mapsp = optLevel != 0 ? &maps : nullptr; + auto output = programs.begin()->second; if (output.empty()) { GenerateBase64Output(prog, mapsp); return true; @@ -133,6 +157,30 @@ static bool GenerateProgram(std::vector &progs, return true; } +static bool GenerateAbcFiles(const std::map &programsInfo, + const std::unique_ptr &options, size_t expectedProgsCount) +{ + std::unordered_map programs; + for (auto &info : programsInfo) { + auto outputFileName = options->OutputFiles().empty() ? options->CompilerOutput() : + options->OutputFiles().at(info.first); + programs.insert({info.second->program, outputFileName}); + } + + if (programs.size() != expectedProgsCount) { + std::cerr << "the size of programs is expected to be " << expectedProgsCount + << ", but is " << programs.size() << std::endl; + return false; + } + + if (!GenerateProgram(programs, options)) { + std::cerr << "GenerateProgram Failed!" << std::endl; + return false; + } + + return true; +} + int Run(int argc, const char **argv) { auto options = std::make_unique(); @@ -175,19 +223,7 @@ int Run(int argc, const char **argv) options->CacheFile()); } - std::vector programs; - programs.reserve(programsInfo.size()); - for (auto &it : programsInfo) { - programs.emplace_back(it.second->program); - } - if (programs.size() != expectedProgsCount) { - std::cerr << "the size of programs is expected to be " << expectedProgsCount - << ", but is " << programs.size() << std::endl; - return 1; - } - - if (!GenerateProgram(programs, options)) { - std::cerr << "GenerateProgram Failed!" << std::endl; + if (!GenerateAbcFiles(programsInfo, options, expectedProgsCount)) { return 1; } diff --git a/es2panda/aot/options.cpp b/es2panda/aot/options.cpp index 5d189f52032ae35cf67940e65da30efd86459325..6b591b2694baa992f8637dd8d890e6de1a201c07 100644 --- a/es2panda/aot/options.cpp +++ b/es2panda/aot/options.cpp @@ -66,17 +66,19 @@ bool Options::CollectInputFilesFromFileList(const std::string &input) return false; } - constexpr size_t ITEM_COUNT = 4; + constexpr size_t ITEM_COUNT_MERGE = 4; // item list: [filePath; recordName; moduleKind; sourceFile] + constexpr size_t ITEM_COUNT_NOT_MERGE = 5; // item list: [filePath; recordName; moduleKind; sourceFile; outputfile] while (std::getline(ifs, line)) { const std::string seperator = ";"; std::vector itemList = GetStringItems(line, seperator); - if (itemList.size() != ITEM_COUNT) { + if ((compilerOptions_.mergeAbc && itemList.size() != ITEM_COUNT_MERGE) || + (!compilerOptions_.mergeAbc && itemList.size() != ITEM_COUNT_NOT_MERGE)) { std::cerr << "Failed to parse input file" << std::endl; return false; } - // itemList: [filePath, recordName, moduleKind, sourceFile] + std::string fileName = itemList[0]; - std::string recordName = itemList[1]; + std::string recordName = compilerOptions_.mergeAbc ? itemList[1] : ""; parser::ScriptKind scriptKind; if (itemList[2] == "script") { scriptKind = parser::ScriptKind::SCRIPT; @@ -89,6 +91,9 @@ bool Options::CollectInputFilesFromFileList(const std::string &input) es2panda::SourceFile src(fileName, recordName, scriptKind); src.sourcefile = itemList[3]; sourceFiles_.push_back(src); + if (!compilerOptions_.mergeAbc) { + outputFiles_.insert({fileName, itemList[4]}); + } } return true; } @@ -307,6 +312,7 @@ bool Options::Parse(int argc, const char **argv) recordName_ = compilerOutput_.empty() ? "Base64Output" : RemoveExtension(util::Helpers::BaseName(compilerOutput_)); } + compilerOptions_.mergeAbc = opMergeAbc.GetValue(); } if (!inputIsEmpty) { diff --git a/es2panda/aot/options.h b/es2panda/aot/options.h index 0bd501f57cda9ffd70e19e34add86b974a26f87f..f2bae2a776c546fc16832cb5f24b8d4f501bb46a 100644 --- a/es2panda/aot/options.h +++ b/es2panda/aot/options.h @@ -132,6 +132,11 @@ public: return npmModuleEntryList_; } + const std::unordered_map &OutputFiles() const + { + return outputFiles_; + } + bool CollectInputFilesFromFileList(const std::string &input); bool CollectInputFilesFromFileDirectory(const std::string &input, const std::string &extension); @@ -154,6 +159,7 @@ private: std::string cacheFile_; std::string npmModuleEntryList_; std::vector sourceFiles_; + std::unordered_map outputFiles_; }; } // namespace panda::es2panda::aot