Skip to content

Commit

Permalink
Rework C++ exception interop again.
Browse files Browse the repository at this point in the history
We now, the first time we encounter a foreign exception, throw a C++
exception through a frame that has a custom personality function and
probe the layout of the __cxa_exception structure.
We then use the offsets learned from this along with the public ABI
functions for allocating the structure.

At the same time, add a test that we are correctly setting the count of
uncaught exceptions.

Fixes gnustep#146
  • Loading branch information
davidchisnall committed Apr 27, 2020
1 parent 76e081d commit 65d6b27
Show file tree
Hide file tree
Showing 9 changed files with 290 additions and 142 deletions.
9 changes: 4 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ if (WIN32)
list(APPEND libobjc_CXX_SRCS eh_win32_msvc.cc)
else ()
list(APPEND libobjc_C_SRCS eh_personality.c)
set(libobjcxx_CXX_SRCS objcxx_eh.cc libstdcxx_current_primary_exception.cc)
endif (WIN32)


Expand Down Expand Up @@ -301,11 +300,11 @@ if (ENABLE_OBJCXX)
set(ENABLE_OBJCXX false)
endif()
endif ()
add_custom_command(OUTPUT eh_trampoline.S
COMMAND ${CMAKE_CXX_COMPILER} -fPIC -S "${CMAKE_SOURCE_DIR}/eh_trampoline.cc" -o - -fexceptions -fno-inline | sed "s/__gxx_personality_v0/test_eh_personality/g" > "${CMAKE_BINARY_DIR}/eh_trampoline.S"
add_custom_command(OUTPUT eh_trampoline.s
COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_FLAGS} -fPIC -S "${CMAKE_SOURCE_DIR}/eh_trampoline.cc" -o - -fexceptions -fno-inline | sed "s/__gxx_personality_v0/test_eh_personality/g" > "${CMAKE_BINARY_DIR}/eh_trampoline.s"
MAIN_DEPENDENCY eh_trampoline.cc)
list(APPEND libobjc_ASM_SRCS eh_trampoline.S)
list(APPEND libobjc_CXX_SRCS cxx_eh_setup.cc)
list(APPEND libobjc_ASM_SRCS eh_trampoline.s)
list(APPEND libobjc_CXX_SRCS objcxx_eh.cc)
endif ()
endif (ENABLE_OBJCXX)

Expand Down
2 changes: 2 additions & 0 deletions Test/ObjCXXEHInterop.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#import "stdio.h"

void poke_objcxx(void);
void check_uncaught_count(void);

void rethrow(id x)
{
Expand All @@ -18,5 +19,6 @@ int main(void)
} @catch (Test *localException) {
printf("In NS_HANDLER block, %p\n", localException);
}
check_uncaught_count();
}

21 changes: 21 additions & 0 deletions Test/ObjCXXEHInterop.mm
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
#import "Test.h"
#import "stdio.h"

#ifdef __unix__
// Declare these inline. The libsupc++ version of cxxabi.h does not include
// __cxa_eh_globls, even though it's mandated by the ABI.
namespace __cxxabiv1
{
struct __cxa_exception;
struct __cxa_eh_globals
{
__cxa_exception *caughtExceptions;
unsigned int uncaughtExceptions;
};
extern "C" __cxa_eh_globals *__cxa_get_globals();
}
extern "C" void check_uncaught_count(void)
{
assert(__cxxabiv1::__cxa_get_globals()->uncaughtExceptions == 0);
}
#else
extern "C" void check_uncaught_count(void) {}
#endif

extern "C" void rethrow(id);


Expand Down
53 changes: 0 additions & 53 deletions cxx_eh_setup.cc

This file was deleted.

2 changes: 2 additions & 0 deletions eh_personality.c
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,8 @@ BEGIN_PERSONALITY_FUNCTION(__gnustep_objcxx_personality_v0)
if (0 == ex->cxx_exception)
{
ex->cxx_exception = objc_init_cxx_exception(ex->object);
ex->cxx_exception->private_1 = exceptionObject->private_1;
ex->cxx_exception->private_2 = exceptionObject->private_2;
}
exceptionObject = ex->cxx_exception;
exceptionClass = cxx_exception_class;
Expand Down
1 change: 1 addition & 0 deletions eh_trampoline.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
void cxx_throw();

__attribute((visibility("hidden")))
int eh_trampoline()
{
struct X { ~X() {} } x;
Expand Down
19 changes: 0 additions & 19 deletions libstdcxx_current_primary_exception.cc

This file was deleted.

Loading

0 comments on commit 65d6b27

Please sign in to comment.