Forwarder

Stephen Pair spair at advantive.com
Wed Jul 25 17:43:19 UTC 2001


Anthony Hannan wrote:

>Stephen Pair <spair at advantive.com> wrote:
>> We must ensure that all references to self in the methods of a 
>> forwardee object are actually referring back to the instance of the 
>> forwarder (thus,references to the forwardee can be controlled).
>
>I assume your only doing this for identity since obviously the message
sends will come back to the 
>same forwardee.  But what about (Forwarder on: anObject) == anObject?
It will return false.  
>Changing identity just in the delagated method is not good enough.

Correct...however, for my purpose, it is good enough.  I'm only
maintaining references to the forwarder and the only reference to the
real object is in the forwarder.  If you have a reference to the
forwarder, why would you ever need to keep a reference to the real
object, except in the forwarder.

>Instead of trying to maintain references to the forwarder object in
method contexts, I think it
>would be more complete and simpler to just redefine the identity (==)
bytecode
>(bytecodePrimEquivalent) and class bytecode (bytecodePrimClass) to do a
normal message lookup if the
>receiver or arg is a Forwarder (for #==, switch the receiver and arg if
arg is the Forwarder). 
>Forwarder instances would understand just one message:
#doesNotUnderstand:, which would forward the
>message (including #==, and #class) to the forwardee and if that
message returns the forwardee or
>uses the forwardee so be it.  Any identity tests between the forwarder
and forwardee will return 
>true.

Hmmm...I'll have to think through that, but my instinct tells me that
such an implementation would be far more difficult and raise many
snafus.  I wasn't attempting to completely hide the existence of either
the forwardee or the forwarder (in fact, doing so would not work for my
application)...but rather, I was attempting to provide a reliable
mechanism for front ending any object, of any class with an identity
that allows the underlying object to change, thus avoiding the need for
a become...and that doesn't clutter up debuggers and such.

>If you want to free the forwardee and have all its references point to
the forwarder, you can use a
>become that uses forwarders as described by Martin McClure's recent
email.  object1 fowardBecome: 
>object2 would change the class of object1 to a Forwarder that points to
object2. 
>Changing the class of any object to a Forwarder would require a little
trickery (We would need two 
>Forwarder classes: CompactClassForwarder and NonCompacteClassForwarder.
Both would be variable 
>length to accomodate any object size.  object2 would be put in the
first slot and nil in the rest.  >Empty objects would have to fail
(Can't do nil become)).

My take on it was that you wouldn't want to have any references to a
forwardee in the first place (except in the forwarder)...but, if you
want to convert an existing object into one hidden by a forwarder, you
could copy the object, morph the class of the existing object into a
forwarder (and I think this could work with a single compact Forwarder
class...I don't think the VM will complain about looking up a class by a
compact index, or by a full class pointer...its just in the image that
things attempt to be converted one way or the other...I think), and
you're done...the only reference to the new real object is by the
Forwarder (and it's your business if you decided to use the real
object's identity).  If you want to swap identities of two objects, you
just do the same exact thing, except have the forwardee slots point
other object's new copy.

>Of course, when freeing the forwardee, you probably want to free it
from all pointer except the
>forwarder pointer.  In which case, you would change the forwarder to
point to a new copy of the
>forwardee before doing the forwardee become.

When you create the new copies, there won't be any references to them
(except in your method context as a temp)...no need to fix up any
pointers.

Also I think this design also allows for delegation...all that's needed
is a delegated send bytecode and/or primitive.  The forwarder is a
delegator (but it always blindly delegates everything it receives).
But, delegation would be fairly in-efficient in this design because you
would need to do an custom message look up and delegation in
#doesNotUnderstand: (or create methods whose only purpose is to
delegate)...what would really make it powerful is the ability to define
and plugin specialized message lookup algorithms.  I wonder if you could
desing the system such that the VM looks for a specialized lookup
algorithm in the Class, if it doesn't find one, it uses the default, if
it does find one (by finding a selector), it invokes that method to
locate the selector.  The custom "method lookup" method could optionally
be implemented as a primitive for better performance.  Anyway...I'm
rambling now.

- Stephen






More information about the Squeak-dev mailing list