diff options
author | nicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-08 21:03:09 +0000 |
---|---|---|
committer | nicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-08 21:03:09 +0000 |
commit | a5974a584702f39174e0744e9647726e92f1a216 (patch) | |
tree | 9b72d3e49901d1f748b383212af5d710212ac59c /libobjc/exception.c | |
parent | 0e18892cd3edaa71b4e5ed33857b660a8766fcae (diff) | |
download | ppe42-gcc-a5974a584702f39174e0744e9647726e92f1a216.tar.gz ppe42-gcc-a5974a584702f39174e0744e9647726e92f1a216.zip |
* objc/objc-exception.h: New file.
* exception.c (objc_set_uncaught_exception_handler): Implemented.
(objc_set_exception_matcher): Implemented.
(objc_exception_throw): Use the uncaught exception handler if set.
(PERSONALITY_FUNCTION): Use the exception matcher instead of the
hardcoded isKindOf.
(isKindOf): Renamed to is_kind_of_exception_matcher. Tidied code
up. Removed segmentation fault when value is 'nil'.
* objc/objc-api.h (_objc_unexpected_exception): Mark as
deprecated.
* Makefile.in (exception.lo, exception_gc.lo): Use
-Wno-deprecated-declarations when compiling.
(OBJC_H): Added objc-exception.h
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@164023 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libobjc/exception.c')
-rw-r--r-- | libobjc/exception.c | 111 |
1 files changed, 80 insertions, 31 deletions
diff --git a/libobjc/exception.c b/libobjc/exception.c index 0ac0b66621d..210beaee406 100644 --- a/libobjc/exception.c +++ b/libobjc/exception.c @@ -1,5 +1,5 @@ /* The implementation of exception handling primitives for Objective-C. - Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -25,9 +25,70 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include <stdlib.h> #include "config.h" #include "objc/objc-api.h" +#include "objc/objc-exception.h" #include "unwind.h" #include "unwind-pe.h" +/* This hook allows libraries to sepecify special actions when an + exception is thrown without a handler in place. This is deprecated + in favour of objc_set_uncaught_exception_handler (). + */ +void (*_objc_unexpected_exception) (id exception); /* !T:SAFE */ + + +/* 'is_kind_of_exception_matcher' is our default exception matcher - + it determines if the object 'exception' is of class 'catch_class', + or of a subclass. +*/ +static int +is_kind_of_exception_matcher (Class catch_class, id exception) +{ + /* NULL catch_class is catch-all (eg, @catch (id object)). */ + if (catch_class == Nil) + return 1; + + /* If exception is nil (eg, @throw nil;), then it can only be catched + * by a catch-all (eg, @catch (id object)). + */ + if (exception != nil) + { + Class c; + + for (c = exception->class_pointer; c != Nil; + c = class_get_super_class (c)) + if (c == catch_class) + return 1; + } + return 0; +} + +/* The exception matcher currently in use. */ +static objc_exception_matcher +__objc_exception_matcher = is_kind_of_exception_matcher; + +objc_exception_matcher +objc_set_exception_matcher (objc_exception_matcher new_matcher) +{ + objc_exception_matcher old_matcher = __objc_exception_matcher; + __objc_exception_matcher = new_matcher; + return old_matcher; +} + +/* The uncaught exception handler currently in use. */ +static objc_uncaught_exception_handler +__objc_uncaught_exception_handler = NULL; + +objc_uncaught_exception_handler +objc_set_uncaught_exception_handler (objc_uncaught_exception_handler + new_handler) +{ + objc_uncaught_exception_handler old_handler + = __objc_uncaught_exception_handler; + __objc_uncaught_exception_handler = new_handler; + return old_handler; +} + + #ifdef __ARM_EABI_UNWINDER__ @@ -84,11 +145,6 @@ struct lsda_header_info unsigned char call_site_encoding; }; -/* This hook allows libraries to sepecify special actions when an - exception is thrown without a handler in place. - */ -void (*_objc_unexpected_exception) (id exception); /* !T:SAFE */ - static const unsigned char * parse_lsda_header (struct _Unwind_Context *context, const unsigned char *p, struct lsda_header_info *info) @@ -160,25 +216,6 @@ get_ttype_entry (struct lsda_header_info *info, _Unwind_Word i) #endif -/* Like unto the method of the same name on Object, but takes an id. */ -/* ??? Does this bork the meta-type system? Can/should we look up an - isKindOf method on the id? */ - -static int -isKindOf (id value, Class target) -{ - Class c; - - /* NULL target is catch-all. */ - if (target == 0) - return 1; - - for (c = value->class_pointer; c; c = class_get_super_class (c)) - if (c == target) - return 1; - return 0; -} - /* Using a different personality function name causes link failures when trying to mix code using different exception handling models. */ #ifdef SJLJ_EXCEPTIONS @@ -406,7 +443,7 @@ PERSONALITY_FUNCTION (int version, Class catch_type = get_ttype_entry (&info, ar_filter); - if (isKindOf (xh->value, catch_type)) + if ((*__objc_exception_matcher) (catch_type, xh->value)) { handler_switch_value = ar_filter; saw_handler = 1; @@ -473,14 +510,14 @@ __objc_exception_cleanup (_Unwind_Reason_Code code __attribute__((unused)), } void -objc_exception_throw (id value) +objc_exception_throw (id exception) { struct ObjcException *header = calloc (1, sizeof (*header)); - + memcpy (&header->base.exception_class, &__objc_exception_class, sizeof (__objc_exception_class)); header->base.exception_cleanup = __objc_exception_cleanup; - header->value = value; + header->value = exception; #ifdef SJLJ_EXCEPTIONS _Unwind_SjLj_RaiseException (&header->base); @@ -488,10 +525,22 @@ objc_exception_throw (id value) _Unwind_RaiseException (&header->base); #endif - /* Some sort of unwinding error. */ + /* No exception handler was installed. Call the uncaught exception + handler if any is defined. + */ + if (__objc_uncaught_exception_handler != 0) + { + (*__objc_uncaught_exception_handler) (exception); + } + + /* As a last resort support the old, deprecated way of setting an + uncaught exception handler. + */ if (_objc_unexpected_exception != 0) { - (*_objc_unexpected_exception) (value); + (*_objc_unexpected_exception) (exception); } + abort (); } + |