discuss-gnustep
[Top][All Lists]
Advanced

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

Re: problems with forward invocation (gcc bug?)


From: Wim Oudshoorn
Subject: Re: problems with forward invocation (gcc bug?)
Date: Tue, 31 Jul 2001 12:58:54 +0200

> If ffcall is not in use, the runtime still calls forward::
> so the code in NSObject is there to handle that.

However, this means that if user code implements
- forward::
it will behave differently if GNUstep is compiled
with or without ffcall.
I think that the OpenStep API does not specify
if -forward:: is called or not, but I am not sure.

>
> I think this is really a compiler bug ... the compiler should know
> how the method is being called, so it should generate the correct
> type information.
> IMO the types supplied by the compiler should
> always reflect the actual arguments passed and return type expected
> by the compiled code.

This might not possible.  We know that -cString returns a (char *)
but the offending line said:

[x cString];

And if the compiler only knows that x is of generic (id) type.
How can it know what the return type of cString is supposed to be?
Combine this with the fact that you can store a selector:

SEL s = @selector (aMethodWithSomeArguments::::);

How does the compiler know what type info to generate?

So the only solution I see is to assume that the
return type for all selectors with the same name
is identical (at least from the ffcall point of view).
And if not, well issue a warning and good luck to you.

> > For this problem there is a rather trivial fix, namely
> > in the function `GSInvocationCallback' refetch
> > the selector if it has no type information.
> > (the GNU objc runtime provides methods to
> > get a selector with type information)
>
> While this would (mostly) work, it could fail if there are two classes
> with methods of the same name but different signatures, since the type
> signature selected may not match that of the method eventually called,
> or it may not match the arguments/return type expected in the compiled
> code, or both!.

I think that as long as the return types are the same
(well, as long as vacall can pop off the arguments)
we can work around it.
Namely in the GSInvocationCallback
- popoff the receiver
- popoff the selector
- lookup in the selector table for the
  class of the receiver the typed information
  (or in the case of DO forward the request.)

I noticed that someone added a patch to retrieve the selector
if it does not have typeinfo.  But the fix is incomplete.
The same procedure should be follewed with the selector that
is popped from the stack (halfway in the same function)


> An additional problem arises with Distributed Objects, the class to which
> the message is being sent may not exist in the process, so the runtime
> may not have any typed version of the selector at all!  In this situation
> a methodSignatureForSelector: message should be sent to the object in the
> remote process in order to find out what signature it expects - but the
> existing code can't do that because it needs to send the message to the
> receiver, but it can't unpack the receiver from the stackframe without
> knowing what the return type is.

But this would work (I think) because both sides NOW the method
  methodSignatureForSelector:
So this call would work.  The problem only arises when
one process does not have the selector at all.

> To workaround this without the compiler
> being fixed to provide the calling signature, we would need to modify the
> runtime to call gs_objc_msg_forward() with two parameters (receiver and
> selector), not just with the selector.  Then gs_objc_msg_forward could
> ask the receiver for its method signature, and use the resulting type
> information.

Yes!

> A simple pool of wrappers would be a bit inefficient ... it would have
> to be
> a map table protected by a lock.  A more efficient solution would be to
> have
> a small number of wrappers (one for each of the common return types) and
> use
> a lock protected pool only for methods with unknown or complex return
> types.

What I basically meant was the following:

keep GSInvocationCallback almost the same as it is,
only store in callback_data argument NOT the selector
but the alignment and size (needed for the vacall_start)

Now create a table/array/map of
ff_callback objects for each combination of the
(alignment/size) pair that is needed.
This can not be statically, because you do not know
what structs you will encounter.

So gs_objc_msg_forward should figure out the return
type data (alignment/size) and lookup theff_callback
object. If it does not exist, create the static data,
create a new ff_callback object, add it to the
table/array/map of ff_callback objects and return it.

This should keep the table small, because it only
stores creates objects for the (alignment/size).
(So probably no need for freeing unused entries)
And I can only detect a potential lock when an entry
is added. But I do not really  know anything about
multithreading.

After rereading your reply, this is basically what
you suggested (I think).



Wim Oudshoorn



reply via email to

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