Copyright 1998 Lars T Hansen.                -*- text -*-

$Id$

	       Known bugs in Larceny that have been fixed.

	 Bugs are listed in the order recorded, with fix dates and
				the fix.


001  (v0.25) 

     Discovered by arithmetic regression test ("test 6"):
       (inexact->exact 0.0)
     bombs with
       Error: quotient:  division by zero: 8 0
     Happens in both generational and stop+copy systems.  Also fails
     for complexes where the real part is 0.0, e.g. (i->e 0.0+1.0i).

     FIX: became fixed when 006 was fixed.

002  (v0.26)  Fixed 970624 by lth

     The exit status from larceny is some random number.

     FIX:
     Wrote the required code to make this work :-)

003  (v0.26)   Fixed 970716 by lth (new assembler only!)

     Singlestepping does not seem to work any longer.

     FIX:
     Rewrote the required bits.

004  (v0.27e)  Fixed 970701 by lth

     The following expression loops forever:

       (rationalize (inexact->exact 0.1) 1/10000000000000000000000000000)

     It hangs for more 0s as well.  According to Chez, the result should be
     1801439850915747/18014398509157469.

     Furthermore, when the source from Larceny is plugged into Chez, then
     it gives the same answer as the Chez built-in rationalize.

     This appears to be a bug in ratnum<?, which in turn is a bug in 
     ratnum-sub, which in turn is a bug in ratnum-add-or-sub 
     (all in Lib/ratnums.sch).  Consider:

  (ratnum-add-or-sub 
    134217728000000007450580597058045853/1342177280000000000000000000000000000 
    134217728000000007450580596789610397/1342177280000000000000000000000000000 
    -)

     and

  (ratnum-add-or-sub 
    134217728000000007450580596789610397/1342177280000000000000000000000000000
    134217728000000007450580597058045853/1342177280000000000000000000000000000 
    -)

     which both evaluate to 1/5000000000000000000000000000, but in the latter
     case the sign is wrong (although the magnitude is right): it should
     be negative.

     This in turn turns out to be a bug in bignum subtraction: the numerator
     of the smaller minus the numerator of the larger is positive!

     FIX:
     In the last instance: this was a bug in bignum->fixnum, which did not
     preserve the sign of a negative bignum.

006  (v0.27e)

     (integer? 0.0) => #f
     Note that (integer? 1.0) => #t and (integer? -1.0) => #t.

     It appears that the algorithm used by generic_integerp in generic.s
     is not correct for 0.0, because 0.0 is not represented like other 
     numbers: its biased exponent is 0.

     Since inexact->exact uses integer?, the problem with the former may
     be a problem with the latter.

     FIX: changed the implementation of generic_integerp in Sparc/generic.s.

007  (v0.27e)

     -0.0 prints without the leading `-'.  It reads as -0.0, however.
     More specifically, (number->string -0.0) => "0.0".  This bug is present
     because the implementation of number->string uses negative? to see
     whether the output should be prefixed by `-' or not, but negative?
     is not #t for -0.0 (just like positive? is not true for 0.0).

     FIX: changed number->string.

008 (v0.28)

    The evaluator is buggy -- it does not run the remset-profile program
    in Util/process-stats, but when given the command

	(remset-profile "stats-std")

    gives the error

	Error: cdr: stats-std is not a pair.

    I have preserved the source file as Bugs/process-stats.sch.

    This is reproducible in the following smaller fragment:
    > (define zz 
        (lambda (x) 
          (let ((a 33)) 
            (do ((i 0 (+ i 1))) 
                ((= i 10)) 
              (display "A") 
              (set! a (+ a x)) 
              (display x)
              (newline)))))
    > (zz 1)
    AError: cdr: () is not a pair.

    That is, it fails in the set!.

    FIX: Turned out that in eval/setlex, what is env0 below was called
	 env, so the rhs was evaluated with the wrong environment.
	
	(define (eval/setlex rib offset expr)
	  (lambda (env0)
	    (let loop ((rib rib) (env env0))
	      (if (= rib 0)
		  (vector-set! (car env) offset (expr env0))
		  (loop (- rib 1) (cdr env))))))


