1 /**
2 * Copyright (c) 2021-2025 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 "compiler/core/compilerImpl.h"
17 #include "generated/diagnostic.h"
18 #include "public/public.h"
19 #include "util/diagnostic.h"
20 #include "util/generateBin.h"
21
22 #include "es2panda.h"
23
24 namespace ark::es2panda {
25 constexpr size_t DEFAULT_THREAD_COUNT = 2;
26
27 namespace util {
28 class Options;
29 } // namespace util
30
31 template <class T>
DirName(T const & path,T const & delims=ark::os::file::File::GetPathDelim ())32 T DirName(T const &path, T const &delims = ark::os::file::File::GetPathDelim())
33 {
34 std::size_t pos = path.find_last_of(delims);
35 if (pos == std::string::npos) {
36 return "./";
37 }
38
39 if (pos == 0) {
40 return delims;
41 }
42
43 std::string_view dirPath = path.substr(0, pos);
44 if (dirPath.compare(".") == 0 || dirPath.compare("..") == 0) {
45 return path.substr(0, pos + 1);
46 }
47
48 return path.substr(0, pos);
49 }
50
SourceFile(std::string_view fn,std::string_view s)51 SourceFile::SourceFile(std::string_view fn, std::string_view s) : filePath(fn), fileFolder(DirName(fn)), source(s) {}
52
SourceFile(std::string_view fn,std::string_view s,bool m)53 SourceFile::SourceFile(std::string_view fn, std::string_view s, bool m)
54 : filePath(fn), fileFolder(DirName(fn)), source(s), isModule(m)
55 {
56 }
SourceFile(std::string_view fn,std::string_view s,bool m,std::string_view d)57 SourceFile::SourceFile(std::string_view fn, std::string_view s, bool m, std::string_view d)
58 : filePath(fn), fileFolder(DirName(fn)), source(s), isModule(m), dest(d)
59 {
60 }
61
SourceFile(std::string_view fn,std::string_view s,std::string_view rp,bool m,bool d)62 SourceFile::SourceFile(std::string_view fn, std::string_view s, std::string_view rp, bool m, bool d)
63 : filePath(fn),
64 fileFolder(DirName(fn)),
65 source(s),
66 resolvedPath(DirName(rp)),
67 isModule(m),
68 isDeclForDynamicStaticInterop(d)
69 {
70 }
71
Compiler(ScriptExtension ext)72 Compiler::Compiler(ScriptExtension ext) : Compiler(ext, DEFAULT_THREAD_COUNT, {}) {}
73
Compiler(ScriptExtension ext,size_t threadCount)74 Compiler::Compiler(ScriptExtension ext, size_t threadCount) : Compiler(ext, threadCount, {}) {}
75
Compiler(ScriptExtension ext,size_t threadCount,std::vector<util::Plugin> && plugins)76 Compiler::Compiler(ScriptExtension ext, size_t threadCount, std::vector<util::Plugin> &&plugins)
77 : plugins_(std::move(plugins)), compiler_(new compiler::CompilerImpl(threadCount, &plugins_)), ext_(ext)
78 {
79 }
80
~Compiler()81 Compiler::~Compiler()
82 {
83 delete compiler_;
84 }
85
Compile(const SourceFile & input,const util::Options & options,util::DiagnosticEngine & diagnosticEngine,uint32_t parseStatus)86 pandasm::Program *Compiler::Compile(const SourceFile &input, const util::Options &options,
87 util::DiagnosticEngine &diagnosticEngine, uint32_t parseStatus)
88 {
89 public_lib::Context context;
90 ArenaAllocator allocator(SpaceType::SPACE_TYPE_COMPILER, nullptr, true);
91 context.allocator = &allocator;
92 context.compilingState = public_lib::CompilingState::SINGLE_COMPILING;
93
94 try {
95 return compiler_->Compile(compiler::CompilationUnit {input, options, parseStatus, ext_, diagnosticEngine},
96 &context);
97 } catch (const util::ThrowableDiagnostic &e) {
98 error_ = e;
99 return nullptr;
100 }
101 }
102
CompileM(std::vector<SourceFile> & inputs,util::Options & options,util::DiagnosticEngine & diagnosticEngine,std::vector<pandasm::Program * > & result)103 unsigned int Compiler::CompileM(std::vector<SourceFile> &inputs, util::Options &options,
104 util::DiagnosticEngine &diagnosticEngine, std::vector<pandasm::Program *> &result)
105 {
106 public_lib::Context context;
107 context.transitionMemory =
108 new public_lib::TransitionMemory(new ArenaAllocator(SpaceType::SPACE_TYPE_COMPILER, nullptr, true));
109 context.allocator = context.transitionMemory->PermanentAllocator();
110
111 context.compilingState = public_lib::CompilingState::MULTI_COMPILING_INIT;
112 unsigned int overallRes = 0;
113 for (auto &input : inputs) {
114 try {
115 options.SetOutput(std::string(input.dest));
116 LOG_IF(options.IsListFiles(), INFO, ES2PANDA)
117 << "> es2panda: compiling from '" << input.filePath << "' to '" << input.dest << "'";
118 auto program =
119 compiler_->Compile(compiler::CompilationUnit {input, options, 0, ext_, diagnosticEngine}, &context);
120 result.push_back(program);
121 } catch (const util::ThrowableDiagnostic &err) {
122 overallRes |= 1U;
123 diagnosticEngine.Log(err);
124 }
125 context.compilingState = public_lib::CompilingState::MULTI_COMPILING_FOLLOW;
126 }
127 delete context.transitionMemory;
128 return overallRes;
129 }
130
GetPhasesList() const131 std::string Compiler::GetPhasesList() const
132 {
133 return compiler::CompilerImpl::GetPhasesList(ext_);
134 }
135
DumpAsm(const pandasm::Program * prog)136 void Compiler::DumpAsm(const pandasm::Program *prog)
137 {
138 compiler::CompilerImpl::DumpAsm(prog);
139 }
140
141 util::DiagnosticEngine *g_diagnosticEngine = nullptr;
142
143 } // namespace ark::es2panda
144