=== modified file 'src/alloc.c' --- src/alloc.c 2012-08-14 21:38:06 +0000 +++ src/alloc.c 2012-08-15 10:45:33 +0000 @@ -3697,7 +3697,21 @@ free_misc (marker); } - +/* Return partially initialized buffer- or frame-local value. */ + +struct Lisp_Buffer_Local_Value * +make_buffer_local_value (void) +{ + struct Lisp_Buffer_Local_Value *blv; + + blv = XBLV (allocate_misc (Lisp_Misc_Buffer_Local_Value)); + blv->frame_local = 0; + blv->local_if_set = 0; + set_blv_where (blv, Qnil); + set_blv_found (blv, 0); + return blv; +} + /* Return a newly created vector or string with specified arguments as elements. If all the arguments are characters that can fit in a string of events, make a string; otherwise, make a vector. @@ -6070,14 +6084,13 @@ } case SYMBOL_LOCALIZED: { - struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (ptr); + Lisp_Object tem; + XSETMISC (tem, SYMBOL_BLV (ptr)); /* If the value is forwarded to a buffer or keyboard field, these are marked when we see the corresponding object. And if it's forwarded to a C variable, either it's not a Lisp_Object var, or it's staticpro'd already. */ - mark_object (blv->where); - mark_object (blv->valcell); - mark_object (blv->defcell); + mark_object (tem); break; } case SYMBOL_FORWARDED: @@ -6139,6 +6152,13 @@ mark_overlay (XOVERLAY (obj)); break; + case Lisp_Misc_Buffer_Local_Value: + XMISCANY (obj)->gcmarkbit = 1; + mark_object (XBLV (obj)->where); + mark_object (XBLV (obj)->defcell); + mark_object (XBLV (obj)->valcell); + break; + default: abort (); } @@ -6460,8 +6480,6 @@ if (!sym->s.gcmarkbit && !pure_p) { - if (sym->s.redirect == SYMBOL_LOCALIZED) - xfree (SYMBOL_BLV (&sym->s)); sym->s.next = symbol_free_list; symbol_free_list = &sym->s; #if GC_MARK_STACK === modified file 'src/data.c' --- src/data.c 2012-08-14 17:10:38 +0000 +++ src/data.c 2012-08-15 10:39:00 +0000 @@ -543,7 +543,7 @@ else { swap_in_symval_forwarding (sym, blv); - valcontents = BLV_VALUE (blv); + valcontents = get_blv_value (blv); } break; } @@ -964,16 +964,16 @@ /* Unload the previously loaded binding. */ if (blv->fwd) - SET_BLV_VALUE (blv, do_symval_forwarding (blv->fwd)); + set_blv_value (blv, do_symval_forwarding (blv->fwd)); /* Select the global binding in the symbol. */ - blv->valcell = blv->defcell; + set_blv_valcell (blv, blv->defcell); if (blv->fwd) store_symval_forwarding (blv->fwd, XCDR (blv->defcell), NULL); /* Indicate that the global binding is set up now. */ - blv->where = Qnil; - SET_BLV_FOUND (blv, 0); + set_blv_where (blv, Qnil); + set_blv_found (blv, 0); } /* Set up the buffer-local symbol SYMBOL for validity in the current buffer. @@ -1001,7 +1001,7 @@ /* Unload the previously loaded binding. */ tem1 = blv->valcell; if (blv->fwd) - SET_BLV_VALUE (blv, do_symval_forwarding (blv->fwd)); + set_blv_value (blv, do_symval_forwarding (blv->fwd)); /* Choose the new binding. */ { Lisp_Object var; @@ -1009,7 +1009,7 @@ if (blv->frame_local) { tem1 = assq_no_quit (var, XFRAME (selected_frame)->param_alist); - blv->where = selected_frame; + set_blv_where (blv, selected_frame); } else { @@ -1021,9 +1021,9 @@ tem1 = blv->defcell; /* Load the new binding. */ - blv->valcell = tem1; + set_blv_valcell (blv, tem1); if (blv->fwd) - store_symval_forwarding (blv->fwd, BLV_VALUE (blv), NULL); + store_symval_forwarding (blv->fwd, get_blv_value (blv), NULL); } } @@ -1050,7 +1050,7 @@ { struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); swap_in_symval_forwarding (sym, blv); - return blv->fwd ? do_symval_forwarding (blv->fwd) : BLV_VALUE (blv); + return blv->fwd ? do_symval_forwarding (blv->fwd) : get_blv_value (blv); } /* FALLTHROUGH */ case SYMBOL_FORWARDED: @@ -1175,7 +1175,7 @@ /* Write out `realvalue' to the old loaded binding. */ if (blv->fwd) - SET_BLV_VALUE (blv, do_symval_forwarding (blv->fwd)); + set_blv_value (blv, do_symval_forwarding (blv->fwd)); /* Find the new binding. */ XSETSYMBOL (symbol, sym); /* May have changed via aliasing. */ @@ -1183,8 +1183,8 @@ (blv->frame_local ? XFRAME (where)->param_alist : BVAR (XBUFFER (where), local_var_alist))); - blv->where = where; - blv->found = 1; + set_blv_where (blv, where); + set_blv_found (blv, 1); if (NILP (tem1)) { @@ -1199,7 +1199,7 @@ if (bindflag || !blv->local_if_set || let_shadows_buffer_binding_p (sym)) { - blv->found = 0; + set_blv_found (blv, 0); tem1 = blv->defcell; } /* If it's a local_if_set, being set not bound, @@ -1219,11 +1219,11 @@ } /* Record which binding is now loaded. */ - blv->valcell = tem1; + set_blv_valcell (blv, tem1); } /* Store the new value in the cons cell. */ - SET_BLV_VALUE (blv, newval); + set_blv_value (blv, newval); if (blv->fwd) { @@ -1465,26 +1465,21 @@ static struct Lisp_Buffer_Local_Value * make_blv (struct Lisp_Symbol *sym, int forwarded, union Lisp_Val_Fwd valcontents) { - struct Lisp_Buffer_Local_Value *blv = xmalloc (sizeof *blv); - Lisp_Object symbol; - Lisp_Object tem; + struct Lisp_Buffer_Local_Value *blv = make_buffer_local_value (); + Lisp_Object symbol, tem; - XSETSYMBOL (symbol, sym); - tem = Fcons (symbol, (forwarded - ? do_symval_forwarding (valcontents.fwd) - : valcontents.value)); + XSETSYMBOL (symbol, sym); + tem = Fcons (symbol, (forwarded + ? do_symval_forwarding (valcontents.fwd) + : valcontents.value)); /* Buffer_Local_Values cannot have as realval a buffer-local or keyboard-local forwarding. */ eassert (!(forwarded && BUFFER_OBJFWDP (valcontents.fwd))); eassert (!(forwarded && KBOARD_OBJFWDP (valcontents.fwd))); blv->fwd = forwarded ? valcontents.fwd : NULL; - blv->where = Qnil; - blv->frame_local = 0; - blv->local_if_set = 0; - blv->defcell = tem; - blv->valcell = tem; - SET_BLV_FOUND (blv, 0); + set_blv_defcell (blv, tem); + set_blv_valcell (blv, tem); return blv; } @@ -1660,10 +1655,8 @@ /* Make sure symbol does not think it is set up for this buffer; force it to look once again for this buffer's value. */ if (current_buffer == XBUFFER (blv->where)) - blv->where = Qnil; - /* blv->valcell = blv->defcell; - * SET_BLV_FOUND (blv, 0); */ - blv->found = 0; + set_blv_where (blv, Qnil); + set_blv_found (blv, 0); } /* If the symbol forwards into a C variable, then load the binding @@ -1733,10 +1726,8 @@ Lisp_Object buf; XSETBUFFER (buf, current_buffer); if (EQ (buf, blv->where)) { - blv->where = Qnil; - /* blv->valcell = blv->defcell; - * SET_BLV_FOUND (blv, 0); */ - blv->found = 0; + set_blv_where (blv, Qnil); + set_blv_found (blv, 0); find_symbol_value (variable); } } @@ -1857,11 +1848,11 @@ if (EQ (variable, XCAR (elt))) { eassert (!blv->frame_local); - eassert (BLV_FOUND (blv) || !EQ (blv->where, tmp)); + eassert (get_blv_found (blv) || !EQ (blv->where, tmp)); return Qt; } } - eassert (!BLV_FOUND (blv) || !EQ (blv->where, tmp)); + eassert (!get_blv_found (blv) || !EQ (blv->where, tmp)); return Qnil; } case SYMBOL_FORWARDED: @@ -1951,7 +1942,7 @@ if (!NILP (Flocal_variable_p (variable, Qnil))) return Fcurrent_buffer (); else if (sym->redirect == SYMBOL_LOCALIZED - && BLV_FOUND (SYMBOL_BLV (sym))) + && get_blv_found (SYMBOL_BLV (sym))) return SYMBOL_BLV (sym)->where; else return Qnil; === modified file 'src/eval.c' --- src/eval.c 2012-08-08 19:53:44 +0000 +++ src/eval.c 2012-08-15 10:11:49 +0000 @@ -3157,12 +3157,12 @@ if (!NILP (Flocal_variable_p (symbol, Qnil))) { eassert (sym->redirect != SYMBOL_LOCALIZED - || (BLV_FOUND (SYMBOL_BLV (sym)) + || (get_blv_found (SYMBOL_BLV (sym)) && EQ (cur_buf, SYMBOL_BLV (sym)->where))); where = cur_buf; } else if (sym->redirect == SYMBOL_LOCALIZED - && BLV_FOUND (SYMBOL_BLV (sym))) + && get_blv_found (SYMBOL_BLV (sym))) where = SYMBOL_BLV (sym)->where; else where = Qnil; === modified file 'src/frame.c' --- src/frame.c 2012-08-14 08:44:24 +0000 +++ src/frame.c 2012-08-15 10:11:49 +0000 @@ -2096,7 +2096,7 @@ case SYMBOL_PLAINVAL: case SYMBOL_FORWARDED: break; case SYMBOL_LOCALIZED: { struct Lisp_Buffer_Local_Value *blv = sym->val.blv; - if (blv->frame_local && BLV_FOUND (blv) && XFRAME (blv->where) == f) + if (blv->frame_local && get_blv_found (blv) && XFRAME (blv->where) == f) swap_in_global_binding (sym); break; } === modified file 'src/lisp.h' --- src/lisp.h 2012-08-14 17:45:25 +0000 +++ src/lisp.h 2012-08-15 10:43:09 +0000 @@ -280,6 +280,7 @@ /* Currently floats are not a misc type, but let's define this in case we want to change that. */ Lisp_Misc_Float, + Lisp_Misc_Buffer_Local_Value, /* This is not a type code. It is for range checking. */ Lisp_Misc_Limit }; @@ -515,10 +516,11 @@ #define XMISC(a) ((union Lisp_Misc *) XUNTAG (a, Lisp_Misc)) #define XMISCANY(a) (eassert (MISCP (a)), &(XMISC (a)->u_any)) -#define XMISCTYPE(a) (XMISCANY (a)->type) +#define XMISCTYPE(a) (XMISCANY (a)->type) #define XMARKER(a) (eassert (MARKERP (a)), &(XMISC (a)->u_marker)) #define XOVERLAY(a) (eassert (OVERLAYP (a)), &(XMISC (a)->u_overlay)) #define XSAVE_VALUE(a) (eassert (SAVE_VALUEP (a)), &(XMISC (a)->u_save_value)) +#define XBLV(a) (eassert (BLVP (a)), &(XMISC (a)->u_blv)) /* Forwarding object types. */ @@ -1342,6 +1344,59 @@ Lisp_Object plist; }; +/* struct Lisp_Buffer_Local_Value is used in a symbol value cell when + the symbol has buffer-local or frame-local bindings. (Exception: + some buffer-local variables are built-in, with their values stored + in the buffer structure itself. They are handled differently, + using struct Lisp_Buffer_Objfwd.) + + The `realvalue' slot holds the variable's current value, or a + forwarding pointer to where that value is kept. This value is the + one that corresponds to the loaded binding. To read or set the + variable, you must first make sure the right binding is loaded; + then you can access the value in (or through) `realvalue'. + + `buffer' and `frame' are the buffer and frame for which the loaded + binding was found. If those have changed, to make sure the right + binding is loaded it is necessary to find which binding goes with + the current buffer and selected frame, then load it. To load it, + first unload the previous binding, then copy the value of the new + binding into `realvalue' (or through it). Also update + LOADED-BINDING to point to the newly loaded binding. + + `local_if_set' indicates that merely setting the variable creates a + local binding for the current buffer. Otherwise the latter, setting + the variable does not do that; only make-local-variable does that. */ + +struct Lisp_Buffer_Local_Value + { + ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Buffer_Local_Value */ + unsigned gcmarkbit : 1; + int spacer : 12; + /* 1 means that merely setting the variable creates a local + binding for the current buffer. */ + unsigned int local_if_set : 1; + /* 1 means this variable can have frame-local bindings, otherwise, it is + can have buffer-local bindings. The two cannot be combined. */ + unsigned int frame_local : 1; + /* 1 means that the binding now loaded was found. + Presumably equivalent to (defcell!=valcell). */ + unsigned int found : 1; + /* If non-NULL, a forwarding to the C var where it should also be set. */ + union Lisp_Fwd *fwd; /* Should never be (Buffer|Kboard)_Objfwd. */ + /* The buffer or frame for which the loaded binding was found. */ + Lisp_Object where; + /* A cons cell that holds the default value. It has the form + (SYMBOL . DEFAULT-VALUE). */ + Lisp_Object defcell; + /* The cons cell from `where's parameter alist. + It always has the form (SYMBOL . VALUE) + Note that if `forward' is non-nil, VALUE may be out of date. + Also if the currently loaded binding is the default binding, then + this is `eq'ual to defcell. */ + Lisp_Object valcell; + }; + /* Hold a C pointer for later use. This type of object is used in the arg to record_unwind_protect. */ struct Lisp_Save_Value @@ -1375,6 +1430,7 @@ struct Lisp_Free u_free; struct Lisp_Marker u_marker; struct Lisp_Overlay u_overlay; + struct Lisp_Buffer_Local_Value u_blv; struct Lisp_Save_Value u_save_value; }; @@ -1417,64 +1473,6 @@ Lisp_Object slottype; /* Qnil, Lisp_Int, Lisp_Symbol, or Lisp_String. */ }; -/* struct Lisp_Buffer_Local_Value is used in a symbol value cell when - the symbol has buffer-local or frame-local bindings. (Exception: - some buffer-local variables are built-in, with their values stored - in the buffer structure itself. They are handled differently, - using struct Lisp_Buffer_Objfwd.) - - The `realvalue' slot holds the variable's current value, or a - forwarding pointer to where that value is kept. This value is the - one that corresponds to the loaded binding. To read or set the - variable, you must first make sure the right binding is loaded; - then you can access the value in (or through) `realvalue'. - - `buffer' and `frame' are the buffer and frame for which the loaded - binding was found. If those have changed, to make sure the right - binding is loaded it is necessary to find which binding goes with - the current buffer and selected frame, then load it. To load it, - first unload the previous binding, then copy the value of the new - binding into `realvalue' (or through it). Also update - LOADED-BINDING to point to the newly loaded binding. - - `local_if_set' indicates that merely setting the variable creates a - local binding for the current buffer. Otherwise the latter, setting - the variable does not do that; only make-local-variable does that. */ - -struct Lisp_Buffer_Local_Value - { - /* 1 means that merely setting the variable creates a local - binding for the current buffer. */ - unsigned int local_if_set : 1; - /* 1 means this variable can have frame-local bindings, otherwise, it is - can have buffer-local bindings. The two cannot be combined. */ - unsigned int frame_local : 1; - /* 1 means that the binding now loaded was found. - Presumably equivalent to (defcell!=valcell). */ - unsigned int found : 1; - /* If non-NULL, a forwarding to the C var where it should also be set. */ - union Lisp_Fwd *fwd; /* Should never be (Buffer|Kboard)_Objfwd. */ - /* The buffer or frame for which the loaded binding was found. */ - Lisp_Object where; - /* A cons cell that holds the default value. It has the form - (SYMBOL . DEFAULT-VALUE). */ - Lisp_Object defcell; - /* The cons cell from `where's parameter alist. - It always has the form (SYMBOL . VALUE) - Note that if `forward' is non-nil, VALUE may be out of date. - Also if the currently loaded binding is the default binding, then - this is `eq'ual to defcell. */ - Lisp_Object valcell; - }; - -#define BLV_FOUND(blv) \ - (eassert ((blv)->found == !EQ ((blv)->defcell, (blv)->valcell)), (blv)->found) -#define SET_BLV_FOUND(blv, v) \ - (eassert ((v) == !EQ ((blv)->defcell, (blv)->valcell)), (blv)->found = (v)) - -#define BLV_VALUE(blv) (XCDR ((blv)->valcell)) -#define SET_BLV_VALUE(blv, v) (XSETCDR ((blv)->valcell, v)) - /* Like Lisp_Objfwd except that value lives in a slot in the current kboard. */ struct Lisp_Kboard_Objfwd @@ -1664,6 +1662,7 @@ #define OVERLAYP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay) #define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker) #define SAVE_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value) +#define BLVP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Buffer_Local_Value) #define INTFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Int) #define BOOLFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Bool) @@ -2407,6 +2406,53 @@ XSYMBOL (sym)->next = next; } +/* Use these functions to get and set Lisp_Object + slots of struct Lisp_Buffer_Local_Value. */ + +LISP_INLINE int +get_blv_found (struct Lisp_Buffer_Local_Value *blv) +{ + eassert (blv->found == !EQ (blv->defcell, blv->valcell)); + return blv->found; +} + +LISP_INLINE void +set_blv_found (struct Lisp_Buffer_Local_Value *blv, int found) +{ + eassert (found == !EQ (blv->defcell, blv->valcell)); + blv->found = found; +} + +LISP_INLINE Lisp_Object +get_blv_value (struct Lisp_Buffer_Local_Value *blv) +{ + return XCDR (blv->valcell); +} + +LISP_INLINE void +set_blv_value (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val) +{ + XSETCDR (blv->valcell, val); +} + +LISP_INLINE void +set_blv_where (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val) +{ + blv->where = val; +} + +LISP_INLINE void +set_blv_defcell (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val) +{ + blv->defcell = val; +} + +LISP_INLINE void +set_blv_valcell (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val) +{ + blv->valcell = val; +} + /* Set overlay's property list. */ LISP_INLINE void @@ -2802,6 +2848,7 @@ extern void display_malloc_warning (void); extern ptrdiff_t inhibit_garbage_collection (void); extern Lisp_Object make_save_value (void *, ptrdiff_t); +extern struct Lisp_Buffer_Local_Value * make_buffer_local_value (void); extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); extern void free_marker (Lisp_Object); extern void free_cons (struct Lisp_Cons *);