all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Lennart Borgman <lennart.borgman@gmail.com>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: 3467@emacsbugs.donarmstrong.com
Subject: bug#3467: 23.0.94; let + make-local-variable => let value made  global
Date: Sat, 6 Jun 2009 22:11:21 +0200	[thread overview]
Message-ID: <e01d8a50906061311s77ad6eccm1bd0ad3e6d0a30ef@mail.gmail.com> (raw)
In-Reply-To: <e01d8a50906051548k2d6d9f15o7a5e841579740c79@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1555 bytes --]

On Sat, Jun 6, 2009 at 12:48 AM, Lennart
Borgman<lennart.borgman@gmail.com> wrote:
>
> Sigh, and my suggestion was of course unnecessary stupid. What is
> needed is of course to record values and frame+buffer localness and
> dito values and reset them. Nothing less than this will ever work
> correctly, or?
>
> And does not this apply to all uses of specbind + unbind_to?
>
> Can it be sufficient to just change specbind and unbind_to? Is there
> anything else that will be affected by changes in the specbind stack?
> Since info about buffer+frame is alwas needed should specbinding be
> changed to the below form?
>
> struct specbinding
>  {
>    Lisp_Object symbol;
>    Lisp_Object old_value;
>    Lisp_Object old_buffer_value;
>    Lisp_Object old_frame_value;
>    specbinding_func func;
>    Lisp_Object unused;         /* Dividing by 16 is faster than by 12 */
>    Lisp_Object unused;
>    Lisp_Object unused;
>  };

Here is a bit modified suggestion and some code where I try to
implement it. Please notice that I have not tested the code. It is
very possible that I have misunderstood something so please look at
the code.

struct specbinding
  {
    Lisp_Object symbol;
    Lisp_Object old_value;
    specbinding_func func;
    // total 8 fields
    Lisp_Object need_test_local;
    Lisp_Object old_buffer;
    Lisp_Object old_buffer_value;
    Lisp_Object old_frame;
    Lisp_Object old_frame_value;
    //Lisp_Object unused;		/* Dividing by 16 is faster than by 12 */
  };

[-- Attachment #2: eval.diff --]
[-- Type: application/octet-stream, Size: 7463 bytes --]

*** eval.c	2009-06-06 22:06:33.359375000 +0200
--- eval-orig.c	2009-03-27 09:21:26.453125000 +0100
***************
*** 3298,3304 ****
        specpdl_ptr->symbol = symbol;
        specpdl_ptr->old_value = valcontents;
        specpdl_ptr->func = NULL;
-       //specpdl_ptr->need_test_local = Qnil; // no need to set this
        ++specpdl_ptr;
        SET_SYMBOL_VALUE (symbol, value);
      }
