clasp-developers / clasp

clasp Common Lisp environment
https://clasp-developers.github.io/
2.58k stars 145 forks source link

LET doesn't bind specials in parallel (again) #1481

Open g000001 opened 1 year ago

g000001 commented 1 year ago

Describe the bug

Same issue as #69

STAK from famous gabriel benchmarks:

;;; STAK -- The TAKeuchi function with special variables instead of parameter
;;; passing.

(defvar *stak-x*)
(defvar *stak-y*)
(defvar *stak-z*)

(defun stak-aux ()
  (if (not (< (the fixnum *stak-y*) (the fixnum *stak-x*)))
      *stak-z*
      (let ((*stak-x* (let ((*stak-x* (the fixnum (1- (the fixnum *stak-x*))))
                            (*stak-y* *stak-y*)
                            (*stak-z* *stak-z*))
                        (stak-aux)))
        (*stak-y* (let ((*stak-x* (the fixnum (1- (the fixnum *stak-y*))))
                            (*stak-y* *stak-z*)
                            (*stak-z* *stak-x*))
                        (stak-aux)))
        (*stak-z* (let ((*stak-x* (the fixnum (1- (the fixnum *stak-z*))))
                            (*stak-y* *stak-x*)
                            (*stak-z* *stak-y*))
                        (stak-aux))))
    (stak-aux))))

(defun stak (*stak-x* *stak-y* *stak-z*)
  (stak-aux))

(lisp-implementation-type)
→ "clasp"

(lisp-implementation-version)
→ "cclasp-boehmprecise-2.3.0-120-gbbe2d9d57-cst"

;;; `stak-aux` decriments special variable infinitely...
(stak 18 12 6) >>>  illegal hardware instruction

Expected behavior

(stak 18 12 6) → 7

cf. lambda binds special variable in parallel properly.

(defun stak-aux ()
  (if (not (< (the fixnum *stak-y*) (the fixnum *stak-x*)))
      *stak-z*
      ((lambda (*stak-x* *stak-y* *stak-z*)
         (stak-aux))
       ((lambda (*stak-x* *stak-y* *stak-z*)
          (stak-aux))
        (the fixnum (1- (the fixnum *stak-x*)))
        *stak-y*
        *stak-z*)
       ((lambda (*stak-x* *stak-y* *stak-z*)
          (stak-aux))
        (the fixnum (1- (the fixnum *stak-y*)))
        *stak-z*
        *stak-x*)
       ((lambda (*stak-x* *stak-y* *stak-z*)
          (stak-aux))
        (the fixnum (1- (the fixnum *stak-z*)))
        *stak-x*
        *stak-y*))))

(defun stak (*stak-x* *stak-y* *stak-z*)
  (stak-aux))

(stak 18 12 6) → 7
Bike commented 1 year ago

No idea how this broke in clasp-cleavir but the bytecode problem is at least fairly obvious. I'll also put in a test so we catch this earlier next time.