* Headers/Foundation/NSMethodSignature.h

(_internalMethodTypes): New instance variable.
        * Source/NSMethodSignature.m: ([+signatureWithObjCTypes]): Store
        the runtime signature separately from the mframe signature.
        Document.
        ([-dealloc]): Free new instance variable.
        ([-methodInfo]): Use _internalMethodTypes to build argument
        information.

        * Source/GSFFCallInvocation.m (GSInvocationCallback)
        * Source/GSFFIInvocation.m (GSInvocationCallback): Use the
        selector registered in the runtime for the receiver instead of
        the constructed selector from the stack to avoid mismatches in the
        runtime.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@19662 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
ayers 2004-07-01 11:38:19 +00:00
parent a843b058ca
commit dbe1800bbd
5 changed files with 74 additions and 5 deletions

View file

@ -1,3 +1,20 @@
2004-07-01 David Ayers <d.ayers@inode.at>
* Headers/Foundation/NSMethodSignature.h
(_internalMethodTypes): New instance variable.
* Source/NSMethodSignature.m: ([+signatureWithObjCTypes]): Store
the runtime signature separately from the mframe signature.
Document.
([-dealloc]): Free new instance variable.
([-methodInfo]): Use _internalMethodTypes to build argument
information.
* Source/GSFFCallInvocation.m (GSInvocationCallback)
* Source/GSFFIInvocation.m (GSInvocationCallback): Use the
selector registered in the runtime for the receiver instead of the
constructed selector from the stack to avoid mismatches in the
runtime.
2004-06-29 Richard Frith-Macdonald <rfm@gnu.org> 2004-06-29 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSUserDefaults.m: Added MacOS-X compatibility methods .. * Source/NSUserDefaults.m: Added MacOS-X compatibility methods ..

View file

@ -76,11 +76,12 @@ typedef struct {
const char *_methodTypes; const char *_methodTypes;
unsigned _argFrameLength; unsigned _argFrameLength;
unsigned _numArgs; unsigned _numArgs;
#ifdef STRICT_MACOS_X #ifdef STRICT_MACOS_X
void *_dummy; void *_dummy;
#else #else
NSArgumentInfo *_info; NSArgumentInfo *_info;
#endif #endif
const char *_internalMethodTypes;
} }
/** /**

View file

@ -774,6 +774,7 @@ GSInvocationCallback (void *callback_data, va_alist args)
int i; int i;
int num_args; int num_args;
void *retval; void *retval;
const char *selectorName;
vacallReturnTypeInfo *typeinfo; vacallReturnTypeInfo *typeinfo;
NSArgumentInfo *info; NSArgumentInfo *info;
GSFFCallInvocation *invocation; GSFFCallInvocation *invocation;
@ -795,6 +796,24 @@ GSInvocationCallback (void *callback_data, va_alist args)
obj = va_arg_ptr(args, id); obj = va_arg_ptr(args, id);
selector = va_arg_ptr(args, SEL); selector = va_arg_ptr(args, SEL);
/* Fetch the selector from the runtime
to get the portable type information later. */
selectorName = sel_get_name(selector);
selector = sel_get_uid(selectorName);
if (!selector)
{
/* The selector is not registered with the runtime. It seems
safe to assume that the receiver does not respond to it which
would happen if we created a selector with the 'correct' types
and registered it manually. So let us raise the corresponding
exception. */
[NSException raise: NSGenericException
format: @"%s does not recognize %s",
GSClassNameFromObject(obj),
selectorName ? selectorName : "(null)"];
}
fwdInvMethod = gs_method_for_receiver_and_selector fwdInvMethod = gs_method_for_receiver_and_selector
(obj, @selector (forwardInvocation:)); (obj, @selector (forwardInvocation:));

View file

