• 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 
IsUnderTry()96     bool IsUnderTry() const
97     {
98         return javaTry != nullptr;
99     }
100 
HasLSDA()101     bool HasLSDA() const
102     {
103         return startLabel != nullptr;
104     }
105 
GetRethrow()106     const UnaryStmtNode *GetRethrow() const
107     {
108         return rethrow;
109     }
110 
SetJavaTry(EHTry * javaTry)111     void SetJavaTry(EHTry *javaTry)
112     {
113         this->javaTry = javaTry;
114     }
115 
GetStartLabel()116     LabelNode *GetStartLabel()
117     {
118         return startLabel;
119     }
120 
GetEndLabel()121     LabelNode *GetEndLabel()
122     {
123         return endLabel;
124     }
125 
126     void Lower(CGFunc &cgFunc);
127     void ConvertThrowToRethrow(CGFunc &cgFunc);
128     void ConvertThrowToRuntime(CGFunc &cgFunc, BaseNode &arg);
129 
130 private:
131     UnaryStmtNode *rethrow;          /* must be a throw stmt */
132     EHTry *javaTry = nullptr;        /* the try statement wrapping this throw */
133     LabelNode *startLabel = nullptr; /* the label that "MCC_RethrowException" or "MCC_ThrowException" begin */
134     LabelNode *endLabel = nullptr;   /* the label that "MCC_RethrowException" or "MCC_ThrowException" end */
135 };
136 
137 class EHFunc {
138 public:
139     static constexpr uint8 kTypeEncoding = 0x9b; /* same thing as LSDAHeader.kTypeEncoding */
140     explicit EHFunc(CGFunc &func);
141     ~EHFunc() = default;
142 
143     void CollectEHInformation(std::vector<std::pair<LabelIdx, CatchNode *>> &catchVec);
144     void InsertEHSwitchTable();
145     void CreateLSDA();
146     bool NeedFullLSDA() const;
147     bool NeedFastLSDA() const;
148     void InsertCxaAfterEachCatch(const std::vector<std::pair<LabelIdx, CatchNode *>> &catchVec);
149     void GenerateCleanupLabel();
150     void MergeCatchToTry(const std::vector<std::pair<LabelIdx, CatchNode *>> &catchVec);
151     void BuildEHTypeTable(const std::vector<std::pair<LabelIdx, CatchNode *>> &catchVec);
152     void LowerThrow(); /* for non-personality function */
153     void CreateTypeInfoSt();
154     void DumpEHFunc() const;
155 
HasThrow()156     bool HasThrow() const
157     {
158         return !rethrowVec.empty();
159     }
160 
AddTry(EHTry & ehTry)161     void AddTry(EHTry &ehTry)
162     {
163         tryVec.emplace_back(&ehTry);
164     }
165 
GetEHTyTableSize()166     size_t GetEHTyTableSize() const
167     {
168         return ehTyTable.size();
169     }
170 
GetEHTyTableMember(int32 index)171     TyIdx &GetEHTyTableMember(int32 index)
172     {
173         CHECK_FATAL(static_cast<size_t>(index) < ehTyTable.size(), "out of ehTyTable");
174         return ehTyTable[index];
175     }
176 
GetLSDAHeader()177     LSDAHeader *GetLSDAHeader()
178     {
179         return lsdaHeader;
180     }
181 
GetLSDACallSiteTable()182     LSDACallSiteTable *GetLSDACallSiteTable()
183     {
184         return lsdaCallSiteTable;
185     }
186 
GetLSDACallSiteTable()187     const LSDACallSiteTable *GetLSDACallSiteTable() const
188     {
189         return lsdaCallSiteTable;
190     }
191 
GetLSDAActionTable()192     const LSDAActionTable *GetLSDAActionTable() const
193     {
194         return lsdaActionTable;
195     }
196 
AddRethrow(EHThrow & rethrow)197     void AddRethrow(EHThrow &rethrow)
198     {
199         rethrowVec.emplace_back(&rethrow);
200     }
201 
202 private:
203     void CreateLSDAAction();
204     void InsertDefaultLabelAndAbortFunc(BlockNode &blkNode, SwitchNode &switchNode, const StmtNode &beforeEndLabel);
205     void FillSwitchTable(SwitchNode &switchNode, const EHTry &ehTry);
206     void CreateLSDAHeader();
207     void FillLSDACallSiteTable();
208     LabelIdx CreateLabel(const std::string &cstr);
209     bool HasTry() const;
210 
211     CGFunc *cgFunc;
212     LabelIdx labelIdx = 0;
213     MapleVector<EHTry *> tryVec;           /* try stmt node */
214     MapleVector<TyIdx> ehTyTable;          /* the type that would emit in LSDA */
215     MapleMap<TyIdx, uint32> ty2IndexTable; /* use the TyIdx to get the index of ehTyTable; */
216     LSDAHeader *lsdaHeader = nullptr;
217     LSDACallSiteTable *lsdaCallSiteTable = nullptr;
218     LSDAActionTable *lsdaActionTable = nullptr;
219     MapleVector<EHThrow *> rethrowVec; /* EHRethrow */
220 };
221 
222 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgBuildEHFunc, maplebe::CGFunc)
223 MAPLE_FUNC_PHASE_DECLARE_END
224 } /* namespace maplebe */
225 
226 #endif /* MAPLEBE_INCLUDE_EH_EH_FUNC_H */