discuss-gnustep
[Top][All Lists]
Advanced

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

Re: Which ObjC2.0 features are missing in the latest GCC?


From: H. Nikolaus Schaller
Subject: Re: Which ObjC2.0 features are missing in the latest GCC?
Date: Mon, 25 Nov 2019 15:07:04 +0100

> Am 25.11.2019 um 12:09 schrieb David Chisnall <gnustep@theravensnest.org>:
> 
> On 25 Nov 2019, at 10:18, H. Nikolaus Schaller <hns@goldelico.com> wrote:
>> 
>> Fred mentioned that it could be possible to define some block wrapper macros 
>> if some time is invested.
>> It that works out, we do not make our decisions depend on gcc *not* 
>> implementing something.
> 
> Fred made this claim, but he also added the caveat that it would likely be 
> limited to blocks with no captures.  In this, I believe that he’s right.
> Consider this trivial compilation unit:
> 
> ```
> @interface X
> - (void)doSomething;
> @end
> 
> typedef void(^block)(void);
> 
> block callMethodOn(id x)
> {
>       return ^() { [x doSomething]; };
> }

That is indeed a challenge.

To show how it would be used:

block b = callMethodOn(object);

b();    // void return, void arguments should do [object doSomething];

> ```
> 
> A few things to notice:
> 
> 1. This single function generates 4 functions.
> 2. The copy and dispose helpers have to understand the offset of each of the 
> captures.  This is fairly simple in this example, because there’s only one 
> capture.
> 3. To avoid bloating the binaries, the copy and destroy helpers have 
> well-known names and COMDATs, so the linker can eliminate duplicates.
> 4. The memory management around creating the block and its captures is 
> non-trivial.  Note that this is compiled with ARC, blocks for Objective-C 
> implement a subset of ARC even in non-ARC mode because getting the memory 
> management right was considered too hard.
> 
> If, every time you want to write something as simple as the original 
> Objective-C source, you have to write something as complex as the LLVM output,

I am not sure that this is the only way to implement it.

First of all the callMethodOn returns some block which is a data structure 
knowing that it should take the parameter x and do some function.
Let's call it NSBlock. NSBlock can be an ordinary object like any other so that 
it can follow the same memory management rules as used otherwise.

So a first draft (without being able to think about all exceptions and corner 
cases - it is impossible to catch up years of clang development in minutes), 
what about translating this to:

> @interface X
> - (void)doSomething;
> @end

typedef NSBlock *block;

block callMethodOn(id x)
{
        fn(id x) { [x doSomething]; }
        NSBlock *b=[NSBlock new];
        [b setParameterList:x]; // use va_list or NSInvocation something - can 
retain the object x
        [b setFunction:fn];
        return block;
}

Then you can do

[block run]

assuming that NSBlock has a -run method (and perhaps a runWithArgs) which does

([self function])([self parameterList])

I haven't worked out all details but it might be possible to put that all into 
wrapper macros
that either translate into ^ notation or into some ObjC code as sketched above.

Yes, syntax is then a little more complex than the ^notation.

Just some idea and Fred may comment on what he had in mind.




reply via email to

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