[Vm-dev] Fix for broken integer arithmetic on 64 bit image/32 bit host

David T. Lewis lewis at mail.msen.com
Sat Nov 11 20:07:58 UTC 2006


There is a bug (Mantis 5238) with integer arithmetic on 64 bit images running
on 32 bit hosts.

I have been pecking away at this bug for a while now, and I have come up with
a solution. In a nutshell, the solution I'm proposing is to add C preprocessor
capability to Slang, then change ObjectMemory>>isIntegerValue: to this:

	^ self isDefined: 'SQ_HOST32'
		inSmalltalk: [true]
		comment: 'cast to int for 64 bit image on 32 bit host'
		ifTrue: ((self cCoerce: intValue to: 'int')
					bitXor: ((self cCoerce: intValue to: 'int') << 1)) >= 0
		ifFalse: (intValue bitXor: (intValue << 1)) >= 0

Which generates the following C code:

sqInt isIntegerValue(sqInt intValue) {
	return
# ifdef SQ_HOST32  // cast to int for 64 bit image on 32 bit host
		((((int) intValue)) ^ ((((int) intValue)) << 1)) >= 0
# else
		(intValue ^ (intValue << 1)) >= 0
# endif  // SQ_HOST32
	;
}

The method is still inlined throughout the interpreter, with generated code
such as this:

	/* begin storeInteger:ofObject:withValue: */
	if (
# ifdef SQ_HOST32  // cast to int for 64 bit image on 32 bit host
		((((int) (evtBuf[0]))) ^ ((((int) (evtBuf[0]))) << 1)) >= 0
# else
		((evtBuf[0]) ^ ((evtBuf[0]) << 1)) >= 0
# endif  // SQ_HOST32
	) {
		longAtput((arg + BaseHeaderSize) + (0 << ShiftForWord), (((evtBuf[0]) << 1) | 1));
	} else {
		/* begin primitiveFail */
		foo->successFlag = 0;
	}


While this adds some complexity to the C code generator, it produces correct
results on all combinations of 32/64 bit image and host, and requires no
additional platform support files. It also preserves the speed advantage of
Tim's current #isIntegerValue: (which unfortunately did not work for 64 bit
images on 32 bit hosts).

Comments?

Dave



More information about the Vm-dev mailing list