mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 09:04:13 +00:00
Fix for fetching type information from remote system.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@17095 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
8831b90cc5
commit
2a99982e1a
8 changed files with 148 additions and 25 deletions
|
@ -1,6 +1,13 @@
|
|||
2003-07-04 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSDistantObject.m: Avoid recursion fetching method signature
|
||||
* Source/NSDistantObject.m: Avoid recursion fetching method signature.
|
||||
* Source/NSObject.m: ([methodSignatureForSelector:]) modified to take
|
||||
into account any protocols that the receiver conforms to, so the
|
||||
returned signature has the fullest possible type information.
|
||||
* Source/GSFFCallInvocation.m: Fetch method signature from receiver
|
||||
in preference to using other info. Ensures we have correct info for
|
||||
the object we are sending the message to.
|
||||
* Source/GSFFIInvocation.m: ditto
|
||||
|
||||
2003-07-03 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
|
|
|
@ -768,20 +768,35 @@ GSInvocationCallback (void *callback_data, va_alist args)
|
|||
@" to forwardInvocation: for '%s'",
|
||||
object_get_class_name (obj), sel_get_name(selector));
|
||||
}
|
||||
|
||||
selector = gs_find_by_receiver_best_typed_sel (obj, selector);
|
||||
sig = nil;
|
||||
|
||||
if (sel_get_type (selector))
|
||||
sig = [obj methodSignatureForSelector: selector];
|
||||
|
||||
/*
|
||||
* If we got a method signature from the receiving object,
|
||||
* ensure that the selector we are using matches the types.
|
||||
*/
|
||||
if (sig != nil)
|
||||
{
|
||||
const char *receiverTypes = [sig methodType];
|
||||
const char *runtimeTypes = sel_get_type (selector);
|
||||
|
||||
if (runtimeTypes == 0 || strcmp(receiverTypes, runtimeTypes) != 0)
|
||||
{
|
||||
const char *runtimeName = sel_get_name (selector);
|
||||
|
||||
selector = sel_get_typed_uid (runtimeName, receiverTypes);
|
||||
if (selector == 0)
|
||||
{
|
||||
selector = sel_register_typed_name (runtimeName, receiverTypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sig == nil && sel_get_type (selector) != 0)
|
||||
{
|
||||
sig = [NSMethodSignature signatureWithObjCTypes: sel_get_type(selector)];
|
||||
}
|
||||
|
||||
if (!sig)
|
||||
{
|
||||
sig = [obj methodSignatureForSelector: selector];
|
||||
}
|
||||
|
||||
NSCAssert1(sig, @"No signature for selector %@",
|
||||
NSStringFromSelector(selector));
|
||||
|
||||
|
|
|
@ -374,19 +374,34 @@ GSFFIInvocationCallback(ffi_cif *cif, void *retp, void **args, void *user)
|
|||
object_get_class_name (obj), sel_get_name(selector));
|
||||
}
|
||||
|
||||
selector = gs_find_by_receiver_best_typed_sel (obj, selector);
|
||||
sig = nil;
|
||||
sig = [obj methodSignatureForSelector: selector];
|
||||
|
||||
/*
|
||||
* If we got a method signature from the receiving object,
|
||||
* ensure that the selector we are using matches the types.
|
||||
*/
|
||||
if (sig != nil)
|
||||
{
|
||||
const char *receiverTypes = [sig methodType];
|
||||
const char *runtimeTypes = sel_get_type (selector);
|
||||
|
||||
if (runtimeTypes == 0 || strcmp(receiverTypes, runtimeTypes) != 0)
|
||||
{
|
||||
const char *runtimeName = sel_get_name (selector);
|
||||
|
||||
selector = sel_get_typed_uid (runtimeName, receiverTypes);
|
||||
if (selector == 0)
|
||||
{
|
||||
selector = sel_register_typed_name (runtimeName, receiverTypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sel_get_type (selector))
|
||||
if (sig == nil && sel_get_type (selector) != 0)
|
||||
{
|
||||
sig = [NSMethodSignature signatureWithObjCTypes: sel_get_type(selector)];
|
||||
}
|
||||
|
||||
if (!sig)
|
||||
{
|
||||
sig = [obj methodSignatureForSelector: selector];
|
||||
}
|
||||
|
||||
NSCAssert1(sig, @"No signature for selector %@",
|
||||
NSStringFromSelector(selector));
|
||||
|
||||
|
|
|
@ -704,7 +704,7 @@ enum
|
|||
}
|
||||
|
||||
/*
|
||||
* We don't need to retain the oibject here - the connection
|
||||
* We don't need to retain the object here - the connection
|
||||
* will retain the proxies local object if necessary (and release it
|
||||
* when all proxies referring to it have been released).
|
||||
*/
|
||||
|
|
|
@ -1238,21 +1238,74 @@ static BOOL double_release_check_enabled = NO;
|
|||
*/
|
||||
- (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector
|
||||
{
|
||||
const char *types;
|
||||
struct objc_method *mth;
|
||||
const char *types;
|
||||
struct objc_method *mth;
|
||||
Class c;
|
||||
|
||||
if (aSelector == 0)
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
|
||||
|
||||
mth = (GSObjCIsInstance(self)
|
||||
? GSGetInstanceMethod(GSObjCClass(self), aSelector)
|
||||
: GSGetClassMethod((Class)self, aSelector));
|
||||
if (GSObjCIsInstance(self))
|
||||
{
|
||||
c = GSObjCClass(self);
|
||||
mth = GSGetInstanceMethod(c, aSelector);
|
||||
}
|
||||
else
|
||||
{
|
||||
c = (Class)self;
|
||||
mth = GSGetClassMethod((Class)self, aSelector);
|
||||
}
|
||||
|
||||
if (mth == 0)
|
||||
{
|
||||
return nil;
|
||||
return nil; // Method not implemented
|
||||
}
|
||||
types = mth->method_types;
|
||||
|
||||
/*
|
||||
* If there are protocols that this class conforms to,
|
||||
* the method may be listed in a protocol with more
|
||||
* detailed type information than in the class itsself
|
||||
* and we must therefore use the information from the
|
||||
* protocol.
|
||||
* This is because protocols also carry information
|
||||
* used by the Distributed Objects system, which the
|
||||
* runtime does not maintain in classes.
|
||||
*/
|
||||
if (c->protocols != 0)
|
||||
{
|
||||
struct objc_protocol_list *protocols = c->protocols;
|
||||
BOOL found = NO;
|
||||
|
||||
while (found == NO && protocols != 0)
|
||||
{
|
||||
unsigned i = 0;
|
||||
|
||||
while (found == NO && i < protocols->count)
|
||||
{
|
||||
Protocol *p;
|
||||
struct objc_method_description *pmth;
|
||||
|
||||
p = protocols->list[i++];
|
||||
if (c == (Class)self)
|
||||
{
|
||||
pmth = [p descriptionForClassMethod: aSelector];
|
||||
}
|
||||
else
|
||||
{
|
||||
pmth = [p descriptionForInstanceMethod: aSelector];
|
||||
}
|
||||
if (pmth != 0)
|
||||
{
|
||||
types = pmth->types;
|
||||
found = YES;
|
||||
}
|
||||
}
|
||||
protocols = protocols->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (types == 0)
|
||||
{
|
||||
return nil;
|
||||
|
|
|
@ -17,6 +17,14 @@
|
|||
|
||||
#include "wgetopt.h"
|
||||
|
||||
/*
|
||||
* Dummy declaration with different bycopy/byref info from the one
|
||||
* in the server ... we expect the info from the server to be used.
|
||||
*/
|
||||
@interface Dummy : NSObject
|
||||
- (id) quietBycopy: (id byref)a;
|
||||
@end
|
||||
|
||||
@interface Auth : NSObject
|
||||
@end
|
||||
|
||||
|
@ -275,6 +283,7 @@ con_messages (id prx)
|
|||
|
||||
printf("Testing bycopy/byref:\n");
|
||||
[prx sendBycopy: obj];
|
||||
[prx quietBycopy: obj];
|
||||
|
||||
#ifdef _F_BYREF
|
||||
[prx sendByref: obj];
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include <Foundation/NSProcessInfo.h>
|
||||
#include <Foundation/NSAutoreleasePool.h>
|
||||
#include <Foundation/NSException.h>
|
||||
|
||||
#define IN_SERVER 1
|
||||
#include "server.h"
|
||||
|
||||
#include "wgetopt.h"
|
||||
|
@ -357,6 +359,13 @@
|
|||
return self;
|
||||
}
|
||||
|
||||
- quietBycopy: (bycopy id)o
|
||||
{
|
||||
printf(" >> quiet bycopy class is %s\n", object_get_class_name (o));
|
||||
fflush(stdout);
|
||||
return self;
|
||||
}
|
||||
|
||||
- sendBycopy: (bycopy id)o
|
||||
{
|
||||
printf(" >> bycopy class is %s\n", object_get_class_name (o));
|
||||
|
|
|
@ -75,10 +75,25 @@ struct myarray {
|
|||
- (oneway void) exceptionTest3;
|
||||
@end
|
||||
|
||||
#ifdef IN_SERVER
|
||||
/*
|
||||
* We don't want the client to know about some methods, so we can
|
||||
* check that they work when it doesn't know them.
|
||||
*/
|
||||
@protocol privateServer
|
||||
- quietBycopy: (bycopy id)o;
|
||||
@end
|
||||
@interface Server : NSObject <ServerProtocol,privateServer>
|
||||
{
|
||||
id the_array;
|
||||
}
|
||||
@end
|
||||
#else
|
||||
@interface Server : NSObject <ServerProtocol>
|
||||
{
|
||||
id the_array;
|
||||
}
|
||||
@end
|
||||
#endif
|
||||
|
||||
#endif /* _server_h */
|
||||
|
|
Loading…
Reference in a new issue