[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Side effect of r35304: "Use GSSelectorTypesMatch() for types comparison.
From: |
Ivan Vučica |
Subject: |
Side effect of r35304: "Use GSSelectorTypesMatch() for types comparison..." |
Date: |
Sun, 19 Aug 2012 23:25:14 +0200 |
Hi Richard, all,
While updating QuartzCore under GNUstep, I ran into an obscure issue caused by Richard's July 20th commit, revision 35304 with log message:
"Use GSSelectorTypesMatch() for types comparison where we are interested in types but not qualifiers and stack layout information."
Primarily I'm having trouble with changes to NSValue.m around what's line 197 in revision 35403 (the revision of -base that I currently use). Here are the changes to + (Class) valueClassWithObjCType: (const char *)type.
35304 rfm /* Try for equivalent types match.
35304 rfm */
35304 rfm else if (GSSelectorTypesMatch(@encode(id), type))
35304 rfm theClass = nonretainedObjectValueClass;
35304 rfm else if (GSSelectorTypesMatch(@encode(NSPoint), type))
35304 rfm theClass = pointValueClass;
35304 rfm else if (GSSelectorTypesMatch(@encode(void *), type))
35304 rfm theClass = pointerValueClass;
35304 rfm else if (GSSelectorTypesMatch(@encode(NSRange), type))
35304 rfm theClass = rangeValueClass;
35304 rfm else if (GSSelectorTypesMatch(@encode(NSRect), type))
35304 rfm theClass = rectValueClass;
35304 rfm else if (GSSelectorTypesMatch(@encode(NSSize), type))
35304 rfm theClass = sizeValueClass;
35304 rfm
I'm currently considering this a bug, since the above behavior differs from Cocoa's. Under Cocoa, if I request to store a CGPoint inside a NSValue using @encode(CGPoint), that's exactly what I get out. However, with GNUstep, if I store a CGPoint into a NSValue, I get a NSPoint out of it, wreaking havoc with my current code that handles case when these structs don't have equal members.
While this would ordinarily be a very welcome change and I'd love it if Cocoa did the same, unfortunately it doesn't. Here's a part of my code that breaks (for further context, see -calculatedAnimationValueAtTime:onLayer: in libs/quartzcore/trunk/CAAnimation.m):
/*
NSValue * from = ....;
*/
if (!strcmp([from objCType], @encode(NSPoint)))
{
CGPoint fromPt = CGPointMake([from pointValue].x, [from pointValue].y);
from = [NSValue valueWithBytes: &fromPt objCType: @encode(CGPoint)];
}
if (!strcmp([from objCType], @encode(CGPoint)))
{
// ... actual handling of both NSPoint and CGPoint here
return;
}
if (...
This code takes care of possibility that CGPoint, the native point type that I work with, has different data types than NSPoint. Under GNUstep, it trips up in case the data types are the same.
I'll modify the CGPoint section of my code to accept both NSPoint and CGPoint; since the 'from' and 'to' values that happened to be NSPoints were already replaced with a CGPoint, and -base erroneously decided to consider the value a NSPoint just because all struct members are of equal type, it's safe to extract values and put them in a CGPoint (they're surely that already). However, it's still just a workaround; who knows what other problems might this change trigger in third-party code.
I'll have QuartzCore print out a warning if it detects this bug in -base.
--
Ivan Vucica
--
Ivan Vučica - ivan@vucica.net