This has been filed as https://savannah.gnu.org/bugs/index.php?53994 and
https://github.com/gnustep/libs-base/issues/25.

On Sun, May 27, 2018 at 6:44 PM Ivan Vučica <i...@vucica.net> wrote:

> I'll open a bug for -base. In the meantime I'll help Stjepan disable
> shadowOffset.
>
> Minimum repro::
>
> #import <Foundation/Foundation.h>
>
> @interface A : NSObject
> {
>   NSSize _s;
> }
> @end
> @implementation A
> - (NSSize) s {
>   return self->_s;
> }
> - (void) setS: (NSSize) s {
>   self->_s = s;
> }
> @end
> int main() {
>   NSSize in = NSMakeSize(1.0, 2.0);
>   NSValue * v = [NSValue valueWithBytes: &in
>                                objCType: @encode(NSSize)];
>   A * a = [A new];
>   [a setValue: v
>        forKey: @"s"];
>
>
>   return 0;
> }
>
>
> Output:
> $ clang `gnustep-config --objc-flags` `gnustep-config --objc-libs`
> `gnustep-config --base-libs` repro.m -o repro && ./repro
> clang: warning: argument unused during compilation: '-fobjc-nonfragile-abi'
> clang: warning: argument unused during compilation: '-fobjc-nonfragile-abi'
> 2018-05-27 18:42:13.137 repro[14432:14432] match! point is {_NSPoint=dd},
> type is {_NSSize=dd}
> ./repro: Uncaught exception NSInvalidArgumentException, reason:
> [GSSizeValue-pointValue] should be overridden by subclass
> Aborted
>
>
>
>
>
> On Sun, May 27, 2018 at 6:18 PM Ivan Vučica <i...@vucica.net> wrote:
>
>> So turns out we don't use shadowOffset in any demo code. So examining
>> CAAnimation was pointless.
>>
>> However I managed to get a backtrace using lldb, and this happens when
>> the code sets the default shadowOffset value. So you pointed to the right
>> place; shadowOffset is the problem. This is the place of the exception, in
>> -[CALayer init] which calls +[CALayer defaultValueForKey:]:
>>
>>   if ([key isEqualToString: @"shadowOffset"])
>>
>>     {
>>       CGSize offset = CGSizeMake(0.0, -3.0);
>>       return [NSValue valueWithBytes: &offset objCType: @encode(CGSize)];
>>     }
>>
>> What is strange is that this happens deep inside base, when I am setting
>> valueWithBytes, with a CGSize type.
>>
>> So I looked closer at the backtrace and it's happening in
>> base/Source/Additions/GSObjCRuntime.m. Relevant chunk:
>>
>>     frame #2: 0x00007ffff59e9d7d libgnustep-base.so.1.25`+[NSException
>> raise:format:](self=0x00007ffff5f69878
>> , _cmd="S", name=0x00007ffff5f69438, format=0x00007ffff6003828) + 365 at
>> NSException.m:1376
>>     frame #3: 0x00007ffff5b9ca2f
>> libgnustep-base.so.1.25`-[NSObject(self=0x000000000148f568, _cmd="\xffffffa9
>> \x02", aSel="\x0e\x01") subclassResponsibility:] + 255 at
>> NSObject+GNUstepBase.m:134
>>     frame #4: 0x00007ffff5b1d32b libgnustep-base.so.1.25`-[NSValue
>> pointValue](self=0x000000000148f568, _cmd=
>> "\x0e\x01") + 43 at NSValue.m:394
>>     frame #5: 0x00007ffff5b58649
>> libgnustep-base.so.1.25`GSObjCSetVal(self=0x00000000014591c8, key="shadowOff
>> set", val=0x000000000148f568, sel="\xffffffda\e", type="{_NSSize=dd}",
>> size=12, offset=0) + 3497 at GSObjCRun
>> time.m:1794
>>     frame #6: 0x00007ffff5a25857
>> libgnustep-base.so.1.25`SetValueForKey(self=0x00000000014591c8, anObject=0x0
>> 00000000148f568, key="shadowOffset", size=12) + 1079 at
>> NSKeyValueCoding.m:150
>>     frame #7: 0x00007ffff5a253ee
>> libgnustep-base.so.1.25`-[NSObject(self=0x00000000014591c8, _cmd="P\x04", an
>> Object=0x000000000148f568, aKey=0x00007ffff62cc560) setValue:forKey:] +
>> 382 at NSKeyValueCoding.m:370
>>     frame #8: 0x00007ffff5a2881d libgnustep-base.so.1.25`-[GSKVOBase
>> setValue:forKey:](self=0x00000000014591c
>> 8, _cmd="P\x04", anObject=0x000000000148f568, aKey=0x00007ffff62cc560) +
>> 221 at NSKeyValueObserving.m:238
>>     frame #9: 0x00007ffff60a22ac libQuartzCore.so.0`-[CALayer
>> init](self=0x00000000014591c8, _cmd="\xffffffa1
>>
>> I added a debug statement to GSObjCSetVal:
>>
>>           case _C_STRUCT_B:
>>             if (GSSelectorTypesMatch(@encode(NSPoint), type))
>>               {
>>                 NSLog(@"match! point is %s, type is %s",
>> @encode(NSPoint), type);
>>                 NSPoint v = [val pointValue];
>>
>> This is the output:
>> 2018-05-27 17:58:46.980 hello_carenderer[10274:10274] match! point is
>> {_NSPoint=dd}, type is {_NSPoint=dd}
>> 2018-05-27 17:58:46.981 hello_carenderer[10274:10274] match! point is
>> {_NSPoint=dd}, type is {_NSSize=dd}
>>
>> Therefore, it's a bug in -base that makes it interpret sizes as points!
>>
>> I'm still coming up with a minimum repro case.
>>
>> (n.b. some of the confusion on why CGSize and CGPoint get understood as
>> their NS equivalents is this chunk from opal:
>>   typedef NSPoint CGPoint;
>>   typedef NSSize CGSize;
>>   typedef NSRect CGRect;
>> I do not believe this to be correct, but I will not be addressing it at
>> this time.
>>
>> Separately: are typedefs of structs meant to be encoded as the original
>> struct name? Probably yes?)
>>
>>
>> On Sun, May 27, 2018 at 5:29 PM Ivan Vučica <i...@vucica.net> wrote:
>>
>>> I added a test to the -base from May 20:
>>>
>>>   NSPoint point = {.x = 16.0, .y = 32.0};
>>>   NSValue *pointV = [NSValue valueWithPoint: point];
>>>
>>>   result = !strcmp(@encode(NSPoint), [pointV objCType]);
>>>   PASS(result, "@encoding(NSPoint) == pointV objCType");
>>>
>>>   result = strcmp(@encode(NSSize), [pointV objCType]);
>>>   PASS(result, "@encoding(NSSize) == pointV objCType");
>>>
>>> with this temporarly ine:
>>>   NSLog(@"%s %s %s", @encode(NSPoint), @encode(NSSize), [pointV
>>> objCType]);
>>>
>>> It passes and prints out:
>>>
>>> 2018-05-27 17:27:38.823 size-point-encoding[25395:25395] {_NSPoint=dd}
>>> {_NSSize=dd} {_NSPoint=dd}
>>>
>>> I''m annoyed at how I did not notice that I did use CGSize. I will
>>> introduce support for NSSize/CGSize.
>>>
>>> Thanks!
>>>
>>> On Mon, May 21, 2018 at 12:53 AM Fred Kiefer <fredkie...@gmx.de> wrote:
>>>
>>>> I added a bit of code in base that allows to use NSValue objects for
>>>> size and point with methods for the other type. This is a bit closer to the
>>>> Cocoa behaviour but will require more tweaking to have it fully correct. It
>>>> will at least allow you to run this test code again.
>>>>
>>>> > Am 20.05.2018 um 16:02 schrieb Fred Kiefer <fredkie...@gmx.de>:
>>>> >
>>>> > I spend some time to understand this issue. But to be honest it took
>>>> me more time to understand why this ever worked :-)
>>>> >
>>>> > The problem here is that base uses two different ways to provide
>>>> concrete subclasses for NSValue. One being GSValue, which supports generic
>>>> data and the other mechanism is to have a specific subclass for types like
>>>> NSPoint and NSSize. For the later base only generates specific methods for
>>>> that types. Resulting in different classes for NSPoint and NSSize, which
>>>> are incompatible although they have the same underlying data size.
>>>> > In your demo application that animation for shadowOffset tries to set
>>>> the offset size with a suitable default value of class GSSizeValue. But the
>>>> code in GSObjCSetVal only compares the type information without looking at
>>>> the type names. That way NSSize is regarded as the same as NSPoint and the
>>>> pointValue get executed, resulting in the error you reported. Either
>>>> GSObjCSetVal has to be more careful and use a check for the actual type
>>>> first. Or we need to make the NSValue subclasses more general.
>>>> >
>>>> > But why did it work before? Most likely because at that time CGSize
>>>> and CGPoint, where different from NSSize and NSPoint so we did not get the
>>>> specific optimisation in NSValue.
>>>> >
>>>> > Hope this helps,
>>>> > Fred
>>>> >
>>>> >> Am 20.05.2018 um 14:03 schrieb Ivan Vučica <i...@vucica.net>:
>>>> >>
>>>> >> Hi,
>>>> >>
>>>> >> Pretty much all Core Animation demos are currently broken under
>>>> GNUstep with a variation on the following:
>>>> >>
>>>> >> 2018-05-20 12:54:25.464 QuartzCoreDemo[13476:13476] Problem posting
>>>> notification: <NSException: 0x15b53b8> NAME:NSInvalidArgumentException
>>>> REASON:[GSSizeValue-pointValue] should be overridden by subclass 
>>>> INFO:(null)
>>>> >>
>>>> >> CA is accessing -pointValue method if it determines that the passed
>>>> NSValue matches the -objCType of NSPoint. It does not check for size 
>>>> values.
>>>> >>
>>>> >> Clearly, sometimes it is trying to interpolate size values, which
>>>> will match the signature and it will incorrectly attempt to access
>>>> -pointValue which is then not implemented by GSSizeValue. I am not sure
>>>> where might it be interpolating size values, but it seems to be doing so.
>>>> (Alternative bug is that NSValue is incorrectly ingesting points as sizes,
>>>> then complaining when the point provided is being interpreted as a point. I
>>>> can try checking this later.)
>>>> >>
>>>> >> I cannot check -respondsToSelector: because the class /does/ in fact
>>>> respond to -pointValue; it just throws an exception.
>>>> >>
>>>> >> Adding a try/catch in this kind of situation would make for some
>>>> very poor code hygiene, in my opinion.
>>>> >>
>>>> >> - Is NSValue supposed to be a class cluster like this? (Not on Mac
>>>> at this time, can't check.)
>>>> >> - Is there a way out?
>>>> >> - Would it make sense to extend GSSizeValue and add -pointValue to
>>>> it? (They're both 2d vectors.)
>>>> >>
>>>> >> Thanks
>>>> >> _______________________________________________
>>>> >> Gnustep-dev mailing list
>>>> >> Gnustep-dev@gnu.org
>>>> >> https://lists.gnu.org/mailman/listinfo/gnustep-dev
>>>> >
>>>> >
>>>> > _______________________________________________
>>>> > Gnustep-dev mailing list
>>>> > Gnustep-dev@gnu.org
>>>> > https://lists.gnu.org/mailman/listinfo/gnustep-dev
>>>>
>>>>
>>>> _______________________________________________
>>>> Gnustep-dev mailing list
>>>> Gnustep-dev@gnu.org
>>>> https://lists.gnu.org/mailman/listinfo/gnustep-dev
>>>>
>>>
_______________________________________________
Gnustep-dev mailing list
Gnustep-dev@gnu.org
https://lists.gnu.org/mailman/listinfo/gnustep-dev

Reply via email to