[Openmcl-devel] New snapshots available
gb at clozure.com
Thu Feb 15 21:02:24 EST 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:
>>> 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
? (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
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