[BUG] ByteArray>>unsignedShortAt:

Ned Konz ned at bike-nomad.com
Sat Apr 3 01:33:47 UTC 2004


On Friday 02 April 2004 2:07 pm, Alain Fischer wrote:
> OS: Mac OS X 10.3.3
> VM: unix - Squeak3.6beta of '4 July 2003' [latest update: #5411]
> Image: Squeak3.6 [latest update: #5424]
>
> (ByteArray with: 255 with: 255) unsignedShortAt: 1
> return -1, it seem to me that the correct result is 65535


Well, that would be consistent with:

	(ByteArray with: 255 with: 255) unsignedShortAt: 1 bigEndian: true


I believe the problem is in the FFIPlugin definition of primitiveFFIIntegerAt 
where it says:

	byteSize < 4 ifTrue:[
		"short/byte"
		byteSize = 1 
			ifTrue:[value _ interpreterProxy byteAt: addr]
			ifFalse:[	value _ self cCode: '*((short int *) addr)' 
								inSmalltalk: [interpreterProxy halfWordAt: addr]].
		isSigned ifTrue:["sign extend value"
			mask _ 1 << (byteSize * 8 - 1).
			value _ (value bitAnd: mask-1) - (value bitAnd: mask)].
		"note: byte/short never exceed SmallInteger range"
		value _ interpreterProxy integerObjectOf: value.


And of course value is an int, so the sign extension always happens.

I think it should read something like this instead:

	byteSize < 4 ifTrue:[
		"short/byte"
		byteSize = 1 
			ifTrue:[value _ interpreterProxy byteAt: addr]
			ifFalse:[
				isSigned ifTrue: [ "sign extend value"
					value := self cCode: '*((short int *) addr)' 
					inSmalltalk: [
						value := interpreterProxy halfWordAt: addr.
						mask := 1 << (byteSize * 8 - 1).
						value := (value bitAnd: mask-1) - (value bitAnd: mask) ]]
				ifFalse: [ "unsigned value"
					value := self cCode: '(int)*((unsigned short int *) addr)' 
					inSmalltalk: [ value := interpreterProxy halfWordAt: addr ]]
		].
		"note: byte/short never exceed SmallInteger range"
		value _ interpreterProxy integerObjectOf: value.
	]

After all, there's no reason to do explicit sign extension in C.

-- 
Ned Konz
http://bike-nomad.com
GPG key ID: BEEA7EFE



More information about the Squeak-dev mailing list