annotate gcc/ada/libgnat/s-exctab.adb @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
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 -- S Y S T E M . E X C E P T I O N _ T A B L E --
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) 1996-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
kono
parents:
diff changeset
32 pragma Compiler_Unit_Warning;
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 with System.Soft_Links; use System.Soft_Links;
kono
parents:
diff changeset
35
kono
parents:
diff changeset
36 package body System.Exception_Table is
kono
parents:
diff changeset
37
kono
parents:
diff changeset
38 use System.Standard_Library;
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 type Hash_Val is mod 2 ** 8;
kono
parents:
diff changeset
41 subtype Hash_Idx is Hash_Val range 1 .. 37;
kono
parents:
diff changeset
42
kono
parents:
diff changeset
43 HTable : array (Hash_Idx) of aliased Exception_Data_Ptr;
kono
parents:
diff changeset
44 -- Actual hash table containing all registered exceptions
kono
parents:
diff changeset
45 --
kono
parents:
diff changeset
46 -- The table is very small and the hash function weak, as looking up
kono
parents:
diff changeset
47 -- registered exceptions is rare and minimizing space and time overhead
kono
parents:
diff changeset
48 -- of registration is more important. In addition, it is expected that the
kono
parents:
diff changeset
49 -- exceptions that need to be looked up are registered dynamically, and
kono
parents:
diff changeset
50 -- therefore will be at the begin of the hash chains.
kono
parents:
diff changeset
51 --
kono
parents:
diff changeset
52 -- The table differs from System.HTable.Static_HTable in that the final
kono
parents:
diff changeset
53 -- element of each chain is not marked by null, but by a pointer to self.
kono
parents:
diff changeset
54 -- This way it is possible to defend against the same entry being inserted
kono
parents:
diff changeset
55 -- twice, without having to do a lookup which is relatively expensive for
kono
parents:
diff changeset
56 -- programs with large number
kono
parents:
diff changeset
57 --
kono
parents:
diff changeset
58 -- All non-local subprograms use the global Task_Lock to protect against
kono
parents:
diff changeset
59 -- concurrent use of the exception table. This is needed as local
kono
parents:
diff changeset
60 -- exceptions may be declared concurrently with those declared at the
kono
parents:
diff changeset
61 -- library level.
kono
parents:
diff changeset
62
kono
parents:
diff changeset
63 -- Local Subprograms
kono
parents:
diff changeset
64
kono
parents:
diff changeset
65 generic
kono
parents:
diff changeset
66 with procedure Process (T : Exception_Data_Ptr; More : out Boolean);
kono
parents:
diff changeset
67 procedure Iterate;
kono
parents:
diff changeset
68 -- Iterate over all
kono
parents:
diff changeset
69
kono
parents:
diff changeset
70 function Lookup (Name : String) return Exception_Data_Ptr;
kono
parents:
diff changeset
71 -- Find and return the Exception_Data of the exception with the given Name
kono
parents:
diff changeset
72 -- (which must be in all uppercase), or null if none was registered.
kono
parents:
diff changeset
73
kono
parents:
diff changeset
74 procedure Register (Item : Exception_Data_Ptr);
kono
parents:
diff changeset
75 -- Register an exception with the given Exception_Data in the table.
kono
parents:
diff changeset
76
kono
parents:
diff changeset
77 function Has_Name (Item : Exception_Data_Ptr; Name : String) return Boolean;
kono
parents:
diff changeset
78 -- Return True iff Item.Full_Name and Name are equal. Both names are
kono
parents:
diff changeset
79 -- assumed to be in all uppercase and end with ASCII.NUL.
kono
parents:
diff changeset
80
kono
parents:
diff changeset
81 function Hash (S : String) return Hash_Idx;
kono
parents:
diff changeset
82 -- Return the index in the hash table for S, which is assumed to be all
kono
parents:
diff changeset
83 -- uppercase and end with ASCII.NUL.
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 --------------
kono
parents:
diff changeset
86 -- Has_Name --
kono
parents:
diff changeset
87 --------------
kono
parents:
diff changeset
88
kono
parents:
diff changeset
89 function Has_Name (Item : Exception_Data_Ptr; Name : String) return Boolean
kono
parents:
diff changeset
90 is
kono
parents:
diff changeset
91 S : constant Big_String_Ptr := To_Ptr (Item.Full_Name);
kono
parents:
diff changeset
92 J : Integer := S'First;
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 begin
kono
parents:
diff changeset
95 for K in Name'Range loop
kono
parents:
diff changeset
96
kono
parents:
diff changeset
97 -- Note that as both items are terminated with ASCII.NUL, the
kono
parents:
diff changeset
98 -- comparison below must fail for strings of different lengths.
kono
parents:
diff changeset
99
kono
parents:
diff changeset
100 if S (J) /= Name (K) then
kono
parents:
diff changeset
101 return False;
kono
parents:
diff changeset
102 end if;
kono
parents:
diff changeset
103
kono
parents:
diff changeset
104 J := J + 1;
kono
parents:
diff changeset
105 end loop;
kono
parents:
diff changeset
106
kono
parents:
diff changeset
107 return True;
kono
parents:
diff changeset
108 end Has_Name;
kono
parents:
diff changeset
109
kono
parents:
diff changeset
110 ------------
kono
parents:
diff changeset
111 -- Lookup --
kono
parents:
diff changeset
112 ------------
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 function Lookup (Name : String) return Exception_Data_Ptr is
kono
parents:
diff changeset
115 Prev : Exception_Data_Ptr;
kono
parents:
diff changeset
116 Curr : Exception_Data_Ptr;
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 begin
kono
parents:
diff changeset
119 Curr := HTable (Hash (Name));
kono
parents:
diff changeset
120 Prev := null;
kono
parents:
diff changeset
121 while Curr /= Prev loop
kono
parents:
diff changeset
122 if Has_Name (Curr, Name) then
kono
parents:
diff changeset
123 return Curr;
kono
parents:
diff changeset
124 end if;
kono
parents:
diff changeset
125
kono
parents:
diff changeset
126 Prev := Curr;
kono
parents:
diff changeset
127 Curr := Curr.HTable_Ptr;
kono
parents:
diff changeset
128 end loop;
kono
parents:
diff changeset
129
kono
parents:
diff changeset
130 return null;
kono
parents:
diff changeset
131 end Lookup;
kono
parents:
diff changeset
132
kono
parents:
diff changeset
133 ----------
kono
parents:
diff changeset
134 -- Hash --
kono
parents:
diff changeset
135 ----------
kono
parents:
diff changeset
136
kono
parents:
diff changeset
137 function Hash (S : String) return Hash_Idx is
kono
parents:
diff changeset
138 Hash : Hash_Val := 0;
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 begin
kono
parents:
diff changeset
141 for J in S'Range loop
kono
parents:
diff changeset
142 exit when S (J) = ASCII.NUL;
kono
parents:
diff changeset
143 Hash := Hash xor Character'Pos (S (J));
kono
parents:
diff changeset
144 end loop;
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 return Hash_Idx'First + Hash mod (Hash_Idx'Last - Hash_Idx'First + 1);
kono
parents:
diff changeset
147 end Hash;
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 -------------
kono
parents:
diff changeset
150 -- Iterate --
kono
parents:
diff changeset
151 -------------
kono
parents:
diff changeset
152
kono
parents:
diff changeset
153 procedure Iterate is
kono
parents:
diff changeset
154 More : Boolean;
kono
parents:
diff changeset
155 Prev, Curr : Exception_Data_Ptr;
kono
parents:
diff changeset
156
kono
parents:
diff changeset
157 begin
kono
parents:
diff changeset
158 Outer : for Idx in HTable'Range loop
kono
parents:
diff changeset
159 Prev := null;
kono
parents:
diff changeset
160 Curr := HTable (Idx);
kono
parents:
diff changeset
161
kono
parents:
diff changeset
162 while Curr /= Prev loop
kono
parents:
diff changeset
163 Process (Curr, More);
kono
parents:
diff changeset
164
kono
parents:
diff changeset
165 exit Outer when not More;
kono
parents:
diff changeset
166
kono
parents:
diff changeset
167 Prev := Curr;
kono
parents:
diff changeset
168 Curr := Curr.HTable_Ptr;
kono
parents:
diff changeset
169 end loop;
kono
parents:
diff changeset
170 end loop Outer;
kono
parents:
diff changeset
171 end Iterate;
kono
parents:
diff changeset
172
kono
parents:
diff changeset
173 --------------
kono
parents:
diff changeset
174 -- Register --
kono
parents:
diff changeset
175 --------------
kono
parents:
diff changeset
176
kono
parents:
diff changeset
177 procedure Register (Item : Exception_Data_Ptr) is
kono
parents:
diff changeset
178 begin
kono
parents:
diff changeset
179 if Item.HTable_Ptr = null then
kono
parents:
diff changeset
180 Prepend_To_Chain : declare
kono
parents:
diff changeset
181 Chain : Exception_Data_Ptr
kono
parents:
diff changeset
182 renames HTable (Hash (To_Ptr (Item.Full_Name).all));
kono
parents:
diff changeset
183
kono
parents:
diff changeset
184 begin
kono
parents:
diff changeset
185 if Chain = null then
kono
parents:
diff changeset
186 Item.HTable_Ptr := Item;
kono
parents:
diff changeset
187 else
kono
parents:
diff changeset
188 Item.HTable_Ptr := Chain;
kono
parents:
diff changeset
189 end if;
kono
parents:
diff changeset
190
kono
parents:
diff changeset
191 Chain := Item;
kono
parents:
diff changeset
192 end Prepend_To_Chain;
kono
parents:
diff changeset
193 end if;
kono
parents:
diff changeset
194 end Register;
kono
parents:
diff changeset
195
kono
parents:
diff changeset
196 -------------------------------
kono
parents:
diff changeset
197 -- Get_Registered_Exceptions --
kono
parents:
diff changeset
198 -------------------------------
kono
parents:
diff changeset
199
kono
parents:
diff changeset
200 procedure Get_Registered_Exceptions
kono
parents:
diff changeset
201 (List : out Exception_Data_Array;
kono
parents:
diff changeset
202 Last : out Integer)
kono
parents:
diff changeset
203 is
kono
parents:
diff changeset
204 procedure Get_One (Item : Exception_Data_Ptr; More : out Boolean);
kono
parents:
diff changeset
205 -- Add Item to List (List'First .. Last) by first incrementing Last
kono
parents:
diff changeset
206 -- and storing Item in List (Last). Last should be in List'First - 1
kono
parents:
diff changeset
207 -- and List'Last.
kono
parents:
diff changeset
208
kono
parents:
diff changeset
209 procedure Get_All is new Iterate (Get_One);
kono
parents:
diff changeset
210 -- Store all registered exceptions in List, updating Last
kono
parents:
diff changeset
211
kono
parents:
diff changeset
212 -------------
kono
parents:
diff changeset
213 -- Get_One --
kono
parents:
diff changeset
214 -------------
kono
parents:
diff changeset
215
kono
parents:
diff changeset
216 procedure Get_One (Item : Exception_Data_Ptr; More : out Boolean) is
kono
parents:
diff changeset
217 begin
kono
parents:
diff changeset
218 if Last < List'Last then
kono
parents:
diff changeset
219 Last := Last + 1;
kono
parents:
diff changeset
220 List (Last) := Item;
kono
parents:
diff changeset
221 More := True;
kono
parents:
diff changeset
222
kono
parents:
diff changeset
223 else
kono
parents:
diff changeset
224 More := False;
kono
parents:
diff changeset
225 end if;
kono
parents:
diff changeset
226 end Get_One;
kono
parents:
diff changeset
227
kono
parents:
diff changeset
228 begin
kono
parents:
diff changeset
229 -- In this routine the invariant is that List (List'First .. Last)
kono
parents:
diff changeset
230 -- contains the registered exceptions retrieved so far.
kono
parents:
diff changeset
231
kono
parents:
diff changeset
232 Last := List'First - 1;
kono
parents:
diff changeset
233
kono
parents:
diff changeset
234 Lock_Task.all;
kono
parents:
diff changeset
235 Get_All;
kono
parents:
diff changeset
236 Unlock_Task.all;
kono
parents:
diff changeset
237 end Get_Registered_Exceptions;
kono
parents:
diff changeset
238
kono
parents:
diff changeset
239 ------------------------
kono
parents:
diff changeset
240 -- Internal_Exception --
kono
parents:
diff changeset
241 ------------------------
kono
parents:
diff changeset
242
kono
parents:
diff changeset
243 function Internal_Exception
kono
parents:
diff changeset
244 (X : String;
kono
parents:
diff changeset
245 Create_If_Not_Exist : Boolean := True) return Exception_Data_Ptr
kono
parents:
diff changeset
246 is
kono
parents:
diff changeset
247 -- If X was not yet registered and Create_if_Not_Exist is True,
kono
parents:
diff changeset
248 -- dynamically allocate and register a new exception.
kono
parents:
diff changeset
249
kono
parents:
diff changeset
250 type String_Ptr is access all String;
kono
parents:
diff changeset
251
kono
parents:
diff changeset
252 Dyn_Copy : String_Ptr;
kono
parents:
diff changeset
253 Copy : aliased String (X'First .. X'Last + 1);
kono
parents:
diff changeset
254 Result : Exception_Data_Ptr;
kono
parents:
diff changeset
255
kono
parents:
diff changeset
256 begin
kono
parents:
diff changeset
257 Lock_Task.all;
kono
parents:
diff changeset
258
kono
parents:
diff changeset
259 Copy (X'Range) := X;
kono
parents:
diff changeset
260 Copy (Copy'Last) := ASCII.NUL;
kono
parents:
diff changeset
261 Result := Lookup (Copy);
kono
parents:
diff changeset
262
kono
parents:
diff changeset
263 -- If unknown exception, create it on the heap. This is a legitimate
kono
parents:
diff changeset
264 -- situation in the distributed case when an exception is defined
kono
parents:
diff changeset
265 -- only in a partition
kono
parents:
diff changeset
266
kono
parents:
diff changeset
267 if Result = null and then Create_If_Not_Exist then
kono
parents:
diff changeset
268 Dyn_Copy := new String'(Copy);
kono
parents:
diff changeset
269
kono
parents:
diff changeset
270 Result :=
kono
parents:
diff changeset
271 new Exception_Data'
kono
parents:
diff changeset
272 (Not_Handled_By_Others => False,
kono
parents:
diff changeset
273 Lang => 'A',
kono
parents:
diff changeset
274 Name_Length => Copy'Length,
kono
parents:
diff changeset
275 Full_Name => Dyn_Copy.all'Address,
kono
parents:
diff changeset
276 HTable_Ptr => null,
kono
parents:
diff changeset
277 Foreign_Data => Null_Address,
kono
parents:
diff changeset
278 Raise_Hook => null);
kono
parents:
diff changeset
279
kono
parents:
diff changeset
280 Register (Result);
kono
parents:
diff changeset
281 end if;
kono
parents:
diff changeset
282
kono
parents:
diff changeset
283 Unlock_Task.all;
kono
parents:
diff changeset
284
kono
parents:
diff changeset
285 return Result;
kono
parents:
diff changeset
286 end Internal_Exception;
kono
parents:
diff changeset
287
kono
parents:
diff changeset
288 ------------------------
kono
parents:
diff changeset
289 -- Register_Exception --
kono
parents:
diff changeset
290 ------------------------
kono
parents:
diff changeset
291
kono
parents:
diff changeset
292 procedure Register_Exception (X : Exception_Data_Ptr) is
kono
parents:
diff changeset
293 begin
kono
parents:
diff changeset
294 Lock_Task.all;
kono
parents:
diff changeset
295 Register (X);
kono
parents:
diff changeset
296 Unlock_Task.all;
kono
parents:
diff changeset
297 end Register_Exception;
kono
parents:
diff changeset
298
kono
parents:
diff changeset
299 ---------------------------------
kono
parents:
diff changeset
300 -- Registered_Exceptions_Count --
kono
parents:
diff changeset
301 ---------------------------------
kono
parents:
diff changeset
302
kono
parents:
diff changeset
303 function Registered_Exceptions_Count return Natural is
kono
parents:
diff changeset
304 Count : Natural := 0;
kono
parents:
diff changeset
305
kono
parents:
diff changeset
306 procedure Count_Item (Item : Exception_Data_Ptr; More : out Boolean);
kono
parents:
diff changeset
307 -- Update Count for given Item
kono
parents:
diff changeset
308
kono
parents:
diff changeset
309 procedure Count_Item (Item : Exception_Data_Ptr; More : out Boolean) is
kono
parents:
diff changeset
310 pragma Unreferenced (Item);
kono
parents:
diff changeset
311 begin
kono
parents:
diff changeset
312 Count := Count + 1;
kono
parents:
diff changeset
313 More := Count < Natural'Last;
kono
parents:
diff changeset
314 end Count_Item;
kono
parents:
diff changeset
315
kono
parents:
diff changeset
316 procedure Count_All is new Iterate (Count_Item);
kono
parents:
diff changeset
317
kono
parents:
diff changeset
318 begin
kono
parents:
diff changeset
319 Lock_Task.all;
kono
parents:
diff changeset
320 Count_All;
kono
parents:
diff changeset
321 Unlock_Task.all;
kono
parents:
diff changeset
322
kono
parents:
diff changeset
323 return Count;
kono
parents:
diff changeset
324 end Registered_Exceptions_Count;
kono
parents:
diff changeset
325
kono
parents:
diff changeset
326 begin
kono
parents:
diff changeset
327 -- Register the standard exceptions at elaboration time
kono
parents:
diff changeset
328
kono
parents:
diff changeset
329 -- We don't need to use the locking version here as the elaboration
kono
parents:
diff changeset
330 -- will not be concurrent and no tasks can call any subprograms of this
kono
parents:
diff changeset
331 -- unit before it has been elaborated.
kono
parents:
diff changeset
332
kono
parents:
diff changeset
333 Register (Abort_Signal_Def'Access);
kono
parents:
diff changeset
334 Register (Tasking_Error_Def'Access);
kono
parents:
diff changeset
335 Register (Storage_Error_Def'Access);
kono
parents:
diff changeset
336 Register (Program_Error_Def'Access);
kono
parents:
diff changeset
337 Register (Numeric_Error_Def'Access);
kono
parents:
diff changeset
338 Register (Constraint_Error_Def'Access);
kono
parents:
diff changeset
339 end System.Exception_Table;