• 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 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