diff --git a/arc.mm b/arc.mm index 10d4acb6..c46d5f0a 100644 --- a/arc.mm +++ b/arc.mm @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #import "lock.h" @@ -250,9 +251,11 @@ static TLS_CALLBACK(cleanupPools)(struct arc_tls* tls) static Class AutoreleasePool; -static IMP NewAutoreleasePool; -static IMP DeleteAutoreleasePool; -static IMP AutoreleaseAdd; +template +using Selector = Return (*)(id, SEL, Arguments...); +static Selector NewAutoreleasePool; +static Selector DeleteAutoreleasePool; +static Selector AutoreleaseAdd; static BOOL useARCAutoreleasePool; @@ -566,12 +569,14 @@ static inline void initAutorelease(void) if (!useARCAutoreleasePool) { [AutoreleasePool class]; - NewAutoreleasePool = class_getMethodImplementation(object_getClass(AutoreleasePool), - SELECTOR(new)); - DeleteAutoreleasePool = class_getMethodImplementation(AutoreleasePool, - SELECTOR(release)); - AutoreleaseAdd = class_getMethodImplementation(object_getClass(AutoreleasePool), - SELECTOR(addObject:)); + auto storeSelector = [](auto &target, Class cls, SEL selector) + { + target = reinterpret_cast>( + class_getMethodImplementation(cls, selector)); + }; + storeSelector(NewAutoreleasePool, object_getClass(AutoreleasePool), SELECTOR(new)); + storeSelector(DeleteAutoreleasePool, AutoreleasePool, SELECTOR(release)); + storeSelector(AutoreleaseAdd, object_getClass(AutoreleasePool), SELECTOR(addObject:)); } } } diff --git a/class.h b/class.h index 090d7132..8526c84d 100644 --- a/class.h +++ b/class.h @@ -5,6 +5,9 @@ #include "sarray2.h" #include +typedef id (*CXXConstructIMP)(id, SEL); +typedef void (*CXXDestructIMP)(id, SEL); + #ifdef __cplusplus extern "C" { @@ -107,12 +110,12 @@ struct objc_class * Pointer to the .cxx_construct method if one exists. This method needs * to be called outside of the normal dispatch mechanism. */ - IMP cxx_construct; + CXXConstructIMP cxx_construct; /** * Pointer to the .cxx_destruct method if one exists. This method needs to * be called outside of the normal dispatch mechanism. */ - IMP cxx_destruct; + CXXDestructIMP cxx_destruct; /** * A pointer to the next sibling class to this. You may find all * subclasses of a given class by following the subclass_list pointer and diff --git a/dtable.c b/dtable.c index 54c0d729..e10e7272 100644 --- a/dtable.c +++ b/dtable.c @@ -381,11 +381,11 @@ static BOOL installMethodInDtable(Class class, } if (selEqualUnTyped(method->selector, cxx_construct)) { - class->cxx_construct = method->imp; + class->cxx_construct = (CXXConstructIMP)method->imp; } else if (selEqualUnTyped(method->selector, cxx_destruct)) { - class->cxx_destruct = method->imp; + class->cxx_destruct = (CXXDestructIMP)method->imp; } for (struct objc_class *subclass=class->subclass_list ; @@ -673,6 +673,7 @@ LEGACY void update_dispatch_table_for_class(Class cls) } BOOL objc_resolve_class(Class); +typedef void (*InitializeIMP)(id, SEL); __attribute__((unused)) static void objc_release_object_lock(id *x) { @@ -851,6 +852,6 @@ OBJC_PUBLIC void objc_send_initialize(id object) // Store the buffer in the temporary dtables list. Note that it is safe to // insert it into a global list, even though it's a temporary variable, // because we will clean it up after this function. - initializeSlot->imp((id)class, initializeSel); + InitializeIMP initialize = (InitializeIMP)initializeSlot->imp; + initialize((id)class, initializeSel); } - diff --git a/runtime.c b/runtime.c index 45b290e9..58282c24 100644 --- a/runtime.c +++ b/runtime.c @@ -846,4 +846,3 @@ void objc_registerClassPair(Class cls) class_table_insert(cls); objc_resolve_class(cls); } -