annotate gcc/ada/libgnat/a-exexpr.adb @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT COMPILER COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- A D A . E X C E P T I O N S . E X C E P T I O N _ P R O P A G A T I O N --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
9 -- Copyright (C) 1992-2019, Free Software Foundation, Inc. --
111
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
kono
parents:
diff changeset
17 -- --
kono
parents:
diff changeset
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
kono
parents:
diff changeset
19 -- additional permissions described in the GCC Runtime Library Exception, --
kono
parents:
diff changeset
20 -- version 3.1, as published by the Free Software Foundation. --
kono
parents:
diff changeset
21 -- --
kono
parents:
diff changeset
22 -- You should have received a copy of the GNU General Public License and --
kono
parents:
diff changeset
23 -- a copy of the GCC Runtime Library Exception along with this program; --
kono
parents:
diff changeset
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
kono
parents:
diff changeset
25 -- <http://www.gnu.org/licenses/>. --
kono
parents:
diff changeset
26 -- --
kono
parents:
diff changeset
27 -- GNAT was originally developed by the GNAT team at New York University. --
kono
parents:
diff changeset
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
kono
parents:
diff changeset
29 -- --
kono
parents:
diff changeset
30 ------------------------------------------------------------------------------
kono
parents:
diff changeset
31
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
32 -- This is the version using the GCC EH mechanism, which could rely on
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
33 -- different underlying unwinding engines, for example DWARF or ARM unwind
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
34 -- info based. Here is a sketch of the most prominent data structures
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
35 -- involved:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
36
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
37 -- (s-excmac.ads)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
38 -- GNAT_GCC_Exception:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
39 -- *-----------------------------------*
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
40 -- o-->| (s-excmac.ads) |
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
41 -- | | Header : <gcc occurrence type> |
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
42 -- | | - Class |
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
43 -- | | ... | Constraint_Error:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
44 -- | |-----------------------------------* Program_Error:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
45 -- | | (a-except.ads) | Foreign_Exception:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
46 -- | | Occurrence : Exception_Occurrence |
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
47 -- | | | (s-stalib. ads)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
48 -- | | - Id : Exception_Id --------------> Exception_Data
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
49 -- o------ - Machine_Occurrence | *------------------------*
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
50 -- | - Msg | | Not_Handled_By_Others |
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
51 -- | - Traceback | | Lang |
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
52 -- | ... | | Foreign_Data --o |
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
53 -- *-----------------------------------* | Full_Name | |
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
54 -- || | ... | |
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
55 -- || foreign rtti blob *----------------|-------*
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
56 -- || *---------------* |
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
57 -- || | ... ... |<-------------------------o
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
58 -- || *---------------*
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
59 -- ||
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
60 -- Setup_Current_Excep()
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
61 -- ||
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
62 -- || Latch into ATCB or
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
63 -- || environment Current Exception Buffer:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
64 -- ||
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
65 -- vv
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
66 -- <> : Exception_Occurrence
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
67 -- *---------------------------*
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
68 -- | ... ... ... ... ... ... * --- Get_Current_Excep() ---->
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
69 -- *---------------------------*
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
70
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
71 -- On "raise" events, the runtime allocates a new GNAT_GCC_Exception
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
72 -- instance and eventually calls into libgcc's Unwind_RaiseException.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
73 -- This part handles the object through the header part only.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
74
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
75 -- During execution, Get_Current_Excep provides a pointer to the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
76 -- Exception_Occurrence being raised or last raised by the current task.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
77
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
78 -- This is actually the address of a statically allocated
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
79 -- Exception_Occurrence attached to the current ATCB or to the environment
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
80 -- thread into which an occurrence being raised is synchronized at critical
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
81 -- points during the raise process, via Setup_Current_Excep.
111
kono
parents:
diff changeset
82
kono
parents:
diff changeset
83 with Ada.Unchecked_Conversion;
kono
parents:
diff changeset
84 with Ada.Unchecked_Deallocation;
kono
parents:
diff changeset
85
kono
parents:
diff changeset
86 with System.Storage_Elements; use System.Storage_Elements;
kono
parents:
diff changeset
87 with System.Exceptions.Machine; use System.Exceptions.Machine;
kono
parents:
diff changeset
88
kono
parents:
diff changeset
89 separate (Ada.Exceptions)
kono
parents:
diff changeset
90 package body Exception_Propagation is
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 use Exception_Traces;
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 Foreign_Exception : aliased System.Standard_Library.Exception_Data;
kono
parents:
diff changeset
95 pragma Import (Ada, Foreign_Exception,
kono
parents:
diff changeset
96 "system__exceptions__foreign_exception");
kono
parents:
diff changeset
97 -- Id for foreign exceptions
kono
parents:
diff changeset
98
kono
parents:
diff changeset
99 --------------------------------------------------------------
kono
parents:
diff changeset
100 -- GNAT Specific Entities To Deal With The GCC EH Circuitry --
kono
parents:
diff changeset
101 --------------------------------------------------------------
kono
parents:
diff changeset
102
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
103 -- Phase identifiers (Unwind Actions)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
104
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
105 type Unwind_Action is new Integer;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
106 pragma Convention (C, Unwind_Action);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
107
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
108 UA_SEARCH_PHASE : constant Unwind_Action := 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
109 UA_CLEANUP_PHASE : constant Unwind_Action := 2;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
110 UA_HANDLER_FRAME : constant Unwind_Action := 4;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
111 UA_FORCE_UNWIND : constant Unwind_Action := 8;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
112 UA_END_OF_STACK : constant Unwind_Action := 16; -- GCC extension
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
113
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
114 pragma Unreferenced
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
115 (UA_HANDLER_FRAME,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
116 UA_FORCE_UNWIND,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
117 UA_END_OF_STACK);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
118
111
kono
parents:
diff changeset
119 procedure GNAT_GCC_Exception_Cleanup
kono
parents:
diff changeset
120 (Reason : Unwind_Reason_Code;
kono
parents:
diff changeset
121 Excep : not null GNAT_GCC_Exception_Access);
kono
parents:
diff changeset
122 pragma Convention (C, GNAT_GCC_Exception_Cleanup);
kono
parents:
diff changeset
123 -- Procedure called when a GNAT GCC exception is free.
kono
parents:
diff changeset
124
kono
parents:
diff changeset
125 procedure Propagate_GCC_Exception
kono
parents:
diff changeset
126 (GCC_Exception : not null GCC_Exception_Access);
kono
parents:
diff changeset
127 pragma No_Return (Propagate_GCC_Exception);
kono
parents:
diff changeset
128 -- Propagate a GCC exception
kono
parents:
diff changeset
129
kono
parents:
diff changeset
130 procedure Reraise_GCC_Exception
kono
parents:
diff changeset
131 (GCC_Exception : not null GCC_Exception_Access);
kono
parents:
diff changeset
132 pragma No_Return (Reraise_GCC_Exception);
kono
parents:
diff changeset
133 pragma Export (C, Reraise_GCC_Exception, "__gnat_reraise_zcx");
kono
parents:
diff changeset
134 -- Called to implement raise without exception, ie reraise. Called
kono
parents:
diff changeset
135 -- directly from gigi.
kono
parents:
diff changeset
136
kono
parents:
diff changeset
137 function Setup_Current_Excep
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
138 (GCC_Exception : not null GCC_Exception_Access;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
139 Phase : Unwind_Action) return EOA;
111
kono
parents:
diff changeset
140 pragma Export (C, Setup_Current_Excep, "__gnat_setup_current_excep");
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
141 -- Acknowledge GCC_Exception as the current exception object being
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
142 -- raised, which could be an Ada or a foreign exception object. Return
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
143 -- a pointer to the embedded Ada occurrence for an Ada exception object,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
144 -- to the current exception buffer otherwise.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
145 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
146 -- Synchronize the current exception buffer as needed for possible
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
147 -- accesses through Get_Current_Except.all afterwards, depending on the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
148 -- Phase bits, received either from the personality routine, from a
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
149 -- forced_unwind cleanup handler, or just before the start of propagation
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
150 -- for an Ada exception (Phase 0 in this case).
111
kono
parents:
diff changeset
151
kono
parents:
diff changeset
152 procedure Unhandled_Except_Handler
kono
parents:
diff changeset
153 (GCC_Exception : not null GCC_Exception_Access);
kono
parents:
diff changeset
154 pragma No_Return (Unhandled_Except_Handler);
kono
parents:
diff changeset
155 pragma Export (C, Unhandled_Except_Handler,
kono
parents:
diff changeset
156 "__gnat_unhandled_except_handler");
kono
parents:
diff changeset
157 -- Called for handle unhandled exceptions, ie the last chance handler
kono
parents:
diff changeset
158 -- on platforms (such as SEH) that never returns after throwing an
kono
parents:
diff changeset
159 -- exception. Called directly by gigi.
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 function CleanupUnwind_Handler
kono
parents:
diff changeset
162 (UW_Version : Integer;
kono
parents:
diff changeset
163 UW_Phases : Unwind_Action;
kono
parents:
diff changeset
164 UW_Eclass : Exception_Class;
kono
parents:
diff changeset
165 UW_Exception : not null GCC_Exception_Access;
kono
parents:
diff changeset
166 UW_Context : System.Address;
kono
parents:
diff changeset
167 UW_Argument : System.Address) return Unwind_Reason_Code;
kono
parents:
diff changeset
168 pragma Import (C, CleanupUnwind_Handler,
kono
parents:
diff changeset
169 "__gnat_cleanupunwind_handler");
kono
parents:
diff changeset
170 -- Hook called at each step of the forced unwinding we perform to trigger
kono
parents:
diff changeset
171 -- cleanups found during the propagation of an unhandled exception.
kono
parents:
diff changeset
172
kono
parents:
diff changeset
173 -- GCC runtime functions used. These are C non-void functions, actually,
kono
parents:
diff changeset
174 -- but we ignore the return values. See raise.c as to why we are using
kono
parents:
diff changeset
175 -- __gnat stubs for these.
kono
parents:
diff changeset
176
kono
parents:
diff changeset
177 procedure Unwind_RaiseException
kono
parents:
diff changeset
178 (UW_Exception : not null GCC_Exception_Access);
kono
parents:
diff changeset
179 pragma Import (C, Unwind_RaiseException, "__gnat_Unwind_RaiseException");
kono
parents:
diff changeset
180
kono
parents:
diff changeset
181 procedure Unwind_ForcedUnwind
kono
parents:
diff changeset
182 (UW_Exception : not null GCC_Exception_Access;
kono
parents:
diff changeset
183 UW_Handler : System.Address;
kono
parents:
diff changeset
184 UW_Argument : System.Address);
kono
parents:
diff changeset
185 pragma Import (C, Unwind_ForcedUnwind, "__gnat_Unwind_ForcedUnwind");
kono
parents:
diff changeset
186
kono
parents:
diff changeset
187 procedure Set_Exception_Parameter
kono
parents:
diff changeset
188 (Excep : EOA;
kono
parents:
diff changeset
189 GCC_Exception : not null GCC_Exception_Access);
kono
parents:
diff changeset
190 pragma Export
kono
parents:
diff changeset
191 (C, Set_Exception_Parameter, "__gnat_set_exception_parameter");
kono
parents:
diff changeset
192 -- Called inserted by gigi to set the exception choice parameter from the
kono
parents:
diff changeset
193 -- gcc occurrence.
kono
parents:
diff changeset
194
kono
parents:
diff changeset
195 procedure Set_Foreign_Occurrence (Excep : EOA; Mo : System.Address);
kono
parents:
diff changeset
196 -- Utility routine to initialize occurrence Excep from a foreign exception
kono
parents:
diff changeset
197 -- whose machine occurrence is Mo. The message is empty, the backtrace
kono
parents:
diff changeset
198 -- is empty too and the exception identity is Foreign_Exception.
kono
parents:
diff changeset
199
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
200 -- Hooks called when entering/leaving an exception handler for a
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
201 -- given occurrence. The calls are generated by gigi in
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
202 -- Exception_Handler_to_gnu_gcc.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
203
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
204 -- Begin_Handler_v1, called when entering an exception handler,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
205 -- claims responsibility for the handler to release the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
206 -- GCC_Exception occurrence. End_Handler_v1, called when
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
207 -- leaving the handler, releases the occurrence, unless the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
208 -- occurrence is propagating further up, or the handler is
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
209 -- dynamically nested in the context of another handler that
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
210 -- claimed responsibility for releasing that occurrence.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
211
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
212 -- Responsibility is claimed by changing the Cleanup field to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
213 -- Claimed_Cleanup, which enables claimed exceptions to be
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
214 -- recognized, and avoids accidental releases even by foreign
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
215 -- handlers.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
216
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
217 function Begin_Handler_v1
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
218 (GCC_Exception : not null GCC_Exception_Access)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
219 return System.Address;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
220 pragma Export (C, Begin_Handler_v1, "__gnat_begin_handler_v1");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
221 -- Called when entering an exception handler. Claim
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
222 -- responsibility for releasing GCC_Exception, by setting the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
223 -- cleanup/release function to Claimed_Cleanup, and return the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
224 -- address of the previous cleanup/release function.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
225
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
226 procedure End_Handler_v1
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
227 (GCC_Exception : not null GCC_Exception_Access;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
228 Saved_Cleanup : System.Address;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
229 Propagating_Exception : GCC_Exception_Access);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
230 pragma Export (C, End_Handler_v1, "__gnat_end_handler_v1");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
231 -- Called when leaving an exception handler. Restore the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
232 -- Saved_Cleanup in the GCC_Exception occurrence, and then release
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
233 -- it, unless it remains claimed by an enclosing handler, or
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
234 -- GCC_Exception and Propagating_Exception are the same
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
235 -- occurrence. Propagating_Exception could be either an
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
236 -- occurrence (re)raised within the handler of GCC_Exception, when
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
237 -- we're executing as an exceptional cleanup, or null, if we're
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
238 -- completing the handler of GCC_Exception normally.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
239
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
240 procedure Claimed_Cleanup
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
241 (Reason : Unwind_Reason_Code;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
242 GCC_Exception : not null GCC_Exception_Access);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
243 pragma Export (C, Claimed_Cleanup, "__gnat_claimed_cleanup");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
244 -- A do-nothing placeholder installed as GCC_Exception.Cleanup
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
245 -- while handling GCC_Exception, to claim responsibility for
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
246 -- releasing it, and to stop it from being accidentally released.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
247
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
248 -- The following are version 0 implementations of the version 1
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
249 -- hooks above. They remain in place for compatibility with the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
250 -- output of compilers that still use version 0, such as those
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
251 -- used during bootstrap. They are interoperable with the v1
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
252 -- hooks, except that the older versions may malfunction when
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
253 -- handling foreign exceptions passed to Reraise_Occurrence.
111
kono
parents:
diff changeset
254
kono
parents:
diff changeset
255 procedure Begin_Handler (GCC_Exception : not null GCC_Exception_Access);
kono
parents:
diff changeset
256 pragma Export (C, Begin_Handler, "__gnat_begin_handler");
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
257 -- Called when entering an exception handler translated by an old
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
258 -- compiler. It does nothing.
111
kono
parents:
diff changeset
259
kono
parents:
diff changeset
260 procedure End_Handler (GCC_Exception : GCC_Exception_Access);
kono
parents:
diff changeset
261 pragma Export (C, End_Handler, "__gnat_end_handler");
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
262 -- Called when leaving an exception handler translated by an old
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
263 -- compiler. It releases GCC_Exception, unless it is null. It is
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
264 -- only ever null when the handler has a 'raise;' translated by a
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
265 -- v0-using compiler. The artificial handler variable passed to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
266 -- End_Handler was set to null to tell End_Handler to refrain from
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
267 -- releasing the reraised exception. In v1 safer ways are used to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
268 -- accomplish that.
111
kono
parents:
diff changeset
269
kono
parents:
diff changeset
270 --------------------------------------------------------------------
kono
parents:
diff changeset
271 -- Accessors to Basic Components of a GNAT Exception Data Pointer --
kono
parents:
diff changeset
272 --------------------------------------------------------------------
kono
parents:
diff changeset
273
kono
parents:
diff changeset
274 -- As of today, these are only used by the C implementation of the GCC
kono
parents:
diff changeset
275 -- propagation personality routine to avoid having to rely on a C
kono
parents:
diff changeset
276 -- counterpart of the whole exception_data structure, which is both
kono
parents:
diff changeset
277 -- painful and error prone. These subprograms could be moved to a more
kono
parents:
diff changeset
278 -- widely visible location if need be.
kono
parents:
diff changeset
279
kono
parents:
diff changeset
280 function Is_Handled_By_Others (E : Exception_Data_Ptr) return Boolean;
kono
parents:
diff changeset
281 pragma Export (C, Is_Handled_By_Others, "__gnat_is_handled_by_others");
kono
parents:
diff changeset
282 pragma Warnings (Off, Is_Handled_By_Others);
kono
parents:
diff changeset
283
kono
parents:
diff changeset
284 function Language_For (E : Exception_Data_Ptr) return Character;
kono
parents:
diff changeset
285 pragma Export (C, Language_For, "__gnat_language_for");
kono
parents:
diff changeset
286
kono
parents:
diff changeset
287 function Foreign_Data_For (E : Exception_Data_Ptr) return Address;
kono
parents:
diff changeset
288 pragma Export (C, Foreign_Data_For, "__gnat_foreign_data_for");
kono
parents:
diff changeset
289
kono
parents:
diff changeset
290 function EID_For (GNAT_Exception : not null GNAT_GCC_Exception_Access)
kono
parents:
diff changeset
291 return Exception_Id;
kono
parents:
diff changeset
292 pragma Export (C, EID_For, "__gnat_eid_for");
kono
parents:
diff changeset
293
kono
parents:
diff changeset
294 ---------------------------------------------------------------------------
kono
parents:
diff changeset
295 -- Objects to materialize "others" and "all others" in the GCC EH tables --
kono
parents:
diff changeset
296 ---------------------------------------------------------------------------
kono
parents:
diff changeset
297
kono
parents:
diff changeset
298 -- Currently, these only have their address taken and compared so there is
kono
parents:
diff changeset
299 -- no real point having whole exception data blocks allocated. Note that
kono
parents:
diff changeset
300 -- there are corresponding declarations in gigi (trans.c) which must be
kono
parents:
diff changeset
301 -- kept properly synchronized.
kono
parents:
diff changeset
302
kono
parents:
diff changeset
303 Others_Value : constant Character := 'O';
kono
parents:
diff changeset
304 pragma Export (C, Others_Value, "__gnat_others_value");
kono
parents:
diff changeset
305
kono
parents:
diff changeset
306 All_Others_Value : constant Character := 'A';
kono
parents:
diff changeset
307 pragma Export (C, All_Others_Value, "__gnat_all_others_value");
kono
parents:
diff changeset
308
kono
parents:
diff changeset
309 Unhandled_Others_Value : constant Character := 'U';
kono
parents:
diff changeset
310 pragma Export (C, Unhandled_Others_Value, "__gnat_unhandled_others_value");
kono
parents:
diff changeset
311 -- Special choice (emitted by gigi) to catch and notify unhandled
kono
parents:
diff changeset
312 -- exceptions on targets which always handle exceptions (such as SEH).
kono
parents:
diff changeset
313 -- The handler will simply call Unhandled_Except_Handler.
kono
parents:
diff changeset
314
kono
parents:
diff changeset
315 -------------------------
kono
parents:
diff changeset
316 -- Allocate_Occurrence --
kono
parents:
diff changeset
317 -------------------------
kono
parents:
diff changeset
318
kono
parents:
diff changeset
319 function Allocate_Occurrence return EOA is
kono
parents:
diff changeset
320 Res : GNAT_GCC_Exception_Access;
kono
parents:
diff changeset
321
kono
parents:
diff changeset
322 begin
kono
parents:
diff changeset
323 Res := New_Occurrence;
kono
parents:
diff changeset
324 Res.Header.Cleanup := GNAT_GCC_Exception_Cleanup'Address;
kono
parents:
diff changeset
325 Res.Occurrence.Machine_Occurrence := Res.all'Address;
kono
parents:
diff changeset
326
kono
parents:
diff changeset
327 return Res.Occurrence'Access;
kono
parents:
diff changeset
328 end Allocate_Occurrence;
kono
parents:
diff changeset
329
kono
parents:
diff changeset
330 --------------------------------
kono
parents:
diff changeset
331 -- GNAT_GCC_Exception_Cleanup --
kono
parents:
diff changeset
332 --------------------------------
kono
parents:
diff changeset
333
kono
parents:
diff changeset
334 procedure GNAT_GCC_Exception_Cleanup
kono
parents:
diff changeset
335 (Reason : Unwind_Reason_Code;
kono
parents:
diff changeset
336 Excep : not null GNAT_GCC_Exception_Access)
kono
parents:
diff changeset
337 is
kono
parents:
diff changeset
338 pragma Unreferenced (Reason);
kono
parents:
diff changeset
339
kono
parents:
diff changeset
340 procedure Free is new Unchecked_Deallocation
kono
parents:
diff changeset
341 (GNAT_GCC_Exception, GNAT_GCC_Exception_Access);
kono
parents:
diff changeset
342
kono
parents:
diff changeset
343 Copy : GNAT_GCC_Exception_Access := Excep;
kono
parents:
diff changeset
344
kono
parents:
diff changeset
345 begin
kono
parents:
diff changeset
346 -- Simply free the memory
kono
parents:
diff changeset
347
kono
parents:
diff changeset
348 Free (Copy);
kono
parents:
diff changeset
349 end GNAT_GCC_Exception_Cleanup;
kono
parents:
diff changeset
350
kono
parents:
diff changeset
351 ----------------------------
kono
parents:
diff changeset
352 -- Set_Foreign_Occurrence --
kono
parents:
diff changeset
353 ----------------------------
kono
parents:
diff changeset
354
kono
parents:
diff changeset
355 procedure Set_Foreign_Occurrence (Excep : EOA; Mo : System.Address) is
kono
parents:
diff changeset
356 begin
kono
parents:
diff changeset
357 Excep.all := (
kono
parents:
diff changeset
358 Id => Foreign_Exception'Access,
kono
parents:
diff changeset
359 Machine_Occurrence => Mo,
kono
parents:
diff changeset
360 Msg => <>,
kono
parents:
diff changeset
361 Msg_Length => 0,
kono
parents:
diff changeset
362 Exception_Raised => True,
kono
parents:
diff changeset
363 Pid => Local_Partition_ID,
kono
parents:
diff changeset
364 Num_Tracebacks => 0,
kono
parents:
diff changeset
365 Tracebacks => <>);
kono
parents:
diff changeset
366 end Set_Foreign_Occurrence;
kono
parents:
diff changeset
367
kono
parents:
diff changeset
368 -------------------------
kono
parents:
diff changeset
369 -- Setup_Current_Excep --
kono
parents:
diff changeset
370 -------------------------
kono
parents:
diff changeset
371
kono
parents:
diff changeset
372 function Setup_Current_Excep
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
373 (GCC_Exception : not null GCC_Exception_Access;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
374 Phase : Unwind_Action) return EOA
111
kono
parents:
diff changeset
375 is
kono
parents:
diff changeset
376 Excep : constant EOA := Get_Current_Excep.all;
kono
parents:
diff changeset
377
kono
parents:
diff changeset
378 begin
kono
parents:
diff changeset
379
kono
parents:
diff changeset
380 if GCC_Exception.Class = GNAT_Exception_Class then
kono
parents:
diff changeset
381
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
382 -- Ada exception : latch the occurrence data in the Current
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
383 -- Exception Buffer if needed and return a pointer to the original
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
384 -- Ada exception object. This particular object was specifically
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
385 -- allocated for this raise and is thus more precise than the fixed
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
386 -- Current Exception Buffer address.
111
kono
parents:
diff changeset
387
kono
parents:
diff changeset
388 declare
kono
parents:
diff changeset
389 GNAT_Occurrence : constant GNAT_GCC_Exception_Access :=
kono
parents:
diff changeset
390 To_GNAT_GCC_Exception (GCC_Exception);
kono
parents:
diff changeset
391 begin
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
392
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
393 -- When reaching here during SEARCH_PHASE, no need to
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
394 -- replicate the copy performed at the propagation start.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
395
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
396 if Phase /= UA_SEARCH_PHASE then
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
397 Excep.all := GNAT_Occurrence.Occurrence;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
398 end if;
111
kono
parents:
diff changeset
399 return GNAT_Occurrence.Occurrence'Access;
kono
parents:
diff changeset
400 end;
kono
parents:
diff changeset
401
kono
parents:
diff changeset
402 else
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
403
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
404 -- Foreign exception (caught by Ada handler, reaching here from
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
405 -- personality routine) : The original exception object doesn't hold
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
406 -- an Ada occurrence info. Set the foreign data pointer in the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
407 -- Current Exception Buffer and return the address of the latter.
111
kono
parents:
diff changeset
408
kono
parents:
diff changeset
409 Set_Foreign_Occurrence (Excep, GCC_Exception.all'Address);
kono
parents:
diff changeset
410
kono
parents:
diff changeset
411 return Excep;
kono
parents:
diff changeset
412 end if;
kono
parents:
diff changeset
413 end Setup_Current_Excep;
kono
parents:
diff changeset
414
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
415 ----------------------
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
416 -- Begin_Handler_v1 --
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
417 ----------------------
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
418
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
419 function Begin_Handler_v1
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
420 (GCC_Exception : not null GCC_Exception_Access)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
421 return System.Address is
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
422 Saved_Cleanup : constant System.Address := GCC_Exception.Cleanup;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
423 begin
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
424 -- Claim responsibility for releasing this exception, and stop
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
425 -- others from releasing it.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
426 GCC_Exception.Cleanup := Claimed_Cleanup'Address;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
427 return Saved_Cleanup;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
428 end Begin_Handler_v1;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
429
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
430 --------------------
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
431 -- End_Handler_v1 --
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
432 --------------------
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
433
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
434 procedure End_Handler_v1
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
435 (GCC_Exception : not null GCC_Exception_Access;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
436 Saved_Cleanup : System.Address;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
437 Propagating_Exception : GCC_Exception_Access) is
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
438 begin
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
439 GCC_Exception.Cleanup := Saved_Cleanup;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
440 -- Restore the Saved_Cleanup, so that it is either used to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
441 -- release GCC_Exception below, or transferred to the next
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
442 -- handler of the Propagating_Exception occurrence. The
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
443 -- following test ensures that an occurrence is only released
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
444 -- once, even after reraises.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
445 --
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
446 -- The idea is that the GCC_Exception is not to be released
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
447 -- unless it had an unclaimed Cleanup when the handler started
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
448 -- (see Begin_Handler_v1 above), but if we propagate across its
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
449 -- handler a reraise of the same exception, we transfer to the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
450 -- Propagating_Exception the responsibility for running the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
451 -- Saved_Cleanup when its handler completes.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
452 --
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
453 -- This ownership transfer mechanism ensures safety, as in
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
454 -- single release and no dangling pointers, because there is no
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
455 -- way to hold on to the Machine_Occurrence of an
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
456 -- Exception_Occurrence: the only situations in which another
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
457 -- Exception_Occurrence gets the same Machine_Occurrence are
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
458 -- through Reraise_Occurrence, and plain reraise, and so we
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
459 -- have the following possibilities:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
460 --
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
461 -- - Reraise_Occurrence is handled within the running handler,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
462 -- and so when completing the dynamically nested handler, we
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
463 -- must NOT release the exception. A Claimed_Cleanup upon
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
464 -- entry of the nested handler, installed when entering the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
465 -- enclosing handler, ensures the exception will not be
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
466 -- released by the nested handler, but rather by the enclosing
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
467 -- handler.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
468 --
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
469 -- - Reraise_Occurrence/reraise escapes the running handler,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
470 -- and we run as an exceptional cleanup for GCC_Exception. The
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
471 -- Saved_Cleanup was reinstalled, but since we're propagating
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
472 -- the same machine occurrence, we do not release it. Instead,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
473 -- we transfer responsibility for releasing it to the eventual
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
474 -- handler of the propagating exception.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
475 --
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
476 -- - An unrelated exception propagates through the running
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
477 -- handler. We restored GCC_Exception.Saved_Cleanup above.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
478 -- Since we're propagating a different exception, we proceed to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
479 -- release GCC_Exception, unless Saved_Cleanup was
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
480 -- Claimed_Cleanup, because then we know we're not in the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
481 -- outermost handler for GCC_Exception.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
482 --
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
483 -- - The handler completes normally, so it reinstalls the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
484 -- Saved_Cleanup and runs it, unless it was Claimed_Cleanup.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
485 -- If Saved_Cleanup is null, Unwind_DeleteException (currently)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
486 -- has no effect, so we could skip it, but if it is ever
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
487 -- changed to do more in this case, we're ready for that,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
488 -- calling it exactly once.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
489 if Saved_Cleanup /= Claimed_Cleanup'Address
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
490 and then
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
491 Propagating_Exception /= GCC_Exception
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
492 then
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
493 declare
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
494 Current : constant EOA := Get_Current_Excep.all;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
495 Cur_Occ : constant GCC_Exception_Access
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
496 := To_GCC_Exception (Current.Machine_Occurrence);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
497 begin
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
498 -- If we are releasing the Machine_Occurrence of the current
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
499 -- exception, reset the access to it, so that it is no
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
500 -- longer accessible.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
501 if Cur_Occ = GCC_Exception then
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
502 Current.Machine_Occurrence := System.Null_Address;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
503 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
504 end;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
505 Unwind_DeleteException (GCC_Exception);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
506 end if;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
507 end End_Handler_v1;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
508
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
509 ---------------------
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
510 -- Claimed_Cleanup --
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
511 ---------------------
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
512
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
513 procedure Claimed_Cleanup
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
514 (Reason : Unwind_Reason_Code;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
515 GCC_Exception : not null GCC_Exception_Access) is
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
516 pragma Unreferenced (Reason);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
517 pragma Unreferenced (GCC_Exception);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
518 begin
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
519 -- This procedure should never run. If it does, it's either a
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
520 -- version 0 handler or a foreign handler, attempting to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
521 -- release an exception while a version 1 handler that claimed
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
522 -- responsibility for releasing the exception remains still
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
523 -- active. This placeholder stops GCC_Exception from being
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
524 -- released by them.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
525
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
526 -- We could get away with just Null_Address instead, with
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
527 -- nearly the same effect, but with this placeholder we can
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
528 -- detect and report unexpected releases, and we can tell apart
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
529 -- a GCC_Exception without a Cleanup, from one with another
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
530 -- active handler, so as to still call Unwind_DeleteException
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
531 -- exactly once: currently, Unwind_DeleteException does nothing
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
532 -- when the Cleanup is null, but should it ever be changed to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
533 -- do more, we'll still be safe.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
534 null;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
535 end Claimed_Cleanup;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
536
111
kono
parents:
diff changeset
537 -------------------
kono
parents:
diff changeset
538 -- Begin_Handler --
kono
parents:
diff changeset
539 -------------------
kono
parents:
diff changeset
540
kono
parents:
diff changeset
541 procedure Begin_Handler (GCC_Exception : not null GCC_Exception_Access) is
kono
parents:
diff changeset
542 pragma Unreferenced (GCC_Exception);
kono
parents:
diff changeset
543 begin
kono
parents:
diff changeset
544 null;
kono
parents:
diff changeset
545 end Begin_Handler;
kono
parents:
diff changeset
546
kono
parents:
diff changeset
547 -----------------
kono
parents:
diff changeset
548 -- End_Handler --
kono
parents:
diff changeset
549 -----------------
kono
parents:
diff changeset
550
kono
parents:
diff changeset
551 procedure End_Handler (GCC_Exception : GCC_Exception_Access) is
kono
parents:
diff changeset
552 begin
kono
parents:
diff changeset
553 if GCC_Exception /= null then
kono
parents:
diff changeset
554
kono
parents:
diff changeset
555 -- The exception might have been reraised, in this case the cleanup
kono
parents:
diff changeset
556 -- mustn't be called.
kono
parents:
diff changeset
557
kono
parents:
diff changeset
558 Unwind_DeleteException (GCC_Exception);
kono
parents:
diff changeset
559 end if;
kono
parents:
diff changeset
560 end End_Handler;
kono
parents:
diff changeset
561
kono
parents:
diff changeset
562 -----------------------------
kono
parents:
diff changeset
563 -- Reraise_GCC_Exception --
kono
parents:
diff changeset
564 -----------------------------
kono
parents:
diff changeset
565
kono
parents:
diff changeset
566 procedure Reraise_GCC_Exception
kono
parents:
diff changeset
567 (GCC_Exception : not null GCC_Exception_Access)
kono
parents:
diff changeset
568 is
kono
parents:
diff changeset
569 begin
kono
parents:
diff changeset
570 -- Simply propagate it
kono
parents:
diff changeset
571
kono
parents:
diff changeset
572 Propagate_GCC_Exception (GCC_Exception);
kono
parents:
diff changeset
573 end Reraise_GCC_Exception;
kono
parents:
diff changeset
574
kono
parents:
diff changeset
575 -----------------------------
kono
parents:
diff changeset
576 -- Propagate_GCC_Exception --
kono
parents:
diff changeset
577 -----------------------------
kono
parents:
diff changeset
578
kono
parents:
diff changeset
579 -- Call Unwind_RaiseException to actually throw, taking care of handling
kono
parents:
diff changeset
580 -- the two phase scheme it implements.
kono
parents:
diff changeset
581
kono
parents:
diff changeset
582 procedure Propagate_GCC_Exception
kono
parents:
diff changeset
583 (GCC_Exception : not null GCC_Exception_Access)
kono
parents:
diff changeset
584 is
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
585 -- Acknowledge the current exception info now, before unwinding
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
586 -- starts so it is available even from C++ handlers involved before
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
587 -- our personality routine.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
588
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
589 Excep : constant EOA :=
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
590 Setup_Current_Excep (GCC_Exception, Phase => 0);
111
kono
parents:
diff changeset
591
kono
parents:
diff changeset
592 begin
kono
parents:
diff changeset
593 -- Perform a standard raise first. If a regular handler is found, it
kono
parents:
diff changeset
594 -- will be entered after all the intermediate cleanups have run. If
kono
parents:
diff changeset
595 -- there is no regular handler, it will return.
kono
parents:
diff changeset
596
kono
parents:
diff changeset
597 Unwind_RaiseException (GCC_Exception);
kono
parents:
diff changeset
598
kono
parents:
diff changeset
599 -- If we get here we know the exception is not handled, as otherwise
kono
parents:
diff changeset
600 -- Unwind_RaiseException arranges for the handler to be entered. Take
kono
parents:
diff changeset
601 -- the necessary steps to enable the debugger to gain control while the
kono
parents:
diff changeset
602 -- stack is still intact.
kono
parents:
diff changeset
603
kono
parents:
diff changeset
604 Notify_Unhandled_Exception (Excep);
kono
parents:
diff changeset
605
kono
parents:
diff changeset
606 -- Now, un a forced unwind to trigger cleanups. Control should not
kono
parents:
diff changeset
607 -- resume there, if there are cleanups and in any cases as the
kono
parents:
diff changeset
608 -- unwinding hook calls Unhandled_Exception_Terminate when end of
kono
parents:
diff changeset
609 -- stack is reached.
kono
parents:
diff changeset
610
kono
parents:
diff changeset
611 Unwind_ForcedUnwind
kono
parents:
diff changeset
612 (GCC_Exception,
kono
parents:
diff changeset
613 CleanupUnwind_Handler'Address,
kono
parents:
diff changeset
614 System.Null_Address);
kono
parents:
diff changeset
615
kono
parents:
diff changeset
616 -- We get here in case of error. The debugger has been notified before
kono
parents:
diff changeset
617 -- the second step above.
kono
parents:
diff changeset
618
kono
parents:
diff changeset
619 Unhandled_Except_Handler (GCC_Exception);
kono
parents:
diff changeset
620 end Propagate_GCC_Exception;
kono
parents:
diff changeset
621
kono
parents:
diff changeset
622 -------------------------
kono
parents:
diff changeset
623 -- Propagate_Exception --
kono
parents:
diff changeset
624 -------------------------
kono
parents:
diff changeset
625
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
626 procedure Propagate_Exception (Excep : Exception_Occurrence) is
111
kono
parents:
diff changeset
627 begin
kono
parents:
diff changeset
628 Propagate_GCC_Exception (To_GCC_Exception (Excep.Machine_Occurrence));
kono
parents:
diff changeset
629 end Propagate_Exception;
kono
parents:
diff changeset
630
kono
parents:
diff changeset
631 -----------------------------
kono
parents:
diff changeset
632 -- Set_Exception_Parameter --
kono
parents:
diff changeset
633 -----------------------------
kono
parents:
diff changeset
634
kono
parents:
diff changeset
635 procedure Set_Exception_Parameter
kono
parents:
diff changeset
636 (Excep : EOA;
kono
parents:
diff changeset
637 GCC_Exception : not null GCC_Exception_Access)
kono
parents:
diff changeset
638 is
kono
parents:
diff changeset
639 begin
kono
parents:
diff changeset
640 -- Setup the exception occurrence
kono
parents:
diff changeset
641
kono
parents:
diff changeset
642 if GCC_Exception.Class = GNAT_Exception_Class then
kono
parents:
diff changeset
643
kono
parents:
diff changeset
644 -- From the GCC exception
kono
parents:
diff changeset
645
kono
parents:
diff changeset
646 declare
kono
parents:
diff changeset
647 GNAT_Occurrence : constant GNAT_GCC_Exception_Access :=
kono
parents:
diff changeset
648 To_GNAT_GCC_Exception (GCC_Exception);
kono
parents:
diff changeset
649 begin
kono
parents:
diff changeset
650 Save_Occurrence (Excep.all, GNAT_Occurrence.Occurrence);
kono
parents:
diff changeset
651 end;
kono
parents:
diff changeset
652
kono
parents:
diff changeset
653 else
kono
parents:
diff changeset
654 -- A default one
kono
parents:
diff changeset
655
kono
parents:
diff changeset
656 Set_Foreign_Occurrence (Excep, GCC_Exception.all'Address);
kono
parents:
diff changeset
657 end if;
kono
parents:
diff changeset
658 end Set_Exception_Parameter;
kono
parents:
diff changeset
659
kono
parents:
diff changeset
660 ------------------------------
kono
parents:
diff changeset
661 -- Unhandled_Except_Handler --
kono
parents:
diff changeset
662 ------------------------------
kono
parents:
diff changeset
663
kono
parents:
diff changeset
664 procedure Unhandled_Except_Handler
kono
parents:
diff changeset
665 (GCC_Exception : not null GCC_Exception_Access)
kono
parents:
diff changeset
666 is
kono
parents:
diff changeset
667 Excep : EOA;
kono
parents:
diff changeset
668 begin
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
669 Excep := Setup_Current_Excep (GCC_Exception, Phase => UA_CLEANUP_PHASE);
111
kono
parents:
diff changeset
670 Unhandled_Exception_Terminate (Excep);
kono
parents:
diff changeset
671 end Unhandled_Except_Handler;
kono
parents:
diff changeset
672
kono
parents:
diff changeset
673 -------------
kono
parents:
diff changeset
674 -- EID_For --
kono
parents:
diff changeset
675 -------------
kono
parents:
diff changeset
676
kono
parents:
diff changeset
677 function EID_For
kono
parents:
diff changeset
678 (GNAT_Exception : not null GNAT_GCC_Exception_Access) return Exception_Id
kono
parents:
diff changeset
679 is
kono
parents:
diff changeset
680 begin
kono
parents:
diff changeset
681 return GNAT_Exception.Occurrence.Id;
kono
parents:
diff changeset
682 end EID_For;
kono
parents:
diff changeset
683
kono
parents:
diff changeset
684 ----------------------
kono
parents:
diff changeset
685 -- Foreign_Data_For --
kono
parents:
diff changeset
686 ----------------------
kono
parents:
diff changeset
687
kono
parents:
diff changeset
688 function Foreign_Data_For
kono
parents:
diff changeset
689 (E : SSL.Exception_Data_Ptr) return Address
kono
parents:
diff changeset
690 is
kono
parents:
diff changeset
691 begin
kono
parents:
diff changeset
692 return E.Foreign_Data;
kono
parents:
diff changeset
693 end Foreign_Data_For;
kono
parents:
diff changeset
694
kono
parents:
diff changeset
695 --------------------------
kono
parents:
diff changeset
696 -- Is_Handled_By_Others --
kono
parents:
diff changeset
697 --------------------------
kono
parents:
diff changeset
698
kono
parents:
diff changeset
699 function Is_Handled_By_Others (E : SSL.Exception_Data_Ptr) return Boolean is
kono
parents:
diff changeset
700 begin
kono
parents:
diff changeset
701 return not E.all.Not_Handled_By_Others;
kono
parents:
diff changeset
702 end Is_Handled_By_Others;
kono
parents:
diff changeset
703
kono
parents:
diff changeset
704 ------------------
kono
parents:
diff changeset
705 -- Language_For --
kono
parents:
diff changeset
706 ------------------
kono
parents:
diff changeset
707
kono
parents:
diff changeset
708 function Language_For (E : SSL.Exception_Data_Ptr) return Character is
kono
parents:
diff changeset
709 begin
kono
parents:
diff changeset
710 return E.all.Lang;
kono
parents:
diff changeset
711 end Language_For;
kono
parents:
diff changeset
712
kono
parents:
diff changeset
713 end Exception_Propagation;