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