diff --git a/.gitignore b/.gitignore index b93343473ab2a0381e8925093d93ac13e464a675..6e433cc0cec37bcbdc3f0738b5d98a12b90e1f68 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,8 @@ test/box/protocol test/box/connector test/unit/queue test/unit/mhash +test/unit/objc_finally +test/unit/objc_catchcxx Makefile CMakeFiles CMakeCache.txt diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 6154fc20a4ab8e22a46e6ce6d8bf54b70122b7c2..7d3a49f43b8a3d46e8883b19aff6303cb843fbee 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -1,3 +1,10 @@ add_executable(queue queue.c) add_executable(mhash mhash.c) +add_executable(objc_finally objc_finally.m) +add_executable(objc_catchcxx objc_catchcxx.m) set_target_properties(mhash PROPERTIES COMPILE_FLAGS "-std=c99") +target_link_libraries(objc_finally ${LIBOBJC_LIB}) +target_link_libraries(objc_catchcxx ${LIBOBJC_LIB} ${LUAJIT_LIB}) +if (TARGET_OS_LINUX OR TARGET_OS_DEBIAN_FREEBSD) + target_link_libraries(objc_catchcxx dl) +endif() diff --git a/test/unit/objc_catchcxx.m b/test/unit/objc_catchcxx.m new file mode 100644 index 0000000000000000000000000000000000000000..b90e53092b57b97965e2170966e90d90dfc9e87c --- /dev/null +++ b/test/unit/objc_catchcxx.m @@ -0,0 +1,15 @@ +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" + +int main() +{ + lua_State *L = luaL_newstate(); + luaL_openlibs(L); + @try { + luaL_error(L, "test"); + } @catch (...) { + printf("exception handled\n"); + } + lua_close(L); +} diff --git a/test/unit/objc_catchcxx.result b/test/unit/objc_catchcxx.result new file mode 100644 index 0000000000000000000000000000000000000000..761f3a20404e3a9aed380cfe9f631e6d231671f8 --- /dev/null +++ b/test/unit/objc_catchcxx.result @@ -0,0 +1 @@ +exception handled diff --git a/test/unit/objc_catchcxx.test b/test/unit/objc_catchcxx.test new file mode 100644 index 0000000000000000000000000000000000000000..13f381fcb7bcb15f5df824b7022269be6f46bbc1 --- /dev/null +++ b/test/unit/objc_catchcxx.test @@ -0,0 +1 @@ +run_test("objc_catchcxx") diff --git a/test/unit/objc_finally.m b/test/unit/objc_finally.m new file mode 100644 index 0000000000000000000000000000000000000000..18cf5c62b5838415226380e92e968d313023f6af --- /dev/null +++ b/test/unit/objc_finally.m @@ -0,0 +1,46 @@ +#include <stdio.h> +#include <objc/Object.h> +#include <objc/runtime.h> + +@interface Exception: Object { +} ++ (id) new; +@end + +@implementation Exception ++ (id) new +{ + return class_createInstance(self, 0); +} +@end + +void +throw_exception(void) +{ + printf("throw\n"); + @throw [Exception new]; +} + +void +test(void) +{ + @try { + throw_exception(); + } @finally { + printf("internal finally\n"); + } +} + +int +main(int ac, char **av) +{ + printf("start\n"); + @try { + test(); + } @catch(id e) { + printf("catch\n"); + } @finally { + printf("external finally\n"); + } + return 0; +} diff --git a/test/unit/objc_finally.result b/test/unit/objc_finally.result new file mode 100644 index 0000000000000000000000000000000000000000..1d09f8b41372dfdb1c732e6c522080975571ae31 --- /dev/null +++ b/test/unit/objc_finally.result @@ -0,0 +1,5 @@ +start +throw +internal finally +catch +external finally diff --git a/test/unit/objc_finally.test b/test/unit/objc_finally.test new file mode 100644 index 0000000000000000000000000000000000000000..65770394cce04b504544ad9578f2c2203990773c --- /dev/null +++ b/test/unit/objc_finally.test @@ -0,0 +1 @@ +run_test("objc_finally") diff --git a/third_party/libobjc/eh_personality.c b/third_party/libobjc/eh_personality.c index e3e4ead29c5cbdf8e7f08aa649539b2d30c4c9ae..77feb2a27162d060c26a66426c3a08440189a0b5 100644 --- a/third_party/libobjc/eh_personality.c +++ b/third_party/libobjc/eh_personality.c @@ -204,7 +204,7 @@ static handler_type check_action_record(struct _Unwind_Context *context, Class thrown_class, unsigned long *selector) { - //if (!action_record) { return handler_cleanup; } + if (!action_record) { return handler_cleanup; } while (action_record) { int filter = read_sleb128(&action_record); @@ -343,6 +343,7 @@ BEGIN_PERSONALITY_FUNCTION(__gnu_objc_personality_v0) action = dwarf_eh_find_callsite(context, &lsda); handler_type handler = check_action_record(context, foreignException, &lsda, action.action_record, thrown_class, &selector); + fprintf(stderr, "handler: %d\n", handler); // If there's no action record, we've only found a cleanup, so keep // searching for something real if (handler == handler_class ||