Anonymous primitives?

Stephen Pair spair at advantive.com
Thu Aug 23 13:21:47 UTC 2001


Rob,

Here is a small example that should illustrate how this kind of
chicanery can mess up the caller's stack.  Install these on any object,
then trying invoking exampleFailure.  You should get a
MessageNotUnderstood error on #show:and: even though clearly your object
implements that method.  This is because the stack was left unbalanced
by calling the primitive with the incorrect number of arguments, and
thus #show:and: is being sent to the wrong object (not self).  If you
are aware of the issue, you can work around it, but I wouldn't build
mission critical systems using this technique:

-----
exampleFailure

	self 
		show: 10 
		and: (self obj: (Array with: 8) at: 1)
-----
show: anObject and: anotherObject

	Transcript show: anObject printString; cr.
	Transcript show: anotherObject printString; cr.
-----
obj: anObject at: index

	<primitive: 60>
-----

- Stephen


> -----Original Message-----
> From: squeak-dev-admin at lists.squeakfoundation.org 
> [mailto:squeak-dev-admin at lists.squeakfoundation.org] On 
> Behalf Of Rob Withers
> Sent: Thursday, August 23, 2001 8:59 AM
> To: squeak-dev at lists.squeakfoundation.org
> Subject: Re: [Anonymous primitives?] Re: [GOODIE] Delegation 
> and Self like things for Squeak
> 
> 
> I thought that that's what you were doing.  It is interesting 
> that we can invoke an arbitrary primitive against any 
> combination of receiver args, including one that has the 
> wrong number of arguments.  I'm not sure what that would do 
> to the stack either, but I presume it will be safe.
> 
> My problem:  I don't want to have to add methods to a proxy, 
> so that it can be as thin in protocol as possible.  Ideally 
> it shouldn't understand any protocol, because it is there 
> only to redirect sends.  Granted, there are system 
> requirements that it understand some protocol, at the moment.
> 
> In order to do this, yet still use the proxy Oop as the 
> receiver, we have to approach the proxy from the side.  We 
> don't want to send a message to the proxy because that would 
> only forward the send to its target.  Therefore, I was asking 
> if there was a way to invoke a primitive on the proxy - with 
> it as the receiver as far as the primitive is concerned - 
> without sending a
> message to it.   The answer seems to be that you would have a method,
> defined as a block or class-side method, that you 
> hand-crafted to setup the primitive call with bytecodes as if 
> it was a message send.  So on the class side of Object, we have
> 
> Object class>>invokePrimitive: primNumber withReceiver: 
> receiver arguments: argArray
> 
>     self pushObject: receiver.
>     self pushArguments: argArray.
>     self invokePrimitiveWithoutTouchingStack.  "Don't push a 
> new receiver. The one we want is there already"
>     self popResult.
> 
> Mark mentioned that he can do this in a block and uses the 
> block arguments as the receiver and arguments to the 
> primitive.  Now that's pretty cool!
> 
> Sorry for the confusion,
> - Rob
> 
> ----- Original Message -----
> From: "Bob Arning" <arning at charm.net>
> To: <rwithers12 at mediaone.net>; <squeak-dev at lists.squeakfoundation.org>
> Sent: Thursday, August 23, 2001 8:14 AM
> Subject: Re: [Anonymous primitives?] Re: [GOODIE] Delegation 
> and Self like things for Squeak
> 
> 
> On Thu, 23 Aug 2001 01:32:51 -0400 "Rob Withers" 
> <rwithers12 at mediaone.net>
> wrote:
> >Bob and Mark, I was thinking closest to what Mark posted I suppose,
> although
> >I forgot to consider that you would have to declare the 
> types in order 
> >to have multi-methods; I don't think that fits well in 
> Smalltalk model 
> >(explicit types are bad - it binds early?), but couldn't it be type 
> >inferenced by usage?  However, the idea of using the 
> compiler to create 
> >a BlockContext which is marked as a primitive is an 
> interesting take.  
> >As Stephen points out, we could setup the bytecodes by hand:
> >    push the first arg as the receiver
> >    push the second arg as the primitiveAdd arg
> >    invoke the primitive
> >    pop the stack
> >
> >Bob, in your suggestion, why would the stack be bloated?
> 
> I don't know that it would be, but I must admit that I don't 
> clearly understand the problem and offered my suggestion 
> simply to point out that a primitive could be invoked for any 
> combination of receiver/arguments. Whether it solves the 
> problem at hand I don't know.
> 
> Cheers,
> Bob
> 
> >- Rob
> >
> >Bob Arning wrote:
> >> Object>>primitive1ForAnyObject: as
> >>
> >> primitive1ForAnyObject: arg
> >>
> >> <primitive: 1>
> >
> >Mark van Gulik wrote:
> >> b ::= [x:integer, y:integer |
> >> Primitive 1;
> >> Crash "It didn't work";  /* in case of failure */
> >> ] : integer;
> >> Print b(3,4);
> 
> 
> 
> 
> 
> 





More information about the Squeak-dev mailing list