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 VariableEnvScope; 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(); 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(VariableEnvScope *envScope, PandaGen *pg, LabelTarget target); 106 NO_COPY_SEMANTIC(LexEnvContext); 107 NO_MOVE_SEMANTIC(LexEnvContext); 108 ~LexEnvContext(); 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 const util::StringView &targetLabel) override; 118 void SetTryEndLabel(const ir::AstNode *node); SetTryEndFlag(bool flag)119 void SetTryEndFlag(bool flag) 120 { 121 tryEndFlag = flag; 122 } 123 GetTryEndFlag()124 bool GetTryEndFlag() const 125 { 126 return tryEndFlag; 127 } 128 private: 129 VariableEnvScope *envScope_; 130 CatchTable *catchTable_ {}; 131 bool tryEndFlag {false}; 132 }; 133 134 class IteratorContext : public DynamicContext { 135 public: 136 explicit IteratorContext(PandaGen *pg, const Iterator &iterator, LabelTarget target); 137 NO_COPY_SEMANTIC(IteratorContext); 138 NO_MOVE_SEMANTIC(IteratorContext); 139 ~IteratorContext(); 140 Type()141 DynamicContextType Type() const override 142 { 143 return DynamicContextType::ITERATOR; 144 } 145 GetIterator()146 const Iterator &GetIterator() const 147 { 148 return iterator_; 149 } 150 HasTryCatch()151 bool HasTryCatch() const override 152 { 153 return true; 154 } 155 156 void AbortContext([[maybe_unused]] ControlFlowChange cfc, 157 [[maybe_unused]] const util::StringView &targetLabel) override; 158 159 private: 160 const Iterator &iterator_; 161 CatchTable *catchTable_; 162 }; 163 164 class DestructuringIteratorContext : public DynamicContext { 165 public: 166 explicit DestructuringIteratorContext(PandaGen *pg, const DestructuringIterator &iterator); 167 NO_COPY_SEMANTIC(DestructuringIteratorContext); 168 NO_MOVE_SEMANTIC(DestructuringIteratorContext); 169 ~DestructuringIteratorContext() override; 170 Type()171 DynamicContextType Type() const override 172 { 173 return DynamicContextType::ITERATOR; 174 } 175 GetIterator()176 const DestructuringIterator &GetIterator() const 177 { 178 return iterator_; 179 } 180 HasTryCatch()181 bool HasTryCatch() const override 182 { 183 return true; 184 } 185 186 void AbortContext(ControlFlowChange cfc, const util::StringView &targetLabel) override; 187 188 private: 189 const DestructuringIterator &iterator_; 190 CatchTable *catchTable_; 191 }; 192 193 class TryContext : public DynamicContext { 194 public: 195 explicit TryContext(PandaGen *pg, const ir::TryStatement *tryStmt, bool hasFinalizer = true) 196 : DynamicContext(pg, {}), tryStmt_(tryStmt), hasFinalizer_(hasFinalizer) 197 { 198 InitCatchTable(); 199 InitFinalizer(); 200 } 201 TryContext(PandaGen * pg)202 explicit TryContext(PandaGen *pg) : DynamicContext(pg, {}) 203 { 204 InitCatchTable(); 205 } 206 207 NO_COPY_SEMANTIC(TryContext); 208 NO_MOVE_SEMANTIC(TryContext); 209 ~TryContext() = default; 210 Type()211 DynamicContextType Type() const override 212 { 213 return DynamicContextType::TRY; 214 } 215 HasTryCatch()216 bool HasTryCatch() const override 217 { 218 return true; 219 } 220 FinalizerRun()221 VReg FinalizerRun() const 222 { 223 return finalizerRun_; 224 } 225 GetCatchTable()226 CatchTable *GetCatchTable() const 227 { 228 return catchTable_; 229 } 230 231 const TryLabelSet &LabelSet() const; 232 bool HasFinalizer() const override; 233 void InitFinalizer(); 234 void EmitFinalizer(); 235 236 void AbortContext([[maybe_unused]] ControlFlowChange cfc, 237 [[maybe_unused]] const util::StringView &targetLabel) override; 238 239 private: 240 void InitCatchTable(); 241 242 const ir::TryStatement *tryStmt_ {}; 243 CatchTable *catchTable_ {}; 244 VReg finalizerRun_ {}; 245 bool hasFinalizer_ {}; 246 bool inFinalizer_ {}; 247 }; 248 } // namespace panda::es2panda::compiler 249 250 #endif 251