Skip to content

Commit 1697a0b

Browse files
committed
Remove explicit defintion of __cxa_exception
1 parent c6efc83 commit 1697a0b

File tree

1 file changed

+29
-22
lines changed

1 file changed

+29
-22
lines changed

objcxx_eh.cc

+29-22
Original file line numberDiff line numberDiff line change
@@ -519,31 +519,15 @@ 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
542529
{
543-
// Manage this header.
544530
int referenceCount;
545-
// __cxa_exception must be last, and no padding can be after it.
546-
__cxa_exception exc;
547531
};
548532
}
549533

@@ -553,13 +537,35 @@ extern "C"
553537
OBJC_PUBLIC
554538
void objc_exception_throw(id object)
555539
{
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+
556562
id *exc = (id *)__cxa_allocate_exception(sizeof(id));
557563
*exc = object;
558564
objc_retain(object);
559565
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
565571
__cxa_eh_globals *globals = __cxa_get_globals ();
@@ -568,7 +574,8 @@ void objc_exception_throw(id object)
568574
__cxa_init_primary_exception(exc, & __objc_id_type_info, eh_cleanup);
569575
header->referenceCount = 1;
570576

571-
_Unwind_Reason_Code err = _Unwind_RaiseException (&header->exc.unwindHeader);
577+
_Unwind_Exception *unwindHeader = pointer_add<_Unwind_Exception>(header, exception_struct_size - sizeof(_Unwind_Exception));
578+
_Unwind_Reason_Code err = _Unwind_RaiseException (unwindHeader);
572579

573580
DEBUG_LOG("objc_exception_throw: _Unwind_RaiseException returned 0x%x for exception 0x%x\n", err, *exc);
574581

0 commit comments

Comments
 (0)