--- 3298,3303 ----
***************
*** 3306,3317 ****
      {
        Lisp_Object ovalue = find_symbol_value (symbol);
        specpdl_ptr->func = 0;
!       //specpdl_ptr->old_value = ovalue;
!       /* Fix-me: Store symbol global value in old_value */
!       specpdl_ptr->old_value = do_symval_forwarding (valcontents);
!       specpdl_ptr->need_test_local = Qt;
!       specpdl_ptr->old_buffer= Qunbound;
!       specpdl_ptr->old_frame= Qunbound;
  
        valcontents = XSYMBOL (symbol)->value;
  
--- 3305,3311 ----
      {
        Lisp_Object ovalue = find_symbol_value (symbol);
        specpdl_ptr->func = 0;
!       specpdl_ptr->old_value = ovalue;
  
        valcontents = XSYMBOL (symbol)->value;
  
***************
*** 3324,3349 ****
  
  	  /* For a local variable, record both the symbol and which
  	     buffer's or frame's value we are saving.  */
!           /* Fix-me: This only saves the current used local binding,
!              not both as it should */
! 	  if (!NILP (Flocal_variable_p (symbol, Qnil))) {
  	    where = current_buffer;
!             specpdl_ptr->old_buffer = where;
!             specpdl_ptr->old_buffer_value = ovalue;
!           } else if (BUFFER_LOCAL_VALUEP (valcontents)
!                      && XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame) {
  	    where = XBUFFER_LOCAL_VALUE (valcontents)->frame;
!             specpdl_ptr->old_frame = where;
!             specpdl_ptr->old_frame_value = ovalue;
! 	  } else {
  	    where = Qnil;
-           }
  
  	  /* We're not using the `unused' slot in the specbinding
  	     structure because this would mean we have to do more
  	     work for simple variables.  */
! 	  //specpdl_ptr->symbol = Fcons (symbol, Fcons (where, current_buffer));
!           specpdl_ptr->symbol = symbol;
  
  	  /* If SYMBOL is a per-buffer variable which doesn't have a
  	     buffer-local value here, make the `let' change the global
--- 3318,3335 ----
  
  	  /* For a local variable, record both the symbol and which
  	     buffer's or frame's value we are saving.  */
! 	  if (!NILP (Flocal_variable_p (symbol, Qnil)))
  	    where = current_buffer;
! 	  else if (BUFFER_LOCAL_VALUEP (valcontents)
! 		   && XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame)
  	    where = XBUFFER_LOCAL_VALUE (valcontents)->frame;
! 	  else
  	    where = Qnil;
  
  	  /* We're not using the `unused' slot in the specbinding
  	     structure because this would mean we have to do more
  	     work for simple variables.  */
! 	  specpdl_ptr->symbol = Fcons (symbol, Fcons (where, current_buffer));
  
  	  /* If SYMBOL is a per-buffer variable which doesn't have a
  	     buffer-local value here, make the `let' change the global
***************
*** 3419,3479 ****
  	 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); */
!       /*   } */
!       else {
!         /* Fix-me: Before restoring anything the buffer/frame
!            localness must be checked.  I am not sure how to do that,
!            but see below for my attempts.
!         */
!         /* Set global value */
          if (!MISCP (SYMBOL_VALUE (this_binding.symbol)))
            SET_SYMBOL_VALUE (this_binding.symbol, this_binding.old_value);
          else
!           set_default (this_binding.symbol, this_binding.old_value, 0, 1);
! 
!         {
!           register Lisp_Object valcontents = SYMBOL_VALUE (symbol);
!           int is_local_now = BUFFER_LOCAL_VALUEP (valcontents) || BUFFER_OBJFWDP (valcontents);
!           int is_buffer_local_now = is_local_now && Flocal_variable_p (this_binding.symbol, Qnil);
!           int is_frame_local_now = is_local_now && !is_buffer_local_now;
!           int was_buffer_local_before = this_binding.old_buffer /= Qunbound;
!           int was_local_before = (was_buffer_local_before ||
!                                   this_binding.old_frame /= Qunbound);
!           int was_frame_local_before = (was_local_before && ! was_buffer_local_before);
!           /* Fix me: restore localness */
!           if (was_buffer_local_before_specbind) {
!             if (!is_buffer_local_now) Fmake_local_variable (this_binding.symbol);
!             /* Set buffer local value */
!             set_internal (symbol, this_binding.old_buffer_value, XBUFFER (this_binding.old_buffer), 1);
!           } else if (was_frame_local_before_specbind) {
!             if (!is_frame_local_now) Fmake_variable_frame_local (this_binding.symbol);
!             /* Set frame local value */
!             set_internal (symbol, this_binding.old_frame_value, NULL, 1);
!           }
!         }
        }
      }
  
--- 3405,3433 ----
  	 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);
  	}
      }
  

  parent reply	other threads:[~2009-06-06 20:11 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-06-04 21:14 bug#3467: 23.0.94; let + make-local-variable => let value made global Lennart Borgman
2009-06-05 14:21 ` Lennart Borgman
2009-06-05 14:36 ` Stefan Monnier
2009-06-05 15:04   ` Lennart Borgman
2009-06-05 22:48     ` Lennart Borgman
2009-06-05 23:08       ` Lennart Borgman
2009-06-05 23:32         ` Lennart Borgman
2009-06-06 20:11       ` Lennart Borgman [this message]
2009-06-07  1:11         ` Lennart Borgman
2009-06-12 22:24           ` Lennart Borgman
2009-06-27  0:24             ` bug#3467: 23.0.94; let + make-local-variable => let value made Stefan Monnier
2009-06-06 20:05 ` bug#3467: 23.0.94; let + make-local-variable => let value made global Richard Stallman
2009-06-06 20:13   ` Lennart Borgman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e01d8a50906061311s77ad6eccm1bd0ad3e6d0a30ef@mail.gmail.com \
    --to=lennart.borgman@gmail.com \
    --cc=3467@emacsbugs.donarmstrong.com \
    --cc=monnier@iro.umontreal.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.