rentsch@unc.UUCP (01/22/86)
I ran into an interesting problem running the Berkeley Smalltalk
interpreter on a Sun-2 workstation.
1594323 * 15625 (print it, gave) -858506901
Both 1594323 and 15625 are SmallIntegers. So, to the appropriate
method: SmallInteger *. That method is:
<primitive: 9>
self = 0 ifTrue: [ ^0 ].
^ super * aNumber
The thing which makes the bug interesting is that after I removed
the <primitive: 9>, it worked! This behavior is surprising since
SmallInteger * is an essential primitive and is not looked up but
done directly by the interpreter.
[For those who want to fix the bug in the interpreter -- and it *is*
an interpreter bug -- here is my fix. In SIPrims.c, routine
SIMulPrm, replace the two lines of code
reg1 *= reg2;
SmallIntegerOperationFinishWithOverflow(SIMulPrmOvfl);
with
if( reg1 ){
int result = reg1 * reg2;
if( result / reg1 != reg2 ){
reg1 = 0x7fffffff;
} else {
reg1 = result;
}
}/**** 0 * anything == 0 ****/
SmallIntegerOperationFinish;
which correctly makes the primitive fail on overflow (by sneakily
yielding a non-SmallInteger for that case).]