ObjFW  Check-in [d7883de826]

Overview
Comment:Add support for SEH exceptions

Does not work yet due to a GCC bug. I already found the bug and also
have a fix for it, but it needs to get upstreamed.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: d7883de826e74442391c9602da346908805fcd6065a05076ff68850bc3d79bb3
User & Date: js on 2014-02-12 15:36:26
Other Links: manifest | tags
Context
2014-02-12
15:45
OFFile: Reset isAtEndOfStream on seek check-in: 0b0950c299 user: js tags: trunk
15:36
Add support for SEH exceptions check-in: d7883de826 user: js tags: trunk
15:34
OFApplication: Fix typo check-in: 22d45f94d0 user: js tags: trunk
Changes

Modified configure.ac from [542c5cd378] to [1da639e3ca].

265
266
267
268
269
270
271




272
273
274
275
276
277
278
279
280
281




282
283
284
285
286
287
288
					conftest.$ac_objext >/dev/null], [
				exception_type="DWARF"
			])
			AS_IF([$EGREP __gnu_objc_personality_sj0 \
					conftest.$ac_objext >/dev/null], [
				exception_type="SjLj"
			])





			case $exception_type in
			DWARF)
				AC_DEFINE(HAVE_DWARF_EXCEPTIONS, 1,
					[Whether DWARF exceptions are used])
				;;
			SjLj)
				AC_DEFINE(HAVE_SJLJ_EXCEPTIONS, 1,
					[Whether SjLj exceptions are used])
				;;




			*)
				AC_MSG_RESULT(unknown)
				AC_MSG_ERROR([Exception type not detected!])
				;;
			esac

			AC_MSG_RESULT($exception_type)







>
>
>
>










>
>
>
>







265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
					conftest.$ac_objext >/dev/null], [
				exception_type="DWARF"
			])
			AS_IF([$EGREP __gnu_objc_personality_sj0 \
					conftest.$ac_objext >/dev/null], [
				exception_type="SjLj"
			])
			AS_IF([$EGREP __gnu_objc_personality_seh0 \
					conftest.$ac_objext >/dev/null], [
				exception_type="SEH"
			])

			case $exception_type in
			DWARF)
				AC_DEFINE(HAVE_DWARF_EXCEPTIONS, 1,
					[Whether DWARF exceptions are used])
				;;
			SjLj)
				AC_DEFINE(HAVE_SJLJ_EXCEPTIONS, 1,
					[Whether SjLj exceptions are used])
				;;
			SEH)
				AC_DEFINE(HAVE_SEH_EXCEPTIONS, 1,
					[Whether SEH exceptions are used])
				;;
			*)
				AC_MSG_RESULT(unknown)
				AC_MSG_ERROR([Exception type not detected!])
				;;
			esac

			AC_MSG_RESULT($exception_type)

Modified src/exceptions/OFException.m from [258c074e64] to [5e0042a4d3].

42
43
44
45
46
47
48








49
50
51
52
53
54
55
 */
#ifndef HAVE_DWARF_EXCEPTIONS
# if defined(OBJC_ZEROCOST_EXCEPTIONS) && !defined(__ARMEL__)
#  define HAVE_DWARF_EXCEPTIONS
# endif
#endif









#ifdef HAVE_DWARF_EXCEPTIONS
struct _Unwind_Context;
typedef enum {
	_URC_OK		  = 0,
	_URC_END_OF_STACK = 5
}_Unwind_Reason_Code;








>
>
>
>
>
>
>
>







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
 */
#ifndef HAVE_DWARF_EXCEPTIONS
# if defined(OBJC_ZEROCOST_EXCEPTIONS) && !defined(__ARMEL__)
#  define HAVE_DWARF_EXCEPTIONS
# endif
#endif

/*
 * Define HAVE_DWARF_EXCEPTIONS if HAVE_SEH_EXCEPTIONS is defined, as SEH
 * exceptions are implemented as a wrapper around DWARF exceptions.
 */
#ifdef HAVE_SEH_EXCEPTIONS
# define HAVE_DWARF_EXCEPTIONS
#endif

#ifdef HAVE_DWARF_EXCEPTIONS
struct _Unwind_Context;
typedef enum {
	_URC_OK		  = 0,
	_URC_END_OF_STACK = 5
}_Unwind_Reason_Code;

Modified src/runtime/exception.m from [85159653ef] to [02a3674deb].

14
15
16
17
18
19
20




21
22
23
24
25
26
27
 * file.
 */

#include "config.h"

#include <stdlib.h>
#include <string.h>





#import "runtime.h"

static const uint64_t objc_exception_class = 0x474E55434F424A43; /* GNUCOBJC */

#define _UA_SEARCH_PHASE  0x01
#define _UA_CLEANUP_PHASE 0x02







>
>
>
>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 * file.
 */

#include "config.h"

#include <stdlib.h>
#include <string.h>

#ifdef HAVE_SEH_EXCEPTIONS
# include <windows.h>
#endif

#import "runtime.h"

static const uint64_t objc_exception_class = 0x474E55434F424A43; /* GNUCOBJC */

#define _UA_SEARCH_PHASE  0x01
#define _UA_CLEANUP_PHASE 0x02
88
89
90
91
92
93
94



95
96
97
98
99

100
101
102
103
104
105
106
			uint32_t fnstart;
			uint32_t *ehtp;
			uint32_t additional;
			uint32_t reserved1;
		} pr_cache;
		long long int : 0;
