1
- typedef struct objc_object * id;
2
1
#include < atomic>
3
2
#include < stdlib.h>
4
3
#include < stdio.h>
5
4
#include " dwarf_eh.h"
5
+ #include " objcxx_eh_private.h"
6
6
#include " objcxx_eh.h"
7
- #include " visibility.h"
8
- #include " objc/runtime.h"
9
7
#include " objc/objc-arc.h"
10
8
11
- #ifndef DEBUG_EXCEPTIONS
12
- #define DEBUG_LOG (...)
13
- #else
14
- #define DEBUG_LOG (str, ...) fprintf(stderr, str, ## __VA_ARGS__)
15
- #endif
16
-
17
9
/* *
18
10
* Helper function that has a custom personality function.
19
11
* This calls `cxx_throw` and has a destructor that must be run. We intercept
@@ -23,92 +15,8 @@ int eh_trampoline();
23
15
24
16
uint64_t cxx_exception_class;
25
17
26
- /* *
27
- * Our own definitions of C++ ABI functions and types. These are provided
28
- * because this file must not include cxxabi.h. We need to handle subtly
29
- * different variations of the ABI and including one specific implementation
30
- * would make that very difficult.
31
- */
32
- namespace __cxxabiv1
33
- {
34
- /* *
35
- * Type info for classes. Forward declared because the GNU ABI provides a
36
- * method on all type_info objects that the dynamic the dynamic cast header
37
- * needs.
38
- */
39
- struct __class_type_info ;
40
- /* *
41
- * The C++ in-flight exception object. We will derive the offset of fields
42
- * in this, so we do not ever actually see a concrete definition of it.
43
- */
44
- struct __cxa_exception ;
45
- /* *
46
- * The public ABI structure for current exception state.
47
- */
48
- struct __cxa_eh_globals
49
- {
50
- /* *
51
- * The current exception that has been caught.
52
- */
53
- __cxa_exception *caughtExceptions;
54
- /* *
55
- * The number of uncaught exceptions still in flight.
56
- */
57
- unsigned int uncaughtExceptions;
58
- };
59
- /* *
60
- * Retrieve the above structure.
61
- */
62
- extern " C" __cxa_eh_globals *__cxa_get_globals ();
63
- }
64
-
65
- namespace std
66
- {
67
- struct type_info ;
68
- }
69
-
70
18
using namespace __cxxabiv1 ;
71
19
72
- // Define some C++ ABI types here, rather than including them. This prevents
73
- // conflicts with the libstdc++ headers, which expose only a subset of the
74
- // type_info class (the part required for standards compliance, not the
75
- // implementation details).
76
-
77
- typedef void (*unexpected_handler)();
78
- typedef void (*terminate_handler)();
79
-
80
- namespace std
81
- {
82
- /* *
83
- * std::type_info, containing the minimum requirements for the ABI.
84
- * Public headers on some implementations also expose some implementation
85
- * details. The layout of our subclasses must respect the layout of the
86
- * C++ runtime library, but also needs to be portable across multiple
87
- * implementations and so should not depend on internal symbols from those
88
- * libraries.
89
- */
90
- class type_info
91
- {
92
- public:
93
- virtual ~type_info ();
94
- bool operator ==(const type_info &) const ;
95
- bool operator !=(const type_info &) const ;
96
- bool before (const type_info &) const ;
97
- type_info ();
98
- private:
99
- type_info (const type_info& rhs);
100
- type_info& operator = (const type_info& rhs);
101
- const char *__type_name;
102
- protected:
103
- type_info (const char *name): __type_name(name) { }
104
- public:
105
- const char * name () const { return __type_name; }
106
- };
107
- }
108
-
109
- extern " C" void __cxa_throw (void *, std::type_info*, void (*)(void *));
110
- extern " C" void __cxa_rethrow ();
111
-
112
20
namespace
113
21
{
114
22
/* *
@@ -140,49 +48,6 @@ std::atomic<ptrdiff_t> type_info_offset;
140
48
*/
141
49
std::atomic<size_t > exception_struct_size;
142
50
143
- /* *
144
- * Helper function to find a particular value scanning backwards in a
145
- * structure.
146
- */
147
- template <typename T>
148
- ptrdiff_t find_backwards (void *addr, T val)
149
- {
150
- T *ptr = reinterpret_cast <T*>(addr);
151
- for (ptrdiff_t disp = -1 ; (disp * sizeof (T) > -128 ) ; disp--)
152
- {
153
- if (ptr[disp] == val)
154
- {
155
- return disp * sizeof (T);
156
- }
157
- }
158
- fprintf (stderr, " Unable to find field in C++ exception structure\n " );
159
- abort ();
160
- }
161
-
162
- /* *
163
- * Helper function to find a particular value scanning forwards in a
164
- * structure.
165
- */
166
- template <typename T>
167
- ptrdiff_t find_forwards (void *addr, T val)
168
- {
169
- T *ptr = reinterpret_cast <T*>(addr);
170
- for (ptrdiff_t disp = 0 ; (disp * sizeof (T) < 256 ) ; disp++)
171
- {
172
- if (ptr[disp] == val)
173
- {
174
- return disp * sizeof (T);
175
- }
176
- }
177
- fprintf (stderr, " Unable to find field in C++ exception structure\n " );
178
- abort ();
179
- }
180
-
181
- template <typename T>
182
- T *pointer_add (void *ptr, ptrdiff_t offset)
183
- {
184
- return reinterpret_cast <T*>(reinterpret_cast <char *>(ptr) + offset);
185
- }
186
51
187
52
/* *
188
53
* Exception cleanup function for C++ exceptions that wrap Objective-C
@@ -225,76 +90,33 @@ namespace gnustep
225
90
{
226
91
namespace libobjc
227
92
{
228
- /* *
229
- * Superclass for the type info for Objective-C exceptions.
230
- */
231
- struct OBJC_PUBLIC __objc_type_info : std::type_info
232
- {
233
- /* *
234
- * Constructor that sets the name.
235
- */
236
- __objc_type_info (const char *name) : type_info(name) {}
237
- /* *
238
- * Helper function used by libsupc++ and libcxxrt to determine if
239
- * this is a pointer type. If so, catches automatically
240
- * dereference the pointer to the thrown pointer in
241
- * `__cxa_begin_catch`.
242
- */
243
- virtual bool __is_pointer_p () const { return true ; }
244
- /* *
245
- * Helper function used by libsupc++ and libcxxrt to determine if
246
- * this is a function pointer type. Irrelevant for our purposes.
247
- */
248
- virtual bool __is_function_p () const { return false ; }
249
- /* *
250
- * Catch handler. This is used in the C++ personality function.
251
- * `thrown_type` is the type info of the thrown object, `this` is
252
- * the type info at the catch site. `thrown_object` is a pointer
253
- * to a pointer to the thrown object and may be adjusted by this
254
- * function.
255
- */
256
- virtual bool __do_catch (const type_info *thrown_type,
93
+ __objc_type_info::__objc_type_info (const char *name) : type_info(name) {}
94
+
95
+ bool __objc_type_info::__is_pointer_p () const { return true ; }
96
+
97
+ bool __objc_type_info::__is_function_p () const { return false ; }
98
+
99
+ bool __objc_type_info::__do_catch (const type_info *thrown_type,
257
100
void **thrown_object,
258
101
unsigned ) const
259
- {
260
- assert (0 );
261
- return false ;
262
- };
263
- /* *
264
- * Function used for `dynamic_cast` between two C++ class types in
265
- * libsupc++ and libcxxrt.
266
- *
267
- * This should never be called on Objective-C types.
268
- */
269
- virtual bool __do_upcast (
102
+ {
103
+ assert (0 );
104
+ return false ;
105
+ };
106
+
107
+ bool __objc_type_info::__do_upcast (
270
108
const __class_type_info *target,
271
109
void **thrown_object) const
272
- {
273
- return false ;
274
- };
110
+ {
111
+ return false ;
275
112
};
113
+
114
+
276
115
/* *
277
- * Singleton type info for the `id` type.
116
+ * The `id` type is mangled to `@id`, which is not a valid mangling
117
+ * of anything else.
278
118
*/
279
- struct OBJC_PUBLIC __objc_id_type_info : __objc_type_info
280
- {
281
- /* *
282
- * The `id` type is mangled to `@id`, which is not a valid mangling
283
- * of anything else.
284
- */
285
- __objc_id_type_info () : __objc_type_info(" @id" ) {};
286
- virtual ~__objc_id_type_info ();
287
- virtual bool __do_catch (const type_info *thrownType,
288
- void **obj,
289
- unsigned outer) const ;
290
- };
291
- struct OBJC_PUBLIC __objc_class_type_info : __objc_type_info
292
- {
293
- virtual ~__objc_class_type_info ();
294
- virtual bool __do_catch (const type_info *thrownType,
295
- void **obj,
296
- unsigned outer) const ;
297
- };
119
+ __objc_id_type_info::__objc_id_type_info () : __objc_type_info(" @id" ) {};
298
120
}
299
121
300
122
static inline id dereference_thrown_object_pointer (void ** obj) {
@@ -430,29 +252,7 @@ void* objc_object_for_cxx_exception(void *thrown_exception, int *isValid)
430
252
} // extern "C"
431
253
432
254
433
- /* *
434
- * C++ structure that is thrown through a frame with the `test_eh_personality`
435
- * personality function. This contains a well-known value that we can search
436
- * for after the unwind header.
437
- */
438
- struct
439
- PRIVATE
440
- MagicValueHolder
441
- {
442
- /* *
443
- * The constant that we will search for to identify this object.
444
- */
445
- static constexpr uint32_t magic = 0x01020304 ;
446
- /* *
447
- * The single field in this structure.
448
- */
449
- uint32_t magic_value;
450
- /* *
451
- * Constructor. Initialises the field with the magic constant.
452
- */
453
- MagicValueHolder () { magic_value = magic; }
454
- };
455
-
255
+ MagicValueHolder::MagicValueHolder () { magic_value = magic; }
456
256
457
257
/* *
458
258
* Function that simply throws an instance of `MagicValueHolder`.
@@ -508,21 +308,4 @@ extern "C" void test_cxx_eh_implementation()
508
308
}
509
309
assert (caught);
510
310
}
511
- #else
512
- static void eh_cleanup (void *exception )
513
- {
514
- DEBUG_LOG (" eh_cleanup: Releasing 0x%x\n " , *(id*)exception );
515
- objc_release (*(id*)exception );
516
- }
517
-
518
- extern " C"
519
- OBJC_PUBLIC
520
- void objc_exception_throw (id object)
521
- {
522
- id *exc = (id *)__cxa_allocate_exception (sizeof (id));
523
- *exc = object;
524
- objc_retain (object);
525
- DEBUG_LOG (" objc_exception_throw: Throwing 0x%x\n " , *exc);
526
- __cxa_throw (exc, & __objc_id_type_info, eh_cleanup);
527
- }
528
311
#endif
0 commit comments