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