1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8 XX Exception Handling XX
10 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
11 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14 /*****************************************************************************/
21 /*****************************************************************************/
23 // The following holds the table of exception handlers.
27 EH_HANDLER_CATCH = 0x1, // Don't use zero (to aid debugging uninitialized memory)
31 EH_HANDLER_FAULT_WAS_FINALLY
34 // ToCORINFO_EH_CLAUSE_FLAGS: Convert an internal EHHandlerType to a CORINFO_EH_CLAUSE_FLAGS value
35 // to pass back to the VM.
36 inline CORINFO_EH_CLAUSE_FLAGS ToCORINFO_EH_CLAUSE_FLAGS(EHHandlerType type)
40 case EH_HANDLER_CATCH:
41 return CORINFO_EH_CLAUSE_NONE;
42 case EH_HANDLER_FILTER:
43 return CORINFO_EH_CLAUSE_FILTER;
44 case EH_HANDLER_FAULT:
45 case EH_HANDLER_FAULT_WAS_FINALLY:
46 return CORINFO_EH_CLAUSE_FAULT;
47 case EH_HANDLER_FINALLY:
48 return CORINFO_EH_CLAUSE_FINALLY;
54 // ToEHHandlerType: Convert a CORINFO_EH_CLAUSE_FLAGS value obtained from the VM in the EH clause structure
55 // to the internal EHHandlerType type.
56 inline EHHandlerType ToEHHandlerType(CORINFO_EH_CLAUSE_FLAGS flags)
58 if (flags & CORINFO_EH_CLAUSE_FAULT)
60 return EH_HANDLER_FAULT;
62 else if (flags & CORINFO_EH_CLAUSE_FINALLY)
64 return EH_HANDLER_FINALLY;
66 else if (flags & CORINFO_EH_CLAUSE_FILTER)
68 return EH_HANDLER_FILTER;
72 // If it's none of the others, assume it is a try/catch.
74 * The VM (and apparently VC) stick in extra bits in the flags field. We ignore any flags
75 * we don't know about.
77 return EH_HANDLER_CATCH;
83 BasicBlock* ebdTryBeg; // First block of the try
84 BasicBlock* ebdTryLast; // Last block of the try
85 BasicBlock* ebdHndBeg; // First block of the handler
86 BasicBlock* ebdHndLast; // Last block of the handler
88 BasicBlock* ebdFilter; // First block of filter, if HasFilter()
89 unsigned ebdTyp; // Exception type (a class token), otherwise
92 EHHandlerType ebdHandlerType;
94 #if !FEATURE_EH_FUNCLETS
95 // How nested is the try/handler within other *handlers* - 0 for outermost clauses, 1 for nesting with a handler,
97 unsigned short ebdHandlerNestingLevel;
98 #endif // !FEATURE_EH_FUNCLETS
100 static const unsigned short NO_ENCLOSING_INDEX = USHRT_MAX;
102 // The index of the enclosing outer try region, NO_ENCLOSING_INDEX if none.
103 // Be careful of 'mutually protect' catch and filter clauses (multiple
104 // handlers with the same try region): the try regions 'nest' so we set
105 // ebdEnclosingTryIndex, but the inner catch is *NOT* nested within the outer catch!
106 // That is, if the "inner catch" throws an exception, it won't be caught by
107 // the "outer catch" for mutually protect handlers.
108 unsigned short ebdEnclosingTryIndex;
110 // The index of the enclosing outer handler region, NO_ENCLOSING_INDEX if none.
111 unsigned short ebdEnclosingHndIndex;
113 #if FEATURE_EH_FUNCLETS
115 // After funclets are created, this is the index of corresponding FuncInfoDsc
116 // Special case for Filter/Filter-handler:
117 // Like the IL the filter funclet immediately preceeds the filter-handler funclet.
118 // So this index points to the filter-handler funclet. If you want the filter
119 // funclet index, just subtract 1.
120 unsigned short ebdFuncIndex;
122 #endif // FEATURE_EH_FUNCLETS
124 IL_OFFSET ebdTryBegOffset; // IL offsets of EH try/end regions as they are imported
125 IL_OFFSET ebdTryEndOffset;
126 IL_OFFSET ebdFilterBegOffset; // only set if HasFilter()
127 IL_OFFSET ebdHndBegOffset;
128 IL_OFFSET ebdHndEndOffset;
130 // Returns the last block of the filter. Assumes the EH clause is a try/filter/filter-handler type.
131 BasicBlock* BBFilterLast();
133 bool HasCatchHandler();
135 bool HasFinallyHandler();
136 bool HasFaultHandler();
137 bool HasFinallyOrFaultHandler();
139 // Returns the block to which control will flow if an (otherwise-uncaught) exception is raised
140 // in the try. This is normally "ebdHndBeg", unless the try region has a filter, in which case that is returned.
141 // (This is, in some sense, the "true handler," at least in the sense of control flow. Note
142 // that we model the transition from a filter to its handler as normal, non-exceptional control flow.)
143 BasicBlock* ExFlowBlock();
145 bool InTryRegionILRange(BasicBlock* pBlk);
146 bool InFilterRegionILRange(BasicBlock* pBlk);
147 bool InHndRegionILRange(BasicBlock* pBlk);
149 bool InTryRegionBBRange(BasicBlock* pBlk);
150 bool InFilterRegionBBRange(BasicBlock* pBlk);
151 bool InHndRegionBBRange(BasicBlock* pBlk);
153 IL_OFFSET ebdTryBegOffs();
154 IL_OFFSET ebdTryEndOffs();
155 IL_OFFSET ebdFilterBegOffs();
156 IL_OFFSET ebdFilterEndOffs();
157 IL_OFFSET ebdHndBegOffs();
158 IL_OFFSET ebdHndEndOffs();
160 static bool ebdIsSameILTry(EHblkDsc* h1, EHblkDsc* h2); // Same 'try' region? Compare IL range.
162 // Return the region index of the most nested EH region that encloses this region, or NO_ENCLOSING_INDEX
163 // if this region is directly in the main function body. Set '*inTryRegion' to 'true' if this region is
164 // most nested within a 'try' region, or 'false' if this region is most nested within a handler. (Note
165 // that filters cannot contain nested EH regions.)
166 unsigned ebdGetEnclosingRegionIndex(bool* inTryRegion);
168 static bool ebdIsSameTry(EHblkDsc* h1, EHblkDsc* h2); // Same 'try' region? Compare begin/last blocks.
169 bool ebdIsSameTry(Compiler* comp, unsigned t2);
170 bool ebdIsSameTry(BasicBlock* ebdTryBeg, BasicBlock* ebdTryLast);
173 void DispEntry(unsigned num); // Display this table entry
177 static bool InBBRange(BasicBlock* pBlk, BasicBlock* pStart, BasicBlock* pEnd);
180 /*****************************************************************************/
182 /*****************************************************************************/