gnustep-dev
[Top][All Lists]
Advanced

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

Re: corebase: use __builtin___CFStringMakeConstantString when available?


From: Stefan Bidigaray
Subject: Re: corebase: use __builtin___CFStringMakeConstantString when available?
Date: Wed, 28 Jun 2017 08:30:36 -0400

Hi Daniel, I guess I should throw my 2 cents in as I know the hacks I had to do in CoreBase in order to get constant CFStrings.

The files of interest will be Source/GSPrivate.h and Source/CFConstantString.c in the CoreBase sources.

GSPrivate.h defined a macro called CONST_STRING_DECL() that creates a constant string structure with the *isa = NULL. CoreBase is able to deal with the *isa pointer being NULL, but not it being a pointer to a structure that is "malformed".

At runtime, it mimics I had to mimic what the libobjc's did and assign the correct *isa for each string. This requires having a complete list of all constant strings and initializing them one-by-one at library load time. This is done in CFConstantString.c. The CFConstantStringInitialize() function is called by CFInitialize() when the library is loaded. I thought about doing what you're suggesting, somehow making a point to _OBJC_CLASS_* structures, but that ended up being a dead-end and not worth pursuing.

Unfortunately, I had to make CoreBase somewhat dependent on various implementation details, for many reasons. In this case, library load times are important, since libobjc and -base need to be up and running before CFConstantStringIntialize() is called. The problem with using __builtin_CFStringMakeConstantString() is that it is equivalent to @"", and this was a problem for me at the time because it would cause the toll-free bridging mechanism to be constant called, unnecessarily.

As you'll quickly see, all this stuff is private to CoreBase, so you'd either have to expose this functionality or come up with your own constant string solution. I wouldn't have a problem exposing it, even though I would rather keep my messy hacks "private".

I think I should also mention that there is nothing in CoreBase that makes it inherently dependent on -base or libobjc. At the time I was still actively working on CoreBase, the need arose for a pure-C base library that was familiar to me. Since I had already done some work with GNUstep and understood the paradigms it made sense to make this so. That was around the time I reimplemented all the toll-free bridged CF-types in C instead of relying on -base's implementations. By modifying the makefile, you can still built a pure-C version on CoreBase, by the way. I'd like to keep it that way.

Hope this helps! And I apologize for taking so long to reply to your email.

Regards
Stefan

On Tue, Jun 27, 2017 at 8:19 PM, Daniel Ferreira (theiostream) <address@hidden> wrote:
Hmm, bad news about this.

Here's the commit that enables this feature on CoreBase, for some
context on what I'll discuss next:
https://github.com/theiostream/corebase/commit/98d799a6de056f1b99fa9a218a0f354f613ba578.

Sadly, simply switching CFSTR() from __CFStringMakeConstantString() to
__builtin___CFStringMakeConstantString() doesn't just work
out-of-the-box. Both clang and gcc generate, out of that builtin, a
struct that "fits" into CFStringRef's spec, but there is one tricky
detail. Its "isa" member is set on compile-time to a pointer tracked
by the __CFConstantStringClassReference symbol.

The symbol itself would not be a problem. We could just point it on
compile-time to null bytes and pretend that never existed (as Apple
seems to do on CFLite). But CoreBase totally relies on that "isa"
member having something meaningful, and it'll pretty much always
forward that null "isa" to libobjc2 to try to figure out the CFType of
that constant string. This broken "isa" will crash libobjc2.

That said, I need a way to place a valid Objective-C class definition
in that symbol on compile-time (probably it'd be an empty subclass of
NSCFString), but I'm totally unaware of any way to do that. Or maybe
make that point to an ordinary _OBJC_CLASS_* symbol somehow. Any
hints?

Otherwise, the other way I can see to implement this is to check if
the "isa" member is a pointer to __CFConstantStringClassReference
every time we try to do something with it. But that'd require a bunch
of changes to CoreBase, Base, and would likely leave behind a lot of
bugs, so I'm really not into this.

