This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [libobjc] fix to nil_method


> This lookup function is supposed to return the function to call to execute
> the method ('doSomething:' for the object 'object' in the example).  In
> the declaration of the lookup function, the value returned is of type IMP
> - the idea of the definition of IMP is to return a 'general function
> taking an id, a SEL, followed by other unspecified arguments'.
> 
> The value returned is casted by the compiler to a pointer to a function
> taking the appropriate number of arguments for that *specific* method ...
> extracted by the declaration of the method ('doSomething:') as seen by the
> compiler in the class @interface; in the example, probably the function is
> casted to be something like void doSomething_impl (id receiver, SEL
> selector, id argument); assuming the method doSomething: returns void, and
> takes an id argument.
> 
> The function pointed to by the pointer is executed, passing the receiver,
> selector, and arguments of the method, in this order.
> 
> As you see, the 'IMP' declaration is never actually used to call a
> function.  The lookup function returns an IMP, which is just a generic
> placeholder for a function pointer, it just means it returns a pointer to
> a function implementing a method - this function takes a receiver, a
> selector, and other unspecified arguments; but it should be casted to the
> actual appropriate form with the appropriate number of arguments before
> being called.
> 
> This is what user-code manually looking up methods should also do
> (background - in some cases you can optimize your end-user code by
> manually looking up method implementation, and caching the method
> implementations, then calling them manually and directly shortcutting the
> method lookup - useful in loops) - before invoking a method implementation
> as returned by the lookup function, it should cast it to a pointer to a
> function taking the appropriate arguments.
> 
> 
> Now, the nil_method thing is a trick built on top of all this to
> implement the behaviour required by ObjC for nil receivers.
> 
> When the receiver of a method call is 'nil' (the null object), the
> semantics is supposed to be that nothing happens and the method call
> returns (id)nil ['id' means 'an object', 'nil' means 'the null object'].  

Yes, thats what I've supposing it to mean. However it is not variadic
function, as variadic function may have special properties at caller
side (ie expects caller to set up things friendly for variable argument
parsing).

Then I believe my patch is right and the IMP prototype slightly
missleading.  I believe the proper prototype of IMP should be just K&R
style function without specified arguments and there is no "proper"
implementation of nil_method in C, however in all existing
implementations it does not matter when extra arguments are present, so
we can simply ignore them.
Then I believe my patch is correct.

THanks for explanation, it scheds a lot of light to objc for me :)

Honza
> A huge amount of user code relies on this behaviour.  It is normally used
> for methods returning void (then calling them with a nil receiver simply
> does nothing), or returning an object (then calling them with a nil
> receiver returns a nil result).
> 
> The way in which this is implemented in the GNU runtime is - the lookup
> function objc_msg_lookup () checks if the receiver is nil; and if it is,
> it returns a pointer to the special function 'nil_method ()'.  
> 'nil_method ()' is a function which does nothing, and returns nil.
> 
> Then, the normal method invocation flow goes on as normal - the nil_method
> () function will be casted to whatever function was supposed to be
> executed to execute that method (that function will take an id, followed
> by a SEL, followed by who knows what arguments, depends on the method),
> and executed.
> 
> Apparently, the usual definition of nil_method () can support this
> behaviour on usual machines, and the problem you get is because the usual
> definition doesn't work on your machine. :-(
> 
> So, it looks to me that the fix should consist in implementing the
> 'nil_method ()' function so that it can be called in place of any function
> taking an 'id' argument followed by a 'SEL' argument, followed by zero, or
> one, or any number of arguments (both a fixed number, or a variable number
> !).
> 
> If declaring it to take just an 'id' then a 'SEL' argument is enough to
> get this result (I suppose it depends on how function calls are
> implemented/compiled, about which I don't know much at the moment) - as in
> Honza's patch, then it's fine for me and the patch looks good.  If not,
> then the patch is not good.
> 
> Anyway I hope I explained the ObjC machine enough to let the
> stack/function calls/etc hackers find a way to fix it ... :-)
> 
> Please note again that the 'declaration' of the 'nil_method()' function
> will *never* be used at runtime in the running program.  It is only
> checked by the compiler when compiling libobjc, in objc_msg_lookup() so
> that nil_method() can be returned without warnings, it must be an IMP, but
> it's irrelevant - we can cast it to an IMP inside objc_msg_lookup().
> 
> Sorry for being long, but I hope it helps.
> 
> I might have got something incorrect as I didn't have time to actually
> examine the compiler and the runtime library, and was talking by heart and
> memories, so if something doesn't match my description, the description
> might need a slight amending.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]