emacs-pretest-bug
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Asynchronous bug


From: Richard Stallman
Subject: Re: Asynchronous bug
Date: Thu, 01 May 2003 13:48:52 -0400

    Watchpoints showed that the value of `nil' is modified in `unbind_to'.
    The way it works is that specpdl_ptr->symbol changes from non-nil
    to nil in the time between the nil test and the use of the value.

The problem was evident when I looked at the code of unbind_to.
Does this patch fix it?

*** eval.c.~1.206.~     Mon Apr 28 17:12:08 2003
--- eval.c      Thu May  1 02:15:49 2003
***************
*** 3070,3083 ****
  
    while (specpdl_ptr != specpdl + count)
      {
!       --specpdl_ptr;
  
!       if (specpdl_ptr->func != 0)
!       (*specpdl_ptr->func) (specpdl_ptr->old_value);
        /* Note that a "binding" of nil is really an unwind protect,
         so in that case the "old value" is a list of forms to evaluate.  */
!       else if (NILP (specpdl_ptr->symbol))
!       Fprogn (specpdl_ptr->old_value);
        /* If the symbol is a list, it is really (SYMBOL WHERE
         . CURRENT-BUFFER) where WHERE is either nil, a buffer, or a
         frame.  If WHERE is a buffer or frame, this indicates we
--- 3070,3083 ----
  
    while (specpdl_ptr != specpdl + count)
      {
!       struct specbinding *this_binding = specpdl_ptr - 1;
  
!       if (this_binding->func != 0)
!       (*this_binding->func) (this_binding->old_value);
        /* Note that a "binding" of nil is really an unwind protect,
         so in that case the "old value" is a list of forms to evaluate.  */
!       else if (NILP (this_binding->symbol))
!       Fprogn (this_binding->old_value);
        /* If the symbol is a list, it is really (SYMBOL WHERE
         . CURRENT-BUFFER) where WHERE is either nil, a buffer, or a
         frame.  If WHERE is a buffer or frame, this indicates we
***************
*** 3085,3114 ****
         binding.  WHERE nil means that the variable had the default
         value when it was bound.  CURRENT-BUFFER is the buffer that
           was current when the variable was bound.  */
!       else if (CONSP (specpdl_ptr->symbol))
        {
          Lisp_Object symbol, where;
  
!         symbol = XCAR (specpdl_ptr->symbol);
!         where = XCAR (XCDR (specpdl_ptr->symbol));
  
          if (NILP (where))
!           Fset_default (symbol, specpdl_ptr->old_value);
          else if (BUFFERP (where))
!           set_internal (symbol, specpdl_ptr->old_value, XBUFFER (where), 1);
          else
!           set_internal (symbol, specpdl_ptr->old_value, NULL, 1);
        }
        else
        {
          /* If variable has a trivial value (no forwarding), we can
             just set it.  No need to check for constant symbols here,
             since that was already done by specbind.  */
!         if (!MISCP (SYMBOL_VALUE (specpdl_ptr->symbol)))
!           SET_SYMBOL_VALUE (specpdl_ptr->symbol, specpdl_ptr->old_value);
          else
!           set_internal (specpdl_ptr->symbol, specpdl_ptr->old_value, 0, 1);
        }
      }
  
    if (NILP (Vquit_flag) && quitf)
--- 3085,3116 ----
         binding.  WHERE nil means that the variable had the default
         value when it was bound.  CURRENT-BUFFER is the buffer that
           was current when the variable was bound.  */
!       else if (CONSP (this_binding->symbol))
        {
          Lisp_Object symbol, where;
  
!         symbol = XCAR (this_binding->symbol);
!         where = XCAR (XCDR (this_binding->symbol));
  
          if (NILP (where))
!           Fset_default (symbol, this_binding->old_value);
          else if (BUFFERP (where))
!           set_internal (symbol, this_binding->old_value, XBUFFER (where), 1);
          else
!           set_internal (symbol, this_binding->old_value, NULL, 1);
        }
        else
        {
          /* If variable has a trivial value (no forwarding), we can
             just set it.  No need to check for constant symbols here,
             since that was already done by specbind.  */
!         if (!MISCP (SYMBOL_VALUE (this_binding->symbol)))
!           SET_SYMBOL_VALUE (this_binding->symbol, this_binding->old_value);
          else
!           set_internal (this_binding->symbol, this_binding->old_value, 0, 1);
        }
+ 
+       --specpdl_ptr;
      }
  
    if (NILP (Vquit_flag) && quitf)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]