GSFFIInvocation: Always use objc_msg_lookup

The current implementation skips hidden classes, which breaks KVO.
It turns out that GSGetMethod + method_getImplementation is about
50% slower than objc_msg_lookup (gnustep-2.2 ABI).
This commit is contained in:
Hugo Melder 2024-12-02 16:45:56 +01:00
parent d4de228c6f
commit bde70572c9

View file

@ -435,22 +435,20 @@ GSFFIInvokeWithTargetAndImp(NSInvocation *inv, id anObject, IMP imp)
} }
else else
{ {
GSMethod method; /* The KVO implementation for libobjc2 (located in gnustep-base Source/NSKVO*)
method = GSGetMethod((GSObjCIsInstance(_target) * uses the non-portable `object_addMethod_np` API from libobjc2.
? (Class)object_getClass(_target) * `object_addMethod_np` creates or reuses a hidden subclass and adds the swizzled
: (Class)_target), * method to the hidden class.
_selector, *
GSObjCIsInstance(_target), * When retrieving the object's class with `object_getClass`, hidden classes are skipped
YES); * and the original class is returned.
imp = method_getImplementation(method); * This is also the case with `class_getInstanceMethod`, where the
/* * original class or (non-swizzled) method is returned instead.
* If fast lookup failed, we may be forwarding or something ... *
* The proper way to retrieve an IMP is with `objc_msg_lookup`.
*/ */
if (imp == 0)
{
imp = objc_msg_lookup(_target, _selector); imp = objc_msg_lookup(_target, _selector);
} }
}
[self setTarget: old_target]; [self setTarget: old_target];
RELEASE(old_target); RELEASE(old_target);