• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 - 2023 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_CODEGEN_H
17 #define ES2PANDA_COMPILER_CORE_CODEGEN_H
18 
19 #include "compiler/base/literals.h"
20 #include "compiler/core/ASTCompiler.h"
21 #include "compiler/core/regAllocator.h"
22 #include "compiler/core/regScope.h"
23 namespace panda::es2panda::compiler {
24 class CatchTable;
25 class DynamicContext;
26 
27 enum class Constant {
28     JS_NAN,
29     JS_HOLE,
30     JS_INFINITY,
31     JS_UNDEFINED,
32     JS_NULL,
33     JS_TRUE,
34     JS_FALSE,
35     JS_SYMBOL,
36     JS_GLOBAL,
37 };
38 
39 class DebugInfo {
40 public:
DebugInfo(ArenaAllocator * allocator)41     explicit DebugInfo(ArenaAllocator *allocator) : variableDebugInfo_(allocator->Adapter()) {};
42     DEFAULT_COPY_SEMANTIC(DebugInfo);
43     DEFAULT_MOVE_SEMANTIC(DebugInfo);
44     ~DebugInfo() = default;
45 
VariableDebugInfo()46     ArenaVector<const varbinder::Scope *> &VariableDebugInfo()
47     {
48         return variableDebugInfo_;
49     }
50 
VariableDebugInfo()51     const ArenaVector<const varbinder::Scope *> &VariableDebugInfo() const
52     {
53         return variableDebugInfo_;
54     }
55 
FirstStatement()56     const ir::Statement *FirstStatement() const
57     {
58         return firstStmt_;
59     }
60 
61 private:
62     friend class CodeGen;
63 
64     ArenaVector<const varbinder::Scope *> variableDebugInfo_;
65     const ir::Statement *firstStmt_ {};
66 };
67 
68 class CodeGen {
69 public:
70     using TypeMap = ArenaUnorderedMap<VReg, const checker::Type *>;
71 
CodeGen(ArenaAllocator * allocator,RegSpiller * spiller,CompilerContext * context,varbinder::FunctionScope * scope,ProgramElement * programElement,AstCompiler * astcompiler)72     explicit CodeGen(ArenaAllocator *allocator, RegSpiller *spiller, CompilerContext *context,
73                      varbinder::FunctionScope *scope, ProgramElement *programElement, AstCompiler *astcompiler) noexcept
74         : astCompiler_(astcompiler),
75           allocator_(allocator),
76           context_(context),
77           debugInfo_(allocator_),
78           topScope_(scope),
79           scope_(topScope_),
80           rootNode_(scope->Node()),
81           insns_(allocator_->Adapter()),
82           catchList_(allocator_->Adapter()),
83           typeMap_(allocator_->Adapter()),
84           programElement_(programElement),
85           sa_(this),
86           ra_(this, spiller),
87           rra_(this, spiller)
88     {
89         astCompiler_->SetCodeGen(this);
90     }
91     virtual ~CodeGen() = default;
92     NO_COPY_SEMANTIC(CodeGen);
93     NO_MOVE_SEMANTIC(CodeGen);
94 
95     [[nodiscard]] virtual IRNode *AllocMov(const ir::AstNode *node, VReg vd, VReg vs) = 0;
96     [[nodiscard]] virtual IRNode *AllocMov(const ir::AstNode *node, OutVReg vd, VReg vs) = 0;
97 
98     [[nodiscard]] ArenaAllocator *Allocator() const noexcept;
99     [[nodiscard]] const ArenaVector<CatchTable *> &CatchList() const noexcept;
100     [[nodiscard]] const varbinder::FunctionScope *TopScope() const noexcept;
101     [[nodiscard]] const varbinder::Scope *Scope() const noexcept;
102     [[nodiscard]] const ir::AstNode *RootNode() const noexcept;
103 
104     [[nodiscard]] ArenaVector<IRNode *> &Insns() noexcept;
105     [[nodiscard]] const ArenaVector<IRNode *> &Insns() const noexcept;
106 
107     [[nodiscard]] VReg AllocReg();
108     [[nodiscard]] VReg AllocRegWithType(const checker::Type *type);
109     [[nodiscard]] VReg NextReg() const noexcept;
110 
111     [[nodiscard]] std::uint32_t TotalRegsNum() const noexcept;
112     [[nodiscard]] std::size_t LabelCount() const noexcept;
113     [[nodiscard]] const DebugInfo &Debuginfo() const noexcept;
IcSize()114     [[nodiscard]] constexpr std::uint32_t IcSize() const noexcept
115     {
116         return 0U;
117     }
118 
119     [[nodiscard]] bool IsDebug() const noexcept;
120     [[nodiscard]] std::uint32_t ParamCount() const noexcept;
121     [[nodiscard]] std::uint32_t FormalParametersCount() const noexcept;
122     [[nodiscard]] std::uint32_t InternalParamCount() const noexcept;
123     [[nodiscard]] const util::StringView &InternalName() const noexcept;
124     [[nodiscard]] const util::StringView &FunctionName() const noexcept;
125     [[nodiscard]] varbinder::VarBinder *VarBinder() const noexcept;
126 
127     [[nodiscard]] Label *AllocLabel();
128     [[nodiscard]] std::int32_t AddLiteralBuffer(LiteralBuffer &&buf);
129 
130     void LoadAccumulatorString(const ir::AstNode *node, const util::StringView &str);
131 
132     void SetLabel(const ir::AstNode *node, Label *label);
133     void Branch(const ir::AstNode *node, class Label *label);
134     [[nodiscard]] bool CheckControlFlowChange() const;
135     Label *ControlFlowChangeBreak(const ir::Identifier *label = nullptr);
136     [[nodiscard]] Label *ControlFlowChangeContinue(const ir::Identifier *label);
137 
138     uint32_t TryDepth() const;
139     [[nodiscard]] CatchTable *CreateCatchTable(util::StringView exceptionType = "");
140     [[nodiscard]] CatchTable *CreateCatchTable(LabelPair tryLabelPair, util::StringView exceptionType = "");
141     void SortCatchTables();
142 
143     void SetFirstStmt(const ir::Statement *stmt) noexcept;
144 
145     [[noreturn]] static void Unimplemented();
146 
147     void SetVRegType(VReg vreg, const checker::Type *type);
148 
149     [[nodiscard]] virtual const checker::Type *GetVRegType(VReg vreg) const;
150 
151     [[nodiscard]] CompilerContext *Context() const noexcept;
152 
153     [[nodiscard]] virtual checker::Type const *TypeForVar(varbinder::Variable const *var) const noexcept;
154 
155     compiler::AstCompiler *GetAstCompiler() const;
156 
157 protected:
158     [[nodiscard]] SimpleAllocator &Sa() noexcept;
159     [[nodiscard]] const SimpleAllocator &Sa() const noexcept;
160     [[nodiscard]] RegAllocator &Ra() noexcept;
161     [[nodiscard]] const RegAllocator &Ra() const noexcept;
162     [[nodiscard]] RangeRegAllocator &Rra() noexcept;
163     [[nodiscard]] const RangeRegAllocator &Rra() const noexcept;
164     [[nodiscard]] ProgramElement *ProgElement() const noexcept;
165     [[nodiscard]] TypeMap &GetTypeMap() noexcept;
166     [[nodiscard]] const TypeMap &GetTypeMap() const noexcept;
167 
168 private:
169     AstCompiler *astCompiler_;
170     ArenaAllocator *allocator_ {};
171     CompilerContext *context_ {};
172     DebugInfo debugInfo_;
173     varbinder::FunctionScope *topScope_ {};
174     varbinder::Scope *scope_ {};
175     const ir::AstNode *rootNode_ {};
176     ArenaVector<IRNode *> insns_;
177     ArenaVector<CatchTable *> catchList_;
178     TypeMap typeMap_;
179     ProgramElement *programElement_ {};
180     DynamicContext *dynamicContext_ {};
181 
182     SimpleAllocator sa_;
183     RegAllocator ra_;
184     RangeRegAllocator rra_;
185     std::size_t labelId_ {0};
186     std::int32_t literalBufferIdx_ {0};
187 
188     std::uint32_t usedRegs_ {VReg::REG_START};
189     std::uint32_t totalRegs_ {VReg::REG_START};
190     friend class ScopeContext;
191     friend class RegScope;
192     friend class LocalRegScope;
193     friend class LoopRegScope;
194     friend class ParamRegScope;
195     friend class FunctionRegScope;
196     friend class DynamicContext;
197 };
198 }  // namespace panda::es2panda::compiler
199 
200 #endif
201