• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "bytecode_optimizer/bytecodeopt_options.h"
17 #include "bytecode_optimizer/optimize_bytecode.h"
18 #include "compiler/compiler_logger.h"
19 #include "mem/arena_allocator.h"
20 #include "mem/pool_manager.h"
21 #include "es2panda.h"
22 #include "util/arktsconfig.h"
23 #include "util/generateBin.h"
24 #include "util/options.h"
25 #include "util/plugin.h"
26 
27 #include <iostream>
28 #include <memory>
29 #include <optional>
30 
31 namespace ark::es2panda::aot {
32 using mem::MemConfig;
33 
34 class MemManager {
35 public:
MemManager()36     explicit MemManager()
37     {
38         constexpr auto COMPILER_SIZE = sizeof(size_t) <= 4 ? 2_GB : 32_GB;
39 
40         MemConfig::Initialize(0, 0, COMPILER_SIZE, 0, 0, 0);
41         PoolManager::Initialize(PoolType::MMAP);
42     }
43 
44     NO_COPY_SEMANTIC(MemManager);
45     NO_MOVE_SEMANTIC(MemManager);
46 
~MemManager()47     ~MemManager()
48     {
49         PoolManager::Finalize();
50         MemConfig::Finalize();
51     }
52 };
53 
CompileFromSource(es2panda::Compiler & compiler,es2panda::SourceFile & input,util::Options * options)54 static int CompileFromSource(es2panda::Compiler &compiler, es2panda::SourceFile &input, util::Options *options)
55 {
56     auto program = std::unique_ptr<pandasm::Program> {compiler.Compile(input, *options)};
57     if (program == nullptr) {
58         const auto &err = compiler.GetError();
59 
60         if (err.Type() == ErrorType::INVALID) {
61             if (compiler.IsAnyError()) {
62                 return 1;
63             }
64             // Intentional exit or --parse-only option usage.
65             return 0;
66         }
67 
68         std::cout << err.TypeString() << ": " << err.Message();
69         std::cout << " [" << (err.File().empty() ? util::BaseName(options->SourceFile()) : util::BaseName(err.File()))
70                   << ":" << err.Line() << ":" << err.Col() << "]" << std::endl;
71 
72         return err.ErrorCode();
73     }
74 
75     return util::GenerateProgram(program.get(), options, [](std::string const &str) { std::cerr << str << std::endl; });
76 }
77 
CompileFromConfig(es2panda::Compiler & compiler,util::Options * options)78 static int CompileFromConfig(es2panda::Compiler &compiler, util::Options *options)
79 {
80     auto compilationList = FindProjectSources(options->CompilerOptions().arktsConfig);
81     if (compilationList.empty()) {
82         std::cerr << "Error: No files to compile" << std::endl;
83         return 1;
84     }
85 
86     unsigned overallRes = 0;
87     for (auto &[src, dst] : compilationList) {
88         std::ifstream inputStream(src);
89         if (inputStream.fail()) {
90             std::cerr << "Error: Failed to open file: " << src << std::endl;
91             return 1;
92         }
93 
94         std::stringstream ss;
95         ss << inputStream.rdbuf();
96         std::string parserInput = ss.str();
97         inputStream.close();
98         es2panda::SourceFile input(src, parserInput, options->ParseModule());
99         options->SetCompilerOutput(dst);
100 
101         options->ListFiles() && std::cout << "> es2panda: compiling from '" << src << "' to '" << dst << "'"
102                                           << std::endl;
103         auto res = CompileFromSource(compiler, input, options);
104         if (res != 0) {
105             std::cout << "> es2panda: failed to compile from " << src << " to " << dst << std::endl;
106             overallRes |= static_cast<unsigned>(res);
107         }
108     }
109 
110     return overallRes;
111 }
112 
InitializePlugins(std::vector<std::string> const & names)113 static std::optional<std::vector<util::Plugin>> InitializePlugins(std::vector<std::string> const &names)
114 {
115     std::vector<util::Plugin> res;
116     for (auto &name : names) {
117         auto plugin = util::Plugin(util::StringView {name});
118         if (!plugin.IsOk()) {
119             std::cerr << "Error: Failed to load plugin " << name << std::endl;
120             return {};
121         }
122         plugin.Initialize();
123         res.push_back(std::move(plugin));
124     }
125     return {std::move(res)};
126 }
127 
Run(int argc,const char ** argv)128 static int Run(int argc, const char **argv)
129 {
130     auto options = std::make_unique<util::Options>();
131     if (!options->Parse(argc, argv)) {
132         std::cerr << options->ErrorMsg() << std::endl;
133         return 1;
134     }
135 
136     Logger::ComponentMask mask {};
137     mask.set(Logger::Component::ES2PANDA);
138     Logger::InitializeStdLogging(Logger::LevelFromString(options->LogLevel()), mask);
139     auto pluginsOpt = InitializePlugins(options->CompilerOptions().plugins);
140     if (!pluginsOpt.has_value()) {
141         return 1;
142     }
143     es2panda::Compiler compiler(options->Extension(), options->ThreadCount(), std::move(pluginsOpt.value()));
144 
145     if (options->ListPhases()) {
146         std::cerr << "Available phases:" << std::endl;
147         std::cerr << compiler.GetPhasesList();
148         return 1;
149     }
150 
151     if (options->CompilerOptions().compilationMode == CompilationMode::PROJECT) {
152         return CompileFromConfig(compiler, options.get());
153     }
154 
155     std::string_view sourceFile;
156     std::string_view parserInput;
157     if (options->CompilerOptions().compilationMode == CompilationMode::GEN_STD_LIB) {
158         sourceFile = "etsstdlib.sts";
159         parserInput = "";
160     } else {
161         sourceFile = options->SourceFile();
162         parserInput = options->ParserInput();
163     }
164     es2panda::SourceFile input(sourceFile, parserInput, options->ParseModule());
165     return CompileFromSource(compiler, input, options.get());
166 }
167 }  // namespace ark::es2panda::aot
168 
main(int argc,const char ** argv)169 int main(int argc, const char **argv)
170 {
171     ark::es2panda::aot::MemManager mm;
172     return ark::es2panda::aot::Run(argc, argv);
173 }
174