13af6ab5fSopenharmony_ci/**
23af6ab5fSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License.
53af6ab5fSopenharmony_ci * You may obtain a copy of the License at
63af6ab5fSopenharmony_ci *
73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
83af6ab5fSopenharmony_ci *
93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and
133af6ab5fSopenharmony_ci * limitations under the License.
143af6ab5fSopenharmony_ci */
153af6ab5fSopenharmony_ci
163af6ab5fSopenharmony_ci#include <iostream>
173af6ab5fSopenharmony_ci
183af6ab5fSopenharmony_ci#include <abc2program/program_dump.h>
193af6ab5fSopenharmony_ci#include <assembly-program.h>
203af6ab5fSopenharmony_ci#include <assembly-emitter.h>
213af6ab5fSopenharmony_ci#include <mem/arena_allocator.h>
223af6ab5fSopenharmony_ci#include <mem/pool_manager.h>
233af6ab5fSopenharmony_ci#include "utils/timers.h"
243af6ab5fSopenharmony_ci
253af6ab5fSopenharmony_ci#include <emitFiles.h>
263af6ab5fSopenharmony_ci#include <es2panda.h>
273af6ab5fSopenharmony_ci#include <options.h>
283af6ab5fSopenharmony_ci#include <protobufSnapshotGenerator.h>
293af6ab5fSopenharmony_ci#include <resolveDepsRelation.h>
303af6ab5fSopenharmony_ci#include <util/commonUtil.h>
313af6ab5fSopenharmony_ci#include <util/dumper.h>
323af6ab5fSopenharmony_ci#include <util/moduleHelpers.h>
333af6ab5fSopenharmony_ci#include <util/programCache.h>
343af6ab5fSopenharmony_ci#include <util/workerQueue.h>
353af6ab5fSopenharmony_ci
363af6ab5fSopenharmony_cinamespace panda::es2panda::aot {
373af6ab5fSopenharmony_ciusing mem::MemConfig;
383af6ab5fSopenharmony_ciclass MemManager {
393af6ab5fSopenharmony_cipublic:
403af6ab5fSopenharmony_ci    explicit MemManager()
413af6ab5fSopenharmony_ci    {
423af6ab5fSopenharmony_ci        constexpr auto COMPILER_SIZE = 8192_MB;
433af6ab5fSopenharmony_ci
443af6ab5fSopenharmony_ci        MemConfig::Initialize(0, 0, COMPILER_SIZE, 0);
453af6ab5fSopenharmony_ci        PoolManager::Initialize(PoolType::MMAP);
463af6ab5fSopenharmony_ci    }
473af6ab5fSopenharmony_ci
483af6ab5fSopenharmony_ci    NO_COPY_SEMANTIC(MemManager);
493af6ab5fSopenharmony_ci    NO_MOVE_SEMANTIC(MemManager);
503af6ab5fSopenharmony_ci
513af6ab5fSopenharmony_ci    ~MemManager()
523af6ab5fSopenharmony_ci    {
533af6ab5fSopenharmony_ci        PoolManager::Finalize();
543af6ab5fSopenharmony_ci        MemConfig::Finalize();
553af6ab5fSopenharmony_ci    }
563af6ab5fSopenharmony_ci};
573af6ab5fSopenharmony_ci
583af6ab5fSopenharmony_cistatic void GenerateBase64Output(panda::pandasm::Program *prog,
593af6ab5fSopenharmony_ci                                 const std::unique_ptr<panda::es2panda::aot::Options> &options)
603af6ab5fSopenharmony_ci{
613af6ab5fSopenharmony_ci    auto pandaFile = panda::pandasm::AsmEmitter::Emit(*prog, nullptr, options->CompilerOptions().targetApiVersion,
623af6ab5fSopenharmony_ci        options->CompilerOptions().targetApiSubVersion);
633af6ab5fSopenharmony_ci    const uint8_t *buffer = pandaFile->GetBase();
643af6ab5fSopenharmony_ci    size_t size = pandaFile->GetPtr().GetSize();
653af6ab5fSopenharmony_ci    std::string content(reinterpret_cast<const char*>(buffer), size);
663af6ab5fSopenharmony_ci    std::string base64Output = util::Base64Encode(content);
673af6ab5fSopenharmony_ci    std::cout << base64Output << std::endl;
683af6ab5fSopenharmony_ci}
693af6ab5fSopenharmony_ci
703af6ab5fSopenharmony_cistatic void DumpPandaFileSizeStatistic(std::map<std::string, size_t> &stat)
713af6ab5fSopenharmony_ci{
723af6ab5fSopenharmony_ci    size_t totalSize = 0;
733af6ab5fSopenharmony_ci    std::cout << "Panda file size statistic:" << std::endl;
743af6ab5fSopenharmony_ci    constexpr std::array<std::string_view, 2> INFO_STATS = {"instructions_number", "codesize"};
753af6ab5fSopenharmony_ci
763af6ab5fSopenharmony_ci    for (const auto &[name, size] : stat) {
773af6ab5fSopenharmony_ci        if (find(INFO_STATS.begin(), INFO_STATS.end(), name) != INFO_STATS.end()) {
783af6ab5fSopenharmony_ci            continue;
793af6ab5fSopenharmony_ci        }
803af6ab5fSopenharmony_ci        std::cout << name << " section: " << size << std::endl;
813af6ab5fSopenharmony_ci        totalSize += size;
823af6ab5fSopenharmony_ci    }
833af6ab5fSopenharmony_ci
843af6ab5fSopenharmony_ci    for (const auto &name : INFO_STATS) {
853af6ab5fSopenharmony_ci        std::cout << name << ": " << stat.at(std::string(name)) << std::endl;
863af6ab5fSopenharmony_ci    }
873af6ab5fSopenharmony_ci
883af6ab5fSopenharmony_ci    std::cout << "total: " << totalSize << std::endl;
893af6ab5fSopenharmony_ci}
903af6ab5fSopenharmony_ci
913af6ab5fSopenharmony_cistatic void DumpPandaFileSizePctStatistic(std::map<std::string, size_t> &stat)
923af6ab5fSopenharmony_ci{
933af6ab5fSopenharmony_ci    size_t totalSize = 0;
943af6ab5fSopenharmony_ci    std::cout << "Panda file size statistic:" << std::endl;
953af6ab5fSopenharmony_ci    constexpr std::array<std::string_view, 2> INFO_STATS = {"instructions_number", "codesize"};
963af6ab5fSopenharmony_ci
973af6ab5fSopenharmony_ci    for (const auto &[name, size] : stat) {
983af6ab5fSopenharmony_ci        if (find(INFO_STATS.begin(), INFO_STATS.end(), name) != INFO_STATS.end()) {
993af6ab5fSopenharmony_ci            continue;
1003af6ab5fSopenharmony_ci        }
1013af6ab5fSopenharmony_ci        totalSize += size;
1023af6ab5fSopenharmony_ci    }
1033af6ab5fSopenharmony_ci
1043af6ab5fSopenharmony_ci    const int itemWidth = 32;   // The width of each item name is 32 bit. (item name is a data structure in abc file)
1053af6ab5fSopenharmony_ci    const int sectionWidth = 8; // The width of each section size is 8 bit. (section size is the size of each item)
1063af6ab5fSopenharmony_ci    const int precision = 2;    // Control the output precision of the size percentage.
1073af6ab5fSopenharmony_ci    const double percentFlag = 100.0f;  // Conversion of percentage output.
1083af6ab5fSopenharmony_ci    for (const auto &[name, size] : stat) {
1093af6ab5fSopenharmony_ci        if (find(INFO_STATS.begin(), INFO_STATS.end(), name) != INFO_STATS.end()) {
1103af6ab5fSopenharmony_ci            continue;
1113af6ab5fSopenharmony_ci        }
1123af6ab5fSopenharmony_ci        std::cout << std::left << std::setw(itemWidth) << name << " section: " << \
1133af6ab5fSopenharmony_ci        std::setw(sectionWidth) << size << ", percent: " << \
1143af6ab5fSopenharmony_ci        std::fixed << std::setprecision(precision) << (size * percentFlag / totalSize) << "%" << std::endl;
1153af6ab5fSopenharmony_ci    }
1163af6ab5fSopenharmony_ci
1173af6ab5fSopenharmony_ci    std::cout << "total: " << totalSize << std::endl;
1183af6ab5fSopenharmony_ci}
1193af6ab5fSopenharmony_ci
1203af6ab5fSopenharmony_cistatic bool GenerateProgramsByWorkers(const std::map<std::string, panda::es2panda::util::ProgramCache*> &programsInfo,
1213af6ab5fSopenharmony_ci    const std::unique_ptr<panda::es2panda::aot::Options> &options, std::map<std::string, size_t> *statp)
1223af6ab5fSopenharmony_ci{
1233af6ab5fSopenharmony_ci    auto queue = new panda::es2panda::aot::EmitFileQueue(options, statp, programsInfo);
1243af6ab5fSopenharmony_ci
1253af6ab5fSopenharmony_ci    bool emitResult = true;
1263af6ab5fSopenharmony_ci    try {
1273af6ab5fSopenharmony_ci        queue->Schedule();
1283af6ab5fSopenharmony_ci        queue->Consume();
1293af6ab5fSopenharmony_ci        queue->Wait();
1303af6ab5fSopenharmony_ci    } catch (const class Error &e) {
1313af6ab5fSopenharmony_ci        emitResult = false;
1323af6ab5fSopenharmony_ci        std::cerr << e.Message() << std::endl;
1333af6ab5fSopenharmony_ci    }
1343af6ab5fSopenharmony_ci
1353af6ab5fSopenharmony_ci    delete queue;
1363af6ab5fSopenharmony_ci    queue = nullptr;
1373af6ab5fSopenharmony_ci
1383af6ab5fSopenharmony_ci    return emitResult;
1393af6ab5fSopenharmony_ci}
1403af6ab5fSopenharmony_ci
1413af6ab5fSopenharmony_cistatic void DumpProgramInfos(const std::map<std::string, panda::es2panda::util::ProgramCache*> &programsInfo,
1423af6ab5fSopenharmony_ci    const std::unique_ptr<panda::es2panda::aot::Options> &options)
1433af6ab5fSopenharmony_ci{
1443af6ab5fSopenharmony_ci    const es2panda::CompilerOptions &compilerOptions = options->CompilerOptions();
1453af6ab5fSopenharmony_ci    if (compilerOptions.dumpAsm || compilerOptions.dumpLiteralBuffer || compilerOptions.dumpAsmProgram ||
1463af6ab5fSopenharmony_ci        compilerOptions.dumpNormalizedAsmProgram) {
1473af6ab5fSopenharmony_ci        for (const auto &progInfo : programsInfo) {
1483af6ab5fSopenharmony_ci            if (compilerOptions.dumpAsmProgram || compilerOptions.dumpNormalizedAsmProgram) {
1493af6ab5fSopenharmony_ci                panda::abc2program::PandasmProgramDumper dumper(compilerOptions.dumpNormalizedAsmProgram,
1503af6ab5fSopenharmony_ci                                                                compilerOptions.isDebug);
1513af6ab5fSopenharmony_ci                dumper.Dump(std::cout, progInfo.second->program);
1523af6ab5fSopenharmony_ci            }
1533af6ab5fSopenharmony_ci
1543af6ab5fSopenharmony_ci            if (compilerOptions.dumpAsm) {
1553af6ab5fSopenharmony_ci                es2panda::Compiler::DumpAsm(&(progInfo.second->program));
1563af6ab5fSopenharmony_ci            }
1573af6ab5fSopenharmony_ci
1583af6ab5fSopenharmony_ci            if (compilerOptions.dumpLiteralBuffer) {
1593af6ab5fSopenharmony_ci                panda::es2panda::util::Dumper::DumpLiterals(progInfo.second->program.literalarray_table);
1603af6ab5fSopenharmony_ci            }
1613af6ab5fSopenharmony_ci
1623af6ab5fSopenharmony_ci            if (compilerOptions.dumpString) {
1633af6ab5fSopenharmony_ci                panda::es2panda::util::Dumper::DumpStrings(progInfo.second->program.strings);
1643af6ab5fSopenharmony_ci            }
1653af6ab5fSopenharmony_ci        }
1663af6ab5fSopenharmony_ci    }
1673af6ab5fSopenharmony_ci}
1683af6ab5fSopenharmony_ci
1693af6ab5fSopenharmony_cistatic bool GenerateProgram(std::map<std::string, panda::es2panda::util::ProgramCache*> &programsInfo,
1703af6ab5fSopenharmony_ci                            const std::unique_ptr<panda::es2panda::aot::Options> &options,
1713af6ab5fSopenharmony_ci                            const std::map<std::string, std::unordered_set<std::string>> &resolvedDepsRelation)
1723af6ab5fSopenharmony_ci{
1733af6ab5fSopenharmony_ci    DumpProgramInfos(programsInfo, options);
1743af6ab5fSopenharmony_ci
1753af6ab5fSopenharmony_ci    if (programsInfo.size() == 1) {
1763af6ab5fSopenharmony_ci        auto *prog = &(programsInfo.begin()->second->program);
1773af6ab5fSopenharmony_ci        if (options->OutputFiles().empty() && options->CompilerOutput().empty()) {
1783af6ab5fSopenharmony_ci            GenerateBase64Output(prog, options);
1793af6ab5fSopenharmony_ci            return true;
1803af6ab5fSopenharmony_ci        }
1813af6ab5fSopenharmony_ci
1823af6ab5fSopenharmony_ci        // Disable generating cached files when cross-program optimization is required, to prevent cached files from
1833af6ab5fSopenharmony_ci        // not being invalidated when their dependencies are changed
1843af6ab5fSopenharmony_ci        if (options->compilerProtoOutput().size() > 0 && !options->CompilerOptions().requireGlobalOptimization) {
1853af6ab5fSopenharmony_ci            panda::proto::ProtobufSnapshotGenerator::GenerateSnapshot(*prog, options->compilerProtoOutput());
1863af6ab5fSopenharmony_ci            return true;
1873af6ab5fSopenharmony_ci        }
1883af6ab5fSopenharmony_ci    }
1893af6ab5fSopenharmony_ci
1903af6ab5fSopenharmony_ci    if (options->NeedRemoveRedundantRecord()) {
1913af6ab5fSopenharmony_ci        util::Helpers::RemoveProgramsRedundantData(programsInfo, resolvedDepsRelation);
1923af6ab5fSopenharmony_ci        DumpProgramInfos(programsInfo, options);
1933af6ab5fSopenharmony_ci    }
1943af6ab5fSopenharmony_ci
1953af6ab5fSopenharmony_ci    bool dumpSize = options->SizeStat();
1963af6ab5fSopenharmony_ci    bool dumpSizePct = options->SizePctStat();
1973af6ab5fSopenharmony_ci    std::map<std::string, size_t> stat;
1983af6ab5fSopenharmony_ci    std::map<std::string, size_t> *statp = (dumpSize || dumpSizePct) ? &stat : nullptr;
1993af6ab5fSopenharmony_ci
2003af6ab5fSopenharmony_ci    if (!GenerateProgramsByWorkers(programsInfo, options, statp)) {
2013af6ab5fSopenharmony_ci        return false;
2023af6ab5fSopenharmony_ci    }
2033af6ab5fSopenharmony_ci
2043af6ab5fSopenharmony_ci    if (dumpSize) {
2053af6ab5fSopenharmony_ci        DumpPandaFileSizeStatistic(stat);
2063af6ab5fSopenharmony_ci    }
2073af6ab5fSopenharmony_ci
2083af6ab5fSopenharmony_ci    if (dumpSizePct) {
2093af6ab5fSopenharmony_ci        DumpPandaFileSizePctStatistic(stat);
2103af6ab5fSopenharmony_ci    }
2113af6ab5fSopenharmony_ci
2123af6ab5fSopenharmony_ci    return true;
2133af6ab5fSopenharmony_ci}
2143af6ab5fSopenharmony_ci
2153af6ab5fSopenharmony_cistatic bool CheckMergeModeConsistency(bool mergeAbc,
2163af6ab5fSopenharmony_ci                                      std::map<std::string, panda::es2panda::util::ProgramCache*> programsInfo)
2173af6ab5fSopenharmony_ci{
2183af6ab5fSopenharmony_ci    std::unordered_map<std::string, std::unordered_set<std::string>> recordNameMap;
2193af6ab5fSopenharmony_ci
2203af6ab5fSopenharmony_ci    // Names of these program records generated from abc input all follow such format: abcName|recordName
2213af6ab5fSopenharmony_ci    for (auto &[name, _] : programsInfo) {
2223af6ab5fSopenharmony_ci        if (util::RecordNotGeneratedFromBytecode(name)) {
2233af6ab5fSopenharmony_ci            continue;
2243af6ab5fSopenharmony_ci        }
2253af6ab5fSopenharmony_ci
2263af6ab5fSopenharmony_ci        auto nameVec = util::Split(name, util::CHAR_VERTICAL_LINE);
2273af6ab5fSopenharmony_ci        auto abcFileName = nameVec[0];
2283af6ab5fSopenharmony_ci        auto recordName = nameVec.back();
2293af6ab5fSopenharmony_ci
2303af6ab5fSopenharmony_ci        if (mergeAbc) {
2313af6ab5fSopenharmony_ci            if (recordName == util::GLOBAL_TYPE_NAME) {
2323af6ab5fSopenharmony_ci                std::cerr << "Current compile mode is merge-abc, all input abc files must be merged mode. "
2333af6ab5fSopenharmony_ci                          << "But file '" << abcFileName << "' is not a merged abc." << std::endl;
2343af6ab5fSopenharmony_ci                return false;
2353af6ab5fSopenharmony_ci            }
2363af6ab5fSopenharmony_ci        } else {
2373af6ab5fSopenharmony_ci            if (recordNameMap.find(abcFileName) != recordNameMap.end()) {
2383af6ab5fSopenharmony_ci                recordNameMap.find(abcFileName)->second.insert(recordName);
2393af6ab5fSopenharmony_ci            } else {
2403af6ab5fSopenharmony_ci                recordNameMap.insert({abcFileName, {recordName}});
2413af6ab5fSopenharmony_ci            }
2423af6ab5fSopenharmony_ci        }
2433af6ab5fSopenharmony_ci    }
2443af6ab5fSopenharmony_ci
2453af6ab5fSopenharmony_ci    if (!mergeAbc) {
2463af6ab5fSopenharmony_ci        for (auto &[abcFileName, recordNameSet] : recordNameMap) {
2473af6ab5fSopenharmony_ci            if (!recordNameSet.count(util::GLOBAL_TYPE_NAME)) {
2483af6ab5fSopenharmony_ci                std::cerr << "Current compile mode is non merge-abc, all input abc files must be unmerged mode. "
2493af6ab5fSopenharmony_ci                          << "But file '" << abcFileName << "' is a merged abc." << std::endl;
2503af6ab5fSopenharmony_ci                return false;
2513af6ab5fSopenharmony_ci            }
2523af6ab5fSopenharmony_ci        }
2533af6ab5fSopenharmony_ci    }
2543af6ab5fSopenharmony_ci
2553af6ab5fSopenharmony_ci    return true;
2563af6ab5fSopenharmony_ci}
2573af6ab5fSopenharmony_ci
2583af6ab5fSopenharmony_cistatic bool GenerateAbcFiles(std::map<std::string, panda::es2panda::util::ProgramCache*> &programsInfo,
2593af6ab5fSopenharmony_ci                             const std::unique_ptr<panda::es2panda::aot::Options> &options, size_t expectedProgsCount,
2603af6ab5fSopenharmony_ci                             const std::map<std::string, std::unordered_set<std::string>> &resolvedDepsRelation)
2613af6ab5fSopenharmony_ci{
2623af6ab5fSopenharmony_ci    if (programsInfo.size() != expectedProgsCount) {
2633af6ab5fSopenharmony_ci        std::cerr << "The size of programs is expected to be " << expectedProgsCount
2643af6ab5fSopenharmony_ci                  << ", but is " << programsInfo.size() << std::endl;
2653af6ab5fSopenharmony_ci        return false;
2663af6ab5fSopenharmony_ci    }
2673af6ab5fSopenharmony_ci
2683af6ab5fSopenharmony_ci    if (!GenerateProgram(programsInfo, options, resolvedDepsRelation)) {
2693af6ab5fSopenharmony_ci        std::cerr << "GenerateProgram Failed!" << std::endl;
2703af6ab5fSopenharmony_ci        return false;
2713af6ab5fSopenharmony_ci    }
2723af6ab5fSopenharmony_ci
2733af6ab5fSopenharmony_ci    return true;
2743af6ab5fSopenharmony_ci}
2753af6ab5fSopenharmony_ci
2763af6ab5fSopenharmony_cistatic bool ResolveDepsRelations(const std::map<std::string, panda::es2panda::util::ProgramCache *> &programsInfo,
2773af6ab5fSopenharmony_ci                                 const std::unique_ptr<panda::es2panda::aot::Options> &options,
2783af6ab5fSopenharmony_ci                                 std::map<std::string, std::unordered_set<std::string>> &resolvedDepsRelation)
2793af6ab5fSopenharmony_ci{
2803af6ab5fSopenharmony_ci    panda::es2panda::aot::DepsRelationResolver depsRelationResolver(programsInfo, options, resolvedDepsRelation);
2813af6ab5fSopenharmony_ci    return depsRelationResolver.Resolve();
2823af6ab5fSopenharmony_ci}
2833af6ab5fSopenharmony_ci
2843af6ab5fSopenharmony_cistatic bool ResolveAndGenerate(std::map<std::string, panda::es2panda::util::ProgramCache*> &programsInfo,
2853af6ab5fSopenharmony_ci                               const std::unique_ptr<panda::es2panda::aot::Options> &options)
2863af6ab5fSopenharmony_ci{
2873af6ab5fSopenharmony_ci    panda::Timer::timerStart(panda::EVENT_RESOLVE_DEPS, "");
2883af6ab5fSopenharmony_ci    // A mapping of program to its records which are resolved and collected as valid dependencies.
2893af6ab5fSopenharmony_ci    std::map<std::string, std::unordered_set<std::string>> resolvedDepsRelation {};
2903af6ab5fSopenharmony_ci
2913af6ab5fSopenharmony_ci    if (options->NeedCollectDepsRelation() &&
2923af6ab5fSopenharmony_ci        !ResolveDepsRelations(programsInfo, options, resolvedDepsRelation)) {
2933af6ab5fSopenharmony_ci        return true;
2943af6ab5fSopenharmony_ci    }
2953af6ab5fSopenharmony_ci    panda::Timer::timerEnd(panda::EVENT_RESOLVE_DEPS, "");
2963af6ab5fSopenharmony_ci
2973af6ab5fSopenharmony_ci    panda::Timer::timerStart(panda::EVENT_EMIT_ABC, "");
2983af6ab5fSopenharmony_ci    if (!GenerateAbcFiles(programsInfo, options, Compiler::GetExpectedProgsCount(), resolvedDepsRelation)) {
2993af6ab5fSopenharmony_ci        return true;
3003af6ab5fSopenharmony_ci    }
3013af6ab5fSopenharmony_ci    panda::Timer::timerEnd(panda::EVENT_EMIT_ABC, "");
3023af6ab5fSopenharmony_ci
3033af6ab5fSopenharmony_ci    return false;
3043af6ab5fSopenharmony_ci}
3053af6ab5fSopenharmony_ci
3063af6ab5fSopenharmony_ciint Run(int argc, const char **argv)
3073af6ab5fSopenharmony_ci{
3083af6ab5fSopenharmony_ci    auto options = std::make_unique<Options>();
3093af6ab5fSopenharmony_ci    if (!options->Parse(argc, argv)) {
3103af6ab5fSopenharmony_ci        std::cerr << options->ErrorMsg() << std::endl;
3113af6ab5fSopenharmony_ci        return 1;
3123af6ab5fSopenharmony_ci    }
3133af6ab5fSopenharmony_ci
3143af6ab5fSopenharmony_ci    if (options->CompilerOptions().targetBcVersion) {
3153af6ab5fSopenharmony_ci        auto bcVersionByApi = panda::panda_file::GetVersionByApi(options->CompilerOptions().targetApiVersion,
3163af6ab5fSopenharmony_ci            options->CompilerOptions().targetApiSubVersion);
3173af6ab5fSopenharmony_ci        std::cout << panda::panda_file::GetVersion(bcVersionByApi.value());
3183af6ab5fSopenharmony_ci        return 0;
3193af6ab5fSopenharmony_ci    }
3203af6ab5fSopenharmony_ci
3213af6ab5fSopenharmony_ci    panda::Timer::timerStart(panda::EVENT_TOTAL, "");
3223af6ab5fSopenharmony_ci    if (options->CompilerOptions().bcVersion || options->CompilerOptions().bcMinVersion) {
3233af6ab5fSopenharmony_ci        std::string version = options->CompilerOptions().bcVersion ?
3243af6ab5fSopenharmony_ci            panda::panda_file::GetVersion(panda::panda_file::version) :
3253af6ab5fSopenharmony_ci            panda::panda_file::GetVersion(panda::panda_file::minVersion);
3263af6ab5fSopenharmony_ci        std::cout << version;
3273af6ab5fSopenharmony_ci        return 0;
3283af6ab5fSopenharmony_ci    }
3293af6ab5fSopenharmony_ci
3303af6ab5fSopenharmony_ci    std::map<std::string, panda::es2panda::util::ProgramCache*> programsInfo;
3313af6ab5fSopenharmony_ci    panda::ArenaAllocator allocator(panda::SpaceType::SPACE_TYPE_COMPILER, nullptr, true);
3323af6ab5fSopenharmony_ci
3333af6ab5fSopenharmony_ci    Compiler::SetExpectedProgsCount(options->CompilerOptions().sourceFiles.size());
3343af6ab5fSopenharmony_ci    panda::Timer::timerStart(panda::EVENT_COMPILE, "");
3353af6ab5fSopenharmony_ci    int ret = Compiler::CompileFiles(options->CompilerOptions(), programsInfo, &allocator);
3363af6ab5fSopenharmony_ci
3373af6ab5fSopenharmony_ci    if (!CheckMergeModeConsistency(options->CompilerOptions().mergeAbc, programsInfo)) {
3383af6ab5fSopenharmony_ci        return 1;
3393af6ab5fSopenharmony_ci    }
3403af6ab5fSopenharmony_ci
3413af6ab5fSopenharmony_ci    if (options->ParseOnly()) {
3423af6ab5fSopenharmony_ci        return ret;
3433af6ab5fSopenharmony_ci    }
3443af6ab5fSopenharmony_ci
3453af6ab5fSopenharmony_ci    if (!options->NpmModuleEntryList().empty()) {
3463af6ab5fSopenharmony_ci        es2panda::util::ModuleHelpers::CompileNpmModuleEntryList(options->NpmModuleEntryList(),
3473af6ab5fSopenharmony_ci            options->CompilerOptions(), programsInfo, &allocator);
3483af6ab5fSopenharmony_ci        Compiler::SetExpectedProgsCount(Compiler::GetExpectedProgsCount() + 1);
3493af6ab5fSopenharmony_ci    }
3503af6ab5fSopenharmony_ci    panda::Timer::timerEnd(panda::EVENT_COMPILE, "");
3513af6ab5fSopenharmony_ci
3523af6ab5fSopenharmony_ci    if (ResolveAndGenerate(programsInfo, options)) {
3533af6ab5fSopenharmony_ci        return 1;
3543af6ab5fSopenharmony_ci    }
3553af6ab5fSopenharmony_ci    panda::Timer::timerEnd(panda::EVENT_TOTAL, "");
3563af6ab5fSopenharmony_ci    if (!options->PerfFile().empty()) {
3573af6ab5fSopenharmony_ci        panda::Timer::PrintTimers();
3583af6ab5fSopenharmony_ci    }
3593af6ab5fSopenharmony_ci    return 0;
3603af6ab5fSopenharmony_ci}
3613af6ab5fSopenharmony_ci}  // namespace panda::es2panda::aot
3623af6ab5fSopenharmony_ci
3633af6ab5fSopenharmony_ciint main(int argc, const char **argv)
3643af6ab5fSopenharmony_ci{
3653af6ab5fSopenharmony_ci    panda::es2panda::aot::MemManager mm;
3663af6ab5fSopenharmony_ci    return panda::es2panda::aot::Run(argc, argv);
3673af6ab5fSopenharmony_ci}
368