@ -406,6 +406,7 @@ GSFFIInvocationCallback(ffi_cif *cif, void *retp, void **args, void *user)
{ {
id obj; id obj;
SEL selector; SEL selector;
const char *selectorName;
GSFFIInvocation *invocation; GSFFIInvocation *invocation;
NSMethodSignature *sig; NSMethodSignature *sig;
GSMethod fwdInvMethod; GSMethod fwdInvMethod;
@ -413,6 +414,23 @@ GSFFIInvocationCallback(ffi_cif *cif, void *retp, void **args, void *user)
obj = *(id *)args[0]; obj = *(id *)args[0];
selector = *(SEL *)args[1]; selector = *(SEL *)args[1];
/* Fetch the selector from the runtime
to get the portable type information later. */
selectorName = sel_get_name(selector);
selector = sel_get_uid(selectorName);
if (!selector)
{
/* The selector is not registered with the runtime. It seems
safe to assume that the receiver does not respond to it which
would happen if we created a selector with the 'correct' types
and registered it manually. So let us raise the corresponding
exception. */
[NSException raise: NSGenericException
format: @"%s does not recognize %s",
GSClassNameFromObject(obj),
selectorName ? selectorName : "(null)"];
}
fwdInvMethod = gs_method_for_receiver_and_selector fwdInvMethod = gs_method_for_receiver_and_selector
(obj, @selector (forwardInvocation:)); (obj, @selector (forwardInvocation:));

View file

@ -28,7 +28,8 @@
#include "config.h" #include "config.h"
#include "GNUstepBase/preface.h" #include "GNUstepBase/preface.h"
#include <mframe.h> #include "mframe.h"
#include <string.h>
#include "Foundation/NSMethodSignature.h" #include "Foundation/NSMethodSignature.h"
#include "Foundation/NSException.h" #include "Foundation/NSException.h"
@ -37,6 +38,15 @@
@implementation NSMethodSignature @implementation NSMethodSignature
/**
* Returns a method signature with the corresponding ObjC types. This
* type string must correspond to a type string recognized by the
* runtime which is a platform independent representation. Internally
* this is transformed to a platform specific representation used
* to generate the NSArgumentInfo structures. You should never need
* to access this internal representation and it should not be passed
* to this method.
*/
+ (NSMethodSignature*) signatureWithObjCTypes: (const char*)t + (NSMethodSignature*) signatureWithObjCTypes: (const char*)t
{ {
NSMethodSignature *newMs; NSMethodSignature *newMs;
@ -46,8 +56,10 @@
return nil; return nil;
} }
newMs = AUTORELEASE([NSMethodSignature alloc]); newMs = AUTORELEASE([NSMethodSignature alloc]);
newMs->_methodTypes = mframe_build_signature(t, &newMs->_argFrameLength, newMs->_methodTypes = NSZoneMalloc(NSDefaultMallocZone(), strlen(t) + 1);
&newMs->_numArgs, 0); strcpy ((char *)newMs->_methodTypes, t);
newMs->_internalMethodTypes
= mframe_build_signature(t, &newMs->_argFrameLength, &newMs->_numArgs, 0);
return newMs; return newMs;
} }
@ -121,6 +133,8 @@
{ {
if (_methodTypes) if (_methodTypes)
NSZoneFree(NSDefaultMallocZone(), (void*)_methodTypes); NSZoneFree(NSDefaultMallocZone(), (void*)_methodTypes);
if (_internalMethodTypes)
NSZoneFree(NSDefaultMallocZone(), (void*)_internalMethodTypes);
if (_info) if (_info)
NSZoneFree(NSDefaultMallocZone(), (void*)_info); NSZoneFree(NSDefaultMallocZone(), (void*)_info);
[super dealloc]; [super dealloc];
@ -168,7 +182,7 @@
{ {
if (_info == 0) if (_info == 0)
{ {
const char *types = _methodTypes; const char *types = _internalMethodTypes;
unsigned int i; unsigned int i;
_info = NSZoneMalloc(NSDefaultMallocZone(), _info = NSZoneMalloc(NSDefaultMallocZone(),