binary selectors ambiguity and space
John M McIntosh
johnmci at smalltalkconsulting.com
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
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
(self isIntegerValue: result) ifTrue:
[self internalPop: 2 thenPush: (self integerObjectOf: result).
^ self fetchNextBytecode "success"]]
ifFalse: [successFlag := true.
self primitiveFloatAdd: rcvr toArg: arg.
successFlag ifTrue: [^ self fetchNextBytecode "success"]].
messageSelector := self specialSelector: 0.
argumentCount := 1.
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
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,
> 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 Rowledge; tim at rowledge.org; http://www.rowledge.org/tim
> Fractured Idiom:- RESPONDEZ S'IL VOUS PLAID - Honk if you're Scots
John M. McIntosh <johnmci at smalltalkconsulting.com> 1-800-477-2659
Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com
More information about the Squeak-dev