Skip to content

Commit c08f725

Browse files
committed
Layout
1 parent c6efc83 commit c08f725

File tree

1 file changed

+52
-45
lines changed

1 file changed

+52
-45
lines changed

objcxx_eh.cc

+52-45
Original file line numberDiff line numberDiff line change
@@ -519,32 +519,16 @@ static void eh_cleanup(void *exception)
519519
objc_release(*(id*)exception);
520520
}
521521

522-
namespace __cxxabiv1
522+
static void eh_cleanup_noop(void *exception)
523523
{
524-
struct __cxa_exception
525-
{
526-
// Manage the exception object itself.
527-
std::type_info *exceptionType;
528-
void (*exceptionDestructor)(void *);
529-
terminate_handler unexpectedHandler;
530-
terminate_handler terminateHandler;
531-
__cxa_exception *nextException;
532-
int handlerCount;
533-
int handlerSwitchValue;
534-
const unsigned char *actionRecord;
535-
const unsigned char *languageSpecificData;
536-
void *catchTemp;
537-
void *adjustedPtr;
538-
_Unwind_Exception unwindHeader;
539-
};
524+
}
540525

526+
namespace __cxxabiv1
527+
{
541528
struct __cxa_refcounted_exception
542-
{
543-
// Manage this header.
544-
int referenceCount;
545-
// __cxa_exception must be last, and no padding can be after it.
546-
__cxa_exception exc;
547-
};
529+
{
530+
int referenceCount;
531+
};
548532
}
549533

550534
extern "C" __cxa_refcounted_exception* __cxa_init_primary_exception(void *obj, std::type_info *tinfo, void (*dest) (void *));
@@ -553,32 +537,55 @@ extern "C"
553537
OBJC_PUBLIC
554538
void objc_exception_throw(id object)
555539
{
556-
id *exc = (id *)__cxa_allocate_exception(sizeof(id));
557-
*exc = object;
558-
objc_retain(object);
559-
DEBUG_LOG("objc_exception_throw: Throwing 0x%x\n", *exc);
540+
// Don't bother with a mutex here. It doesn't matter if two threads set
541+
// these values at the same time.
542+
if (!done_setup)
543+
{
544+
DEBUG_LOG("objc_exception_throw: Doing initial setup\n");
545+
MagicValueHolder *magicExc = (MagicValueHolder *)__cxa_allocate_exception(sizeof(MagicValueHolder));
546+
MagicValueHolder x;
547+
*magicExc = x;
548+
549+
__cxa_refcounted_exception *header =
550+
__cxa_init_primary_exception(magicExc, & __objc_id_type_info, NULL);
551+
552+
type_info_offset = find_forwards(header, & __objc_id_type_info);
553+
exception_struct_size = find_forwards(header, MagicValueHolder::magic);
554+
__cxa_free_exception(magicExc);
555+
556+
DEBUG_LOG("objc_exception_throw: type_info_offset: 0x%x\n", unsigned(type_info_offset));
557+
DEBUG_LOG("objc_exception_throw: exception_struct_size: 0x%x\n", unsigned(exception_struct_size));
558+
559+
done_setup = true;
560+
}
561+
562+
id *exc = (id *)__cxa_allocate_exception(sizeof(id));
563+
*exc = object;
564+
objc_retain(object);
565+
DEBUG_LOG("objc_exception_throw: Throwing 0x%x\n", *exc);
560566

561567
#ifndef __GLIBCXX__
562-
// At the moment, only libstdc++ exposes __cxa_init_primary_exception
568+
// At the moment, only libstdc++ exposes __cxa_init_primary_exception.
563569
__cxa_throw(exc, & __objc_id_type_info, eh_cleanup);
564570
#else
565-
__cxa_eh_globals *globals = __cxa_get_globals ();
566-
globals->uncaughtExceptions += 1;
567-
__cxa_refcounted_exception *header =
568-
__cxa_init_primary_exception(exc, & __objc_id_type_info, eh_cleanup);
569-
header->referenceCount = 1;
570-
571-
_Unwind_Reason_Code err = _Unwind_RaiseException (&header->exc.unwindHeader);
572-
573-
DEBUG_LOG("objc_exception_throw: _Unwind_RaiseException returned 0x%x for exception 0x%x\n", err, *exc);
574-
575-
if (_URC_END_OF_STACK == err && 0 != _objc_unexpected_exception)
576-
{
577-
DEBUG_LOG("Invoking _objc_unexpected_exception\n");
578-
_objc_unexpected_exception(object);
579-
}
580-
DEBUG_LOG("Throw returned %d\n",(int) err);
581-
abort();
571+
__cxa_eh_globals *globals = __cxa_get_globals ();
572+
globals->uncaughtExceptions += 1;
573+
__cxa_refcounted_exception *header =
574+
__cxa_init_primary_exception(exc, & __objc_id_type_info, eh_cleanup);
575+
header->referenceCount = 1;
576+
577+
_Unwind_Exception *unwindHeader = pointer_add<_Unwind_Exception>(header, exception_struct_size - sizeof(_Unwind_Exception));
578+
_Unwind_Reason_Code err = _Unwind_RaiseException (unwindHeader);
579+
580+
DEBUG_LOG("objc_exception_throw: _Unwind_RaiseException returned 0x%x for exception 0x%x\n", err, *exc);
581+
582+
if (_URC_END_OF_STACK == err && 0 != _objc_unexpected_exception)
583+
{
584+
DEBUG_LOG("Invoking _objc_unexpected_exception\n");
585+
_objc_unexpected_exception(object);
586+
}
587+
DEBUG_LOG("Throw returned %d\n",(int) err);
588+
abort();
582589
#endif
583590
}
584591

0 commit comments

Comments
 (0)