[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