diff --git a/ChangeLog b/ChangeLog index 8399ab666..20cff38ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,23 @@ -2004-08-17 David Ayers +2004-08-19 David Ayers + + * Headers/Additions/GNUstepBase/GSObjCRuntime.h + * Source/Additions/GSObjCRuntime.m (GSSelectorTypesMatch): + New Function. + (gs_skip_type_qualifier_and_layout_info): Ditto. + + * Source/callframe.m (callframe_do_call): Use GSSelectorTypesMatch + instead of sel_types_match. + * Source/cifframe.m (cifframe_do_call): Ditto. + * Source/mframe.m (mframe_do_call): Ditto. + + * Source/GSFFCallInvocation.m (GSInvocationCallback): Use + NSDebugFLog to NSWarnFLog. + * Source/GSFFIInvocation.m (GSFFIInvocationCallback): Ditto. + + * Testing/nsmethodsignature.m: Use GSSelectorTypesMatch instead of + sel_types_match. Test it. + +2004-08-18 David Ayers * Testing/nsmethodsignature.m: Add more testing utilities. @@ -201,7 +220,7 @@ in NSPropertyList.m, so we only have one version to worry about. * Source/NSString.m ditto. -2004-07-01 David Ayers +2004-07-02 David Ayers * Headers/Foundation/NSMethodSignature.h * Source/NSMethodSignature.m diff --git a/Headers/Additions/GNUstepBase/GSObjCRuntime.h b/Headers/Additions/GNUstepBase/GSObjCRuntime.h index 6eb7361c1..a54ce8703 100644 --- a/Headers/Additions/GNUstepBase/GSObjCRuntime.h +++ b/Headers/Additions/GNUstepBase/GSObjCRuntime.h @@ -342,6 +342,14 @@ GSTypesFromSelector(SEL sel) return sel_get_type(sel); } +/** + * Compare only the type information ignoring qualifiers, the frame layout + * and register markers. Unlike sel_types_match, this function also + * handles comparisons of types with and without any layout information. + */ +GS_EXPORT BOOL +GSSelectorTypesMatch(const char *types1, const char *types2); + /** * Returns a protocol object with the corresponding name. * This function searches the registered classes for any protocol diff --git a/Source/Additions/GSObjCRuntime.m b/Source/Additions/GSObjCRuntime.m index 5d457dd9b..bee1d5134 100644 --- a/Source/Additions/GSObjCRuntime.m +++ b/Source/Additions/GSObjCRuntime.m @@ -1095,6 +1095,60 @@ GSRemoveMethodList(Class cls, } +GS_STATIC_INLINE const char * +gs_skip_type_qualifier_and_layout_info (const char *types) +{ + while (*types == '+' + || *types == '-' + || *types == _C_CONST + || *types == _C_IN + || *types == _C_INOUT + || *types == _C_OUT + || *types == _C_BYCOPY + || *types == _C_BYREF + || *types == _C_ONEWAY + || *types == _C_GCINVISIBLE + || isdigit ((unsigned char) *types)) + { + types++; + } + + return types; +} + +/* See header for documentation. */ +GS_EXPORT BOOL +GSSelectorTypesMatch(const char *types1, const char *types2) +{ + if (! types1 || ! types2) + return NO; + + while (*types1 && *types2) + { + types1 = gs_skip_type_qualifier_and_layout_info (types1); + types2 = gs_skip_type_qualifier_and_layout_info (types2); + + if (! *types1 && ! *types2) + return YES; + + /* (Ayers) This does not account for older versions of gcc + which encoded structures as {??=} while new versions replaced + the ?? with the structure name. But it seems to expensive to + handle that here and sel_types_match also never took this into + account. */ + if (*types1 != *types2) + return NO; + + types1++; + types2++; + } + + types1 = gs_skip_type_qualifier_and_layout_info (types1); + types2 = gs_skip_type_qualifier_and_layout_info (types2); + + return (! *types1 && ! *types2); +} + /* See header for documentation. */ GSIVar GSCGetInstanceVariableDefinition(Class cls, const char *name) diff --git a/Source/GSFFCallInvocation.m b/Source/GSFFCallInvocation.m index 226ded052..e87025c6e 100644 --- a/Source/GSFFCallInvocation.m +++ b/Source/GSFFCallInvocation.m @@ -852,7 +852,7 @@ GSInvocationCallback (void *callback_data, va_alist args) * type qalifiers and sizes differ, and those where the * actual types differ. */ - NSWarnFLog(@"Changed type signature '%s' to '%s' for '%s'", + NSDebugFLog(@"Changed type signature '%s' to '%s' for '%s'", runtimeTypes, receiverTypes, runtimeName); } } diff --git a/Source/GSFFIInvocation.m b/Source/GSFFIInvocation.m index 89f627511..cc9d1246e 100644 --- a/Source/GSFFIInvocation.m +++ b/Source/GSFFIInvocation.m @@ -465,7 +465,7 @@ GSFFIInvocationCallback(ffi_cif *cif, void *retp, void **args, void *user) * type qalifiers and sizes differ, and those where the * actual types differ. */ - NSWarnFLog(@"Changed type signature '%s' to '%s' for '%s'", + NSDebugFLog(@"Changed type signature '%s' to '%s' for '%s'", runtimeTypes, receiverTypes, runtimeName); } } diff --git a/Source/callframe.m b/Source/callframe.m index 0bead037d..554c6c05f 100644 --- a/Source/callframe.m +++ b/Source/callframe.m @@ -35,8 +35,6 @@ typedef long long smallret_t; typedef int smallret_t; #endif -extern BOOL sel_types_match(const char* t1, const char* t2); - callframe_t * callframe_from_info (NSArgumentInfo *info, int numargs, void **retval) { @@ -300,7 +298,7 @@ callframe_do_call (DOContext *ctxt, /* Make sure we successfully got the method type, and that its types match the ENCODED_TYPES. */ NSCParameterAssert (type); - NSCParameterAssert (sel_types_match(encoded_types, type)); + NSCParameterAssert (GSSelectorTypesMatch(encoded_types, type)); /* Build the cif frame */ sig = [NSMethodSignature signatureWithObjCTypes: type]; diff --git a/Source/cifframe.m b/Source/cifframe.m index c9145869d..962af5626 100644 --- a/Source/cifframe.m +++ b/Source/cifframe.m @@ -81,7 +81,6 @@ typedef int smallret_t; #error FFI Sizeof LONG LONG case not handled #endif #endif -extern BOOL sel_types_match(const char* t1, const char* t2); ffi_type *cifframe_type(const char *typePtr, const char **advance); @@ -696,7 +695,7 @@ cifframe_do_call (DOContext *ctxt, /* Make sure we successfully got the method type, and that its types match the ENCODED_TYPES. */ NSCParameterAssert (type); - NSCParameterAssert (sel_types_match(encoded_types, type)); + NSCParameterAssert (GSSelectorTypesMatch(encoded_types, type)); /* Build the cif frame */ sig = [NSMethodSignature signatureWithObjCTypes: type]; diff --git a/Source/mframe.m b/Source/mframe.m index 3b4ccf3cb..81964182e 100644 --- a/Source/mframe.m +++ b/Source/mframe.m @@ -58,7 +58,6 @@ /* memory.h and strings.h conflict on some systems. */ #endif /* not STDC_HEADERS and not HAVE_STRING_H */ -extern BOOL sel_types_match(const char* t1, const char* t2); /* For encoding and decoding the method arguments, we have to know where @@ -879,7 +878,7 @@ mframe_do_call (DOContext *ctxt, /* Make sure we successfully got the method type, and that its types match the ENCODED_TYPES. */ NSCParameterAssert (type); - NSCParameterAssert (sel_types_match(encoded_types, type)); + NSCParameterAssert (GSSelectorTypesMatch(encoded_types, type)); /* * The compiler/runtime doesn't always seem to get the encoding right diff --git a/Testing/nsmethodsignature.m b/Testing/nsmethodsignature.m index bb3820ba6..75c0e131e 100644 --- a/Testing/nsmethodsignature.m +++ b/Testing/nsmethodsignature.m @@ -30,7 +30,6 @@ #include -extern BOOL sel_types_match(const char* t1, const char* t2); #define SRV_NAME @"nsmethodsignaturetest" @@ -275,13 +274,13 @@ test_compare_server_signature(void) #define TEST_SEL(SELNAME) { \ lclSig = [objct runtimeSignatureForSelector: @selector(SELNAME)]; \ rmtSig = [proxy runtimeSignatureForSelector: @selector(SELNAME)]; \ - if (!sel_types_match(lclSig, rmtSig)) \ + if (!GSSelectorTypesMatch(lclSig, rmtSig)) \ NSLog(@"runtime: sel:%s\nlcl:%s\nrmt:%s", \ GSNameFromSelector(@selector(SELNAME)), \ lclSig, rmtSig); \ lclSig = [objct mframeSignatureForSelector: @selector(SELNAME)]; \ rmtSig = [proxy mframeSignatureForSelector: @selector(SELNAME)]; \ - if (!sel_types_match(lclSig, rmtSig)) \ + if (!GSSelectorTypesMatch(lclSig, rmtSig)) \ NSLog(@"mframe : sel:%s\nlcl:%s\nrmt:%s", \ GSNameFromSelector(@selector(SELNAME)), \ lclSig, rmtSig); \ @@ -335,6 +334,47 @@ test_compare_server_signature(void) } } +void +test_GSSelectorTypesMatch(void) +{ + const char *pairs[][2] = { {"@@::", "@12@0:4:8"}, + {"@@::", "@12@+0:+4:+8"}, + {"@@::", "@12@-0:-4:-8"}, + {"@12@0:4:8", "@@::"}, + {"@12@+0:+4:+8", "@@::"}, + {"@12@-0:-4:-8", "@@::"}, + + {"@12@0:4:8", "@12@+0:+4:+8"}, + {"@12@0:4:8", "@12@-0:-4:-8"}, + {"@12@+0:+4:+8", "@12@0:4:8"}, + {"@12@-0:-4:-8", "@12@0:4:8"}, + + {"@12@0:4:8", "@16@+4:+8:+12"}, + {"@12@0:4:8", "@16@-4:-8:-12"}, + {"@12@+0:+4:+8", "@16@4:8:12"}, + {"@12@-0:-4:-8", "@16@4:8:12"}, + + {"{_MyLargeStruct=dd}56@+8:+12@+16c+23s+26i+28l24f28d32{_MyLargeStruct=dd}40{_MySmallStruct=c}44", + "{_MyLargeStruct=dd}46@+8:+12@+16c+17s+16i+20l+24f+28d24{_MyLargeStruct=dd}32{_MySmallStruct=c}45"}, + /* This comparison is currently not supported. + {"{_MyLargeStruct=dd}56@+8:+12@+16c+23s+26i+28l24f28d32{_MyLargeStruct=dd}40{_MySmallStruct=c}44", + "{??=dd}46@+8:+12@+16c+17s+16i+20l+24f+28d24{??=dd}32{??=c}45"}, + */ + {0, 0} }; + unsigned int i = 0; + + while (pairs[i][0]) + { + if (GSSelectorTypesMatch(pairs[i][0], pairs[i][1]) == NO) + { + NSLog(@"pair %d does not match:\n%s\n%s", + i, pairs[i][0], pairs[i][1]); + failed = 1; + } + i++; + } +} + void run_server(void) { @@ -366,6 +406,7 @@ main(int argc, char *argv[]) { test_mframe_build_signature(); test_compare_server_signature(); + test_GSSelectorTypesMatch(); if (failed) [NSException raise: NSInternalInconsistencyException format: @"discrepancies between gcc/mframe signatures"];