Fix forwarding recursion bug

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@10784 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Adam Fedor 2001-08-27 15:47:24 +00:00
parent c132d8afa2
commit 210a1351d0
6 changed files with 87 additions and 31 deletions

View file

@ -1,3 +1,10 @@
2001-08-21 Willem Rein Oudshoorn <woudshoo@xs4all.nl>
* Source/GSFFCallInvocation.m: Clearified comments
(gs_method_for_receiver_and_selector) added
(GSInvocationCallback): Check if forwardInvocation: is
implemented to avoid infinite recursion bug.
Fri Aug 24 12:34:56 2001 Nicola Pero <nicola@brainstorm.co.uk>
* Source/NSUserDefaults.m ([-__createArgumentDictionary]): Make

View file

@ -9,7 +9,7 @@ NSSymbolStringEncoding = "Adobe Symbol";
NSWindowsCP1251StringEncoding = "Windows Cyrillic (CP1251)";
NSWindowsCP1252StringEncoding = "Windows Latin-1 (CP1252)";
NSWindowsCP1253StringEncoding = "Windows Greek (CP1253)";
NSWindowsCP1254StringEncoding = "Windows Turkish (CP1254);
NSWindowsCP1254StringEncoding = "Windows Turkish (CP1254)";
NSWindowsCP1250StringEncoding = "Windows Latin-2 (CP1250)";
NSISOLatin1StringEncoding = "ISO Latin-1 West European (ISO-8859-1)";
NSISOLatin2StringEncoding = "ISO Latin-2 East European (ISO-8859-2)";
@ -31,4 +31,4 @@ NSKOI8RStringEncoding = "Cyrillic KOI8-R (Russian)";
NSJapaneseEUCStringEncoding = "Japanese EUC";
NSShiftJISStringEncoding = "Japanese Shift-JIS";
NSISO2022JPStringEncoding = "Japanese JIS (7 bits) (ISO 2022)";
NSGB2312StringEncoding = "Simplified Chinese GB2312";
NSGB2312StringEncoding = "Simplified Chinese GB2312";

View file

@ -6,11 +6,11 @@ NSNonLossyASCIIStringEncoding = "Non-lossy ASCII (7 bits)";
NSMacOSRomanStringEncoding = "MacOS Roman";
NSNEXTSTEPStringEncoding = "NEXTSTEP";
NSSymbolStringEncoding = "Adobe Symbol";
NSWindowsCP1251StringEncoding = "Windows Cyrillique (CP1251)";
NSWindowsCP1252StringEncoding = "Windows Latin-1 (CP1252)";
NSWindowsCP1253StringEncoding = "Windows Grec (CP1253)";
NSWindowsCP1254StringEncoding = "Windows Turquie (CP1254);
NSWindowsCP1250StringEncoding = "Windows Latin-2 (CP1250)";
NSWindowsCP1251StringEncoding = "Windows Cyrillique (CP1251)";
NSWindowsCP1252StringEncoding = "Windows Latin-1 (CP1252)";
NSWindowsCP1253StringEncoding = "Windows Grec (CP1253)";
NSWindowsCP1254StringEncoding = "Windows Turquie (CP1254)";
NSWindowsCP1250StringEncoding = "Windows Latin-2 (CP1250)";
NSISOLatin1StringEncoding = "ISO Latin-1 Europe de l'Ouest (ISO-8859-1)";
NSISOLatin2StringEncoding = "ISO Latin-2 Europe de l'Est (ISO-8859-2)";
NSISOLatin3StringEncoding = "ISO Latin-3 Europe de la Sud (ISO-8859-3)";

View file

@ -9,7 +9,7 @@ NSSymbolStringEncoding = "Adobe Symbol";
NSWindowsCP1251StringEncoding = "Windows Kyrillisch (CP1251)";
NSWindowsCP1252StringEncoding = "Windows Latin-1 (CP1252)";
NSWindowsCP1253StringEncoding = "Windows Griechisch (CP1253)";
NSWindowsCP1254StringEncoding = "Windows Türkisch (CP1254);
NSWindowsCP1254StringEncoding = "Windows Türkisch (CP1254)";
NSWindowsCP1250StringEncoding = "Windows Latin-2 (CP1250)";
NSISOLatin1StringEncoding = "ISO Latin-1 Westeuropäisch (ISO-8859-1)";
NSISOLatin2StringEncoding = "ISO Latin-2 Osteuropäisch (ISO-8859-2)";
@ -31,4 +31,4 @@ NSKOI8RStringEncoding = "Kyrillisch KOI8-R (Russisch)";
NSJapaneseEUCStringEncoding = "Japanisch EUC";
NSShiftJISStringEncoding = "Japanisch Shift-JIS";
NSISO2022JPStringEncoding = "Japanisch JIS 7 Bit (ISO 2022)";
NSGB2312StringEncoding = "Chinesisch - Simplified Chinese GB2312";
NSGB2312StringEncoding = "Chinesisch - Simplified Chinese GB2312";

View file

@ -9,7 +9,7 @@ NSSymbolStringEncoding = "Adobe Symbol";
NSWindowsCP1251StringEncoding = "Windows Cirillico (CP1251)";
NSWindowsCP1252StringEncoding = "Windows Latin-1 (CP1252)";
NSWindowsCP1253StringEncoding = "Windows Greco (CP1253)";
NSWindowsCP1254StringEncoding = "Windows Turco (CP1254);
NSWindowsCP1254StringEncoding = "Windows Turco (CP1254)";
NSWindowsCP1250StringEncoding = "Windows Latin-2 (CP1250)";
NSISOLatin1StringEncoding = "ISO Latin-1 Europa Occidentale (ISO-8859-1)";
NSISOLatin2StringEncoding = "ISO Latin-2 Europa Orientale (ISO-8859-2)";

View file

@ -34,6 +34,7 @@
#define INLINE inline
#endif
typedef struct _NSInvocation_t {
@defs(NSInvocation)
} NSInvocation_t;
@ -194,6 +195,37 @@ gs_splittable (const char *type)
return result;
}
/*
* If we are using the GNU ObjC runtime we could
* simplify this function quite a lot because this
* function is already present in the ObjC runtime.
* However, it is not part of the public API, so
* we work around it.
*/
static INLINE Method_t
gs_method_for_receiver_and_selector (id receiver, SEL sel)
{
if (receiver)
{
if (object_is_instance (receiver))
{
return class_get_instance_method (object_get_class
(receiver), sel);
}
else if (object_is_meta_class (receiver))
{
return class_get_class_method (object_get_meta_class
(receiver), sel);
}
}
return METHOD_NULL;
}
/*
* Selectors are not unique, and not all selectors have
* type information. This method tries to find the
@ -205,9 +237,9 @@ gs_splittable (const char *type)
* name, except if we can access the
* internal data structures of the runtime.
*
* This has the additional advantage that
* we can check if we check for incompatible
* return types.
* If we can access the private data structures
* we can also check for incompatible
* return types between all equivalent selectors.
*/
static INLINE SEL
@ -229,8 +261,13 @@ gs_find_best_typed_sel (SEL sel)
/*
* Take the receiver into account for finding the best
* selector. If no receiver is given fallback
* to gs_find_best_typed_sel
* selector. That is, we look if the receiver
* implements the selector and the implementation
* selector has type info. If both conditions
* are satisfied, return this selector.
*
* In all other cases fallback
* to gs_find_best_typed_sel ().
*/
static INLINE SEL
gs_find_by_receiver_best_typed_sel (id receiver, SEL sel)
@ -240,23 +277,16 @@ gs_find_by_receiver_best_typed_sel (id receiver, SEL sel)
if (receiver)
{
Method_t method = 0;
Method_t method;
if (object_is_instance (receiver))
{
method = class_get_instance_method (object_get_class
(receiver), sel);
}
else if (object_is_meta_class (receiver))
{
method = class_get_class_method (object_get_meta_class
(receiver), sel);
}
method = gs_method_for_receiver_and_selector (receiver, sel);
/* CHECKME: Can we assume that:
(a) method_name is a selector (compare libobjc header files)
(b) this selector IS really typed?
At the moment I assume (a) but not (b)
not assuming (b) is the reason for
calling gs_find_best_typed_sel () even
if we have an implementation.
*/
if (method)
sel = method->method_name;
@ -700,6 +730,8 @@ GSInvocationCallback (void *callback_data, va_alist args)
NSArgumentInfo *info;
GSFFCallInvocation *invocation;
NSMethodSignature *sig;
Method_t fwdInvMethod;
typeinfo = (vacallReturnTypeInfo *) callback_data;
@ -714,8 +746,18 @@ GSInvocationCallback (void *callback_data, va_alist args)
}
obj = va_arg_ptr(args, id);
selector = va_arg_ptr(args, SEL);
fwdInvMethod = gs_method_for_receiver_and_selector
(obj, @selector (forwardInvocation:));
if (!fwdInvMethod)
{
NSCAssert1 (0, @"GSFFCallInvocation: Class '%s' does not respond"
@" to forwardInvocation:",
object_get_class_name (obj));
}
selector = va_arg_ptr(args, SEL);
selector = gs_find_by_receiver_best_typed_sel (obj, selector);
sig = nil;
@ -815,10 +857,17 @@ GSInvocationCallback (void *callback_data, va_alist args)
}
}
/* Now do it */
[obj forwardInvocation: invocation];
/*
* Now do it.
* The next line is equivalent to
*
* [obj forwardInvocation: invocation];
*
* but we have already the Method_t for forwardInvocation
* so the line below is somewhat faster. */
fwdInvMethod->method_imp (obj, fwdInvMethod->method_name, invocation);
/* Return the proper type */
/* Return the proper type */
retval = [invocation returnFrame: NULL];
#undef CASE_TYPE