changeset 108575:f6cfadfc0fb6

* eval.c (specbind): Disallow let-binding frame-local vars. Remove left-over duplicate test. Add comment.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Fri, 14 May 2010 13:53:42 -0400
parents 27a878644c60
children c85c4eac55a6
files etc/NEWS src/ChangeLog src/eval.c
diffstat 3 files changed, 33 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/etc/NEWS	Fri May 14 12:41:01 2010 -0400
+++ b/etc/NEWS	Fri May 14 13:53:42 2010 -0400
@@ -221,6 +221,7 @@
 
 * Lisp changes in Emacs 24.1
 
+** frame-local variables cannot be let-bound any more.
 ** prog-mode is a new major-mode meant to be the parent of programming mode.
 ** define-minor-mode accepts a new keyword :variable.
 
--- a/src/ChangeLog	Fri May 14 12:41:01 2010 -0400
+++ b/src/ChangeLog	Fri May 14 13:53:42 2010 -0400
@@ -1,3 +1,8 @@
+2010-05-14  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* eval.c (specbind): Remove left-over duplicate test.
+	Disallow let-binding frame-local vars.  Add comment.
+
 2010-05-14  Eli Zaretskii  <eliz@gnu.org>
 
 	Make the cache of bidi iterator states dynamically allocated.
@@ -5,7 +10,7 @@
 	(bidi_init_it): Call it.
 	(bidi_cache_iterator_state): Enlarge the cache if needed.
 
-	* bidi.c (bidi_move_to_visually_next): Renamed from
+	* bidi.c (bidi_move_to_visually_next): Rename from
 	bidi_get_next_char_visually.  All callers changed.
 
 2010-05-14  Kenichi Handa  <handa@m17n.org>
@@ -18,8 +23,8 @@
 	Set CMP_IT->reversed_p.
 	(composition_update_it): Pay attention to CMP_IT->reversed_p.
 
-	* xdisp.c (set_iterator_to_next): Call
-	composition_compute_stop_pos with negative ENDPOS if we are
+	* xdisp.c (set_iterator_to_next):
+	Call composition_compute_stop_pos with negative ENDPOS if we are
 	scanning backward.  Call composition_compute_stop_pos if scan
 	direction is changed.
 	(next_element_from_buffer): Call composition_compute_stop_pos with
--- a/src/eval.c	Fri May 14 12:41:01 2010 -0400
+++ b/src/eval.c	Fri May 14 13:53:42 2010 -0400
@@ -3308,6 +3308,21 @@
   specpdl_ptr = specpdl + count;
 }
 
+/* specpdl_ptr->symbol is a field which describes which variable is
+   let-bound, so it can be properly undone when we unbind_to.
+   It can have the following two shapes:
+   - SYMBOL : if it's a plain symbol, it means that we have let-bound
+     a symbol that is not buffer-local (at least at the time
+     the let binding started).  Note also that it should not be
+     aliased (i.e. when let-binding V1 that's aliased to V2, we want
+     to record V2 here).
+   - (SYMBOL WHERE . BUFFER) : this means that it is a let-binding for
+     variable SYMBOL which can be buffer-local.  WHERE tells us
+     which buffer is affected (or nil if the let-binding affects the
+     global value of the variable) and BUFFER tells us which buffer was
+     current (i.e. if WHERE is non-nil, then BUFFER==WHERE, otherwise
+     BUFFER did not yet have a buffer-local value).  */
+
 void
 specbind (symbol, value)
      Lisp_Object symbol, value;
@@ -3339,7 +3354,10 @@
 	    set_internal (symbol, value, Qnil, 1);
 	  break;
 	}
-    case SYMBOL_LOCALIZED: case SYMBOL_FORWARDED:
+    case SYMBOL_LOCALIZED:
+      if (SYMBOL_BLV (sym)->frame_local)
+	error ("Frame-local vars cannot be let-bound");
+    case SYMBOL_FORWARDED:
       {
 	Lisp_Object ovalue = find_symbol_value (symbol);
 	specpdl_ptr->func = 0;
@@ -3376,6 +3394,7 @@
 	    /* FIXME: The third value `current_buffer' is only used in
 	       let_shadows_buffer_binding_p which is itself only used
 	       in set_internal for local_if_set.  */
+	    eassert (NILP (where) || EQ (where, cur_buf));
 	    specpdl_ptr->symbol = Fcons (symbol, Fcons (where, cur_buf));
 
 	    /* If SYMBOL is a per-buffer variable which doesn't have a
@@ -3460,13 +3479,10 @@
 	    Fset_default (symbol, this_binding.old_value);
 	  /* If `where' is non-nil, reset the value in the appropriate
 	     local binding, but only if that binding still exists.  */
-	  else if (BUFFERP (where))
-	    {
-	      if (BUFFERP (where)
-		  ? !NILP (Flocal_variable_p (symbol, where))
-		  : !NILP (Fassq (symbol, XFRAME (where)->param_alist)))
-		set_internal (symbol, this_binding.old_value, where, 1);
-	    }
+	  else if (BUFFERP (where)
+		   ? !NILP (Flocal_variable_p (symbol, where))
+		   : !NILP (Fassq (symbol, XFRAME (where)->param_alist)))
+	    set_internal (symbol, this_binding.old_value, where, 1);
 	}
       /* If variable has a trivial value (no forwarding), we can
 	 just set it.  No need to check for constant symbols here,