-
Notifications
You must be signed in to change notification settings - Fork 122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Selector forwarding is broken on Windows (mingw and msvc) #312
Comments
@davidchisnall Any idea what's going on here? The simplest program to reproduce the issue is like this: #import <Foundation/Foundation.h>
#import "Testing.h"
#import "ObjectTesting.h"
@interface GSFakeNSString : NSObject
{
NSString* _originalItem;
}
- (id) initWithItem: (NSString*)item;
- (NSString*) originalItem;
- (id) target;
- (SEL)action;
- (void) action: (id)sender;
@end
@implementation GSFakeNSString
- (id) initWithItem: (NSString*)item
{
self = [super init];
if (self)
{
_originalItem = item;
}
return self;
}
- (NSString*) originalItem
{
return _originalItem;
}
- (id)target
{
return self;
}
- (SEL)action
{
return @selector(action:);
}
- (id)forwardingTargetForSelector:(SEL)selector
{
if ([_originalItem respondsToSelector:selector])
return _originalItem;
return nil;
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
SEL selector = [invocation selector];
// Forward any invocation to the original item if it supports it...
if ([_originalItem respondsToSelector:selector])
[invocation invokeWithTarget:_originalItem];
}
-(NSMethodSignature*)methodSignatureForSelector:(SEL)selector
{
NSMethodSignature *signature = [[_originalItem class] instanceMethodSignatureForSelector:selector];
if(signature == nil)
{
signature = [NSMethodSignature signatureWithObjCTypes:"@^v^c"];
}
return(signature);
}
- (void)doesNotRecognizeSelector:(SEL)selector
{
NSLog(@"%s:selector not recognized: %@", __PRETTY_FUNCTION__, NSStringFromSelector(selector));
}
@end
int main(int argc,char **argv)
{
START_SET("GSFFIInvocation")
NSString *string = @"Hello, World!";
GSFakeNSString *fakeString = [[GSFakeNSString alloc] initWithItem:string];
NSString *upperCaseString = [string uppercaseString];
NSString *fakeUpperCaseString = [fakeString uppercaseString];
PASS_EQUAL(upperCaseString, fakeUpperCaseString, "uppercaseString selector is forwarded from the fake string to the actual NSString object");
NSLog(@"Upper case string: %@, fake upper case string: %@", upperCaseString, fakeUpperCaseString);
END_SET("GSFFIInvocation")
return 0;
} On Linux this passes, on Windows this gives:
From what I can see, when the |
I thought we had a test for the hook that forwardingTargetForSelector uses. It is the one that is allowed to rewrite the receiver and so the passes a pointer to the receiver to the forwarding hook, which can the rewrite it and message send then uses the result. It sounds like something is going wrong there and we’re somehow passing the pointer to the pointer instead. |
Yes, there's Test/Forward.m. But it seems the implementation of those hooks in libs-base is more complex than what's in that test. |
@davidchisnall As far as I can tell:
|
Selector forwarding from one object to another seems to be broken when using libobjc2 on Windows (see also: gnustep/plugins-themes-WinUXTheme#7 (comment)).
I've opened a PR in libs-base which shows the problem: gnustep/libs-base#466
The text was updated successfully, but these errors were encountered: