@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})
@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)
@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)}.
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.
+
\f
* Lisp Changes in Emacs 27.1
/* Number of live and free conses etc. */
-static EMACS_INT total_conses, total_markers, total_symbols, total_buffers;
-static EMACS_INT total_free_conses, total_free_markers, total_free_symbols;
+static EMACS_INT total_conses, total_symbols, total_buffers;
+static EMACS_INT total_free_conses, total_free_symbols;
static EMACS_INT total_free_floats, total_floats;
/* Points to memory space allocated as "spare", to be freed if we run
#endif /* MAX_SAVE_STACK > 0 */
+static void unchain_finalizer (struct Lisp_Finalizer *);
static void mark_terminals (void);
static void gc_sweep (void);
static Lisp_Object make_pure_vector (ptrdiff_t);
cleanup_vector (struct Lisp_Vector *vector)
{
detect_suspicious_free (vector);
- if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FONT))
+
+ if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_BIGNUM))
+ mpz_clear (PSEUDOVEC_STRUCT (vector, Lisp_Bignum)->value);
+ else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FINALIZER))
+ unchain_finalizer (PSEUDOVEC_STRUCT (vector, Lisp_Finalizer));
+ else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FONT))
{
if ((vector->header.size & PSEUDOVECTOR_SIZE_MASK) == FONT_OBJECT_MAX)
{
finalize_one_mutex (PSEUDOVEC_STRUCT (vector, Lisp_Mutex));
else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_CONDVAR))
finalize_one_condvar (PSEUDOVEC_STRUCT (vector, Lisp_CondVar));
+ else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_MARKER))
+ {
+ /* sweep_buffer should already have unchained this from its buffer. */
+ eassert (! PSEUDOVEC_STRUCT (vector, Lisp_Marker)->buffer);
+ }
+#ifdef HAVE_MODULES
+ else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_USER_PTR))
+ {
+ struct Lisp_User_Ptr *uptr = PSEUDOVEC_STRUCT (vector, Lisp_User_Ptr);
+ if (uptr->finalizer)
+ uptr->finalizer (uptr->p);
+ }
+#endif
}
/* Reclaim space used by unmarked vectors. */
\f
-/***********************************************************************
- Marker (Misc) Allocation
- ***********************************************************************/
-
-/* Like union Lisp_Misc, but padded so that its size is a multiple of
- the required alignment. */
-
-union aligned_Lisp_Misc
-{
- union Lisp_Misc m;
- unsigned char c[(sizeof (union Lisp_Misc) + LISP_ALIGNMENT - 1)
- & -LISP_ALIGNMENT];
-};
-
-/* Allocation of markers and other objects that share that structure.
- Works like allocation of conses. */
-
-#define MARKER_BLOCK_SIZE \
- ((1020 - sizeof (struct marker_block *)) / sizeof (union aligned_Lisp_Misc))
-
-struct marker_block
-{
- /* Place `markers' first, to preserve alignment. */
- union aligned_Lisp_Misc markers[MARKER_BLOCK_SIZE];
- struct marker_block *next;
-};
-
-static struct marker_block *marker_block;
-static int marker_block_index = MARKER_BLOCK_SIZE;
-
-static union Lisp_Misc *misc_free_list;
-
-/* Return a newly allocated Lisp_Misc object of specified TYPE. */
-
-static Lisp_Object
-allocate_misc (enum Lisp_Misc_Type type)
-{
- Lisp_Object val;
-
- MALLOC_BLOCK_INPUT;
-
- if (misc_free_list)
- {
- XSETMISC (val, misc_free_list);
- misc_free_list = misc_free_list->u_free.chain;
- }
- else
- {
- if (marker_block_index == MARKER_BLOCK_SIZE)
- {
- struct marker_block *new = lisp_malloc (sizeof *new, MEM_TYPE_MISC);
- new->next = marker_block;
- marker_block = new;
- marker_block_index = 0;
- total_free_markers += MARKER_BLOCK_SIZE;
- }
- XSETMISC (val, &marker_block->markers[marker_block_index].m);
- marker_block_index++;
- }
-
- MALLOC_UNBLOCK_INPUT;
-
- --total_free_markers;
- consing_since_gc += sizeof (union Lisp_Misc);
- misc_objects_consed++;
- XMISCANY (val)->type = type;
- XMISCANY (val)->gcmarkbit = 0;
- return val;
-}
-
Lisp_Object
make_misc_ptr (void *a)
{
- Lisp_Object val = allocate_misc (Lisp_Misc_Ptr);
- XUNTAG (val, Lisp_Misc, struct Lisp_Misc_Ptr)->pointer = a;
- return val;
+ struct Lisp_Misc_Ptr *p = ALLOCATE_PSEUDOVECTOR (struct Lisp_Misc_Ptr, pointer,
+ PVEC_MISC_PTR);
+ p->pointer = a;
+ return make_lisp_ptr (p, Lisp_Vectorlike);
}
-/* Return a Lisp_Misc_Overlay object with specified START, END and PLIST. */
+/* Return a new overlay with specified START, END and PLIST. */
Lisp_Object
build_overlay (Lisp_Object start, Lisp_Object end, Lisp_Object plist)
{
- register Lisp_Object overlay;
-
- overlay = allocate_misc (Lisp_Misc_Overlay);
+ struct Lisp_Overlay *p = ALLOCATE_PSEUDOVECTOR (struct Lisp_Overlay, next,
+ PVEC_OVERLAY);
+ Lisp_Object overlay = make_lisp_ptr (p, Lisp_Vectorlike);
OVERLAY_START (overlay) = start;
OVERLAY_END (overlay) = end;
set_overlay_plist (overlay, plist);
- XOVERLAY (overlay)->next = NULL;
+ p->next = NULL;
return overlay;
}
doc: /* Return a newly allocated marker which does not point at any place. */)
(void)
{
- register Lisp_Object val;
- register struct Lisp_Marker *p;
-
- val = allocate_misc (Lisp_Misc_Marker);
- p = XMARKER (val);
+ struct Lisp_Marker *p = ALLOCATE_PSEUDOVECTOR (struct Lisp_Marker, buffer,
+ PVEC_MARKER);
p->buffer = 0;
p->bytepos = 0;
p->charpos = 0;
p->next = NULL;
p->insertion_type = 0;
p->need_adjustment = 0;
- return val;
+ return make_lisp_ptr (p, Lisp_Vectorlike);
}
/* Return a newly allocated marker which points into BUF
Lisp_Object
build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos)
{
- Lisp_Object obj;
- struct Lisp_Marker *m;
-
/* No dead buffers here. */
eassert (BUFFER_LIVE_P (buf));
/* Every character is at least one byte. */
eassert (charpos <= bytepos);
- obj = allocate_misc (Lisp_Misc_Marker);
- m = XMARKER (obj);
+ struct Lisp_Marker *m = ALLOCATE_PSEUDOVECTOR (struct Lisp_Marker, buffer,
+ PVEC_MARKER);
m->buffer = buf;
m->charpos = charpos;
m->bytepos = bytepos;
m->need_adjustment = 0;
m->next = BUF_MARKERS (buf);
BUF_MARKERS (buf) = m;
- return obj;
+ return make_lisp_ptr (m, Lisp_Vectorlike);
}
\f
Lisp_Object
make_bignum_str (const char *num, int base)
{
- Lisp_Object obj;
- struct Lisp_Bignum *b;
- int check;
-
- obj = allocate_misc (Lisp_Misc_Bignum);
- b = XBIGNUM (obj);
+ struct Lisp_Bignum *b = ALLOCATE_PSEUDOVECTOR (struct Lisp_Bignum, value,
+ PVEC_BIGNUM);
mpz_init (b->value);
- check = mpz_set_str (b->value, num, base);
+ int check = mpz_set_str (b->value, num, base);
eassert (check == 0);
- return obj;
+ return make_lisp_ptr (b, Lisp_Vectorlike);
}
/* Given an mpz_t, make a number. This may return a bignum or a
Lisp_Object
make_number (mpz_t value)
{
- Lisp_Object obj;
- struct Lisp_Bignum *b;
-
if (mpz_fits_slong_p (value))
{
long l = mpz_get_si (value);
if (!FIXNUM_OVERFLOW_P (l))
- {
- XSETINT (obj, l);
- return obj;
- }
+ return make_fixnum (l);
}
/* Check if fixnum can be larger than long. */
v = -v;
if (!FIXNUM_OVERFLOW_P (v))
- {
- XSETINT (obj, v);
- return obj;
- }
+ return make_fixnum (v);
}
}
- obj = allocate_misc (Lisp_Misc_Bignum);
- b = XBIGNUM (obj);
+ struct Lisp_Bignum *b = ALLOCATE_PSEUDOVECTOR (struct Lisp_Bignum, value,
+ PVEC_BIGNUM);
/* We could mpz_init + mpz_swap here, to avoid a copy, but the
resulting API seemed possibly confusing. */
mpz_init_set (b->value, value);
- return obj;
+ return make_lisp_ptr (b, Lisp_Vectorlike);
}
void
Lisp_Object
make_user_ptr (void (*finalizer) (void *), void *p)
{
- Lisp_Object obj;
- struct Lisp_User_Ptr *uptr;
-
- obj = allocate_misc (Lisp_Misc_User_Ptr);
- uptr = XUSER_PTR (obj);
+ struct Lisp_User_Ptr *uptr = ALLOCATE_PSEUDOVECTOR (struct Lisp_User_Ptr,
+ finalizer, PVEC_USER_PTR);
uptr->finalizer = finalizer;
uptr->p = p;
- return obj;
+ return make_lisp_ptr (uptr, Lisp_Vectorlike);
}
#endif
finalizer != head;
finalizer = finalizer->next)
{
- finalizer->base.gcmarkbit = true;
+ VECTOR_MARK (finalizer);
mark_object (finalizer->function);
}
}
while (finalizer != src)
{
struct Lisp_Finalizer *next = finalizer->next;
- if (!finalizer->base.gcmarkbit && !NILP (finalizer->function))
+ if (!VECTOR_MARKED_P (finalizer) && !NILP (finalizer->function))
{
unchain_finalizer (finalizer);
finalizer_insert (dest, finalizer);
while (finalizers->next != finalizers)
{
finalizer = finalizers->next;
- eassert (finalizer->base.type == Lisp_Misc_Finalizer);
unchain_finalizer (finalizer);
function = finalizer->function;
if (!NILP (function))
FUNCTION. FUNCTION will be run once per finalizer object. */)
(Lisp_Object function)
{
- Lisp_Object val = allocate_misc (Lisp_Misc_Finalizer);
- struct Lisp_Finalizer *finalizer = XFINALIZER (val);
+ struct Lisp_Finalizer *finalizer
+ = ALLOCATE_PSEUDOVECTOR (struct Lisp_Finalizer, prev, PVEC_FINALIZER);
finalizer->function = function;
finalizer->prev = finalizer->next = NULL;
finalizer_insert (&finalizers, finalizer);
- return val;
+ return make_lisp_ptr (finalizer, Lisp_Vectorlike);
}
\f
return 0;
}
-
-/* If P is a pointer to a live Lisp Misc on the heap, return the object.
- Otherwise, return nil. M is a pointer to the mem_block for P. */
-
-static Lisp_Object
-live_misc_holding (struct mem_node *m, void *p)
-{
- if (m->type == MEM_TYPE_MISC)
- {
- struct marker_block *b = m->start;
- char *cp = p;
- ptrdiff_t offset = cp - (char *) &b->markers[0];
-
- /* P must point into a Lisp_Misc, not be
- one of the unused cells in the current misc block,
- and not be on the free-list. */
- if (0 <= offset && offset < MARKER_BLOCK_SIZE * sizeof b->markers[0]
- && (b != marker_block
- || offset / sizeof b->markers[0] < marker_block_index))
- {
- cp = ptr_bounds_copy (cp, b);
- union Lisp_Misc *s = p = cp -= offset % sizeof b->markers[0];
- if (s->u_any.type != Lisp_Misc_Free)
- return make_lisp_ptr (s, Lisp_Misc);
- }
- }
- return Qnil;
-}
-
-static bool
-live_misc_p (struct mem_node *m, void *p)
-{
- return !NILP (live_misc_holding (m, p));
-}
-
/* If P is a pointer to a live vector-like object, return the object.
Otherwise, return nil.
M is a pointer to the mem_block for P. */
|| EQ (obj, live_buffer_holding (m, po)));
break;
- case Lisp_Misc:
- mark_p = EQ (obj, live_misc_holding (m, po));
- break;
-
default:
break;
}
obj = live_string_holding (m, p);
break;
- case MEM_TYPE_MISC:
- obj = live_misc_holding (m, p);
- break;
-
case MEM_TYPE_SYMBOL:
obj = live_symbol_holding (m, p);
break;
case MEM_TYPE_STRING:
return live_string_p (m, p);
- case MEM_TYPE_MISC:
- return live_misc_p (m, p);
-
case MEM_TYPE_SYMBOL:
return live_symbol_p (m, p);
static Lisp_Object
make_pure_bignum (struct Lisp_Bignum *value)
{
- Lisp_Object new;
size_t i, nlimbs = mpz_size (value->value);
size_t nbytes = nlimbs * sizeof (mp_limb_t);
mp_limb_t *pure_limbs;
mp_size_t new_size;
- struct Lisp_Bignum *b = pure_alloc (sizeof (struct Lisp_Bignum), Lisp_Misc);
- b->type = Lisp_Misc_Bignum;
+ struct Lisp_Bignum *b = pure_alloc (sizeof *b, Lisp_Vectorlike);
+ XSETPVECTYPESIZE (b, PVEC_BIGNUM, 0, VECSIZE (struct Lisp_Bignum));
pure_limbs = pure_alloc (nbytes, -1);
for (i = 0; i < nlimbs; ++i)
mpz_roinit_n (b->value, pure_limbs, new_size);
- XSETMISC (new, b);
- return new;
+ return make_lisp_ptr (b, Lisp_Vectorlike);
}
/* Return a vector with room for LEN Lisp_Objects allocated from
size_t tot = 0;
tot += total_conses * sizeof (struct Lisp_Cons);
tot += total_symbols * sizeof (struct Lisp_Symbol);
- tot += total_markers * sizeof (union Lisp_Misc);
tot += total_string_bytes;
tot += total_vector_slots * word_size;
tot += total_floats * sizeof (struct Lisp_Float);
{
if (CONSP (XCAR (tail))
&& MARKERP (XCAR (XCAR (tail)))
- && !XMARKER (XCAR (XCAR (tail)))->gcmarkbit)
+ && !VECTOR_MARKED_P (XMARKER (XCAR (XCAR (tail)))))
*prev = XCDR (tail);
else
prev = xcdr_addr (tail);
list4 (Qsymbols, make_fixnum (sizeof (struct Lisp_Symbol)),
bounded_number (total_symbols),
bounded_number (total_free_symbols)),
- list4 (Qmiscs, make_fixnum (sizeof (union Lisp_Misc)),
- bounded_number (total_markers),
- bounded_number (total_free_markers)),
list4 (Qstrings, make_fixnum (sizeof (struct Lisp_String)),
bounded_number (total_strings),
bounded_number (total_free_strings)),
static void
mark_overlay (struct Lisp_Overlay *ptr)
{
- for (; ptr && !ptr->gcmarkbit; ptr = ptr->next)
+ for (; ptr && !VECTOR_MARKED_P (ptr); ptr = ptr->next)
{
- ptr->gcmarkbit = 1;
+ VECTOR_MARK (ptr);
/* These two are always markers and can be marked fast. */
- XMARKER (ptr->start)->gcmarkbit = 1;
- XMARKER (ptr->end)->gcmarkbit = 1;
+ VECTOR_MARK (XMARKER (ptr->start));
+ VECTOR_MARK (XMARKER (ptr->end));
mark_object (ptr->plist);
}
}
mark_char_table (ptr, (enum pvec_type) pvectype);
break;
+ case PVEC_MARKER:
+ /* DO NOT mark thru the marker's chain.
+ The buffer's markers chain does not preserve markers from gc;
+ instead, markers are removed from the chain when freed by gc. */
case PVEC_BOOL_VECTOR:
- /* No Lisp_Objects to mark in a bool vector. */
+ case PVEC_MISC_PTR:
+#ifdef HAVE_MODULES
+ case PVEC_USER_PTR:
+#endif
+ /* No Lisp_Objects to mark in these. */
+ VECTOR_MARK (ptr);
+ break;
+
+ case PVEC_OVERLAY:
+ mark_overlay (XOVERLAY (obj));
+ break;
+
+ case PVEC_FINALIZER:
VECTOR_MARK (ptr);
+ mark_object (XFINALIZER (obj)->function);
break;
case PVEC_SUBR:
}
break;
- case Lisp_Misc:
- CHECK_ALLOCATED_AND_LIVE (live_misc_p);
-
- if (XMISCANY (obj)->gcmarkbit)
- break;
-
- switch (XMISCTYPE (obj))
- {
- case Lisp_Misc_Marker:
- /* DO NOT mark thru the marker's chain.
- The buffer's markers chain does not preserve markers from gc;
- instead, markers are removed from the chain when freed by gc. */
- XMISCANY (obj)->gcmarkbit = 1;
- break;
-
- case Lisp_Misc_Ptr:
- case Lisp_Misc_Bignum:
- XMISCANY (obj)->gcmarkbit = true;
- break;
-
- case Lisp_Misc_Overlay:
- mark_overlay (XOVERLAY (obj));
- break;
-
- case Lisp_Misc_Finalizer:
- XMISCANY (obj)->gcmarkbit = true;
- mark_object (XFINALIZER (obj)->function);
- break;
-
-#ifdef HAVE_MODULES
- case Lisp_Misc_User_Ptr:
- XMISCANY (obj)->gcmarkbit = true;
- break;
-#endif
-
- default:
- emacs_abort ();
- }
- break;
-
case Lisp_Cons:
{
- register struct Lisp_Cons *ptr = XCONS (obj);
+ struct Lisp_Cons *ptr = XCONS (obj);
if (CONS_MARKED_P (ptr))
break;
CHECK_ALLOCATED_AND_LIVE (live_cons_p);
survives_p = XSYMBOL (obj)->u.s.gcmarkbit;
break;
- case Lisp_Misc:
- survives_p = XMISCANY (obj)->gcmarkbit;
- break;
-
case Lisp_String:
survives_p = STRING_MARKED_P (XSTRING (obj));
break;
total_free_symbols = num_free;
}
-NO_INLINE /* For better stack traces. */
-static void
-sweep_misc (void)
-{
- register struct marker_block *mblk;
- struct marker_block **mprev = &marker_block;
- register int lim = marker_block_index;
- EMACS_INT num_free = 0, num_used = 0;
-
- /* Put all unmarked misc's on free list. For a marker, first
- unchain it from the buffer it points into. */
-
- misc_free_list = 0;
-
- for (mblk = marker_block; mblk; mblk = *mprev)
- {
- register int i;
- int this_free = 0;
-
- for (i = 0; i < lim; i++)
- {
- if (!mblk->markers[i].m.u_any.gcmarkbit)
- {
- if (mblk->markers[i].m.u_any.type == Lisp_Misc_Marker)
- /* Make sure markers have been unchained from their buffer
- in sweep_buffer before we collect them. */
- eassert (!mblk->markers[i].m.u_marker.buffer);
- else if (mblk->markers[i].m.u_any.type == Lisp_Misc_Finalizer)
- unchain_finalizer (&mblk->markers[i].m.u_finalizer);
-#ifdef HAVE_MODULES
- else if (mblk->markers[i].m.u_any.type == Lisp_Misc_User_Ptr)
- {
- struct Lisp_User_Ptr *uptr = &mblk->markers[i].m.u_user_ptr;
- if (uptr->finalizer)
- uptr->finalizer (uptr->p);
- }
-#endif
- else if (mblk->markers[i].m.u_any.type == Lisp_Misc_Bignum)
- mpz_clear (mblk->markers[i].m.u_bignum.value);
- /* Set the type of the freed object to Lisp_Misc_Free.
- We could leave the type alone, since nobody checks it,
- but this might catch bugs faster. */
- mblk->markers[i].m.u_marker.type = Lisp_Misc_Free;
- mblk->markers[i].m.u_free.chain = misc_free_list;
- misc_free_list = &mblk->markers[i].m;
- this_free++;
- }
- else
- {
- num_used++;
- mblk->markers[i].m.u_any.gcmarkbit = 0;
- }
- }
- lim = MARKER_BLOCK_SIZE;
- /* If this block contains only free markers and we have already
- seen more than two blocks worth of free markers then deallocate
- this block. */
- if (this_free == MARKER_BLOCK_SIZE && num_free > MARKER_BLOCK_SIZE)
- {
- *mprev = mblk->next;
- /* Unhook from the free list. */
- misc_free_list = mblk->markers[0].m.u_free.chain;
- lisp_free (mblk);
- }
- else
- {
- num_free += this_free;
- mprev = &mblk->next;
- }
- }
-
- total_markers = num_used;
- total_free_markers = num_free;
-}
-
/* Remove BUFFER's markers that are due to be swept. This is needed since
we treat BUF_MARKERS and markers's `next' field as weak pointers. */
static void
struct Lisp_Marker *this, **prev = &BUF_MARKERS (buffer);
while ((this = *prev))
- if (this->gcmarkbit)
+ if (VECTOR_MARKED_P (this))
prev = &this->next;
else
{
sweep_intervals ();
sweep_symbols ();
sweep_buffers ();
- sweep_misc ();
sweep_vectors ();
check_string_bytes (!noninteractive);
}
DEFSYM (Qconses, "conses");
DEFSYM (Qsymbols, "symbols");
- DEFSYM (Qmiscs, "miscs");
DEFSYM (Qstrings, "strings");
DEFSYM (Qvectors, "vectors");
DEFSYM (Qfloats, "floats");
ptrdiff_t *len_ptr,
ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr, bool change_req)
{
- Lisp_Object overlay, start, end;
- struct Lisp_Overlay *tail;
ptrdiff_t idx = 0;
ptrdiff_t len = *len_ptr;
Lisp_Object *vec = *vec_ptr;
ptrdiff_t prev = BEGV;
bool inhibit_storing = 0;
- for (tail = current_buffer->overlays_before; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
+ tail; tail = tail->next)
{
- ptrdiff_t startpos, endpos;
-
- XSETMISC (overlay, tail);
-
- start = OVERLAY_START (overlay);
- end = OVERLAY_END (overlay);
- endpos = OVERLAY_POSITION (end);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
+ Lisp_Object start = OVERLAY_START (overlay);
+ Lisp_Object end = OVERLAY_END (overlay);
+ ptrdiff_t endpos = OVERLAY_POSITION (end);
if (endpos < pos)
{
if (prev < endpos)
prev = endpos;
break;
}
- startpos = OVERLAY_POSITION (start);
+ ptrdiff_t startpos = OVERLAY_POSITION (start);
/* This one ends at or after POS
so its start counts for PREV_PTR if it's before POS. */
if (prev < startpos && startpos < pos)
next = startpos;
}
- for (tail = current_buffer->overlays_after; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
+ tail; tail = tail->next)
{
- ptrdiff_t startpos, endpos;
-
- XSETMISC (overlay, tail);
-
- start = OVERLAY_START (overlay);
- end = OVERLAY_END (overlay);
- startpos = OVERLAY_POSITION (start);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
+ Lisp_Object start = OVERLAY_START (overlay);
+ Lisp_Object end = OVERLAY_END (overlay);
+ ptrdiff_t startpos = OVERLAY_POSITION (start);
if (pos < startpos)
{
if (startpos < next)
next = startpos;
break;
}
- endpos = OVERLAY_POSITION (end);
+ ptrdiff_t endpos = OVERLAY_POSITION (end);
if (pos < endpos)
{
if (idx == len)
Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr)
{
- Lisp_Object overlay, ostart, oend;
- struct Lisp_Overlay *tail;
ptrdiff_t idx = 0;
ptrdiff_t len = *len_ptr;
Lisp_Object *vec = *vec_ptr;
bool inhibit_storing = 0;
bool end_is_Z = end == Z;
- for (tail = current_buffer->overlays_before; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
+ tail; tail = tail->next)
{
- ptrdiff_t startpos, endpos;
-
- XSETMISC (overlay, tail);
-
- ostart = OVERLAY_START (overlay);
- oend = OVERLAY_END (overlay);
- endpos = OVERLAY_POSITION (oend);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
+ Lisp_Object ostart = OVERLAY_START (overlay);
+ Lisp_Object oend = OVERLAY_END (overlay);
+ ptrdiff_t endpos = OVERLAY_POSITION (oend);
if (endpos < beg)
{
if (prev < endpos)
prev = endpos;
break;
}
- startpos = OVERLAY_POSITION (ostart);
+ ptrdiff_t startpos = OVERLAY_POSITION (ostart);
/* Count an interval if it overlaps the range, is empty at the
start of the range, or is empty at END provided END denotes the
end of the buffer. */
next = startpos;
}
- for (tail = current_buffer->overlays_after; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
+ tail; tail = tail->next)
{
- ptrdiff_t startpos, endpos;
-
- XSETMISC (overlay, tail);
-
- ostart = OVERLAY_START (overlay);
- oend = OVERLAY_END (overlay);
- startpos = OVERLAY_POSITION (ostart);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
+ Lisp_Object ostart = OVERLAY_START (overlay);
+ Lisp_Object oend = OVERLAY_END (overlay);
+ ptrdiff_t startpos = OVERLAY_POSITION (ostart);
if (end < startpos)
{
if (startpos < next)
next = startpos;
break;
}
- endpos = OVERLAY_POSITION (oend);
+ ptrdiff_t endpos = OVERLAY_POSITION (oend);
/* Count an interval if it overlaps the range, is empty at the
start of the range, or is empty at END provided END denotes the
end of the buffer. */
bool
overlay_touches_p (ptrdiff_t pos)
{
- Lisp_Object overlay;
- struct Lisp_Overlay *tail;
-
- for (tail = current_buffer->overlays_before; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
+ tail; tail = tail->next)
{
- ptrdiff_t endpos;
-
- XSETMISC (overlay ,tail);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
eassert (OVERLAYP (overlay));
- endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+ ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
if (endpos < pos)
break;
if (endpos == pos || OVERLAY_POSITION (OVERLAY_START (overlay)) == pos)
return 1;
}
- for (tail = current_buffer->overlays_after; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
+ tail; tail = tail->next)
{
- ptrdiff_t startpos;
-
- XSETMISC (overlay, tail);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
eassert (OVERLAYP (overlay));
- startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
+ ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
if (pos < startpos)
break;
if (startpos == pos || OVERLAY_POSITION (OVERLAY_END (overlay)) == pos)
ptrdiff_t
overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
{
- Lisp_Object overlay, window, str;
- struct Lisp_Overlay *ov;
- ptrdiff_t startpos, endpos;
bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
overlay_heads.used = overlay_heads.bytes = 0;
overlay_tails.used = overlay_tails.bytes = 0;
- 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));
- startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
- endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+ ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
+ ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
if (endpos < pos)
break;
if (endpos != pos && startpos != pos)
continue;
- window = Foverlay_get (overlay, Qwindow);
+ Lisp_Object window = Foverlay_get (overlay, Qwindow);
if (WINDOWP (window) && XWINDOW (window) != w)
continue;
+ Lisp_Object str;
if (startpos == pos
&& (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
record_overlay_string (&overlay_heads, str,
Foverlay_get (overlay, Qpriority),
endpos - startpos);
}
- 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));
- startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
- endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+ ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
+ ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
if (startpos > pos)
break;
if (endpos != pos && startpos != pos)
continue;
- window = Foverlay_get (overlay, Qwindow);
+ Lisp_Object window = Foverlay_get (overlay, Qwindow);
if (WINDOWP (window) && XWINDOW (window) != w)
continue;
+ Lisp_Object str;
if (startpos == pos
&& (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
record_overlay_string (&overlay_heads, str,
void
recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos)
{
- Lisp_Object overlay, beg, end;
- struct Lisp_Overlay *prev, *tail, *next;
+ struct Lisp_Overlay *prev, *next;
/* See if anything in overlays_before should move to overlays_after. */
But we use it for symmetry and in case that should cease to be true
with some future change. */
prev = NULL;
- for (tail = buf->overlays_before; tail; prev = tail, tail = next)
+ for (struct Lisp_Overlay *tail = buf->overlays_before;
+ tail; prev = tail, tail = next)
{
next = tail->next;
- XSETMISC (overlay, tail);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
eassert (OVERLAYP (overlay));
- beg = OVERLAY_START (overlay);
- end = OVERLAY_END (overlay);
+ Lisp_Object beg = OVERLAY_START (overlay);
+ Lisp_Object end = OVERLAY_END (overlay);
if (OVERLAY_POSITION (end) > pos)
{
for (other = buf->overlays_after; other;
other_prev = other, other = other->next)
{
- Lisp_Object otherbeg, otheroverlay;
-
- XSETMISC (otheroverlay, other);
+ Lisp_Object otheroverlay = make_lisp_ptr (other, Lisp_Vectorlike);
eassert (OVERLAYP (otheroverlay));
- otherbeg = OVERLAY_START (otheroverlay);
+ Lisp_Object otherbeg = OVERLAY_START (otheroverlay);
if (OVERLAY_POSITION (otherbeg) >= where)
break;
}
/* See if anything in overlays_after should be in overlays_before. */
prev = NULL;
- for (tail = buf->overlays_after; tail; prev = tail, tail = next)
+ for (struct Lisp_Overlay *tail = buf->overlays_after;
+ tail; prev = tail, tail = next)
{
next = tail->next;
- XSETMISC (overlay, tail);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
eassert (OVERLAYP (overlay));
- beg = OVERLAY_START (overlay);
- end = OVERLAY_END (overlay);
+ Lisp_Object beg = OVERLAY_START (overlay);
+ Lisp_Object end = OVERLAY_END (overlay);
/* Stop looking, when we know that nothing further
can possibly end before POS. */
for (other = buf->overlays_before; other;
other_prev = other, other = other->next)
{
- Lisp_Object otherend, otheroverlay;
-
- XSETMISC (otheroverlay, other);
+ Lisp_Object otheroverlay = make_lisp_ptr (other, Lisp_Vectorlike);
eassert (OVERLAYP (otheroverlay));
- otherend = OVERLAY_END (otheroverlay);
+ Lisp_Object otherend = OVERLAY_END (otheroverlay);
if (OVERLAY_POSITION (otherend) <= where)
break;
}
void
fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
{
- Lisp_Object overlay;
struct Lisp_Overlay *before_list UNINIT;
struct Lisp_Overlay *after_list UNINIT;
/* These are either nil, indicating that before_list or after_list
/* 'Parent', likewise, indicates a cons cell or
current_buffer->overlays_before or overlays_after, depending
which loop we're in. */
- struct Lisp_Overlay *tail, *parent;
- ptrdiff_t startpos, endpos;
+ struct Lisp_Overlay *parent;
/* This algorithm shifts links around instead of consing and GCing.
The loop invariant is that before_list (resp. after_list) is a
(after_list) if it is, is still uninitialized. So it's not a bug
that before_list isn't initialized, although it may look
strange. */
- for (parent = NULL, tail = current_buffer->overlays_before; tail;)
+ parent = NULL;
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
+ tail; tail = tail->next)
{
- XSETMISC (overlay, tail);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
- endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
- startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
+ ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+ ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
/* If the overlay is backwards, make it empty. */
if (endpos < startpos)
set_buffer_overlays_before (current_buffer, tail->next);
else
parent->next = tail->next;
- tail = tail->next;
}
else
- parent = tail, tail = parent->next;
+ parent = tail;
}
- for (parent = NULL, tail = current_buffer->overlays_after; tail;)
+ parent = NULL;
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
+ tail; tail = tail->next)
{
- XSETMISC (overlay, tail);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
- startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
- endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+ ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
+ ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
/* If the overlay is backwards, make it empty. */
if (endpos < startpos)
set_buffer_overlays_after (current_buffer, tail->next);
else
parent->next = tail->next;
- tail = tail->next;
}
else
- parent = tail, tail = parent->next;
+ parent = tail;
}
/* Splice the constructed (wrong) lists into the buffer's lists,
overlay whose ending marker is after-insertion-marker if disorder
exists). */
while (tail
- && (XSETMISC (tem, tail),
+ && (tem = make_lisp_ptr (tail, Lisp_Vectorlike),
(end = OVERLAY_POSITION (OVERLAY_END (tem))) >= pos))
{
parent = tail;
overlays are in correct order. */
while (tail)
{
- XSETMISC (tem, tail);
+ tem = make_lisp_ptr (tail, Lisp_Vectorlike);
end = OVERLAY_POSITION (OVERLAY_END (tem));
if (end == pos)
However, the overlays you get are the real objects that the buffer uses. */)
(void)
{
- struct Lisp_Overlay *ol;
- Lisp_Object before = Qnil, after = Qnil, tmp;
+ Lisp_Object before = Qnil, after = Qnil;
- for (ol = current_buffer->overlays_before; ol; ol = ol->next)
- {
- XSETMISC (tmp, ol);
- before = Fcons (tmp, before);
- }
- for (ol = current_buffer->overlays_after; ol; ol = ol->next)
- {
- XSETMISC (tmp, ol);
- after = Fcons (tmp, after);
- }
+ for (struct Lisp_Overlay *ol = current_buffer->overlays_before;
+ ol; ol = ol->next)
+ before = Fcons (make_lisp_ptr (ol, Lisp_Vectorlike), before);
+ for (struct Lisp_Overlay *ol = current_buffer->overlays_after;
+ ol; ol = ol->next)
+ after = Fcons (make_lisp_ptr (ol, Lisp_Vectorlike), after);
return Fcons (Fnreverse (before), Fnreverse (after));
}
report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3)
{
- Lisp_Object prop, overlay;
- struct Lisp_Overlay *tail;
/* True if this change is an insertion. */
bool insertion = (after ? XFIXNAT (arg3) == 0 : EQ (start, end));
- overlay = Qnil;
- tail = NULL;
-
/* We used to run the functions as soon as we found them and only register
them in last_overlay_modification_hooks for the purpose of the `after'
case. But running elisp code as we traverse the list of overlays is
/* We are being called before a change.
Scan the overlays to find the functions to call. */
last_overlay_modification_hooks_used = 0;
- for (tail = current_buffer->overlays_before; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
+ tail; tail = tail->next)
{
ptrdiff_t startpos, endpos;
Lisp_Object ostart, oend;
- XSETMISC (overlay, tail);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
ostart = OVERLAY_START (overlay);
oend = OVERLAY_END (overlay);
if (insertion && (XFIXNAT (start) == startpos
|| XFIXNAT (end) == startpos))
{
- prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
+ Lisp_Object prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
if (!NILP (prop))
add_overlay_mod_hooklist (prop, overlay);
}
if (insertion && (XFIXNAT (start) == endpos
|| XFIXNAT (end) == endpos))
{
- prop = Foverlay_get (overlay, Qinsert_behind_hooks);
+ Lisp_Object prop = Foverlay_get (overlay, Qinsert_behind_hooks);
if (!NILP (prop))
add_overlay_mod_hooklist (prop, overlay);
}
for both insertion and deletion. */
if (XFIXNAT (end) > startpos && XFIXNAT (start) < endpos)
{
- prop = Foverlay_get (overlay, Qmodification_hooks);
+ Lisp_Object prop = Foverlay_get (overlay, Qmodification_hooks);
if (!NILP (prop))
add_overlay_mod_hooklist (prop, overlay);
}
}
- for (tail = current_buffer->overlays_after; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
+ tail; tail = tail->next)
{
ptrdiff_t startpos, endpos;
Lisp_Object ostart, oend;
- XSETMISC (overlay, tail);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
ostart = OVERLAY_START (overlay);
oend = OVERLAY_END (overlay);
if (insertion && (XFIXNAT (start) == startpos
|| XFIXNAT (end) == startpos))
{
- prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
+ Lisp_Object prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
if (!NILP (prop))
add_overlay_mod_hooklist (prop, overlay);
}
if (insertion && (XFIXNAT (start) == endpos
|| XFIXNAT (end) == endpos))
{
- prop = Foverlay_get (overlay, Qinsert_behind_hooks);
+ Lisp_Object prop = Foverlay_get (overlay, Qinsert_behind_hooks);
if (!NILP (prop))
add_overlay_mod_hooklist (prop, overlay);
}
for both insertion and deletion. */
if (XFIXNAT (end) > startpos && XFIXNAT (start) < endpos)
{
- prop = Foverlay_get (overlay, Qmodification_hooks);
+ Lisp_Object prop = Foverlay_get (overlay, Qmodification_hooks);
if (!NILP (prop))
add_overlay_mod_hooklist (prop, overlay);
}
void
evaporate_overlays (ptrdiff_t pos)
{
- Lisp_Object overlay, hit_list;
- struct Lisp_Overlay *tail;
-
- hit_list = Qnil;
+ Lisp_Object hit_list = Qnil;
if (pos <= current_buffer->overlay_center)
- for (tail = current_buffer->overlays_before; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
+ tail; tail = tail->next)
{
- ptrdiff_t endpos;
- XSETMISC (overlay, tail);
- endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
+ ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
if (endpos < pos)
break;
if (endpos == pos && OVERLAY_POSITION (OVERLAY_START (overlay)) == pos
hit_list = Fcons (overlay, hit_list);
}
else
- for (tail = current_buffer->overlays_after; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
+ tail; tail = tail->next)
{
- ptrdiff_t startpos;
- XSETMISC (overlay, tail);
- startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
+ ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
if (startpos > pos)
break;
if (startpos == pos && OVERLAY_POSITION (OVERLAY_END (overlay)) == pos
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;
case PVEC_MODULE_FUNCTION:
return Qmodule_function;
/* "Impossible" cases. */
+ case PVEC_MISC_PTR:
case PVEC_XWIDGET:
case PVEC_OTHER:
case PVEC_XWIDGET_VIEW:
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)
}
}
- 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)
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;
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;
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))
{
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;
/* 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
#define lisp_h_EQ(x, y) (XLI (x) == XLI (y))
#define lisp_h_FLOATP(x) (XTYPE (x) == Lisp_Float)
#define lisp_h_FIXNUMP(x) ((XTYPE (x) & (Lisp_Int0 | ~Lisp_Int1)) == Lisp_Int0)
-#define lisp_h_MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker)
-#define lisp_h_MISCP(x) (XTYPE (x) == Lisp_Misc)
#define lisp_h_NILP(x) EQ (x, Qnil)
#define lisp_h_SET_SYMBOL_VAL(sym, v) \
(eassert ((sym)->u.s.redirect == SYMBOL_PLAINVAL), \
# define EQ(x, y) lisp_h_EQ (x, y)
# define FLOATP(x) lisp_h_FLOATP (x)
# define FIXNUMP(x) lisp_h_FIXNUMP (x)
-# define MARKERP(x) lisp_h_MARKERP (x)
-# define MISCP(x) lisp_h_MISCP (x)
# define NILP(x) lisp_h_NILP (x)
# define SET_SYMBOL_VAL(sym, v) lisp_h_SET_SYMBOL_VAL (sym, v)
# define SYMBOL_CONSTANT_P(sym) lisp_h_SYMBOL_CONSTANT_P (sym)
/* Symbol. XSYMBOL (object) points to a struct Lisp_Symbol. */
Lisp_Symbol = 0,
- /* Miscellaneous. XMISC (object) points to a union Lisp_Misc,
- whose first member indicates the subtype. */
- Lisp_Misc = 1,
+ /* Type 1 is currently unused. */
- /* Integer. XFIXNUM (obj) is the integer value. */
+ /* Fixnum. XFIXNUM (obj) is the integer value. */
Lisp_Int0 = 2,
Lisp_Int1 = USE_LSB_TAG ? 6 : 3,
Lisp_Float = 7
};
-/* This is the set of data types that share a common structure.
- The first member of the structure is a type code from this set.
- The enum values are arbitrary, but we'll use large numbers to make it
- more likely that we'll spot the error if a random word in memory is
- mistakenly interpreted as a Lisp_Misc. */
-enum Lisp_Misc_Type
- {
- Lisp_Misc_Free = 0x5eab,
- Lisp_Misc_Marker,
- Lisp_Misc_Overlay,
- Lisp_Misc_Finalizer,
- Lisp_Misc_Ptr,
-#ifdef HAVE_MODULES
- Lisp_Misc_User_Ptr,
-#endif
- Lisp_Misc_Bignum,
- /* This is not a type code. It is for range checking. */
- Lisp_Misc_Limit
- };
-
/* These are the types of forwarding objects used in the value slot
of symbols for special built-in variables whose value is stored in
C variables. */
};
/* If you want to define a new Lisp data type, here are some
- instructions. See the thread at
- https://lists.gnu.org/r/emacs-devel/2012-10/msg00561.html
- for more info.
+ instructions.
First, there are already a couple of Lisp types that can be used if
your new type does not need to be exposed to Lisp programs nor
- displayed to users. These are Lisp_Misc_Ptr, a Lisp_Misc
- subtype; and PVEC_OTHER, a kind of vectorlike object. The former
+ displayed to users. These are Lisp_Misc_Ptr and PVEC_OTHER,
+ which are both vectorlike objects. The former
is suitable for stashing a pointer in a Lisp object; the pointer
might be to some low-level C object that contains auxiliary
information. The latter is useful for vector-like Lisp objects
These two types don't look pretty when printed, so they are
unsuitable for Lisp objects that can be exposed to users.
- To define a new data type, add one more Lisp_Misc subtype or one
- more pseudovector subtype. Pseudovectors are more suitable for
- objects with several slots that need to support fast random access,
- while Lisp_Misc types are for everything else. A pseudovector object
- provides one or more slots for Lisp objects, followed by struct
- members that are accessible only from C. A Lisp_Misc object is a
- wrapper for a C struct that can contain anything you like.
+ To define a new data type, add a pseudovector subtype by extending
+ the pvec_type enumeration. A pseudovector provides one or more
+ slots for Lisp objects, followed by struct members that are
+ accessible only from C.
There is no way to explicitly free a Lisp Object; only the garbage
collector frees them.
- To add a new pseudovector type, extend the pvec_type enumeration;
- to add a new Lisp_Misc, extend the Lisp_Misc_Type enumeration.
-
- For a Lisp_Misc, you will also need to add your entry to union
- Lisp_Misc, but make sure the first word has the same structure as
- the others, starting with a 16-bit member of the Lisp_Misc_Type
- enumeration and a 1-bit GC markbit. Also make sure the overall
- size of the union is not increased by your addition. The latter
- requirement is to keep Lisp_Misc objects small enough, so they
- are handled faster: since all Lisp_Misc types use the same space,
- enlarging any of them will affect all the rest. If you really
- need a larger object, it is best to use Lisp_Vectorlike instead.
-
For a new pseudovector, it's highly desirable to limit the size
of your data type by VBLOCK_BYTES_MAX bytes (defined in alloc.c).
Otherwise you will need to change sweep_vectors (also in alloc.c).
{
PVEC_NORMAL_VECTOR,
PVEC_FREE,
+ PVEC_BIGNUM,
+ PVEC_MARKER,
+ PVEC_OVERLAY,
+ PVEC_FINALIZER,
+ PVEC_MISC_PTR,
+#ifdef HAVE_MODULES
+ PVEC_USER_PTR,
+#endif
PVEC_PROCESS,
PVEC_FRAME,
PVEC_WINDOW,
#define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String))
#define XSETSYMBOL(a, b) ((a) = make_lisp_symbol (b))
#define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float))
-#define XSETMISC(a, b) ((a) = make_lisp_ptr (b, Lisp_Misc))
/* Pseudovector types. */
return (x ^ x >> (EMACS_INT_WIDTH - FIXNUM_BITS)) & INTMASK;
}
-/* These structures are used for various misc types. */
-
-struct Lisp_Misc_Any /* Supertype of all Misc types. */
-{
- ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_??? */
- bool_bf gcmarkbit : 1;
- unsigned spacer : 15;
-};
-
-INLINE bool
-(MISCP) (Lisp_Object x)
-{
- return lisp_h_MISCP (x);
-}
-
-INLINE struct Lisp_Misc_Any *
-XMISCANY (Lisp_Object a)
-{
- eassert (MISCP (a));
- return XUNTAG (a, Lisp_Misc, struct Lisp_Misc_Any);
-}
-
-INLINE enum Lisp_Misc_Type
-XMISCTYPE (Lisp_Object a)
-{
- return XMISCANY (a)->type;
-}
-
struct Lisp_Marker
{
- ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Marker */
- bool_bf gcmarkbit : 1;
- unsigned spacer : 13;
- /* This flag is temporarily used in the functions
- decode/encode_coding_object to record that the marker position
- must be adjusted after the conversion. */
- bool_bf need_adjustment : 1;
- /* True means normal insertion at the marker's position
- leaves the marker after the inserted text. */
- bool_bf insertion_type : 1;
+ union vectorlike_header header;
+
/* This is the buffer that the marker points into, or 0 if it points nowhere.
Note: a chain of markers can contain markers pointing into different
buffers (the chain is per buffer_text rather than per buffer, so it's
*/
struct buffer *buffer;
+ /* This flag is temporarily used in the functions
+ decode/encode_coding_object to record that the marker position
+ must be adjusted after the conversion. */
+ bool_bf need_adjustment : 1;
+ /* True means normal insertion at the marker's position
+ leaves the marker after the inserted text. */
+ bool_bf insertion_type : 1;
+
/* The remaining fields are meaningless in a marker that
does not point anywhere. */
I.e. 9words plus 2 bits, 3words of which are for external linked lists.
*/
{
- ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Overlay */
- bool_bf gcmarkbit : 1;
- unsigned spacer : 15;
- struct Lisp_Overlay *next;
+ union vectorlike_header header;
Lisp_Object start;
Lisp_Object end;
Lisp_Object plist;
+ struct Lisp_Overlay *next;
};
struct Lisp_Misc_Ptr
{
- ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Ptr */
- bool_bf gcmarkbit : 1;
- unsigned spacer : 15;
+ union vectorlike_header header;
void *pointer;
};
C code, it should not be given a mint_ptr generated from Lisp code
as that would allow Lisp code to coin pointers from integers and
could lead to crashes. To package a C pointer into a Lisp-visible
- object you can put the pointer into a Lisp_Misc object instead; see
+ object you can put the pointer into a pseudovector instead; see
Lisp_User_Ptr for an example. */
INLINE Lisp_Object
INLINE bool
mint_ptrp (Lisp_Object x)
{
- return FIXNUMP (x) || (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Ptr);
+ return FIXNUMP (x) || PSEUDOVECTORP (x, PVEC_MISC_PTR);
}
INLINE void *
eassert (mint_ptrp (a));
if (FIXNUMP (a))
return XFIXNUMPTR (a);
- return XUNTAG (a, Lisp_Misc, struct Lisp_Misc_Ptr)->pointer;
+ return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Misc_Ptr)->pointer;
}
#ifdef HAVE_MODULES
struct Lisp_User_Ptr
{
- ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_User_Ptr */
- bool_bf gcmarkbit : 1;
- unsigned spacer : 15;
-
+ union vectorlike_header header;
void (*finalizer) (void *);
void *p;
};
/* A finalizer sentinel. */
struct Lisp_Finalizer
{
- struct Lisp_Misc_Any base;
-
- /* Circular list of all active weak references. */
- struct Lisp_Finalizer *prev;
- struct Lisp_Finalizer *next;
+ union vectorlike_header header;
/* Call FUNCTION when the finalizer becomes unreachable, even if
FUNCTION contains a reference to the finalizer; i.e., call
FUNCTION when it is reachable _only_ through finalizers. */
Lisp_Object function;
+
+ /* Circular list of all active weak references. */
+ struct Lisp_Finalizer *prev;
+ struct Lisp_Finalizer *next;
};
INLINE bool
FINALIZERP (Lisp_Object x)
{
- return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Finalizer;
+ return PSEUDOVECTORP (x, PVEC_FINALIZER);
}
INLINE struct Lisp_Finalizer *
XFINALIZER (Lisp_Object a)
{
eassert (FINALIZERP (a));
- return XUNTAG (a, Lisp_Misc, struct Lisp_Finalizer);
-}
-
-/* A miscellaneous object, when it's on the free list. */
-struct Lisp_Free
- {
- ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Free */
- bool_bf gcmarkbit : 1;
- unsigned spacer : 15;
- union Lisp_Misc *chain;
- };
-
-struct Lisp_Bignum
- {
- ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Bignum */
- bool_bf gcmarkbit : 1;
- unsigned spacer : 15;
- mpz_t value;
- };
-
-/* To get the type field of a union Lisp_Misc, use XMISCTYPE.
- It uses one of these struct subtypes to get the type field. */
-
-union Lisp_Misc
- {
- struct Lisp_Misc_Any u_any; /* Supertype of all Misc types. */
- struct Lisp_Free u_free;
- struct Lisp_Marker u_marker;
- struct Lisp_Overlay u_overlay;
- struct Lisp_Finalizer u_finalizer;
- struct Lisp_Misc_Ptr u_misc_ptr;
-#ifdef HAVE_MODULES
- struct Lisp_User_Ptr u_user_ptr;
-#endif
- struct Lisp_Bignum u_bignum;
- };
-
-INLINE union Lisp_Misc *
-XMISC (Lisp_Object a)
-{
- return XUNTAG (a, Lisp_Misc, union Lisp_Misc);
+ return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Finalizer);
}
INLINE bool
-(MARKERP) (Lisp_Object x)
+MARKERP (Lisp_Object x)
{
- return lisp_h_MARKERP (x);
+ return PSEUDOVECTORP (x, PVEC_MARKER);
}
INLINE struct Lisp_Marker *
XMARKER (Lisp_Object a)
{
eassert (MARKERP (a));
- return XUNTAG (a, Lisp_Misc, struct Lisp_Marker);
+ return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Marker);
}
INLINE bool
OVERLAYP (Lisp_Object x)
{
- return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay;
+ return PSEUDOVECTORP (x, PVEC_OVERLAY);
}
INLINE struct Lisp_Overlay *
XOVERLAY (Lisp_Object a)
{
eassert (OVERLAYP (a));
- return XUNTAG (a, Lisp_Misc, struct Lisp_Overlay);
+ return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Overlay);
}
#ifdef HAVE_MODULES
INLINE bool
USER_PTRP (Lisp_Object x)
{
- return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_User_Ptr;
+ return PSEUDOVECTORP (x, PVEC_USER_PTR);
}
INLINE struct Lisp_User_Ptr *
XUSER_PTR (Lisp_Object a)
{
eassert (USER_PTRP (a));
- return XUNTAG (a, Lisp_Misc, struct Lisp_User_Ptr);
+ return XUNTAG (a, Lisp_Vectorlike, struct Lisp_User_Ptr);
}
#endif
+struct Lisp_Bignum
+{
+ union vectorlike_header header;
+ mpz_t value;
+};
+
INLINE bool
BIGNUMP (Lisp_Object x)
{
- return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Bignum;
+ return PSEUDOVECTORP (x, PVEC_BIGNUM);
}
INLINE struct Lisp_Bignum *
XBIGNUM (Lisp_Object a)
{
eassert (BIGNUMP (a));
- return XUNTAG (a, Lisp_Misc, struct Lisp_Bignum);
+ return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Bignum);
}
INLINE bool
{
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)
{
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));
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)
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)),
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;
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;
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))
}
/* 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;
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))
/* 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);