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:
Richard Frith-MacDonald 2010-04-14 11:52:21 +00:00
parent 4da5c940ab
commit 00164a28ed
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>
* Source/NSArray.m: ([-initWithContentsOfFile:]) added ugly OSX

View file

@ -79,6 +79,20 @@
#import "GNUstepBase/GSLock.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.
*/
@ -2144,9 +2158,9 @@ static NSLock *cached_proxies_gate = nil;
{
/* Step through all the arguments, finding the ones that were
passed by reference. */
for (tmptype = objc_skip_argspec (tmptype), argnum = 0;
for (tmptype = skip_argspec (tmptype), argnum = 0;
*tmptype != '\0';
tmptype = objc_skip_argspec (tmptype), argnum++)
tmptype = skip_argspec (tmptype), argnum++)
{
/* Get the type qualifiers, like IN, OUT, INOUT, ONEWAY. */
flags = objc_get_type_qualifiers(tmptype);
@ -2602,23 +2616,23 @@ static NSLock *cached_proxies_gate = nil;
sig = [NSMethodSignature signatureWithObjCTypes: type];
inv = [[NSInvocation alloc] initWithMethodSignature: sig];
tmptype = objc_skip_argspec (type);
etmptype = objc_skip_argspec (etmptype);
tmptype = skip_argspec (type);
etmptype = skip_argspec (etmptype);
[inv setTarget: object];
tmptype = objc_skip_argspec (tmptype);
etmptype = objc_skip_argspec (etmptype);
tmptype = skip_argspec (tmptype);
etmptype = skip_argspec (etmptype);
[inv setSelector: selector];
/* Step TMPTYPE and ETMPTYPE in lock-step through their
method type strings. */
for (tmptype = objc_skip_argspec (tmptype),
etmptype = objc_skip_argspec (etmptype), argnum = 2;
for (tmptype = skip_argspec (tmptype),
etmptype = skip_argspec (etmptype), argnum = 2;
*tmptype != '\0';
tmptype = objc_skip_argspec (tmptype),
etmptype = objc_skip_argspec (etmptype), argnum++)
tmptype = skip_argspec (tmptype),
etmptype = skip_argspec (etmptype), argnum++)
{
void *datum;
@ -2793,13 +2807,13 @@ static NSLock *cached_proxies_gate = nil;
{
/* Step through all the arguments, finding the ones that were
passed by reference. */
for (tmptype = objc_skip_argspec (tmptype),
for (tmptype = skip_argspec (tmptype),
argnum = 0,
etmptype = objc_skip_argspec (etmptype);
etmptype = skip_argspec (etmptype);
*tmptype != '\0';
tmptype = objc_skip_argspec (tmptype),
tmptype = skip_argspec (tmptype),
argnum++,
etmptype = objc_skip_argspec (etmptype))
etmptype = skip_argspec (etmptype))
{
/* Get the type qualifiers, like IN, OUT, INOUT, ONEWAY. */
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,
* this method extracts size and alignment information for the specified
* 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 />
* 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 *
NSGetSizeAndAlignment(const char *typePtr,
@ -158,6 +159,7 @@ NSGetSizeAndAlignment(const char *typePtr,
{
*alignp = objc_alignof_type (typePtr);
}
typePtr = objc_skip_typespec (typePtr);
}
return typePtr;
}

View file

@ -78,6 +78,23 @@ extern struct sarray *__objc_uninstalled_dtable;
*/
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
* superclasses.
@ -585,7 +602,7 @@ ivar_getTypeEncoding(Ivar ivar)
static size_t
lengthOfTypeEncoding(const char *types)
{
const char *end = objc_skip_argspec(types);
const char *end = skip_argspec(types);
size_t length;
end--;
@ -615,7 +632,7 @@ findParameterStart(const char *types, unsigned int index)
for (i = 0; i < index; i++)
{
types = objc_skip_argspec(types);
types = skip_argspec(types);
if ('\0' == *types)
{
return NULL;
@ -698,7 +715,7 @@ method_getNumberOfArguments(Method method)
while ('\0' != *types)
{
types = objc_skip_argspec(types);
types = skip_argspec(types);
count++;
}
return count - 1;