APPROVE COMMIT
NOTE: This patch has been committed
# HG changeset patch
# User Aidan Kehoe <kehoea(a)parhasard.net>
# Date 1534796950 -3600
# Mon Aug 20 21:29:10 2018 +0100
# Node ID 483ea92098737f7a89dc002092032e6c6a9ad1e3
# Parent 51111ef13381b362dba0f4463ddae7257871e24f
Further reduce unnecessary marker byte-char conversion.
src/ChangeLog addition:
2018-08-20 Aidan Kehoe <kehoea(a)parhasard.net>
* callint.c (check_mark):
* callint.c (Fcall_interactively):
* editfns.c:
* editfns.c (Fpoint):
* editfns.c (region_limit):
* editfns.c (Fpoint_min_marker):
* editfns.c (Fpoint_max_marker):
* editfns.c (save_restriction_save):
* editfns.c (save_restriction_restore):
* editfns.c (transpose_markers):
* fileio.c:
* fileio.c (restore_point_unwind):
* keymap.c (get_relevant_keymaps):
* lisp.h:
* lread.c (readchar):
* lread.c (unreadchar):
* lstream.c (lisp_buffer_reader):
* lstream.c (lisp_buffer_writer):
* lstream.c (lisp_buffer_write_with_extents):
* lstream.c (lisp_buffer_rewinder):
* lstream.c (lisp_buffer_marker):
* marker.c:
* marker.c (fixup_set_marker_args):
* marker.c (set_marker_internal):
* marker.c (set_byte_marker_position):
* marker.c (Fset_marker):
* marker.c (set_marker_restricted):
* marker.c (copy_marker_1):
* print.c (output_string):
* text.c (get_buffer_pos_byte):
* text.c (get_buffer_range_byte):
Further reduce unnecessary marker byte-char conversion.
In particular:
-- Make #'copy-marker consistently O(1) with a marker argument.
-- Make #'set-marker O(1) with a marker POSITION.
-- Make set_marker_restricted O(1).
-- Avoid any byte-char conversions with get_buffer_pos_byte ()
with a marker POS.
-- Avoid any byte-char conversions with get_buffer_range_byte ()
with a marker FROM and a marker TO.
diff -r 51111ef13381 -r 483ea9209873 src/ChangeLog
--- a/src/ChangeLog Wed Aug 15 23:17:12 2018 +0100
+++ b/src/ChangeLog Mon Aug 20 21:29:10 2018 +0100
@@ -1,3 +1,46 @@
+2018-08-20 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * callint.c (check_mark):
+ * callint.c (Fcall_interactively):
+ * editfns.c:
+ * editfns.c (Fpoint):
+ * editfns.c (region_limit):
+ * editfns.c (Fpoint_min_marker):
+ * editfns.c (Fpoint_max_marker):
+ * editfns.c (save_restriction_save):
+ * editfns.c (save_restriction_restore):
+ * editfns.c (transpose_markers):
+ * fileio.c:
+ * fileio.c (restore_point_unwind):
+ * keymap.c (get_relevant_keymaps):
+ * lisp.h:
+ * lread.c (readchar):
+ * lread.c (unreadchar):
+ * lstream.c (lisp_buffer_reader):
+ * lstream.c (lisp_buffer_writer):
+ * lstream.c (lisp_buffer_write_with_extents):
+ * lstream.c (lisp_buffer_rewinder):
+ * lstream.c (lisp_buffer_marker):
+ * marker.c:
+ * marker.c (fixup_set_marker_args):
+ * marker.c (set_marker_internal):
+ * marker.c (set_byte_marker_position):
+ * marker.c (Fset_marker):
+ * marker.c (set_marker_restricted):
+ * marker.c (copy_marker_1):
+ * print.c (output_string):
+ * text.c (get_buffer_pos_byte):
+ * text.c (get_buffer_range_byte):
+ Further reduce unnecessary marker byte-char conversion.
+ In particular:
+ -- Make #'copy-marker consistently O(1) with a marker argument.
+ -- Make #'set-marker O(1) with a marker POSITION.
+ -- Make set_marker_restricted O(1).
+ -- Avoid any byte-char conversions with get_buffer_pos_byte ()
+ with a marker POS.
+ -- Avoid any byte-char conversions with get_buffer_range_byte ()
+ with a marker FROM and a marker TO.
+
2018-08-15 Aidan Kehoe <kehoea(a)parhasard.net>
Calls to marker_position() are O(N), reduce them in bytecode.
diff -r 51111ef13381 -r 483ea9209873 src/callint.c
--- a/src/callint.c Wed Aug 15 23:17:12 2018 +0100
+++ b/src/callint.c Mon Aug 20 21:29:10 2018 +0100
@@ -220,7 +220,7 @@
return expr;
}
-static Charbpos
+static Bytebpos
check_mark (void)
{
Lisp_Object tem;
@@ -232,7 +232,7 @@
if (NILP (tem) || (XBUFFER (tem) != current_buffer))
invalid_operation ("The mark is not set now", Qunbound);
- return marker_position (current_buffer->mark);
+ return byte_marker_position (current_buffer->mark);
}
static Lisp_Object
@@ -827,12 +827,12 @@
}
case 'r': /* Region, point and mark as 2 args. */
{
- Charbpos tem = check_mark ();
- args[argnum] = (BUF_PT (current_buffer) < tem
+ Bytebpos tem = check_mark ();
+ args[argnum] = (BYTE_BUF_PT (current_buffer) < tem
? Fcopy_marker (current_buffer->point_marker, Qt)
: current_buffer->mark);
varies[argnum] = Qregion_beginning;
- args[++argnum] = (BUF_PT (current_buffer) > tem
+ args[++argnum] = (BYTE_BUF_PT (current_buffer) > tem
? Fcopy_marker (current_buffer->point_marker,
Qt)
: current_buffer->mark);
diff -r 51111ef13381 -r 483ea9209873 src/editfns.c
--- a/src/editfns.c Wed Aug 15 23:17:12 2018 +0100
+++ b/src/editfns.c Mon Aug 20 21:29:10 2018 +0100
@@ -138,14 +138,6 @@
}
-static Lisp_Object
-buildmark (Charbpos val, Lisp_Object buffer)
-{
- Lisp_Object mark = Fmake_marker ();
- Fset_marker (mark, make_fixnum (val), buffer);
- return mark;
-}
-
DEFUN ("point", Fpoint, 0, 1, 0, /*
Return value of point, as an integer.
Beginning of buffer is position (point-min).
@@ -203,19 +195,19 @@
static Lisp_Object
region_limit (int beginningp, struct buffer *b)
{
- Lisp_Object m;
-
#if 0 /* FSFmacs */
if (!NILP (Vtransient_mark_mode) && NILP (Vmark_even_if_inactive)
&& NILP (b->mark_active))
Fsignal (Qmark_inactive, Qnil);
#endif
- m = Fmarker_position (b->mark);
- if (NILP (m)) invalid_operation ("There is no region now", Qunbound);
- if (!!(BUF_PT (b) < XFIXNUM (m)) == !!beginningp)
+ if (XMARKER (b->mark)->buffer == NULL)
+ {
+ invalid_operation ("There is no region now", Qunbound);
+ }
+ if (!!(BYTE_BUF_PT (b) < byte_marker_position (b->mark)) == !!beginningp)
return make_fixnum (BUF_PT (b));
else
- return m;
+ return Fmarker_position (b->mark);
}
DEFUN ("region-beginning", Fregion_beginning, 0, 1, 0, /*
@@ -439,7 +431,8 @@
(buffer))
{
struct buffer *b = decode_buffer (buffer, 1);
- return buildmark (BUF_BEGV (b), wrap_buffer (b));
+ return set_byte_marker_position (Fmake_marker (), BYTE_BUF_BEGV (b),
+ wrap_buffer (b));
}
DEFUN ("point-max", Fpoint_max, 0, 1, 0, /*
@@ -463,7 +456,8 @@
(buffer))
{
struct buffer *b = decode_buffer (buffer, 1);
- return buildmark (BUF_ZV (b), wrap_buffer (b));
+ return set_byte_marker_position (Fmake_marker (), BYTE_BUF_ZV (b),
+ wrap_buffer (b));
}
DEFUN ("following-char", Ffollowing_char, 0, 1, 0, /*
@@ -2149,8 +2143,8 @@
But that was clearly before the advent of marker-insertion-type. --ben */
- Fset_marker (bottom, make_fixnum (BUF_BEGV (buf)), wrap_buffer (buf));
- Fset_marker (top, make_fixnum (BUF_ZV (buf)), wrap_buffer (buf));
+ set_byte_marker_position (bottom, BYTE_BUF_BEGV (buf), wrap_buffer (buf));
+ set_byte_marker_position (top, BYTE_BUF_ZV (buf), wrap_buffer (buf));
Fset_marker_insertion_type (top, Qt);
return noseeum_cons (wrap_buffer (buf), noseeum_cons (bottom, top));
@@ -2167,29 +2161,35 @@
/* someone could have killed the buffer in the meantime ... */
if (BUFFER_LIVE_P (buf))
{
- Charbpos start = marker_position (XCAR (markers));
- Charbpos end = marker_position (XCDR (markers));
- Bytebpos byte_start = charbpos_to_bytebpos (buf, start);
- Bytebpos byte_end = charbpos_to_bytebpos (buf, end);
+ Bytebpos byte_start = byte_marker_position (XCAR (markers));
+ Bytebpos byte_end = byte_marker_position (XCDR (markers));
+ Bytebpos clipped;
- if (BUF_BEGV (buf) != start)
+ if (BYTE_BUF_BEGV (buf) != byte_start)
{
local_clip_changed = 1;
- SET_BOTH_BUF_BEGV (buf, start, byte_start);
+ SET_BOTH_BUF_BEGV (buf, bytebpos_to_charbpos (buf, byte_start),
+ byte_start);
narrow_line_number_cache (buf);
}
- if (BUF_ZV (buf) != end)
+ if (BYTE_BUF_ZV (buf) != byte_end)
{
local_clip_changed = 1;
- SET_BOTH_BUF_ZV (buf, end, byte_end);
+ SET_BOTH_BUF_ZV (buf, bytebpos_to_charbpos (buf, byte_end),
+ byte_end);
}
if (local_clip_changed)
MARK_CLIP_CHANGED;
/* If point is outside the new visible range, move it inside. */
- BUF_SET_PT (buf, charbpos_clip_to_bounds (BUF_BEGV (buf), BUF_PT (buf),
- BUF_ZV (buf)));
+ clipped = bytebpos_clip_to_bounds (BYTE_BUF_BEGV (buf),
+ BYTE_BUF_PT (buf),
+ BYTE_BUF_ZV (buf));
+ if (clipped != BYTE_BUF_PT (buf))
+ {
+ BYTE_BUF_SET_PT (buf, clipped);
+ }
}
/* Free all the junk we allocated, so that a `save-restriction' comes
@@ -2314,11 +2314,10 @@
mpos += diff;
else
mpos -= amt2;
- set_marker_position (marker, mpos);
+ Fset_marker (marker, make_fixnum (mpos), wrap_buffer (buf));
}
}
}
-
#endif /* 0 */
DEFUN ("transpose-regions", Ftranspose_regions, 4, 5, 0, /*
diff -r 51111ef13381 -r 483ea9209873 src/fileio.c
--- a/src/fileio.c Wed Aug 15 23:17:12 2018 +0100
+++ b/src/fileio.c Mon Aug 20 21:29:10 2018 +0100
@@ -195,7 +195,7 @@
static Lisp_Object
restore_point_unwind (Lisp_Object point_marker)
{
- BUF_SET_PT (current_buffer, marker_position (point_marker));
+ BYTE_BUF_SET_PT (current_buffer, byte_marker_position (point_marker));
return Fset_marker (point_marker, Qnil, Qnil);
}
diff -r 51111ef13381 -r 483ea9209873 src/keymap.c
--- a/src/keymap.c Wed Aug 15 23:17:12 2018 +0100
+++ b/src/keymap.c Mon Aug 20 21:29:10 2018 +0100
@@ -2678,8 +2678,7 @@
}
else if (MARKERP (position) && !NILP (Fmarker_buffer (position)))
{
- get_relevant_extent_keymaps (Fmarker_position (position),
- Fmarker_buffer (position),
+ get_relevant_extent_keymaps (position, Fmarker_buffer (position),
Qnil, &closure);
}
else if (EVENTP (position))
diff -r 51111ef13381 -r 483ea9209873 src/lisp.h
--- a/src/lisp.h Wed Aug 15 23:17:12 2018 +0100
+++ b/src/lisp.h Mon Aug 20 21:29:10 2018 +0100
@@ -5704,8 +5704,17 @@
Bytebpos byte_marker_position (Lisp_Object);
Charbpos marker_position (Lisp_Object);
-void set_byte_marker_position (Lisp_Object, Bytebpos);
-void set_marker_position (Lisp_Object, Charbpos);
+
+/* Set the byte position of MARKER, a marker object, to BYTENO in
+ BUFFER. MARKER must be a marker object, BUFFER must be a valid buffer, and
+ BYTENO must be a valid byte position within BUFFER. MARKER may not be
+ BUFFER's point marker. Values for MARKER, BYTENO, and BUFFER are checked
+ only if ERROR_CHECK_STRUCTURES is defined, and cause an assertion failure
+ if out of range, so callers need to check values themselves. */
+Lisp_Object set_byte_marker_position (Lisp_Object marker, Bytebpos byteno,
+ Lisp_Object buffer);
+/* No set_marker_position (); use Fset_marker (). */
+
void unchain_marker (Lisp_Object);
Lisp_Object noseeum_copy_marker (Lisp_Object, Lisp_Object);
Lisp_Object set_marker_restricted (Lisp_Object, Lisp_Object, Lisp_Object);
diff -r 51111ef13381 -r 483ea9209873 src/lread.c
--- a/src/lread.c Wed Aug 15 23:17:12 2018 +0100
+++ b/src/lread.c Mon Aug 20 21:29:10 2018 +0100
@@ -264,13 +264,14 @@
else if (MARKERP (readcharfun))
{
Ichar c;
- Charbpos mpos = marker_position (readcharfun);
+ Bytebpos mpos = byte_marker_position (readcharfun);
struct buffer *inbuffer = XMARKER (readcharfun)->buffer;
- if (mpos >= BUF_ZV (inbuffer))
+ if (mpos >= BYTE_BUF_ZV (inbuffer))
return -1;
c = BUF_FETCH_CHAR (inbuffer, mpos);
- set_marker_position (readcharfun, mpos + 1);
+ INC_BYTEBPOS (inbuffer, mpos);
+ set_byte_marker_position (readcharfun, mpos, wrap_buffer (inbuffer));
return c;
}
else
@@ -309,7 +310,19 @@
#endif
}
else if (MARKERP (readcharfun))
- set_marker_position (readcharfun, marker_position (readcharfun) - 1);
+ {
+ Bytebpos mpos = byte_marker_position (readcharfun);
+ struct buffer *buf = XMARKER (readcharfun)->buffer;
+
+ DEC_BYTEBPOS (buf, mpos);
+
+ set_byte_marker_position (readcharfun,
+ /* This is extra-conservative, no code
+ actually unreads without having read
+ anything. */
+ max (mpos, BYTE_BUF_BEG (buf)),
+ wrap_buffer (buf));
+ }
else
call1 (readcharfun, make_char (c));
}
diff -r 51111ef13381 -r 483ea9209873 src/lstream.c
--- a/src/lstream.c Wed Aug 15 23:17:12 2018 +0100
+++ b/src/lstream.c Mon Aug 20 21:29:10 2018 +0100
@@ -2090,7 +2090,7 @@
*p = '\n';
}
- set_byte_marker_position (str->start, end);
+ set_byte_marker_position (str->start, end, wrap_buffer (buf));
return size;
}
@@ -2107,7 +2107,7 @@
pos = marker_position (str->start);
pos += buffer_insert_raw_string_1 (buf, pos, data, size, 0);
- set_marker_position (str->start, pos);
+ Fset_marker (str->start, make_fixnum (pos), wrap_buffer (buf));
return size;
}
@@ -2128,7 +2128,7 @@
position,
len),
0);
- set_marker_position (str->start, pos);
+ Fset_marker (str->start, make_fixnum (pos), wrap_buffer (buf));
return len;
}
@@ -2138,16 +2138,16 @@
struct lisp_buffer_stream *str =
LISP_BUFFER_STREAM_DATA (stream);
struct buffer *buf = XBUFFER (str->buffer);
- long pos = marker_position (str->orig_start);
+ Bytebpos pos = byte_marker_position (str->orig_start);
if (!BUFFER_LIVE_P (buf))
return -1; /* Fut. */
- if (pos > BUF_ZV (buf))
- pos = BUF_ZV (buf);
- if (pos < marker_position (str->orig_start))
- pos = marker_position (str->orig_start);
- if (MARKERP (str->end) && pos > marker_position (str->end))
- pos = marker_position (str->end);
- set_marker_position (str->start, pos);
+ if (pos > BYTE_BUF_ZV (buf))
+ pos = BYTE_BUF_ZV (buf);
+ if (pos < byte_marker_position (str->orig_start))
+ pos = byte_marker_position (str->orig_start);
+ if (MARKERP (str->end) && pos > byte_marker_position (str->end))
+ pos = byte_marker_position (str->end);
+ set_byte_marker_position (str->start, pos, wrap_buffer (buf));
return 0;
}
diff -r 51111ef13381 -r 483ea9209873 src/marker.c
--- a/src/marker.c Wed Aug 15 23:17:12 2018 +0100
+++ b/src/marker.c Mon Aug 20 21:29:10 2018 +0100
@@ -175,83 +175,154 @@
#endif
-static Lisp_Object
-set_marker_internal (Lisp_Object marker, Lisp_Object position,
- Lisp_Object buffer, int restricted_p)
+static Bytebpos
+fixup_set_marker_args (Lisp_Object marker, Lisp_Object position,
+ Bytebpos byteno, Lisp_Object buffer,
+ Boolint restricted_p, struct buffer **buffer_out,
+ Boolint *pointp_out)
{
+ struct buffer *b;
+ Boolint point_p;
Charbpos charno;
- struct buffer *b;
- Lisp_Marker *m;
- int point_p;
CHECK_MARKER (marker);
-
- point_p = POINT_MARKER_P (marker);
+ point_p = *pointp_out = POINT_MARKER_P (marker);
- /* If position is nil or a marker that points nowhere,
- make this marker point nowhere. */
- if (NILP (position) ||
+ /* If position is nil or a marker that points nowhere, make this marker
+ point nowhere. */
+ if ((NILP (position) && -1 == byteno) ||
(MARKERP (position) && !XMARKER (position)->buffer))
{
if (point_p)
- invalid_operation ("Can't make point-marker point nowhere",
- marker);
- if (XMARKER (marker)->buffer)
- unchain_marker (marker);
- return marker;
+ {
+ invalid_operation ("Can't make point-marker point nowhere",
+ marker);
+ }
+
+ /* This is a signal that the marker should not point anyhere, none of
+ the other _out variables need to be set. */
+ *buffer_out = NULL;
+ return -1;
+ }
+
+ if (NILP (buffer))
+ {
+ b = *buffer_out = current_buffer;
+ }
+ else
+ {
+ CHECK_BUFFER (buffer);
+ b = *buffer_out = XBUFFER (buffer);
+
+ if (!BUFFER_LIVE_P (XBUFFER (buffer)))
+ {
+ if (point_p)
+ {
+ invalid_operation ("Can't move point-marker into killed
buffer",
+ marker);
+ }
+
+ *buffer_out = NULL;
+ return -1;
+ }
+ }
+
+ if (point_p && XMARKER (marker)->buffer != b)
+ {
+ invalid_operation ("Can't change buffer of point-marker", marker);
+ }
+
+ if (byteno != -1)
+ {
+ if (restricted_p)
+ {
+ if (byteno < BYTE_BUF_BEGV (b)) byteno = BYTE_BUF_BEGV (b);
+ if (byteno > BYTE_BUF_ZV (b)) byteno = BYTE_BUF_ZV (b);
+ }
+ else
+ {
+ if (byteno < BYTE_BUF_BEG (b)) byteno = BYTE_BUF_BEG (b);
+ if (byteno > BYTE_BUF_Z (b)) byteno = BYTE_BUF_Z (b);
+ }
+
+ return byteno;
+ }
+
+ if (MARKERP (position) && XMARKER (position)->buffer == b)
+ {
+ text_checking_assert (-1 == byteno);
+ byteno = membpos_to_bytebpos (b, XMARKER (position)->membpos);
+
+ if (restricted_p)
+ {
+ if (byteno < BYTE_BUF_BEGV (b)) byteno = BYTE_BUF_BEGV (b);
+ if (byteno > BYTE_BUF_ZV (b)) byteno = BYTE_BUF_ZV (b);
+ }
+
+ /* No need to do the usual restriction to valid buffer positions, since
+ we know POSITION is valid within BUFFER. */
+
+ return byteno;
}
CHECK_FIXNUM_COERCE_MARKER (position);
- if (NILP (buffer))
- b = current_buffer;
- else
- {
- CHECK_BUFFER (buffer);
- b = XBUFFER (buffer);
- /* If buffer is dead, set marker to point nowhere. */
- if (!BUFFER_LIVE_P (XBUFFER (buffer)))
- {
- if (point_p)
- invalid_operation
- ("Can't move point-marker in a killed buffer", marker);
- if (XMARKER (marker)->buffer)
- unchain_marker (marker);
- return marker;
- }
- }
-
charno = XFIXNUM (position);
- m = XMARKER (marker);
-
if (restricted_p)
{
- if (charno < BUF_BEGV (b)) charno = BUF_BEGV (b);
- if (charno > BUF_ZV (b)) charno = BUF_ZV (b);
+ if (charno < BUF_BEGV (b))
+ {
+ return BYTE_BUF_BEGV (b);
+ }
+ if (charno > BUF_ZV (b))
+ {
+ return BYTE_BUF_ZV (b);
+ }
}
else
{
- if (charno < BUF_BEG (b)) charno = BUF_BEG (b);
- if (charno > BUF_Z (b)) charno = BUF_Z (b);
+ if (charno < BUF_BEG (b))
+ {
+ return BYTE_BUF_BEG (b);
+ }
+ if (charno > BUF_Z (b))
+ {
+ return BYTE_BUF_Z (b);
+ }
+ }
+
+ return charbpos_to_bytebpos (b, charno);
+}
+
+static Lisp_Object
+set_marker_internal (Lisp_Object marker, Bytebpos byteno, struct buffer *b,
+ Boolint point_p)
+{
+ Lisp_Marker *m;
+
+ m = XMARKER (marker);
+
+ if (NULL == b)
+ {
+ /* Make this marker point nowhere. */
+ if (m->buffer)
+ {
+ unchain_marker (marker);
+ }
+
+ return marker;
}
if (point_p)
{
-#ifndef moving_point_by_moving_its_marker_is_a_bug
- BUF_SET_PT (b, charno); /* this will move the marker */
-#else /* It's not a feature, so it must be a bug */
- invalid_operation ("DEBUG: attempt to move point via point-marker",
- marker);
-#endif
+ BYTE_BUF_SET_PT (b, byteno); /* this will move the marker */
}
else
{
- m->membpos = charbpos_to_membpos (b, charno);
+ m->membpos = bytebpos_to_membpos (b, byteno);
}
if (m->buffer != b)
{
- if (point_p)
- invalid_operation ("Can't change buffer of point-marker", marker);
if (m->buffer != 0)
unchain_marker (marker);
m->buffer = b;
@@ -264,7 +335,31 @@
return marker;
}
+
+/* Set the byte position of MARKER, a marker object, to BYTENO in
+ BUFFER. MARKER must be a marker object, BUFFER must be a valid buffer, and
+ BYTENO must be a valid byte position within BUFFER. MARKER may not be
+ BUFFER's point marker. */
+Lisp_Object
+set_byte_marker_position (Lisp_Object marker, Bytebpos byteno,
+ Lisp_Object buffer)
+{
+#ifdef ERROR_CHECK_STRUCTURES
+ struct buffer *b;
+ Boolint point_p = 0;
+ Bytebpos old_byteno = byteno;
+ /* For the type, range checking. */
+ byteno = fixup_set_marker_args (marker, Qnil, byteno, buffer, 0, &b,
+ &point_p);
+
+ structure_checking_assert (!point_p);
+ structure_checking_assert (byteno == old_byteno);
+ structure_checking_assert (b == XBUFFER (buffer));
+#endif
+
+ return set_marker_internal (marker, byteno, XBUFFER (buffer), 0);
+}
DEFUN ("set-marker", Fset_marker, 2, 3, 0, /*
Move MARKER to position POSITION in BUFFER.
@@ -282,20 +377,31 @@
*/
(marker, position, buffer))
{
- return set_marker_internal (marker, position, buffer, 0);
+ struct buffer *b;
+ Bytebpos byteno = -1;
+ Boolint point_p;
+
+ byteno = fixup_set_marker_args (marker, position, -1, buffer, 0, &b,
+ &point_p);
+
+ return set_marker_internal (marker, byteno, b, point_p);
}
-
/* This version of Fset_marker won't let the position
be outside the visible part. */
Lisp_Object
set_marker_restricted (Lisp_Object marker, Lisp_Object position,
Lisp_Object buffer)
{
- return set_marker_internal (marker, position, buffer, 1);
+ struct buffer *b;
+ Bytebpos byteno = -1;
+ Boolint point_p;
+
+ byteno = fixup_set_marker_args (marker, position, -1, buffer, 1, &b,
+ &point_p);
+ return set_marker_internal (marker, byteno, b, point_p);
}
-
/* This is called during garbage collection,
so we must be careful to ignore and preserve mark bits,
including those in chain fields of markers. */
@@ -359,29 +465,6 @@
return bytebpos_to_charbpos (buf, byte_marker_position (marker));
}
-void
-set_byte_marker_position (Lisp_Object marker, Bytebpos pos)
-{
- Lisp_Marker *m = XMARKER (marker);
- struct buffer *buf = m->buffer;
-
- if (!buf)
- invalid_argument ("Marker does not point anywhere", Qunbound);
-
- m->membpos = bytebpos_to_membpos (buf, pos);
-}
-
-void
-set_marker_position (Lisp_Object marker, Charbpos pos)
-{
- struct buffer *buf = XMARKER (marker)->buffer;
-
- if (!buf)
- invalid_argument ("Marker does not point anywhere", Qunbound);
-
- set_byte_marker_position (marker, charbpos_to_bytebpos (buf, pos));
-}
-
static Lisp_Object
copy_marker_1 (Lisp_Object marker, Lisp_Object type, int noseeum)
{
diff -r 51111ef13381 -r 483ea9209873 src/print.c
--- a/src/print.c Wed Aug 15 23:17:12 2018 +0100
+++ b/src/print.c Mon Aug 20 21:29:10 2018 +0100
@@ -491,7 +491,8 @@
marker_position (function), nonreloc, reloc,
offset, len, -1, 0);
set_byte_marker_position (function,
- byte_marker_position (function) + len);
+ byte_marker_position (function) + len,
+ wrap_buffer (XMARKER (function)->buffer));
UNGCPRO;
return len; /* We will have errored on failure. */
}
diff -r 51111ef13381 -r 483ea9209873 src/text.c
--- a/src/text.c Wed Aug 15 23:17:12 2018 +0100
+++ b/src/text.c Mon Aug 20 21:29:10 2018 +0100
@@ -4246,10 +4246,40 @@
Bytebpos
get_buffer_pos_byte (struct buffer *b, Lisp_Object pos, unsigned int flags)
{
- Charbpos bpos = get_buffer_pos_char (b, pos, flags);
- if (bpos < 0) /* could happen with GB_NO_ERROR_IF_BAD */
- return -1;
- return charbpos_to_bytebpos (b, bpos);
+ if (MARKERP (pos) && XMARKER (pos)->buffer == b)
+ {
+ /* Does not GC */
+ Bytebpos ind;
+ Bytebpos min_allowed, max_allowed;
+
+ ind = byte_marker_position (pos);
+ min_allowed
+ = flags & GB_ALLOW_PAST_ACCESSIBLE ? BYTE_BUF_BEG (b)
+ : BYTE_BUF_BEGV (b);
+ max_allowed
+ = flags & GB_ALLOW_PAST_ACCESSIBLE ? BYTE_BUF_Z (b) : BYTE_BUF_ZV (b);
+
+ if (ind < min_allowed || ind > max_allowed)
+ {
+ if (flags & GB_COERCE_RANGE)
+ ind = ind < min_allowed ? min_allowed : max_allowed;
+ else if (flags & GB_NO_ERROR_IF_BAD)
+ ind = -1;
+ else
+ {
+ args_out_of_range (wrap_buffer (b), pos);
+ }
+ }
+
+ return ind;
+ }
+ else
+ {
+ Charbpos bpos = get_buffer_pos_char (b, pos, flags);
+ if (bpos < 0) /* could happen with GB_NO_ERROR_IF_BAD */
+ return -1;
+ return charbpos_to_bytebpos (b, bpos);
+ }
}
/* Return a pair of buffer positions representing a range of text,
@@ -4311,17 +4341,58 @@
Bytebpos *from_out, Bytebpos *to_out,
unsigned int flags)
{
- Charbpos s, e;
-
- get_buffer_range_char (b, from, to, &s, &e, flags);
- if (s >= 0)
- *from_out = charbpos_to_bytebpos (b, s);
- else /* could happen with GB_NO_ERROR_IF_BAD */
- *from_out = -1;
- if (e >= 0)
- *to_out = charbpos_to_bytebpos (b, e);
+ if (MARKERP (from) && XMARKER (from)->buffer == b
+ && MARKERP (to) && XMARKER (to)->buffer == b)
+ {
+ /* Does not GC */
+ Bytebpos min_allowed, max_allowed;
+
+ min_allowed = (flags & GB_ALLOW_PAST_ACCESSIBLE) ?
+ BYTE_BUF_BEG (b) : BYTE_BUF_BEGV (b);
+ max_allowed = (flags & GB_ALLOW_PAST_ACCESSIBLE) ?
+ BYTE_BUF_Z (b) : BYTE_BUF_ZV (b);
+
+ if (NILP (from) && (flags & GB_ALLOW_NIL))
+ *from_out = min_allowed;
+ else
+ *from_out = get_buffer_pos_byte (b, from, flags | GB_NO_ERROR_IF_BAD);
+
+ if (NILP (to) && (flags & GB_ALLOW_NIL))
+ *to_out = max_allowed;
+ else
+ *to_out = get_buffer_pos_byte (b, to, flags | GB_NO_ERROR_IF_BAD);
+
+ if ((*from_out < 0 || *to_out < 0) && !(flags &
GB_NO_ERROR_IF_BAD))
+ {
+ args_out_of_range_3 (wrap_buffer (b), from, to);
+ }
+
+ if (*from_out >= 0 && *to_out >= 0 && *from_out >
*to_out)
+ {
+ if (flags & GB_CHECK_ORDER)
+ invalid_argument_2 ("start greater than end", from, to);
+ else
+ {
+ Bytebpos temp = *from_out;
+ *from_out = *to_out;
+ *to_out = temp;
+ }
+ }
+ }
else
- *to_out = -1;
+ {
+ Charbpos s, e;
+
+ get_buffer_range_char (b, from, to, &s, &e, flags);
+ if (s >= 0)
+ *from_out = charbpos_to_bytebpos (b, s);
+ else /* could happen with GB_NO_ERROR_IF_BAD */
+ *from_out = -1;
+ if (e >= 0)
+ *to_out = charbpos_to_bytebpos (b, e);
+ else
+ *to_out = -1;
+ }
}
static Charcount
--
‘As I sat looking up at the Guinness ad, I could never figure out /
How your man stayed up on the surfboard after forty pints of stout’
(C. Moore)