discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: libs-corebase: NS/CFNumber bridging crashes with small objects


From: Frederik Seiffert
Subject: Re: libs-corebase: NS/CFNumber bridging crashes with small objects
Date: Fri, 8 Nov 2019 20:24:48 +0100

Hi Stefan,

When I wrote all that stuff, I honestly wasn't even thinking about small objects. That being said, the facilities to interact with Objective-C objects is there.

Having a quick look at the code, however, it looks like toll-free bridging was never implemented for CFNumber. 

That’s what I suspected (although toll-free bridging for CFNumber seems work fine for non-small objects). I’d appreciate if you could take a look how to enable small objects support for CFNumber. We have some 3rd party code that runs into this, and I’m trying to keep GNUstep-specific changes to a minimum.

Something to keep in mind: The toll-free bridging mechanism in GNUstep is not as seamless as the one in Cocoa. It would take a lot of extra development to beat it into shape, so major bugs are bound to exist.

Can you elaborate on what kind of cases are expected to work or not work, and which areas would need work? In my limited testing it seemed like the basics were working, but I didn’t spend too much time with it yet.

Thanks again,
Frederik


Am 08.11.2019 um 15:33 schrieb Stefan Bidigaray <stefanbidi@gmail.com>:

When I wrote all that stuff, I honestly wasn't even thinking about small objects. That being said, the facilities to interact with Objective-C objects is there.

Having a quick look at the code, however, it looks like toll-free bridging was never implemented for CFNumber. Essentially, every function needs a CF_OBJC_FUNCDISPATCHV call to the equivalent ObjC method + a NSCFNumber class needs to be created. Shouldn't be too hard, but I won't have time to get a better look until this weekend. There's also the OBJC_SMALL_OBJECT_MASK macro in objc/runtime.h that can be used to figure out if we're dealing with a small object. The ObjC dispatch macro should take care of all cases, though.

Something to keep in mind: The toll-free bridging mechanism in GNUstep is not as seamless as the one in Cocoa. It would take a lot of extra development to beat it into shape, so major bugs are bound to exist.

Regards
Stefan

On Fri, Nov 8, 2019, 07:58 David Chisnall <gnustep@theravensnest.org> wrote:
Hi,

There are a few different representations of numbers in the small object
representation.  On 32-bit platforms, there is only small int, which has
the low bit set to 1 and stores a 32-bit integer in the remaining bits.
On 64-bit platforms, the low 3 bits indicate the type, with the
following values:

0: Object pointer
1: Small int (61-bit integer)
2: Small extended double (64-bit double, where the low bits of the
mantissa are represented)
3: Small repeating double (64-bit double where the low bits are a short
repeated pattern.
4: Unused
5: Tiny string (8 7-bit ASCI characters, plus length).
6: Unused
7: Unused

The numerical representations are defined in NSNumber:

https://github.com/gnustep/libs-base/blob/280b2cbe834007fa7945d783f3a538ecbaab52b5/Source/NSNumber.m#L374

https://github.com/gnustep/libs-base/blob/280b2cbe834007fa7945d783f3a538ecbaab52b5/Source/NSNumber.m#L436

The tiny string representation is defined in GSString.m:

https://github.com/gnustep/libs-base/blob/dd368559230c485b1234695673f21b2269caca09/Source/GSString.m#L778

Note that, with the 2.0 ABI, the GSTinyString representation is emitted
by the compiler and so are considered part of the stable ABI.  The other
number representations are not and are considered internal to the -base
implementation and may change between versions.  I believe CoreBase is
version locked to base, so that isn't a problem.

The code in CoreBase will need updating to check for the small number
representation.  I'd be inclined to do this by moving some of the code
from NSNumber.m and GSString.m into a private header that can be shared
between base and CoreBase.

David

On 08/11/2019 11:18, Frederik Seiffert wrote:
> Hi all,
>
> I found that toll-free bridging of NSNumber to CFNumber crashes when
> using a "small object" (aka tagged pointer):
>
> NSNumber *num = @(42);
> NSLog(@"Type: %ld", (long)CFNumberGetType((__bridge CFNumberRef)num));
>
> Crashes like this:
>
> * thread #1: tid = 27602, 0x00007fe328027ba0
> libgnustep-corebase.so.0`CFNumberGetType
> [inlined] CFNumberGetType_internal(num=0x0000000000000151) at
> CFNumber.c:204, name = 'test', stop reason = invalid address (fault
> address: 0x15b)
>      frame #0: 0x00007fe328027ba0
> libgnustep-corebase.so.0`CFNumberGetType
> [inlined] CFNumberGetType_internal(num=0x0000000000000151) at CFNumber.c:204
>     201 CF_INLINE CFNumberType
>     202 CFNumberGetType_internal(CFNumberRef num)
>     203 {
> -> 204   return (CFNumberType)num->_parent._flags.info <http://flags.info>;
>     205 }
>     206
>     207 CF_INLINE CFIndex
>
>
> Note that 0x151 is a small int object for 42. Replacing 42 with e.g.
> INT_MAX (which doesn’t fit in a small object) makes the code work fine.
>
> Could anyone with knowledge of the corebase / small objects internals
> take a look at this, or point me in the right direction how to fix this?
>
> Related, there currently doesn’t seem to be a way to report bugs on
> corebase. Would it be possible to enable the bugtracker for the corebase
> GitHub project?
>
> Thanks!
> Frederik
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]