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