#else



		/*
		 * The Itanium Exception ABI says to have those and never touch
		 * them.
		 */
		uint64_t private1, private2;

#endif
	} exception;
	id object;
#if !defined(__arm__) && !defined(__ARM__)
	uintptr_t landingpad;
	intptr_t filter;
#endif







>
>
>





>







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
			uint32_t fnstart;
			uint32_t *ehtp;
			uint32_t additional;
			uint32_t reserved1;
		} pr_cache;
		long long int : 0;
#else
# ifdef HAVE_SEH_EXCEPTIONS
		uint64_t private[6];
# else
		/*
		 * The Itanium Exception ABI says to have those and never touch
		 * them.
		 */
		uint64_t private1, private2;
# endif
#endif
	} exception;
	id object;
#if !defined(__arm__) && !defined(__ARM__)
	uintptr_t landingpad;
	intptr_t filter;
#endif
170
171
172
173
174
175
176






177
178
179
180
181
182
183



184
185
186
187
188
189
190
#else
# define CONTINUE_UNWIND return _URC_CONTINUE_UNWIND

extern uintptr_t _Unwind_GetIP(struct _Unwind_Context*);
extern void _Unwind_SetIP(struct _Unwind_Context*, uintptr_t);
extern void _Unwind_SetGR(struct _Unwind_Context*, int, uintptr_t);
#endif







#if defined(HAVE_DWARF_EXCEPTIONS)
# define PERSONALITY __gnu_objc_personality_v0
# define RAISE_EXCEPTION _Unwind_RaiseException
#elif defined(HAVE_SJLJ_EXCEPTIONS)
# define PERSONALITY __gnu_objc_personality_sj0
# define RAISE_EXCEPTION _Unwind_SjLj_RaiseException



#else
# error Unknown exception type!
#endif

static objc_uncaught_exception_handler uncaught_exception_handler;

static uint64_t







>
>
>
>
>
>







>
>
>







178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#else
# define CONTINUE_UNWIND return _URC_CONTINUE_UNWIND

extern uintptr_t _Unwind_GetIP(struct _Unwind_Context*);
extern void _Unwind_SetIP(struct _Unwind_Context*, uintptr_t);
extern void _Unwind_SetGR(struct _Unwind_Context*, int, uintptr_t);
#endif

#ifdef HAVE_SEH_EXCEPTIONS
extern EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void*,
    PCONTEXT, PDISPATCHER_CONTEXT, _Unwind_Reason_Code(*)(int, int, uint64_t,
    struct _Unwind_Exception*, struct _Unwind_Context*));
#endif

#if defined(HAVE_DWARF_EXCEPTIONS)
# define PERSONALITY __gnu_objc_personality_v0
# define RAISE_EXCEPTION _Unwind_RaiseException
#elif defined(HAVE_SJLJ_EXCEPTIONS)
# define PERSONALITY __gnu_objc_personality_sj0
# define RAISE_EXCEPTION _Unwind_SjLj_RaiseException
#elif defined(HAVE_SEH_EXCEPTIONS)
# define PERSONALITY gnu_objc_personality
# define RAISE_EXCEPTION _Unwind_RaiseException
#else
# error Unknown exception type!
#endif

static objc_uncaught_exception_handler uncaught_exception_handler;

static uint64_t
512
513
514
515
516
517
518



519
520
521
522
523
524
525
		CONTINUE_UNWIND;
	default:
		return _URC_FAILURE;
	}

	_Unwind_SetGR(ctx, 12, (uintptr_t)ex);
#else



_Unwind_Reason_Code
PERSONALITY(int version, int actions, uint64_t ex_class,
    struct _Unwind_Exception *ex, struct _Unwind_Context *ctx)
{
#endif
	struct objc_exception *e = (struct objc_exception*)ex;
	bool foreign = (ex_class != objc_exception_class);







>
>
>







529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
		CONTINUE_UNWIND;
	default:
		return _URC_FAILURE;
	}

	_Unwind_SetGR(ctx, 12, (uintptr_t)ex);
#else
# ifdef HAVE_SEH_EXCEPTIONS
static
# endif
_Unwind_Reason_Code
PERSONALITY(int version, int actions, uint64_t ex_class,
    struct _Unwind_Exception *ex, struct _Unwind_Context *ctx)
{
#endif
	struct objc_exception *e = (struct objc_exception*)ex;
	bool foreign = (ex_class != objc_exception_class);
636
637
638
639
640
641
642










objc_setUncaughtExceptionHandler(objc_uncaught_exception_handler handler)
{
	objc_uncaught_exception_handler old = uncaught_exception_handler;
	uncaught_exception_handler = handler;

	return old;
}

















>
>
>
>
>
>
>
>
>
>
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
objc_setUncaughtExceptionHandler(objc_uncaught_exception_handler handler)
{
	objc_uncaught_exception_handler old = uncaught_exception_handler;
	uncaught_exception_handler = handler;

	return old;
}

#ifdef HAVE_SEH_EXCEPTIONS
EXCEPTION_DISPOSITION
__gnu_objc_personality_seh0(PEXCEPTION_RECORD ms_exc, void *this_frame,
    PCONTEXT ms_orig_context, PDISPATCHER_CONTEXT ms_disp)
{
	return _GCC_specific_handler(ms_exc, this_frame, ms_orig_context,
	    ms_disp, PERSONALITY);
}
#endif