From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: internal handling of buffer-local variables Date: Wed, 14 Nov 2007 14:07:43 -0500 Message-ID: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1195067606 9543 80.91.229.12 (14 Nov 2007 19:13:26 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 14 Nov 2007 19:13:26 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Nov 14 20:13:30 2007 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1IsNg0-0005Gj-Ts for ged-emacs-devel@m.gmane.org; Wed, 14 Nov 2007 20:13:29 +0100 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1IsNfo-0004DJ-3r for ged-emacs-devel@m.gmane.org; Wed, 14 Nov 2007 14:13:16 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1IsNfX-00044Y-0P for emacs-devel@gnu.org; Wed, 14 Nov 2007 14:12:59 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1IsNfT-00042E-Tr for emacs-devel@gnu.org; Wed, 14 Nov 2007 14:12:57 -0500 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1IsNfT-00041x-Ax for emacs-devel@gnu.org; Wed, 14 Nov 2007 14:12:55 -0500 Original-Received: from tomts36.bellnexxia.net ([209.226.175.93] helo=tomts36-srv.bellnexxia.net) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1IsNfS-0000EI-Fy for emacs-devel@gnu.org; Wed, 14 Nov 2007 14:12:55 -0500 Original-Received: from pastel.home ([70.53.194.136]) by tomts36-srv.bellnexxia.net (InterMail vM.5.01.06.13 201-253-122-130-113-20050324) with ESMTP id <20071114191248.PIZJ7990.tomts36-srv.bellnexxia.net@pastel.home> for ; Wed, 14 Nov 2007 14:12:48 -0500 Original-Received: by pastel.home (Postfix, from userid 20848) id 0B8F07F4E; Wed, 14 Nov 2007 14:07:42 -0500 (EST) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.50 (gnu/linux) X-detected-kernel: by monty-python.gnu.org: Solaris 8 (1) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:83204 Archived-At: While tracking down some unrelated problem, I bumped into the appended code. As you can seem, the comment says that swap_out_buffer_local_variables is supposed to make sure no var has the bindings for B loaded. But then the code goes on and checks whether the binding for current_buffer is loaded. Worse yet: when it encounters such a thing, it loads the global binding but sets the symbols' `buffer' field to claim that the loaded binding is for B, thus leading to an inconsistent state. This can lead to problems further down where a buffer that is now dead (and whose local_var_alist is empty) has a binding loaded (and with found_for_buffer set). I'm not sure the problem can really cause trouble because found_for_buffer is not used systematically (e.g. Flocal_variable_p ignores it), but it looks dangerous. I'm tempted to replace the body of the if with a call to swap_in_global_binding. I've tried this change here and it seems to work correctly, but I'd like to hear what other people think about it. Stefan /* Make sure no local variables remain set up with buffer B for their current values. */ static void swap_out_buffer_local_variables (b) struct buffer *b; { Lisp_Object oalist, alist, sym, tem, buffer; XSETBUFFER (buffer, b); oalist = b->local_var_alist; for (alist = oalist; CONSP (alist); alist = XCDR (alist)) { sym = XCAR (XCAR (alist)); /* Need not do anything if some other buffer's binding is now encached. */ tem = XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->buffer; if (BUFFERP (tem) && XBUFFER (tem) == current_buffer) { /* Symbol is set up for this buffer's old local value. Set it up for the current buffer with the default value. */ tem = XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->cdr; /* Store the symbol's current value into the alist entry it is currently set up for. This is so that, if the local is marked permanent, and we make it local again later in Fkill_all_local_variables, we don't lose the value. */ XSETCDR (XCAR (tem), do_symval_forwarding (XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->realvalue)); /* Switch to the symbol's default-value alist entry. */ XSETCAR (tem, tem); /* Mark it as current for buffer B. */ XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->buffer = buffer; /* Store the current value into any forwarding in the symbol. */ store_symval_forwarding (sym, XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->realvalue, XCDR (tem), NULL); } } }