[Openmcl-devel] New snapshots available

Gary Byers gb at clozure.com
Fri Feb 16 02:02:24 UTC 2007



On Wed, 14 Feb 2007, Phil wrote:

>
> On Feb 14, 2007, at 7:18 PM, Gary Byers wrote:
>
>> 
>> 
>> On Wed, 14 Feb 2007, Phil wrote:
>> 
>>> Gary,
>>> 
>>> Great to see progress on supporting Leopard/Obj-C 2.0.  I did have a 
>>> couple of questions re: the release notes...
>>> 
>>> On Feb 14, 2007, at 5:32 AM, Gary Byers wrote:
>> The bug that I'm aware of has to do with the fact that SEND considers
>> the set of method type signatures in effect when it's used to be closed,
>> so if "foo" is a message declared to return :int at some point in time,
>> a (SEND x 'foo) will compile to something that expects an integer
>> to be returned and doesn't expect any sort of ambiguity.
>> 
>> If new interfaces are loaded (after that first SEND was compiled) and
>> some disjoint class defines a method on FOO that returns :FLOAT, then
>> any subsequent SEND -should- consider the message to have an ambiguous
>> type signature and should expand into code which does runtime typechecking
>> of the receiver and does a CASE or COND or something to select the
>> right implementation.
>> 
>> The original SEND - compiled in a simpler world - won't get recompiled.
>> 
>> Is this what you're referring to ?  Or are there other cases which
>> lose ?
>> 
>
> That would be the issue as I've generated CDB's for many additional 
> frameworks which work flawlessly for all methods which don't result in the 
> ambiguous return type scenario.  All releases I've tried including OpenMCL 
> 1.1-pre-061024, do not appear to be successful in performing the runtime 
> check so, effectively these ambiguous methods become uncallable.

Hmm.  Could you give me an example of something that fails once
ambiguity is introduced ?

I did run into (and hopefully fixed) one case where the type dispatch
wasn't the correct way of resolving ambiguity.  Many methods are
defined on some "Protocol" rather than on a class or metaclass, and
classes that conform to a Protocol inherit that Protocol's methods.
It's possible for a given message to have methods that're defined
on both classes and on Protocols, and for those methods to have
different type signatures.  Any dispatching code has to figure out
whether a Protocol or class method is applicable in that case (at
most one method can be applicable.)

>
>>> 
>>>> - The ObjC bridge has had a long-standing bug whereby a standalone
>>>>  Cocoa application may have needed to find the interface databases
>>>>  at runtime in order for MAKE-OBJC-INSTANCE and MAKE-INSTANCE of
>>>>  an ObjC class to work.  (These functions needed to be able to
>>>>  send an "init" message to the newly-allocated instance, and needed
>>>>  to know the type signature of that init message in order to do that.)
>>>>  The current scheme tries to avoid this by pre-compiling helper
>>>>  functions to enable calling all known "init" message signatures.
>>>>  (More accurately, all fixed-argument "init" message signatures.)
>>>>  This scheme avoids the need to send messages whose argument
>>>>  and result types are computed at runtime (via %SEND), and %SEND
>>>>  (a) was known to be inefficient and (b) would have a lot of
>>>>  difficulty handling all known structure return/passing conventions
>>>>  on supported platforms.  Accordingly, %SEND has been deprecated
>>>>  (with extreme prejudice, e.g., removed.)
>>> 
>>> Ugh... I was using %SEND.  Is there a way to accomplish the following 
>>> without %SEND: take an arbitrary object (unknown at compile-time), either 
>>> look at the type of the object or a list of methods for the object, and 
>>> call a series of methods belonging to a list or matching a pattern?
>> 
>> Yes (at least in theory); the general idea would be to do something
>> similar to what's done for "init" methods now (try to map a signature
>> to a compiled helper function that knows how to do ff-calls of that
>> signature, maybe create that function at runtime if it didn't already 
>> exist, and funcall the helper function.)
>> 
>> %SEND basically tried to build the arguments to to CCL:%FF-CALL and
>> call it.  That worked reasonably well on ppc32 Darwin (it was at
>> least Turing-complete), since sending a message ultimately just
>> involved doing a foreign function call and making sure that the
>> arguments and result wound up in the right place.  On other platforms,
>> dealing with structure arguments/return values requires a lot of
>> additional complexity wrapped around the (simple) foreign function call,
>> and it'd be difficult for %SEND (or something like it) do decide what
>> to wrap around that call and how to do it.
>
> Thanks for the information... I didn't realize that %SEND would cause such 
> grief on other platforms.  I'll look into going the helper function route.
>
To see what I mean, try the following on a PPC64 Darwin system:


? (def-foreign-type :rect
    (:struct :rect
      (:x :int)
      (:y :int)
      (:width :int)
      (:height :int)))

? (pprint (macroexpand '(ff-call inset_rect result :rect r :int delta :rect)))


All of this stuff that SEND does (dispatching on the class of the
receiver to select an appropriate method, where "method" basically
means "means of doing an ff-call" as well as the effect of doing that
call) is embarrassingly similar to CLOS generic-function dispatch.
Introducing a new type signature to an ObjC message would be (vaguely)
like adding a method to a generic function (and that might change the
generic function's dispatching/discriminating code a bit, which has
the same effect as introducing a CASE clause in SEND.)

A couple of years ago, Randall Beer and I were talking about the
idea of using a specialized form of generic function to send ObjC
messages.  I think that we may have taken an overly complicated
approach to this, at least partly because we wanted to find an
alternative to typing long, strange-looking function names.

(One advantage of sticking with long strange-looking function names
would be that there's be a 1:1 correspondence between (for instance)
NS:INIT-WITH-FRAME$TEXT-CONTAINER$ and the documented message
"initWithFrame:textContainer:".)

There are a lot of details to be worked out (some of which Randall
may have worked out a few years ago in some disabled code in the
bridge), but there are some advantages to viewing message-sends as
a (limited) kind of generic-function call.






More information about the Openmcl-devel mailing list