009  (v0.28)  Fixed 970430 by lth.

     Garbage collector bug, standard collector.

     In binary delphi970426/bin/larceny.noprof with heap in that same
     directory.

     Parameters: -heaps 4 -size1 256K -size2 512K -size3 512K -size4 1536K 

     Transcript

	Larceny v0.28 (SunOS;split) (lth/Sat Apr 26 08:17:23 EDT 1997)

	> (load "bin/dynamic.fasl")
	> (collect)
	> (dynamic-benchmark 50)

	--------------------------------------------------------
	dynamic
	Error: cdr: 0 is not a pair.

     The error is repeatable also in the current system:

	Larceny v0.28 (SunOS;split) (lth/Tue Apr 29 17:46:45 EDT 1997)

     with the heap file as used in the previous system.  However, that
     heap is identical to the current heap.

     Annoy-user transcript (for what it's worth):

	Garbage collecting generation 1.
	Garbage collecting generation 1.
	Garbage collecting generation 2.
	Garbage collecting generation 1.
	Garbage collecting generation 1.
	Garbage collecting generation 1.
	Garbage collecting generation 1.
	Garbage collecting generation 1.
	Garbage collecting generation 1.
	Garbage collecting generation 1.
	Garbage collecting generation 1.
	Garbage collecting generation 3.
	Contracting generation 3 by 315392 bytes; size=1257472.
	Garbage collecting generation 1.
	Garbage collecting generation 1.
	Garbage collecting generation 3.
	Expanding generation 3 by 253952 bytes; size=1511424.
	Garbage collecting generation 1.
	Garbage collecting generation 1.
	Garbage collecting generation 3.
	Garbage collecting generation 1.
	Garbage collecting generation 1.
	Error: cdr: 0 is not a pair.

    Full debug transcript (>2300 lines) is in Bugs/gcbug-transcript.

    Debug transcript shows that before_promotion and after_promotion
    are not being called for old-heap(2,2) when promoting or collecting
    into old-heap(3,3).  This is a bug.  This kind of collection
    happens just before the crash (and also several times previously in
    the run).

    FIX:
    This turned out to be three interacting bugs.
    * First, the array of prom_bits was not initialized properly, although
      it is likely that this was overcome rapidly (or worked by accident,
      seeing as memory is usually allocated 0-initialized).
    * Second, the algorithms used by before_promote_all and after_promote_all
      were wrong.
    * Third, a typo in after_promote_all made out-of-bounds array references
      to prom-bits possible (although not in the current case).


010  (v0.28) Fixed 970716 by lth

     Error in vector-ref

     Symptom:
	> (vector-ref (vector-ref (sys$get-resource-usage) 11) 3)
	#<WEIRD OBJECT>

     Another:
	> (vector-ref '#(1 2 3) 3)
	quote

     Most likely the 'blu' below should be 'bleu' (code from 
     Sparcasm/gen-prim.sch).

	(define (emit-vector-like-ref! as r fault tag)
	  (let ((r1 (force-hwreg! as r $r.argreg2)))
	    (if (not (unsafe-code))
		(begin
		  (emit! as `(,$i.andicc ,r1 3 ,$r.g0))
		  (emit! as `(,$i.bne.a ,fault))
		  (emit! as `(,$i.slot))
		  (emit! as `(,$i.ldi ,$r.result (- ,tag) ,$r.tmp2))
		  (emit! as `(,$i.srai ,$r.tmp2 8 ,$r.tmp2))
		  (emit! as `(,$i.subrcc ,$r.tmp2 ,r1 ,$r.g0))
		  (emit! as `(,$i.blu ,fault))))
	    (emit! as `(,$i.addi ,$r.result ,(- 4 tag) ,$r.tmp0))
	    (emit! as `(,$i.ldr ,$r.tmp0 ,r1 ,$r.result))))

     Note: fix this in the _new_ assembler.

     FIX:
     Changed the instruction to bleu.

011  (v0.28) Fixed 970727 by lth

     Error reporting for vector-ref is broken:

	> (vector-ref '#(1 2 3) 4)
	Error: Exception-handler: confused about vector-ref: #(1 2 3) 2

     This is a known problem: the value '2' is not the right value;
     the generated code does not pass the right value to the fault handler.

     Fix this in the _new_ assembler only.

     Consolidated bugs: [013,015,014,016].  This is really a problem with
     the way emit-double-tagcheck-assert! and emit-single-tagcheck-assert!
     are implemented in the assembler.  Tag checking code needs to be
     revisited anyway, which is why I haven't implemented a quick fix.
     --lars

     [013] Error reporting for bytevector-like-ref is broken:

	(bytevector-like-ref "123" 4)
	Error: Exception-handler: confused about bytevector-like-ref: 123 2

     [014] Error reporting for bytevector-ref is broken:

	(bytevector-ref (make-bytevector 3) 4)
	Error: Exception-handler: confused about bytevector-ref: 
		#<BYTEVECTOR> 2

     [015] Error reporting for bytevector-set! is broken:

	(bytevector-set! (make-bytevector 3) 4 27)
	Error: bytevector-set!: 3 is not a valid index into bytevector

     [016] Error reporting for vector-set! is broken:

	(vector-set! (vector 1 2 3) 4 0)
	Error: vector-set!: 3 is not a valid index into vector

     FIX: Implemented the necessary changes in Asm/Sparc/gen-prim.sch.


012  (v0.28)  970507
     Priority: low.
     Category: RTS / correctness

     Remembered-set size information from the command line is disregarded
     when creating the remembered sets in the garbage collector.

     See file Rts/Sys/memmgr.c

     Fixed 9909** by lth by implementing it as part of cleanup for
     revision of radioactive decay paper.


017  (v0.28)  970507  Fixed 970625 by lth

     Must restore console i/o on error.  Consider:

        (with-output-to-file "/dev/null" (lambda () (error)))

     After this, the repl accepts and executes commands (try (exit)),
     but output is still to /dev/null.

     FIX:
     Wrote the necessary code in the Repl and its error handlers to do this.

018  (v0.28)  970507  Fixed June(?) 1997 by lth

     Expt only takes exact integer powers:

	(expt 2 1.5)
	Error: expt: don't yet know how to deal with21.5

     FIX: Apparently, I've since written the code.

019  (v0.28)  970507  Fixed 971030 by lth

     With the generational collector, it is only possible to allocate objects
     that fit in the youngest generation, and that generation is of a
     fixed size.  This should not be a problem with the stop-and-copy (heaps=1)
     or conservative collectors.

     This should be fixed by allowing objects to be allocated "on the side"
     of the youngest generation; the current barrier system should be able
     to deal with this.

020  (v0.28b) 970527  Fixed 970624 by lth

     Transcript:

	everest(8) % larceny ../larceny.heap
	Larceny v0.28b/precise (SunOS;split) (lth/Tue May 27 20:03:53 EDT 1997)

	> (load "dynamic.sch")
	> (dynamic-benchmark 10)

	--------------------------------------------------------
	dynamic
	Error: dynamic-parse-expressionsIllegal expression list: ~srest

     Apparently a bug in the interpreter.

     FIX:
     Turned out to be an error in the rewriting of certain quasiquotations,
     which caused the macro expander to generate erroneous code for CASE
     expressions.  This error did not show up in compiled code because the
     compiler uses a different macro expander for CASE.  However, the
     compiler uses a copy of the same quasiquotation rewriter, so that had 
     to be fixed too.

021  (v0.28b) 970528  Fixed 980115 by lth

     Free list coalescing is not done properly in unix-alloc.c.  This is 
     a benign problem with the current GC structure, but should be fixed.
     - free list should be address ordered (for coalescing, and also so
       that we can return memory to the OS).
     - a new free block can merge two previously separated blocks so that
       all three blocks become one.

     FIX:
     Reimplemented free list management.

022  (v0.28d) 970625  Fixed 970701 by lth

     The following functions do not accept complex arguments:
	SQRT, SIN, COS, TAN, ASIN, ACOS, ATAN, LOG, EXP

023  (v0.28d) 970701  Fixed 970701 by lth

     'Magnitude' is broken:

     > (magnitude 3+2i)
     Error: Attempt to apply 2, which is not a procedure.

     FIX:
     Simple typo in the implementation.


024  (v0.28d) 970701  Fixed 970101 by lth

     Make-polar is broken:

     > (make-polar 3.605551275463989 0.5880026035475675)
     -0.5258437067537658-0.2631263153813724i

     But the correct answer is approx. 3+2i.  The code is very wrong --
     it's not even _close_ to correct.

     FIX (970701) / lth:
     Rewritten.


025  (v0.28d) 970701  Fixed 970701 by lth

     Flonum/compnum multiplication is broken:

      > (* 1.0 0.8320502943378437+0.554700196225229i)
      0.0

     FIX: was typo in compnum/compnum multiplication in generic.s.


026  (v0.28d) 970701  Fixed 970716 by lth

     LOG does not accept negative arguments.

028  (v0.28c) 970611  Fixed 970702 by lth

     Message-ID: <339EF37B.5361@ccs.neu.edu>
     Date: Wed, 11 Jun 1997 13:51:04 -0500
     From: William D Clinger <will@ccs.neu.edu>
     To: lth@ccs.neu.edu
     Subject: Minor bug report (segmentation fault)
     
     This bug is so minor that I'm not going to fix it right now.
     I'll just let you add it to the list of things to fix later.
     
     You seem to get a segmentation fault if you call gcctl on the
     young part of the non-predictive heap.
     
     Will
     
     ----
     
     [Benchmarks]% larc2 -calibrate
     Calibration run using non-predictive collector
     Larceny v0.28c/precise (SunOS;split) (will/Wed Jun 11 13:36:01 EDT 1997)
     Non-predictive hi_mark=80, lo_mark=0, oflo_mark=80.
     GC type: sc/fixed+2*sc/variable+static
     
     Heap statistics:
     Generation 0
       Size of semispace 1: 262144 bytes
       Size of semispace 2: 262144 bytes
       Live data: 0 bytes
       Live stack: 0 bytes
     Generation 1
       Size of semispace 1: 524288 bytes
       Size of semispace 2: 0 bytes
       Live data: 0 bytes
     Generation 2
       Size of semispace 1: 2097152 bytes
       Size of semispace 2: 0 bytes
       Live data: 0 bytes
     Generation 3
       Size of semispace 1: 0 bytes
       Size of semispace 2: 0 bytes
       Live data: 0 bytes
     Generation 4
       Size of semispace 1: 825344 bytes
       Size of semispace 2: 0 bytes
       Live data: 825344 bytes
     
     > (gcctl 4 'j-fixed 0) ; should be (gcctl 3 'j-fixed 0)
     Segmentation fault
     
     FIX:
     The code for set_policy in memmgr.c did perform a range check on
     the heap number, but it compared it against the maximum generation 
     number.  The code was fixed to compare agains the index of the
     oldest old heap.

030  v0.28e (970708 / lth)  Fixed 970716 by lth

     Reader bug: initial capital letters are not folded to lowercase:

	> 'Loadfile
	Loadfile
	> 'loadfile
	loadfile
	> 'loAdfile
	loadfile
	> 

     FIX:
     But in read-symbol introduced during optimization.

031  v0.28e (970708 / lth) Fixed 981202 by lth
     Priority: medium.

     Dynamic-wind must be made aware of timer interrupts [some parts must
     be guarded by critical sections.]

     FIX:
     Added critical sections; revisit when we do threads for real.

032  v0.28e (970715 / lth) Fixed 971023 by lth

     It appears that the error continuation grows longer and longer with
     each error.  This is an error.

     This is easily seen with the backtrace walker: for each error,
     or at least for most errors, the backtrace structure gets longer and
     longer.  Interestingly it looks like this:

	> (walk (error-continuation))
	#(#f #f 0.0 #f #f)   72
	#(*error-handler* #f 0.0 #f #f)   54
	#(*error-handler* #f 0.0 #f #f)   54
	#(*error-handler* #f 0.0 #f #f)   54
	#(*error-handler* #f 0.0 #f #f)   54
	#(*error-handler* #f 0.0 #f #f)   54
	#(*error-handler* #f 0.0 #f #f)   54
	#(#f #f 1 #f #f)   67
	#(#f #f 1 #f #f)   36
	#f   377
	SYSTEM PROCEDURE   10062
	Error: >=: #f is not a real number.

     where we also see that not only does it look strange, but it
     terminates in an unexpected way.  This gets more interesting as we
     just print out the continuation: notice the reader error at the 
     end!  Something bad is lurking there...

	#(72 #(54 #(54 #(54 #(54 #(54 #(54 #(54 #(54 #(54 #(54 #(54 #(54 #(6898 #(7032 #(10143 #(188 #(54 #(54 #(54 #(54 #(54 #(54 #(10143 #(59 #(377 #(10062 Error: Bogus display procedure; reverting to default.

     Here's a more extensive trace:

	everest(4) % larceny
	Larceny v0.31 (precise;SunOS;split) (lth/Wed Oct 15 15:47:02 EDT 1997)
	
	> (load "oddeven.fasl")
	> (load "walk.sch")
	> (even? '(1 2 3 . 4))
	Error: cdr: 4 is not a pair.
	
	> (walk2 (error-continuation))
	Frame length 4
	Return offset 72
	dynamic link is valid
	procedure information: #(#f #f 0.0 #f #f)
	reg1 = (() cdr :  4  is not a pair.)
	Frame length 4
	Return offset 54
	dynamic link is valid
	procedure information: #(*error-handler* #f 0.0 #f #f)
	reg1 = (() cdr :  4  is not a pair.)
	Frame length 4
	Return offset 54
	dynamic link is valid
	procedure information: #(*error-handler* #f 0.0 #f #f)
	reg1 = (() cdr :  4  is not a pair.)
	Frame length 4
	Return offset 54
	dynamic link is valid
	procedure information: #(*error-handler* #f 0.0 #f #f)
	reg1 = (() cdr :  4  is not a pair.)
	Frame length 4
	Return offset 54
	dynamic link is valid
	procedure information: #(*error-handler* #f 0.0 #f #f)
	reg1 = (1 4 #<PROCEDURE> #<PROCEDURE>)
	Frame length 4
	Return offset 54
	dynamic link is valid
	procedure information: #(*error-handler* #f 0.0 #f #f)
	reg1 = (1 4 #<PROCEDURE> #<PROCEDURE>)
	Frame length 4
	Return offset 54
	dynamic link is valid
	procedure information: #(*error-handler* #f 0.0 #f #f)
	reg1 = (1 4 #<PROCEDURE> #<PROCEDURE>)
	Frame length 38
	Return offset 10143
	dynamic link is valid
	procedure information: system procedure
	reg1 = 43
	reg2 = #<PROCEDURE>
	reg3 = 4
	reg4 = #<PROCEDURE even?>
	reg5 = #!undefined
	reg6 = 1
	reg7 = ()
	reg8 = #<PROCEDURE>
	reg9 = (#<PROCEDURE>)
	reg10 = 1
	reg11 = #<PROCEDURE>
	reg12 = (#<PROCEDURE>)
	reg13 = even?
	reg14 = 1
	reg15 = ()
	reg16 = #<PROCEDURE>
	reg17 = (4)
	reg18 = #f
	reg19 = 10
	reg20 = -1
	reg21 = (#<PROCEDURE read-string> . 0)
	reg22 = (#<PROCEDURE read-symbol> . 0)
	reg23 = (#<PROCEDURE read-symbol2> . 0)
	reg24 = (#<PROCEDURE read-atom> . 0)
	reg25 = (#<PROCEDURE parse-prefixed-number> . 0)
	reg26 = (#<PROCEDURE parse-number-loop> . 0)
	reg27 = (#<PROCEDURE peculiar-identifier?> . 0)
	reg28 = (#<PROCEDURE flush-comment> . 0)
	reg29 = (#<PROCEDURE flush-comment-and-read> . 0)
	reg30 = (#<PROCEDURE flush-comment-and-read-list> . 0)
	reg31 = (#<PROCEDURE read-eof> . 0)
	reg32 = (#<PROCEDURE read-unexpected-eof> . 0)
	reg33 = (#<PROCEDURE char-downcase> (#<PROCEDURE warn> . 0) (#<PROCEDURE read-illegal> . 0) (#<PROCEDURE read-dispatch-whitespace> . 0) (#<PROCEDURE read-dispatch-extra-paren> . 0) (#<PROCEDURE read-dispatch-symbol-starter> . 0) (#<PROCEDURE read-dispatch-parse> . 0) (#<PROCEDURE read-dispatch-reserved> . 0) (#<PROCEDURE read-list-whitespace> . 0) (#!undefined . 0))
	reg34 = 4
	reg35 = 0
	Frame length 4
	Return offset -102637
	dynamic link is valid
	procedure information: ((88 . #(even? #f 1 #f #f)) (108 . #(odd? #f 1 #f #f)) (268 . #(even? #f 1 #f #f)))
	reg1 = 4
	Frame length 4
	Return offset 100
	dynamic link is valid
	procedure information: ((88 . #(even? #f 1 #f #f)) (108 . #(odd? #f 1 #f #f)) (268 . #(even? #f 1 #f #f)))
	reg1 = (3 . 4)
	Frame length 4
	Return offset 60
	dynamic link is valid
	procedure information: ((88 . #(even? #f 1 #f #f)) (108 . #(odd? #f 1 #f #f)) (268 . #(even? #f 1 #f #f)))
	reg1 = (2 3 . 4)
	Frame length 4
	Return offset 100
	dynamic link is valid
	procedure information: ((88 . #(even? #f 1 #f #f)) (108 . #(odd? #f 1 #f #f)) (268 . #(even? #f 1 #f #f)))
	reg1 = (1 2 3 . 4)
	Frame length 7
	Return offset 377
	dynamic link is valid
	procedure information: #f
	reg1 = (even? '(1 2 3 . 4))
	reg2 = #<PROCEDURE>
	reg3 = (even? '(1 2 3 . 4))
	reg4 = #<ENVIRONMENT larceny-environment>
	Frame length 3
	Return offset 10062
	dynamic link is valid
	procedure information: system procedure
	Frame length #f
	Return offset -4194305
	Error: >=: #f is not a real number.

     Notice the invalid frame size!

     The plot is thickening: here's a backtrace of the current 
     continuation structure in a clean heap:

	everest(5) % larceny
	Larceny v0.31 (precise;SunOS;split) (lth/Wed Oct 15 15:47:02 EDT 1997)
	
	> (load "walk.sch")
	> (walk2 (current-continuation-structure))
	
	Frame length 5
	Return offset 59
	dynamic link is valid
	procedure information: #(#f #f 1 #f #f)
	#1 = ()
	#2 = #<PROCEDURE>
	
	Frame length 7
	Return offset 377
	dynamic link is valid
	procedure information: #f
	#1 = (walk2 (current-continuation-structure))
	#2 = #<PROCEDURE>
	#3 = (walk2 (current-continuation-structure))
	#4 = #<ENVIRONMENT larceny-environment>
	
	Frame length 3
	Return offset 10062
	dynamic link is valid
	procedure information: system procedure
	
	Frame length #f
	Return offset -4194305
	Error: >=: #f is not a real number.

     FIX:
     Error in continuation structure turned out to be a bug in callout.c.

     Aggregation of frames turned out to be the wrapping of handler
     procedures in error handler installation -- don't do that!

033  v0.28f (970717 / lth)  Fixed 970727 byt lth

     (This is an old error.)
     The typechecking of character comparisons is not correct, it only
     checks that the objects have the same low 8 bits:

	> (char=? 1 1)
	#t
	> (char<? 1 1)
	#f

     The error is in Asm/Sparc/gen-prim.sch, in the procedure emit-charcmp!.

     FIX: rewrote emit-charcmp! in the obvious way.

035  v0.28f (970812 / lth)  Fixed 980409 by lth

     The macro expander (and Twobit?) rely on some global variables called
     %list, %list->vector, %cons, %append, and %make-promise.  

     These dependencies should be removed completely, probably by using
     magic global names (more magic than the above...) that the linker
     treats specially, possibly by having all environments inherit
     from an environment where they are bound.

     Also NOTE that those names are not present in the null environment, 
     so some code that should run in that environment (notably code with
     quasiquotations, but perhaps other code as well) will not in fact run.
     The same fix applies.

     FIX: implemented magic names.  Magic names start with . and may contain
     no underscores (for reasons of possibly ugly interaction with the 
     compiler).

037  v0.28f (970915 / lth)  Fixed 970716 by lth

     Negation of a bignum does not work correctly if the resulting number
     is the most negative fixnum:

       > (fixnum? (- (expt 2 29)))
       #f
       > (fixnum? (- (+ (- (expt 2 29)) 1) 1))
       #t
       > (fixnum? (+ (- (- (expt 2 29)) 1) 1))
       #f

     The resulting number should be represented as a fixnum.

     Note that the third expression is _also_ an error, possibly related.

     Actually, it seems to go deeper: this is very wrong:

	> (- (expt 2 29))
	536870912
	> (- 0 (expt 2 29))
	536870912

     FIX: 
     Turned out to be bignum->fixnum, once again, that did not handle
     the most negative fixnum correctly.


038  v0.29a (970917 / lth)  Fixed 971030 by lth

     Typetag-set! gives a strange error message when it's not the structure
     but the typetag that is bad:

	> (typetag-set! (make-vector 3) 20)
	Error: typetag-set!: #(#f #f #f) is not typetag-settable.

     FIX:
     Added code to ehandler.sch to discover this.


039  v0.30 (970924 / lth)  SunOS

     The following crashes with 'Illegal instruction':

	(let ((x (inexact->exact (log -1.3))))
	  (make-rectangular (rationalize (real-part x) 1/1000) 
                            (rationalize (imag-part x) 1/1000)))

     It appears that an illtrap 0 appears in the middle of an
     otherwise fine-looking instruction stream, in place of a
     conditional branch:

	(gdb) x/20i $pc-40
	0x512ac0 <end+5182368>:	cmp  %o0, 0x316
	0x512ac4 <end+5182372>:	bne,a   0x512ad8 <end+5182392>
	0x512ac8 <end+5182376>:	nop 
	0x512acc <end+5182380>:	mov  %o4, %o0
	0x512ad0 <end+5182384>:	call  %i7 + 0x568
	0x512ad4 <end+5182388>:	mov  0x1a8, %g1
	0x512ad8 <end+5182392>:	call  0x512ae0 <end+5182400>
	0x512adc <end+5182396>:	add  %o7, 0x40, %o7
	0x512ae0 <end+5182400>:	st  %o7, [ %o3 + 4 ]
	0x512ae4 <end+5182404>:	deccc  %i4
	0x512ae8 <end+5182408>:	illtrap  0
	0x512aec <end+5182412>:	and  %o0, 7, %g1
	0x512af0 <end+5182416>:	call  %i7 + 0x560
	0x512af4 <end+5182420>:	add  %o7, -20, %o7
	0x512af8 <end+5182424>:	and  %o0, 7, %g1
	0x512afc <end+5182428>:	cmp  %g1, 7
	0x512b00 <end+5182432>:	be,a   0x512b14 <end+5182452>
	0x512b04 <end+5182436>:	ld  [ %o0 + -3 ], %g1
	0x512b08 <end+5182440>:	mov  0x1a4, %g1
	0x512b0c <end+5182444>:	jmp  %i7 + 0x568
	(gdb) x/x $pc
	0x512ae8 <end+5182408>:	0x00000000

     The instruction is intact when the program starts (at that address,
     which should be in the static area).

     Furthermore, the problem happens in the call to rationalize (either
     one); real-part and imag-part seem to work fine.  

     Here's the last part of a syscall trace:

	generic_lessp: 5851d 0
	internal_scheme_call: 150
	generic_lessp: 5851d 586fd
	internal_scheme_call: 44
	internal_scheme_return: 2
	internal_scheme_return: 2
	generic_equalp: 5851d 0
	internal_scheme_call: 154
	generic_equalp: 5851d 5870d
	internal_scheme_call: 40
	internal_scheme_return: 2
	internal_scheme_return: 2
	internal_scheme_call: 14c
	internal_scheme_call: 34
	internal_scheme_return: 5872d
	internal_scheme_return: 5872d
	internal_scheme_call: 14c
	internal_scheme_call: 30
	internal_scheme_return: 58765
	internal_scheme_return: 58765
	internal_scheme_call: 14c
	internal_scheme_call: 34
	internal_scheme_return: 5878d
	internal_scheme_return: 5878d
	internal_scheme_call: 14c
	internal_scheme_call: 30
	internal_scheme_return: 587c5
	internal_scheme_return: 587c5
	
	#x14c/4 = 83 = contagion
	#x30/4 = 12 = bignum-multiply
	#x34/4 = 13 = bignum-divide 

     So far, it appears that some code is clobbering the code stream,
     probably with a wild assignment.

     Here's the transcript:

	> (define x (inexact->exact (log -1.3)))
	(gdb) x/i 0x512ae8
	0x512ae8 <end+5182408>:	bne,a   0x512afc <end+5182428>
	> (define a (real-part x))
	(gdb) x/i 0x512ae8
	0x512ae8 <end+5182408>:	bne,a   0x512afc <end+5182428>
	> (rationalize a 1/1000)
	Program received signal SIGILL, Illegal instruction.
	0x512ae8 in ?? ()
	(gdb) x/i 0x512ae8
	0x512ae8 <end+5182408>:	illtrap  0

     After some grubbing around in the code for rationalize, we have
     that the same error is provoked by the less mysterious

	> (/ 147135000507969563/562949953421312000)

     and also by (/ 1 ...), as expected, and also by:

	> (define one (make-ratnum 1 1))
	> one
	1/1
	> (/ one 147135000507969563/562949953421312000)

     So it seems ratnum-div is at fault, somehow (not contagion).

     Rebuilding the heap didn't seem to make any difference (i.e., 
     the heap is probably OK).

     Expanding syshooks with two functions preserves the error...

     This provokes the same error:

	((system-function 'ratnum-div)
         ((system-function 'make-ratnum) 1 1)
         147135000507969563/562949953421312000)

     Interestingly, so does this:
        ((system-function 'ratnum-div)
         147135000507969563/562949953421312000
         ((system-function 'make-ratnum) 1 1))
     but it overwrites a slightly different address (512a50 rather 
     than 512ae8).

     Also fails with protect_static() in place...

     FIX:
     Turned out to be an error in generic.s where %GLOBALS was used in
     a section between save and restore.

     Thanks to Johan who suggested write protecting the static area,
     thereby quickly finding the offending instruction.

040  v0.31 (9710xx / lth)  Fixed 9761030 by lth

     The _make_ utility uses call-with-error-control but this is not loaded
     with the load-development-environment system.  

     In general, call-with-error-control, call-with-error-handler, 
     call-with-reset-handler should be exposed in the default 
     interaction environment.

     FIX:
     Exported functions; added file Util/make-support.sch.

041  v0.31 (9710xx / dougo)  Fixed 981215 by lth
     Priority: should not be fixed.

     The macro-expander and evaluator are not robust and produce strange 
     error messages when handed syntactically incorrect programs.  Consider,

	> (if)
	Error: car: () is not a pair.

     [Editorial: we should toss the macro-expander and switch to the
      hygienic macro package. -- lars]

     FIX: the new macro expander fixed this.

043  v0.31 (971024 / lth)  Fixed 9811?? by lth
     Priority: low

     [Performance bug]
     Make-string needs to be a primop.  I classify this as a bug because
     the performance implications are potentially considerable, and
     because the new pass3 wants to rely on make-string being a primop.
     One possibility here is to expand (make-string n c) to
       (let ((s (make-bytevector n)))
         (bytevector-fill! s (char->integer c))
         s)
     since both make-bytevector, bytevector-fill!, and char->integer
     are primops.

     FIX:
     Implemented make-string as a bona fide primop.

045  v0.31 (971024 / lth)  Fixed 971030 by lth

     environment-gettable? needs to check for an undefined value.

     FIX:
     Implemented obvious fix.

046  v0.31 (971024 / lth)  Fixed 971031 by lth

     The console I/O system must do the right thing when asked to open
     and close.  See comments in code.

     FIX:
     Added code to conio.sch and unix.sch to implement this.

047  v0.31 (971029 / lth) Fixed 981203 by lth
     Priority: low

     `Round' does not properly round down to even (e.g., for 0.5, 2.5, 4.5)
     as exposed by the test suite and as noted in comments in 
     Sparc/generic.s; this is for flonums only (it rounds ratnums properly).

     FIX: rewrote code in Sparc/generic.s to call the libm rint() routine.

048  v0.31 (971031 / lth)  Fixed 9711?? by lth

     Consider the following scenario:

     > (read)
     #<EOF>
     >

     everest%

     I.e., if the user types the end-of-file character in a program while
     the program is reading from the standard input port, then the REPL
     interprets that EOF as an exit signal.  Instead, EOF encountered during
     an evaluation should maybe be treated differently, e.g., by always
     reestablishing the I/O ports after an evaluation, and requiring another
     EOF.  Chez Scheme does it this way, and it seems much cleaner.

     FIX:
     Presumably the code to handle this was written?

049  v0.31 (971031 / lth)  Fixed 980107 by lth

     [Performance bug]
     port? needs to be a primop; see Lib/iosys.sch.

     FIX:
     Added code to Compiler/twobit.imp.sch, Lib/primops.sch, and 
     Asm/Sparc/gen-prim.sch to implement this.

050  v0.31 (971031 / lth)  Fixed 980107 by lth

     [Performance bug]
     structure? needs to be a primop; see Lib/struct.sch.

     FIX:
     Added code to Compiler/twobit.imp.sch, Lib/primops.sch, and 
     Asm/Sparc/gen-prim.sch to implement this.

051  v0.31 (971031 / lth)  Fixed 980107 by lth

     [Performance bug]
     eof-object? needs to be a primop.

     FIX:
     Added code to Compiler/twobit.imp.sch, Lib/primops.sch, and 
     Asm/Sparc/gen-prim.sch to implement this.

052 v0.32 (971103 / lth)  Fixed 981218 by wdc
    Priority: low

    [Performance bug]
    bignum->flonum is very, very slow.  The fix for this exists but
    needs to be implemented and tested.  See comments in 
    Lib/Common/flonums.sch.

    (Bignum->flonum is also very, very buggy.  See eg. bug 082, and 
     comments in the code.)

    FIX:
    Reimplemented bignum->flonum.

054 v0.32 (971107 / lth) Fixed 981214 by lth
    Priority: high.  Await new compiler before fixing.

    [Macros that work]
    When a syntactic keyword is used as a variable, e.g.,

	> repeat

    then the macro expander gives an error and returns the syntactic
    environment, which is massive.  This is _not_ useful.  On the whole,
    macro expander errors should be mapped onto regular errors?

    FIX: new macro expander fixes it.

055 v0.32 (980116 / lth)  Fixed 980116 by lth

    I/O redirection at the shell seems to be overridden by Larceny; this
    may have something to do with how I/O ports are handled?

    FIX:
    Turned out that in conio.sch, there was a single global variable
    to record 'first time through' and thereby allow the use of the
    standard i/o streams; there should be one variable for input and
    one for output.  This was implemented, and redirection now works
    correctly.

058 v0.32 (980423 / will)  Fixed 980424 by lth

    Since -1.0 is the mathematically ideal result of
    (- (expt 2. 100) (+ (expt 2 100) 1)), the R5RS says that

        (zero? (- (expt 2. 100) (+ (expt 2 100) 1)))

    should evaluate to #f, not to #t.  Scheme48 gets this right, but it is
    the only implementation I have found that does.  This is probably a
    common bug in implementations of Scheme.

    [This is curious, because it is the case in Larceny that
     (= (inexact->exact (expt 2.0 100)) (expt 2 100)).  One notes that
     (- (expt 2.0 100) (+ (expt 2 100) 1)) => 0.0, which is wrong, hence
     some contagion rule gets it wrong here. --lars]

    FIX:
    Changed the contagion matrix for arithmetic.

059 v0.32 (980423 / wdc) Fixed 981203 by lth
    Priority: low

    Brad Lucier noted a problem with the complex contagion rule in Common 
    Lisp.  The mathematically ideal result for

        (let ((z (make-rectangular +inf +inf))
          (* 1. z))

    is z itself.  Chez Scheme gets this right, but Larceny 0.32 gets it wrong.

    Notes:
    Produces +nan.0+nan.0i in 0.33 also.  Works for finite values in z.
    The reason is that +inf.0 * 0 -> invalid operation in IEEE arithmetic.

    The rule should be: a+bi * c = (make-rectangular (* a c) (* b c)).
    Seems most reasonable to implement this in Lmul_comp2 in generic.s.

    Also watch the case where it's (* 1 z) rather than (* 1. z).

    FIX:
    Implemented the new rule in Sparc/generic.s.

060 v0.33 (980425 / lth) Fixed 981203 by lth
    Priority: low

    This is the same problem as for the (fixed) bug 058, but for complex
    numbers:

      (- (+ 1 (make-rectangular (expt 2 100) 1))
         (make-rectangular (expt 2.0 100) 1.0))
    => 0.0

      (= (+ 1 (make-rectangular (expt 2 100) 1))
         (make-rectangular (expt 2.0 100) 1.0))
    => #t

    Larceny could do better here (and return 1 in the first case, #f in the
    second).  The first bug is in contagion; the second in econtagion.

    The case is rectnum OP compnum where one of the components of the
    rectnums is a bignum that is not exactly representable as a flonum.
    Contagion coerces the rectnum to a compnum, but that's wrong, because
    the compnum _is_ exactly representable as a rectnum.  So the right
    thing to do is to convert the compnum to a rectnum if it is representable,
    otherwise to convert the rectnum to a compnum.

    FIX:
    Changed the contagion matrices as required.

061 v0.33 (980428 / lth)  Fixed 980428 by lth

    Logand, logior, logxor cannot cope with the largest negative fixnum,
    and exhibit the following behavior:
	
	> (logand -536870912 1)
	Error: exception-handler: confused about logand

    The reason for the bug is the tag check used in the implementation:

      (sparc.tsubrcc as $r.result tmp $r.g0)
      (sparc.bvc.a   as L1)

    Of course, the overflow flag will _also_ be set if there was a true
    overflow from the subtraction!

    FIX: Implemented the correct tag checking code.

063 v0.34 (980511 / lth)  Fixed 980511 by lth

    The definition of 'vector' in sparc.imp.sch is either buggy (not likely)
    or provokes a bug, e.g. in the call to vector in mcode.sch (more likely).
    In any event, if enabled then Larceny fails during startup during the 
    first call to environment-set! with the error 

	Error: Wrong number of arguments to procedure #<PROCEDURE>

    FIX: This was an off-by-one bug in emit-init-proc-slots! in gen-msi.sch.

064 v0.34 (980514 / lth)  Fixed 981215 by lth
    Priority: high.  Await new compiler before fixing.

    From: comp.lang.scheme
      1) STk way
         (call-with-current-continuation (lambda (exit) (exit (values 1 2))))
         ==>                                            ^^^^^^^^
           1
           2

     2) SCSH way
        (call-with-current-continuation (lambda (exit) (exit 1 2)))
         ==>
           ; 2 values
           1
           2

    As far as I understand r5rs, it says nothing about the issue, but
    my gut feeling is that the SCSH way is more elegant.

    BTW, SCSH's `values' also checks its arguments for not being 
    multiple-valued.

    In Larceny 0.34, we have:
      >(call-with-values 
         (lambda () 
           (call-with-current-continuation (lambda (k) (values 1 2 3)))) 
         (lambda (a b c) 
           (list a b c)))
     (1 2 3)
     > (call-with-values 
         (lambda () 
           (call-with-current-continuation 
             (lambda (k) (k 1 2 3)))) 
           (lambda (a b c) 
             (list a b c)))
     Error: Wrong number of arguments to procedure #<PROCEDURE>

    And it appears the last one is probably wrong: k should take 3
    arguments, but apparently receives only one, which can be seen
    from:

     > (call-with-values 
        (lambda ()
          (call-with-current-continuation 
            (lambda (k) (k 1 2 3)))) 
        (lambda a a))
    (1)

    (Arguably, there's a bug in Lib/malcode.mal because the closure
    passed as k does not check the number of arguments it receives!)

    FIX: implemented the correct code in malcode.mal.

065 v0.34 (980518 / lth) Fixed 981202 by lth
    Priority: low

    This applies to Larceny.  See code from Will in Lib/mcode.sch,
    and see item 066.

    From: jlrubin@no_meat_byproducts.bway.net (Josh Rubin)
    Subject: exact->inexact implementation question
    Newsgroups: comp.lang.scheme
    Date: Mon, 18 May 1998 11:27:38 GMT
    Organization: ISPNews http://ispnews.com
    
    The Scheme standard requires that exact->inexact applied to a rational
    number return the nearest representable inexact number. Assuming
    inexact numbers are IEEE doubles, how does one do this
    conversion?  The code I have seen for this conversion
    ( the Gnu bignum package Rational.as_double() ) is buggy.
    
    Converting the numerator and denominator to double and then dividing
    rounds  three times and doesn't always produce the closest result.
    
    The only way I can think of is to do a multi-precision integer
    division to get (1 + mantissa length) bits of accuracy in the quotient
    and then building a double "by hand". 
    
    Josh Rubin
    jlrubin@no_meat_byproducts.bway.net    Remove spam blocker to reply.

    FIX:
    Adapted code from Will to do the right thing.

066 v0.34 (980518 / wdc)  Fixed 981203 by lth
    Priority: low

    Test case: (exact->inexact 14285714285714285714285) should be
    1.4285714285714286e22, not 1.4285714285714284e22.

    [See also item 065.]

    FIX: added to test suite.

070 v0.34 (981006 / lth)  Fixed 981113 by lth
    Priority: low

    Writer: should print all the special names accepted by the reader:

	> #\tab
	#\	
	> #\space
	#\space

    Here the bug is in the printing of a tab character.

    FIX: Implemented the necessary logic in Lib/print.sch, Lib/reader.sch,
    and Lib/unix.sch (character codes).

072 v0.34 (981113 / lth)  Fixed 990929 by lth
    Priority: medium.
    Category: LIB, TWOBIT / user-friendliness

    The (break) procedure always invokes the RTS debugger.  It would be
    more useful if it would invoke the user-installable breakpoint handler,
    if that has been installed.  The current behavior should be renamed
    as 'debugvsm'.

    Fix: made BREAK invoke the value of a new BREAK-HANDLER parameter.

073 v0.36 (981203 / lth) Fixed 981203 by lth
    Priority: low

    We lose precision someplace:

	> (string->number (string-append "#b" (number->string (sqrt 2) 2)))
	1.4142135623730954
	> (sqrt 2)
	1.4142135623730951

    FIX: this was fixed when rounding was fixed (see bug 047).

075 v0.36 (981207 / lth) Fixed 981214 by lth
    Priority: high

    Jaffer's test suite:

	> (letrec ((x 3)) (define x 10) x)
	Error: Reference to undefined global variable `define'.

    This is a macro expander bug:

	Larceny v0.36 (precise:SunOS5:split) (lth 07-Dec-98 09:50:13)

	> (macro-expand '(letrec ((x 3)) (define x 10) x))
	((lambda (x) (begin (set! x '3) (define x '10) x)) '#!unspecified)

    Await new macro expander.  Search for BUG IN LARCENY in r4rstest.scm.

    FIX: new macro expander fixes it.

076 v0.36 (981207 / lth) Fixed 981207 by lth
    Priority: high

    Jaffer's test suite:

	> (string->number "")
	Error: car: () is not a pair.

    [Should return #f.]

    FIX:
    parse-number in string->number expects a nonempty list of characters;
    made sure that if input is empty, #f is returned straightaway.

078 v0.36 (981207 / lth) Fixed 981207 by lth
    Priority: high.

    Jaffer's test suite:

    Close-input-port on an already-closed input port fails.  This
    is by design in Larceny but the R5RS clearly states that it's
    ok to close an already-closed port.

    FIX:
    close-input-port and close-output-port work around the problem w/o
    affecting the lower-level I/O system.  (Somewhat of a hack.)

079 v0.36 (981207 / lth)  Fixed 981207 by lth
    Priority: high.

    Jaffer's test suite:

	(#<PROCEDURE modulo> 33333333333333333333 -3)  ==> -3
	 BUT EXPECTED 0
	(#<PROCEDURE modulo> 2177452800 -86400)  ==> -86400
	 BUT EXPECTED 0
	(#<PROCEDURE modulo> -2177452800 -86400)  ==> -86400
	 BUT EXPECTED 0

    FIX: changed modulo in Lib/Common/number.sch.


080 v0.36 (981207 / lth)  Fixed 981207 by lth
    Priority: high

    This isn't even remotely right
	> (modulo  33333333333333333333 -3.0)
	1362.0

    Notes:
    Note that
	> (modulo  33333333333333333333.0 -3.0)
	0.0
    which is nearly the right answer (it should in principle be -0.0).

    The problem seems to be in modulo: rather than using algorithm*, which
    it should, it ends up doing mixed exact/inexact arithmetic with resulting
    loss of accuracy.

    FIX: made sure all computation happens using exact arithmetic.  It
    still returns 0.0 rather than -0.0; this wouldn't be hard to fix but
    await work to clean up IEEE arithmetic.

081 v0.36 (981207 / lth, previously reported by wdc)  FIXED 9812014 by lth
    Priority: high

    In the interpreter, but not in the compiler:

	> (begin (define (x) 1) (define (y) 2))
	Error: symbol-hash: (x) is not a symbol.

    This is a macro expander bug, as can be seen from

	> (macro-expand '(begin (define (x) 1) (define (y) 2)))
	(begin (define (x) '1) (define (y) '2))

    The definitions should have been rewritten to canonical form, but
    were not.

    FIX: New macro expander took care of it.

082 v0.37 + new compiler (981214 / lth) Fixed 981218 by wdc
    Priority: high.

	> (log (fact 256))
	Error: <: -364.0037127757854+4.532360141827194i is not a real number.

    In fact: 

	> (exact->inexact (fact 180))
	Error: log: Domain error: 0.0

    And furthermore, we see that bignum->flonum is again the culprit:

	(bignum->flonum (fact 180))
	-6.216419369289196e-288

    Here, it should have returned +inf.0.

    FIX: 
    Re-implemented bignum->flonum.

085 v0.39 (981216 / lth)  Fixed 2000-09-xx by wdc/lth
    Priority: medium
    Category: LIB, INTERPRETER, TWOBIT / correctness
    See also: 084, 099, 153

    Environments should contain syntax environments, and both 
    compile-expression (Compiler/compile313.sch) and macro-expand 
    (Eval/macro-expand.sch) should allow any environment to be used.

    [In any case the current setup is not the right thing.]


086 v0.39 (981216 / lth) Fixed 990928 by lth
    Priority: low
    Category: RTS / correctness

    With -stats switch, Larceny does not print size of text/static area, 
    if there's one; see print_heapstats() in Rts/Sys/stats.c.

    Fix: implemented support for proper static area stats in stats.c, 
    memmgr.c, and static-heap.c.

090 v0.40 (981219 / lth ) Fixed (date unknown year 2000) by wdc
    Priority: medium.
    Category: TWOBIT / performance

    With (integrate-usual-primitives #f), calls to the primitives 
    .make-cell, .cell-ref, and .cell-set! are compiled as normal 
    procedure calls.  This runs correctly -- I've added the correct
    names to the environment -- but code that uses assignments takes
    a performance hit.

    The way to fix this may be to make (integrate-usual-primitives #f) not
    change the way the compiler operates but instead just reduce the
    primitive table to contain the name:* primitives.

091 v0.40 (981219 / lth ) Fixed 2002-11-17 by lth
    Priority: medium.
    Category: TWOBIT / correctness

    The macro expander generates calls to procedures (unspecified) and 
    (undefined).  With (integrate-usual-primitives #f), this is incorrect 
    -- either these should be the procedures (.unspecified) and (.undefined),
    in which case see Bug 090, or they should be the correct constants.

    Fixed by changing Compiler/prefs.sch and the primitive tables.

092 v0.40 (981219 / lth) Fixed 990416 by wdc
    Priority: medium.

    SPARC Assembler error.

    When compiling Testsuite/GC/nucleic2.sch with benchmark-block-mode,
    the assembler signals an error in sparcutil.sch:emit-const->register!
    called from gen-msi.sch:emit-register->global! (setglbl), because
    there the former cannot handle more than 1023 global variables -- 
    the constant vector offset is too large.

    This should be easy to fix if the offset is always known when
    emit-const->register! is called.  If that is not the case, then
    we must implement another crock like `short-effective-addresses'.

093 v0.41 (981221 / lth) Fixed 990414 by wdc
    Priority: high.

    Macro expander error.

    'Case' really ought to do better when the constants are fixnums,
    symbols, characters; currently it just expands to a call to memv.

    Consider, for example, this, which is pretty slow:

	(define (fibonacci n)
	  (case n
	    ((0)  0)
	    ((1)  1)
	    (else (+ (fibonacci (- n 2)) (fibonacci (- n 1))))))

    This is a problem with an interaction between the LETREC* scope
    of the usual macros and the order of definition of the macro for
    CASE and the inline for MEMV.

	> (macro-expand '(case x ((0 1) 'a) ((2 3) 'b) (else 'c)))
	((lambda ()
	   ((lambda (.temp|1|4)
	      (if (memv .temp|1|4 '(0 1))
	        'a
	        (if (memv .temp|1|4 '(2 3)) 'b 'c)))
	    x)))

	> (macro-expand '(memv x '(0 1 2)))
	((lambda ()
	   ((lambda (.t0|2|3|6 .t1|2|3|6)
	      (if (eq? .t0|2|3|6 '0)
	        .t1|2|3|6
	        ((lambda (.t1|2|3|10)
	           (if (eq? .t0|2|3|6 '1)
	             .t1|2|3|10
	             ((lambda (.t1|2|3|14)
	                (if (eq? .t0|2|3|6 '2)
	                  .t1|2|3|14
	                  ((lambda (.t1|2|3|18) '#f) (cdr .t1|2|3|14))))
	              (cdr .t1|2|3|10))))
	         (cdr .t1|2|3|6))))
	    x
	    '(0 1 2))))

    This problem results in *major* lossage on LATTICE.

096 v0.41 (981221 / lth) Fixed 990108 by lth
    Priority: high.

    RTS error.

    Strings passed to the routines in Rts/Sys/unix.c are limited to
    1023 characters because getstring() has an internal buffer of length 1KB.
    For example,  (system very-long-command) fails.

    FIX:
    Implemented appropriate buffer alloction in getstring().

097 v0.41 (981221 / lth)  Fixed 981221 by lth
    Priority: low

    Disassembler does not work properly in Chez Scheme; try

	> (disassemble (assemble (compile '(lambda (x) (car x)))))
	Segment # #f

	Error: variable bytevector-word-ref is not bound.
	Type (debug) to enter the debugger.

    FIX:
    Copied the procedure over from the Larceny compatibility library.

103 v1.0a1 (990104 / lth)  Fixed 2000-09-xx by wdc/lth
    Priority: medium.
    Category: TWOBIT / quality-of-implementation
    See also: 090, 091

    Macro expander bug.

    This should be easy to fix.  

	Date: Fri, 18 Dec 1998 17:48:22 -0500
	From: Lars Thomas Hansen <lth@ccs.neu.edu>

	[This is with up-to-date sources except sparc.imp.sch]

	As far as I'm concerned, this is a minor annoyance: it's not entirely
	reasonable for Twobit to warn me with (integrate-usual-procedures #f).
	I can imagine differing opinions on the matter.

	> (integrate-usual-procedures #f)
	#f
	> (define + (lambda (a b) (cons a b)))
	WARNING from macro expander:
	Redefining 
	+
	+
	> (+ 1 2)
	(1 . 2)

    Fixed as a result of more sophisticated handling of syntax
    environments and inline procedures.

104 v1.0a1 (990107 / wdc)
    Priority: medium

    Twobit is generating executable code for calls to UNSPECIFIED
    in command positions.

    Fixed 990405 / wdc: POST-SIMPLIFY-BEGIN now cleans this up.

105 v1.0a1 (990107 / wdc)
    Priority: high

    Twobit is generating very poor code for named LET.

    Test case:

	> (define (test1)
	    (do ((i 0 (+ i 1))
		 (j 0 (+ j 1)))
		((= i 100000000) j)))
	test1
	> (define (test2)
	    (let loop ((i 0) (j 0))
	      (if (= i 100000000)
		  j
		  (loop (+ i 1) (+ j 1)))))
	test2
	> (time (test1))
	Words allocated: 474
	Words reclaimed: 0
	Elapsed time...: 4280 ms (User: 4270 ms; System: 0 ms)
	Elapsed GC time: 0 ms (in 0 collections.)
	100000000
	> (time (test2))
	Words allocated: 482
	Words reclaimed: 0
	Elapsed time...: 15787 ms (User: 15650 ms; System: 0 ms)
	Elapsed GC time: 0 ms (in 0 collections.)
	100000000

    Fixed 990312 / wdc: changed the macro for named LET in Compiler/usual.sch
    by introducing a preliminary let and not returning a procedure.

107 v1.0a1 (990122 / lth)
    Priority: high.

    The macro for CASE is wrong -- it generates incorrect code for CASE
    without an ELSE:

	> (make-readable 
	    (macro-expand 
	      '(lambda (x)
	         (case (car x)
	           ((codevector)
	            (dump-codevector! #f (cadr x)))
	           ((constantvector)
	            (dump-constants (cadr x)))))))
	((lambda ()
	   (lambda (.x|1)
	     ((lambda (.temp|2|5)
	        (if (memv .temp|2|5 '(codevector))
		  (dump-codevector! '#f (car (cdr .x|1)))
	          (dump-constants (car (cdr .x|1)))))
	      (car .x|1)))))

    The reason appears to be that ELSE is missing from the keyword list in
    the nested letrec-syntax in the definition of CASE in usual.sch.

    Fixed 990312 / wdc: changed macro for CASE in Compiler/usual.sch by
    adding ELSE to the keyword list of nested macro.

108 v1.0a1 (990208 / lth)
    Priority: medium.
    Category: RTS / correctness

    Very large fixnums that result in address wrap-around make some 
    allocation primitives crash the system:

	> (make-vector (- (expt 2 29) 4))

	Process scheme segmentation violation (core dumped)

	> (make-bytevector (- (expt 2 29) 4))

	Process scheme segmentation violation (core dumped)

    Fixed 991121 by lth: Hacked the millicode to check correctly
    for available space.  Hacked the assembler to emit code that deals
    with overflow during size calculations.  Introduced several
    low-priority bugs to document aspects not handled by the fixes.

109 v1.0a1 (990317 / lth; wdc)
    Priority: high.

    Twobit fails to detect bugs like

	(lambda (x x) ...)

    This can cause the system to crash with a segmentation fault;
    consider this test case:

	(define (exhibit-bug)

	  (define internal-name #f)

	  (define (goto x . inputs)
	    (apply x inputs))

	  (define (internal-name random-input)
	    (set! internal-name #f)
	    (goto internal-name 'something))

	  (goto internal-name 'something))

    Fixed 990405 / wdc: M-LAMBDA now detects this.

110 v1.0a1 (990317 / lth)
    Priority: medium.

    The macro-expansion of DO is not the best possible: if there are no
    expressions in the test, then the test is evaluated for its value and
    that value is returned.  This results in slower code for the test and is
    not required by the Report.  Eg.

	(do ((i 0 (+ i 1)))
	    ((= i 100))
          ...)

    appears to get expanded as 

	(letrec ((loop (lambda (i)
                         (let ((i (= i 100)))
                           (if i i (begin ... (loop (+ i 1))))))))
          (loop 0))

    when it could be expanded as

	(letrec ((loop (lambda (i)
                         (if (= i 100) 
                             #!unspecified
	                     (begin ... (loop (+ i 1)))))))
          (loop 0))

    or indeed as

	(letrec ((loop (lambda (i)
                         (if (not (= i 100))
	                     (begin ... (loop (+ i 1)))))))
          (loop 0))

    Fixed 990405 / wdc: Changed DO macro.
   
111 v1.0a1 (990317 / lth)  Fixed at unknown date by wdc
    Priority: high
    Category: TWOBIT / correctness

    [This may have been fixed when bug 109 was fixed, but I haven't
    yet checked. - wdc]

    Message-Id: <199903171640.LAA27566@vega.ccs.neu.edu>
    To: will@ccs.neu.edu
    Subject: Re: Twobit bug 
    Date: Wed, 17 Mar 1999 11:40:46 -0500
    From: Lars Thomas Hansen <lth@ccs.neu.edu>

    I also found another bug just now -- another coredump.  I haven't
    investigated it because I have other things to do and I managed to work
    around it, but I saved the pertinent data and information.  Again it
    appears to be related to a (large) nest of internal definitions.  
    The tar file with the information is
    /home/lth/net/larceny/compiler-bug-990317.tar, in case you're
    interested.  (It could be an assembler error as well as a compiler
    error.)

    Tested in 0.45 and found to have been fixed.

115 v0.34 (981016 / wdc)
    Priority: medium

    [Performance bug]
    If the second or third argument to a primop is a register variable,
    then it is unnecessarily copied to another register before the
    operation is performed.

    FIX:
    New code generator.

116  v0.34 (981016 / wdc)
     Priority: medium

     [Performance bug]
     Nested non-tail calls save the same registers several times.

    FIX:
    New code generator.

117 v0.34 (981016 / wdc)
    Priority: medium

    [Performance bug]
    Known local procedures should not be lifted out of lambda
    expressions that escape.

    FIX:
    New code generator.

118 v0.34 (981016 / wdc)
    Priority: low

    [Performance bug]
    Passing more than one argument to LIST results in a real call
    instead of inlined calls to CONS.  Also, tail calls to LIST
    are compiled as non-tail calls.

    FIX:
    New pass 1.

119 v0.34 (981016 / wdc)
    Priority: high

    Known local procedures that take a variable number of arguments
    are not rewritten to take a fixed number of arguments if the
    local procedure is bound by LET instead of LETREC.  Example:

         (let ((foo (lambda args args)))
           (foo x1 x2 x3 x4 x5 x6 x7 x8 x9 x10))

         ((lambda ()
            (define .foo_3 (lambda .args_2 .args_2))
            (.foo_3 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10)))

    FIX:
    SIMPLIFY-LET now calls STANDARDIZE-KNOWN-CALLS.

120 v1.0a1 (990324 / wdc) Fixed: 990416 wdc
    Priority: low

    [Performance bug]
    LET expressions allocate registers even when the value of a
    LET-bound variable comes from an existing register variable.
    Pass 3 should fix this.

    FIX: Copy propagation, provided (common-subexpression-elimination).

121 v1.0a1 (990325 / lth)
    Priority: high

    [Assembler bug]
    Consider:

	((lambda () 10.0))

    In 1.0a1 this returns '0', as will 

	((lambda () 1/2))

    The bug appears to be in the assembler.  The peephole optimizer
    generates a const/return operation, but the assembler emits incorrect
    code for the operation.

    Fixed 990405 / wdc: Changed immediate-int? in sparcutil.sch.

122 v1.0a1 (990329 / wdc)
    Priority: high

    Pass 1 of Twobit sometimes computes the referencing information
    incorrectly because m-set is calling remq! for its result.  This
    reduces the effectiveness of closure analysis and probably causes
    incorrect code to be generated also (although I have no test case
    to show this).  Test case:

    (let ()
      (define (make-ht hashfun searcher size) 0)
      (define (substitute1 x y z) (substitute1 1 2 3))
      (define (put! ht key val) 0)
      (put! 0 0 0))

    Fixed 990329 / wdc: Changed use of remq! to a use of remq.

124 v1.0a1 (990421 / lth)
    Priority: medium
    Category: LIB / correctness

    WITH-INPUT-FROM-PORT and WITH-OUTPUT-TO-PORT (which are also used by
    WITH-INPUT-FROM-FILE and WITH-OUTPUT-TO-FILE) are not behaving 
    correctly if the thunk jumps out of the dynamic context and then
    back in again.  The input port in effect inside the procedure remains
    in effect outside the procedure, and any change to the input port
    outside the procedure is visible inside the procedure after the jump
    back in.  Ditto for output-ports.  Easy to fix with dynamic-wind.

    Fixed 990??? / lth: wrapped the procedures with dynamic-wind.


127 v0.43 (990629 / lth)
    Priority: high
    Category: TWOBIT

    Incorrect or incomplete error codes and values are being passed 
    to the error handler with the new compiler:

	Larceny 0.43, larceny.heap:

	> (define (foo x) (vector-ref x 10))
	foo
	> (foo #t)
	Error: +: #t is not a number.
	> (foo (make-vector 10))
	Error: +: #(() () () () () () () () () ()) is not a number.

    This error is also a suspect in crashes (core dumps) I've observed.

    Fixed 990706 / lth: The problem was that emit-trap!, in sparcutil.sch,
    did not convert its exception code to a fixnum.

128 v0.43 (990701 / lth)  Fixed 2000-09-12 by lth
    Priority: medium
    Category: RTS / correctness

    When we use the conservative collector with ALL_INTERIOR_POINTERS=0,
    then some tricky code in the RTS that allocates a single chunk of 
    memory and splits it into multiple objects won't work.  The places
    where this occurs are _at_least_ the following (I have not scanned
    the sources completely):

       Rts/Sys/stats.c, for memstats structure
       Rts/Sparc/cglue.c, for rest args
       Rts/Sys/argv.c, for arg vector and strings
       Rts/Standard-C/millicode.c, for rest args
       Rts/Sys/ffi.c, for args to Scheme callbacks

    Impact: current fixes are enough to allow benchmarking, but the
    others must be fixed.

129 v0.43 (990709 / lth)  Fixed 2000-09-14 by wdc
    Priority: low
    Category: TWOBIT / correctness

    The macro expander incorrectly gives a warning about empty top-level 
    BEGIN forms:

	> (begin)
	WARNING from macro expander:
	Non-standard begin expression
	(begin)

130 v0.43 (990715 / lth)  Fixed (date unknown, year 2000) by wdc
    Priority: medium
    Category: TWOBIT / correctness

    Twobit is confused by the following program, which uses a trick to ensure
    that knowledge of the default fill is only encoded in the compiler.  I use
    a similar trick for make-vector; it signals an error for that too.


    > (compile '(define make-string
	          (lambda (x . rest)
		    (if (null? rest)
	  	        (make-string x)
		        (make-string x (car rest))))))
    WARNING from macro expander:
    Redefining 
    make-string
    Error: Wrong number of arguments to integrable procedure(make-string .x|1)

131 v0.43 (990816 / lth)
    Priority: medium
    Category: ASSEMBLER, LIB / correctness

    These are the wrong error messages:

	> (fx* (expt 2 28) 4)
	Error: set-cdr!: 268435456 is not a pair.

	> (fx+ (expt 2 28) (expt 2 28))
	Error: exception-handler: confused about fx+

	> (fx- (expt 2 28) (- (expt 2 28)))
	Error: exception-handler: confused about fx-

	> (fx-- (expt 2 29))
	Error: exception-handler: confused about fx--

    (The ordering procedures and fxnegative?, fxpositive?, fxzero? get 
    it right.)

    Diagnosis.

    The disassembled code for fx+, fx-, fx-- looks right (passes the
    right codes), so it's probably decoding that gets it wrong.  Clearly, 
    the fix-binop and fix-unop cases in Lib/Common/ehandler.sch do not 
    deal with overflow, so that's where the 'confused' messages come
    from.  Also, the assembler passes the arguments 0 X for (fx-- X),
    which is confusing.

    In the case of fx*, there are _two_ errors in the fixnum-arithmetic
    case of emit-multiply-code in Asm/Sparc/sparcprim-part1.sch.  First,
    $ex.mul is being passed native, not as a fixnum.  Second, it should
    be $ex.fxmul (though this code does not yet exist), passed as a 
    fixnum, and then the exception handler must be set up to deal with
    that eventuality.

    Fixed 990816 by lth

    Hacked the assembler and the error handler as described above.

132 v0.43 (990715 / lth)
    Priority: medium
    Category: RTS / space usage

    It would appear, according to output from -annoy-user, that the space
    assigned to remembered sets grows monotonically, which is not what
    we would like -- space should be returned to the common pool
    whereever possible.  Most reasonably, pool memory should be freed
    when a remset is cleared.

    Fixed 991022 by lth in post-v0.46.

134 v0.45 and all earlier (990915 / lth)  Fixed 990928 by lth
    Priority: medium
    Category: RTS measurements / correctness

    The number of words copied and moved are overreported by factors of four, 
    because the stats module does not convert bytes to words when computing
    these fields.

    Fix: added the necessary calculations to Rts/Sys/stats.c.

135 v0.45 and many earlier (990920 / lth)
    Priority: high
    Category: RTS / correctness

    The millicode call $m.gc always triggers a garbage collection.  This
    is wrong, because $m.gc is called from the inline allocator due to
    storage exhaustion, but the correct remedy is not always to collect --
    in the stop/copy collector, the correct remedy is to move to the
    next chunk.  In the current system it always collects, leading to
    excessively high collection times for the stop+copy system.

    Has been fixed in the radioactive99 system; the fix (involving memory.s, 
    cglue.c, gc.c, gc_t.h, gc_t.c, young_heap_t.h, young_heap_t.c, sc-heap.c,
    nursery.c, bdw-collector.c) must be ported.

    Fixed 990928 by lth by renaming M_GC as M_MORECORE and implementing
    code in memory.s, cglue.c, young_heap_t.*, sc-heap.c, nursery.c.
    Avoided changing GC interface by having cglue.c call a yh_ method
    directly.

136 v0.45 (??? / lth)  Fixed 000912 by wdc
    Priority: high
    Category: TWOBIT / correctness

    Interaction of toplevel BEGINs with DEFINEs.  The macro
    
    (define-syntax define-values
      (syntax-rules ()
        ((define-values (?v1 ?v2 ...) ?expr)
         (begin
           (define __super-secret-variable-name
             (call-with-values 
              (lambda () ?expr)
              (lambda values values)))
           (define-values #t (?v1 ?v2 ...) __super-secret-variable-name 0)))
        ((define-values #t () ?v ?n)
         (set! ?v #f))
        ((define-values #t (?v1 ?v2 ...) ?v ?n)
         (begin
           (define ?v1 (list-ref ?v ?n))
           (define-values #t (?v2 ...) ?v (+ ?n 1))))))
    
    run on the code
    
    (define-values (a) (values 1))
    
    expands as 
    
    ((lambda ()
       (begin
         (begin
           (set! .__super-secret-variable-name|1
             (call-with-values
               (lambda () (values '1))
               (lambda .values|1|3 .values|1|3)))
           '.__super-secret-variable-name|1)
         (begin
           (set! a
             (list-ref __super-secret-variable-name '0))
           'a)
         (set! __super-secret-variable-name '#f))))
    
    but the expansion incorrectly uses an alpha-converted name for
    __super-secret-variable-name in the definition but not in later uses.

    This is clearly a bug, but it is not entirely obvious what the
    correct behavior should be.  Consider

        (define-syntax defv
          (syntax-rules ()
            ((defv ?var ?expr)
             (begin (define ?var (lambda () secret))
                    (define secret ?expr)))))

        (define secret 1)
        (define f1 (lambda () secret))
        (defv f2 2)
        (define secret 3)
        (define f3 (lambda () secret))
        (defv f4 4)

    To what should (list (f1) (f2) (f3) (f4)) evaluate?

        (3 3 3 3)    ; Chez Scheme v6.1
        (3 2 3 4)    ; Scheme 48 0.36
        (4 4 4 4)    ; Larceny after this bug was fixed

    The third possibility was chosen for Larceny because that is
    the result obtained when the DEFV macro is expanded by hand,
    and because the semantics of Chez Scheme and Scheme 48 lead
    to buggy expansions for slightly different examples.

    FIX:  DESUGAR-DEFINE must macro-expand the defined variable
    name before calling MAKE-TOPLEVEL-DEFINITION.

137 v0.45 (991013 / lth)  Fixed 000912 by wdc
    Priority: high
    Category: TWOBIT / correctness

    This was illegal in R4RS but is legal in R5RS, cf sec 5.1.  Almost
    certainly related to the logged bug #136.

    > (begin (load "../Auxlib/list.fasl")
             (define x (make-list 125000))
             (do ((i 0 (+ i 1)) (y x (reverse y))) ((= i 100) #t)))
    ERROR detected during macro expansion:
    Definition out of context
    (define x (make-list 125000))

    FIX:  Removed logic that checks for R4RS restrictions.
    (This bug was not related to bug #136, except that both bugs
    were in the same procedure.)

147 v0.48 (991123 / lth)  Fixed 2000-09-14 by wdc
    Priority: medium
    Category: TWOBIT / correctness

    The macro expander barfs on an incorrect use of ASSV:
	> (macro-expand '(assv x))

	Error: car: () is not a pair.
	Entering debugger; type "?" for help.
	debug> b
	=> compiled procedure debug/enter-debugger
	   system continuation
	   compiled procedure #f
	   compiled procedure m-transcribe-low-level
	   compiled procedure #f
	...
	debug> 2 d
	compiled procedure #f
	debug> c
	(lambda (exp rename compare)
	  (let ((arg1 (cadr exp)) (arg2 (caddr exp)))
	    (if (or (boolean? arg1)
	            (char? arg1)
	            (and (pair? arg1)
	                 (= (length arg1) 2)
	                 (identifier? (car arg1))
	                 (compare (car arg1) (rename 'quote))
	                 (symbol? (cadr arg1)))
	            (and (pair? arg2)
	                 (= (length arg2) 2)
	                 (identifier? (car arg2))
	                 (compare (car arg2) (rename 'quote))
	                 (every1?
	                   (lambda (y)
	                     (and (pair? y)
	                          (let ((x (car y)))
	                            (or (boolean? x) (char? x) (symbol? x)))))
	                   (cadr arg2))))
	        (cons (rename 'assq) (cdr exp))
	        exp)))

    Fix: Added test to transformers for EQV?, MEMV, ASSV.

152 v0.47 (2000-01-26 / lth)  Fixed 2000-03-13 by lth
    Priority: high
    Category: Libraries / correctness

	Larceny v0.47 "'Bat' Guano" (precise:SunOS5:split) (lth 18-Nov-99 13:22:00)

	> (/ 3975757967 1e6)
	-319.209329		        ;; This is wrong, obviously
	> (/ 3975757967 10)
	-319209329/10			;; Ratnum arithmetic is broken
	
	Not an obvious optimizer bug:
	
	> (define a 3975757967)
	a
	> (define b 1e6)
	b
	> (/ a b)
	-319.209329
	
	Bug also present in 1.0a1.
	
	ratnum-div seems to do the right thing when handed the arguments, so
	what we're seeing might be ratnum-div being handed a wrongly converted
	fixnum by contagion.

	Fails in make-reduced-ratnum because

	> (quotient 3975757967 1)
	-319209329

	which is very wrong.

        The bug:

	In Petit Larceny: The bug is that the millicode that does 
	bignum/fixnum division for one-word nonnegative bignums calls 
	ga_box_int rather than ga_box_longint to box (or not) the result.

	In SPARC Larceny: similar problem: code that determined
        whether the result was a fixnum was wrong.

154 v0.48 (2000-05-05 / lth)  Fixed 2000-09-14 by wdc
    Priority: medium
    Category: TWOBIT / interface

    Some error messages are extremely hard to decipher.

	Error: Wrong number of arguments to known procedure((begin \
	\.text-extending-right|2) ((begin *) (begin .xunit|16) '0.5) \
	\((begin *) (begin .yunit|19) ((begin -) (begin .i|4) '0.5)))

155 v0.48 (2000-05-21 / lth)  Fixed 2000-09-11 by lth
    Priority: medium
    Category: DOCUMENTATION

    MSIE 5.0 on the Macintosh does not display most documents in the
    user manual correctly.  For example, in Low-level functionality
    the first entry is displayed correctly but the remaining entries
    are displayed indented relative to the first.  It could be a bug
    in how MSIE renders <DL>...</DL> or it could be a bug in how
    the Larceny pages use the HTML.

    Diagnose: It has to do with the interaction of <P> and <DD> in
    a <DL>...</DL>.  If the document is laid out with matching <P>..</P>
    tags around paragraphs inside the <DD> block, then things work
    fine, see eg procedures.html which has been fixed to do this right.
    If the <P> comes before the <DD> (and/or the </P> is missing) 
    then MSIE appears to get confused.

    The HTML in these files is pretty messy, anyway.

    Fix: went thru all files and fixed by hand... what a chore!

156 v0.48 (2000-06-03 / lth)  Fixed 2000-09-11 by lth
    Priority: medium
    Category: SPARC DISASSEMBLER

	> (define (foo) (let loop () (loop)))
	foo
	> (disassemble foo)
	Error: Can't disassemble 32c00000 at ip=24 with op2=3

    Indeed, 

	> (define (foo) (let loop () (loop)))
	foo
	> (foo)
	Illegal Instruction (core dumped)

    This appears to be an assembler bug in CLASS-SLOT or ADD1, depending
    on who one wants to blame.  The assembler wants to create the instruction 
	32 bf ff ff	bne,a	.-4
    which is what it emits first, but then a later fixup overflows
    the field and clobbers the op2 field, changing it from 010 to 011.
    What should happen is that adding 1 (really 4) to a -1 (really -4)
    should yield zero and no overflow.

    Fix: fixed ADD1 to do modolo addition in a 22-bit field.

157 v0.48 (2000-05-17 / lth)  Fixed 2000-09-11 by lth (actually before that)
    Priority: medium
    Category: LIBRARY

    STRING-UPCASE is broken.  Use the following patch instead until the fix 
    makes it into a release.  --lars

	(define (string-upcase s)
	  (string-upcase! (string-copy s)))

158 v0.48 (2000-05-17 / lth)  Fixed 2000-09-14 by wdc
    Priority: medium
    Category: TWOBIT / user-friendliness

    This is actually a problem of nongraceful handling of erroneous input.
    Twobit hangs when given a CASE clause without any expressions, e.g.

	(case x
	  ((foo))
          (else 1))

    Note, it gives the correct error message if presented with only

        (case x
          ((foo)))

159 v0.49 (2000-07-10 / lth)  Fixed 2000-09-12 by wdc
    Priority: high
    Category: TWOBIT / correctness

    Given the code

    (define (bug glarg . rest)

      (define results #f)

      (define (process-datum datum n)
	((results 'lookup)))

      (define (analyze all-data)
	(for-each-benchmark-result process-datum all-data))

      (define (mark/cons-analysis)
	(analyze glarg))

      (if (null? rest)
	  (mark/cons-analysis)
	  #t))

    Twobit produces code where the reference to `glarg' is made with a GLOBAL
    instruction.

    The output from pass3 looks OK to my eyes:

    > (make-readable (pass3 (pass2 (pass1 test))))
    ((lambda (.T13)
       ((lambda (.T14) 'bug) (set! bug .T13)))
     (lambda (.glarg|1 . .rest|1)
       ((lambda (.results|2)
	  ((lambda (.CELL:.results|2)
	     ((lambda (.process-datum|2|24)
		((lambda (.T8)
		   ((lambda (.T10)
		      (if .T10
			  ((lambda (.REG1)
			     ((lambda (.REG2)
				(for-each-benchmark-result .REG1 .REG2))
			      .glarg|1))
			   .process-datum|2|24)
			  '#t))
		    (null? .rest|1)))
		 (.cell-set! .CELL:.results|2 '#f)))
	      (lambda (IGNORED IGNORED)
		((lambda (.T4)
		   ((lambda (.T5) (.T5)) (.T4 'lookup)))
		 (.cell-ref .CELL:.results|2)))))
	   (.make-cell .results|2)))
	(unspecified))))

    FIX:  This was a bug in the frame optimization performed by
    cg-if-result (Compiler/pass4p1.sch).  That optimization cannot
    be performed if any live variables for which a phantom store
    has been emitted are no longer in registers.

160 v0.49 (2000-07-17 / lth)  Fixed 2000-09-11 by lth
    Priority: medium
    Category: LIBRARY / performance

    An obscure bug: if the symbol table is in the static area, and it is
    grown so much that it must be rehashed, then the new table is
    allocated in the collected heap.  However, the old table remains 
    in the static area, and since it is already in the remembered set
    because it contains pointers to new symbols in the collected
    heap, it will _remain_ in the remembered set and will continue to
    be scanned on all subsequent collections, even minor collections.

    In the default heap image with Twobit, the table contains some 10,000
    elements on startup, so this is not a trivial cost.

    The easiest fix is to clear the symbol table after rehashing, to
    ensure that any table in non-collected memory will not cause 
    unnecessary remembered set scanning.  As far as I can tell, this will
    make a real difference on some of the really weird results that
    are seen on the Twobit benchmark. (cf my dissertation)

    Fix: implemented just that, and ascertained that it made a difference.

161 v0.49 (2000-08-29 / lth)  Fixed 2000-09-11 by lth
    Priority: medium
    Category: LIBRARY / performance

    The random number generator will almost always go into bignums if the 
    modulus is larger than 16383, resulting in poor performance and
    increased allocation.  It does not need to do this; only if the
    modulus is 28 bits or larger does it have to do that.  The reason is
    that it does one iteration too many, growing an intermediate result
    too large.  Rather than:

    (lambda (n)
      (if (and (fixnum? n) (< n 16384))
          (random14 n)
          (loop n (random14 16384) n)))))

    we should have

    (lambda (n)
      (if (and (fixnum? n) (< n 16384))
          (random14 n)
          (loop (quotient n 16384) (random14 16384) n)))))

162 v0.48 (2000-08-29 / lth)  Fixed 2000-09-13 by wdc
    Priority: high
    Category: TWOBIT / correctness

    This might be a bug in assignment elimination or it might be the same
    bug I reported a few weeks back (#159), in fact it is very plausible
    that it is, as it has the same structure.  However in that case it
    appeared to be a bug in pass4, this time it is in pass3.

    Consider

       (define (twobit-bug)

	 (define type 'latex)

	 (define (stats)
	   (foo (if (eq? type 'latex) 9 10000)))

	 (call-it stats))

       (define (foo x) #t)
       (define (call-it x) (x))

    Now 

       > (make-readable (pass3 (pass2 (pass1 test))))

       ((lambda (.T10)
	  ((lambda (.T11) 'twobit-bug)
	   (set! twobit-bug .T10)))
	(lambda ()
	  (define .twobit-bug|2
	    (lambda ()
	      ((lambda (.type|4)
		 ((lambda (.CELL:.type|4)
		    ((lambda (.REG1)
		       ((lambda (.T8) (call-it .REG1))
			(.cell-set! .CELL:.type|4 'latex)))
		     (lambda ()
		       ((lambda (.T4)
			  ((lambda (.REG1) (foo .REG1)) (if .T4 '9 '10000)))
			(eq? .type|4 'latex)))))
		  (.make-cell .type|4)))
	       (unspecified))))
	  (.twobit-bug|2)))

    Observe that a cell is introduced for the local TYPE.  Then the cell is
    given its value before the value is used, but the EQ? test does not use
    the contents of the cell; rather, it picks up the unspecified value that
    is in .TYPE|4.

    Replacing (if (eq? type 'latex) 9 10000) by simply (eq? type 'latex)
    does not get rid of the cell but the output from pass3 now looks
    correct.  Ditto if the symbol IF is replaced by the name of some global
    procedure.

    Fix:  This was a bug in pass 2.  Control optimization was not
    preserving Twobit's referencing invariants, on which assignment
    elimination depends.

163 v0.51 (2002-01-18 / lth)  Fixed 2002-01-19 by lth
    Priority: medium
    Category: LIB / correctness

    Bignum remainder does not handle the signs correctly.  Test case:
      (remainder 3303030303030 -12345566789012)
    should return
      3303030303030
    but returns
      -3303030303030

    Fix:  Fixed bignum-remainder to compute the sign the way RnRS
    requires.

164 v0.51 (2002-01-18 / lth)  Fixed 2002-01-18 by lth
    Priority: medium
    Category: LIB / correctness

    Bignum bug: This would result in a division by zero error:
      (/ 0 4217293152016490)

    Fix:  Don't remember.

165 v0.51 (2002-01-18 / lth)  Fixed 2002-01-18 by lth
    Priority: medium
    Category: LIB / correctness

    Bignum bug: This used to return an illegal ratnum (both numerator
    and denominator were negative):
       (/ -123234566789000009 -1234512345000)

    Fix:  Made sure that only a positive second argument was passed
    to make-reduced-ratnum from bignum-divide.
