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: Fri, 02 May 2003 03:06:42 -0400

    Isn't this going to cause the unwind-protect to be re-executed
    if a signal is thrown while executing
    (*specpdl_ptr->func) (specpdl_ptr->old_value);
    now that specpdl_ptr is decremented afterwards ?

Yes, you're right.  How about this version?

Lisp_Object
unbind_to (count, value)
     int count;
     Lisp_Object value;
{
  int quitf = !NILP (Vquit_flag);
  struct gcpro gcpro1;

  GCPRO1 (value);
  Vquit_flag = Qnil;

  while (specpdl_ptr != specpdl + count)
    {
      struct specbinding this_binding = *--specpdl_ptr;

      if (this_binding.func != 0)
        (*this_binding.func) (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
         bound a variable that had a buffer-local or frame-local
         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);
        }
    }

  if (NILP (Vquit_flag) && quitf)
    Vquit_flag = Qt;

  UNGCPRO;
  return value;
}




reply via email to

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