1/** 2 * Copyright (c) 2021 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_DYNAMIC_CONTEXT_H 17#define ES2PANDA_COMPILER_CORE_DYNAMIC_CONTEXT_H 18 19#include <util/ustring.h> 20#include <ir/irnode.h> 21#include <compiler/core/labelTarget.h> 22#include <compiler/base/iterators.h> 23 24namespace panda::es2panda::ir { 25class TryStatement; 26class ForOfStatement; 27class LabelledStatement; 28} // namespace panda::es2panda::ir 29 30namespace panda::es2panda::compiler { 31class PandaGen; 32class VariableEnvScope; 33class CatchTable; 34class TryLabelSet; 35 36enum class DynamicContextType { NONE, LABEL, LEX_ENV, ITERATOR, TRY }; 37 38class DynamicContext { 39public: 40 NO_COPY_SEMANTIC(DynamicContext); 41 NO_MOVE_SEMANTIC(DynamicContext); 42 virtual ~DynamicContext(); 43 44 void *operator new(size_t) = delete; 45 void *operator new[](size_t) = delete; 46 47 virtual void AbortContext([[maybe_unused]] ControlFlowChange cfc, 48 [[maybe_unused]] const util::StringView &targetLabel) {}; 49 50 virtual bool HasTryCatch() const 51 { 52 return false; 53 } 54 55 virtual bool HasFinalizer() const 56 { 57 return HasTryCatch(); 58 } 59 60 virtual DynamicContextType Type() const = 0; 61 62 DynamicContext *Prev() 63 { 64 return prev_; 65 } 66 67 const DynamicContext *Prev() const 68 { 69 return prev_; 70 } 71 72 const LabelTarget &Target() const 73 { 74 return target_; 75 } 76 77protected: 78 explicit DynamicContext(PandaGen *pg, LabelTarget target); 79 80 PandaGen *pg_; 81 LabelTarget target_; 82 DynamicContext *prev_ {}; 83}; 84 85class LabelContext : public DynamicContext { 86public: 87 explicit LabelContext(PandaGen *pg, LabelTarget target) : DynamicContext(pg, target) {} 88 explicit LabelContext(PandaGen *pg, const ir::LabelledStatement *labelledStmt); 89 NO_COPY_SEMANTIC(LabelContext); 90 NO_MOVE_SEMANTIC(LabelContext); 91 ~LabelContext(); 92 93 DynamicContextType Type() const override 94 { 95 return DynamicContextType::LABEL; 96 } 97 98private: 99 Label *label_ {}; 100 const ir::LabelledStatement *labelledStmt_ {}; 101}; 102 103class LexEnvContext : public DynamicContext { 104public: 105 explicit LexEnvContext(VariableEnvScope *envScope, PandaGen *pg, LabelTarget target); 106 NO_COPY_SEMANTIC(LexEnvContext); 107 NO_MOVE_SEMANTIC(LexEnvContext); 108 ~LexEnvContext(); 109 110 DynamicContextType Type() const override 111 { 112 return DynamicContextType::LEX_ENV; 113 } 114 115 bool HasTryCatch() const override; 116 void AbortContext([[maybe_unused]] ControlFlowChange cfc, 117 [[maybe_unused]] const util::StringView &targetLabel) override; 118 119private: 120 VariableEnvScope *envScope_; 121 CatchTable *catchTable_ {}; 122}; 123 124class IteratorContext : public DynamicContext { 125public: 126 explicit IteratorContext(PandaGen *pg, const Iterator &iterator, LabelTarget target); 127 NO_COPY_SEMANTIC(IteratorContext); 128 NO_MOVE_SEMANTIC(IteratorContext); 129 ~IteratorContext(); 130 131 DynamicContextType Type() const override 132 { 133 return DynamicContextType::ITERATOR; 134 } 135 136 const Iterator &GetIterator() const 137 { 138 return iterator_; 139 } 140 141 bool HasTryCatch() const override 142 { 143 return true; 144 } 145 146 void AbortContext([[maybe_unused]] ControlFlowChange cfc, 147 [[maybe_unused]] const util::StringView &targetLabel) override; 148 149private: 150 const Iterator &iterator_; 151 CatchTable *catchTable_; 152}; 153 154class DestructuringIteratorContext : public DynamicContext { 155public: 156 explicit DestructuringIteratorContext(PandaGen *pg, const DestructuringIterator &iterator); 157 NO_COPY_SEMANTIC(DestructuringIteratorContext); 158 NO_MOVE_SEMANTIC(DestructuringIteratorContext); 159 ~DestructuringIteratorContext() override; 160 161 DynamicContextType Type() const override 162 { 163 return DynamicContextType::ITERATOR; 164 } 165 166 const DestructuringIterator &GetIterator() const 167 { 168 return iterator_; 169 } 170 171 bool HasTryCatch() const override 172 { 173 return true; 174 } 175 176 void AbortContext(ControlFlowChange cfc, const util::StringView &targetLabel) override; 177 178private: 179 const DestructuringIterator &iterator_; 180 CatchTable *catchTable_; 181}; 182 183class TryContext : public DynamicContext { 184public: 185 explicit TryContext(PandaGen *pg, const ir::TryStatement *tryStmt, bool hasFinalizer = true) 186 : DynamicContext(pg, {}), tryStmt_(tryStmt), hasFinalizer_(hasFinalizer) 187 { 188 InitCatchTable(); 189 InitFinalizer(); 190 } 191 192 explicit TryContext(PandaGen *pg) : DynamicContext(pg, {}) 193 { 194 InitCatchTable(); 195 } 196 197 NO_COPY_SEMANTIC(TryContext); 198 NO_MOVE_SEMANTIC(TryContext); 199 ~TryContext() = default; 200 201 DynamicContextType Type() const override 202 { 203 return DynamicContextType::TRY; 204 } 205 206 bool HasTryCatch() const override 207 { 208 return true; 209 } 210 211 VReg FinalizerRun() const 212 { 213 return finalizerRun_; 214 } 215 216 CatchTable *GetCatchTable() const 217 { 218 return catchTable_; 219 } 220 221 const TryLabelSet &LabelSet() const; 222 bool HasFinalizer() const override; 223 void InitFinalizer(); 224 void EmitFinalizer(); 225 226 void AbortContext([[maybe_unused]] ControlFlowChange cfc, 227 [[maybe_unused]] const util::StringView &targetLabel) override; 228 229private: 230 void InitCatchTable(); 231 232 const ir::TryStatement *tryStmt_ {}; 233 CatchTable *catchTable_ {}; 234 VReg finalizerRun_ {}; 235 bool hasFinalizer_ {}; 236 bool inFinalizer_ {}; 237}; 238} // namespace panda::es2panda::compiler 239 240#endif 241