Index: src/runtime/ObjFW_RT.h ================================================================== --- src/runtime/ObjFW_RT.h +++ src/runtime/ObjFW_RT.h @@ -272,15 +272,15 @@ const char *_Nullable types OBJC_M68K_REG("a3")); extern IMP _Nullable class_replaceMethod(Class _Nonnull cls OBJC_M68K_REG("a0"), SEL _Nonnull sel OBJC_M68K_REG("a1"), IMP _Nonnull imp OBJC_M68K_REG("a2"), const char *_Nullable types OBJC_M68K_REG("a3")); -extern Class _Nullable object_getClass(id _Nullable obj OBJC_M68K_REG("a0")); -extern Class _Nullable object_setClass(id _Nullable obj OBJC_M68K_REG("a0"), +extern Class _Nullable object_getClass(id _Nullable object OBJC_M68K_REG("a0")); +extern Class _Nullable object_setClass(id _Nullable object OBJC_M68K_REG("a0"), Class _Nonnull OBJC_M68K_REG("a1")); extern const char *_Nullable object_getClassName( - id _Nullable obj OBJC_M68K_REG("a0")); + id _Nullable object OBJC_M68K_REG("a0")); extern const char *_Nonnull protocol_getName( Protocol *_Nonnull p OBJC_M68K_REG("a0")); extern bool protocol_isEqual(Protocol *_Nonnull a OBJC_M68K_REG("a0"), Protocol *_Nonnull b OBJC_M68K_REG("a1")); extern bool protocol_conformsToProtocol( @@ -302,12 +302,13 @@ * * These declarations are also required to prevent Clang's implicit * declarations which include __declspec(dllimport) on Windows. */ extern void __objc_exec_class(void *_Nonnull module); -extern IMP _Nonnull objc_msg_lookup(id _Nullable obj, SEL _Nonnull sel); -extern IMP _Nonnull objc_msg_lookup_stret(id _Nullable obj, SEL _Nonnull sel); +extern IMP _Nonnull objc_msg_lookup(id _Nullable object, SEL _Nonnull sel); +extern IMP _Nonnull objc_msg_lookup_stret(id _Nullable object, + SEL _Nonnull sel); extern IMP _Nonnull objc_msg_lookup_super(struct objc_super *_Nonnull super, SEL _Nonnull sel); extern IMP _Nonnull objc_msg_lookup_super_stret( struct objc_super *_Nonnull super, SEL _Nonnull sel); extern id _Nullable objc_lookUpClass(const char *_Nonnull name); @@ -324,15 +325,15 @@ ptrdiff_t offset, id _Nullable value, bool atomic, signed char copy); extern void objc_getPropertyStruct(void *_Nonnull dest, const void *_Nonnull src, ptrdiff_t size, bool atomic, bool strong); extern void objc_setPropertyStruct(void *_Nonnull dest, const void *_Nonnull src, ptrdiff_t size, bool atomic, bool strong); -extern void objc_enumerationMutation(id _Nonnull obj); +extern void objc_enumerationMutation(id _Nonnull object); # ifndef OBJC_NO_PERSONALITY_DECLARATION extern int __gnu_objc_personality_v0(int version, int actions, uint64_t ex_class, void *_Nonnull ex, void *_Nonnull ctx); # endif #ifdef __cplusplus } #endif #endif Index: src/runtime/linklib/linklib.m ================================================================== --- src/runtime/linklib/linklib.m +++ src/runtime/linklib/linklib.m @@ -214,17 +214,28 @@ { glue_objc_setPropertyStruct(dest, src, size, atomic, strong); } void -objc_enumerationMutation(id obj) +objc_enumerationMutation(id object) { - glue_objc_enumerationMutation(obj); + /* + * This does not use the glue code to hack around a compiler bug. + * + * When using the generated inline stubs, the compiler does not emit + * any frame information, making the unwind fail. As a result + * objc_enumerationMutation() might throw an exception that could never + * be caught. If, however, we're using a function pointer instead of + * the inline stub, the compiler does generate a frame and everything + * works fine. + */ + uintptr_t throw = (((uintptr_t)ObjFWRTBase) - 0x8A); + ((void (*)(id OBJC_M68K_REG("a0")))throw)(object); } int __gnu_objc_personality_v0(int version, int actions, uint64_t ex_class, void *ex, void *ctx) { return glue___gnu_objc_personality_v0(version, actions, &ex_class, ex, ctx); } Index: src/runtime/private.h ================================================================== --- src/runtime/private.h +++ src/runtime/private.h @@ -187,11 +187,10 @@ const char *_Nonnull name OBJC_M68K_REG("a0")); extern Class _Nullable glue_objc_lookup_class( const char *_Nonnull name OBJC_M68K_REG("a0")); extern Class _Nonnull glue_objc_get_class( const char *_Nonnull name OBJC_M68K_REG("a0")); -extern void glue_objc_exception_throw(id _Nullable object OBJC_M68K_REG("a0")); extern int glue_objc_sync_enter(id _Nullable object OBJC_M68K_REG("a0")); extern int glue_objc_sync_exit(id _Nullable object OBJC_M68K_REG("a0")); extern id _Nullable glue_objc_getProperty(id _Nonnull self OBJC_M68K_REG("a0"), SEL _Nonnull _cmd OBJC_M68K_REG("a1"), ptrdiff_t offset OBJC_M68K_REG("d0"), bool atomic OBJC_M68K_REG("d1")); @@ -205,11 +204,10 @@ bool strong OBJC_M68K_REG("d2")); extern void glue_objc_setPropertyStruct(void *_Nonnull dest OBJC_M68K_REG("a0"), const void *_Nonnull src OBJC_M68K_REG("a1"), ptrdiff_t size OBJC_M68K_REG("d0"), bool atomic OBJC_M68K_REG("d1"), bool strong OBJC_M68K_REG("d2")); -extern void glue_objc_enumerationMutation(id _Nonnull obj OBJC_M68K_REG("a0")); extern int glue___gnu_objc_personality_v0(int version OBJC_M68K_REG("d0"), int actions OBJC_M68K_REG("d1"), uint64_t *_Nonnull ex_class OBJC_M68K_REG("d2"), void *_Nonnull ex OBJC_M68K_REG("a0"), void *_Nonnull ctx OBJC_M68K_REG("a1"));