[Vm-dev] VM Maker: VMMaker.oscog-eem.1453.mcz

commits at source.squeak.org commits at source.squeak.org
Tue Sep 15 01:04:35 UTC 2015


Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1453.mcz

==================== Summary ====================

Name: VMMaker.oscog-eem.1453
Author: eem
Time: 14 September 2015, 6:02:22.862 pm
UUID: baf34f5d-4d8d-4f5f-b74a-1d76ecd08695
Ancestors: VMMaker.oscog-eem.1452

Fix bugs with 4-byte long integers in the 64-bit or machine word on 64-bit signed integer conversion routines.

=============== Diff against VMMaker.oscog-eem.1452 ===============

Item was changed:
  ----- Method: InterpreterPrimitives>>signed64BitValueOf: (in category 'primitive support') -----
  signed64BitValueOf: oop
  	"Convert the given object into an integer value.
  	 The object may be either a positive SmallInteger or a eight-byte LargeInteger."
  	| sz value negative ok |
  	<inline: false>
  	<returnTypeC: #sqLong>
  	<var: #value type: #sqLong>
  	(objectMemory isIntegerObject: oop) ifTrue:
  		[^self cCoerce: (objectMemory integerValueOf: oop) to: #sqLong].
  
  	(objectMemory isNonIntegerImmediate: oop) ifTrue:
  		[self primitiveFail.
  		 ^0].
  
  	ok := objectMemory isClassOfNonImm: oop
  					equalTo: (objectMemory splObj: ClassLargePositiveInteger)
  					compactClassIndex: ClassLargePositiveIntegerCompactIndex.
  	ok
  		ifTrue: [negative := false]
  		ifFalse:
  			[negative := true.
  			 ok := objectMemory isClassOfNonImm: oop
  							equalTo: (objectMemory splObj: ClassLargeNegativeInteger)
  							compactClassIndex: ClassLargeNegativeIntegerCompactIndex.
  			ok ifFalse:
  				[self primitiveFail.
  				 ^0]].
  	sz := objectMemory numBytesOfBytes: oop.
  	sz > (self sizeof: #sqLong) ifTrue:
  		[self primitiveFail.
  		 ^0].
  
  	self cppIf: VMBIGENDIAN
  		ifTrue:
  			[value := objectMemory fetchByte: sz - 1 ofObject: oop.
  			 sz - 2 to: 0 by: -1 do: [:i |
  				value := value << 8 + (objectMemory fetchByte: i ofObject: oop)]]
  		ifFalse:
  			[value := sz > 4
  						ifTrue: [objectMemory fetchLong64: 0 ofObject: oop]
+ 						ifFalse: [(objectMemory fetchLong32: 0 ofObject: oop) asUnsignedInteger]].
- 						ifFalse: [objectMemory fetchLong32: 0 ofObject: oop]].
  	"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.  Note that we have to
  	handle the most negative 64-bit value -9223372036854775808 specially."
  	self cCode: []
  		inSmalltalk:
  			[(value anyMask: 16r8000000000000000) ifTrue:
  				[value := value - 16r10000000000000000]].
  	value < 0 ifTrue:
  		[self cCode:
  			[self assert: (self sizeof: value) == 8.
  			 self assert: (self sizeof: value << 1) == 8].
  		"Don't fail for -9223372036854775808/-16r8000000000000000.
  		 Alas the simple (negative and: [value - 1 > 0]) isn't adequate since in C the result of signed integer
  		 overflow is undefined and hence under optimization this may fail.  The shift, however, is well-defined."
  		 (negative and: [0 = (self cCode: [value << 1]
  									inSmalltalk: [value << 1 bitAnd: (1 << 64) - 1])]) ifTrue: 
  			[^value].
  		 self primitiveFail.
  		 ^0].
  	^negative
  		ifTrue:[0 - value]
  		ifFalse:[value]!

Item was changed:
  ----- Method: InterpreterPrimitives>>signedMachineIntegerValueOf: (in category 'primitive support') -----
  signedMachineIntegerValueOf: oop
  	"Answer a signed value of an integer up to the size of a machine word.
  	The object may be either a positive SmallInteger or a LargeInteger of size <= word size."
  	<returnTypeC: #'long'>
  	| negative ok bs value bits |
  	<var: #value type: #long>
  	(objectMemory isIntegerObject: oop) ifTrue:
  		[^objectMemory integerValueOf: oop].
  
  	(objectMemory isNonIntegerImmediate: oop) ifTrue:
  		[^self primitiveFail].
  
  	ok := objectMemory isClassOfNonImm: oop
  					equalTo: (objectMemory splObj: ClassLargePositiveInteger)
  					compactClassIndex: ClassLargePositiveIntegerCompactIndex.
  	ok
  		ifTrue: [negative := false]
  		ifFalse:
  			[negative := true.
  			 ok := objectMemory isClassOfNonImm: oop
  							equalTo: (objectMemory splObj: ClassLargeNegativeInteger)
  							compactClassIndex: ClassLargeNegativeIntegerCompactIndex.
  			ok ifFalse: [^self primitiveFail]].
  	bs := objectMemory numBytesOf: oop.
  	bs > (self sizeof: #'unsigned long') ifTrue:
  		[^self primitiveFail].
  
  	((self sizeof: #'unsigned long') = 8
  	and: [bs > 4]) ifTrue:
  		[value := self cppIf: VMBIGENDIAN
  					ifTrue:
  						[    (objectMemory fetchByte: 0 ofObject: oop)
  						 + ((objectMemory fetchByte: 1 ofObject: oop) <<  8)
  						 + ((objectMemory fetchByte: 2 ofObject: oop) << 16)
  						 + ((objectMemory fetchByte: 3 ofObject: oop) << 24)
  						 + ((objectMemory fetchByte: 4 ofObject: oop) << 32)
  						 + ((objectMemory fetchByte: 5 ofObject: oop) << 40)
  						 + ((objectMemory fetchByte: 6 ofObject: oop) << 48)
  						 + ((objectMemory fetchByte: 7 ofObject: oop) << 56)]
  					ifFalse:
  						[objectMemory fetchLong64: 0 ofObject: oop]]
  		ifFalse:
  			[value := self cppIf: VMBIGENDIAN
  						ifTrue:
  							[    (objectMemory fetchByte: 0 ofObject: oop)
  							 + ((objectMemory fetchByte: 1 ofObject: oop) <<  8)
  							 + ((objectMemory fetchByte: 2 ofObject: oop) << 16)
  							 + ((objectMemory fetchByte: 3 ofObject: oop) << 24)]
  						ifFalse:
+ 							[(objectMemory fetchLong32: 0 ofObject: oop) asUnsignedInteger]].
- 							[objectMemory fetchLong32: 0 ofObject: oop]].
  	
  	self cCode: []
  		inSmalltalk:
  			[bits := (self sizeof: #long) * 8.
  			 (value bitShift: 1 - bits) > 0 ifTrue:
  				[value := value - (1 bitShift: bits)]].
  	value < 0 ifTrue:
  		["Don't fail for -16r80000000[00000000].
  		  Alas the simple (negative and: [value - 1 > 0]) isn't adequate since in C the result of signed integer
  		  overflow is undefined and hence under optimization this may fail.  The shift, however, is well-defined."
  		 (negative and: [0 = (self cCode: [value << 1]
  									inSmalltalk: [value << 1 bitAnd: (1 << bits) - 1])]) ifTrue: 
  			[^value].
  		 ^self primitiveFail].
  	^negative
  		ifTrue: [0 - value]
  		ifFalse: [value]!



More information about the Vm-dev mailing list