Mercurial > emacs
comparison src/buffer.c @ 107984:bef5d1738c0b
Make variable forwarding explicit rather the using special values.
Basically, this makes the structure of buffer-local values and object
forwarding explicit in the type of Lisp_Symbols rather than use
special Lisp_Objects for that. This tends to lead to slightly more
verbose code, but is more C-like, simpler, and makes it easier to make
sure we handled all cases, among other things by letting the compiler
help us check it.
* lisp.h (enum Lisp_Misc_Type, union Lisp_Misc):
Removing forwarding objects.
(enum Lisp_Fwd_Type, enum symbol_redirect, union Lisp_Fwd): New types.
(struct Lisp_Symbol): Make the various forms of variable-forwarding
explicit rather than hiding them inside Lisp_Object "values".
(XFWDTYPE): New macro.
(XINTFWD, XBOOLFWD, XOBJFWD, XKBOARD_OBJFWD): Redefine.
(XBUFFER_LOCAL_VALUE): Remove.
(SYMBOL_VAL, SYMBOL_ALIAS, SYMBOL_BLV, SYMBOL_FWD, SET_SYMBOL_VAL)
(SET_SYMBOL_ALIAS, SET_SYMBOL_BLV, SET_SYMBOL_FWD): New macros.
(SYMBOL_VALUE, SET_SYMBOL_VALUE): Remove.
(struct Lisp_Intfwd, struct Lisp_Boolfwd, struct Lisp_Objfwd)
(struct Lisp_Buffer_Objfwd, struct Lisp_Kboard_Objfwd):
Remove the Lisp_Misc_* header.
(struct Lisp_Buffer_Local_Value): Redefine.
(BLV_FOUND, SET_BLV_FOUND, BLV_VALUE, SET_BLV_VALUE): New macros.
(struct Lisp_Misc_Any): Add filler to get the right size.
(struct Lisp_Free): Use struct Lisp_Misc_Any rather than struct
Lisp_Intfwd.
(DEFVAR_LISP, DEFVAR_LISP_NOPRO, DEFVAR_BOOL, DEFVAR_INT)
(DEFVAR_KBOARD): Allocate a forwarding object.
* data.c (do_blv_forwarding, store_blv_forwarding): New macros.
(let_shadows_global_binding_p): New function.
(union Lisp_Val_Fwd): New type.
(make_blv): New function.
(swap_in_symval_forwarding, indirect_variable, do_symval_forwarding)
(store_symval_forwarding, swap_in_global_binding, Fboundp)
(swap_in_symval_forwarding, find_symbol_value, Fset)
(let_shadows_buffer_binding_p, set_internal, default_value)
(Fset_default, Fmake_variable_buffer_local, Fmake_local_variable)
(Fkill_local_variable, Fmake_variable_frame_local)
(Flocal_variable_p, Flocal_variable_if_set_p)
(Fvariable_binding_locus):
* xdisp.c (select_frame_for_redisplay):
* lread.c (Fintern, Funintern, init_obarray, defvar_int)
(defvar_bool, defvar_lisp_nopro, defvar_lisp, defvar_kboard):
* frame.c (store_frame_param):
* eval.c (Fdefvaralias, Fuser_variable_p, specbind, unbind_to):
* bytecode.c (Fbyte_code) <varref, varset>: Adapt to the new symbol
value structure.
* buffer.c (PER_BUFFER_SYMBOL): Move from buffer.h.
(clone_per_buffer_values): Only adjust markers into the current buffer.
(reset_buffer_local_variables): PER_BUFFER_IDX is never -2.
(Fbuffer_local_value, set_buffer_internal_1)
(swap_out_buffer_local_variables):
Adapt to the new symbol value structure.
(DEFVAR_PER_BUFFER): Allocate a Lisp_Buffer_Objfwd object.
(defvar_per_buffer): Take a new arg for the fwd object.
(buffer_lisp_local_variables): Return a proper alist (different fix
for bug#4138).
* alloc.c (Fmake_symbol): Use SET_SYMBOL_VAL.
(Fgarbage_collect): Don't handle buffer_defaults specially.
(mark_object): Handle new symbol value structure rather than the old
special Lisp_Misc_* objects.
(gc_sweep) <symbols>: Free also the buffer-local-value objects.
* term.c (set_tty_color_mode):
* bidi.c (bidi_initialize): Don't access the ->value field directly.
* buffer.h (PER_BUFFER_VAR_OFFSET): Don't bother with
a buffer_local_flags.
* print.c (print_object): Get rid of impossible forwarding objects.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Mon, 19 Apr 2010 21:50:52 -0400 |
parents | 688679bd79f5 |
children | 4b71850034e6 |
comparison
equal
deleted
inserted
replaced
107983:781bff25a517 | 107984:bef5d1738c0b |
---|---|
76 | 76 |
77 If a slot in this structure is -1, then even though there may | 77 If a slot in this structure is -1, then even though there may |
78 be a DEFVAR_PER_BUFFER for the slot, there is no default value for it; | 78 be a DEFVAR_PER_BUFFER for the slot, there is no default value for it; |
79 and the corresponding slot in buffer_defaults is not used. | 79 and the corresponding slot in buffer_defaults is not used. |
80 | 80 |
81 If a slot is -2, then there is no DEFVAR_PER_BUFFER for it, | |
82 but there is a default value which is copied into each buffer. | |
83 | |
84 If a slot in this structure corresponding to a DEFVAR_PER_BUFFER is | 81 If a slot in this structure corresponding to a DEFVAR_PER_BUFFER is |
85 zero, that is a bug */ | 82 zero, that is a bug */ |
86 | 83 |
87 struct buffer buffer_local_flags; | 84 struct buffer buffer_local_flags; |
88 | 85 |
91 | 88 |
92 DECL_ALIGN (struct buffer, buffer_local_symbols); | 89 DECL_ALIGN (struct buffer, buffer_local_symbols); |
93 | 90 |
94 /* A Lisp_Object pointer to the above, used for staticpro */ | 91 /* A Lisp_Object pointer to the above, used for staticpro */ |
95 static Lisp_Object Vbuffer_local_symbols; | 92 static Lisp_Object Vbuffer_local_symbols; |
93 | |
94 /* Return the symbol of the per-buffer variable at offset OFFSET in | |
95 the buffer structure. */ | |
96 | |
97 #define PER_BUFFER_SYMBOL(OFFSET) \ | |
98 (*(Lisp_Object *)((OFFSET) + (char *) &buffer_local_symbols)) | |
96 | 99 |
97 /* Flags indicating which built-in buffer-local variables | 100 /* Flags indicating which built-in buffer-local variables |
98 are permanent locals. */ | 101 are permanent locals. */ |
99 static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS]; | 102 static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS]; |
100 | 103 |
505 /* Don't touch the `name' which should be unique for every buffer. */ | 508 /* Don't touch the `name' which should be unique for every buffer. */ |
506 if (offset == PER_BUFFER_VAR_OFFSET (name)) | 509 if (offset == PER_BUFFER_VAR_OFFSET (name)) |
507 continue; | 510 continue; |
508 | 511 |
509 obj = PER_BUFFER_VALUE (from, offset); | 512 obj = PER_BUFFER_VALUE (from, offset); |
510 if (MARKERP (obj)) | 513 if (MARKERP (obj) && XMARKER (obj)->buffer == from) |
511 { | 514 { |
512 struct Lisp_Marker *m = XMARKER (obj); | 515 struct Lisp_Marker *m = XMARKER (obj); |
513 obj = Fmake_marker (); | 516 obj = Fmake_marker (); |
514 XMARKER (obj)->insertion_type = m->insertion_type; | 517 XMARKER (obj)->insertion_type = m->insertion_type; |
515 set_marker_both (obj, to_buffer, m->charpos, m->bytepos); | 518 set_marker_both (obj, to_buffer, m->charpos, m->bytepos); |
768 b->local_var_alist = Qnil; | 771 b->local_var_alist = Qnil; |
769 else | 772 else |
770 { | 773 { |
771 Lisp_Object tmp, prop, last = Qnil; | 774 Lisp_Object tmp, prop, last = Qnil; |
772 for (tmp = b->local_var_alist; CONSP (tmp); tmp = XCDR (tmp)) | 775 for (tmp = b->local_var_alist; CONSP (tmp); tmp = XCDR (tmp)) |
773 if (CONSP (XCAR (tmp)) | 776 if (!NILP (prop = Fget (XCAR (XCAR (tmp)), Qpermanent_local))) |
774 && SYMBOLP (XCAR (XCAR (tmp))) | |
775 && !NILP (prop = Fget (XCAR (XCAR (tmp)), Qpermanent_local))) | |
776 { | 777 { |
777 /* If permanent-local, keep it. */ | 778 /* If permanent-local, keep it. */ |
778 last = tmp; | 779 last = tmp; |
779 if (EQ (prop, Qpermanent_local_hook)) | 780 if (EQ (prop, Qpermanent_local_hook)) |
780 { | 781 { |
820 offset += sizeof (Lisp_Object)) | 821 offset += sizeof (Lisp_Object)) |
821 { | 822 { |
822 int idx = PER_BUFFER_IDX (offset); | 823 int idx = PER_BUFFER_IDX (offset); |
823 if ((idx > 0 | 824 if ((idx > 0 |
824 && (permanent_too | 825 && (permanent_too |
825 || buffer_permanent_local_flags[idx] == 0)) | 826 || buffer_permanent_local_flags[idx] == 0))) |
826 /* Is -2 used anywhere? */ | |
827 || idx == -2) | |
828 PER_BUFFER_VALUE (b, offset) = PER_BUFFER_DEFAULT (offset); | 827 PER_BUFFER_VALUE (b, offset) = PER_BUFFER_DEFAULT (offset); |
829 } | 828 } |
830 } | 829 } |
831 | 830 |
832 /* We split this away from generate-new-buffer, because rename-buffer | 831 /* We split this away from generate-new-buffer, because rename-buffer |
936 struct Lisp_Symbol *sym; | 935 struct Lisp_Symbol *sym; |
937 | 936 |
938 CHECK_SYMBOL (variable); | 937 CHECK_SYMBOL (variable); |
939 CHECK_BUFFER (buffer); | 938 CHECK_BUFFER (buffer); |
940 buf = XBUFFER (buffer); | 939 buf = XBUFFER (buffer); |
941 | 940 sym = XSYMBOL (variable); |
942 sym = indirect_variable (XSYMBOL (variable)); | 941 |
943 XSETSYMBOL (variable, sym); | 942 start: |
944 | 943 switch (sym->redirect) |
945 /* Look in local_var_list */ | 944 { |
946 result = Fassoc (variable, buf->local_var_alist); | 945 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; |
947 if (NILP (result)) | 946 case SYMBOL_PLAINVAL: result = SYMBOL_VAL (sym); break; |
948 { | 947 case SYMBOL_LOCALIZED: |
949 int offset, idx; | 948 { /* Look in local_var_alist. */ |
950 int found = 0; | 949 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); |
951 | 950 XSETSYMBOL (variable, sym); /* Update In case of aliasing. */ |
952 /* Look in special slots */ | 951 result = Fassoc (variable, buf->local_var_alist); |
953 /* buffer-local Lisp variables start at `undo_list', | 952 if (!NILP (result)) |
954 tho only the ones from `name' on are GC'd normally. */ | 953 { |
955 for (offset = PER_BUFFER_VAR_OFFSET (undo_list); | 954 if (blv->fwd) |
956 offset < sizeof (struct buffer); | 955 { /* What binding is loaded right now? */ |
957 /* sizeof EMACS_INT == sizeof Lisp_Object */ | 956 Lisp_Object current_alist_element = blv->valcell; |
958 offset += (sizeof (EMACS_INT))) | 957 |
959 { | 958 /* The value of the currently loaded binding is not |
960 idx = PER_BUFFER_IDX (offset); | 959 stored in it, but rather in the realvalue slot. |
961 if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx)) | 960 Store that value into the binding it belongs to |
962 && SYMBOLP (PER_BUFFER_SYMBOL (offset)) | 961 in case that is the one we are about to use. */ |
963 && EQ (PER_BUFFER_SYMBOL (offset), variable)) | 962 |
964 { | 963 XSETCDR (current_alist_element, |
965 result = PER_BUFFER_VALUE (buf, offset); | 964 do_symval_forwarding (blv->fwd)); |
966 found = 1; | 965 } |
967 break; | 966 /* Now get the (perhaps updated) value out of the binding. */ |
968 } | 967 result = XCDR (result); |
969 } | 968 } |
970 | 969 else |
971 if (!found) | 970 result = Fdefault_value (variable); |
972 result = Fdefault_value (variable); | 971 break; |
973 } | 972 } |
974 else | 973 case SYMBOL_FORWARDED: |
975 { | 974 { |
976 Lisp_Object valcontents; | 975 union Lisp_Fwd *fwd = SYMBOL_FWD (sym); |
977 Lisp_Object current_alist_element; | 976 if (BUFFER_OBJFWDP (fwd)) |
978 | 977 result = PER_BUFFER_VALUE (buf, XBUFFER_OBJFWD (fwd)->offset); |
979 /* What binding is loaded right now? */ | 978 else |
980 valcontents = sym->value; | 979 result = Fdefault_value (variable); |
981 current_alist_element | 980 break; |
982 = XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr); | 981 } |
983 | 982 default: abort (); |
984 /* The value of the currently loaded binding is not | |
985 stored in it, but rather in the realvalue slot. | |
986 Store that value into the binding it belongs to | |
987 in case that is the one we are about to use. */ | |
988 | |
989 Fsetcdr (current_alist_element, | |
990 do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->realvalue)); | |
991 | |
992 /* Now get the (perhaps updated) value out of the binding. */ | |
993 result = XCDR (result); | |
994 } | 983 } |
995 | 984 |
996 if (!EQ (result, Qunbound)) | 985 if (!EQ (result, Qunbound)) |
997 return result; | 986 return result; |
998 | 987 |
1023 val = find_symbol_value (XCAR (elt)); | 1012 val = find_symbol_value (XCAR (elt)); |
1024 /* Use the current buffer value only if buf is the current buffer. */ | 1013 /* Use the current buffer value only if buf is the current buffer. */ |
1025 if (buf != current_buffer) | 1014 if (buf != current_buffer) |
1026 val = XCDR (elt); | 1015 val = XCDR (elt); |
1027 | 1016 |
1028 /* If symbol is unbound, put just the symbol in the list. */ | 1017 result = Fcons (Fcons (XCAR (elt), val), result); |
1029 if (EQ (val, Qunbound)) | |
1030 result = Fcons (XCAR (elt), result); | |
1031 /* Otherwise, put (symbol . value) in the list. */ | |
1032 else | |
1033 result = Fcons (Fcons (XCAR (elt), val), result); | |
1034 } | 1018 } |
1035 | 1019 |
1036 return result; | 1020 return result; |
1037 } | 1021 } |
1038 | 1022 |
1860 void | 1844 void |
1861 set_buffer_internal_1 (b) | 1845 set_buffer_internal_1 (b) |
1862 register struct buffer *b; | 1846 register struct buffer *b; |
1863 { | 1847 { |
1864 register struct buffer *old_buf; | 1848 register struct buffer *old_buf; |
1865 register Lisp_Object tail, valcontents; | 1849 register Lisp_Object tail; |
1866 Lisp_Object tem; | |
1867 | 1850 |
1868 #ifdef USE_MMAP_FOR_BUFFERS | 1851 #ifdef USE_MMAP_FOR_BUFFERS |
1869 if (b->text->beg == NULL) | 1852 if (b->text->beg == NULL) |
1870 enlarge_buffer_text (b, 0); | 1853 enlarge_buffer_text (b, 0); |
1871 #endif /* USE_MMAP_FOR_BUFFERS */ | 1854 #endif /* USE_MMAP_FOR_BUFFERS */ |
1933 } | 1916 } |
1934 | 1917 |
1935 /* Look down buffer's list of local Lisp variables | 1918 /* Look down buffer's list of local Lisp variables |
1936 to find and update any that forward into C variables. */ | 1919 to find and update any that forward into C variables. */ |
1937 | 1920 |
1938 for (tail = b->local_var_alist; CONSP (tail); tail = XCDR (tail)) | 1921 do |
1939 { | 1922 { |
1940 if (CONSP (XCAR (tail)) | 1923 for (tail = b->local_var_alist; CONSP (tail); tail = XCDR (tail)) |
1941 && SYMBOLP (XCAR (XCAR (tail))) | 1924 { |
1942 && (valcontents = SYMBOL_VALUE (XCAR (XCAR (tail))), | 1925 Lisp_Object var = XCAR (XCAR (tail)); |
1943 (BUFFER_LOCAL_VALUEP (valcontents))) | 1926 struct Lisp_Symbol *sym = XSYMBOL (var); |
1944 && (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue, | 1927 if (sym->redirect == SYMBOL_LOCALIZED /* Just to be sure. */ |
1945 (BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem)))) | 1928 && SYMBOL_BLV (sym)->fwd) |
1946 /* Just reference the variable to cause it to become set for | 1929 /* Just reference the variable |
1947 this buffer. */ | 1930 to cause it to become set for this buffer. */ |
1948 Fsymbol_value (XCAR (XCAR (tail))); | 1931 Fsymbol_value (var); |
1949 } | 1932 } |
1950 | 1933 } |
1951 /* Do the same with any others that were local to the previous buffer */ | 1934 /* Do the same with any others that were local to the previous buffer */ |
1952 | 1935 while (b != old_buf && (b = old_buf, b)); |
1953 if (old_buf) | |
1954 for (tail = old_buf->local_var_alist; CONSP (tail); tail = XCDR (tail)) | |
1955 { | |
1956 if (CONSP (tail) | |
1957 && SYMBOLP (XCAR (XCAR (tail))) | |
1958 && (valcontents = SYMBOL_VALUE (XCAR (XCAR (tail))), | |
1959 (BUFFER_LOCAL_VALUEP (valcontents))) | |
1960 && (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue, | |
1961 (BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem)))) | |
1962 /* Just reference the variable to cause it to become set for | |
1963 this buffer. */ | |
1964 Fsymbol_value (XCAR (XCAR (tail))); | |
1965 } | |
1966 } | 1936 } |
1967 | 1937 |
1968 /* Switch to buffer B temporarily for redisplay purposes. | 1938 /* Switch to buffer B temporarily for redisplay purposes. |
1969 This avoids certain things that don't need to be done within redisplay. */ | 1939 This avoids certain things that don't need to be done within redisplay. */ |
1970 | 1940 |
2675 | 2645 |
2676 static void | 2646 static void |
2677 swap_out_buffer_local_variables (b) | 2647 swap_out_buffer_local_variables (b) |
2678 struct buffer *b; | 2648 struct buffer *b; |
2679 { | 2649 { |
2680 Lisp_Object oalist, alist, sym, buffer; | 2650 Lisp_Object oalist, alist, buffer; |
2681 | 2651 |
2682 XSETBUFFER (buffer, b); | 2652 XSETBUFFER (buffer, b); |
2683 oalist = b->local_var_alist; | 2653 oalist = b->local_var_alist; |
2684 | 2654 |
2685 for (alist = oalist; CONSP (alist); alist = XCDR (alist)) | 2655 for (alist = oalist; CONSP (alist); alist = XCDR (alist)) |
2686 { | 2656 { |
2687 if (CONSP (XCAR (alist)) | 2657 Lisp_Object sym = XCAR (XCAR (alist)); |
2688 && (sym = XCAR (XCAR (alist)), SYMBOLP (sym)) | 2658 eassert (XSYMBOL (sym)->redirect == SYMBOL_LOCALIZED); |
2689 /* Need not do anything if some other buffer's binding is | 2659 /* Need not do anything if some other buffer's binding is |
2690 now encached. */ | 2660 now encached. */ |
2691 && EQ (XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->buffer, | 2661 if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer)) |
2692 buffer)) | |
2693 { | 2662 { |
2694 /* Symbol is set up for this buffer's old local value: | 2663 /* Symbol is set up for this buffer's old local value: |
2695 swap it out! */ | 2664 swap it out! */ |
2696 swap_in_global_binding (sym); | 2665 swap_in_global_binding (XSYMBOL (sym)); |
2697 } | 2666 } |
2698 } | 2667 } |
2699 } | 2668 } |
2700 | 2669 |
2701 /* Find all the overlays in the current buffer that contain position POS. | 2670 /* Find all the overlays in the current buffer that contain position POS. |
5160 bzero (buffer_permanent_local_flags, sizeof buffer_permanent_local_flags); | 5129 bzero (buffer_permanent_local_flags, sizeof buffer_permanent_local_flags); |
5161 | 5130 |
5162 /* Make sure all markable slots in buffer_defaults | 5131 /* Make sure all markable slots in buffer_defaults |
5163 are initialized reasonably, so mark_buffer won't choke. */ | 5132 are initialized reasonably, so mark_buffer won't choke. */ |
5164 reset_buffer (&buffer_defaults); | 5133 reset_buffer (&buffer_defaults); |
5134 eassert (EQ (buffer_defaults.name, make_number (0))); | |
5165 reset_buffer_local_variables (&buffer_defaults, 1); | 5135 reset_buffer_local_variables (&buffer_defaults, 1); |
5136 eassert (EQ (buffer_local_symbols.name, make_number (0))); | |
5166 reset_buffer (&buffer_local_symbols); | 5137 reset_buffer (&buffer_local_symbols); |
5167 reset_buffer_local_variables (&buffer_local_symbols, 1); | 5138 reset_buffer_local_variables (&buffer_local_symbols, 1); |
5168 /* Prevent GC from getting confused. */ | 5139 /* Prevent GC from getting confused. */ |
5169 buffer_defaults.text = &buffer_defaults.own_text; | 5140 buffer_defaults.text = &buffer_defaults.own_text; |
5170 buffer_local_symbols.text = &buffer_local_symbols.own_text; | 5141 buffer_local_symbols.text = &buffer_local_symbols.own_text; |
5419 /* Similar to defvar_lisp but define a variable whose value is the Lisp | 5390 /* Similar to defvar_lisp but define a variable whose value is the Lisp |
5420 Object stored in the current buffer. address is the address of the slot | 5391 Object stored in the current buffer. address is the address of the slot |
5421 in the buffer that is current now. */ | 5392 in the buffer that is current now. */ |
5422 | 5393 |
5423 /* TYPE is nil for a general Lisp variable. | 5394 /* TYPE is nil for a general Lisp variable. |
5424 An integer specifies a type; then only LIsp values | 5395 An integer specifies a type; then only Lisp values |
5425 with that type code are allowed (except that nil is allowed too). | 5396 with that type code are allowed (except that nil is allowed too). |
5426 LNAME is the LIsp-level variable name. | 5397 LNAME is the Lisp-level variable name. |
5427 VNAME is the name of the buffer slot. | 5398 VNAME is the name of the buffer slot. |
5428 DOC is a dummy where you write the doc string as a comment. */ | 5399 DOC is a dummy where you write the doc string as a comment. */ |
5429 #define DEFVAR_PER_BUFFER(lname, vname, type, doc) \ | 5400 #define DEFVAR_PER_BUFFER(lname, vname, type, doc) \ |
5430 defvar_per_buffer (lname, vname, type, 0) | 5401 do { \ |
5402 static struct Lisp_Buffer_Objfwd bo_fwd; \ | |
5403 defvar_per_buffer (&bo_fwd, lname, vname, type, 0); \ | |
5404 } while (0) | |
5431 | 5405 |
5432 static void | 5406 static void |
5433 defvar_per_buffer (namestring, address, type, doc) | 5407 defvar_per_buffer (bo_fwd, namestring, address, type, doc) |
5408 struct Lisp_Buffer_Objfwd *bo_fwd; | |
5434 char *namestring; | 5409 char *namestring; |
5435 Lisp_Object *address; | 5410 Lisp_Object *address; |
5436 Lisp_Object type; | 5411 Lisp_Object type; |
5437 char *doc; | 5412 char *doc; |
5438 { | 5413 { |
5439 Lisp_Object sym, val; | 5414 struct Lisp_Symbol *sym; |
5440 int offset; | 5415 int offset; |
5441 | 5416 |
5442 sym = intern (namestring); | 5417 sym = XSYMBOL (intern (namestring)); |
5443 val = allocate_misc (); | |
5444 offset = (char *)address - (char *)current_buffer; | 5418 offset = (char *)address - (char *)current_buffer; |
5445 | 5419 |
5446 XMISCTYPE (val) = Lisp_Misc_Buffer_Objfwd; | 5420 bo_fwd->type = Lisp_Fwd_Buffer_Obj; |
5447 XBUFFER_OBJFWD (val)->offset = offset; | 5421 bo_fwd->offset = offset; |
5448 XBUFFER_OBJFWD (val)->slottype = type; | 5422 bo_fwd->slottype = type; |
5449 SET_SYMBOL_VALUE (sym, val); | 5423 sym->redirect = SYMBOL_FORWARDED; |
5450 PER_BUFFER_SYMBOL (offset) = sym; | 5424 { |
5425 /* I tried to do the job without a cast, but it seems impossible. | |
5426 union Lisp_Fwd *fwd; &(fwd->u_buffer_objfwd) = bo_fwd; */ | |
5427 SET_SYMBOL_FWD (sym, (union Lisp_Fwd *)bo_fwd); | |
5428 } | |
5429 XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym); | |
5451 | 5430 |
5452 if (PER_BUFFER_IDX (offset) == 0) | 5431 if (PER_BUFFER_IDX (offset) == 0) |
5453 /* Did a DEFVAR_PER_BUFFER without initializing the corresponding | 5432 /* Did a DEFVAR_PER_BUFFER without initializing the corresponding |
5454 slot of buffer_local_flags */ | 5433 slot of buffer_local_flags */ |
5455 abort (); | 5434 abort (); |