Commit d614e4a8 authored by Paul Eggert's avatar Paul Eggert

Turn misc objects into pseudovectors

Eliminate the category of miscellaneous objects, and turn all
such objects into pseudovectors.  The immediate motivation
for this change is to free up an enum Lisp_Type tag value, a
scarce resource that can be better used elsewhere.  However,
this change is worthwhile in its own right, as it improves
performance slightly on my platform, 0.3% faster for 'make
compile-always' on Fedora 28, and it simplifies the garbage
collector and interpreter (Bug#32405).
* doc/lispref/internals.texi (Garbage Collection):
* etc/NEWS:
Document change to garbage-collect return value.
* src/alloc.c (total_markers, total_free_markers):
(union aligned_Lisp_Misc, MARKER_BLOCK_SIZE)
(struct marker_block, marker_block, marker_block_index)
(misc_free_list, allocate_misc, live_misc_holding)
(live_misc_p, sweep_misc):
* src/lisp.h (lisp_h_MARKERP, lisp_h_MISCP, MARKERP, MISCP)
(Lisp_Misc, enum Lisp_Misc_Type, Lisp_Misc_Free)
(Lisp_Misc_Marker, Lisp_Misc_Overlay, Lisp_Misc_Finalizer)
(Lisp_Misc_Ptr, Lisp_Misc_User_Ptr, Lisp_Misc_Limit)
(Lisp_Misc_Bignum)
(XSETMISC, struct Lisp_Misc_Any, XMISCANY, XMISCTYPE)
(struct Lisp_Free, union Lisp_Misc, XMISC):
Remove.  All uses removed.
(cleanup_vector): Clean up objects that were formerly misc
and are now pseudovectors.
(make_misc_ptr, build_overlay, Fmake_marker, build_marker)
(make_bignum_str, make_number, make_pure_bignum)
(make_user_ptr, Fmake_finalizer):
Build as pseudovectors, not as misc objects.
(mark_finalizer_list, queue_doomed_finalizers)
(compact_undo_list, mark_overlay, mark_object)
(unchain_dead_markers):
Mark as vector-like objects, not as misc objects.
(mark_maybe_object, mark_maybe_pointer, valid_lisp_object_p)
(total_bytes_of_live_objects, survives_gc_p):
* src/fns.c (sxhash):
No need to worry about misc objects.
(garbage_collect_1): Do not generate a 'misc' component.
(syms_of_alloc): No need for 'misc' symbol.
* src/buffer.c (overlays_at, overlays_in, overlay_touches_p)
(overlay_strings, recenter_overlay_lists)
(fix_start_end_in_overlays, fix_overlays_before)
(Foverlay_lists, report_overlay_modification)
(evaporate_overlays):
* src/editfns.c (overlays_around):
* src/data.c (Ftype_of):
* src/fns.c (internal_equal):
* src/lisp.h (mint_ptrp, xmint_pointer, FINALIZERP)
(XFINALIZER, MARKERP, XMARKER, OVERLAYP, XOVERLAY, USER_PTRP)
(XUSER_PTR, BIGNUMP, XBIGNUM):
* src/print.c (print_vectorlike, print_object):
* src/undo.c (record_marker_adjustments):
* src/xdisp.c (load_overlay_strings):
Formerly misc objects are now pseudovectors.
* src/lisp.h (PVEC_MARKER, PVEC_OVERLAY, PVEC_FINALIZER)
(PVEC_BIGNUM, PVEC_MISC_PTR, PVEC_USER_PTR):
New constants, replacing their misc versions.  All uses changed.
(struct Lisp_Marker, struct Lisp_Overlay, struct Lisp_Misc_Ptr)
(struct Lisp_Bignum, struct Lisp_User_Ptr, struct Lisp_Finalizer):
Make usable as a pseudovector by using a pseudovector header,
replacing any DIY components, and putting Lisp_Object members
first.  All uses changed.
parent d3ec5117
......@@ -318,7 +318,6 @@ future allocations. So an overall result is:
@example
((@code{conses} @var{cons-size} @var{used-conses} @var{free-conses})
(@code{symbols} @var{symbol-size} @var{used-symbols} @var{free-symbols})
(@code{miscs} @var{misc-size} @var{used-miscs} @var{free-miscs})
(@code{strings} @var{string-size} @var{used-strings} @var{free-strings})
(@code{string-bytes} @var{byte-size} @var{used-bytes})
(@code{vectors} @var{vector-size} @var{used-vectors})
......@@ -334,7 +333,7 @@ Here is an example:
@example
(garbage-collect)
@result{} ((conses 16 49126 8058) (symbols 48 14607 0)
(miscs 40 34 56) (strings 32 2942 2607)
(strings 32 2942 2607)
(string-bytes 1 78607) (vectors 16 7247)
(vector-slots 8 341609 29474) (floats 8 71 102)
(intervals 56 27 26) (buffers 944 8)
......@@ -371,14 +370,6 @@ Internal size of a miscellaneous entity, i.e.,
@code{sizeof (union Lisp_Misc)}, which is a size of the
largest type enumerated in @code{enum Lisp_Misc_Type}.
@item used-miscs
The number of miscellaneous objects in use. These include markers
and overlays, plus certain objects not visible to users.
@item free-miscs
The number of miscellaneous objects for which space has been obtained
from the operating system, but that are not currently being used.
@item string-size
Internal size of a string header, i.e., @code{sizeof (struct Lisp_String)}.
......
......@@ -817,6 +817,10 @@ is backwards-compatible with versions of Emacs in which the old function
exists. See the node "Displaying Buffers in Side Windows" in the ELisp
manual for more details.
** The 'garbage-collect' function no longer returns a 'misc' component
because garbage collection no longer treats miscellaneous objects
specially; they are now allocated like any other pseudovector.
* Lisp Changes in Emacs 27.1
......
This diff is collapsed.
This diff is collapsed.
......@@ -221,29 +221,17 @@ for example, (type-of 1) returns `integer'. */)
case Lisp_Cons:
return Qcons;
case Lisp_Misc:
switch (XMISCTYPE (object))
{
case Lisp_Misc_Marker:
return Qmarker;
case Lisp_Misc_Overlay:
return Qoverlay;
case Lisp_Misc_Finalizer:
return Qfinalizer;
#ifdef HAVE_MODULES
case Lisp_Misc_User_Ptr:
return Quser_ptr;
#endif
case Lisp_Misc_Bignum:
return Qinteger;
default:
emacs_abort ();
}
case Lisp_Vectorlike:
switch (PSEUDOVECTOR_TYPE (XVECTOR (object)))
{
case PVEC_NORMAL_VECTOR: return Qvector;
case PVEC_BIGNUM: return Qinteger;
case PVEC_MARKER: return Qmarker;
case PVEC_OVERLAY: return Qoverlay;
case PVEC_FINALIZER: return Qfinalizer;
#ifdef HAVE_MODULES
case PVEC_USER_PTR: return Quser_ptr;
#endif
case PVEC_WINDOW_CONFIGURATION: return Qwindow_configuration;
case PVEC_PROCESS: return Qprocess;
case PVEC_WINDOW: return Qwindow;
......@@ -279,6 +267,7 @@ for example, (type-of 1) returns `integer'. */)
case PVEC_MODULE_FUNCTION:
return Qmodule_function;
/* "Impossible" cases. */
case PVEC_MISC_PTR:
case PVEC_XWIDGET:
case PVEC_OTHER:
case PVEC_XWIDGET_VIEW:
......
......@@ -484,21 +484,18 @@ If you set the marker not to point anywhere, the buffer will have no mark. */)
static ptrdiff_t
overlays_around (EMACS_INT pos, Lisp_Object *vec, ptrdiff_t len)
{
Lisp_Object overlay, start, end;
struct Lisp_Overlay *tail;
ptrdiff_t startpos, endpos;
ptrdiff_t idx = 0;
for (tail = current_buffer->overlays_before; tail; tail = tail->next)
for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
tail; tail = tail->next)
{
XSETMISC (overlay, tail);
end = OVERLAY_END (overlay);
endpos = OVERLAY_POSITION (end);
Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
Lisp_Object end = OVERLAY_END (overlay);
ptrdiff_t endpos = OVERLAY_POSITION (end);
if (endpos < pos)
break;
start = OVERLAY_START (overlay);
startpos = OVERLAY_POSITION (start);
Lisp_Object start = OVERLAY_START (overlay);
ptrdiff_t startpos = OVERLAY_POSITION (start);
if (startpos <= pos)
{
if (idx < len)
......@@ -508,16 +505,16 @@ overlays_around (EMACS_INT pos, Lisp_Object *vec, ptrdiff_t len)
}
}
for (tail = current_buffer->overlays_after; tail; tail = tail->next)
for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
tail; tail = tail->next)
{
XSETMISC (overlay, tail);
start = OVERLAY_START (overlay);
startpos = OVERLAY_POSITION (start);
Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
Lisp_Object start = OVERLAY_START (overlay);
ptrdiff_t startpos = OVERLAY_POSITION (start);
if (pos < startpos)
break;
end = OVERLAY_END (overlay);
endpos = OVERLAY_POSITION (end);
Lisp_Object end = OVERLAY_END (overlay);
ptrdiff_t endpos = OVERLAY_POSITION (end);
if (pos <= endpos)
{
if (idx < len)
......
......@@ -2287,7 +2287,7 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind,
ht = CALLN (Fmake_hash_table, QCtest, Qeq);
switch (XTYPE (o1))
{
case Lisp_Cons: case Lisp_Misc: case Lisp_Vectorlike:
case Lisp_Cons: case Lisp_Vectorlike:
{
struct Lisp_Hash_Table *h = XHASH_TABLE (ht);
EMACS_UINT hash;
......@@ -2344,31 +2344,6 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind,
depth++;
goto tail_recurse;
case Lisp_Misc:
if (XMISCTYPE (o1) != XMISCTYPE (o2))
return false;
if (OVERLAYP (o1))
{
if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o2),
equal_kind, depth + 1, ht)
|| !internal_equal (OVERLAY_END (o1), OVERLAY_END (o2),
equal_kind, depth + 1, ht))
return false;
o1 = XOVERLAY (o1)->plist;
o2 = XOVERLAY (o2)->plist;
depth++;
goto tail_recurse;
}
if (MARKERP (o1))
{
return (XMARKER (o1)->buffer == XMARKER (o2)->buffer
&& (XMARKER (o1)->buffer == 0
|| XMARKER (o1)->bytepos == XMARKER (o2)->bytepos));
}
if (BIGNUMP (o1))
return mpz_cmp (XBIGNUM (o1)->value, XBIGNUM (o2)->value) == 0;
break;
case Lisp_Vectorlike:
{
register int i;
......@@ -2378,6 +2353,26 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind,
same size. */
if (ASIZE (o2) != size)
return false;
if (BIGNUMP (o1))
return mpz_cmp (XBIGNUM (o1)->value, XBIGNUM (o2)->value) == 0;
if (OVERLAYP (o1))
{
if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o2),
equal_kind, depth + 1, ht)
|| !internal_equal (OVERLAY_END (o1), OVERLAY_END (o2),
equal_kind, depth + 1, ht))
return false;
o1 = XOVERLAY (o1)->plist;
o2 = XOVERLAY (o2)->plist;
depth++;
goto tail_recurse;
}
if (MARKERP (o1))
{
return (XMARKER (o1)->buffer == XMARKER (o2)->buffer
&& (XMARKER (o1)->buffer == 0
|| XMARKER (o1)->bytepos == XMARKER (o2)->bytepos));
}
/* Boolvectors are compared much like strings. */
if (BOOL_VECTOR_P (o1))
{
......@@ -4477,13 +4472,6 @@ sxhash (Lisp_Object obj, int depth)
hash = XUFIXNUM (obj);
break;
case Lisp_Misc:
if (XMISCTYPE (obj) == Lisp_Misc_Bignum)
{
hash = sxhash_bignum (XBIGNUM (obj));
break;
}
FALLTHROUGH;
case Lisp_Symbol:
hash = XHASH (obj);
break;
......@@ -4494,7 +4482,9 @@ sxhash (Lisp_Object obj, int depth)
/* This can be everything from a vector to an overlay. */
case Lisp_Vectorlike:
if (VECTORP (obj) || RECORDP (obj))
if (BIGNUMP (obj))
hash = sxhash_bignum (XBIGNUM (obj));
else if (VECTORP (obj) || RECORDP (obj))
/* According to the CL HyperSpec, two arrays are equal only if
they are `eq', except for strings and bit-vectors. In
Emacs, this works differently. We have to compare element
......
This diff is collapsed.
......@@ -1367,6 +1367,76 @@ print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag,
{
switch (PSEUDOVECTOR_TYPE (XVECTOR (obj)))
{
case PVEC_BIGNUM:
{
struct Lisp_Bignum *b = XBIGNUM (obj);
char *str = mpz_get_str (NULL, 10, b->value);
record_unwind_protect_ptr (xfree, str);
print_c_string (str, printcharfun);
}
break;
case PVEC_MARKER:
print_c_string ("#<marker ", printcharfun);
/* Do you think this is necessary? */
if (XMARKER (obj)->insertion_type != 0)
print_c_string ("(moves after insertion) ", printcharfun);
if (! XMARKER (obj)->buffer)
print_c_string ("in no buffer", printcharfun);
else
{
int len = sprintf (buf, "at %"pD"d in ", marker_position (obj));
strout (buf, len, len, printcharfun);
print_string (BVAR (XMARKER (obj)->buffer, name), printcharfun);
}
printchar ('>', printcharfun);
break;
case PVEC_OVERLAY:
print_c_string ("#<overlay ", printcharfun);
if (! XMARKER (OVERLAY_START (obj))->buffer)
print_c_string ("in no buffer", printcharfun);
else
{
int len = sprintf (buf, "from %"pD"d to %"pD"d in ",
marker_position (OVERLAY_START (obj)),
marker_position (OVERLAY_END (obj)));
strout (buf, len, len, printcharfun);
print_string (BVAR (XMARKER (OVERLAY_START (obj))->buffer, name),
printcharfun);
}
printchar ('>', printcharfun);
break;
#ifdef HAVE_MODULES
case PVEC_USER_PTR:
{
print_c_string ("#<user-ptr ", printcharfun);
int i = sprintf (buf, "ptr=%p finalizer=%p",
XUSER_PTR (obj)->p,
XUSER_PTR (obj)->finalizer);
strout (buf, i, i, printcharfun);
printchar ('>', printcharfun);
}
break;
#endif
case PVEC_FINALIZER:
print_c_string ("#<finalizer", printcharfun);
if (NILP (XFINALIZER (obj)->function))
print_c_string (" used", printcharfun);
printchar ('>', printcharfun);
break;
case PVEC_MISC_PTR:
{
/* This shouldn't happen in normal usage, but let's
print it anyway for the benefit of the debugger. */
int i = sprintf (buf, "#<ptr %p>", xmint_pointer (obj));
strout (buf, i, i, printcharfun);
}
break;
case PVEC_PROCESS:
if (escapeflag)
{
......@@ -2096,103 +2166,16 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
break;
case Lisp_Vectorlike:
if (! print_vectorlike (obj, printcharfun, escapeflag, buf))
goto badtype;
break;
case Lisp_Misc:
switch (XMISCTYPE (obj))
{
case Lisp_Misc_Marker:
print_c_string ("#<marker ", printcharfun);
/* Do you think this is necessary? */
if (XMARKER (obj)->insertion_type != 0)
print_c_string ("(moves after insertion) ", printcharfun);
if (! XMARKER (obj)->buffer)
print_c_string ("in no buffer", printcharfun);
else
{
int len = sprintf (buf, "at %"pD"d in ", marker_position (obj));
strout (buf, len, len, printcharfun);
print_string (BVAR (XMARKER (obj)->buffer, name), printcharfun);
}
printchar ('>', printcharfun);
break;
case Lisp_Misc_Overlay:
print_c_string ("#<overlay ", printcharfun);
if (! XMARKER (OVERLAY_START (obj))->buffer)
print_c_string ("in no buffer", printcharfun);
else
{
int len = sprintf (buf, "from %"pD"d to %"pD"d in ",
marker_position (OVERLAY_START (obj)),
marker_position (OVERLAY_END (obj)));
strout (buf, len, len, printcharfun);
print_string (BVAR (XMARKER (OVERLAY_START (obj))->buffer, name),
printcharfun);
}
printchar ('>', printcharfun);
break;
#ifdef HAVE_MODULES
case Lisp_Misc_User_Ptr:
{
print_c_string ("#<user-ptr ", printcharfun);
int i = sprintf (buf, "ptr=%p finalizer=%p",
XUSER_PTR (obj)->p,
XUSER_PTR (obj)->finalizer);
strout (buf, i, i, printcharfun);
printchar ('>', printcharfun);
break;
}
#endif
case Lisp_Misc_Finalizer:
print_c_string ("#<finalizer", printcharfun);
if (NILP (XFINALIZER (obj)->function))
print_c_string (" used", printcharfun);
printchar ('>', printcharfun);
break;
/* Remaining cases shouldn't happen in normal usage, but let's
print them anyway for the benefit of the debugger. */
case Lisp_Misc_Free:
print_c_string ("#<misc free cell>", printcharfun);
break;
case Lisp_Misc_Ptr:
{
int i = sprintf (buf, "#<ptr %p>", xmint_pointer (obj));
strout (buf, i, i, printcharfun);
}
break;
case Lisp_Misc_Bignum:
{
struct Lisp_Bignum *b = XBIGNUM (obj);
char *str = mpz_get_str (NULL, 10, b->value);
record_unwind_protect_ptr (xfree, str);
print_c_string (str, printcharfun);
}
break;
default:
goto badtype;
}
break;
if (print_vectorlike (obj, printcharfun, escapeflag, buf))
break;
FALLTHROUGH;
default:
badtype:
{
int len;
/* We're in trouble if this happens!
Probably should just emacs_abort (). */
print_c_string ("#<EMACS BUG: INVALID DATATYPE ", printcharfun);
if (MISCP (obj))
len = sprintf (buf, "(MISC 0x%04x)", (unsigned) XMISCTYPE (obj));
else if (VECTORLIKEP (obj))
if (VECTORLIKEP (obj))
len = sprintf (buf, "(PVEC 0x%08zx)", (size_t) ASIZE (obj));
else
len = sprintf (buf, "(0x%02x)", (unsigned) XTYPE (obj));
......
......@@ -126,15 +126,11 @@ record_insert (ptrdiff_t beg, ptrdiff_t length)
static void
record_marker_adjustments (ptrdiff_t from, ptrdiff_t to)
{
Lisp_Object marker;
register struct Lisp_Marker *m;
register ptrdiff_t charpos, adjustment;
prepare_record();
prepare_record ();
for (m = BUF_MARKERS (current_buffer); m; m = m->next)
for (struct Lisp_Marker *m = BUF_MARKERS (current_buffer); m; m = m->next)
{
charpos = m->charpos;
ptrdiff_t charpos = m->charpos;
eassert (charpos <= Z);
if (from <= charpos && charpos <= to)
......@@ -146,11 +142,11 @@ record_marker_adjustments (ptrdiff_t from, ptrdiff_t to)
insertion_type t markers will automatically move forward
upon re-inserting the deleted text, so we have to arrange
for them to move backward to the correct position. */
adjustment = (m->insertion_type ? to : from) - charpos;
ptrdiff_t adjustment = (m->insertion_type ? to : from) - charpos;
if (adjustment)
{
XSETMISC (marker, m);
Lisp_Object marker = make_lisp_ptr (m, Lisp_Vectorlike);
bset_undo_list
(current_buffer,
Fcons (Fcons (marker, make_fixnum (adjustment)),
......
......@@ -5819,11 +5819,7 @@ compare_overlay_entries (const void *e1, const void *e2)
static void
load_overlay_strings (struct it *it, ptrdiff_t charpos)
{
Lisp_Object overlay, window, str, invisible;
struct Lisp_Overlay *ov;
ptrdiff_t start, end;
ptrdiff_t n = 0, i, j;
int invis;
ptrdiff_t n = 0;
struct overlay_entry entriesbuf[20];
ptrdiff_t size = ARRAYELTS (entriesbuf);
struct overlay_entry *entries = entriesbuf;
......@@ -5859,12 +5855,13 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos)
while (false)
/* Process overlay before the overlay center. */
for (ov = current_buffer->overlays_before; ov; ov = ov->next)
for (struct Lisp_Overlay *ov = current_buffer->overlays_before;
ov; ov = ov->next)
{
XSETMISC (overlay, ov);
Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike);
eassert (OVERLAYP (overlay));
start = OVERLAY_POSITION (OVERLAY_START (overlay));
end = OVERLAY_POSITION (OVERLAY_END (overlay));
ptrdiff_t start = OVERLAY_POSITION (OVERLAY_START (overlay));
ptrdiff_t end = OVERLAY_POSITION (OVERLAY_END (overlay));
if (end < charpos)
break;
......@@ -5875,17 +5872,18 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos)
continue;
/* Skip this overlay if it doesn't apply to IT->w. */
window = Foverlay_get (overlay, Qwindow);
Lisp_Object window = Foverlay_get (overlay, Qwindow);
if (WINDOWP (window) && XWINDOW (window) != it->w)
continue;
/* If the text ``under'' the overlay is invisible, both before-
and after-strings from this overlay are visible; start and
end position are indistinguishable. */
invisible = Foverlay_get (overlay, Qinvisible);
invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
Lisp_Object invisible = Foverlay_get (overlay, Qinvisible);
int invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
/* If overlay has a non-empty before-string, record it. */
Lisp_Object str;
if ((start == charpos || (end == charpos && invis != 0))
&& (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
&& SCHARS (str))
......@@ -5899,12 +5897,13 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos)
}
/* Process overlays after the overlay center. */
for (ov = current_buffer->overlays_after; ov; ov = ov->next)
for (struct Lisp_Overlay *ov = current_buffer->overlays_after;
ov; ov = ov->next)
{
XSETMISC (overlay, ov);
Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike);
eassert (OVERLAYP (overlay));
start = OVERLAY_POSITION (OVERLAY_START (overlay));
end = OVERLAY_POSITION (OVERLAY_END (overlay));
ptrdiff_t start = OVERLAY_POSITION (OVERLAY_START (overlay));
ptrdiff_t end = OVERLAY_POSITION (OVERLAY_END (overlay));
if (start > charpos)
break;
......@@ -5915,16 +5914,17 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos)
continue;
/* Skip this overlay if it doesn't apply to IT->w. */
window = Foverlay_get (overlay, Qwindow);
Lisp_Object window = Foverlay_get (overlay, Qwindow);
if (WINDOWP (window) && XWINDOW (window) != it->w)
continue;
/* If the text ``under'' the overlay is invisible, it has a zero
dimension, and both before- and after-strings apply. */
invisible = Foverlay_get (overlay, Qinvisible);
invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
Lisp_Object invisible = Foverlay_get (overlay, Qinvisible);
int invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
/* If overlay has a non-empty before-string, record it. */
Lisp_Object str;
if ((start == charpos || (end == charpos && invis != 0))
&& (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
&& SCHARS (str))
......@@ -5950,12 +5950,11 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos)
/* IT->current.overlay_string_index is the number of overlay strings
that have already been consumed by IT. Copy some of the
remaining overlay strings to IT->overlay_strings. */
i = 0;
j = it->current.overlay_string_index;
while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
ptrdiff_t j = it->current.overlay_string_index;
for (ptrdiff_t i = 0; i < OVERLAY_STRING_CHUNK_SIZE && j < n; i++, j++)
{
it->overlay_strings[i] = entries[j].string;
it->string_overlays[i++] = entries[j++].overlay;
it->string_overlays[i] = entries[j].overlay;
}
CHECK_IT (it);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment