Workaround for buggy runtime functions.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@30154 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2010-04-14 11:52:21 +00:00
parent 5ee8f8d24c
commit 1904a2cbe5
4 changed files with 60 additions and 19 deletions

View file

@ -1,3 +1,11 @@
2010-04-14 Richard Frith-Macdonald <rfm@gnu.org>
* Source/ObjectiveC2/runtime.c: work around buggy objc_skip_argspec()
* Source/NSConnection.m: work around buggy objc_skip_argspec()
* Source/NSObjCRuntime.m: Fix NSGetSizeAndAlignment() so it's OSX
compatible and can be used to replace objc_skip_argspec() (as that
function calls objc_skip_offset() which can skip a character too far).
2010-04-13 Richard Frith-Macdonald <rfm@gnu.org> 2010-04-13 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSArray.m: ([-initWithContentsOfFile:]) added ugly OSX * Source/NSArray.m: ([-initWithContentsOfFile:]) added ugly OSX

View file

@ -79,6 +79,20 @@
#import "GNUstepBase/GSLock.h" #import "GNUstepBase/GSLock.h"
#import "GNUstepBase/NSObject+GNUstepBase.h" #import "GNUstepBase/NSObject+GNUstepBase.h"
/* Skip past an argument and also any offset information before the next.
*/
static inline const char *
skip_argspec(const char *ptr)
{
if (ptr != NULL)
{
ptr = NSGetSizeAndAlignment(ptr, NULL, NULL);
if (*ptr == '+') ptr++;
while (isdigit(*ptr)) ptr++;
}
return ptr;
}
/* /*
* Setup for inline operation of pointer map tables. * Setup for inline operation of pointer map tables.
*/ */
@ -2144,9 +2158,9 @@ static NSLock *cached_proxies_gate = nil;
{ {
/* Step through all the arguments, finding the ones that were /* Step through all the arguments, finding the ones that were
passed by reference. */ passed by reference. */
for (tmptype = objc_skip_argspec (tmptype), argnum = 0; for (tmptype = skip_argspec (tmptype), argnum = 0;
*tmptype != '\0'; *tmptype != '\0';
tmptype = objc_skip_argspec (tmptype), argnum++) tmptype = skip_argspec (tmptype), argnum++)
{ {
/* Get the type qualifiers, like IN, OUT, INOUT, ONEWAY. */ /* Get the type qualifiers, like IN, OUT, INOUT, ONEWAY. */
flags = objc_get_type_qualifiers(tmptype); flags = objc_get_type_qualifiers(tmptype);
@ -2602,23 +2616,23 @@ static NSLock *cached_proxies_gate = nil;
sig = [NSMethodSignature signatureWithObjCTypes: type]; sig = [NSMethodSignature signatureWithObjCTypes: type];
inv = [[NSInvocation alloc] initWithMethodSignature: sig]; inv = [[NSInvocation alloc] initWithMethodSignature: sig];
tmptype = objc_skip_argspec (type); tmptype = skip_argspec (type);
etmptype = objc_skip_argspec (etmptype); etmptype = skip_argspec (etmptype);
[inv setTarget: object]; [inv setTarget: object];
tmptype = objc_skip_argspec (tmptype); tmptype = skip_argspec (tmptype);
etmptype = objc_skip_argspec (etmptype); etmptype = skip_argspec (etmptype);
[inv setSelector: selector]; [inv setSelector: selector];
/* Step TMPTYPE and ETMPTYPE in lock-step through their /* Step TMPTYPE and ETMPTYPE in lock-step through their
method type strings. */ method type strings. */
for (tmptype = objc_skip_argspec (tmptype), for (tmptype = skip_argspec (tmptype),
etmptype = objc_skip_argspec (etmptype), argnum = 2; etmptype = skip_argspec (etmptype), argnum = 2;
*tmptype != '\0'; *tmptype != '\0';
tmptype = objc_skip_argspec (tmptype), tmptype = skip_argspec (tmptype),
etmptype = objc_skip_argspec (etmptype), argnum++) etmptype = skip_argspec (etmptype), argnum++)
{ {
void *datum; void *datum;
@ -2793,13 +2807,13 @@ static NSLock *cached_proxies_gate = nil;
{ {
/* Step through all the arguments, finding the ones that were /* Step through all the arguments, finding the ones that were
passed by reference. */ passed by reference. */
for (tmptype = objc_skip_argspec (tmptype), for (tmptype = skip_argspec (tmptype),
argnum = 0, argnum = 0,
etmptype = objc_skip_argspec (etmptype); etmptype = skip_argspec (etmptype);
*tmptype != '\0'; *tmptype != '\0';
tmptype = objc_skip_argspec (tmptype), tmptype = skip_argspec (tmptype),
argnum++, argnum++,
etmptype = objc_skip_argspec (etmptype)) etmptype = skip_argspec (etmptype))
{ {
/* Get the type qualifiers, like IN, OUT, INOUT, ONEWAY. */ /* Get the type qualifiers, like IN, OUT, INOUT, ONEWAY. */
flags = objc_get_type_qualifiers(etmptype); flags = objc_get_type_qualifiers(etmptype);

View file

@ -129,9 +129,10 @@ NSStringFromClass(Class aClass)
* When provided with a C string containing encoded type information, * When provided with a C string containing encoded type information,
* this method extracts size and alignment information for the specified * this method extracts size and alignment information for the specified
* type into the buffers pointed to by sizep and alignp.<br /> * type into the buffers pointed to by sizep and alignp.<br />
* If either sizep or alignp is a nil pointer, the corresponding data is * If either sizep or alignp is a null pointer, the corresponding data is
* not extracted.<br /> * not extracted.<br />
* The function returns a pointer to the type information C string. * The function returns a pointer into the type information C string
* immediately after the decoded information.
*/ */
const char * const char *
NSGetSizeAndAlignment(const char *typePtr, NSGetSizeAndAlignment(const char *typePtr,
@ -158,6 +159,7 @@ NSGetSizeAndAlignment(const char *typePtr,
{ {
*alignp = objc_alignof_type (typePtr); *alignp = objc_alignof_type (typePtr);
} }
typePtr = objc_skip_typespec (typePtr);
} }
return typePtr; return typePtr;
} }

View file

@ -78,6 +78,23 @@ extern struct sarray *__objc_uninstalled_dtable;
*/ */
extern objc_mutex_t __objc_runtime_mutex; extern objc_mutex_t __objc_runtime_mutex;
/* objc_skip_argspec() is often buggy as it calls the buggy objc_skip_offset()
* so we use a local version.
*/
static inline const char *
skip_argspec(const char *types)
{
if (types && *types)
{
types = objc_skip_typespec(types);
if (*types == '+')
types++;
while (isdigit(*types))
types++;
}
return types;
}
/** /**
* Looks up the instance method in a specific class, without recursing into * Looks up the instance method in a specific class, without recursing into
* superclasses. * superclasses.
@ -585,7 +602,7 @@ ivar_getTypeEncoding(Ivar ivar)
static size_t static size_t
lengthOfTypeEncoding(const char *types) lengthOfTypeEncoding(const char *types)
{ {
const char *end = objc_skip_argspec(types); const char *end = skip_argspec(types);
size_t length; size_t length;
end--; end--;
@ -615,7 +632,7 @@ findParameterStart(const char *types, unsigned int index)
for (i = 0; i < index; i++) for (i = 0; i < index; i++)
{ {
types = objc_skip_argspec(types); types = skip_argspec(types);
if ('\0' == *types) if ('\0' == *types)
{ {
return NULL; return NULL;
@ -698,7 +715,7 @@ method_getNumberOfArguments(Method method)
while ('\0' != *types) while ('\0' != *types)
{ {
types = objc_skip_argspec(types); types = skip_argspec(types);
count++; count++;
} }
return count - 1; return count - 1;