0.6.11.14:
authorWilliam Harold Newman <william.newman@airmail.net>
Wed, 14 Mar 2001 13:46:52 +0000 (13:46 +0000)
committerWilliam Harold Newman <william.newman@airmail.net>
Wed, 14 Mar 2001 13:46:52 +0000 (13:46 +0000)
response to MNA message sbcl-devel 2001-03-07..
..merged test case to exercise byte compiler bug
..merged patch to fix the bug
also merged Dan Barlow's explanation (sbcl-devel 2001-03-12)
into a comment in the source

src/compiler/byte-comp.lisp
src/runtime/interrupt.c
tests/compiler.pure-cload.lisp
version.lisp-expr

index ae010f6..db5be90 100644 (file)
         (values (if info
                     (byte-continuation-info-results info)
                     0)))
+    (unless (eql values 0)
+      ;; Someone wants the value, so copy it.
+      (output-do-xop segment 'dup))
     (etypecase leaf
-      (global-var
+      (global-var        
        (ecase (global-var-kind leaf)
         ((:special :global)
          (output-push-constant segment (global-var-name leaf))
          (output-do-inline-function segment 'setf-symbol-value))))
       (lambda-var
-       ;; Note: It's important to test for whether there are any
-       ;; references to the variable before we actually try to set it.
-       ;; (Setting a lexical variable with no refs caused bugs ca. CMU
-       ;; CL 18c, because the compiler deletes such variables.)
-       (cond ((leaf-refs leaf)
-             (unless (eql values 0)
-               ;; Someone wants the value, so copy it.
-               (output-do-xop segment 'dup))
-             (output-set-lambda-var segment leaf (node-environment set)))
-            ;; If no one wants the value, then pop it, else leave it
-            ;; for them.
-            ((eql values 0)
-             (output-byte-with-operand segment byte-pop-n 1)))))
+        ;; Note: It's important to test for whether there are any
+        ;; references to the variable before we actually try to set it.
+        ;; (Setting a lexical variable with no refs caused bugs ca. CMU
+        ;; CL 18c, because the compiler deletes such variables.)
+        (cond ((leaf-refs leaf)                
+                (output-set-lambda-var segment leaf (node-environment set)))
+              ;; If no one wants the value, then pop it, else leave it
+              ;; for them.
+              ((eql values 0)
+                (output-byte-with-operand segment byte-pop-n 1)))))
     (unless (eql values 0)
       (checked-canonicalize-values segment cont 1)))
   (values))
index 94b2de8..a3fd5a0 100644 (file)
@@ -280,9 +280,30 @@ interrupt_handle_pending(os_context_t *context)
         }
     }
 
-    /* FIXME: How come we unconditionally copy from pending_mask into
-     * the context, and then test whether pending_signal is set? If
-     * pending_signal wasn't set, how could pending_mask be valid? */
+    /* FIXME: This isn't very clear. It would be good to reverse
+     * engineer it and rewrite the code more clearly, or write a clear
+     * explanation of what's going on in the comments, or both.
+     *
+     * WHN's question 1a: How come we unconditionally copy from
+     * pending_mask into the context, and then test whether
+     * pending_signal is set?
+     * 
+     * WHN's question 1b: If pending_signal wasn't set, how could
+     * pending_mask be valid?
+     * 
+     * Dan Barlow's reply (sbcl-devel 2001-03-13): And the answer is -
+     * or appears to be - because interrupt_maybe_gc set it that way
+     * (look in the #ifndef __i386__ bit). We can't GC during a
+     * pseudo-atomic, so we set maybe_gc_pending=1 and
+     * arch_set_pseudo_atomic_interrupted(..) When we come out of
+     * pseudo_atomic we're marked as interrupted, so we call
+     * interrupt_handle_pending, which does the GC using the pending
+     * context (it needs a context so that it has registers to use as
+     * GC roots) then notices there's no actual interrupt handler to
+     * call, so doesn't. That's the second question [1b] answered,
+     * anyway. Why we still need to copy the pending_mask into the
+     * context given that we're now done with the context anyway, I
+     * couldn't say. */
     memcpy(os_context_sigmask_addr(context), &pending_mask, sizeof(sigset_t));
     sigemptyset(&pending_mask);
     if (pending_signal) {
index 8c7dd8e..c1b5ef1 100644 (file)
   (declare (type (mod 1000) a b))
   (let ((tmp (= 10 (+ (incf a) (incf a) (incf b) (incf b)))))
     (or tmp (error "TMP not true"))))
+
+;;; Exercise a (byte-)compiler bug by causing a call to ERROR, not
+;;; because the symbol isn't defined as a variable, but because
+;;;  TYPE-ERROR in SB-KERNEL::OBJECT-NOT-TYPE-ERROR-HANDLER:
+;;;     0 is not of type (OR FUNCTION SB-KERNEL:FDEFN).
+;;; Correct behavior is to warn at compile time because the symbol
+;;; isn't declared as a variable, but to set its SYMBOL-VALUE anyway.
+;;; 
+;;; This bug was in sbcl-0.6.11.13.
+(print (setq improperly-declared-var '(1 2)))
+(assert (equal (symbol-value 'improperly-declared-var) '(1 2)))
+(makunbound 'improperly-declared-var)
+;;; This is a slightly different way of getting the same symptoms out
+;;; of the sbcl-0.6.11.13 byte compiler bug.
+(print (setq *print-level* *print-level*))
index e1626ff..fe1a06f 100644 (file)
@@ -15,4 +15,4 @@
 ;;; versions, and a string like "0.6.5.12" is used for versions which
 ;;; aren't released but correspond only to CVS tags or snapshots.
 
-"0.6.11.13"
+"0.6.11.14"