diff options
| author | Paul Eggert | 2018-08-08 19:46:29 -0700 |
|---|---|---|
| committer | Paul Eggert | 2018-08-11 18:50:25 -0700 |
| commit | d614e4a8cd2d5fe37b38bb4d8191013a7d917731 (patch) | |
| tree | f27e866dc009cba536575c9a30af362296a9b60e /src | |
| parent | d3ec5117da3146573cad5c1f8d01ab2e58f21e92 (diff) | |
| download | emacs-d614e4a8cd2d5fe37b38bb4d8191013a7d917731.tar.gz emacs-d614e4a8cd2d5fe37b38bb4d8191013a7d917731.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/alloc.c | 393 | ||||
| -rw-r--r-- | src/buffer.c | 250 | ||||
| -rw-r--r-- | src/data.c | 27 | ||||
| -rw-r--r-- | src/editfns.c | 31 | ||||
| -rw-r--r-- | src/fns.c | 58 | ||||
| -rw-r--r-- | src/lisp.h | 218 | ||||
| -rw-r--r-- | src/print.c | 165 | ||||
| -rw-r--r-- | src/undo.c | 14 | ||||
| -rw-r--r-- | src/xdisp.c | 45 |
9 files changed, 395 insertions, 806 deletions
diff --git a/src/alloc.c b/src/alloc.c index c3e02c20f85..fea0cec383b 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -247,8 +247,8 @@ bool gc_in_progress; | |||
| 247 | 247 | ||
| 248 | /* Number of live and free conses etc. */ | 248 | /* Number of live and free conses etc. */ |
| 249 | 249 | ||
| 250 | static EMACS_INT total_conses, total_markers, total_symbols, total_buffers; | 250 | static EMACS_INT total_conses, total_symbols, total_buffers; |
| 251 | static EMACS_INT total_free_conses, total_free_markers, total_free_symbols; | 251 | static EMACS_INT total_free_conses, total_free_symbols; |
| 252 | static EMACS_INT total_free_floats, total_floats; | 252 | static EMACS_INT total_free_floats, total_floats; |
| 253 | 253 | ||
| 254 | /* Points to memory space allocated as "spare", to be freed if we run | 254 | /* Points to memory space allocated as "spare", to be freed if we run |
| @@ -356,6 +356,7 @@ no_sanitize_memcpy (void *dest, void const *src, size_t size) | |||
| 356 | 356 | ||
| 357 | #endif /* MAX_SAVE_STACK > 0 */ | 357 | #endif /* MAX_SAVE_STACK > 0 */ |
| 358 | 358 | ||
| 359 | static void unchain_finalizer (struct Lisp_Finalizer *); | ||
| 359 | static void mark_terminals (void); | 360 | static void mark_terminals (void); |
| 360 | static void gc_sweep (void); | 361 | static void gc_sweep (void); |
| 361 | static Lisp_Object make_pure_vector (ptrdiff_t); | 362 | static Lisp_Object make_pure_vector (ptrdiff_t); |
| @@ -3197,7 +3198,12 @@ static void | |||
| 3197 | cleanup_vector (struct Lisp_Vector *vector) | 3198 | cleanup_vector (struct Lisp_Vector *vector) |
| 3198 | { | 3199 | { |
| 3199 | detect_suspicious_free (vector); | 3200 | detect_suspicious_free (vector); |
| 3200 | if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FONT)) | 3201 | |
| 3202 | if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_BIGNUM)) | ||
| 3203 | mpz_clear (PSEUDOVEC_STRUCT (vector, Lisp_Bignum)->value); | ||
| 3204 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FINALIZER)) | ||
| 3205 | unchain_finalizer (PSEUDOVEC_STRUCT (vector, Lisp_Finalizer)); | ||
| 3206 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FONT)) | ||
| 3201 | { | 3207 | { |
| 3202 | if ((vector->header.size & PSEUDOVECTOR_SIZE_MASK) == FONT_OBJECT_MAX) | 3208 | if ((vector->header.size & PSEUDOVECTOR_SIZE_MASK) == FONT_OBJECT_MAX) |
| 3203 | { | 3209 | { |
| @@ -3220,6 +3226,19 @@ cleanup_vector (struct Lisp_Vector *vector) | |||
| 3220 | finalize_one_mutex (PSEUDOVEC_STRUCT (vector, Lisp_Mutex)); | 3226 | finalize_one_mutex (PSEUDOVEC_STRUCT (vector, Lisp_Mutex)); |
| 3221 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_CONDVAR)) | 3227 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_CONDVAR)) |
| 3222 | finalize_one_condvar (PSEUDOVEC_STRUCT (vector, Lisp_CondVar)); | 3228 | finalize_one_condvar (PSEUDOVEC_STRUCT (vector, Lisp_CondVar)); |
| 3229 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_MARKER)) | ||
| 3230 | { | ||
| 3231 | /* sweep_buffer should already have unchained this from its buffer. */ | ||
| 3232 | eassert (! PSEUDOVEC_STRUCT (vector, Lisp_Marker)->buffer); | ||
| 3233 | } | ||
| 3234 | #ifdef HAVE_MODULES | ||
| 3235 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_USER_PTR)) | ||
| 3236 | { | ||
| 3237 | struct Lisp_User_Ptr *uptr = PSEUDOVEC_STRUCT (vector, Lisp_User_Ptr); | ||
| 3238 | if (uptr->finalizer) | ||
| 3239 | uptr->finalizer (uptr->p); | ||
| 3240 | } | ||
| 3241 | #endif | ||
| 3223 | } | 3242 | } |
| 3224 | 3243 | ||
| 3225 | /* Reclaim space used by unmarked vectors. */ | 3244 | /* Reclaim space used by unmarked vectors. */ |
| @@ -3650,96 +3669,27 @@ Its value is void, and its function definition and property list are nil. */) | |||
| 3650 | 3669 | ||
| 3651 | 3670 | ||
| 3652 | 3671 | ||
| 3653 | /*********************************************************************** | ||
| 3654 | Marker (Misc) Allocation | ||
| 3655 | ***********************************************************************/ | ||
| 3656 | |||
| 3657 | /* Like union Lisp_Misc, but padded so that its size is a multiple of | ||
| 3658 | the required alignment. */ | ||
| 3659 | |||
| 3660 | union aligned_Lisp_Misc | ||
| 3661 | { | ||
| 3662 | union Lisp_Misc m; | ||
| 3663 | unsigned char c[(sizeof (union Lisp_Misc) + LISP_ALIGNMENT - 1) | ||
| 3664 | & -LISP_ALIGNMENT]; | ||
| 3665 | }; | ||
| 3666 | |||
| 3667 | /* Allocation of markers and other objects that share that structure. | ||
| 3668 | Works like allocation of conses. */ | ||
| 3669 | |||
| 3670 | #define MARKER_BLOCK_SIZE \ | ||
| 3671 | ((1020 - sizeof (struct marker_block *)) / sizeof (union aligned_Lisp_Misc)) | ||
| 3672 | |||
| 3673 | struct marker_block | ||
| 3674 | { | ||
| 3675 | /* Place `markers' first, to preserve alignment. */ | ||
| 3676 | union aligned_Lisp_Misc markers[MARKER_BLOCK_SIZE]; | ||
| 3677 | struct marker_block *next; | ||
| 3678 | }; | ||
| 3679 | |||
| 3680 | static struct marker_block *marker_block; | ||
| 3681 | static int marker_block_index = MARKER_BLOCK_SIZE; | ||
| 3682 | |||
| 3683 | static union Lisp_Misc *misc_free_list; | ||
| 3684 | |||
| 3685 | /* Return a newly allocated Lisp_Misc object of specified TYPE. */ | ||
| 3686 | |||
| 3687 | static Lisp_Object | ||
| 3688 | allocate_misc (enum Lisp_Misc_Type type) | ||
| 3689 | { | ||
| 3690 | Lisp_Object val; | ||
| 3691 | |||
| 3692 | MALLOC_BLOCK_INPUT; | ||
| 3693 | |||
| 3694 | if (misc_free_list) | ||
| 3695 | { | ||
| 3696 | XSETMISC (val, misc_free_list); | ||
| 3697 | misc_free_list = misc_free_list->u_free.chain; | ||
| 3698 | } | ||
| 3699 | else | ||
| 3700 | { | ||
| 3701 | if (marker_block_index == MARKER_BLOCK_SIZE) | ||
| 3702 | { | ||
| 3703 | struct marker_block *new = lisp_malloc (sizeof *new, MEM_TYPE_MISC); | ||
| 3704 | new->next = marker_block; | ||
| 3705 | marker_block = new; | ||
| 3706 | marker_block_index = 0; | ||
| 3707 | total_free_markers += MARKER_BLOCK_SIZE; | ||
| 3708 | } | ||
| 3709 | XSETMISC (val, &marker_block->markers[marker_block_index].m); | ||
| 3710 | marker_block_index++; | ||
| 3711 | } | ||
| 3712 | |||
| 3713 | MALLOC_UNBLOCK_INPUT; | ||
| 3714 | |||
| 3715 | --total_free_markers; | ||
| 3716 | consing_since_gc += sizeof (union Lisp_Misc); | ||
| 3717 | misc_objects_consed++; | ||
| 3718 | XMISCANY (val)->type = type; | ||
| 3719 | XMISCANY (val)->gcmarkbit = 0; | ||
| 3720 | return val; | ||
| 3721 | } | ||
| 3722 | |||
| 3723 | Lisp_Object | 3672 | Lisp_Object |
| 3724 | make_misc_ptr (void *a) | 3673 | make_misc_ptr (void *a) |
| 3725 | { | 3674 | { |
| 3726 | Lisp_Object val = allocate_misc (Lisp_Misc_Ptr); | 3675 | struct Lisp_Misc_Ptr *p = ALLOCATE_PSEUDOVECTOR (struct Lisp_Misc_Ptr, pointer, |
| 3727 | XUNTAG (val, Lisp_Misc, struct Lisp_Misc_Ptr)->pointer = a; | 3676 | PVEC_MISC_PTR); |
| 3728 | return val; | 3677 | p->pointer = a; |
| 3678 | return make_lisp_ptr (p, Lisp_Vectorlike); | ||
| 3729 | } | 3679 | } |
| 3730 | 3680 | ||
| 3731 | /* Return a Lisp_Misc_Overlay object with specified START, END and PLIST. */ | 3681 | /* Return a new overlay with specified START, END and PLIST. */ |
| 3732 | 3682 | ||
| 3733 | Lisp_Object | 3683 | Lisp_Object |
| 3734 | build_overlay (Lisp_Object start, Lisp_Object end, Lisp_Object plist) | 3684 | build_overlay (Lisp_Object start, Lisp_Object end, Lisp_Object plist) |
| 3735 | { | 3685 | { |
| 3736 | register Lisp_Object overlay; | 3686 | struct Lisp_Overlay *p = ALLOCATE_PSEUDOVECTOR (struct Lisp_Overlay, next, |
| 3737 | 3687 | PVEC_OVERLAY); | |
| 3738 | overlay = allocate_misc (Lisp_Misc_Overlay); | 3688 | Lisp_Object overlay = make_lisp_ptr (p, Lisp_Vectorlike); |
| 3739 | OVERLAY_START (overlay) = start; | 3689 | OVERLAY_START (overlay) = start; |
| 3740 | OVERLAY_END (overlay) = end; | 3690 | OVERLAY_END (overlay) = end; |
| 3741 | set_overlay_plist (overlay, plist); | 3691 | set_overlay_plist (overlay, plist); |
| 3742 | XOVERLAY (overlay)->next = NULL; | 3692 | p->next = NULL; |
| 3743 | return overlay; | 3693 | return overlay; |
| 3744 | } | 3694 | } |
| 3745 | 3695 | ||
| @@ -3747,18 +3697,15 @@ DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0, | |||
| 3747 | doc: /* Return a newly allocated marker which does not point at any place. */) | 3697 | doc: /* Return a newly allocated marker which does not point at any place. */) |
| 3748 | (void) | 3698 | (void) |
| 3749 | { | 3699 | { |
| 3750 | register Lisp_Object val; | 3700 | struct Lisp_Marker *p = ALLOCATE_PSEUDOVECTOR (struct Lisp_Marker, buffer, |
| 3751 | register struct Lisp_Marker *p; | 3701 | PVEC_MARKER); |
| 3752 | |||
| 3753 | val = allocate_misc (Lisp_Misc_Marker); | ||
| 3754 | p = XMARKER (val); | ||
| 3755 | p->buffer = 0; | 3702 | p->buffer = 0; |
| 3756 | p->bytepos = 0; | 3703 | p->bytepos = 0; |
| 3757 | p->charpos = 0; | 3704 | p->charpos = 0; |
| 3758 | p->next = NULL; | 3705 | p->next = NULL; |
| 3759 | p->insertion_type = 0; | 3706 | p->insertion_type = 0; |
| 3760 | p->need_adjustment = 0; | 3707 | p->need_adjustment = 0; |
| 3761 | return val; | 3708 | return make_lisp_ptr (p, Lisp_Vectorlike); |
| 3762 | } | 3709 | } |
| 3763 | 3710 | ||
| 3764 | /* Return a newly allocated marker which points into BUF | 3711 | /* Return a newly allocated marker which points into BUF |
| @@ -3767,17 +3714,14 @@ DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0, | |||
| 3767 | Lisp_Object | 3714 | Lisp_Object |
| 3768 | build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos) | 3715 | build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos) |
| 3769 | { | 3716 | { |
| 3770 | Lisp_Object obj; | ||
| 3771 | struct Lisp_Marker *m; | ||
| 3772 | |||
| 3773 | /* No dead buffers here. */ | 3717 | /* No dead buffers here. */ |
| 3774 | eassert (BUFFER_LIVE_P (buf)); | 3718 | eassert (BUFFER_LIVE_P (buf)); |
| 3775 | 3719 | ||
| 3776 | /* Every character is at least one byte. */ | 3720 | /* Every character is at least one byte. */ |
| 3777 | eassert (charpos <= bytepos); | 3721 | eassert (charpos <= bytepos); |
| 3778 | 3722 | ||
| 3779 | obj = allocate_misc (Lisp_Misc_Marker); | 3723 | struct Lisp_Marker *m = ALLOCATE_PSEUDOVECTOR (struct Lisp_Marker, buffer, |
| 3780 | m = XMARKER (obj); | 3724 | PVEC_MARKER); |
| 3781 | m->buffer = buf; | 3725 | m->buffer = buf; |
| 3782 | m->charpos = charpos; | 3726 | m->charpos = charpos; |
| 3783 | m->bytepos = bytepos; | 3727 | m->bytepos = bytepos; |
| @@ -3785,7 +3729,7 @@ build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos) | |||
| 3785 | m->need_adjustment = 0; | 3729 | m->need_adjustment = 0; |
| 3786 | m->next = BUF_MARKERS (buf); | 3730 | m->next = BUF_MARKERS (buf); |
| 3787 | BUF_MARKERS (buf) = m; | 3731 | BUF_MARKERS (buf) = m; |
| 3788 | return obj; | 3732 | return make_lisp_ptr (m, Lisp_Vectorlike); |
| 3789 | } | 3733 | } |
| 3790 | 3734 | ||
| 3791 | 3735 | ||
| @@ -3793,16 +3737,12 @@ build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos) | |||
| 3793 | Lisp_Object | 3737 | Lisp_Object |
| 3794 | make_bignum_str (const char *num, int base) | 3738 | make_bignum_str (const char *num, int base) |
| 3795 | { | 3739 | { |
| 3796 | Lisp_Object obj; | 3740 | struct Lisp_Bignum *b = ALLOCATE_PSEUDOVECTOR (struct Lisp_Bignum, value, |
| 3797 | struct Lisp_Bignum *b; | 3741 | PVEC_BIGNUM); |
| 3798 | int check; | ||
| 3799 | |||
| 3800 | obj = allocate_misc (Lisp_Misc_Bignum); | ||
| 3801 | b = XBIGNUM (obj); | ||
| 3802 | mpz_init (b->value); | 3742 | mpz_init (b->value); |
| 3803 | check = mpz_set_str (b->value, num, base); | 3743 | int check = mpz_set_str (b->value, num, base); |
| 3804 | eassert (check == 0); | 3744 | eassert (check == 0); |
| 3805 | return obj; | 3745 | return make_lisp_ptr (b, Lisp_Vectorlike); |
| 3806 | } | 3746 | } |
| 3807 | 3747 | ||
| 3808 | /* Given an mpz_t, make a number. This may return a bignum or a | 3748 | /* Given an mpz_t, make a number. This may return a bignum or a |
| @@ -3811,17 +3751,11 @@ make_bignum_str (const char *num, int base) | |||
| 3811 | Lisp_Object | 3751 | Lisp_Object |
| 3812 | make_number (mpz_t value) | 3752 | make_number (mpz_t value) |
| 3813 | { | 3753 | { |
| 3814 | Lisp_Object obj; | ||
| 3815 | struct Lisp_Bignum *b; | ||
| 3816 | |||
| 3817 | if (mpz_fits_slong_p (value)) | 3754 | if (mpz_fits_slong_p (value)) |
| 3818 | { | 3755 | { |
| 3819 | long l = mpz_get_si (value); | 3756 | long l = mpz_get_si (value); |
| 3820 | if (!FIXNUM_OVERFLOW_P (l)) | 3757 | if (!FIXNUM_OVERFLOW_P (l)) |
| 3821 | { | 3758 | return make_fixnum (l); |
| 3822 | XSETINT (obj, l); | ||
| 3823 | return obj; | ||
| 3824 | } | ||
| 3825 | } | 3759 | } |
| 3826 | 3760 | ||
| 3827 | /* Check if fixnum can be larger than long. */ | 3761 | /* Check if fixnum can be larger than long. */ |
| @@ -3845,20 +3779,17 @@ make_number (mpz_t value) | |||
| 3845 | v = -v; | 3779 | v = -v; |
| 3846 | 3780 | ||
| 3847 | if (!FIXNUM_OVERFLOW_P (v)) | 3781 | if (!FIXNUM_OVERFLOW_P (v)) |
| 3848 | { | 3782 | return make_fixnum (v); |
| 3849 | XSETINT (obj, v); | ||
| 3850 | return obj; | ||
| 3851 | } | ||
| 3852 | } | 3783 | } |
| 3853 | } | 3784 | } |
| 3854 | 3785 | ||
| 3855 | obj = allocate_misc (Lisp_Misc_Bignum); | 3786 | struct Lisp_Bignum *b = ALLOCATE_PSEUDOVECTOR (struct Lisp_Bignum, value, |
| 3856 | b = XBIGNUM (obj); | 3787 | PVEC_BIGNUM); |
| 3857 | /* We could mpz_init + mpz_swap here, to avoid a copy, but the | 3788 | /* We could mpz_init + mpz_swap here, to avoid a copy, but the |
| 3858 | resulting API seemed possibly confusing. */ | 3789 | resulting API seemed possibly confusing. */ |
| 3859 | mpz_init_set (b->value, value); | 3790 | mpz_init_set (b->value, value); |
| 3860 | 3791 | ||
| 3861 | return obj; | 3792 | return make_lisp_ptr (b, Lisp_Vectorlike); |
| 3862 | } | 3793 | } |
| 3863 | 3794 | ||
| 3864 | void | 3795 | void |
| @@ -3934,14 +3865,11 @@ make_event_array (ptrdiff_t nargs, Lisp_Object *args) | |||
| 3934 | Lisp_Object | 3865 | Lisp_Object |
| 3935 | make_user_ptr (void (*finalizer) (void *), void *p) | 3866 | make_user_ptr (void (*finalizer) (void *), void *p) |
| 3936 | { | 3867 | { |
| 3937 | Lisp_Object obj; | 3868 | struct Lisp_User_Ptr *uptr = ALLOCATE_PSEUDOVECTOR (struct Lisp_User_Ptr, |
| 3938 | struct Lisp_User_Ptr *uptr; | 3869 | finalizer, PVEC_USER_PTR); |
| 3939 | |||
| 3940 | obj = allocate_misc (Lisp_Misc_User_Ptr); | ||
| 3941 | uptr = XUSER_PTR (obj); | ||
| 3942 | uptr->finalizer = finalizer; | 3870 | uptr->finalizer = finalizer; |
| 3943 | uptr->p = p; | 3871 | uptr->p = p; |
| 3944 | return obj; | 3872 | return make_lisp_ptr (uptr, Lisp_Vectorlike); |
| 3945 | } | 3873 | } |
| 3946 | #endif | 3874 | #endif |
| 3947 | 3875 | ||
| @@ -3984,7 +3912,7 @@ mark_finalizer_list (struct Lisp_Finalizer *head) | |||
| 3984 | finalizer != head; | 3912 | finalizer != head; |
| 3985 | finalizer = finalizer->next) | 3913 | finalizer = finalizer->next) |
| 3986 | { | 3914 | { |
| 3987 | finalizer->base.gcmarkbit = true; | 3915 | VECTOR_MARK (finalizer); |
| 3988 | mark_object (finalizer->function); | 3916 | mark_object (finalizer->function); |
| 3989 | } | 3917 | } |
| 3990 | } | 3918 | } |
| @@ -4001,7 +3929,7 @@ queue_doomed_finalizers (struct Lisp_Finalizer *dest, | |||
| 4001 | while (finalizer != src) | 3929 | while (finalizer != src) |
| 4002 | { | 3930 | { |
| 4003 | struct Lisp_Finalizer *next = finalizer->next; | 3931 | struct Lisp_Finalizer *next = finalizer->next; |
| 4004 | if (!finalizer->base.gcmarkbit && !NILP (finalizer->function)) | 3932 | if (!VECTOR_MARKED_P (finalizer) && !NILP (finalizer->function)) |
| 4005 | { | 3933 | { |
| 4006 | unchain_finalizer (finalizer); | 3934 | unchain_finalizer (finalizer); |
| 4007 | finalizer_insert (dest, finalizer); | 3935 | finalizer_insert (dest, finalizer); |
| @@ -4037,7 +3965,6 @@ run_finalizers (struct Lisp_Finalizer *finalizers) | |||
| 4037 | while (finalizers->next != finalizers) | 3965 | while (finalizers->next != finalizers) |
| 4038 | { | 3966 | { |
| 4039 | finalizer = finalizers->next; | 3967 | finalizer = finalizers->next; |
| 4040 | eassert (finalizer->base.type == Lisp_Misc_Finalizer); | ||
| 4041 | unchain_finalizer (finalizer); | 3968 | unchain_finalizer (finalizer); |
| 4042 | function = finalizer->function; | 3969 | function = finalizer->function; |
| 4043 | if (!NILP (function)) | 3970 | if (!NILP (function)) |
| @@ -4057,12 +3984,12 @@ count as reachable for the purpose of deciding whether to run | |||
| 4057 | FUNCTION. FUNCTION will be run once per finalizer object. */) | 3984 | FUNCTION. FUNCTION will be run once per finalizer object. */) |
| 4058 | (Lisp_Object function) | 3985 | (Lisp_Object function) |
| 4059 | { | 3986 | { |
| 4060 | Lisp_Object val = allocate_misc (Lisp_Misc_Finalizer); | 3987 | struct Lisp_Finalizer *finalizer |
| 4061 | struct Lisp_Finalizer *finalizer = XFINALIZER (val); | 3988 | = ALLOCATE_PSEUDOVECTOR (struct Lisp_Finalizer, prev, PVEC_FINALIZER); |
| 4062 | finalizer->function = function; | 3989 | finalizer->function = function; |
| 4063 | finalizer->prev = finalizer->next = NULL; | 3990 | finalizer->prev = finalizer->next = NULL; |
| 4064 | finalizer_insert (&finalizers, finalizer); | 3991 | finalizer_insert (&finalizers, finalizer); |
| 4065 | return val; | 3992 | return make_lisp_ptr (finalizer, Lisp_Vectorlike); |
| 4066 | } | 3993 | } |
| 4067 | 3994 | ||
| 4068 | 3995 | ||
| @@ -4683,41 +4610,6 @@ live_float_p (struct mem_node *m, void *p) | |||
| 4683 | return 0; | 4610 | return 0; |
| 4684 | } | 4611 | } |
| 4685 | 4612 | ||
| 4686 | |||
| 4687 | /* If P is a pointer to a live Lisp Misc on the heap, return the object. | ||
| 4688 | Otherwise, return nil. M is a pointer to the mem_block for P. */ | ||
| 4689 | |||
| 4690 | static Lisp_Object | ||
| 4691 | live_misc_holding (struct mem_node *m, void *p) | ||
| 4692 | { | ||
| 4693 | if (m->type == MEM_TYPE_MISC) | ||
| 4694 | { | ||
| 4695 | struct marker_block *b = m->start; | ||
| 4696 | char *cp = p; | ||
| 4697 | ptrdiff_t offset = cp - (char *) &b->markers[0]; | ||
| 4698 | |||
| 4699 | /* P must point into a Lisp_Misc, not be | ||
| 4700 | one of the unused cells in the current misc block, | ||
| 4701 | and not be on the free-list. */ | ||
| 4702 | if (0 <= offset && offset < MARKER_BLOCK_SIZE * sizeof b->markers[0] | ||
| 4703 | && (b != marker_block | ||
| 4704 | || offset / sizeof b->markers[0] < marker_block_index)) | ||
| 4705 | { | ||
| 4706 | cp = ptr_bounds_copy (cp, b); | ||
| 4707 | union Lisp_Misc *s = p = cp -= offset % sizeof b->markers[0]; | ||
| 4708 | if (s->u_any.type != Lisp_Misc_Free) | ||
| 4709 | return make_lisp_ptr (s, Lisp_Misc); | ||
| 4710 | } | ||
| 4711 | } | ||
| 4712 | return Qnil; | ||
| 4713 | } | ||
| 4714 | |||
| 4715 | static bool | ||
| 4716 | live_misc_p (struct mem_node *m, void *p) | ||
| 4717 | { | ||
| 4718 | return !NILP (live_misc_holding (m, p)); | ||
| 4719 | } | ||
| 4720 | |||
| 4721 | /* If P is a pointer to a live vector-like object, return the object. | 4613 | /* If P is a pointer to a live vector-like object, return the object. |
| 4722 | Otherwise, return nil. | 4614 | Otherwise, return nil. |
| 4723 | M is a pointer to the mem_block for P. */ | 4615 | M is a pointer to the mem_block for P. */ |
| @@ -4836,10 +4728,6 @@ mark_maybe_object (Lisp_Object obj) | |||
| 4836 | || EQ (obj, live_buffer_holding (m, po))); | 4728 | || EQ (obj, live_buffer_holding (m, po))); |
| 4837 | break; | 4729 | break; |
| 4838 | 4730 | ||
| 4839 | case Lisp_Misc: | ||
| 4840 | mark_p = EQ (obj, live_misc_holding (m, po)); | ||
| 4841 | break; | ||
| 4842 | |||
| 4843 | default: | 4731 | default: |
| 4844 | break; | 4732 | break; |
| 4845 | } | 4733 | } |
| @@ -4921,10 +4809,6 @@ mark_maybe_pointer (void *p) | |||
| 4921 | obj = live_string_holding (m, p); | 4809 | obj = live_string_holding (m, p); |
| 4922 | break; | 4810 | break; |
| 4923 | 4811 | ||
| 4924 | case MEM_TYPE_MISC: | ||
| 4925 | obj = live_misc_holding (m, p); | ||
| 4926 | break; | ||
| 4927 | |||
| 4928 | case MEM_TYPE_SYMBOL: | 4812 | case MEM_TYPE_SYMBOL: |
| 4929 | obj = live_symbol_holding (m, p); | 4813 | obj = live_symbol_holding (m, p); |
| 4930 | break; | 4814 | break; |
| @@ -5325,9 +5209,6 @@ valid_lisp_object_p (Lisp_Object obj) | |||
| 5325 | case MEM_TYPE_STRING: | 5209 | case MEM_TYPE_STRING: |
| 5326 | return live_string_p (m, p); | 5210 | return live_string_p (m, p); |
| 5327 | 5211 | ||
| 5328 | case MEM_TYPE_MISC: | ||
| 5329 | return live_misc_p (m, p); | ||
| 5330 | |||
| 5331 | case MEM_TYPE_SYMBOL: | 5212 | case MEM_TYPE_SYMBOL: |
| 5332 | return live_symbol_p (m, p); | 5213 | return live_symbol_p (m, p); |
| 5333 | 5214 | ||
| @@ -5550,14 +5431,13 @@ make_pure_float (double num) | |||
| 5550 | static Lisp_Object | 5431 | static Lisp_Object |
| 5551 | make_pure_bignum (struct Lisp_Bignum *value) | 5432 | make_pure_bignum (struct Lisp_Bignum *value) |
| 5552 | { | 5433 | { |
| 5553 | Lisp_Object new; | ||
| 5554 | size_t i, nlimbs = mpz_size (value->value); | 5434 | size_t i, nlimbs = mpz_size (value->value); |
| 5555 | size_t nbytes = nlimbs * sizeof (mp_limb_t); | 5435 | size_t nbytes = nlimbs * sizeof (mp_limb_t); |
| 5556 | mp_limb_t *pure_limbs; | 5436 | mp_limb_t *pure_limbs; |
| 5557 | mp_size_t new_size; | 5437 | mp_size_t new_size; |
| 5558 | 5438 | ||
| 5559 | struct Lisp_Bignum *b = pure_alloc (sizeof (struct Lisp_Bignum), Lisp_Misc); | 5439 | struct Lisp_Bignum *b = pure_alloc (sizeof *b, Lisp_Vectorlike); |
| 5560 | b->type = Lisp_Misc_Bignum; | 5440 | XSETPVECTYPESIZE (b, PVEC_BIGNUM, 0, VECSIZE (struct Lisp_Bignum)); |
| 5561 | 5441 | ||
| 5562 | pure_limbs = pure_alloc (nbytes, -1); | 5442 | pure_limbs = pure_alloc (nbytes, -1); |
| 5563 | for (i = 0; i < nlimbs; ++i) | 5443 | for (i = 0; i < nlimbs; ++i) |
| @@ -5569,8 +5449,7 @@ make_pure_bignum (struct Lisp_Bignum *value) | |||
| 5569 | 5449 | ||
| 5570 | mpz_roinit_n (b->value, pure_limbs, new_size); | 5450 | mpz_roinit_n (b->value, pure_limbs, new_size); |
| 5571 | 5451 | ||
| 5572 | XSETMISC (new, b); | 5452 | return make_lisp_ptr (b, Lisp_Vectorlike); |
| 5573 | return new; | ||
| 5574 | } | 5453 | } |
| 5575 | 5454 | ||
| 5576 | /* Return a vector with room for LEN Lisp_Objects allocated from | 5455 | /* Return a vector with room for LEN Lisp_Objects allocated from |
| @@ -5777,7 +5656,6 @@ total_bytes_of_live_objects (void) | |||
| 5777 | size_t tot = 0; | 5656 | size_t tot = 0; |
| 5778 | tot += total_conses * sizeof (struct Lisp_Cons); | 5657 | tot += total_conses * sizeof (struct Lisp_Cons); |
| 5779 | tot += total_symbols * sizeof (struct Lisp_Symbol); | 5658 | tot += total_symbols * sizeof (struct Lisp_Symbol); |
| 5780 | tot += total_markers * sizeof (union Lisp_Misc); | ||
| 5781 | tot += total_string_bytes; | 5659 | tot += total_string_bytes; |
| 5782 | tot += total_vector_slots * word_size; | 5660 | tot += total_vector_slots * word_size; |
| 5783 | tot += total_floats * sizeof (struct Lisp_Float); | 5661 | tot += total_floats * sizeof (struct Lisp_Float); |
| @@ -5898,7 +5776,7 @@ compact_undo_list (Lisp_Object list) | |||
| 5898 | { | 5776 | { |
| 5899 | if (CONSP (XCAR (tail)) | 5777 | if (CONSP (XCAR (tail)) |
| 5900 | && MARKERP (XCAR (XCAR (tail))) | 5778 | && MARKERP (XCAR (XCAR (tail))) |
| 5901 | && !XMARKER (XCAR (XCAR (tail)))->gcmarkbit) | 5779 | && !VECTOR_MARKED_P (XMARKER (XCAR (XCAR (tail))))) |
| 5902 | *prev = XCDR (tail); | 5780 | *prev = XCDR (tail); |
| 5903 | else | 5781 | else |
| 5904 | prev = xcdr_addr (tail); | 5782 | prev = xcdr_addr (tail); |
| @@ -6125,9 +6003,6 @@ garbage_collect_1 (void *end) | |||
| 6125 | list4 (Qsymbols, make_fixnum (sizeof (struct Lisp_Symbol)), | 6003 | list4 (Qsymbols, make_fixnum (sizeof (struct Lisp_Symbol)), |
| 6126 | bounded_number (total_symbols), | 6004 | bounded_number (total_symbols), |
| 6127 | bounded_number (total_free_symbols)), | 6005 | bounded_number (total_free_symbols)), |
| 6128 | list4 (Qmiscs, make_fixnum (sizeof (union Lisp_Misc)), | ||
| 6129 | bounded_number (total_markers), | ||
| 6130 | bounded_number (total_free_markers)), | ||
| 6131 | list4 (Qstrings, make_fixnum (sizeof (struct Lisp_String)), | 6006 | list4 (Qstrings, make_fixnum (sizeof (struct Lisp_String)), |
| 6132 | bounded_number (total_strings), | 6007 | bounded_number (total_strings), |
| 6133 | bounded_number (total_free_strings)), | 6008 | bounded_number (total_free_strings)), |
| @@ -6314,12 +6189,12 @@ mark_compiled (struct Lisp_Vector *ptr) | |||
| 6314 | static void | 6189 | static void |
| 6315 | mark_overlay (struct Lisp_Overlay *ptr) | 6190 | mark_overlay (struct Lisp_Overlay *ptr) |
| 6316 | { | 6191 | { |
| 6317 | for (; ptr && !ptr->gcmarkbit; ptr = ptr->next) | 6192 | for (; ptr && !VECTOR_MARKED_P (ptr); ptr = ptr->next) |
| 6318 | { | 6193 | { |
| 6319 | ptr->gcmarkbit = 1; | 6194 | VECTOR_MARK (ptr); |
| 6320 | /* These two are always markers and can be marked fast. */ | 6195 | /* These two are always markers and can be marked fast. */ |
| 6321 | XMARKER (ptr->start)->gcmarkbit = 1; | 6196 | VECTOR_MARK (XMARKER (ptr->start)); |
| 6322 | XMARKER (ptr->end)->gcmarkbit = 1; | 6197 | VECTOR_MARK (XMARKER (ptr->end)); |
| 6323 | mark_object (ptr->plist); | 6198 | mark_object (ptr->plist); |
| 6324 | } | 6199 | } |
| 6325 | } | 6200 | } |
| @@ -6620,9 +6495,26 @@ mark_object (Lisp_Object arg) | |||
| 6620 | mark_char_table (ptr, (enum pvec_type) pvectype); | 6495 | mark_char_table (ptr, (enum pvec_type) pvectype); |
| 6621 | break; | 6496 | break; |
| 6622 | 6497 | ||
| 6498 | case PVEC_MARKER: | ||
| 6499 | /* DO NOT mark thru the marker's chain. | ||
| 6500 | The buffer's markers chain does not preserve markers from gc; | ||
| 6501 | instead, markers are removed from the chain when freed by gc. */ | ||
| 6623 | case PVEC_BOOL_VECTOR: | 6502 | case PVEC_BOOL_VECTOR: |
| 6624 | /* No Lisp_Objects to mark in a bool vector. */ | 6503 | case PVEC_MISC_PTR: |
| 6504 | #ifdef HAVE_MODULES | ||
| 6505 | case PVEC_USER_PTR: | ||
| 6506 | #endif | ||
| 6507 | /* No Lisp_Objects to mark in these. */ | ||
| 6508 | VECTOR_MARK (ptr); | ||
| 6509 | break; | ||
| 6510 | |||
| 6511 | case PVEC_OVERLAY: | ||
| 6512 | mark_overlay (XOVERLAY (obj)); | ||
| 6513 | break; | ||
| 6514 | |||
| 6515 | case PVEC_FINALIZER: | ||
| 6625 | VECTOR_MARK (ptr); | 6516 | VECTOR_MARK (ptr); |
| 6517 | mark_object (XFINALIZER (obj)->function); | ||
| 6626 | break; | 6518 | break; |
| 6627 | 6519 | ||
| 6628 | case PVEC_SUBR: | 6520 | case PVEC_SUBR: |
| @@ -6680,49 +6572,9 @@ mark_object (Lisp_Object arg) | |||
| 6680 | } | 6572 | } |
| 6681 | break; | 6573 | break; |
| 6682 | 6574 | ||
| 6683 | case Lisp_Misc: | ||
| 6684 | CHECK_ALLOCATED_AND_LIVE (live_misc_p); | ||
| 6685 | |||
| 6686 | if (XMISCANY (obj)->gcmarkbit) | ||
| 6687 | break; | ||
| 6688 | |||
| 6689 | switch (XMISCTYPE (obj)) | ||
| 6690 | { | ||
| 6691 | case Lisp_Misc_Marker: | ||
| 6692 | /* DO NOT mark thru the marker's chain. | ||
| 6693 | The buffer's markers chain does not preserve markers from gc; | ||
| 6694 | instead, markers are removed from the chain when freed by gc. */ | ||
| 6695 | XMISCANY (obj)->gcmarkbit = 1; | ||
| 6696 | break; | ||
| 6697 | |||
| 6698 | case Lisp_Misc_Ptr: | ||
| 6699 | case Lisp_Misc_Bignum: | ||
| 6700 | XMISCANY (obj)->gcmarkbit = true; | ||
| 6701 | break; | ||
| 6702 | |||
| 6703 | case Lisp_Misc_Overlay: | ||
| 6704 | mark_overlay (XOVERLAY (obj)); | ||
| 6705 | break; | ||
| 6706 | |||
| 6707 | case Lisp_Misc_Finalizer: | ||
| 6708 | XMISCANY (obj)->gcmarkbit = true; | ||
| 6709 | mark_object (XFINALIZER (obj)->function); | ||
| 6710 | break; | ||
| 6711 | |||
| 6712 | #ifdef HAVE_MODULES | ||
| 6713 | case Lisp_Misc_User_Ptr: | ||
| 6714 | XMISCANY (obj)->gcmarkbit = true; | ||
| 6715 | break; | ||
| 6716 | #endif | ||
| 6717 | |||
| 6718 | default: | ||
| 6719 | emacs_abort (); | ||
| 6720 | } | ||
| 6721 | break; | ||
| 6722 | |||
| 6723 | case Lisp_Cons: | 6575 | case Lisp_Cons: |
| 6724 | { | 6576 | { |
| 6725 | register struct Lisp_Cons *ptr = XCONS (obj); | 6577 | struct Lisp_Cons *ptr = XCONS (obj); |
| 6726 | if (CONS_MARKED_P (ptr)) | 6578 | if (CONS_MARKED_P (ptr)) |
| 6727 | break; | 6579 | break; |
| 6728 | CHECK_ALLOCATED_AND_LIVE (live_cons_p); | 6580 | CHECK_ALLOCATED_AND_LIVE (live_cons_p); |
| @@ -6799,10 +6651,6 @@ survives_gc_p (Lisp_Object obj) | |||
| 6799 | survives_p = XSYMBOL (obj)->u.s.gcmarkbit; | 6651 | survives_p = XSYMBOL (obj)->u.s.gcmarkbit; |
| 6800 | break; | 6652 | break; |
| 6801 | 6653 | ||
| 6802 | case Lisp_Misc: | ||
| 6803 | survives_p = XMISCANY (obj)->gcmarkbit; | ||
| 6804 | break; | ||
| 6805 | |||
| 6806 | case Lisp_String: | 6654 | case Lisp_String: |
| 6807 | survives_p = STRING_MARKED_P (XSTRING (obj)); | 6655 | survives_p = STRING_MARKED_P (XSTRING (obj)); |
| 6808 | break; | 6656 | break; |
| @@ -7079,81 +6927,6 @@ sweep_symbols (void) | |||
| 7079 | total_free_symbols = num_free; | 6927 | total_free_symbols = num_free; |
| 7080 | } | 6928 | } |
| 7081 | 6929 | ||
| 7082 | NO_INLINE /* For better stack traces. */ | ||
| 7083 | static void | ||
| 7084 | sweep_misc (void) | ||
| 7085 | { | ||
| 7086 | register struct marker_block *mblk; | ||
| 7087 | struct marker_block **mprev = &marker_block; | ||
| 7088 | register int lim = marker_block_index; | ||
| 7089 | EMACS_INT num_free = 0, num_used = 0; | ||
| 7090 | |||
| 7091 | /* Put all unmarked misc's on free list. For a marker, first | ||
| 7092 | unchain it from the buffer it points into. */ | ||
| 7093 | |||
| 7094 | misc_free_list = 0; | ||
| 7095 | |||
| 7096 | for (mblk = marker_block; mblk; mblk = *mprev) | ||
| 7097 | { | ||
| 7098 | register int i; | ||
| 7099 | int this_free = 0; | ||
| 7100 | |||
| 7101 | for (i = 0; i < lim; i++) | ||
| 7102 | { | ||
| 7103 | if (!mblk->markers[i].m.u_any.gcmarkbit) | ||
| 7104 | { | ||
| 7105 | if (mblk->markers[i].m.u_any.type == Lisp_Misc_Marker) | ||
| 7106 | /* Make sure markers have been unchained from their buffer | ||
| 7107 | in sweep_buffer before we collect them. */ | ||
| 7108 | eassert (!mblk->markers[i].m.u_marker.buffer); | ||
| 7109 | else if (mblk->markers[i].m.u_any.type == Lisp_Misc_Finalizer) | ||
| 7110 | unchain_finalizer (&mblk->markers[i].m.u_finalizer); | ||
| 7111 | #ifdef HAVE_MODULES | ||
| 7112 | else if (mblk->markers[i].m.u_any.type == Lisp_Misc_User_Ptr) | ||
| 7113 | { | ||
| 7114 | struct Lisp_User_Ptr *uptr = &mblk->markers[i].m.u_user_ptr; | ||
| 7115 | if (uptr->finalizer) | ||
| 7116 | uptr->finalizer (uptr->p); | ||
| 7117 | } | ||
| 7118 | #endif | ||
| 7119 | else if (mblk->markers[i].m.u_any.type == Lisp_Misc_Bignum) | ||
| 7120 | mpz_clear (mblk->markers[i].m.u_bignum.value); | ||
| 7121 | /* Set the type of the freed object to Lisp_Misc_Free. | ||
| 7122 | We could leave the type alone, since nobody checks it, | ||
| 7123 | but this might catch bugs faster. */ | ||
| 7124 | mblk->markers[i].m.u_marker.type = Lisp_Misc_Free; | ||
| 7125 | mblk->markers[i].m.u_free.chain = misc_free_list; | ||
| 7126 | misc_free_list = &mblk->markers[i].m; | ||
| 7127 | this_free++; | ||
| 7128 | } | ||
| 7129 | else | ||
| 7130 | { | ||
| 7131 | num_used++; | ||
| 7132 | mblk->markers[i].m.u_any.gcmarkbit = 0; | ||
| 7133 | } | ||
| 7134 | } | ||
| 7135 | lim = MARKER_BLOCK_SIZE; | ||
| 7136 | /* If this block contains only free markers and we have already | ||
| 7137 | seen more than two blocks worth of free markers then deallocate | ||
| 7138 | this block. */ | ||
| 7139 | if (this_free == MARKER_BLOCK_SIZE && num_free > MARKER_BLOCK_SIZE) | ||
| 7140 | { | ||
| 7141 | *mprev = mblk->next; | ||
| 7142 | /* Unhook from the free list. */ | ||
| 7143 | misc_free_list = mblk->markers[0].m.u_free.chain; | ||
| 7144 | lisp_free (mblk); | ||
| 7145 | } | ||
| 7146 | else | ||
| 7147 | { | ||
| 7148 | num_free += this_free; | ||
| 7149 | mprev = &mblk->next; | ||
| 7150 | } | ||
| 7151 | } | ||
| 7152 | |||
| 7153 | total_markers = num_used; | ||
| 7154 | total_free_markers = num_free; | ||
| 7155 | } | ||
| 7156 | |||
| 7157 | /* Remove BUFFER's markers that are due to be swept. This is needed since | 6930 | /* Remove BUFFER's markers that are due to be swept. This is needed since |
| 7158 | we treat BUF_MARKERS and markers's `next' field as weak pointers. */ | 6931 | we treat BUF_MARKERS and markers's `next' field as weak pointers. */ |
| 7159 | static void | 6932 | static void |
| @@ -7162,7 +6935,7 @@ unchain_dead_markers (struct buffer *buffer) | |||
| 7162 | struct Lisp_Marker *this, **prev = &BUF_MARKERS (buffer); | 6935 | struct Lisp_Marker *this, **prev = &BUF_MARKERS (buffer); |
| 7163 | 6936 | ||
| 7164 | while ((this = *prev)) | 6937 | while ((this = *prev)) |
| 7165 | if (this->gcmarkbit) | 6938 | if (VECTOR_MARKED_P (this)) |
| 7166 | prev = &this->next; | 6939 | prev = &this->next; |
| 7167 | else | 6940 | else |
| 7168 | { | 6941 | { |
| @@ -7210,7 +6983,6 @@ gc_sweep (void) | |||
| 7210 | sweep_intervals (); | 6983 | sweep_intervals (); |
| 7211 | sweep_symbols (); | 6984 | sweep_symbols (); |
| 7212 | sweep_buffers (); | 6985 | sweep_buffers (); |
| 7213 | sweep_misc (); | ||
| 7214 | sweep_vectors (); | 6986 | sweep_vectors (); |
| 7215 | check_string_bytes (!noninteractive); | 6987 | check_string_bytes (!noninteractive); |
| 7216 | } | 6988 | } |
| @@ -7585,7 +7357,6 @@ do hash-consing of the objects allocated to pure space. */); | |||
| 7585 | 7357 | ||
| 7586 | DEFSYM (Qconses, "conses"); | 7358 | DEFSYM (Qconses, "conses"); |
| 7587 | DEFSYM (Qsymbols, "symbols"); | 7359 | DEFSYM (Qsymbols, "symbols"); |
| 7588 | DEFSYM (Qmiscs, "miscs"); | ||
| 7589 | DEFSYM (Qstrings, "strings"); | 7360 | DEFSYM (Qstrings, "strings"); |
| 7590 | DEFSYM (Qvectors, "vectors"); | 7361 | DEFSYM (Qvectors, "vectors"); |
| 7591 | DEFSYM (Qfloats, "floats"); | 7362 | DEFSYM (Qfloats, "floats"); |
diff --git a/src/buffer.c b/src/buffer.c index ec6f4647119..878844dd020 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -2789,8 +2789,6 @@ overlays_at (EMACS_INT pos, bool extend, Lisp_Object **vec_ptr, | |||
| 2789 | ptrdiff_t *len_ptr, | 2789 | ptrdiff_t *len_ptr, |
| 2790 | ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr, bool change_req) | 2790 | ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr, bool change_req) |
| 2791 | { | 2791 | { |
| 2792 | Lisp_Object overlay, start, end; | ||
| 2793 | struct Lisp_Overlay *tail; | ||
| 2794 | ptrdiff_t idx = 0; | 2792 | ptrdiff_t idx = 0; |
| 2795 | ptrdiff_t len = *len_ptr; | 2793 | ptrdiff_t len = *len_ptr; |
| 2796 | Lisp_Object *vec = *vec_ptr; | 2794 | Lisp_Object *vec = *vec_ptr; |
| @@ -2798,22 +2796,20 @@ overlays_at (EMACS_INT pos, bool extend, Lisp_Object **vec_ptr, | |||
| 2798 | ptrdiff_t prev = BEGV; | 2796 | ptrdiff_t prev = BEGV; |
| 2799 | bool inhibit_storing = 0; | 2797 | bool inhibit_storing = 0; |
| 2800 | 2798 | ||
| 2801 | for (tail = current_buffer->overlays_before; tail; tail = tail->next) | 2799 | for (struct Lisp_Overlay *tail = current_buffer->overlays_before; |
| 2800 | tail; tail = tail->next) | ||
| 2802 | { | 2801 | { |
| 2803 | ptrdiff_t startpos, endpos; | 2802 | Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); |
| 2804 | 2803 | Lisp_Object start = OVERLAY_START (overlay); | |
| 2805 | XSETMISC (overlay, tail); | 2804 | Lisp_Object end = OVERLAY_END (overlay); |
| 2806 | 2805 | ptrdiff_t endpos = OVERLAY_POSITION (end); | |
| 2807 | start = OVERLAY_START (overlay); | ||
| 2808 | end = OVERLAY_END (overlay); | ||
| 2809 | endpos = OVERLAY_POSITION (end); | ||
| 2810 | if (endpos < pos) | 2806 | if (endpos < pos) |
| 2811 | { | 2807 | { |
| 2812 | if (prev < endpos) | 2808 | if (prev < endpos) |
| 2813 | prev = endpos; | 2809 | prev = endpos; |
| 2814 | break; | 2810 | break; |
| 2815 | } | 2811 | } |
| 2816 | startpos = OVERLAY_POSITION (start); | 2812 | ptrdiff_t startpos = OVERLAY_POSITION (start); |
| 2817 | /* This one ends at or after POS | 2813 | /* This one ends at or after POS |
| 2818 | so its start counts for PREV_PTR if it's before POS. */ | 2814 | so its start counts for PREV_PTR if it's before POS. */ |
| 2819 | if (prev < startpos && startpos < pos) | 2815 | if (prev < startpos && startpos < pos) |
| @@ -2846,22 +2842,20 @@ overlays_at (EMACS_INT pos, bool extend, Lisp_Object **vec_ptr, | |||
| 2846 | next = startpos; | 2842 | next = startpos; |
| 2847 | } | 2843 | } |
| 2848 | 2844 | ||
| 2849 | for (tail = current_buffer->overlays_after; tail; tail = tail->next) | 2845 | for (struct Lisp_Overlay *tail = current_buffer->overlays_after; |
| 2846 | tail; tail = tail->next) | ||
| 2850 | { | 2847 | { |
| 2851 | ptrdiff_t startpos, endpos; | 2848 | Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); |
| 2852 | 2849 | Lisp_Object start = OVERLAY_START (overlay); | |
| 2853 | XSETMISC (overlay, tail); | 2850 | Lisp_Object end = OVERLAY_END (overlay); |
| 2854 | 2851 | ptrdiff_t startpos = OVERLAY_POSITION (start); | |
| 2855 | start = OVERLAY_START (overlay); | ||
| 2856 | end = OVERLAY_END (overlay); | ||
| 2857 | startpos = OVERLAY_POSITION (start); | ||
| 2858 | if (pos < startpos) | 2852 | if (pos < startpos) |
| 2859 | { | 2853 | { |
| 2860 | if (startpos < next) | 2854 | if (startpos < next) |
| 2861 | next = startpos; | 2855 | next = startpos; |
| 2862 | break; | 2856 | break; |
| 2863 | } | 2857 | } |
| 2864 | endpos = OVERLAY_POSITION (end); | 2858 | ptrdiff_t endpos = OVERLAY_POSITION (end); |
| 2865 | if (pos < endpos) | 2859 | if (pos < endpos) |
| 2866 | { | 2860 | { |
| 2867 | if (idx == len) | 2861 | if (idx == len) |
| @@ -2923,8 +2917,6 @@ overlays_in (EMACS_INT beg, EMACS_INT end, bool extend, | |||
| 2923 | Lisp_Object **vec_ptr, ptrdiff_t *len_ptr, | 2917 | Lisp_Object **vec_ptr, ptrdiff_t *len_ptr, |
| 2924 | ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr) | 2918 | ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr) |
| 2925 | { | 2919 | { |
| 2926 | Lisp_Object overlay, ostart, oend; | ||
| 2927 | struct Lisp_Overlay *tail; | ||
| 2928 | ptrdiff_t idx = 0; | 2920 | ptrdiff_t idx = 0; |
| 2929 | ptrdiff_t len = *len_ptr; | 2921 | ptrdiff_t len = *len_ptr; |
| 2930 | Lisp_Object *vec = *vec_ptr; | 2922 | Lisp_Object *vec = *vec_ptr; |
| @@ -2933,22 +2925,20 @@ overlays_in (EMACS_INT beg, EMACS_INT end, bool extend, | |||
| 2933 | bool inhibit_storing = 0; | 2925 | bool inhibit_storing = 0; |
| 2934 | bool end_is_Z = end == Z; | 2926 | bool end_is_Z = end == Z; |
| 2935 | 2927 | ||
| 2936 | for (tail = current_buffer->overlays_before; tail; tail = tail->next) | 2928 | for (struct Lisp_Overlay *tail = current_buffer->overlays_before; |
| 2929 | tail; tail = tail->next) | ||
| 2937 | { | 2930 | { |
| 2938 | ptrdiff_t startpos, endpos; | 2931 | Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); |
| 2939 | 2932 | Lisp_Object ostart = OVERLAY_START (overlay); | |
| 2940 | XSETMISC (overlay, tail); | 2933 | Lisp_Object oend = OVERLAY_END (overlay); |
| 2941 | 2934 | ptrdiff_t endpos = OVERLAY_POSITION (oend); | |
| 2942 | ostart = OVERLAY_START (overlay); | ||
| 2943 | oend = OVERLAY_END (overlay); | ||
| 2944 | endpos = OVERLAY_POSITION (oend); | ||
| 2945 | if (endpos < beg) | 2935 | if (endpos < beg) |
| 2946 | { | 2936 | { |
| 2947 | if (prev < endpos) | 2937 | if (prev < endpos) |
| 2948 | prev = endpos; | 2938 | prev = endpos; |
| 2949 | break; | 2939 | break; |
| 2950 | } | 2940 | } |
| 2951 | startpos = OVERLAY_POSITION (ostart); | 2941 | ptrdiff_t startpos = OVERLAY_POSITION (ostart); |
| 2952 | /* Count an interval if it overlaps the range, is empty at the | 2942 | /* Count an interval if it overlaps the range, is empty at the |
| 2953 | start of the range, or is empty at END provided END denotes the | 2943 | start of the range, or is empty at END provided END denotes the |
| 2954 | end of the buffer. */ | 2944 | end of the buffer. */ |
| @@ -2980,22 +2970,20 @@ overlays_in (EMACS_INT beg, EMACS_INT end, bool extend, | |||
| 2980 | next = startpos; | 2970 | next = startpos; |
| 2981 | } | 2971 | } |
| 2982 | 2972 | ||
| 2983 | for (tail = current_buffer->overlays_after; tail; tail = tail->next) | 2973 | for (struct Lisp_Overlay *tail = current_buffer->overlays_after; |
| 2974 | tail; tail = tail->next) | ||
| 2984 | { | 2975 | { |
| 2985 | ptrdiff_t startpos, endpos; | 2976 | Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); |
| 2986 | 2977 | Lisp_Object ostart = OVERLAY_START (overlay); | |
| 2987 | XSETMISC (overlay, tail); | 2978 | Lisp_Object oend = OVERLAY_END (overlay); |
| 2988 | 2979 | ptrdiff_t startpos = OVERLAY_POSITION (ostart); | |
| 2989 | ostart = OVERLAY_START (overlay); | ||
| 2990 | oend = OVERLAY_END (overlay); | ||
| 2991 | startpos = OVERLAY_POSITION (ostart); | ||
| 2992 | if (end < startpos) | 2980 | if (end < startpos) |
| 2993 | { | 2981 | { |
| 2994 | if (startpos < next) | 2982 | if (startpos < next) |
| 2995 | next = startpos; | 2983 | next = startpos; |
| 2996 | break; | 2984 | break; |
| 2997 | } | 2985 | } |
| 2998 | endpos = OVERLAY_POSITION (oend); | 2986 | ptrdiff_t endpos = OVERLAY_POSITION (oend); |
| 2999 | /* Count an interval if it overlaps the range, is empty at the | 2987 | /* Count an interval if it overlaps the range, is empty at the |
| 3000 | start of the range, or is empty at END provided END denotes the | 2988 | start of the range, or is empty at END provided END denotes the |
| 3001 | end of the buffer. */ | 2989 | end of the buffer. */ |
| @@ -3097,31 +3085,26 @@ disable_line_numbers_overlay_at_eob (void) | |||
| 3097 | bool | 3085 | bool |
| 3098 | overlay_touches_p (ptrdiff_t pos) | 3086 | overlay_touches_p (ptrdiff_t pos) |
| 3099 | { | 3087 | { |
| 3100 | Lisp_Object overlay; | 3088 | for (struct Lisp_Overlay *tail = current_buffer->overlays_before; |
| 3101 | struct Lisp_Overlay *tail; | 3089 | tail; tail = tail->next) |
| 3102 | |||
| 3103 | for (tail = current_buffer->overlays_before; tail; tail = tail->next) | ||
| 3104 | { | 3090 | { |
| 3105 | ptrdiff_t endpos; | 3091 | Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); |
| 3106 | |||
| 3107 | XSETMISC (overlay ,tail); | ||
| 3108 | eassert (OVERLAYP (overlay)); | 3092 | eassert (OVERLAYP (overlay)); |
| 3109 | 3093 | ||
| 3110 | endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); | 3094 | ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); |
| 3111 | if (endpos < pos) | 3095 | if (endpos < pos) |
| 3112 | break; | 3096 | break; |
| 3113 | if (endpos == pos || OVERLAY_POSITION (OVERLAY_START (overlay)) == pos) | 3097 | if (endpos == pos || OVERLAY_POSITION (OVERLAY_START (overlay)) == pos) |
| 3114 | return 1; | 3098 | return 1; |
| 3115 | } | 3099 | } |
| 3116 | 3100 | ||
| 3117 | for (tail = current_buffer->overlays_after; tail; tail = tail->next) | 3101 | for (struct Lisp_Overlay *tail = current_buffer->overlays_after; |
| 3102 | tail; tail = tail->next) | ||
| 3118 | { | 3103 | { |
| 3119 | ptrdiff_t startpos; | 3104 | Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); |
| 3120 | |||
| 3121 | XSETMISC (overlay, tail); | ||
| 3122 | eassert (OVERLAYP (overlay)); | 3105 | eassert (OVERLAYP (overlay)); |
| 3123 | 3106 | ||
| 3124 | startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); | 3107 | ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); |
| 3125 | if (pos < startpos) | 3108 | if (pos < startpos) |
| 3126 | break; | 3109 | break; |
| 3127 | if (startpos == pos || OVERLAY_POSITION (OVERLAY_END (overlay)) == pos) | 3110 | if (startpos == pos || OVERLAY_POSITION (OVERLAY_END (overlay)) == pos) |
| @@ -3337,27 +3320,26 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str, | |||
| 3337 | ptrdiff_t | 3320 | ptrdiff_t |
| 3338 | overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr) | 3321 | overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr) |
| 3339 | { | 3322 | { |
| 3340 | Lisp_Object overlay, window, str; | ||
| 3341 | struct Lisp_Overlay *ov; | ||
| 3342 | ptrdiff_t startpos, endpos; | ||
| 3343 | bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); | 3323 | bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); |
| 3344 | 3324 | ||
| 3345 | overlay_heads.used = overlay_heads.bytes = 0; | 3325 | overlay_heads.used = overlay_heads.bytes = 0; |
| 3346 | overlay_tails.used = overlay_tails.bytes = 0; | 3326 | overlay_tails.used = overlay_tails.bytes = 0; |
| 3347 | for (ov = current_buffer->overlays_before; ov; ov = ov->next) | 3327 | for (struct Lisp_Overlay *ov = current_buffer->overlays_before; |
| 3328 | ov; ov = ov->next) | ||
| 3348 | { | 3329 | { |
| 3349 | XSETMISC (overlay, ov); | 3330 | Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike); |
| 3350 | eassert (OVERLAYP (overlay)); | 3331 | eassert (OVERLAYP (overlay)); |
| 3351 | 3332 | ||
| 3352 | startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); | 3333 | ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); |
| 3353 | endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); | 3334 | ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); |
| 3354 | if (endpos < pos) | 3335 | if (endpos < pos) |
| 3355 | break; | 3336 | break; |
| 3356 | if (endpos != pos && startpos != pos) | 3337 | if (endpos != pos && startpos != pos) |
| 3357 | continue; | 3338 | continue; |
| 3358 | window = Foverlay_get (overlay, Qwindow); | 3339 | Lisp_Object window = Foverlay_get (overlay, Qwindow); |
| 3359 | if (WINDOWP (window) && XWINDOW (window) != w) | 3340 | if (WINDOWP (window) && XWINDOW (window) != w) |
| 3360 | continue; | 3341 | continue; |
| 3342 | Lisp_Object str; | ||
| 3361 | if (startpos == pos | 3343 | if (startpos == pos |
| 3362 | && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) | 3344 | && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) |
| 3363 | record_overlay_string (&overlay_heads, str, | 3345 | record_overlay_string (&overlay_heads, str, |
| @@ -3372,20 +3354,22 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr) | |||
| 3372 | Foverlay_get (overlay, Qpriority), | 3354 | Foverlay_get (overlay, Qpriority), |
| 3373 | endpos - startpos); | 3355 | endpos - startpos); |
| 3374 | } | 3356 | } |
| 3375 | for (ov = current_buffer->overlays_after; ov; ov = ov->next) | 3357 | for (struct Lisp_Overlay *ov = current_buffer->overlays_after; |
| 3358 | ov; ov = ov->next) | ||
| 3376 | { | 3359 | { |
| 3377 | XSETMISC (overlay, ov); | 3360 | Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike); |
| 3378 | eassert (OVERLAYP (overlay)); | 3361 | eassert (OVERLAYP (overlay)); |
| 3379 | 3362 | ||
| 3380 | startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); | 3363 | ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); |
| 3381 | endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); | 3364 | ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); |
| 3382 | if (startpos > pos) | 3365 | if (startpos > pos) |
| 3383 | break; | 3366 | break; |
| 3384 | if (endpos != pos && startpos != pos) | 3367 | if (endpos != pos && startpos != pos) |
| 3385 | continue; | 3368 | continue; |
| 3386 | window = Foverlay_get (overlay, Qwindow); | 3369 | Lisp_Object window = Foverlay_get (overlay, Qwindow); |
| 3387 | if (WINDOWP (window) && XWINDOW (window) != w) | 3370 | if (WINDOWP (window) && XWINDOW (window) != w) |
| 3388 | continue; | 3371 | continue; |
| 3372 | Lisp_Object str; | ||
| 3389 | if (startpos == pos | 3373 | if (startpos == pos |
| 3390 | && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) | 3374 | && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) |
| 3391 | record_overlay_string (&overlay_heads, str, | 3375 | record_overlay_string (&overlay_heads, str, |
| @@ -3460,8 +3444,7 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr) | |||
| 3460 | void | 3444 | void |
| 3461 | recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos) | 3445 | recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos) |
| 3462 | { | 3446 | { |
| 3463 | Lisp_Object overlay, beg, end; | 3447 | struct Lisp_Overlay *prev, *next; |
| 3464 | struct Lisp_Overlay *prev, *tail, *next; | ||
| 3465 | 3448 | ||
| 3466 | /* See if anything in overlays_before should move to overlays_after. */ | 3449 | /* See if anything in overlays_before should move to overlays_after. */ |
| 3467 | 3450 | ||
| @@ -3469,14 +3452,15 @@ recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos) | |||
| 3469 | But we use it for symmetry and in case that should cease to be true | 3452 | But we use it for symmetry and in case that should cease to be true |
| 3470 | with some future change. */ | 3453 | with some future change. */ |
| 3471 | prev = NULL; | 3454 | prev = NULL; |
| 3472 | for (tail = buf->overlays_before; tail; prev = tail, tail = next) | 3455 | for (struct Lisp_Overlay *tail = buf->overlays_before; |
| 3456 | tail; prev = tail, tail = next) | ||
| 3473 | { | 3457 | { |
| 3474 | next = tail->next; | 3458 | next = tail->next; |
| 3475 | XSETMISC (overlay, tail); | 3459 | Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); |
| 3476 | eassert (OVERLAYP (overlay)); | 3460 | eassert (OVERLAYP (overlay)); |
| 3477 | 3461 | ||
| 3478 | beg = OVERLAY_START (overlay); | 3462 | Lisp_Object beg = OVERLAY_START (overlay); |
| 3479 | end = OVERLAY_END (overlay); | 3463 | Lisp_Object end = OVERLAY_END (overlay); |
| 3480 | 3464 | ||
| 3481 | if (OVERLAY_POSITION (end) > pos) | 3465 | if (OVERLAY_POSITION (end) > pos) |
| 3482 | { | 3466 | { |
| @@ -3495,12 +3479,10 @@ recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos) | |||
| 3495 | for (other = buf->overlays_after; other; | 3479 | for (other = buf->overlays_after; other; |
| 3496 | other_prev = other, other = other->next) | 3480 | other_prev = other, other = other->next) |
| 3497 | { | 3481 | { |
| 3498 | Lisp_Object otherbeg, otheroverlay; | 3482 | Lisp_Object otheroverlay = make_lisp_ptr (other, Lisp_Vectorlike); |
| 3499 | |||
| 3500 | XSETMISC (otheroverlay, other); | ||
| 3501 | eassert (OVERLAYP (otheroverlay)); | 3483 | eassert (OVERLAYP (otheroverlay)); |
| 3502 | 3484 | ||
| 3503 | otherbeg = OVERLAY_START (otheroverlay); | 3485 | Lisp_Object otherbeg = OVERLAY_START (otheroverlay); |
| 3504 | if (OVERLAY_POSITION (otherbeg) >= where) | 3486 | if (OVERLAY_POSITION (otherbeg) >= where) |
| 3505 | break; | 3487 | break; |
| 3506 | } | 3488 | } |
| @@ -3522,14 +3504,15 @@ recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos) | |||
| 3522 | 3504 | ||
| 3523 | /* See if anything in overlays_after should be in overlays_before. */ | 3505 | /* See if anything in overlays_after should be in overlays_before. */ |
| 3524 | prev = NULL; | 3506 | prev = NULL; |
| 3525 | for (tail = buf->overlays_after; tail; prev = tail, tail = next) | 3507 | for (struct Lisp_Overlay *tail = buf->overlays_after; |
| 3508 | tail; prev = tail, tail = next) | ||
| 3526 | { | 3509 | { |
| 3527 | next = tail->next; | 3510 | next = tail->next; |
| 3528 | XSETMISC (overlay, tail); | 3511 | Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); |
| 3529 | eassert (OVERLAYP (overlay)); | 3512 | eassert (OVERLAYP (overlay)); |
| 3530 | 3513 | ||
| 3531 | beg = OVERLAY_START (overlay); | 3514 | Lisp_Object beg = OVERLAY_START (overlay); |
| 3532 | end = OVERLAY_END (overlay); | 3515 | Lisp_Object end = OVERLAY_END (overlay); |
| 3533 | 3516 | ||
| 3534 | /* Stop looking, when we know that nothing further | 3517 | /* Stop looking, when we know that nothing further |
| 3535 | can possibly end before POS. */ | 3518 | can possibly end before POS. */ |
| @@ -3553,12 +3536,10 @@ recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos) | |||
| 3553 | for (other = buf->overlays_before; other; | 3536 | for (other = buf->overlays_before; other; |
| 3554 | other_prev = other, other = other->next) | 3537 | other_prev = other, other = other->next) |
| 3555 | { | 3538 | { |
| 3556 | Lisp_Object otherend, otheroverlay; | 3539 | Lisp_Object otheroverlay = make_lisp_ptr (other, Lisp_Vectorlike); |
| 3557 | |||
| 3558 | XSETMISC (otheroverlay, other); | ||
| 3559 | eassert (OVERLAYP (otheroverlay)); | 3540 | eassert (OVERLAYP (otheroverlay)); |
| 3560 | 3541 | ||
| 3561 | otherend = OVERLAY_END (otheroverlay); | 3542 | Lisp_Object otherend = OVERLAY_END (otheroverlay); |
| 3562 | if (OVERLAY_POSITION (otherend) <= where) | 3543 | if (OVERLAY_POSITION (otherend) <= where) |
| 3563 | break; | 3544 | break; |
| 3564 | } | 3545 | } |
| @@ -3613,7 +3594,6 @@ adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length) | |||
| 3613 | void | 3594 | void |
| 3614 | fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end) | 3595 | fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end) |
| 3615 | { | 3596 | { |
| 3616 | Lisp_Object overlay; | ||
| 3617 | struct Lisp_Overlay *before_list UNINIT; | 3597 | struct Lisp_Overlay *before_list UNINIT; |
| 3618 | struct Lisp_Overlay *after_list UNINIT; | 3598 | struct Lisp_Overlay *after_list UNINIT; |
| 3619 | /* These are either nil, indicating that before_list or after_list | 3599 | /* These are either nil, indicating that before_list or after_list |
| @@ -3623,8 +3603,7 @@ fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end) | |||
| 3623 | /* 'Parent', likewise, indicates a cons cell or | 3603 | /* 'Parent', likewise, indicates a cons cell or |
| 3624 | current_buffer->overlays_before or overlays_after, depending | 3604 | current_buffer->overlays_before or overlays_after, depending |
| 3625 | which loop we're in. */ | 3605 | which loop we're in. */ |
| 3626 | struct Lisp_Overlay *tail, *parent; | 3606 | struct Lisp_Overlay *parent; |
| 3627 | ptrdiff_t startpos, endpos; | ||
| 3628 | 3607 | ||
| 3629 | /* This algorithm shifts links around instead of consing and GCing. | 3608 | /* This algorithm shifts links around instead of consing and GCing. |
| 3630 | The loop invariant is that before_list (resp. after_list) is a | 3609 | The loop invariant is that before_list (resp. after_list) is a |
| @@ -3633,12 +3612,14 @@ fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end) | |||
| 3633 | (after_list) if it is, is still uninitialized. So it's not a bug | 3612 | (after_list) if it is, is still uninitialized. So it's not a bug |
| 3634 | that before_list isn't initialized, although it may look | 3613 | that before_list isn't initialized, although it may look |
| 3635 | strange. */ | 3614 | strange. */ |
| 3636 | for (parent = NULL, tail = current_buffer->overlays_before; tail;) | 3615 | parent = NULL; |
| 3616 | for (struct Lisp_Overlay *tail = current_buffer->overlays_before; | ||
| 3617 | tail; tail = tail->next) | ||
| 3637 | { | 3618 | { |
| 3638 | XSETMISC (overlay, tail); | 3619 | Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); |
| 3639 | 3620 | ||
| 3640 | endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); | 3621 | ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); |
| 3641 | startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); | 3622 | ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); |
| 3642 | 3623 | ||
| 3643 | /* If the overlay is backwards, make it empty. */ | 3624 | /* If the overlay is backwards, make it empty. */ |
| 3644 | if (endpos < startpos) | 3625 | if (endpos < startpos) |
| @@ -3676,17 +3657,18 @@ fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end) | |||
| 3676 | set_buffer_overlays_before (current_buffer, tail->next); | 3657 | set_buffer_overlays_before (current_buffer, tail->next); |
| 3677 | else | 3658 | else |
| 3678 | parent->next = tail->next; | 3659 | parent->next = tail->next; |
| 3679 | tail = tail->next; | ||
| 3680 | } | 3660 | } |
| 3681 | else | 3661 | else |
| 3682 | parent = tail, tail = parent->next; | 3662 | parent = tail; |
| 3683 | } | 3663 | } |
| 3684 | for (parent = NULL, tail = current_buffer->overlays_after; tail;) | 3664 | parent = NULL; |
| 3665 | for (struct Lisp_Overlay *tail = current_buffer->overlays_after; | ||
| 3666 | tail; tail = tail->next) | ||
| 3685 | { | 3667 | { |
| 3686 | XSETMISC (overlay, tail); | 3668 | Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); |
| 3687 | 3669 | ||
| 3688 | startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); | 3670 | ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); |
| 3689 | endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); | 3671 | ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); |
| 3690 | 3672 | ||
| 3691 | /* If the overlay is backwards, make it empty. */ | 3673 | /* If the overlay is backwards, make it empty. */ |
| 3692 | if (endpos < startpos) | 3674 | if (endpos < startpos) |
| @@ -3722,10 +3704,9 @@ fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end) | |||
| 3722 | set_buffer_overlays_after (current_buffer, tail->next); | 3704 | set_buffer_overlays_after (current_buffer, tail->next); |
| 3723 | else | 3705 | else |
| 3724 | parent->next = tail->next; | 3706 | parent->next = tail->next; |
| 3725 | tail = tail->next; | ||
| 3726 | } | 3707 | } |
| 3727 | else | 3708 | else |
| 3728 | parent = tail, tail = parent->next; | 3709 | parent = tail; |
| 3729 | } | 3710 | } |
| 3730 | 3711 | ||
| 3731 | /* Splice the constructed (wrong) lists into the buffer's lists, | 3712 | /* Splice the constructed (wrong) lists into the buffer's lists, |
| @@ -3776,7 +3757,7 @@ fix_overlays_before (struct buffer *bp, ptrdiff_t prev, ptrdiff_t pos) | |||
| 3776 | overlay whose ending marker is after-insertion-marker if disorder | 3757 | overlay whose ending marker is after-insertion-marker if disorder |
| 3777 | exists). */ | 3758 | exists). */ |
| 3778 | while (tail | 3759 | while (tail |
| 3779 | && (XSETMISC (tem, tail), | 3760 | && (tem = make_lisp_ptr (tail, Lisp_Vectorlike), |
| 3780 | (end = OVERLAY_POSITION (OVERLAY_END (tem))) >= pos)) | 3761 | (end = OVERLAY_POSITION (OVERLAY_END (tem))) >= pos)) |
| 3781 | { | 3762 | { |
| 3782 | parent = tail; | 3763 | parent = tail; |
| @@ -3801,7 +3782,7 @@ fix_overlays_before (struct buffer *bp, ptrdiff_t prev, ptrdiff_t pos) | |||
| 3801 | overlays are in correct order. */ | 3782 | overlays are in correct order. */ |
| 3802 | while (tail) | 3783 | while (tail) |
| 3803 | { | 3784 | { |
| 3804 | XSETMISC (tem, tail); | 3785 | tem = make_lisp_ptr (tail, Lisp_Vectorlike); |
| 3805 | end = OVERLAY_POSITION (OVERLAY_END (tem)); | 3786 | end = OVERLAY_POSITION (OVERLAY_END (tem)); |
| 3806 | 3787 | ||
| 3807 | if (end == pos) | 3788 | if (end == pos) |
| @@ -4308,19 +4289,14 @@ The lists you get are copies, so that changing them has no effect. | |||
| 4308 | However, the overlays you get are the real objects that the buffer uses. */) | 4289 | However, the overlays you get are the real objects that the buffer uses. */) |
| 4309 | (void) | 4290 | (void) |
| 4310 | { | 4291 | { |
| 4311 | struct Lisp_Overlay *ol; | 4292 | Lisp_Object before = Qnil, after = Qnil; |
| 4312 | Lisp_Object before = Qnil, after = Qnil, tmp; | ||
| 4313 | 4293 | ||
| 4314 | for (ol = current_buffer->overlays_before; ol; ol = ol->next) | 4294 | for (struct Lisp_Overlay *ol = current_buffer->overlays_before; |
| 4315 | { | 4295 | ol; ol = ol->next) |
| 4316 | XSETMISC (tmp, ol); | 4296 | before = Fcons (make_lisp_ptr (ol, Lisp_Vectorlike), before); |
| 4317 | before = Fcons (tmp, before); | 4297 | for (struct Lisp_Overlay *ol = current_buffer->overlays_after; |
| 4318 | } | 4298 | ol; ol = ol->next) |
| 4319 | for (ol = current_buffer->overlays_after; ol; ol = ol->next) | 4299 | after = Fcons (make_lisp_ptr (ol, Lisp_Vectorlike), after); |
| 4320 | { | ||
| 4321 | XSETMISC (tmp, ol); | ||
| 4322 | after = Fcons (tmp, after); | ||
| 4323 | } | ||
| 4324 | 4300 | ||
| 4325 | return Fcons (Fnreverse (before), Fnreverse (after)); | 4301 | return Fcons (Fnreverse (before), Fnreverse (after)); |
| 4326 | } | 4302 | } |
| @@ -4439,14 +4415,9 @@ void | |||
| 4439 | report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after, | 4415 | report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after, |
| 4440 | Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3) | 4416 | Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3) |
| 4441 | { | 4417 | { |
| 4442 | Lisp_Object prop, overlay; | ||
| 4443 | struct Lisp_Overlay *tail; | ||
| 4444 | /* True if this change is an insertion. */ | 4418 | /* True if this change is an insertion. */ |
| 4445 | bool insertion = (after ? XFIXNAT (arg3) == 0 : EQ (start, end)); | 4419 | bool insertion = (after ? XFIXNAT (arg3) == 0 : EQ (start, end)); |
| 4446 | 4420 | ||
| 4447 | overlay = Qnil; | ||
| 4448 | tail = NULL; | ||
| 4449 | |||
| 4450 | /* We used to run the functions as soon as we found them and only register | 4421 | /* We used to run the functions as soon as we found them and only register |
| 4451 | them in last_overlay_modification_hooks for the purpose of the `after' | 4422 | them in last_overlay_modification_hooks for the purpose of the `after' |
| 4452 | case. But running elisp code as we traverse the list of overlays is | 4423 | case. But running elisp code as we traverse the list of overlays is |
| @@ -4460,12 +4431,13 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after, | |||
| 4460 | /* We are being called before a change. | 4431 | /* We are being called before a change. |
| 4461 | Scan the overlays to find the functions to call. */ | 4432 | Scan the overlays to find the functions to call. */ |
| 4462 | last_overlay_modification_hooks_used = 0; | 4433 | last_overlay_modification_hooks_used = 0; |
| 4463 | for (tail = current_buffer->overlays_before; tail; tail = tail->next) | 4434 | for (struct Lisp_Overlay *tail = current_buffer->overlays_before; |
| 4435 | tail; tail = tail->next) | ||
| 4464 | { | 4436 | { |
| 4465 | ptrdiff_t startpos, endpos; | 4437 | ptrdiff_t startpos, endpos; |
| 4466 | Lisp_Object ostart, oend; | 4438 | Lisp_Object ostart, oend; |
| 4467 | 4439 | ||
| 4468 | XSETMISC (overlay, tail); | 4440 | Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); |
| 4469 | 4441 | ||
| 4470 | ostart = OVERLAY_START (overlay); | 4442 | ostart = OVERLAY_START (overlay); |
| 4471 | oend = OVERLAY_END (overlay); | 4443 | oend = OVERLAY_END (overlay); |
| @@ -4476,14 +4448,14 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after, | |||
| 4476 | if (insertion && (XFIXNAT (start) == startpos | 4448 | if (insertion && (XFIXNAT (start) == startpos |
| 4477 | || XFIXNAT (end) == startpos)) | 4449 | || XFIXNAT (end) == startpos)) |
| 4478 | { | 4450 | { |
| 4479 | prop = Foverlay_get (overlay, Qinsert_in_front_hooks); | 4451 | Lisp_Object prop = Foverlay_get (overlay, Qinsert_in_front_hooks); |
| 4480 | if (!NILP (prop)) | 4452 | if (!NILP (prop)) |
| 4481 | add_overlay_mod_hooklist (prop, overlay); | 4453 | add_overlay_mod_hooklist (prop, overlay); |
| 4482 | } | 4454 | } |
| 4483 | if (insertion && (XFIXNAT (start) == endpos | 4455 | if (insertion && (XFIXNAT (start) == endpos |
| 4484 | || XFIXNAT (end) == endpos)) | 4456 | || XFIXNAT (end) == endpos)) |
| 4485 | { | 4457 | { |
| 4486 | prop = Foverlay_get (overlay, Qinsert_behind_hooks); | 4458 | Lisp_Object prop = Foverlay_get (overlay, Qinsert_behind_hooks); |
| 4487 | if (!NILP (prop)) | 4459 | if (!NILP (prop)) |
| 4488 | add_overlay_mod_hooklist (prop, overlay); | 4460 | add_overlay_mod_hooklist (prop, overlay); |
| 4489 | } | 4461 | } |
| @@ -4491,18 +4463,19 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after, | |||
| 4491 | for both insertion and deletion. */ | 4463 | for both insertion and deletion. */ |
| 4492 | if (XFIXNAT (end) > startpos && XFIXNAT (start) < endpos) | 4464 | if (XFIXNAT (end) > startpos && XFIXNAT (start) < endpos) |
| 4493 | { | 4465 | { |
| 4494 | prop = Foverlay_get (overlay, Qmodification_hooks); | 4466 | Lisp_Object prop = Foverlay_get (overlay, Qmodification_hooks); |
| 4495 | if (!NILP (prop)) | 4467 | if (!NILP (prop)) |
| 4496 | add_overlay_mod_hooklist (prop, overlay); | 4468 | add_overlay_mod_hooklist (prop, overlay); |
| 4497 | } | 4469 | } |
| 4498 | } | 4470 | } |
| 4499 | 4471 | ||
| 4500 | for (tail = current_buffer->overlays_after; tail; tail = tail->next) | 4472 | for (struct Lisp_Overlay *tail = current_buffer->overlays_after; |
| 4473 | tail; tail = tail->next) | ||
| 4501 | { | 4474 | { |
| 4502 | ptrdiff_t startpos, endpos; | 4475 | ptrdiff_t startpos, endpos; |
| 4503 | Lisp_Object ostart, oend; | 4476 | Lisp_Object ostart, oend; |
| 4504 | 4477 | ||
| 4505 | XSETMISC (overlay, tail); | 4478 | Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); |
| 4506 | 4479 | ||
| 4507 | ostart = OVERLAY_START (overlay); | 4480 | ostart = OVERLAY_START (overlay); |
| 4508 | oend = OVERLAY_END (overlay); | 4481 | oend = OVERLAY_END (overlay); |
| @@ -4513,14 +4486,14 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after, | |||
| 4513 | if (insertion && (XFIXNAT (start) == startpos | 4486 | if (insertion && (XFIXNAT (start) == startpos |
| 4514 | || XFIXNAT (end) == startpos)) | 4487 | || XFIXNAT (end) == startpos)) |
| 4515 | { | 4488 | { |
| 4516 | prop = Foverlay_get (overlay, Qinsert_in_front_hooks); | 4489 | Lisp_Object prop = Foverlay_get (overlay, Qinsert_in_front_hooks); |
| 4517 | if (!NILP (prop)) | 4490 | if (!NILP (prop)) |
| 4518 | add_overlay_mod_hooklist (prop, overlay); | 4491 | add_overlay_mod_hooklist (prop, overlay); |
| 4519 | } | 4492 | } |
| 4520 | if (insertion && (XFIXNAT (start) == endpos | 4493 | if (insertion && (XFIXNAT (start) == endpos |
| 4521 | || XFIXNAT (end) == endpos)) | 4494 | || XFIXNAT (end) == endpos)) |
| 4522 | { | 4495 | { |
| 4523 | prop = Foverlay_get (overlay, Qinsert_behind_hooks); | 4496 | Lisp_Object prop = Foverlay_get (overlay, Qinsert_behind_hooks); |
| 4524 | if (!NILP (prop)) | 4497 | if (!NILP (prop)) |
| 4525 | add_overlay_mod_hooklist (prop, overlay); | 4498 | add_overlay_mod_hooklist (prop, overlay); |
| 4526 | } | 4499 | } |
| @@ -4528,7 +4501,7 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after, | |||
| 4528 | for both insertion and deletion. */ | 4501 | for both insertion and deletion. */ |
| 4529 | if (XFIXNAT (end) > startpos && XFIXNAT (start) < endpos) | 4502 | if (XFIXNAT (end) > startpos && XFIXNAT (start) < endpos) |
| 4530 | { | 4503 | { |
| 4531 | prop = Foverlay_get (overlay, Qmodification_hooks); | 4504 | Lisp_Object prop = Foverlay_get (overlay, Qmodification_hooks); |
| 4532 | if (!NILP (prop)) | 4505 | if (!NILP (prop)) |
| 4533 | add_overlay_mod_hooklist (prop, overlay); | 4506 | add_overlay_mod_hooklist (prop, overlay); |
| 4534 | } | 4507 | } |
| @@ -4596,16 +4569,13 @@ call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, bool after, | |||
| 4596 | void | 4569 | void |
| 4597 | evaporate_overlays (ptrdiff_t pos) | 4570 | evaporate_overlays (ptrdiff_t pos) |
| 4598 | { | 4571 | { |
| 4599 | Lisp_Object overlay, hit_list; | 4572 | Lisp_Object hit_list = Qnil; |
| 4600 | struct Lisp_Overlay *tail; | ||
| 4601 | |||
| 4602 | hit_list = Qnil; | ||
| 4603 | if (pos <= current_buffer->overlay_center) | 4573 | if (pos <= current_buffer->overlay_center) |
| 4604 | for (tail = current_buffer->overlays_before; tail; tail = tail->next) | 4574 | for (struct Lisp_Overlay *tail = current_buffer->overlays_before; |
| 4575 | tail; tail = tail->next) | ||
| 4605 | { | 4576 | { |
| 4606 | ptrdiff_t endpos; | 4577 | Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); |
| 4607 | XSETMISC (overlay, tail); | 4578 | ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); |
| 4608 | endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); | ||
| 4609 | if (endpos < pos) | 4579 | if (endpos < pos) |
| 4610 | break; | 4580 | break; |
| 4611 | if (endpos == pos && OVERLAY_POSITION (OVERLAY_START (overlay)) == pos | 4581 | if (endpos == pos && OVERLAY_POSITION (OVERLAY_START (overlay)) == pos |
| @@ -4613,11 +4583,11 @@ evaporate_overlays (ptrdiff_t pos) | |||
| 4613 | hit_list = Fcons (overlay, hit_list); | 4583 | hit_list = Fcons (overlay, hit_list); |
| 4614 | } | 4584 | } |
| 4615 | else | 4585 | else |
| 4616 | for (tail = current_buffer->overlays_after; tail; tail = tail->next) | 4586 | for (struct Lisp_Overlay *tail = current_buffer->overlays_after; |
| 4587 | tail; tail = tail->next) | ||
| 4617 | { | 4588 | { |
| 4618 | ptrdiff_t startpos; | 4589 | Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); |
| 4619 | XSETMISC (overlay, tail); | 4590 | ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); |
| 4620 | startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); | ||
| 4621 | if (startpos > pos) | 4591 | if (startpos > pos) |
| 4622 | break; | 4592 | break; |
| 4623 | if (startpos == pos && OVERLAY_POSITION (OVERLAY_END (overlay)) == pos | 4593 | if (startpos == pos && OVERLAY_POSITION (OVERLAY_END (overlay)) == pos |
diff --git a/src/data.c b/src/data.c index 7d701fde0e2..c8a9c6b3783 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -221,29 +221,17 @@ for example, (type-of 1) returns `integer'. */) | |||
| 221 | case Lisp_Cons: | 221 | case Lisp_Cons: |
| 222 | return Qcons; | 222 | return Qcons; |
| 223 | 223 | ||
| 224 | case Lisp_Misc: | ||
| 225 | switch (XMISCTYPE (object)) | ||
| 226 | { | ||
| 227 | case Lisp_Misc_Marker: | ||
| 228 | return Qmarker; | ||
| 229 | case Lisp_Misc_Overlay: | ||
| 230 | return Qoverlay; | ||
| 231 | case Lisp_Misc_Finalizer: | ||
| 232 | return Qfinalizer; | ||
| 233 | #ifdef HAVE_MODULES | ||
| 234 | case Lisp_Misc_User_Ptr: | ||
| 235 | return Quser_ptr; | ||
| 236 | #endif | ||
| 237 | case Lisp_Misc_Bignum: | ||
| 238 | return Qinteger; | ||
| 239 | default: | ||
| 240 | emacs_abort (); | ||
| 241 | } | ||
| 242 | |||
| 243 | case Lisp_Vectorlike: | 224 | case Lisp_Vectorlike: |
| 244 | switch (PSEUDOVECTOR_TYPE (XVECTOR (object))) | 225 | switch (PSEUDOVECTOR_TYPE (XVECTOR (object))) |
| 245 | { | 226 | { |
| 246 | case PVEC_NORMAL_VECTOR: return Qvector; | 227 | case PVEC_NORMAL_VECTOR: return Qvector; |
| 228 | case PVEC_BIGNUM: return Qinteger; | ||
| 229 | case PVEC_MARKER: return Qmarker; | ||
| 230 | case PVEC_OVERLAY: return Qoverlay; | ||
| 231 | case PVEC_FINALIZER: return Qfinalizer; | ||
| 232 | #ifdef HAVE_MODULES | ||
| 233 | case PVEC_USER_PTR: return Quser_ptr; | ||
| 234 | #endif | ||
| 247 | case PVEC_WINDOW_CONFIGURATION: return Qwindow_configuration; | 235 | case PVEC_WINDOW_CONFIGURATION: return Qwindow_configuration; |
| 248 | case PVEC_PROCESS: return Qprocess; | 236 | case PVEC_PROCESS: return Qprocess; |
| 249 | case PVEC_WINDOW: return Qwindow; | 237 | case PVEC_WINDOW: return Qwindow; |
| @@ -279,6 +267,7 @@ for example, (type-of 1) returns `integer'. */) | |||
| 279 | case PVEC_MODULE_FUNCTION: | 267 | case PVEC_MODULE_FUNCTION: |
| 280 | return Qmodule_function; | 268 | return Qmodule_function; |
| 281 | /* "Impossible" cases. */ | 269 | /* "Impossible" cases. */ |
| 270 | case PVEC_MISC_PTR: | ||
| 282 | case PVEC_XWIDGET: | 271 | case PVEC_XWIDGET: |
| 283 | case PVEC_OTHER: | 272 | case PVEC_OTHER: |
| 284 | case PVEC_XWIDGET_VIEW: | 273 | case PVEC_XWIDGET_VIEW: |
diff --git a/src/editfns.c b/src/editfns.c index a0a66bd19ab..92566fe3bbe 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -484,21 +484,18 @@ If you set the marker not to point anywhere, the buffer will have no mark. */) | |||
| 484 | static ptrdiff_t | 484 | static ptrdiff_t |
| 485 | overlays_around (EMACS_INT pos, Lisp_Object *vec, ptrdiff_t len) | 485 | overlays_around (EMACS_INT pos, Lisp_Object *vec, ptrdiff_t len) |
| 486 | { | 486 | { |
| 487 | Lisp_Object overlay, start, end; | ||
| 488 | struct Lisp_Overlay *tail; | ||
| 489 | ptrdiff_t startpos, endpos; | ||
| 490 | ptrdiff_t idx = 0; | 487 | ptrdiff_t idx = 0; |
| 491 | 488 | ||
| 492 | for (tail = current_buffer->overlays_before; tail; tail = tail->next) | 489 | for (struct Lisp_Overlay *tail = current_buffer->overlays_before; |
| 490 | tail; tail = tail->next) | ||
| 493 | { | 491 | { |
| 494 | XSETMISC (overlay, tail); | 492 | Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); |
| 495 | 493 | Lisp_Object end = OVERLAY_END (overlay); | |
| 496 | end = OVERLAY_END (overlay); | 494 | ptrdiff_t endpos = OVERLAY_POSITION (end); |
| 497 | endpos = OVERLAY_POSITION (end); | ||
| 498 | if (endpos < pos) | 495 | if (endpos < pos) |
| 499 | break; | 496 | break; |
| 500 | start = OVERLAY_START (overlay); | 497 | Lisp_Object start = OVERLAY_START (overlay); |
| 501 | startpos = OVERLAY_POSITION (start); | 498 | ptrdiff_t startpos = OVERLAY_POSITION (start); |
| 502 | if (startpos <= pos) | 499 | if (startpos <= pos) |
| 503 | { | 500 | { |
| 504 | if (idx < len) | 501 | if (idx < len) |
| @@ -508,16 +505,16 @@ overlays_around (EMACS_INT pos, Lisp_Object *vec, ptrdiff_t len) | |||
| 508 | } | 505 | } |
| 509 | } | 506 | } |
| 510 | 507 | ||
| 511 | for (tail = current_buffer->overlays_after; tail; tail = tail->next) | 508 | for (struct Lisp_Overlay *tail = current_buffer->overlays_after; |
| 509 | tail; tail = tail->next) | ||
| 512 | { | 510 | { |
| 513 | XSETMISC (overlay, tail); | 511 | Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); |
| 514 | 512 | Lisp_Object start = OVERLAY_START (overlay); | |
| 515 | start = OVERLAY_START (overlay); | 513 | ptrdiff_t startpos = OVERLAY_POSITION (start); |
| 516 | startpos = OVERLAY_POSITION (start); | ||
| 517 | if (pos < startpos) | 514 | if (pos < startpos) |
| 518 | break; | 515 | break; |
| 519 | end = OVERLAY_END (overlay); | 516 | Lisp_Object end = OVERLAY_END (overlay); |
| 520 | endpos = OVERLAY_POSITION (end); | 517 | ptrdiff_t endpos = OVERLAY_POSITION (end); |
| 521 | if (pos <= endpos) | 518 | if (pos <= endpos) |
| 522 | { | 519 | { |
| 523 | if (idx < len) | 520 | if (idx < len) |
| @@ -2287,7 +2287,7 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, | |||
| 2287 | ht = CALLN (Fmake_hash_table, QCtest, Qeq); | 2287 | ht = CALLN (Fmake_hash_table, QCtest, Qeq); |
| 2288 | switch (XTYPE (o1)) | 2288 | switch (XTYPE (o1)) |
| 2289 | { | 2289 | { |
| 2290 | case Lisp_Cons: case Lisp_Misc: case Lisp_Vectorlike: | 2290 | case Lisp_Cons: case Lisp_Vectorlike: |
| 2291 | { | 2291 | { |
| 2292 | struct Lisp_Hash_Table *h = XHASH_TABLE (ht); | 2292 | struct Lisp_Hash_Table *h = XHASH_TABLE (ht); |
| 2293 | EMACS_UINT hash; | 2293 | EMACS_UINT hash; |
| @@ -2344,31 +2344,6 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, | |||
| 2344 | depth++; | 2344 | depth++; |
| 2345 | goto tail_recurse; | 2345 | goto tail_recurse; |
| 2346 | 2346 | ||
| 2347 | case Lisp_Misc: | ||
| 2348 | if (XMISCTYPE (o1) != XMISCTYPE (o2)) | ||
| 2349 | return false; | ||
| 2350 | if (OVERLAYP (o1)) | ||
| 2351 | { | ||
| 2352 | if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o2), | ||
| 2353 | equal_kind, depth + 1, ht) | ||
| 2354 | || !internal_equal (OVERLAY_END (o1), OVERLAY_END (o2), | ||
| 2355 | equal_kind, depth + 1, ht)) | ||
| 2356 | return false; | ||
| 2357 | o1 = XOVERLAY (o1)->plist; | ||
| 2358 | o2 = XOVERLAY (o2)->plist; | ||
| 2359 | depth++; | ||
| 2360 | goto tail_recurse; | ||
| 2361 | } | ||
| 2362 | if (MARKERP (o1)) | ||
| 2363 | { | ||
| 2364 | return (XMARKER (o1)->buffer == XMARKER (o2)->buffer | ||
| 2365 | && (XMARKER (o1)->buffer == 0 | ||
| 2366 | || XMARKER (o1)->bytepos == XMARKER (o2)->bytepos)); | ||
| 2367 | } | ||
| 2368 | if (BIGNUMP (o1)) | ||
| 2369 | return mpz_cmp (XBIGNUM (o1)->value, XBIGNUM (o2)->value) == 0; | ||
| 2370 | break; | ||
| 2371 | |||
| 2372 | case Lisp_Vectorlike: | 2347 | case Lisp_Vectorlike: |
| 2373 | { | 2348 | { |
| 2374 | register int i; | 2349 | register int i; |
| @@ -2378,6 +2353,26 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, | |||
| 2378 | same size. */ | 2353 | same size. */ |
| 2379 | if (ASIZE (o2) != size) | 2354 | if (ASIZE (o2) != size) |
| 2380 | return false; | 2355 | return false; |
| 2356 | if (BIGNUMP (o1)) | ||
| 2357 | return mpz_cmp (XBIGNUM (o1)->value, XBIGNUM (o2)->value) == 0; | ||
| 2358 | if (OVERLAYP (o1)) | ||
| 2359 | { | ||
| 2360 | if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o2), | ||
| 2361 | equal_kind, depth + 1, ht) | ||
| 2362 | || !internal_equal (OVERLAY_END (o1), OVERLAY_END (o2), | ||
| 2363 | equal_kind, depth + 1, ht)) | ||
| 2364 | return false; | ||
| 2365 | o1 = XOVERLAY (o1)->plist; | ||
| 2366 | o2 = XOVERLAY (o2)->plist; | ||
| 2367 | depth++; | ||
| 2368 | goto tail_recurse; | ||
| 2369 | } | ||
| 2370 | if (MARKERP (o1)) | ||
| 2371 | { | ||
| 2372 | return (XMARKER (o1)->buffer == XMARKER (o2)->buffer | ||
| 2373 | && (XMARKER (o1)->buffer == 0 | ||
| 2374 | || XMARKER (o1)->bytepos == XMARKER (o2)->bytepos)); | ||
| 2375 | } | ||
| 2381 | /* Boolvectors are compared much like strings. */ | 2376 | /* Boolvectors are compared much like strings. */ |
| 2382 | if (BOOL_VECTOR_P (o1)) | 2377 | if (BOOL_VECTOR_P (o1)) |
| 2383 | { | 2378 | { |
| @@ -4477,13 +4472,6 @@ sxhash (Lisp_Object obj, int depth) | |||
| 4477 | hash = XUFIXNUM (obj); | 4472 | hash = XUFIXNUM (obj); |
| 4478 | break; | 4473 | break; |
| 4479 | 4474 | ||
| 4480 | case Lisp_Misc: | ||
| 4481 | if (XMISCTYPE (obj) == Lisp_Misc_Bignum) | ||
| 4482 | { | ||
| 4483 | hash = sxhash_bignum (XBIGNUM (obj)); | ||
| 4484 | break; | ||
| 4485 | } | ||
| 4486 | FALLTHROUGH; | ||
| 4487 | case Lisp_Symbol: | 4475 | case Lisp_Symbol: |
| 4488 | hash = XHASH (obj); | 4476 | hash = XHASH (obj); |
| 4489 | break; | 4477 | break; |
| @@ -4494,7 +4482,9 @@ sxhash (Lisp_Object obj, int depth) | |||
| 4494 | 4482 | ||
| 4495 | /* This can be everything from a vector to an overlay. */ | 4483 | /* This can be everything from a vector to an overlay. */ |
| 4496 | case Lisp_Vectorlike: | 4484 | case Lisp_Vectorlike: |
| 4497 | if (VECTORP (obj) || RECORDP (obj)) | 4485 | if (BIGNUMP (obj)) |
| 4486 | hash = sxhash_bignum (XBIGNUM (obj)); | ||
| 4487 | else if (VECTORP (obj) || RECORDP (obj)) | ||
| 4498 | /* According to the CL HyperSpec, two arrays are equal only if | 4488 | /* According to the CL HyperSpec, two arrays are equal only if |
| 4499 | they are `eq', except for strings and bit-vectors. In | 4489 | they are `eq', except for strings and bit-vectors. In |
| 4500 | Emacs, this works differently. We have to compare element | 4490 | Emacs, this works differently. We have to compare element |
diff --git a/src/lisp.h b/src/lisp.h index 6ca34168928..c080cc6b146 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -365,8 +365,6 @@ typedef EMACS_INT Lisp_Word; | |||
| 365 | #define lisp_h_EQ(x, y) (XLI (x) == XLI (y)) | 365 | #define lisp_h_EQ(x, y) (XLI (x) == XLI (y)) |
| 366 | #define lisp_h_FLOATP(x) (XTYPE (x) == Lisp_Float) | 366 | #define lisp_h_FLOATP(x) (XTYPE (x) == Lisp_Float) |
| 367 | #define lisp_h_FIXNUMP(x) ((XTYPE (x) & (Lisp_Int0 | ~Lisp_Int1)) == Lisp_Int0) | 367 | #define lisp_h_FIXNUMP(x) ((XTYPE (x) & (Lisp_Int0 | ~Lisp_Int1)) == Lisp_Int0) |
| 368 | #define lisp_h_MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker) | ||
| 369 | #define lisp_h_MISCP(x) (XTYPE (x) == Lisp_Misc) | ||
| 370 | #define lisp_h_NILP(x) EQ (x, Qnil) | 368 | #define lisp_h_NILP(x) EQ (x, Qnil) |
| 371 | #define lisp_h_SET_SYMBOL_VAL(sym, v) \ | 369 | #define lisp_h_SET_SYMBOL_VAL(sym, v) \ |
| 372 | (eassert ((sym)->u.s.redirect == SYMBOL_PLAINVAL), \ | 370 | (eassert ((sym)->u.s.redirect == SYMBOL_PLAINVAL), \ |
| @@ -430,8 +428,6 @@ typedef EMACS_INT Lisp_Word; | |||
| 430 | # define EQ(x, y) lisp_h_EQ (x, y) | 428 | # define EQ(x, y) lisp_h_EQ (x, y) |
| 431 | # define FLOATP(x) lisp_h_FLOATP (x) | 429 | # define FLOATP(x) lisp_h_FLOATP (x) |
| 432 | # define FIXNUMP(x) lisp_h_FIXNUMP (x) | 430 | # define FIXNUMP(x) lisp_h_FIXNUMP (x) |
| 433 | # define MARKERP(x) lisp_h_MARKERP (x) | ||
| 434 | # define MISCP(x) lisp_h_MISCP (x) | ||
| 435 | # define NILP(x) lisp_h_NILP (x) | 431 | # define NILP(x) lisp_h_NILP (x) |
| 436 | # define SET_SYMBOL_VAL(sym, v) lisp_h_SET_SYMBOL_VAL (sym, v) | 432 | # define SET_SYMBOL_VAL(sym, v) lisp_h_SET_SYMBOL_VAL (sym, v) |
| 437 | # define SYMBOL_CONSTANT_P(sym) lisp_h_SYMBOL_CONSTANT_P (sym) | 433 | # define SYMBOL_CONSTANT_P(sym) lisp_h_SYMBOL_CONSTANT_P (sym) |
| @@ -482,11 +478,9 @@ enum Lisp_Type | |||
| 482 | /* Symbol. XSYMBOL (object) points to a struct Lisp_Symbol. */ | 478 | /* Symbol. XSYMBOL (object) points to a struct Lisp_Symbol. */ |
| 483 | Lisp_Symbol = 0, | 479 | Lisp_Symbol = 0, |
| 484 | 480 | ||
| 485 | /* Miscellaneous. XMISC (object) points to a union Lisp_Misc, | 481 | /* Type 1 is currently unused. */ |
| 486 | whose first member indicates the subtype. */ | ||
| 487 | Lisp_Misc = 1, | ||
| 488 | 482 | ||
| 489 | /* Integer. XFIXNUM (obj) is the integer value. */ | 483 | /* Fixnum. XFIXNUM (obj) is the integer value. */ |
| 490 | Lisp_Int0 = 2, | 484 | Lisp_Int0 = 2, |
| 491 | Lisp_Int1 = USE_LSB_TAG ? 6 : 3, | 485 | Lisp_Int1 = USE_LSB_TAG ? 6 : 3, |
| 492 | 486 | ||
| @@ -506,26 +500,6 @@ enum Lisp_Type | |||
| 506 | Lisp_Float = 7 | 500 | Lisp_Float = 7 |
| 507 | }; | 501 | }; |
| 508 | 502 | ||
| 509 | /* This is the set of data types that share a common structure. | ||
| 510 | The first member of the structure is a type code from this set. | ||
| 511 | The enum values are arbitrary, but we'll use large numbers to make it | ||
| 512 | more likely that we'll spot the error if a random word in memory is | ||
| 513 | mistakenly interpreted as a Lisp_Misc. */ | ||
| 514 | enum Lisp_Misc_Type | ||
| 515 | { | ||
| 516 | Lisp_Misc_Free = 0x5eab, | ||
| 517 | Lisp_Misc_Marker, | ||
| 518 | Lisp_Misc_Overlay, | ||
| 519 | Lisp_Misc_Finalizer, | ||
| 520 | Lisp_Misc_Ptr, | ||
| 521 | #ifdef HAVE_MODULES | ||
| 522 | Lisp_Misc_User_Ptr, | ||
| 523 | #endif | ||
| 524 | Lisp_Misc_Bignum, | ||
| 525 | /* This is not a type code. It is for range checking. */ | ||
| 526 | Lisp_Misc_Limit | ||
| 527 | }; | ||
| 528 | |||
| 529 | /* These are the types of forwarding objects used in the value slot | 503 | /* These are the types of forwarding objects used in the value slot |
| 530 | of symbols for special built-in variables whose value is stored in | 504 | of symbols for special built-in variables whose value is stored in |
| 531 | C variables. */ | 505 | C variables. */ |
| @@ -539,14 +513,12 @@ enum Lisp_Fwd_Type | |||
| 539 | }; | 513 | }; |
| 540 | 514 | ||
| 541 | /* If you want to define a new Lisp data type, here are some | 515 | /* If you want to define a new Lisp data type, here are some |
| 542 | instructions. See the thread at | 516 | instructions. |
| 543 | https://lists.gnu.org/r/emacs-devel/2012-10/msg00561.html | ||
| 544 | for more info. | ||
| 545 | 517 | ||
| 546 | First, there are already a couple of Lisp types that can be used if | 518 | First, there are already a couple of Lisp types that can be used if |
| 547 | your new type does not need to be exposed to Lisp programs nor | 519 | your new type does not need to be exposed to Lisp programs nor |
| 548 | displayed to users. These are Lisp_Misc_Ptr, a Lisp_Misc | 520 | displayed to users. These are Lisp_Misc_Ptr and PVEC_OTHER, |
| 549 | subtype; and PVEC_OTHER, a kind of vectorlike object. The former | 521 | which are both vectorlike objects. The former |
| 550 | is suitable for stashing a pointer in a Lisp object; the pointer | 522 | is suitable for stashing a pointer in a Lisp object; the pointer |
| 551 | might be to some low-level C object that contains auxiliary | 523 | might be to some low-level C object that contains auxiliary |
| 552 | information. The latter is useful for vector-like Lisp objects | 524 | information. The latter is useful for vector-like Lisp objects |
| @@ -557,30 +529,14 @@ enum Lisp_Fwd_Type | |||
| 557 | These two types don't look pretty when printed, so they are | 529 | These two types don't look pretty when printed, so they are |
| 558 | unsuitable for Lisp objects that can be exposed to users. | 530 | unsuitable for Lisp objects that can be exposed to users. |
| 559 | 531 | ||
| 560 | To define a new data type, add one more Lisp_Misc subtype or one | 532 | To define a new data type, add a pseudovector subtype by extending |
| 561 | more pseudovector subtype. Pseudovectors are more suitable for | 533 | the pvec_type enumeration. A pseudovector provides one or more |
| 562 | objects with several slots that need to support fast random access, | 534 | slots for Lisp objects, followed by struct members that are |
| 563 | while Lisp_Misc types are for everything else. A pseudovector object | 535 | accessible only from C. |
| 564 | provides one or more slots for Lisp objects, followed by struct | ||
| 565 | members that are accessible only from C. A Lisp_Misc object is a | ||
| 566 | wrapper for a C struct that can contain anything you like. | ||
| 567 | 536 | ||
| 568 | There is no way to explicitly free a Lisp Object; only the garbage | 537 | There is no way to explicitly free a Lisp Object; only the garbage |
| 569 | collector frees them. | 538 | collector frees them. |
| 570 | 539 | ||
| 571 | To add a new pseudovector type, extend the pvec_type enumeration; | ||
| 572 | to add a new Lisp_Misc, extend the Lisp_Misc_Type enumeration. | ||
| 573 | |||
| 574 | For a Lisp_Misc, you will also need to add your entry to union | ||
| 575 | Lisp_Misc, but make sure the first word has the same structure as | ||
| 576 | the others, starting with a 16-bit member of the Lisp_Misc_Type | ||
| 577 | enumeration and a 1-bit GC markbit. Also make sure the overall | ||
| 578 | size of the union is not increased by your addition. The latter | ||
| 579 | requirement is to keep Lisp_Misc objects small enough, so they | ||
| 580 | are handled faster: since all Lisp_Misc types use the same space, | ||
| 581 | enlarging any of them will affect all the rest. If you really | ||
| 582 | need a larger object, it is best to use Lisp_Vectorlike instead. | ||
| 583 | |||
| 584 | For a new pseudovector, it's highly desirable to limit the size | 540 | For a new pseudovector, it's highly desirable to limit the size |
| 585 | of your data type by VBLOCK_BYTES_MAX bytes (defined in alloc.c). | 541 | of your data type by VBLOCK_BYTES_MAX bytes (defined in alloc.c). |
| 586 | Otherwise you will need to change sweep_vectors (also in alloc.c). | 542 | Otherwise you will need to change sweep_vectors (also in alloc.c). |
| @@ -973,6 +929,14 @@ enum pvec_type | |||
| 973 | { | 929 | { |
| 974 | PVEC_NORMAL_VECTOR, | 930 | PVEC_NORMAL_VECTOR, |
| 975 | PVEC_FREE, | 931 | PVEC_FREE, |
| 932 | PVEC_BIGNUM, | ||
| 933 | PVEC_MARKER, | ||
| 934 | PVEC_OVERLAY, | ||
| 935 | PVEC_FINALIZER, | ||
| 936 | PVEC_MISC_PTR, | ||
| 937 | #ifdef HAVE_MODULES | ||
| 938 | PVEC_USER_PTR, | ||
| 939 | #endif | ||
| 976 | PVEC_PROCESS, | 940 | PVEC_PROCESS, |
| 977 | PVEC_FRAME, | 941 | PVEC_FRAME, |
| 978 | PVEC_WINDOW, | 942 | PVEC_WINDOW, |
| @@ -1173,7 +1137,6 @@ INLINE bool | |||
| 1173 | #define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String)) | 1137 | #define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String)) |
| 1174 | #define XSETSYMBOL(a, b) ((a) = make_lisp_symbol (b)) | 1138 | #define XSETSYMBOL(a, b) ((a) = make_lisp_symbol (b)) |
| 1175 | #define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float)) | 1139 | #define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float)) |
| 1176 | #define XSETMISC(a, b) ((a) = make_lisp_ptr (b, Lisp_Misc)) | ||
| 1177 | 1140 | ||
| 1178 | /* Pseudovector types. */ | 1141 | /* Pseudovector types. */ |
| 1179 | 1142 | ||
| @@ -2273,46 +2236,10 @@ SXHASH_REDUCE (EMACS_UINT x) | |||
| 2273 | return (x ^ x >> (EMACS_INT_WIDTH - FIXNUM_BITS)) & INTMASK; | 2236 | return (x ^ x >> (EMACS_INT_WIDTH - FIXNUM_BITS)) & INTMASK; |
| 2274 | } | 2237 | } |
| 2275 | 2238 | ||
| 2276 | /* These structures are used for various misc types. */ | ||
| 2277 | |||
| 2278 | struct Lisp_Misc_Any /* Supertype of all Misc types. */ | ||
| 2279 | { | ||
| 2280 | ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_??? */ | ||
| 2281 | bool_bf gcmarkbit : 1; | ||
| 2282 | unsigned spacer : 15; | ||
| 2283 | }; | ||
| 2284 | |||
| 2285 | INLINE bool | ||
| 2286 | (MISCP) (Lisp_Object x) | ||
| 2287 | { | ||
| 2288 | return lisp_h_MISCP (x); | ||
| 2289 | } | ||
| 2290 | |||
| 2291 | INLINE struct Lisp_Misc_Any * | ||
| 2292 | XMISCANY (Lisp_Object a) | ||
| 2293 | { | ||
| 2294 | eassert (MISCP (a)); | ||
| 2295 | return XUNTAG (a, Lisp_Misc, struct Lisp_Misc_Any); | ||
| 2296 | } | ||
| 2297 | |||
| 2298 | INLINE enum Lisp_Misc_Type | ||
| 2299 | XMISCTYPE (Lisp_Object a) | ||
| 2300 | { | ||
| 2301 | return XMISCANY (a)->type; | ||
| 2302 | } | ||
| 2303 | |||
| 2304 | struct Lisp_Marker | 2239 | struct Lisp_Marker |
| 2305 | { | 2240 | { |
| 2306 | ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Marker */ | 2241 | union vectorlike_header header; |
| 2307 | bool_bf gcmarkbit : 1; | 2242 | |
| 2308 | unsigned spacer : 13; | ||
| 2309 | /* This flag is temporarily used in the functions | ||
| 2310 | decode/encode_coding_object to record that the marker position | ||
| 2311 | must be adjusted after the conversion. */ | ||
| 2312 | bool_bf need_adjustment : 1; | ||
| 2313 | /* True means normal insertion at the marker's position | ||
| 2314 | leaves the marker after the inserted text. */ | ||
| 2315 | bool_bf insertion_type : 1; | ||
| 2316 | /* This is the buffer that the marker points into, or 0 if it points nowhere. | 2243 | /* This is the buffer that the marker points into, or 0 if it points nowhere. |
| 2317 | Note: a chain of markers can contain markers pointing into different | 2244 | Note: a chain of markers can contain markers pointing into different |
| 2318 | buffers (the chain is per buffer_text rather than per buffer, so it's | 2245 | buffers (the chain is per buffer_text rather than per buffer, so it's |
| @@ -2325,6 +2252,14 @@ struct Lisp_Marker | |||
| 2325 | */ | 2252 | */ |
| 2326 | struct buffer *buffer; | 2253 | struct buffer *buffer; |
| 2327 | 2254 | ||
| 2255 | /* This flag is temporarily used in the functions | ||
| 2256 | decode/encode_coding_object to record that the marker position | ||
| 2257 | must be adjusted after the conversion. */ | ||
| 2258 | bool_bf need_adjustment : 1; | ||
| 2259 | /* True means normal insertion at the marker's position | ||
| 2260 | leaves the marker after the inserted text. */ | ||
| 2261 | bool_bf insertion_type : 1; | ||
| 2262 | |||
| 2328 | /* The remaining fields are meaningless in a marker that | 2263 | /* The remaining fields are meaningless in a marker that |
| 2329 | does not point anywhere. */ | 2264 | does not point anywhere. */ |
| 2330 | 2265 | ||
| @@ -2357,20 +2292,16 @@ struct Lisp_Overlay | |||
| 2357 | I.e. 9words plus 2 bits, 3words of which are for external linked lists. | 2292 | I.e. 9words plus 2 bits, 3words of which are for external linked lists. |
| 2358 | */ | 2293 | */ |
| 2359 | { | 2294 | { |
| 2360 | ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Overlay */ | 2295 | union vectorlike_header header; |
| 2361 | bool_bf gcmarkbit : 1; | ||
| 2362 | unsigned spacer : 15; | ||
| 2363 | struct Lisp_Overlay *next; | ||
| 2364 | Lisp_Object start; | 2296 | Lisp_Object start; |
| 2365 | Lisp_Object end; | 2297 | Lisp_Object end; |
| 2366 | Lisp_Object plist; | 2298 | Lisp_Object plist; |
| 2299 | struct Lisp_Overlay *next; | ||
| 2367 | }; | 2300 | }; |
| 2368 | 2301 | ||
| 2369 | struct Lisp_Misc_Ptr | 2302 | struct Lisp_Misc_Ptr |
| 2370 | { | 2303 | { |
| 2371 | ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Ptr */ | 2304 | union vectorlike_header header; |
| 2372 | bool_bf gcmarkbit : 1; | ||
| 2373 | unsigned spacer : 15; | ||
| 2374 | void *pointer; | 2305 | void *pointer; |
| 2375 | }; | 2306 | }; |
| 2376 | 2307 | ||
| @@ -2388,7 +2319,7 @@ extern Lisp_Object make_misc_ptr (void *); | |||
| 2388 | C code, it should not be given a mint_ptr generated from Lisp code | 2319 | C code, it should not be given a mint_ptr generated from Lisp code |
| 2389 | as that would allow Lisp code to coin pointers from integers and | 2320 | as that would allow Lisp code to coin pointers from integers and |
| 2390 | could lead to crashes. To package a C pointer into a Lisp-visible | 2321 | could lead to crashes. To package a C pointer into a Lisp-visible |
| 2391 | object you can put the pointer into a Lisp_Misc object instead; see | 2322 | object you can put the pointer into a pseudovector instead; see |
| 2392 | Lisp_User_Ptr for an example. */ | 2323 | Lisp_User_Ptr for an example. */ |
| 2393 | 2324 | ||
| 2394 | INLINE Lisp_Object | 2325 | INLINE Lisp_Object |
| @@ -2401,7 +2332,7 @@ make_mint_ptr (void *a) | |||
| 2401 | INLINE bool | 2332 | INLINE bool |
| 2402 | mint_ptrp (Lisp_Object x) | 2333 | mint_ptrp (Lisp_Object x) |
| 2403 | { | 2334 | { |
| 2404 | return FIXNUMP (x) || (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Ptr); | 2335 | return FIXNUMP (x) || PSEUDOVECTORP (x, PVEC_MISC_PTR); |
| 2405 | } | 2336 | } |
| 2406 | 2337 | ||
| 2407 | INLINE void * | 2338 | INLINE void * |
| @@ -2410,16 +2341,13 @@ xmint_pointer (Lisp_Object a) | |||
| 2410 | eassert (mint_ptrp (a)); | 2341 | eassert (mint_ptrp (a)); |
| 2411 | if (FIXNUMP (a)) | 2342 | if (FIXNUMP (a)) |
| 2412 | return XFIXNUMPTR (a); | 2343 | return XFIXNUMPTR (a); |
| 2413 | return XUNTAG (a, Lisp_Misc, struct Lisp_Misc_Ptr)->pointer; | 2344 | return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Misc_Ptr)->pointer; |
| 2414 | } | 2345 | } |
| 2415 | 2346 | ||
| 2416 | #ifdef HAVE_MODULES | 2347 | #ifdef HAVE_MODULES |
| 2417 | struct Lisp_User_Ptr | 2348 | struct Lisp_User_Ptr |
| 2418 | { | 2349 | { |
| 2419 | ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_User_Ptr */ | 2350 | union vectorlike_header header; |
| 2420 | bool_bf gcmarkbit : 1; | ||
| 2421 | unsigned spacer : 15; | ||
| 2422 | |||
| 2423 | void (*finalizer) (void *); | 2351 | void (*finalizer) (void *); |
| 2424 | void *p; | 2352 | void *p; |
| 2425 | }; | 2353 | }; |
| @@ -2428,123 +2356,89 @@ struct Lisp_User_Ptr | |||
| 2428 | /* A finalizer sentinel. */ | 2356 | /* A finalizer sentinel. */ |
| 2429 | struct Lisp_Finalizer | 2357 | struct Lisp_Finalizer |
| 2430 | { | 2358 | { |
| 2431 | struct Lisp_Misc_Any base; | 2359 | union vectorlike_header header; |
| 2432 | |||
| 2433 | /* Circular list of all active weak references. */ | ||
| 2434 | struct Lisp_Finalizer *prev; | ||
| 2435 | struct Lisp_Finalizer *next; | ||
| 2436 | 2360 | ||
| 2437 | /* Call FUNCTION when the finalizer becomes unreachable, even if | 2361 | /* Call FUNCTION when the finalizer becomes unreachable, even if |
| 2438 | FUNCTION contains a reference to the finalizer; i.e., call | 2362 | FUNCTION contains a reference to the finalizer; i.e., call |
| 2439 | FUNCTION when it is reachable _only_ through finalizers. */ | 2363 | FUNCTION when it is reachable _only_ through finalizers. */ |
| 2440 | Lisp_Object function; | 2364 | Lisp_Object function; |
| 2365 | |||
| 2366 | /* Circular list of all active weak references. */ | ||
| 2367 | struct Lisp_Finalizer *prev; | ||
| 2368 | struct Lisp_Finalizer *next; | ||
| 2441 | }; | 2369 | }; |
| 2442 | 2370 | ||
| 2443 | INLINE bool | 2371 | INLINE bool |
| 2444 | FINALIZERP (Lisp_Object x) | 2372 | FINALIZERP (Lisp_Object x) |
| 2445 | { | 2373 | { |
| 2446 | return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Finalizer; | 2374 | return PSEUDOVECTORP (x, PVEC_FINALIZER); |
| 2447 | } | 2375 | } |
| 2448 | 2376 | ||
| 2449 | INLINE struct Lisp_Finalizer * | 2377 | INLINE struct Lisp_Finalizer * |
| 2450 | XFINALIZER (Lisp_Object a) | 2378 | XFINALIZER (Lisp_Object a) |
| 2451 | { | 2379 | { |
| 2452 | eassert (FINALIZERP (a)); | 2380 | eassert (FINALIZERP (a)); |
| 2453 | return XUNTAG (a, Lisp_Misc, struct Lisp_Finalizer); | 2381 | return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Finalizer); |
| 2454 | } | ||
| 2455 | |||
| 2456 | /* A miscellaneous object, when it's on the free list. */ | ||
| 2457 | struct Lisp_Free | ||
| 2458 | { | ||
| 2459 | ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Free */ | ||
| 2460 | bool_bf gcmarkbit : 1; | ||
| 2461 | unsigned spacer : 15; | ||
| 2462 | union Lisp_Misc *chain; | ||
| 2463 | }; | ||
| 2464 | |||
| 2465 | struct Lisp_Bignum | ||
| 2466 | { | ||
| 2467 | ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Bignum */ | ||
| 2468 | bool_bf gcmarkbit : 1; | ||
| 2469 | unsigned spacer : 15; | ||
| 2470 | mpz_t value; | ||
| 2471 | }; | ||
| 2472 | |||
| 2473 | /* To get the type field of a union Lisp_Misc, use XMISCTYPE. | ||
| 2474 | It uses one of these struct subtypes to get the type field. */ | ||
| 2475 | |||
| 2476 | union Lisp_Misc | ||
| 2477 | { | ||
| 2478 | struct Lisp_Misc_Any u_any; /* Supertype of all Misc types. */ | ||
| 2479 | struct Lisp_Free u_free; | ||
| 2480 | struct Lisp_Marker u_marker; | ||
| 2481 | struct Lisp_Overlay u_overlay; | ||
| 2482 | struct Lisp_Finalizer u_finalizer; | ||
| 2483 | struct Lisp_Misc_Ptr u_misc_ptr; | ||
| 2484 | #ifdef HAVE_MODULES | ||
| 2485 | struct Lisp_User_Ptr u_user_ptr; | ||
| 2486 | #endif | ||
| 2487 | struct Lisp_Bignum u_bignum; | ||
| 2488 | }; | ||
| 2489 | |||
| 2490 | INLINE union Lisp_Misc * | ||
| 2491 | XMISC (Lisp_Object a) | ||
| 2492 | { | ||
| 2493 | return XUNTAG (a, Lisp_Misc, union Lisp_Misc); | ||
| 2494 | } | 2382 | } |
| 2495 | 2383 | ||
| 2496 | INLINE bool | 2384 | INLINE bool |
| 2497 | (MARKERP) (Lisp_Object x) | 2385 | MARKERP (Lisp_Object x) |
| 2498 | { | 2386 | { |
| 2499 | return lisp_h_MARKERP (x); | 2387 | return PSEUDOVECTORP (x, PVEC_MARKER); |
| 2500 | } | 2388 | } |
| 2501 | 2389 | ||
| 2502 | INLINE struct Lisp_Marker * | 2390 | INLINE struct Lisp_Marker * |
| 2503 | XMARKER (Lisp_Object a) | 2391 | XMARKER (Lisp_Object a) |
| 2504 | { | 2392 | { |
| 2505 | eassert (MARKERP (a)); | 2393 | eassert (MARKERP (a)); |
| 2506 | return XUNTAG (a, Lisp_Misc, struct Lisp_Marker); | 2394 | return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Marker); |
| 2507 | } | 2395 | } |
| 2508 | 2396 | ||
| 2509 | INLINE bool | 2397 | INLINE bool |
| 2510 | OVERLAYP (Lisp_Object x) | 2398 | OVERLAYP (Lisp_Object x) |
| 2511 | { | 2399 | { |
| 2512 | return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay; | 2400 | return PSEUDOVECTORP (x, PVEC_OVERLAY); |
| 2513 | } | 2401 | } |
| 2514 | 2402 | ||
| 2515 | INLINE struct Lisp_Overlay * | 2403 | INLINE struct Lisp_Overlay * |
| 2516 | XOVERLAY (Lisp_Object a) | 2404 | XOVERLAY (Lisp_Object a) |
| 2517 | { | 2405 | { |
| 2518 | eassert (OVERLAYP (a)); | 2406 | eassert (OVERLAYP (a)); |
| 2519 | return XUNTAG (a, Lisp_Misc, struct Lisp_Overlay); | 2407 | return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Overlay); |
| 2520 | } | 2408 | } |
| 2521 | 2409 | ||
| 2522 | #ifdef HAVE_MODULES | 2410 | #ifdef HAVE_MODULES |
| 2523 | INLINE bool | 2411 | INLINE bool |
| 2524 | USER_PTRP (Lisp_Object x) | 2412 | USER_PTRP (Lisp_Object x) |
| 2525 | { | 2413 | { |
| 2526 | return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_User_Ptr; | 2414 | return PSEUDOVECTORP (x, PVEC_USER_PTR); |
| 2527 | } | 2415 | } |
| 2528 | 2416 | ||
| 2529 | INLINE struct Lisp_User_Ptr * | 2417 | INLINE struct Lisp_User_Ptr * |
| 2530 | XUSER_PTR (Lisp_Object a) | 2418 | XUSER_PTR (Lisp_Object a) |
| 2531 | { | 2419 | { |
| 2532 | eassert (USER_PTRP (a)); | 2420 | eassert (USER_PTRP (a)); |
| 2533 | return XUNTAG (a, Lisp_Misc, struct Lisp_User_Ptr); | 2421 | return XUNTAG (a, Lisp_Vectorlike, struct Lisp_User_Ptr); |
| 2534 | } | 2422 | } |
| 2535 | #endif | 2423 | #endif |
| 2536 | 2424 | ||
| 2425 | struct Lisp_Bignum | ||
| 2426 | { | ||
| 2427 | union vectorlike_header header; | ||
| 2428 | mpz_t value; | ||
| 2429 | }; | ||
| 2430 | |||
| 2537 | INLINE bool | 2431 | INLINE bool |
| 2538 | BIGNUMP (Lisp_Object x) | 2432 | BIGNUMP (Lisp_Object x) |
| 2539 | { | 2433 | { |
| 2540 | return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Bignum; | 2434 | return PSEUDOVECTORP (x, PVEC_BIGNUM); |
| 2541 | } | 2435 | } |
| 2542 | 2436 | ||
| 2543 | INLINE struct Lisp_Bignum * | 2437 | INLINE struct Lisp_Bignum * |
| 2544 | XBIGNUM (Lisp_Object a) | 2438 | XBIGNUM (Lisp_Object a) |
| 2545 | { | 2439 | { |
| 2546 | eassert (BIGNUMP (a)); | 2440 | eassert (BIGNUMP (a)); |
| 2547 | return XUNTAG (a, Lisp_Misc, struct Lisp_Bignum); | 2441 | return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Bignum); |
| 2548 | } | 2442 | } |
| 2549 | 2443 | ||
| 2550 | INLINE bool | 2444 | INLINE bool |
diff --git a/src/print.c b/src/print.c index 3819c505b12..824f8d75779 100644 --- a/src/print.c +++ b/src/print.c | |||
| @@ -1367,6 +1367,76 @@ print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag, | |||
| 1367 | { | 1367 | { |
| 1368 | switch (PSEUDOVECTOR_TYPE (XVECTOR (obj))) | 1368 | switch (PSEUDOVECTOR_TYPE (XVECTOR (obj))) |
| 1369 | { | 1369 | { |
| 1370 | case PVEC_BIGNUM: | ||
| 1371 | { | ||
| 1372 | struct Lisp_Bignum *b = XBIGNUM (obj); | ||
| 1373 | char *str = mpz_get_str (NULL, 10, b->value); | ||
| 1374 | record_unwind_protect_ptr (xfree, str); | ||
| 1375 | print_c_string (str, printcharfun); | ||
| 1376 | } | ||
| 1377 | break; | ||
| 1378 | |||
| 1379 | case PVEC_MARKER: | ||
| 1380 | print_c_string ("#<marker ", printcharfun); | ||
| 1381 | /* Do you think this is necessary? */ | ||
| 1382 | if (XMARKER (obj)->insertion_type != 0) | ||
| 1383 | print_c_string ("(moves after insertion) ", printcharfun); | ||
| 1384 | if (! XMARKER (obj)->buffer) | ||
| 1385 | print_c_string ("in no buffer", printcharfun); | ||
| 1386 | else | ||
| 1387 | { | ||
| 1388 | int len = sprintf (buf, "at %"pD"d in ", marker_position (obj)); | ||
| 1389 | strout (buf, len, len, printcharfun); | ||
| 1390 | print_string (BVAR (XMARKER (obj)->buffer, name), printcharfun); | ||
| 1391 | } | ||
| 1392 | printchar ('>', printcharfun); | ||
| 1393 | break; | ||
| 1394 | |||
| 1395 | case PVEC_OVERLAY: | ||
| 1396 | print_c_string ("#<overlay ", printcharfun); | ||
| 1397 | if (! XMARKER (OVERLAY_START (obj))->buffer) | ||
| 1398 | print_c_string ("in no buffer", printcharfun); | ||
| 1399 | else | ||
| 1400 | { | ||
| 1401 | int len = sprintf (buf, "from %"pD"d to %"pD"d in ", | ||
| 1402 | marker_position (OVERLAY_START (obj)), | ||
| 1403 | marker_position (OVERLAY_END (obj))); | ||
| 1404 | strout (buf, len, len, printcharfun); | ||
| 1405 | print_string (BVAR (XMARKER (OVERLAY_START (obj))->buffer, name), | ||
| 1406 | printcharfun); | ||
| 1407 | } | ||
| 1408 | printchar ('>', printcharfun); | ||
| 1409 | break; | ||
| 1410 | |||
| 1411 | #ifdef HAVE_MODULES | ||
| 1412 | case PVEC_USER_PTR: | ||
| 1413 | { | ||
| 1414 | print_c_string ("#<user-ptr ", printcharfun); | ||
| 1415 | int i = sprintf (buf, "ptr=%p finalizer=%p", | ||
| 1416 | XUSER_PTR (obj)->p, | ||
| 1417 | XUSER_PTR (obj)->finalizer); | ||
| 1418 | strout (buf, i, i, printcharfun); | ||
| 1419 | printchar ('>', printcharfun); | ||
| 1420 | } | ||
| 1421 | break; | ||
| 1422 | #endif | ||
| 1423 | |||
| 1424 | case PVEC_FINALIZER: | ||
| 1425 | print_c_string ("#<finalizer", printcharfun); | ||
| 1426 | if (NILP (XFINALIZER (obj)->function)) | ||
| 1427 | print_c_string (" used", printcharfun); | ||
| 1428 | printchar ('>', printcharfun); | ||
| 1429 | break; | ||
| 1430 | |||
| 1431 | case PVEC_MISC_PTR: | ||
| 1432 | { | ||
| 1433 | /* This shouldn't happen in normal usage, but let's | ||
| 1434 | print it anyway for the benefit of the debugger. */ | ||
| 1435 | int i = sprintf (buf, "#<ptr %p>", xmint_pointer (obj)); | ||
| 1436 | strout (buf, i, i, printcharfun); | ||
| 1437 | } | ||
| 1438 | break; | ||
| 1439 | |||
| 1370 | case PVEC_PROCESS: | 1440 | case PVEC_PROCESS: |
| 1371 | if (escapeflag) | 1441 | if (escapeflag) |
| 1372 | { | 1442 | { |
| @@ -2096,103 +2166,16 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) | |||
| 2096 | break; | 2166 | break; |
| 2097 | 2167 | ||
| 2098 | case Lisp_Vectorlike: | 2168 | case Lisp_Vectorlike: |
| 2099 | if (! print_vectorlike (obj, printcharfun, escapeflag, buf)) | 2169 | if (print_vectorlike (obj, printcharfun, escapeflag, buf)) |
| 2100 | goto badtype; | 2170 | break; |
| 2101 | break; | 2171 | FALLTHROUGH; |
| 2102 | |||
| 2103 | case Lisp_Misc: | ||
| 2104 | switch (XMISCTYPE (obj)) | ||
| 2105 | { | ||
| 2106 | case Lisp_Misc_Marker: | ||
| 2107 | print_c_string ("#<marker ", printcharfun); | ||
| 2108 | /* Do you think this is necessary? */ | ||
| 2109 | if (XMARKER (obj)->insertion_type != 0) | ||
| 2110 | print_c_string ("(moves after insertion) ", printcharfun); | ||
| 2111 | if (! XMARKER (obj)->buffer) | ||
| 2112 | print_c_string ("in no buffer", printcharfun); | ||
| 2113 | else | ||
| 2114 | { | ||
| 2115 | int len = sprintf (buf, "at %"pD"d in ", marker_position (obj)); | ||
| 2116 | strout (buf, len, len, printcharfun); | ||
| 2117 | print_string (BVAR (XMARKER (obj)->buffer, name), printcharfun); | ||
| 2118 | } | ||
| 2119 | printchar ('>', printcharfun); | ||
| 2120 | break; | ||
| 2121 | |||
| 2122 | case Lisp_Misc_Overlay: | ||
| 2123 | print_c_string ("#<overlay ", printcharfun); | ||
| 2124 | if (! XMARKER (OVERLAY_START (obj))->buffer) | ||
| 2125 | print_c_string ("in no buffer", printcharfun); | ||
| 2126 | else | ||
| 2127 | { | ||
| 2128 | int len = sprintf (buf, "from %"pD"d to %"pD"d in ", | ||
| 2129 | marker_position (OVERLAY_START (obj)), | ||
| 2130 | marker_position (OVERLAY_END (obj))); | ||
| 2131 | strout (buf, len, len, printcharfun); | ||
| 2132 | print_string (BVAR (XMARKER (OVERLAY_START (obj))->buffer, name), | ||
| 2133 | printcharfun); | ||
| 2134 | } | ||
| 2135 | printchar ('>', printcharfun); | ||
| 2136 | break; | ||
| 2137 | |||
| 2138 | #ifdef HAVE_MODULES | ||
| 2139 | case Lisp_Misc_User_Ptr: | ||
| 2140 | { | ||
| 2141 | print_c_string ("#<user-ptr ", printcharfun); | ||
| 2142 | int i = sprintf (buf, "ptr=%p finalizer=%p", | ||
| 2143 | XUSER_PTR (obj)->p, | ||
| 2144 | XUSER_PTR (obj)->finalizer); | ||
| 2145 | strout (buf, i, i, printcharfun); | ||
| 2146 | printchar ('>', printcharfun); | ||
| 2147 | break; | ||
| 2148 | } | ||
| 2149 | #endif | ||
| 2150 | |||
| 2151 | case Lisp_Misc_Finalizer: | ||
| 2152 | print_c_string ("#<finalizer", printcharfun); | ||
| 2153 | if (NILP (XFINALIZER (obj)->function)) | ||
| 2154 | print_c_string (" used", printcharfun); | ||
| 2155 | printchar ('>', printcharfun); | ||
| 2156 | break; | ||
| 2157 | |||
| 2158 | /* Remaining cases shouldn't happen in normal usage, but let's | ||
| 2159 | print them anyway for the benefit of the debugger. */ | ||
| 2160 | |||
| 2161 | case Lisp_Misc_Free: | ||
| 2162 | print_c_string ("#<misc free cell>", printcharfun); | ||
| 2163 | break; | ||
| 2164 | |||
| 2165 | case Lisp_Misc_Ptr: | ||
| 2166 | { | ||
| 2167 | int i = sprintf (buf, "#<ptr %p>", xmint_pointer (obj)); | ||
| 2168 | strout (buf, i, i, printcharfun); | ||
| 2169 | } | ||
| 2170 | break; | ||
| 2171 | |||
| 2172 | case Lisp_Misc_Bignum: | ||
| 2173 | { | ||
| 2174 | struct Lisp_Bignum *b = XBIGNUM (obj); | ||
| 2175 | char *str = mpz_get_str (NULL, 10, b->value); | ||
| 2176 | record_unwind_protect_ptr (xfree, str); | ||
| 2177 | print_c_string (str, printcharfun); | ||
| 2178 | } | ||
| 2179 | break; | ||
| 2180 | |||
| 2181 | default: | ||
| 2182 | goto badtype; | ||
| 2183 | } | ||
| 2184 | break; | ||
| 2185 | |||
| 2186 | default: | 2172 | default: |
| 2187 | badtype: | ||
| 2188 | { | 2173 | { |
| 2189 | int len; | 2174 | int len; |
| 2190 | /* We're in trouble if this happens! | 2175 | /* We're in trouble if this happens! |
| 2191 | Probably should just emacs_abort (). */ | 2176 | Probably should just emacs_abort (). */ |
| 2192 | print_c_string ("#<EMACS BUG: INVALID DATATYPE ", printcharfun); | 2177 | print_c_string ("#<EMACS BUG: INVALID DATATYPE ", printcharfun); |
| 2193 | if (MISCP (obj)) | 2178 | if (VECTORLIKEP (obj)) |
| 2194 | len = sprintf (buf, "(MISC 0x%04x)", (unsigned) XMISCTYPE (obj)); | ||
| 2195 | else if (VECTORLIKEP (obj)) | ||
| 2196 | len = sprintf (buf, "(PVEC 0x%08zx)", (size_t) ASIZE (obj)); | 2179 | len = sprintf (buf, "(PVEC 0x%08zx)", (size_t) ASIZE (obj)); |
| 2197 | else | 2180 | else |
| 2198 | len = sprintf (buf, "(0x%02x)", (unsigned) XTYPE (obj)); | 2181 | len = sprintf (buf, "(0x%02x)", (unsigned) XTYPE (obj)); |
diff --git a/src/undo.c b/src/undo.c index e80ec58ab09..1975e387e3f 100644 --- a/src/undo.c +++ b/src/undo.c | |||
| @@ -126,15 +126,11 @@ record_insert (ptrdiff_t beg, ptrdiff_t length) | |||
| 126 | static void | 126 | static void |
| 127 | record_marker_adjustments (ptrdiff_t from, ptrdiff_t to) | 127 | record_marker_adjustments (ptrdiff_t from, ptrdiff_t to) |
| 128 | { | 128 | { |
| 129 | Lisp_Object marker; | 129 | prepare_record (); |
| 130 | register struct Lisp_Marker *m; | ||
| 131 | register ptrdiff_t charpos, adjustment; | ||
| 132 | |||
| 133 | prepare_record(); | ||
| 134 | 130 | ||
| 135 | for (m = BUF_MARKERS (current_buffer); m; m = m->next) | 131 | for (struct Lisp_Marker *m = BUF_MARKERS (current_buffer); m; m = m->next) |
| 136 | { | 132 | { |
| 137 | charpos = m->charpos; | 133 | ptrdiff_t charpos = m->charpos; |
| 138 | eassert (charpos <= Z); | 134 | eassert (charpos <= Z); |
| 139 | 135 | ||
| 140 | if (from <= charpos && charpos <= to) | 136 | if (from <= charpos && charpos <= to) |
| @@ -146,11 +142,11 @@ record_marker_adjustments (ptrdiff_t from, ptrdiff_t to) | |||
| 146 | insertion_type t markers will automatically move forward | 142 | insertion_type t markers will automatically move forward |
| 147 | upon re-inserting the deleted text, so we have to arrange | 143 | upon re-inserting the deleted text, so we have to arrange |
| 148 | for them to move backward to the correct position. */ | 144 | for them to move backward to the correct position. */ |
| 149 | adjustment = (m->insertion_type ? to : from) - charpos; | 145 | ptrdiff_t adjustment = (m->insertion_type ? to : from) - charpos; |
| 150 | 146 | ||
| 151 | if (adjustment) | 147 | if (adjustment) |
| 152 | { | 148 | { |
| 153 | XSETMISC (marker, m); | 149 | Lisp_Object marker = make_lisp_ptr (m, Lisp_Vectorlike); |
| 154 | bset_undo_list | 150 | bset_undo_list |
| 155 | (current_buffer, | 151 | (current_buffer, |
| 156 | Fcons (Fcons (marker, make_fixnum (adjustment)), | 152 | Fcons (Fcons (marker, make_fixnum (adjustment)), |
diff --git a/src/xdisp.c b/src/xdisp.c index 76fde99f323..0835ccafd4d 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -5819,11 +5819,7 @@ compare_overlay_entries (const void *e1, const void *e2) | |||
| 5819 | static void | 5819 | static void |
| 5820 | load_overlay_strings (struct it *it, ptrdiff_t charpos) | 5820 | load_overlay_strings (struct it *it, ptrdiff_t charpos) |
| 5821 | { | 5821 | { |
| 5822 | Lisp_Object overlay, window, str, invisible; | 5822 | ptrdiff_t n = 0; |
| 5823 | struct Lisp_Overlay *ov; | ||
| 5824 | ptrdiff_t start, end; | ||
| 5825 | ptrdiff_t n = 0, i, j; | ||
| 5826 | int invis; | ||
| 5827 | struct overlay_entry entriesbuf[20]; | 5823 | struct overlay_entry entriesbuf[20]; |
| 5828 | ptrdiff_t size = ARRAYELTS (entriesbuf); | 5824 | ptrdiff_t size = ARRAYELTS (entriesbuf); |
| 5829 | struct overlay_entry *entries = entriesbuf; | 5825 | struct overlay_entry *entries = entriesbuf; |
| @@ -5859,12 +5855,13 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos) | |||
| 5859 | while (false) | 5855 | while (false) |
| 5860 | 5856 | ||
| 5861 | /* Process overlay before the overlay center. */ | 5857 | /* Process overlay before the overlay center. */ |
| 5862 | for (ov = current_buffer->overlays_before; ov; ov = ov->next) | 5858 | for (struct Lisp_Overlay *ov = current_buffer->overlays_before; |
| 5859 | ov; ov = ov->next) | ||
| 5863 | { | 5860 | { |
| 5864 | XSETMISC (overlay, ov); | 5861 | Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike); |
| 5865 | eassert (OVERLAYP (overlay)); | 5862 | eassert (OVERLAYP (overlay)); |
| 5866 | start = OVERLAY_POSITION (OVERLAY_START (overlay)); | 5863 | ptrdiff_t start = OVERLAY_POSITION (OVERLAY_START (overlay)); |
| 5867 | end = OVERLAY_POSITION (OVERLAY_END (overlay)); | 5864 | ptrdiff_t end = OVERLAY_POSITION (OVERLAY_END (overlay)); |
| 5868 | 5865 | ||
| 5869 | if (end < charpos) | 5866 | if (end < charpos) |
| 5870 | break; | 5867 | break; |
| @@ -5875,17 +5872,18 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos) | |||
| 5875 | continue; | 5872 | continue; |
| 5876 | 5873 | ||
| 5877 | /* Skip this overlay if it doesn't apply to IT->w. */ | 5874 | /* Skip this overlay if it doesn't apply to IT->w. */ |
| 5878 | window = Foverlay_get (overlay, Qwindow); | 5875 | Lisp_Object window = Foverlay_get (overlay, Qwindow); |
| 5879 | if (WINDOWP (window) && XWINDOW (window) != it->w) | 5876 | if (WINDOWP (window) && XWINDOW (window) != it->w) |
| 5880 | continue; | 5877 | continue; |
| 5881 | 5878 | ||
| 5882 | /* If the text ``under'' the overlay is invisible, both before- | 5879 | /* If the text ``under'' the overlay is invisible, both before- |
| 5883 | and after-strings from this overlay are visible; start and | 5880 | and after-strings from this overlay are visible; start and |
| 5884 | end position are indistinguishable. */ | 5881 | end position are indistinguishable. */ |
| 5885 | invisible = Foverlay_get (overlay, Qinvisible); | 5882 | Lisp_Object invisible = Foverlay_get (overlay, Qinvisible); |
| 5886 | invis = TEXT_PROP_MEANS_INVISIBLE (invisible); | 5883 | int invis = TEXT_PROP_MEANS_INVISIBLE (invisible); |
| 5887 | 5884 | ||
| 5888 | /* If overlay has a non-empty before-string, record it. */ | 5885 | /* If overlay has a non-empty before-string, record it. */ |
| 5886 | Lisp_Object str; | ||
| 5889 | if ((start == charpos || (end == charpos && invis != 0)) | 5887 | if ((start == charpos || (end == charpos && invis != 0)) |
| 5890 | && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)) | 5888 | && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)) |
| 5891 | && SCHARS (str)) | 5889 | && SCHARS (str)) |
| @@ -5899,12 +5897,13 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos) | |||
| 5899 | } | 5897 | } |
| 5900 | 5898 | ||
| 5901 | /* Process overlays after the overlay center. */ | 5899 | /* Process overlays after the overlay center. */ |
| 5902 | for (ov = current_buffer->overlays_after; ov; ov = ov->next) | 5900 | for (struct Lisp_Overlay *ov = current_buffer->overlays_after; |
| 5901 | ov; ov = ov->next) | ||
| 5903 | { | 5902 | { |
| 5904 | XSETMISC (overlay, ov); | 5903 | Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike); |
| 5905 | eassert (OVERLAYP (overlay)); | 5904 | eassert (OVERLAYP (overlay)); |
| 5906 | start = OVERLAY_POSITION (OVERLAY_START (overlay)); | 5905 | ptrdiff_t start = OVERLAY_POSITION (OVERLAY_START (overlay)); |
| 5907 | end = OVERLAY_POSITION (OVERLAY_END (overlay)); | 5906 | ptrdiff_t end = OVERLAY_POSITION (OVERLAY_END (overlay)); |
| 5908 | 5907 | ||
| 5909 | if (start > charpos) | 5908 | if (start > charpos) |
| 5910 | break; | 5909 | break; |
| @@ -5915,16 +5914,17 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos) | |||
| 5915 | continue; | 5914 | continue; |
| 5916 | 5915 | ||
| 5917 | /* Skip this overlay if it doesn't apply to IT->w. */ | 5916 | /* Skip this overlay if it doesn't apply to IT->w. */ |
| 5918 | window = Foverlay_get (overlay, Qwindow); | 5917 | Lisp_Object window = Foverlay_get (overlay, Qwindow); |
| 5919 | if (WINDOWP (window) && XWINDOW (window) != it->w) | 5918 | if (WINDOWP (window) && XWINDOW (window) != it->w) |
| 5920 | continue; | 5919 | continue; |
| 5921 | 5920 | ||
| 5922 | /* If the text ``under'' the overlay is invisible, it has a zero | 5921 | /* If the text ``under'' the overlay is invisible, it has a zero |
| 5923 | dimension, and both before- and after-strings apply. */ | 5922 | dimension, and both before- and after-strings apply. */ |
| 5924 | invisible = Foverlay_get (overlay, Qinvisible); | 5923 | Lisp_Object invisible = Foverlay_get (overlay, Qinvisible); |
| 5925 | invis = TEXT_PROP_MEANS_INVISIBLE (invisible); | 5924 | int invis = TEXT_PROP_MEANS_INVISIBLE (invisible); |
| 5926 | 5925 | ||
| 5927 | /* If overlay has a non-empty before-string, record it. */ | 5926 | /* If overlay has a non-empty before-string, record it. */ |
| 5927 | Lisp_Object str; | ||
| 5928 | if ((start == charpos || (end == charpos && invis != 0)) | 5928 | if ((start == charpos || (end == charpos && invis != 0)) |
| 5929 | && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)) | 5929 | && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)) |
| 5930 | && SCHARS (str)) | 5930 | && SCHARS (str)) |
| @@ -5950,12 +5950,11 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos) | |||
| 5950 | /* IT->current.overlay_string_index is the number of overlay strings | 5950 | /* IT->current.overlay_string_index is the number of overlay strings |
| 5951 | that have already been consumed by IT. Copy some of the | 5951 | that have already been consumed by IT. Copy some of the |
| 5952 | remaining overlay strings to IT->overlay_strings. */ | 5952 | remaining overlay strings to IT->overlay_strings. */ |
| 5953 | i = 0; | 5953 | ptrdiff_t j = it->current.overlay_string_index; |
| 5954 | j = it->current.overlay_string_index; | 5954 | for (ptrdiff_t i = 0; i < OVERLAY_STRING_CHUNK_SIZE && j < n; i++, j++) |
| 5955 | while (i < OVERLAY_STRING_CHUNK_SIZE && j < n) | ||
| 5956 | { | 5955 | { |
| 5957 | it->overlay_strings[i] = entries[j].string; | 5956 | it->overlay_strings[i] = entries[j].string; |
| 5958 | it->string_overlays[i++] = entries[j++].overlay; | 5957 | it->string_overlays[i] = entries[j].overlay; |
| 5959 | } | 5958 | } |
| 5960 | 5959 | ||
| 5961 | CHECK_IT (it); | 5960 | CHECK_IT (it); |