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: Daniel Ferreira (theiostream)
Subject: Re: corebase: use __builtin___CFStringMakeConstantString when available?
Date: Wed, 12 Jul 2017 15:31:48 -0300

I was just browsing swift-corelibs-foundation by accident (to see
something totally unrelated) and I just ran into how it solves the
issue. It uses a linker feature I did not even know existed to use a
"symbol alias list". It does exactly what I'd wondered if it were
possible – mapping an actual class symbol (their "NSCFConstantString")
into __CFConstantStringClassReference.

It passes `-Wl,-alias_list,SymbolAliases` to the linker, and
`SymbolAliases` contains
https://github.com/apple/swift-corelibs-foundation/blob/19249417b01573bd6aa32b9a24cc42273315a48b/CoreFoundation/Base.subproj/SymbolAliases#L4.

Any change CoreBase could make use of this?

-- Daniel.

On Wed, Jun 28, 2017 at 9:30 AM, Stefan Bidigaray <address@hidden> wrote:
> 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]