Let's browse this code:
primitiveEqual | integerReceiver integerArgument result | integerArgument := self popStack. integerReceiver := self popStack. result := self compare31or32Bits: integerReceiver equal: integerArgument. self checkBooleanResult: result
compare31or32Bits: obj1 equal: obj2 "May set success to false"
"First compare two ST integers..." ((self isIntegerObject: obj1) and: [self isIntegerObject: obj2]) ifTrue: [^ obj1 = obj2].
"Now compare, assuming positive integers, but setting fail if not" ^ (self positive32BitValueOf: obj1) = (self positive32BitValueOf: obj2)
positive32BitValueOf: oop "Convert the given object into an integer value. The object may be either a positive ST integer or a four-byte LargePositiveInteger."
| sz value | (self isIntegerObject: oop) ifTrue: [ value := self integerValueOf: oop. value < 0 ifTrue: [^ self primitiveFail]. ^ value].
self assertClassOf: oop is: (self splObj: ClassLargePositiveInteger). successFlag ifTrue: [ sz := self lengthOf: oop. sz = 4 ifFalse: [^ self primitiveFail]]. successFlag ifTrue: [ ^ (self fetchByte: 0 ofObject: oop) + ((self fetchByte: 1 ofObject: oop) << 8) + ((self fetchByte: 2 ofObject: oop) << 16) + ((self fetchByte: 3 ofObject: oop) << 24) ].
Why do we need to check equality vs 32bit ClassLargePositiveInteger? Is there any producer of such un-normalized LargePositiveInteger? If not, a much simpler thing that would work is to just compare the oop:
primitiveEqual | integerReceiver integerArgument result | integerArgument := self popStack. integerReceiver := self popStack. (self isIntegerObject: integerArgument) ifFalse: [self primitiveFail. ^nil]. self checkBooleanResult: integerReceiver = integerArgument
OK, it will fail for LargeInt instead of answering false, if we really need to accelerate this edge case, just do:
primitiveEqual | integerReceiver integerArgument result | integerArgument := self popStack. integerReceiver := self popStack. (self isIntegerObject: integerArgument) ifFalse: [self assertClassOf: oop is: (self splObj: ClassLargePositiveInteger)]. self checkBooleanResult: integerReceiver = integerArgument
It's not very pure, we may compare an encoded signed interger value xxxx...xxxxxxx1 with a pointer yyyy...yyyyy00, but they will never equal. Or maybe we never really call the primitive because we use kinda special bytecode ? I'm just curious...
Nicolas
vm-dev@lists.squeakfoundation.org