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#ifndef ES2PANDA_COMPILER_CORE_EMITTER_H
17#define ES2PANDA_COMPILER_CORE_EMITTER_H
18
19#include "compiler/base/literals.h"
20
21#include "util/ustring.h"
22
23#include <list>
24#include <mutex>
25#include <string>
26#include <unordered_map>
27#include <unordered_set>
28#include <vector>
29
30namespace ark::pandasm {
31struct Program;
32struct Function;
33struct Ins;
34namespace debuginfo {
35struct LocalVariable;
36}  // namespace debuginfo
37}  // namespace ark::pandasm
38
39namespace ark::es2panda::varbinder {
40class Scope;
41class LocalVariable;
42}  // namespace ark::es2panda::varbinder
43
44namespace ark::es2panda::public_lib {
45struct Context;
46}  // namespace ark::es2panda::public_lib
47
48namespace ark::es2panda::compiler {
49class CodeGen;
50class DebugInfo;
51class Label;
52class IRNode;
53class ProgramElement;
54class RegSpiller;
55
56class FunctionEmitter {
57public:
58    explicit FunctionEmitter(const CodeGen *cg, ProgramElement *programElement)
59        : cg_(cg), programElement_(programElement)
60    {
61    }
62
63    virtual ~FunctionEmitter() = default;
64    NO_COPY_SEMANTIC(FunctionEmitter);
65    NO_MOVE_SEMANTIC(FunctionEmitter);
66
67    void Generate();
68
69protected:
70    using VariablesStartsMap = std::unordered_map<const varbinder::Variable *, uint32_t>;
71
72protected:
73    virtual pandasm::Function *GenFunctionSignature() = 0;
74    virtual void GenFunctionAnnotations(pandasm::Function *func) = 0;
75    virtual void GenVariableSignature(pandasm::debuginfo::LocalVariable &variableDebug,
76                                      varbinder::LocalVariable *variable) const = 0;
77
78    void GenInstructionDebugInfo(const IRNode *ins, ark::pandasm::Ins *pandaIns);
79    void GenFunctionInstructions(pandasm::Function *func);
80    void GenScopeVariableInfo(pandasm::Function *func, const varbinder::Scope *scope) const;
81    void GenScopeVariableInfoEnd(pandasm::Function *func, const varbinder::Scope *scope, uint32_t count,
82                                 uint32_t scopeStart, const VariablesStartsMap &starts) const;
83    void GenSourceFileDebugInfo(pandasm::Function *func);
84    void GenFunctionCatchTables(ark::pandasm::Function *func);
85    void GenVariablesDebugInfo(pandasm::Function *func);
86    util::StringView SourceCode() const;
87
88    const CodeGen *Cg() const
89    {
90        return cg_;
91    }
92
93    ProgramElement *GetProgramElement() const
94    {
95        return programElement_;
96    }
97
98private:
99    const CodeGen *cg_;
100    ProgramElement *programElement_;
101    size_t offset_ {0};
102};
103
104class Emitter {
105public:
106    virtual ~Emitter();
107    NO_COPY_SEMANTIC(Emitter);
108    NO_MOVE_SEMANTIC(Emitter);
109
110    void AddLiteralBuffer(const LiteralBuffer &literals, uint32_t index);
111    void AddProgramElement(ProgramElement *programElement);
112    static void DumpAsm(const pandasm::Program *prog);
113    pandasm::Program *Finalize(bool dumpDebugInfo, std::string_view globalClass = "");
114
115    uint32_t &LiteralBufferIndex()
116    {
117        return literalBufferIndex_;
118    }
119
120    virtual void GenAnnotation() = 0;
121
122protected:
123    explicit Emitter(const public_lib::Context *context);
124
125    pandasm::Program *Program() const
126    {
127        return prog_;
128    }
129
130    const public_lib::Context *Context() const
131    {
132        return context_;
133    }
134
135private:
136    pandasm::Program *prog_;
137    const public_lib::Context *context_;
138    uint32_t literalBufferIndex_ {};
139};
140}  // namespace ark::es2panda::compiler
141
142#endif
143