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 */