[net.lang.st80] Interesting bug in Berkeley Smalltalk interpreter

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).]