Re: "-forwardInvocation:" like NSInvocation creation
Re: "-forwardInvocation:" like NSInvocation creation
- Subject: Re: "-forwardInvocation:" like NSInvocation creation
- From: Gwynne Raskind <email@hidden>
- Date: Wed, 31 Mar 2010 11:36:29 -0400
On Mar 31, 2010, at 2:26 AM, Philip Mötteli wrote:
>> Another alternative would be to combine method_getNumberOfArguments() and method_copyArgumentType() with ffi_prep_cif() and ffi_call(), which I think is what libobjc itself does these days. libffi is available since at least 10.5. Pass the method's IMP to ffi_call() and don't forget to adjust the call to ffi_prep_cif() for the hidden self and _cmd arguments.
> That's the way I would have to go, if I would have to re-implement, what Apple already has done for -forwardInvocation:. That's also, what GNUstep does. I think libffi or the other library, that has the same purpose, I forgot its name, are even made by GNUstep.
> It's just a pity, to reinvent the wheel. I mean, we're talking OO here, reuse of code and not continuous rewriting.
I would guess that they pulled direct support for it out of NSInvocation and the runtime API because 1) it involves parsing Objective-C type encoding strings, and 2) it's unsafe to save stack frames (more below). Based on some of the changes they made in the modern runtime and the consistent lack of complete documentation of the contents, I suspect they're trying to get people to consider encoding strings as entirely opaque objects, much like selectors.
I even tend to agree with the sentiment, as using them for a case like this has its pitfalls and difficult edge cases. One example would be having a forwarder which returns a structure which doesn't fit in a GPR or on PPC in general. objc_msgSend_stret() handles this by returning the structure in a hidden pointer parameter. The PPC ABI demands a memory allocation with a pointer passed in a specific GPR, i386 copies it on the stack, x86_64 can put it in a register or on the stack depending on size and ordering. I don't remember what arm does, but I'd guess offhand it makes use of the red zone for the purpose. Only the compiler knows for certain exactly what choice was made for any given situation, short of someone reimplementing the target ABI's logic.
Keep in mind that even if you get it working, from what your post said you're trying to save off a stack frame for later use. Any pointers and objects saved in the frame will have unpredictable lifetimes outside the forwarder call (even in functions called from it) unless very carefully managed. Under GC you'll have to allocate the memory for your ffi structures as scanned and collectable, or call retain on any passed-in objects under RR. Non-object pointers are just plain unsafe unless you can somehow guarantee their lifetimes for the existence of your saved frame; for exmaple, this would be just plain impossible if the forwarder were called with a parameter like "&addressOfLocalVariable". In the end it's rarely feasible to actually save a call for indeterminate future use outside the call. C and Objective-C are just too low level.
It's closely related to why it took so long for blocks to be implemented and why memory management questions about them keep cropping up.
-- Gwynne
Attachment:
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden