'From Croquet1.0beta of 11 April 2006 [latest update: #1] on 19 March 2008 at 11:37:06 pm'! "Change Set: SignedIntFixes Date: 19 March 2008 Author: Andreas Raab Fixes various issues with * Interpreter>>signed32BitValueOf: * Interpreter>>signed64BitValueOf: * Interpreter>>signed64BitIntegerFor: which were incorrect to varying degrees."! !Interpreter methodsFor: 'primitive support' stamp: 'ar 3/19/2008 20:45'! signed32BitValueOf: oop "Convert the given object into an integer value. The object may be either a positive ST integer or a four-byte LargeInteger." | sz value largeClass negative | self inline: false. (self isIntegerObject: oop) ifTrue: [^self integerValueOf: oop]. largeClass := self fetchClassOf: oop. largeClass = self classLargePositiveInteger ifTrue:[negative := false] ifFalse:[largeClass = self classLargeNegativeInteger ifTrue:[negative := true] ifFalse:[^self primitiveFail]]. sz := self lengthOf: oop. sz = 4 ifFalse: [^ self primitiveFail]. value := (self fetchByte: 0 ofObject: oop) + ((self fetchByte: 1 ofObject: oop) << 8) + ((self fetchByte: 2 ofObject: oop) << 16) + ((self fetchByte: 3 ofObject: oop) << 24). "Filter out values out of range for the signed interpretation such as 16rFFFFFFFF (positive w/ bit 32 set) and -16rFFFFFFFF (negative w/ bit 32 set). Since the sign is implicit in the class we require that the high bit of the magnitude is not set which is a simple test here." value < 0 ifTrue:[^self primitiveFail]. negative ifTrue:[^0 - value] ifFalse:[^value]! ! !Interpreter methodsFor: 'primitive support' stamp: 'ar 3/19/2008 23:18'! signed64BitIntegerFor: integerValue "Return a Large Integer object for the given integer value" | newLargeInteger magnitude largeClass intValue highWord sz | self inline: false. self var: 'integerValue' type: 'sqLong'. self var: 'magnitude' type: 'sqLong'. self var: 'highWord' type: 'usqInt'. integerValue < 0 ifTrue:[ largeClass := self classLargeNegativeInteger. magnitude := 0 - integerValue] ifFalse:[ largeClass := self classLargePositiveInteger. magnitude := integerValue]. magnitude <= 16r7FFFFFFF ifTrue:[^self signed32BitIntegerFor: integerValue]. highWord := self cCode: 'magnitude >> 32'. "shift is coerced to usqInt otherwise" highWord = 0 ifTrue:[sz := 4] ifFalse:[ sz := 5. (highWord := highWord >> 8) > 0 ifTrue:[sz := sz + 1]. (highWord := highWord >> 8) > 0 ifTrue:[sz := sz + 1]. (highWord := highWord >> 8) > 0 ifTrue:[sz := sz + 1]. ]. newLargeInteger := self instantiateClass: largeClass indexableSize: sz. 0 to: sz-1 do: [:i | intValue := self cCode: '(magnitude >> (i * 8)) & 255'. self storeByte: i ofObject: newLargeInteger withValue: intValue]. ^ newLargeInteger! ! !Interpreter methodsFor: 'primitive support' stamp: 'ar 3/19/2008 23:35'! signed64BitValueOf: oop "Convert the given object into an integer value. The object may be either a positive ST integer or a eight-byte LargeInteger." | sz value largeClass negative szsqLong | self inline: false. self returnTypeC: 'sqLong'. self var: 'value' type: 'sqLong'. (self isIntegerObject: oop) ifTrue: [^self cCoerce: (self integerValueOf: oop) to: 'sqLong']. largeClass := self fetchClassOf: oop. largeClass = self classLargePositiveInteger ifTrue:[negative := false] ifFalse:[largeClass = self classLargeNegativeInteger ifTrue:[negative := true] ifFalse:[^self primitiveFail]]. szsqLong := self cCode: 'sizeof(sqLong)'. sz := self lengthOf: oop. sz > szsqLong ifTrue: [^ self primitiveFail]. value := 0. 0 to: sz - 1 do: [:i | value := value + ((self cCoerce: (self fetchByte: i ofObject: oop) to: 'sqLong') << (i*8))]. "Filter out values out of range for the signed interpretation such as 16rFFFFFFFF... (positive w/ bit 64 set) and -16rFFFFFFFF... (negative w/ bit 64 set). Since the sign is implicit in the class we require that the high bit of the magnitude is not set which is a simple test here." value < 0 ifTrue:[^self primitiveFail]. negative ifTrue:[^0 - value] ifFalse:[^value]! !