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 24 namespace panda::es2panda::ir { 25 class TryStatement; 26 class ForOfStatement; 27 class LabelledStatement; 28 } // namespace panda::es2panda::ir 29 30 namespace panda::es2panda::compiler { 31 class PandaGen; 32 class LoopEnvScope; 33 class CatchTable; 34 class TryLabelSet; 35 36 enum class DynamicContextType { NONE, LABEL, LEX_ENV, ITERATOR, TRY }; 37 38 class DynamicContext { 39 public: 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 AbortContext(ControlFlowChange cfc,const util::StringView & targetLabel)47 virtual void AbortContext([[maybe_unused]] ControlFlowChange cfc, 48 [[maybe_unused]] const util::StringView &targetLabel) {}; 49 HasTryCatch()50 virtual bool HasTryCatch() const 51 { 52 return false; 53 } 54 HasFinalizer()55 virtual bool HasFinalizer() const 56 { 57 return HasTryCatch(); 58 } 59 60 virtual DynamicContextType Type() const = 0; 61 Prev()62 DynamicContext *Prev() 63 { 64 return prev_; 65 } 66 Prev()67 const DynamicContext *Prev() const 68 { 69 return prev_; 70 } 71 Target()72 const LabelTarget &Target() const 73 { 74 return target_; 75 } 76 77 protected: 78 explicit DynamicContext(PandaGen *pg, LabelTarget target); 79 80 PandaGen *pg_; 81 LabelTarget target_; 82 DynamicContext *prev_ {}; 83 }; 84 85 class LabelContext : public DynamicContext { 86 public: LabelContext(PandaGen * pg,LabelTarget target)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() override; 92 Type()93 DynamicContextType Type() const override 94 { 95 return DynamicContextType::LABEL; 96 } 97 98 private: 99 Label *label_ {}; 100 const ir::LabelledStatement *labelledStmt_ {}; 101 }; 102 103 class LexEnvContext : public DynamicContext { 104 public: 105 explicit LexEnvContext(LoopEnvScope *envScope, PandaGen *pg, LabelTarget target); 106 NO_COPY_SEMANTIC(LexEnvContext); 107 NO_MOVE_SEMANTIC(LexEnvContext); 108 ~LexEnvContext() override; 109 Type()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 119 private: 120 LoopEnvScope *envScope_; 121 CatchTable *catchTable_ {}; 122 }; 123 124 class IteratorContext : public DynamicContext { 125 public: 126 explicit IteratorContext(PandaGen *pg, const Iterator &iterator, LabelTarget target); 127 NO_COPY_SEMANTIC(IteratorContext); 128 NO_MOVE_SEMANTIC(IteratorContext); 129 ~IteratorContext() override; 130 Type()131 DynamicContextType Type() const override 132 { 133 return DynamicContextType::ITERATOR; 134 } 135 GetIterator()136 const Iterator &GetIterator() const 137 { 138 return iterator_; 139 } 140 HasTryCatch()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 149 private: 150 const Iterator &iterator_; 151 CatchTable *catchTable_; 152 }; 153 154 class DestructuringIteratorContext : public DynamicContext { 155 public: 156 explicit DestructuringIteratorContext(PandaGen *pg, const DestructuringIterator &iterator); 157 NO_COPY_SEMANTIC(DestructuringIteratorContext); 158 NO_MOVE_SEMANTIC(DestructuringIteratorContext); 159 ~DestructuringIteratorContext() override; 160 Type()161 DynamicContextType Type() const override 162 { 163 return DynamicContextType::ITERATOR; 164 } 165 GetIterator()166 const DestructuringIterator &GetIterator() const 167 { 168 return iterator_; 169 } 170 HasTryCatch()171 bool HasTryCatch() const override 172 { 173 return true; 174 } 175 176 void AbortContext(ControlFlowChange cfc, const util::StringView &targetLabel) override; 177 178 private: 179 const DestructuringIterator &iterator_; 180 CatchTable *catchTable_; 181 }; 182 183 class TryContext : public DynamicContext { 184 public: 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 TryContext(PandaGen * pg)192 explicit TryContext(PandaGen *pg) : DynamicContext(pg, {}) 193 { 194 InitCatchTable(); 195 } 196 197 NO_COPY_SEMANTIC(TryContext); 198 NO_MOVE_SEMANTIC(TryContext); 199 ~TryContext() override = default; 200 Type()201 DynamicContextType Type() const override 202 { 203 return DynamicContextType::TRY; 204 } 205 HasTryCatch()206 bool HasTryCatch() const override 207 { 208 return true; 209 } 210 FinalizerRun()211 VReg FinalizerRun() const 212 { 213 return finalizerRun_; 214 } 215 GetCatchTable()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 229 private: 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