binary selectors ambiguity and space

John M McIntosh johnmci at
Wed May 17 22:37:30 UTC 2006

Likely it's constructive to use the source, er Tim, so lets consider  
what + really does...

foo := 1 +  2  compiled results in bytecodes

5 <76> pushConstant: 1
6 <77> pushConstant: 2
7 <B0> send: +
8 <68> popIntoTemp: 0

For other forms it would be pushOops, pushOops,  + and popIntoSomething.

The bytecode prim is on Interpreter>>

"normally you think we would invoke the message send, but that is  
slow, we want to avoid that if we are dealing with special cases, like
SmallIntegers or Floats,
We grab the two values off the stack then see if both are integers,  
if so we
add them together, then see if the result is still a SmallInteger, if  
so  we pop the stack and push the result, and process the next byte  
code, we are done.
If one or more of the parms are not SmallIntegers we attempt to do a  
floating point add, which loads the values as Double Float or  
converts from
SmallInteger to Double Float. If that fails we end up scheduling a  
proper message send of '+' to the receiver.

Note how we at the end pop the 2 values off the stack then push the  
result onto the stack, then after bytecode finishs the top item on  
the stack is
the value we store somewhere, like back into an instance variable,  
class variable, temporary slot...

	| rcvr arg result |
	rcvr := self internalStackValue: 1.
	arg := self internalStackValue: 0.
	(self areIntegers: rcvr and: arg)
		ifTrue: [result := (self integerValueOf: rcvr) + (self  
integerValueOf: arg).
				(self isIntegerValue: result) ifTrue:
					[self internalPop: 2 thenPush: (self integerObjectOf: result).
					^ self fetchNextBytecode "success"]]
		ifFalse: [successFlag := true.
				self externalizeIPandSP.
				self primitiveFloatAdd: rcvr toArg: arg.
				self internalizeIPandSP.
				successFlag ifTrue: [^ self fetchNextBytecode "success"]].

	messageSelector := self specialSelector: 0.
	argumentCount := 1.
	self normalSend


A few years back I considered what if they are large integers in the  
range of +- 2 billion and the result was a 32  bit integer, could we  
load as 32bit integers, do the math and store a smallInteger result  
or convert to largeInteger? I did write some code for that, but it  
was deemed a bit too specialized and really what application would  
need it?

On 17-May-06, at 11:34 AM, tim Rowledge wrote:

> On 17-May-06, at 9:36 AM, Duncan Mak wrote:
>> I was thinking of using become: to implement something like this,  
>> yeah.
> You can't do that. Smallintegers cannot be become:'d. Other numbers  
> shouldn't be. A number is a number - a manifest object that is what  
> it is.  You *cannot* increment a number. There is nothing you can  
> do to '3' to make it anything but '3'.
> I fear you're still stuck in the C rape-and-pillage mindset where  
> you get to plunder memory locations and have your wicked way with  
> them like some rampaging Assyrian horde-member. It just isn't how  
> Smalltalk works, so try to put that aside.
> tim
> --
> tim Rowledge; tim at;
> Fractured Idiom:- RESPONDEZ S'IL VOUS PLAID - Honk if you're Scots

John M. McIntosh <johnmci at> 1-800-477-2659
Corporate Smalltalk Consulting Ltd.

More information about the Squeak-dev mailing list