From f8a25d00ae45a3362b08a999026835fde85f6ef0 Mon Sep 17 00:00:00 2001 From: Stephen Berman Date: Thu, 12 Feb 2026 18:48:20 +0100 Subject: Make 'overlays_in' use only real EOB (bug#80242) This restores the original behavior of 'overlays_in'. Changes in this behavior had been made for cases of narrowing, but this resulted in a regression with uses of 'remove-overlays'. * src/buffer.c (overlays_in): Change all occurrences of ZV to Z. * test/src/buffer-tests.el (test-overlays-in-2) (test-remove-overlays): Adjust expected results to accommodate changes in 'overlays_in'. --- src/buffer.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index 3d85d784f1c..1129d178c7b 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -3082,14 +3082,13 @@ overlays_in (ptrdiff_t beg, ptrdiff_t end, bool extend, { ptrdiff_t idx = 0; ptrdiff_t len = *len_ptr; - ptrdiff_t next = ZV; + ptrdiff_t next = Z; Lisp_Object *vec = *vec_ptr; struct itree_node *node; - /* Extend the search range if overlays beginning at ZV are - wanted. */ - ptrdiff_t search_end = ZV; - if (end >= ZV && (empty || trailing)) + /* Extend the search range if overlays beginning at Z are wanted. */ + ptrdiff_t search_end = Z; + if (end >= Z && (empty || trailing)) ++search_end; ITREE_FOREACH (node, current_buffer->overlays, beg, search_end, @@ -3103,7 +3102,7 @@ overlays_in (ptrdiff_t beg, ptrdiff_t end, bool extend, else if (node->begin == end) { next = node->begin; - if ((! empty || end < ZV) && beg < end) + if ((! empty || end < Z) && beg < end) break; if (empty && node->begin != node->end) continue; @@ -3125,7 +3124,7 @@ overlays_in (ptrdiff_t beg, ptrdiff_t end, bool extend, idx++; } if (next_ptr) - *next_ptr = next ? next : ZV; + *next_ptr = next ? next : Z; return idx; } -- cgit v1.2.1 From ba9a765081873a5caf5053e8b6203b00ef7324e0 Mon Sep 17 00:00:00 2001 From: Helmut Eller Date: Sat, 22 Jun 2024 16:43:29 +0200 Subject: Make Lisp_Buffer_Objfwd objects const The predicate field is always a builtin symbol. That means we know the bit pattern at compile-time and they don't change at runtime. * src/buffer.c (DEFVAR_PER_BUFFER): Create a const struct. (defvar_per_buffer): Remove predicate and address arguments. (syms_of_buffer): Instead of &BVAR (current_buffer, foo) use a plain foo as argument to DEFVAR_PER_BUFFER. * src/pdumper.c (dump_field_fwd): No more relocs needed for Lisp_Fwd_Buffer_Obj and we can't apply them in the .rodata section. --- src/buffer.c | 157 ++++++++++++++++++++++++++++++----------------------------- 1 file changed, 79 insertions(+), 78 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index 1129d178c7b..70ae2ba3d7b 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -4980,31 +4980,33 @@ init_buffer (void) that nil is allowed too). DOC is a dummy where you write the doc string as a comment. */ -#define DEFVAR_PER_BUFFER(lname, vname, predicate, doc) \ - do { \ - static struct Lisp_Buffer_Objfwd bo_fwd; \ - defvar_per_buffer (&bo_fwd, lname, vname, predicate); \ - } while (0) +/* FIXME: use LISPSYM_INITIALLY instead of TAG_PTR_INITIALLY */ +#define DEFVAR_PER_BUFFER(lname, vname, predicate_, doc) \ +do \ + { \ + const Lisp_Object sym = TAG_PTR_INITIALLY ( \ + Lisp_Symbol, (intptr_t)((i##predicate_) * sizeof *lispsym)); \ + static const struct Lisp_Buffer_Objfwd bo_fwd = { \ + .type = Lisp_Fwd_Buffer_Obj, \ + .offset = offsetof (struct buffer, vname##_), \ + .predicate = sym, \ + }; \ + defvar_per_buffer (&bo_fwd, lname); \ + } \ +while (0) static void -defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring, - Lisp_Object *address, Lisp_Object predicate) +defvar_per_buffer (const struct Lisp_Buffer_Objfwd *bo_fwd, + const char *namestring) { - struct Lisp_Symbol *sym; - int offset; - - sym = XSYMBOL (intern (namestring)); - offset = (char *)address - (char *)current_buffer; + struct Lisp_Symbol *sym = XSYMBOL (intern (namestring)); - bo_fwd->type = Lisp_Fwd_Buffer_Obj; - bo_fwd->offset = offset; - bo_fwd->predicate = predicate; sym->u.s.declared_special = true; sym->u.s.redirect = SYMBOL_FORWARDED; SET_SYMBOL_FWD (sym, bo_fwd); - XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym); + XSETSYMBOL (PER_BUFFER_SYMBOL (bo_fwd->offset), sym); - if (PER_BUFFER_IDX (offset) == 0) + if (PER_BUFFER_IDX (bo_fwd->offset) == 0) /* Did a DEFVAR_PER_BUFFER without initializing the corresponding slot of buffer_local_flags. */ emacs_abort (); @@ -5103,14 +5105,14 @@ syms_of_buffer (void) DEFSYM (Qclone_indirect_buffer_hook, "clone-indirect-buffer-hook"); DEFVAR_PER_BUFFER ("tab-line-format", - &BVAR (current_buffer, tab_line_format), + tab_line_format, Qnil, doc: /* Analogous to `mode-line-format', but controls the tab line. The tab line appears, optionally, at the top of a window; the mode line appears at the bottom. */); DEFVAR_PER_BUFFER ("header-line-format", - &BVAR (current_buffer, header_line_format), + header_line_format, Qnil, doc: /* Analogous to `mode-line-format', but controls the header line. The header line appears, optionally, at the top of a window; the mode @@ -5119,7 +5121,7 @@ line appears at the bottom. Also see `header-line-indent-mode' if `display-line-numbers-mode' is turned on and header-line text should be aligned with buffer text. */); - DEFVAR_PER_BUFFER ("mode-line-format", &BVAR (current_buffer, mode_line_format), + DEFVAR_PER_BUFFER ("mode-line-format", mode_line_format, Qnil, doc: /* Template for displaying mode line for a window's buffer. @@ -5193,7 +5195,7 @@ A string is printed verbatim in the mode line except for %-constructs: %% -- print %. Decimal digits after the % specify field width to which to pad. */); - DEFVAR_PER_BUFFER ("major-mode", &BVAR (current_buffer, major_mode), + DEFVAR_PER_BUFFER ("major-mode", major_mode, Qsymbolp, doc: /* Symbol for current buffer's major mode. The default value (normally `fundamental-mode') affects new buffers. @@ -5201,28 +5203,28 @@ A value of nil means to use the current buffer's major mode, provided it is not marked as "special". */); DEFVAR_PER_BUFFER ("local-minor-modes", - &BVAR (current_buffer, local_minor_modes), + local_minor_modes, Qnil, doc: /* Minor modes currently active in the current buffer. This is a list of symbols, or nil if there are no minor modes active. */); - DEFVAR_PER_BUFFER ("mode-name", &BVAR (current_buffer, mode_name), + DEFVAR_PER_BUFFER ("mode-name", mode_name, Qnil, doc: /* Pretty name of current buffer's major mode. Usually a string, but can use any of the constructs for `mode-line-format', which see. Format with `format-mode-line' to produce a string value. */); - DEFVAR_PER_BUFFER ("local-abbrev-table", &BVAR (current_buffer, abbrev_table), Qnil, + DEFVAR_PER_BUFFER ("local-abbrev-table", abbrev_table, Qnil, doc: /* Local (mode-specific) abbrev table of current buffer. */); - DEFVAR_PER_BUFFER ("abbrev-mode", &BVAR (current_buffer, abbrev_mode), Qnil, + DEFVAR_PER_BUFFER ("abbrev-mode", abbrev_mode, Qnil, doc: /* Non-nil if Abbrev mode is enabled. Use the command `abbrev-mode' to change the value of this variable in the current buffer. Customize this variable to non-nil to enable Abbrev mode by default in all buffers. */); - DEFVAR_PER_BUFFER ("fill-column", &BVAR (current_buffer, fill_column), + DEFVAR_PER_BUFFER ("fill-column", fill_column, Qintegerp, doc: /* Column beyond which automatic line-wrapping should happen. It is used by filling commands, such as `fill-region' and `fill-paragraph', @@ -5230,12 +5232,12 @@ and by `auto-fill-mode', which see. See also `current-fill-column'. Interactively, you can set the buffer local value using \\[set-fill-column]. */); - DEFVAR_PER_BUFFER ("left-margin", &BVAR (current_buffer, left_margin), + DEFVAR_PER_BUFFER ("left-margin", left_margin, Qintegerp, doc: /* Column for the default `indent-line-function' to indent to. Linefeed indents to this column in Fundamental mode. */); - DEFVAR_PER_BUFFER ("tab-width", &BVAR (current_buffer, tab_width), + DEFVAR_PER_BUFFER ("tab-width", tab_width, Qintegerp, doc: /* Distance between tab stops (for display of tab characters), in columns. This controls the width of a TAB character on display. @@ -5245,14 +5247,14 @@ indentation step. However, if the major mode's indentation facility inserts one or more TAB characters, this variable will affect the indentation step as well, even if `indent-tabs-mode' is non-nil. */); - DEFVAR_PER_BUFFER ("ctl-arrow", &BVAR (current_buffer, ctl_arrow), Qnil, + DEFVAR_PER_BUFFER ("ctl-arrow", ctl_arrow, Qnil, doc: /* Non-nil means display control chars with uparrow `^'. A value of nil means use backslash `\\' and octal digits. This variable does not apply to characters whose display is specified in the current display table (if there is one; see `standard-display-table'). */); DEFVAR_PER_BUFFER ("enable-multibyte-characters", - &BVAR (current_buffer, enable_multibyte_characters), + enable_multibyte_characters, Qnil, doc: /* Non-nil means the buffer contents are regarded as multi-byte characters. Otherwise they are regarded as unibyte. This affects the display, @@ -5266,7 +5268,7 @@ See also Info node `(elisp)Text Representations'. */); make_symbol_constant (intern_c_string ("enable-multibyte-characters")); DEFVAR_PER_BUFFER ("buffer-file-coding-system", - &BVAR (current_buffer, buffer_file_coding_system), Qnil, + buffer_file_coding_system, Qnil, doc: /* Coding system to be used for encoding the buffer contents on saving. This variable applies to saving the buffer, and also to `write-region' and other functions that use `write-region'. @@ -5284,7 +5286,7 @@ The variable `coding-system-for-write', if non-nil, overrides this variable. This variable is never applied to a way of decoding a file while reading it. */); DEFVAR_PER_BUFFER ("bidi-display-reordering", - &BVAR (current_buffer, bidi_display_reordering), Qnil, + bidi_display_reordering, Qnil, doc: /* Non-nil means reorder bidirectional text for display in the visual order. Setting this to nil is intended for use in debugging the display code. Don't set to nil in normal sessions, as that is not supported. @@ -5292,7 +5294,7 @@ See also `bidi-paragraph-direction'; setting that non-nil might speed up redisplay. */); DEFVAR_PER_BUFFER ("bidi-paragraph-start-re", - &BVAR (current_buffer, bidi_paragraph_start_re), Qnil, + bidi_paragraph_start_re, Qnil, doc: /* If non-nil, a regexp matching a line that starts OR separates paragraphs. The value of nil means to use empty lines as lines that start and @@ -5314,7 +5316,7 @@ set both these variables to "^". See also `bidi-paragraph-direction'. */); DEFVAR_PER_BUFFER ("bidi-paragraph-separate-re", - &BVAR (current_buffer, bidi_paragraph_separate_re), Qnil, + bidi_paragraph_separate_re, Qnil, doc: /* If non-nil, a regexp matching a line that separates paragraphs. The value of nil means to use empty lines as paragraph separators. @@ -5335,7 +5337,7 @@ set both these variables to "^". See also `bidi-paragraph-direction'. */); DEFVAR_PER_BUFFER ("bidi-paragraph-direction", - &BVAR (current_buffer, bidi_paragraph_direction), Qnil, + bidi_paragraph_direction, Qnil, doc: /* If non-nil, forces directionality of text paragraphs in the buffer. If this is nil (the default), the direction of each paragraph is @@ -5346,7 +5348,7 @@ Any other value is treated as nil. This variable has no effect unless the buffer's value of `bidi-display-reordering' is non-nil. */); - DEFVAR_PER_BUFFER ("truncate-lines", &BVAR (current_buffer, truncate_lines), Qnil, + DEFVAR_PER_BUFFER ("truncate-lines", truncate_lines, Qnil, doc: /* Non-nil means do not display continuation lines. Instead, give each line of text just one screen line. @@ -5359,7 +5361,7 @@ Minibuffers set this variable to nil. Don't set this to a non-nil value when `visual-line-mode' is turned on, as it could produce confusing results. */); - DEFVAR_PER_BUFFER ("word-wrap", &BVAR (current_buffer, word_wrap), Qnil, + DEFVAR_PER_BUFFER ("word-wrap", word_wrap, Qnil, doc: /* Non-nil means to use word-wrapping for continuation lines. When word-wrapping is on, continuation lines are wrapped at the space or tab character nearest to the right window edge. @@ -5377,14 +5379,14 @@ to t, and additionally redefines simple editing commands to act on visual lines rather than logical lines. See the documentation of `visual-line-mode'. */); - DEFVAR_PER_BUFFER ("default-directory", &BVAR (current_buffer, directory), + DEFVAR_PER_BUFFER ("default-directory", directory, Qstringp, doc: /* Name of default directory of current buffer. It should be an absolute directory name; on GNU and Unix systems, these names start with "/" or "~" and end with "/". To interactively change the default directory, use the command `cd'. */); - DEFVAR_PER_BUFFER ("auto-fill-function", &BVAR (current_buffer, auto_fill_function), + DEFVAR_PER_BUFFER ("auto-fill-function", auto_fill_function, Qnil, doc: /* Function called (if non-nil) to perform auto-fill. It is called after self-inserting any character specified in @@ -5392,31 +5394,31 @@ the `auto-fill-chars' table. NOTE: This variable is not a hook; its value may not be a list of functions. */); - DEFVAR_PER_BUFFER ("buffer-file-name", &BVAR (current_buffer, filename), + DEFVAR_PER_BUFFER ("buffer-file-name", filename, Qstringp, doc: /* Name of file visited in current buffer, or nil if not visiting a file. This should be an absolute file name. */); - DEFVAR_PER_BUFFER ("buffer-file-truename", &BVAR (current_buffer, file_truename), + DEFVAR_PER_BUFFER ("buffer-file-truename", file_truename, Qstringp, doc: /* Abbreviated truename of file visited in current buffer, or nil if none. The truename of a file is calculated by `file-truename' and then abbreviated with `abbreviate-file-name'. */); DEFVAR_PER_BUFFER ("buffer-auto-save-file-name", - &BVAR (current_buffer, auto_save_file_name), + auto_save_file_name, Qstringp, doc: /* Name of file for auto-saving current buffer. If it is nil, that means don't auto-save this buffer. */); - DEFVAR_PER_BUFFER ("buffer-read-only", &BVAR (current_buffer, read_only), Qnil, + DEFVAR_PER_BUFFER ("buffer-read-only", read_only, Qnil, doc: /* Non-nil if this buffer is read-only. */); - DEFVAR_PER_BUFFER ("buffer-backed-up", &BVAR (current_buffer, backed_up), Qnil, + DEFVAR_PER_BUFFER ("buffer-backed-up", backed_up, Qnil, doc: /* Non-nil if this buffer's file has been backed up. Backing up is done before the first time the file is saved. */); - DEFVAR_PER_BUFFER ("buffer-saved-size", &BVAR (current_buffer, save_length), + DEFVAR_PER_BUFFER ("buffer-saved-size", save_length, Qintegerp, doc: /* Length of current buffer when last read in, saved or auto-saved. 0 initially. @@ -5426,7 +5428,7 @@ If you set this to -2, that means don't turn off auto-saving in this buffer if its text size shrinks. If you use `buffer-swap-text' on a buffer, you probably should set this to -2 in that buffer. */); - DEFVAR_PER_BUFFER ("selective-display", &BVAR (current_buffer, selective_display), + DEFVAR_PER_BUFFER ("selective-display", selective_display, Qnil, doc: /* Non-nil enables selective display. @@ -5439,11 +5441,11 @@ in a file, save the ^M as a newline. This usage is obsolete; use overlays or text properties instead. */); DEFVAR_PER_BUFFER ("selective-display-ellipses", - &BVAR (current_buffer, selective_display_ellipses), + selective_display_ellipses, Qnil, doc: /* Non-nil means display ... on previous line when a line is invisible. */); - DEFVAR_PER_BUFFER ("overwrite-mode", &BVAR (current_buffer, overwrite_mode), + DEFVAR_PER_BUFFER ("overwrite-mode", overwrite_mode, Qoverwrite_mode, doc: /* Non-nil if self-insertion should replace existing text. The value should be one of `overwrite-mode-textual', @@ -5453,7 +5455,7 @@ inserts at the end of a line, and inserts when point is before a tab, until the tab is filled in. If `overwrite-mode-binary', self-insertion replaces newlines and tabs too. */); - DEFVAR_PER_BUFFER ("buffer-display-table", &BVAR (current_buffer, display_table), + DEFVAR_PER_BUFFER ("buffer-display-table", display_table, Qnil, doc: /* Display table that controls display of the contents of current buffer. @@ -5490,7 +5492,7 @@ In addition, a char-table has six extra slots to control the display of: See also the functions `display-table-slot' and `set-display-table-slot'. */); - DEFVAR_PER_BUFFER ("left-margin-width", &BVAR (current_buffer, left_margin_cols), + DEFVAR_PER_BUFFER ("left-margin-width", left_margin_cols, Qintegerp, doc: /* Width in columns of left marginal area for display of a buffer. A value of nil means no marginal area. @@ -5498,7 +5500,7 @@ A value of nil means no marginal area. Setting this variable does not take effect until a new buffer is displayed in a window. To make the change take effect, call `set-window-buffer'. */); - DEFVAR_PER_BUFFER ("right-margin-width", &BVAR (current_buffer, right_margin_cols), + DEFVAR_PER_BUFFER ("right-margin-width", right_margin_cols, Qintegerp, doc: /* Width in columns of right marginal area for display of a buffer. A value of nil means no marginal area. @@ -5506,7 +5508,7 @@ A value of nil means no marginal area. Setting this variable does not take effect until a new buffer is displayed in a window. To make the change take effect, call `set-window-buffer'. */); - DEFVAR_PER_BUFFER ("left-fringe-width", &BVAR (current_buffer, left_fringe_width), + DEFVAR_PER_BUFFER ("left-fringe-width", left_fringe_width, Qintegerp, doc: /* Width of this buffer's left fringe (in pixels). A value of 0 means no left fringe is shown in this buffer's window. @@ -5515,7 +5517,7 @@ A value of nil means to use the left fringe width from the window's frame. Setting this variable does not take effect until a new buffer is displayed in a window. To make the change take effect, call `set-window-buffer'. */); - DEFVAR_PER_BUFFER ("right-fringe-width", &BVAR (current_buffer, right_fringe_width), + DEFVAR_PER_BUFFER ("right-fringe-width", right_fringe_width, Qintegerp, doc: /* Width of this buffer's right fringe (in pixels). A value of 0 means no right fringe is shown in this buffer's window. @@ -5524,7 +5526,7 @@ A value of nil means to use the right fringe width from the window's frame. Setting this variable does not take effect until a new buffer is displayed in a window. To make the change take effect, call `set-window-buffer'. */); - DEFVAR_PER_BUFFER ("fringes-outside-margins", &BVAR (current_buffer, fringes_outside_margins), + DEFVAR_PER_BUFFER ("fringes-outside-margins", fringes_outside_margins, Qnil, doc: /* Non-nil means to display fringes outside display margins. A value of nil means to display fringes between margins and buffer text. @@ -5532,17 +5534,17 @@ A value of nil means to display fringes between margins and buffer text. Setting this variable does not take effect until a new buffer is displayed in a window. To make the change take effect, call `set-window-buffer'. */); - DEFVAR_PER_BUFFER ("scroll-bar-width", &BVAR (current_buffer, scroll_bar_width), + DEFVAR_PER_BUFFER ("scroll-bar-width", scroll_bar_width, Qintegerp, doc: /* Width of this buffer's vertical scroll bars in pixels. A value of nil means to use the scroll bar width from the window's frame. */); - DEFVAR_PER_BUFFER ("scroll-bar-height", &BVAR (current_buffer, scroll_bar_height), + DEFVAR_PER_BUFFER ("scroll-bar-height", scroll_bar_height, Qintegerp, doc: /* Height of this buffer's horizontal scroll bars in pixels. A value of nil means to use the scroll bar height from the window's frame. */); - DEFVAR_PER_BUFFER ("vertical-scroll-bar", &BVAR (current_buffer, vertical_scroll_bar_type), + DEFVAR_PER_BUFFER ("vertical-scroll-bar", vertical_scroll_bar_type, Qvertical_scroll_bar, doc: /* Position of this buffer's vertical scroll bar. The value takes effect whenever you tell a window to display this buffer; @@ -5552,7 +5554,7 @@ A value of `left' or `right' means put the vertical scroll bar at that side of the window; a value of nil means don't show any vertical scroll bars. A value of t (the default) means do whatever the window's frame specifies. */); - DEFVAR_PER_BUFFER ("horizontal-scroll-bar", &BVAR (current_buffer, horizontal_scroll_bar_type), + DEFVAR_PER_BUFFER ("horizontal-scroll-bar", horizontal_scroll_bar_type, Qnil, doc: /* Position of this buffer's horizontal scroll bar. The value takes effect whenever you tell a window to display this buffer; @@ -5564,14 +5566,14 @@ A value of t (the default) means do whatever the window's frame specifies. */); DEFVAR_PER_BUFFER ("indicate-empty-lines", - &BVAR (current_buffer, indicate_empty_lines), Qnil, + indicate_empty_lines, Qnil, doc: /* Visually indicate unused ("empty") screen lines after the buffer end. If non-nil, a bitmap is displayed in the left fringe of a window on graphical displays for each screen line that doesn't correspond to any buffer text. */); DEFVAR_PER_BUFFER ("indicate-buffer-boundaries", - &BVAR (current_buffer, indicate_buffer_boundaries), Qnil, + indicate_buffer_boundaries, Qnil, doc: /* Visually indicate buffer boundaries and scrolling. If non-nil, the first and last line of the buffer are marked in the fringe of a window on graphical displays with angle bitmaps, or if the window can be @@ -5596,7 +5598,7 @@ bitmaps in right fringe. To show just the angle bitmaps in the left fringe, but no arrow bitmaps, use ((top . left) (bottom . left)). */); DEFVAR_PER_BUFFER ("fringe-indicator-alist", - &BVAR (current_buffer, fringe_indicator_alist), Qnil, + fringe_indicator_alist, Qnil, doc: /* Mapping from logical to physical fringe indicator bitmaps. The value is an alist where each element (INDICATOR . BITMAPS) specifies the fringe bitmaps used to display a specific logical @@ -5615,7 +5617,7 @@ last (only) line has no final newline. BITMAPS may also be a single symbol which is used in both left and right fringes. */); DEFVAR_PER_BUFFER ("fringe-cursor-alist", - &BVAR (current_buffer, fringe_cursor_alist), Qnil, + fringe_cursor_alist, Qnil, doc: /* Mapping from logical to physical fringe cursor bitmaps. The value is an alist where each element (CURSOR . BITMAP) specifies the fringe bitmaps used to display a specific logical @@ -5630,7 +5632,7 @@ BITMAP is the corresponding fringe bitmap shown for the logical cursor type. */); DEFVAR_PER_BUFFER ("scroll-up-aggressively", - &BVAR (current_buffer, scroll_up_aggressively), Qfraction, + scroll_up_aggressively, Qfraction, doc: /* How far to scroll windows upward. If you move point off the bottom, the window scrolls automatically. This variable controls how far it scrolls. The value nil, the default, @@ -5643,7 +5645,7 @@ window scrolls by a full window height. Meaningful values are between 0.0 and 1.0, inclusive. */); DEFVAR_PER_BUFFER ("scroll-down-aggressively", - &BVAR (current_buffer, scroll_down_aggressively), Qfraction, + scroll_down_aggressively, Qfraction, doc: /* How far to scroll windows downward. If you move point off the top, the window scrolls automatically. This variable controls how far it scrolls. The value nil, the default, @@ -5694,7 +5696,7 @@ from happening repeatedly and making Emacs nonfunctional. */); The functions are run using the `run-hooks' function. */); Vfirst_change_hook = Qnil; - DEFVAR_PER_BUFFER ("buffer-undo-list", &BVAR (current_buffer, undo_list), Qnil, + DEFVAR_PER_BUFFER ("buffer-undo-list", undo_list, Qnil, doc: /* List of undo entries in current buffer. Recent changes come first; older changes follow newer. @@ -5740,10 +5742,10 @@ the changes between two undo boundaries as a single step to be undone. If the value of the variable is t, undo information is not recorded. */); - DEFVAR_PER_BUFFER ("mark-active", &BVAR (current_buffer, mark_active), Qnil, + DEFVAR_PER_BUFFER ("mark-active", mark_active, Qnil, doc: /* Non-nil means the mark and region are currently active in this buffer. */); - DEFVAR_PER_BUFFER ("cache-long-scans", &BVAR (current_buffer, cache_long_scans), Qnil, + DEFVAR_PER_BUFFER ("cache-long-scans", cache_long_scans, Qnil, doc: /* Non-nil means that Emacs should use caches in attempt to speedup buffer scans. There is no reason to set this to nil except for debugging purposes. @@ -5779,23 +5781,23 @@ maintained internally by the Emacs primitives. Enabling or disabling the cache should not affect the behavior of any of the motion functions; it should only affect their performance. */); - DEFVAR_PER_BUFFER ("point-before-scroll", &BVAR (current_buffer, point_before_scroll), Qnil, + DEFVAR_PER_BUFFER ("point-before-scroll", point_before_scroll, Qnil, doc: /* Value of point before the last series of scroll operations, or nil. */); - DEFVAR_PER_BUFFER ("buffer-file-format", &BVAR (current_buffer, file_format), Qnil, + DEFVAR_PER_BUFFER ("buffer-file-format", file_format, Qnil, doc: /* List of formats to use when saving this buffer. Formats are defined by `format-alist'. This variable is set when a file is visited. */); DEFVAR_PER_BUFFER ("buffer-auto-save-file-format", - &BVAR (current_buffer, auto_save_file_format), Qnil, + auto_save_file_format, Qnil, doc: /* Format in which to write auto-save files. Should be a list of symbols naming formats that are defined in `format-alist'. If it is t, which is the default, auto-save files are written in the same format as a regular save would use. */); DEFVAR_PER_BUFFER ("buffer-invisibility-spec", - &BVAR (current_buffer, invisibility_spec), Qnil, + invisibility_spec, Qnil, doc: /* Invisibility spec of this buffer. The default is t, which means that text is invisible if it has a non-nil `invisible' property. @@ -5809,12 +5811,12 @@ Setting this variable is very fast, much faster than scanning all the text in the buffer looking for properties to change. */); DEFVAR_PER_BUFFER ("buffer-display-count", - &BVAR (current_buffer, display_count), Qintegerp, + display_count, Qintegerp, doc: /* A number incremented each time this buffer is displayed in a window. The function `set-window-buffer' increments it. */); DEFVAR_PER_BUFFER ("buffer-display-time", - &BVAR (current_buffer, display_time), Qnil, + display_time, Qnil, doc: /* Time stamp updated each time this buffer is displayed in a window. The function `set-window-buffer' updates this variable to the value obtained by calling `current-time'. @@ -5850,7 +5852,7 @@ member of the list. Any other non-nil value means disregard `buffer-read-only' and all `read-only' text properties. */); Vinhibit_read_only = Qnil; - DEFVAR_PER_BUFFER ("cursor-type", &BVAR (current_buffer, cursor_type), Qnil, + DEFVAR_PER_BUFFER ("cursor-type", cursor_type, Qnil, doc: /* Cursor to use when this buffer is in the selected window. Values are interpreted as follows: @@ -5874,7 +5876,7 @@ cursor's appearance is instead controlled by the variable `cursor-in-non-selected-windows'. */); DEFVAR_PER_BUFFER ("line-spacing", - &BVAR (current_buffer, extra_line_spacing), Qnil, + extra_line_spacing, Qnil, doc: /* Additional space to put between lines when displaying a buffer. The space is measured in pixels, and put below lines on graphic displays, see `display-graphic-p'. @@ -5885,7 +5887,7 @@ it is interpreted as space above and below the line, respectively. A value of nil means add no extra space. */); DEFVAR_PER_BUFFER ("cursor-in-non-selected-windows", - &BVAR (current_buffer, cursor_in_non_selected_windows), Qnil, + cursor_in_non_selected_windows, Qnil, doc: /* Non-nil means show a cursor in non-selected windows. If nil, only shows a cursor in the selected window. If t, displays a cursor related to the usual cursor type @@ -5896,8 +5898,7 @@ Use Custom to set this variable and update the display. */); /* While this is defined here, each *term.c module must implement the logic itself. */ - DEFVAR_PER_BUFFER ("text-conversion-style", &BVAR (current_buffer, - text_conversion_style), + DEFVAR_PER_BUFFER ("text-conversion-style", text_conversion_style, Qnil, doc: /* How the on screen keyboard's input method should insert in this buffer. -- cgit v1.2.1 From 10befec978d1f1490f1eb43fd590e9474252063f Mon Sep 17 00:00:00 2001 From: Helmut Eller Date: Sun, 23 Jun 2024 06:39:18 +0200 Subject: Introduce a struct Lisp_Fwd This contains the type and an union of Lisp_Objfwd, Lisp_Intfwd etc. lispfwd is now a pointer to a struct Lisp_Fwd; the void *fwdptr field is gone. * src/lisp.h (struct Lisp_Fwd): New. (Lisp_Intfwd, Lisp_Boolfwd, Lisp_Objfwd, Lisp_Buffer_Objfwd) (Lisp_Kboard_Objfwd): The type is in in Lisp_Fwd. (lispwfd): Is now a pointer to struct Lisp_Fwd. (SYMBOL_BLV, SET_SYMBOL_FWD, XFWDTYPE, BUFFER_OBJFWDP): Update accordingly. (defvar_lisp, defvar_lisp_nopro, defvar_bool, defvar_int) (defvar_kboard): These all take now a Lisp_Fwd. (DEFVAR_LISP, DEFVAR_LISP_NOPRO, DEFVAR_BOOL, DEFVAR_INT) (DEFVAR_KBOARD): Update for new types. * src/lread.c (defvar_int, defvar_bool, defvar_lisp_nopro) (defvar_lisp, defvar_kboard): Update for new types. * src/pdumper.c (dump_field_fwd, dump_blv): Update accordingly. (dump_fwd_int, dump_fwd_bool, dump_fwd_obj, dump_fwd_buffer_obj) (dump_fwd): Deleted. * src/buffer.c (DEFVAR_PER_BUFFER, defvar_per_buffer, buffer_local_value) (set_buffer_internal_1): Update accordingly for new types. * src/data.c (XBOOLFWD, XKBOARD_OBJFWD, XFIXNUMFWD, XOBJFWD, boundp) (store_symval_forwarding, swap_in_global_binding) (swap_in_symval_forwarding, find_symbol_value, set_internal) (default_value, set_default_internal, make_blv, Fmake_local_variable): Update accordingly. --- src/buffer.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index 70ae2ba3d7b..9abce241897 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1379,7 +1379,7 @@ buffer_local_value (Lisp_Object variable, Lisp_Object buffer) result = assq_no_quit (variable, BVAR (buf, local_var_alist)); if (!NILP (result)) { - if (blv->fwd.fwdptr) + if (blv->fwd) { /* What binding is loaded right now? */ Lisp_Object current_alist_element = blv->valcell; @@ -2380,7 +2380,7 @@ void set_buffer_internal_2 (register struct buffer *b) Lisp_Object var = XCAR (XCAR (tail)); struct Lisp_Symbol *sym = XSYMBOL (var); if (sym->u.s.redirect == SYMBOL_LOCALIZED /* Just to be sure. */ - && SYMBOL_BLV (sym)->fwd.fwdptr) + && SYMBOL_BLV (sym)->fwd) /* Just reference the variable to cause it to become set for this buffer. */ Fsymbol_value (var); @@ -4986,24 +4986,25 @@ do \ { \ const Lisp_Object sym = TAG_PTR_INITIALLY ( \ Lisp_Symbol, (intptr_t)((i##predicate_) * sizeof *lispsym)); \ - static const struct Lisp_Buffer_Objfwd bo_fwd = { \ + static const struct Lisp_Fwd bo_fwd = { \ .type = Lisp_Fwd_Buffer_Obj, \ - .offset = offsetof (struct buffer, vname##_), \ - .predicate = sym, \ + .u.bufobjfwd = { .offset = offsetof (struct buffer, vname##_), \ + .predicate = sym }, \ }; \ defvar_per_buffer (&bo_fwd, lname); \ } \ while (0) static void -defvar_per_buffer (const struct Lisp_Buffer_Objfwd *bo_fwd, - const char *namestring) +defvar_per_buffer (const struct Lisp_Fwd *fwd, const char *namestring) { + eassert (fwd->type == Lisp_Fwd_Buffer_Obj); + const struct Lisp_Buffer_Objfwd *bo_fwd = XBUFFER_OBJFWD (fwd); struct Lisp_Symbol *sym = XSYMBOL (intern (namestring)); sym->u.s.declared_special = true; sym->u.s.redirect = SYMBOL_FORWARDED; - SET_SYMBOL_FWD (sym, bo_fwd); + SET_SYMBOL_FWD (sym, fwd); XSETSYMBOL (PER_BUFFER_SYMBOL (bo_fwd->offset), sym); if (PER_BUFFER_IDX (bo_fwd->offset) == 0) -- cgit v1.2.1 From 3442fdd2a2d9702bf9ed856b9bf0a0b1d0992747 Mon Sep 17 00:00:00 2001 From: Helmut Eller Date: Sun, 23 Jun 2024 17:25:21 +0200 Subject: Remove struct Lisp_Buffer_Objfwd * src/lisp.h (struct Lisp_Buffer_Objfwd): Deleted. (struct Lisp_Fwd): Add the fields bufoffset and bufpredicate. Make the type a 1-byte bitfield so that the entire struct still fits in two words. (XBUFFER_OFFSET): Renamed from XBUFFER_OBJFWD. * src/buffer.c (DEFVAR_PER_BUFFER, defvar_per_buffer) (buffer_local_value): Update accordingly. * src/data.c (do_symval_forwarding, store_symval_forwarding) (set_internal, default_value, set_default_internal) (Fmake_local_variable, Fkill_local_variable, Flocal_variable_): Use XBUFFER_OFFSET. --- src/buffer.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index 9abce241897..cc559ad0ad6 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1402,7 +1402,7 @@ buffer_local_value (Lisp_Object variable, Lisp_Object buffer) { lispfwd fwd = SYMBOL_FWD (sym); if (BUFFER_OBJFWDP (fwd)) - result = per_buffer_value (buf, XBUFFER_OBJFWD (fwd)->offset); + result = per_buffer_value (buf, XBUFFER_OFFSET (fwd)); else result = Fdefault_value (variable); break; @@ -4982,32 +4982,31 @@ init_buffer (void) /* FIXME: use LISPSYM_INITIALLY instead of TAG_PTR_INITIALLY */ #define DEFVAR_PER_BUFFER(lname, vname, predicate_, doc) \ -do \ - { \ - const Lisp_Object sym = TAG_PTR_INITIALLY ( \ - Lisp_Symbol, (intptr_t)((i##predicate_) * sizeof *lispsym)); \ - static const struct Lisp_Fwd bo_fwd = { \ - .type = Lisp_Fwd_Buffer_Obj, \ - .u.bufobjfwd = { .offset = offsetof (struct buffer, vname##_), \ - .predicate = sym }, \ - }; \ + do { \ + const Lisp_Object sym \ + = TAG_PTR_INITIALLY (Lisp_Symbol, (intptr_t)((i##predicate_) \ + * sizeof *lispsym)); \ + static const struct Lisp_Fwd bo_fwd \ + = { .type = Lisp_Fwd_Buffer_Obj, \ + .bufoffset = offsetof (struct buffer, vname##_), \ + .u.bufpredicate = sym }; \ + static_assert (offsetof (struct buffer, vname##_) \ + < (1 << 8 * sizeof bo_fwd.bufoffset)); \ defvar_per_buffer (&bo_fwd, lname); \ - } \ -while (0) + } while (0) static void defvar_per_buffer (const struct Lisp_Fwd *fwd, const char *namestring) { eassert (fwd->type == Lisp_Fwd_Buffer_Obj); - const struct Lisp_Buffer_Objfwd *bo_fwd = XBUFFER_OBJFWD (fwd); struct Lisp_Symbol *sym = XSYMBOL (intern (namestring)); sym->u.s.declared_special = true; sym->u.s.redirect = SYMBOL_FORWARDED; SET_SYMBOL_FWD (sym, fwd); - XSETSYMBOL (PER_BUFFER_SYMBOL (bo_fwd->offset), sym); + XSETSYMBOL (PER_BUFFER_SYMBOL (XBUFFER_OFFSET (fwd)), sym); - if (PER_BUFFER_IDX (bo_fwd->offset) == 0) + if (PER_BUFFER_IDX (XBUFFER_OFFSET (fwd)) == 0) /* Did a DEFVAR_PER_BUFFER without initializing the corresponding slot of buffer_local_flags. */ emacs_abort (); -- cgit v1.2.1 From 9008e6a9d7f041875c2fe9f58d5b5b44e84f649f Mon Sep 17 00:00:00 2001 From: Helmut Eller Date: Sun, 23 Jun 2024 21:46:16 +0200 Subject: Introduce an enum Lisp_Fwd_Predicate Using an enum instead of a symbol makes it obvious that this field is of no concern to the GC. * src/lisp.h (enum Lisp_Fwd_Predicate): New. (struct Lisp_Fwd): Use it instead of a symbol. * src/buffer.c (DEFVAR_PER_BUFFER): Create the necessary enum constant instead of a symbol. * src/data.c (check_fwd_predicate, check_choice): New helpers. (store_symval_forwarding): Use it. --- src/buffer.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index cc559ad0ad6..afc2f0f4d89 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -4980,19 +4980,15 @@ init_buffer (void) that nil is allowed too). DOC is a dummy where you write the doc string as a comment. */ -/* FIXME: use LISPSYM_INITIALLY instead of TAG_PTR_INITIALLY */ -#define DEFVAR_PER_BUFFER(lname, vname, predicate_, doc) \ - do { \ - const Lisp_Object sym \ - = TAG_PTR_INITIALLY (Lisp_Symbol, (intptr_t)((i##predicate_) \ - * sizeof *lispsym)); \ - static const struct Lisp_Fwd bo_fwd \ - = { .type = Lisp_Fwd_Buffer_Obj, \ - .bufoffset = offsetof (struct buffer, vname##_), \ - .u.bufpredicate = sym }; \ - static_assert (offsetof (struct buffer, vname##_) \ - < (1 << 8 * sizeof bo_fwd.bufoffset)); \ - defvar_per_buffer (&bo_fwd, lname); \ +#define DEFVAR_PER_BUFFER(lname, vname, predicate, doc) \ + do { \ + static const struct Lisp_Fwd bo_fwd \ + = { .type = Lisp_Fwd_Buffer_Obj, \ + .bufoffset = offsetof (struct buffer, vname##_), \ + .u.bufpredicate = FWDPRED_##predicate }; \ + static_assert (offsetof (struct buffer, vname##_) \ + < (1 << 8 * sizeof bo_fwd.bufoffset)); \ + defvar_per_buffer (&bo_fwd, lname); \ } while (0) static void -- cgit v1.2.1 From 40f696757c2afe15a583945992955429b00de563 Mon Sep 17 00:00:00 2001 From: Helmut Eller Date: Mon, 24 Jun 2024 10:06:54 +0200 Subject: Move the Lisp_Fwd.bufoffset field back to the union * src/lisp.h (struct Lisp_Fwd): With the predicate enum, we can now pack the offset and the predicate into a one-word struct. (XBUFFER_OFFSET): Use the new field name. * src/buffer.c (DEFVAR_PER_BUFFER): Create the one-word struct. * src/data.c (store_symval_forwarding): Use the new field name. --- src/buffer.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c index afc2f0f4d89..b1a835b7ac5 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -4980,14 +4980,17 @@ init_buffer (void) that nil is allowed too). DOC is a dummy where you write the doc string as a comment. */ -#define DEFVAR_PER_BUFFER(lname, vname, predicate, doc) \ +#define DEFVAR_PER_BUFFER(lname, vname, predicate_, doc) \ do { \ - static const struct Lisp_Fwd bo_fwd \ - = { .type = Lisp_Fwd_Buffer_Obj, \ - .bufoffset = offsetof (struct buffer, vname##_), \ - .u.bufpredicate = FWDPRED_##predicate }; \ + static const struct Lisp_Fwd bo_fwd = { \ + .type = Lisp_Fwd_Buffer_Obj, \ + .u.buf = { \ + .offset = offsetof (struct buffer, vname##_), \ + .predicate = FWDPRED_##predicate_ \ + } \ + }; \ static_assert (offsetof (struct buffer, vname##_) \ - < (1 << 8 * sizeof bo_fwd.bufoffset)); \ + < (1 << 8 * sizeof bo_fwd.u.buf.offset)); \ defvar_per_buffer (&bo_fwd, lname); \ } while (0) -- cgit v1.2.1