Also, Apple's "workaround" on CFLite and CFNetwork for compilers that
don't support this builtin is to simply build the CFString struct by
hand -- still relying on __CFConstantStringClassReference as an isa.
So that'd break CoreBase as well.

If we choose not to implement this right now due to the complexity
being too large, I suppose I *can* export these constant strings as
Objective-C string literals. But it'd still be weird for a CF-only
library to rely on ObjC to export its CFStringRefs. :(

-- Daniel.

On Tue, Jun 27, 2017 at 6:32 PM, Ivan Vučica <address@hidden> wrote:
> The test should be done similarly, though: test for the feature rather
> than the compiler.
>
> On Tue, Jun 27, 2017 at 9:15 PM, Fred Kiefer <address@hidden> wrote:
>> I agree that we should add this feature, but from looking at the actual code I don’t think it will help us.
>> The feature seems to be only present in gcc on Darwin with the Next, that is old Apple ObjC, runtime. We should rather be looking for a way to convince the gcc people to enable this on more platforms.
>> This shouldn’t be much of a limitation for Daniel as he will be using clang anyway.
>>
>> Fred
>>
>>
>>> Am 27.06.2017 um 19:34 schrieb Ivan Vučica <address@hidden>:
>>>
>>> It seems sane, and you should update corebase's autoconf to detect presence of this compiler built-in.
>>>
>>> That is: an installed header should be generated and contain a constant describing whether CFStringMake...() is present.
>>>
>>> On June 27, 2017 5:32:04 PM GMT+01:00, "Daniel Ferreira (theiostream)" <address@hidden> wrote:
>>> Hi,
>>>
>>> I'm currently working on developing a CoreFoundation-based library
>>> with CoreBase, and I just realized that unlike in OSX, CFSTR() does
>>> not generate a compile-time CFStringRef constant.
>>>
>>> This is fine compatibility-wise since CFSTR() does not guarantee that
>>> it will do so -- in fact, Apple's own CoreFoundation headers check if
>>> we are on Linux and if that is the case, it does not enable this
>>> compile-time feature.
>>>
>>> However, as far as my (extremely brief) investigation went we can
>>> generate compile-time CFStringRefs using
>>> __builtin___CFStringMakeConstantString(), which is present since this
>>> gcc commit[1] and since forever in clang. So it makes sense to me that
>>> this should not be platform-dependent, but rather compiler-dependent.
>>>
>>> This helps because I need to export some CFStringRefs as symbols in a
>>> new lib for WebKit compatibility, and without this feature I'd be left
>>> with the option to either:
>>> a) create an Objective-C file in a C-only library just for exporting NSStrings;
>>> b) make a bizarre __attribute__((constructor))-like thing to
>>> initialize the constant strings onto the symbols on library load.
>>>
>>> Does this seem sane? If so, I need a tip in how to guard for this
>>> builtin in gcc.
>>>
>>> -- Daniel.
>>>
>>> [1]: https://github.com/gcc-mirror/gcc/commit/d4238e8bcce578381de9480d78a651830a8f9754,
>>> looks like it was added in gcc 5.3.
>>>
>>>
>>> Gnustep-dev mailing list
>>> address@hidden
>>> https://lists.gnu.org/mailman/listinfo/gnustep-dev
>>>
>>> --
>>> Sent from my Android device with K-9 Mail. Please excuse my brevity.
>>> _______________________________________________
>>> Gnustep-dev mailing list
>>> address@hidden
>>> https://lists.gnu.org/mailman/listinfo/gnustep-dev
>>
>>
>> _______________________________________________
>> Gnustep-dev mailing list
>> address@hidden
>> https://lists.gnu.org/mailman/listinfo/gnustep-dev
>
> _______________________________________________
> Gnustep-dev mailing list
> address@hidden
> https://lists.gnu.org/mailman/listinfo/gnustep-dev

_______________________________________________
Gnustep-dev mailing list
address@hidden
https://lists.gnu.org/mailman/listinfo/gnustep-dev


reply via email to

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