Differences From Artifact [ae672d1e54]:
- File src/runtime/exception.m — part of check-in [643985e07a] at 2017-04-02 12:13:41 on branch trunk — Use OF_PATH_CURRENT_DIRECTORY instead of @"." (user: js, size: 18202) [annotate] [blame] [check-ins using]
To Artifact [80255e6a7d]:
- File src/runtime/exception.m — part of check-in [13c2017326] at 2017-04-14 02:16:35 on branch trunk — runtime: Add support for emergency exceptions (user: js, size: 19536) [annotate] [blame] [check-ins using]
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdlib.h> #include <string.h> #ifdef HAVE_SEH_EXCEPTIONS # include <windows.h> #endif #import "runtime.h" #import "runtime-private.h" #import "macros.h" #if defined(HAVE_DWARF_EXCEPTIONS) # define PERSONALITY __gnu_objc_personality_v0 # define CXX_PERSONALITY_STR "__gxx_personality_v0" #elif defined(HAVE_SJLJ_EXCEPTIONS) # define PERSONALITY __gnu_objc_personality_sj0 # define CXX_PERSONALITY_STR "__gxx_personality_sj0" | > > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef HAVE_SEH_EXCEPTIONS # include <windows.h> #endif #import "runtime.h" #import "runtime-private.h" #import "macros.h" #ifdef OF_HAVE_THREADS # include "threading.h" #endif #if defined(HAVE_DWARF_EXCEPTIONS) # define PERSONALITY __gnu_objc_personality_v0 # define CXX_PERSONALITY_STR "__gxx_personality_v0" #elif defined(HAVE_SJLJ_EXCEPTIONS) # define PERSONALITY __gnu_objc_personality_sj0 # define CXX_PERSONALITY_STR "__gxx_personality_sj0" |
︙ | ︙ | |||
59 60 61 62 63 64 65 66 67 68 69 70 71 72 | struct _Unwind_Context *ctx) # define CALL_PERSONALITY(func) func(state, ex, ctx) #endif #define GNUCOBJC_EXCEPTION_CLASS UINT64_C(0x474E55434F424A43) /* GNUCOBJC */ #define GNUCCXX0_EXCEPTION_CLASS UINT64_C(0x474E5543432B2B00) /* GNUCC++\0 */ #define CLNGCXX0_EXCEPTION_CLASS UINT64_C(0x434C4E47432B2B00) /* CLNGC++\0 */ #define _UA_SEARCH_PHASE 0x01 #define _UA_CLEANUP_PHASE 0x02 #define _UA_HANDLER_FRAME 0x04 #define _UA_FORCE_UNWIND 0x08 #define DW_EH_PE_absptr 0x00 | > > | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | struct _Unwind_Context *ctx) # define CALL_PERSONALITY(func) func(state, ex, ctx) #endif #define GNUCOBJC_EXCEPTION_CLASS UINT64_C(0x474E55434F424A43) /* GNUCOBJC */ #define GNUCCXX0_EXCEPTION_CLASS UINT64_C(0x474E5543432B2B00) /* GNUCC++\0 */ #define CLNGCXX0_EXCEPTION_CLASS UINT64_C(0x434C4E47432B2B00) /* CLNGC++\0 */ #define NUM_EMERGENCY_EXCEPTIONS 4 #define _UA_SEARCH_PHASE 0x01 #define _UA_CLEANUP_PHASE 0x02 #define _UA_HANDLER_FRAME 0x04 #define _UA_FORCE_UNWIND 0x08 #define DW_EH_PE_absptr 0x00 |
︙ | ︙ | |||
221 222 223 224 225 226 227 228 229 230 231 232 233 234 | #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 static objc_uncaught_exception_handler uncaught_exception_handler; static uint64_t read_uleb128(const uint8_t **ptr) { uint64_t value = 0; uint8_t shift = 0; | > > > > > > > > > > | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | #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 static objc_uncaught_exception_handler uncaught_exception_handler; static struct objc_exception emergency_exceptions[NUM_EMERGENCY_EXCEPTIONS]; #ifdef OF_HAVE_THREADS static of_spinlock_t emergency_exceptions_spinlock; OF_CONSTRUCTOR() { if (!of_spinlock_new(&emergency_exceptions_spinlock)) OBJC_ERROR("Cannot create spinlock!") } #endif static uint64_t read_uleb128(const uint8_t **ptr) { uint64_t value = 0; uint8_t shift = 0; |
︙ | ︙ | |||
660 661 662 663 664 665 666 667 668 669 670 | } static void cleanup(_Unwind_Reason_Code reason, struct _Unwind_Exception *ex) { free(ex); } void objc_exception_throw(id object) { | > > > > > > > > > > > > > > > > | > > > > > > | > > > > > > > > > > > > > > > > > | | 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 | } static void cleanup(_Unwind_Reason_Code reason, struct _Unwind_Exception *ex) { free(ex); } static void cleanup_emergency(_Unwind_Reason_Code reason, struct _Unwind_Exception *ex) { #ifdef OF_HAVE_THREADS if (!of_spinlock_lock(&emergency_exceptions_spinlock)) OBJC_ERROR("Cannot lock spinlock!"); #endif ex->class = 0; #ifdef OF_HAVE_THREADS if (!of_spinlock_unlock(&emergency_exceptions_spinlock)) OBJC_ERROR("Cannot unlock spinlock!"); #endif } void objc_exception_throw(id object) { struct objc_exception *e = malloc(sizeof(*e)); bool emergency = false; if (e == NULL) { #ifdef OF_HAVE_THREADS if (!of_spinlock_lock(&emergency_exceptions_spinlock)) OBJC_ERROR("Cannot lock spinlock!"); #endif for (uint_fast8_t i = 0; i < NUM_EMERGENCY_EXCEPTIONS; i++) { if (emergency_exceptions[i].exception.class == 0) { e = &emergency_exceptions[i]; e->exception.class = GNUCOBJC_EXCEPTION_CLASS; emergency = true; break; } } #ifdef OF_HAVE_THREADS if (!of_spinlock_unlock(&emergency_exceptions_spinlock)) OBJC_ERROR("Cannot lock spinlock!"); #endif } if (e == NULL) OBJC_ERROR("Not enough memory to allocate exception!") memset(e, 0, sizeof(*e)); e->exception.class = GNUCOBJC_EXCEPTION_CLASS; e->exception.cleanup = (emergency ? cleanup_emergency : cleanup); e->object = object; if (_Unwind_RaiseException(&e->exception) == _URC_END_OF_STACK && uncaught_exception_handler != NULL) uncaught_exception_handler(object); OBJC_ERROR("_Unwind_RaiseException() returned!") |
︙ | ︙ |