• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 MAPLEBE_INCLUDE_EH_EH_FUNC_H
17 #define MAPLEBE_INCLUDE_EH_EH_FUNC_H
18 #include "mir_parser.h"
19 #include "mir_function.h"
20 #include "lsda.h"
21 #include "cg_phase.h"
22 #include "maple_phase.h"
23 
24 namespace maplebe {
25 class EHTry {
26 public:
EHTry(MapleAllocator & alloc,TryNode & tryNode)27     EHTry(MapleAllocator &alloc, TryNode &tryNode) : tryNode(&tryNode), catchVec(alloc.Adapter()) {}
28     ~EHTry() = default;
29 
GetTryNode()30     TryNode *GetTryNode() const
31     {
32         return tryNode;
33     }
34 
SetEndtryNode(StmtNode & endtryNode)35     void SetEndtryNode(StmtNode &endtryNode)
36     {
37         this->endTryNode = &endtryNode;
38     }
39 
GetEndtryNode()40     StmtNode *GetEndtryNode()
41     {
42         return endTryNode;
43     }
44 
SetFallthruGoto(StmtNode * fallthruGoto)45     void SetFallthruGoto(StmtNode *fallthruGoto)
46     {
47         this->fallThroughGoto = fallthruGoto;
48     }
49 
GetFallthruGoto()50     StmtNode *GetFallthruGoto()
51     {
52         return fallThroughGoto;
53     }
54 
GetCatchVecSize()55     size_t GetCatchVecSize() const
56     {
57         return catchVec.size();
58     }
59 
PushBackCatchVec(CatchNode & catchNode)60     void PushBackCatchVec(CatchNode &catchNode)
61     {
62         catchVec.emplace_back(&catchNode);
63     }
64 
GetCatchNodeAt(size_t pos)65     CatchNode *GetCatchNodeAt(size_t pos) const
66     {
67         CHECK_FATAL(pos < GetCatchVecSize(), "pos is out of range.");
68         return catchVec.at(pos);
69     }
70 
SetLSDACallSite(LSDACallSite & lsdaCallSite)71     void SetLSDACallSite(LSDACallSite &lsdaCallSite)
72     {
73         this->lsdaCallSite = &lsdaCallSite;
74     }
75 
SetCSAction(uint32 action)76     void SetCSAction(uint32 action) const
77     {
78         lsdaCallSite->csAction = action;
79     }
80 
81     void DumpEHTry(const MIRModule &mirModule);
82 
83 private:
84     TryNode *tryNode;
85     StmtNode *endTryNode = nullptr;
86     StmtNode *fallThroughGoto = nullptr; /* no throw in the try block, the goto stmt to the fall through */
87     MapleVector<CatchNode *> catchVec;
88     LSDACallSite *lsdaCallSite = nullptr; /* one try has a callsite */
89 };
90 
91 class EHThrow {
92 public:
EHThrow(UnaryStmtNode & rtNode)93     explicit EHThrow(UnaryStmtNode &rtNode) : rethrow(&rtNode) {}
94     ~EHThrow() = default;
95 
HasLSDA()96     bool HasLSDA() const
97     {
98         return startLabel != nullptr;
99     }
100 
GetRethrow()101     const UnaryStmtNode *GetRethrow() const
102     {
103         return rethrow;
104     }
105 
GetStartLabel()106     LabelNode *GetStartLabel()
107     {
108         return startLabel;
109     }
110 
GetEndLabel()111     LabelNode *GetEndLabel()
112     {
113         return endLabel;
114     }
115 
116     void ConvertThrowToRethrow(CGFunc &cgFunc);
117     void ConvertThrowToRuntime(CGFunc &cgFunc, BaseNode &arg);
118 
119 private:
120     UnaryStmtNode *rethrow;          /* must be a throw stmt */
121     LabelNode *startLabel = nullptr; /* the label that "MCC_RethrowException" or "MCC_ThrowException" begin */
122     LabelNode *endLabel = nullptr;   /* the label that "MCC_RethrowException" or "MCC_ThrowException" end */
123 };
124 
125 class EHFunc {
126 public:
127     static constexpr uint8 kTypeEncoding = 0x9b; /* same thing as LSDAHeader.kTypeEncoding */
128     explicit EHFunc(CGFunc &func);
129     ~EHFunc() = default;
130 
131     void InsertEHSwitchTable();
132     void CreateLSDA();
133     bool NeedFullLSDA() const;
134     bool NeedFastLSDA() const;
135     void GenerateCleanupLabel();
136     void MergeCatchToTry(const std::vector<std::pair<LabelIdx, CatchNode *>> &catchVec);
137     void BuildEHTypeTable(const std::vector<std::pair<LabelIdx, CatchNode *>> &catchVec);
138     void CreateTypeInfoSt();
139     void DumpEHFunc() const;
140 
HasThrow()141     bool HasThrow() const
142     {
143         return !rethrowVec.empty();
144     }
145 
AddTry(EHTry & ehTry)146     void AddTry(EHTry &ehTry)
147     {
148         tryVec.emplace_back(&ehTry);
149     }
150 
GetEHTyTableSize()151     size_t GetEHTyTableSize() const
152     {
153         return ehTyTable.size();
154     }
155 
GetEHTyTableMember(int32 index)156     TyIdx &GetEHTyTableMember(int32 index)
157     {
158         CHECK_FATAL(static_cast<size_t>(index) < ehTyTable.size(), "out of ehTyTable");
159         return ehTyTable[index];
160     }
161 
GetLSDAHeader()162     LSDAHeader *GetLSDAHeader()
163     {
164         return lsdaHeader;
165     }
166 
GetLSDACallSiteTable()167     LSDACallSiteTable *GetLSDACallSiteTable()
168     {
169         return lsdaCallSiteTable;
170     }
171 
GetLSDACallSiteTable()172     const LSDACallSiteTable *GetLSDACallSiteTable() const
173     {
174         return lsdaCallSiteTable;
175     }
176 
GetLSDAActionTable()177     const LSDAActionTable *GetLSDAActionTable() const
178     {
179         return lsdaActionTable;
180     }
181 
AddRethrow(EHThrow & rethrow)182     void AddRethrow(EHThrow &rethrow)
183     {
184         rethrowVec.emplace_back(&rethrow);
185     }
186 
187 private:
188     void CreateLSDAAction();
189     void InsertDefaultLabelAndAbortFunc(BlockNode &blkNode, SwitchNode &switchNode, const StmtNode &beforeEndLabel);
190     void FillSwitchTable(SwitchNode &switchNode, const EHTry &ehTry);
191     void CreateLSDAHeader();
192     void FillLSDACallSiteTable();
193     LabelIdx CreateLabel(const std::string &cstr);
194     bool HasTry() const;
195 
196     CGFunc *cgFunc;
197     LabelIdx labelIdx = 0;
198     MapleVector<EHTry *> tryVec;           /* try stmt node */
199     MapleVector<TyIdx> ehTyTable;          /* the type that would emit in LSDA */
200     MapleMap<TyIdx, uint32> ty2IndexTable; /* use the TyIdx to get the index of ehTyTable; */
201     LSDAHeader *lsdaHeader = nullptr;
202     LSDACallSiteTable *lsdaCallSiteTable = nullptr;
203     LSDAActionTable *lsdaActionTable = nullptr;
204     MapleVector<EHThrow *> rethrowVec; /* EHRethrow */
205 };
206 
207 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgBuildEHFunc, maplebe::CGFunc)
208 MAPLE_FUNC_PHASE_DECLARE_END
209 } /* namespace maplebe */
210 
211 #endif /* MAPLEBE_INCLUDE_EH_EH_FUNC_H */