From eeaea515623db982d4e7d453711e6f0fad9c08d8 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Fri, 27 Jul 2012 11:51:52 +0400 Subject: [PATCH] Revert last save_excursion_save and save_excursion_restore changes. * alloc.c, editfns.c, marker.c, lisp.h: Revert. Lots of crashes reported by Chong Yidong . --- src/ChangeLog | 8 ++- src/alloc.c | 53 +++++++-------- src/editfns.c | 174 +++++++++++++++++++++++++------------------------- src/lisp.h | 47 ++------------ src/marker.c | 21 +----- 5 files changed, 123 insertions(+), 180 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index adcdfb7c056..93697303cbb 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,9 +1,15 @@ +2012-07-27 Dmitry Antipov + + Revert last save_excursion_save and save_excursion_restore changes. + * alloc.c, editfns.c, marker.c, lisp.h: Revert. + Lots of crashes reported by Chong Yidong . + 2012-07-27 Dmitry Antipov Fix recently-introduced typos in Windows port. Reported by Martin Rudalics . * w32.c (init_environment): Replace comma with semicolon. - * w32fns.c (syms_of_w32fns): Likewise. + * w32fns.c (syms_of_w32fns): Add missing parenthesis. 2012-07-27 Paul Eggert diff --git a/src/alloc.c b/src/alloc.c index 948ce7b6f5c..c7936921a09 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -3685,10 +3685,17 @@ DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0, doc: /* Return a newly allocated marker which does not point at any place. */) (void) { - register Lisp_Object marker = allocate_misc (Lisp_Misc_Marker); + register Lisp_Object val; + register struct Lisp_Marker *p; - init_marker (XMARKER (marker), NULL, 0, 0, 0); - return marker; + val = allocate_misc (Lisp_Misc_Marker); + p = XMARKER (val); + p->buffer = 0; + p->bytepos = 0; + p->charpos = 0; + p->next = NULL; + p->insertion_type = 0; + return val; } /* Return a newly allocated marker which points into BUF @@ -3697,23 +3704,24 @@ DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0, Lisp_Object build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos) { - register Lisp_Object marker = allocate_misc (Lisp_Misc_Marker); - - /* Use Fmake_marker to create marker points to nowhere. */ - eassert (buf != NULL); + Lisp_Object obj; + struct Lisp_Marker *m; /* No dead buffers here. */ eassert (!NILP (BVAR (buf, name))); - /* In a single-byte buffer, two positions must be equal. - Otherwise, every character is at least one byte. */ - if (BUF_Z (buf) == BUF_Z_BYTE (buf)) - eassert (charpos == bytepos); - else - eassert (charpos <= bytepos); - - init_marker (XMARKER (marker), buf, charpos, bytepos, 0); - return marker; + /* Every character is at least one byte. */ + eassert (charpos <= bytepos); + + obj = allocate_misc (Lisp_Misc_Marker); + m = XMARKER (obj); + m->buffer = buf; + m->charpos = charpos; + m->bytepos = bytepos; + m->insertion_type = 0; + m->next = BUF_MARKERS (buf); + BUF_MARKERS (buf) = m; + return obj; } /* Put MARKER back on the free list after using it temporarily. */ @@ -6081,19 +6089,6 @@ mark_object (Lisp_Object arg) case PVEC_SUBR: break; - case PVEC_EXCURSION: - { - struct Lisp_Excursion *e = (struct Lisp_Excursion *) ptr; - /* No Lisp_Objects but two special pointers to mark here. */ - eassert (e->buffer != NULL); - eassert (e->window != NULL); - if (!VECTOR_MARKED_P (e->buffer)) - mark_buffer (e->buffer); - if (!VECTOR_MARKED_P (e->window)) - mark_vectorlike ((struct Lisp_Vector *) e->window); - } - break; - case PVEC_FREE: abort (); diff --git a/src/editfns.c b/src/editfns.c index 8b6c29bc934..f174594dd97 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -821,104 +821,104 @@ This function does not move point. */) Qnil, Qt, Qnil); } -/* Record buffer state before entering Fsave_excursion. */ - + Lisp_Object save_excursion_save (void) { - Lisp_Object excursion; - struct buffer *b = current_buffer; - struct window *w = XWINDOW (selected_window); - struct Lisp_Excursion *ex = xmalloc (sizeof *ex); - struct Lisp_Marker *m = XMARKER (BVAR (b, mark)); - - ex->size = 0; - ex->buffer = b; - ex->window = w; - ex->visible = (XBUFFER (w->buffer) == b); - ex->active = !NILP (BVAR (b, mark_active)); - - /* We do not initialize type and gcmarkbit since this marker - is never referenced via Lisp_Object and invisible for GC. */ - init_marker (&ex->point, b, PT, PT_BYTE, 0); - - /* Likewise. Note that charpos and bytepos may be zero. */ - init_marker (&ex->mark, m->buffer, m->charpos, - m->bytepos, m->insertion_type); - - /* Make it a pseudovector and return excursion object. */ - XSETTYPED_PVECTYPE (ex, size, PVEC_EXCURSION); - XSETEXCURSION (excursion, ex); - return excursion; + int visible = (XBUFFER (XWINDOW (selected_window)->buffer) + == current_buffer); + + return Fcons (Fpoint_marker (), + Fcons (Fcopy_marker (BVAR (current_buffer, mark), Qnil), + Fcons (visible ? Qt : Qnil, + Fcons (BVAR (current_buffer, mark_active), + selected_window)))); } -/* Restore buffer state before leaving Fsave_excursion. */ - Lisp_Object -save_excursion_restore (Lisp_Object obj) +save_excursion_restore (Lisp_Object info) { - struct Lisp_Excursion *ex = XEXCURSION (obj); - struct buffer *b = ex->buffer; - - eassert (b != NULL); - eassert (ex->window != NULL); - - /* Restore buffer state only if the buffer is live. - Otherwise, just cancel an excursion state. */ + Lisp_Object tem, tem1, omark, nmark; + struct gcpro gcpro1, gcpro2, gcpro3; + int visible_p; + + tem = Fmarker_buffer (XCAR (info)); + /* If buffer being returned to is now deleted, avoid error */ + /* Otherwise could get error here while unwinding to top level + and crash */ + /* In that case, Fmarker_buffer returns nil now. */ + if (NILP (tem)) + return Qnil; - if (!NILP (BVAR (b, name))) + omark = nmark = Qnil; + GCPRO3 (info, omark, nmark); + + Fset_buffer (tem); + + /* Point marker. */ + tem = XCAR (info); + Fgoto_char (tem); + unchain_marker (XMARKER (tem)); + + /* Mark marker. */ + info = XCDR (info); + tem = XCAR (info); + omark = Fmarker_position (BVAR (current_buffer, mark)); + Fset_marker (BVAR (current_buffer, mark), tem, Fcurrent_buffer ()); + nmark = Fmarker_position (tem); + unchain_marker (XMARKER (tem)); + + /* visible */ + info = XCDR (info); + visible_p = !NILP (XCAR (info)); + +#if 0 /* We used to make the current buffer visible in the selected window + if that was true previously. That avoids some anomalies. + But it creates others, and it wasn't documented, and it is simpler + and cleaner never to alter the window/buffer connections. */ + tem1 = Fcar (tem); + if (!NILP (tem1) + && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer)) + Fswitch_to_buffer (Fcurrent_buffer (), Qnil); +#endif /* 0 */ + + /* Mark active */ + info = XCDR (info); + tem = XCAR (info); + tem1 = BVAR (current_buffer, mark_active); + BVAR (current_buffer, mark_active) = tem; + + /* If mark is active now, and either was not active + or was at a different place, run the activate hook. */ + if (! NILP (tem)) { - int active; - struct Lisp_Marker *m; - ptrdiff_t oldpos, newpos; - - /* Restore current buffer. */ - set_buffer_internal (b); - - /* Restore buffer position. */ - SET_PT_BOTH (clip_to_bounds (BEGV, ex->point.charpos, ZV), - clip_to_bounds (BEGV_BYTE, ex->point.bytepos, ZV_BYTE)); - unchain_marker (&ex->point); - - /* Restore mark if it was non-zero. */ - m = XMARKER (BVAR (b, mark)); - oldpos = m->charpos; - if (BEGV <= ex->mark.charpos) - attach_marker (m, b, ex->mark.charpos, ex->mark.bytepos); - newpos = ex->mark.charpos; - unchain_marker (&ex->mark); - - /* If mark and region was active, restore them. */ - active = !NILP (BVAR (b, mark_active)); - BVAR (b, mark_active) = ex->active ? Qt : Qnil; - - /* If mark is active now, and either was not active - or was at a different place, run the activate hook. */ - if (ex->active && oldpos != newpos) - { - obj = intern ("activate-mark-hook"); - Frun_hooks (1, &obj); - } - /* If mark has ceased to be active, run deactivate hook. */ - else if (active) - { - obj = intern ("deactivate-mark-hook"); - Frun_hooks (1, &obj); - } - - /* If buffer was visible in a window, and a different window - was selected, and the old selected window is still showing - this buffer, restore point in that window. */ - if (ex->visible) - { - struct window *w = ex->window; - - if (w != XWINDOW (selected_window) && XBUFFER (w->buffer) == b) - attach_marker (XMARKER (w->pointm), b, PT, PT_BYTE); - } + if (! EQ (omark, nmark)) + { + tem = intern ("activate-mark-hook"); + Frun_hooks (1, &tem); + } + } + /* If mark has ceased to be active, run deactivate hook. */ + else if (! NILP (tem1)) + { + tem = intern ("deactivate-mark-hook"); + Frun_hooks (1, &tem); } - xfree (ex); + /* If buffer was visible in a window, and a different window was + selected, and the old selected window is still showing this + buffer, restore point in that window. */ + tem = XCDR (info); + if (visible_p + && !EQ (tem, selected_window) + && (tem1 = XWINDOW (tem)->buffer, + (/* Window is live... */ + BUFFERP (tem1) + /* ...and it shows the current buffer. */ + && XBUFFER (tem1) == current_buffer))) + Fset_window_point (tem, make_number (PT)); + + UNGCPRO; return Qnil; } diff --git a/src/lisp.h b/src/lisp.h index dd03a130c7c..f0129f05efd 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -375,7 +375,6 @@ enum pvec_type PVEC_TERMINAL, PVEC_WINDOW_CONFIGURATION, PVEC_SUBR, - PVEC_EXCURSION, PVEC_OTHER, /* These last 4 are special because we OR them in fns.c:internal_equal, so they have to use a disjoint bit pattern: @@ -545,8 +544,6 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper) (struct terminal *) XUNTAG (a, Lisp_Vectorlike)) #define XSUBR(a) (eassert (SUBRP (a)), \ (struct Lisp_Subr *) XUNTAG (a, Lisp_Vectorlike)) -#define XEXCURSION(a) (eassert (EXCURSIONP (a)), \ - (struct Lisp_Excursion *) XUNTAG (a, Lisp_Vectorlike)) #define XBUFFER(a) (eassert (BUFFERP (a)), \ (struct buffer *) XUNTAG (a, Lisp_Vectorlike)) #define XCHAR_TABLE(a) (eassert (CHAR_TABLE_P (a)), \ @@ -599,12 +596,9 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper) #define XSETPROCESS(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_PROCESS)) #define XSETWINDOW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)) #define XSETTERMINAL(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)) -/* These are special because both Lisp_Subr and Lisp_Excursion lacks - struct vectorlike_header. */ +/* XSETSUBR is special since Lisp_Subr lacks struct vectorlike_header. */ #define XSETSUBR(a, b) \ XSETTYPED_PSEUDOVECTOR (a, b, XSUBR (a)->size, PVEC_SUBR) -#define XSETEXCURSION(a, b) \ - XSETTYPED_PSEUDOVECTOR (a, b, XEXCURSION (a)->size, PVEC_EXCURSION) #define XSETCOMPILED(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_COMPILED)) #define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)) #define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)) @@ -1521,33 +1515,6 @@ struct Lisp_Float #define XFLOAT_INIT(f,n) (XFLOAT (f)->u.data = (n)) #endif -/* This structure is used to record buffer state for Fsave_excursion. - It's mostly treated as Lisp_Vector but allocated and freed explicitly - with xmalloc and xfree, so there is no vectorlike_header here. */ - -struct Lisp_Excursion -{ - ptrdiff_t size; - - /* Saved value of XWINDOW (selected_window). */ - struct window *window; - - /* Buffer where this excursion is in effect. */ - struct buffer *buffer; - - /* Non-zero if the window above has displayed the buffer. */ - unsigned visible : 1; - - /* Non-zero if this buffer has the mark active. */ - unsigned active : 1; - - /* Saved point. */ - struct Lisp_Marker point; - - /* Saved mark. May point to nowhere. */ - struct Lisp_Marker mark; -}; - /* A character, declared with the following typedef, is a member of some character set associated with the current buffer. */ #ifndef _UCHAR_T /* Protect against something in ctab.h on AIX. */ @@ -1730,10 +1697,8 @@ typedef struct { #define PROCESSP(x) PSEUDOVECTORP (x, PVEC_PROCESS) #define WINDOWP(x) PSEUDOVECTORP (x, PVEC_WINDOW) #define TERMINALP(x) PSEUDOVECTORP (x, PVEC_TERMINAL) -/* These are special because both Lisp_Subr and Lisp_Excursion lacks - struct vectorlike_header. */ +/* SUBRP is special since Lisp_Subr lacks struct vectorlike_header. */ #define SUBRP(x) TYPED_PSEUDOVECTORP (x, Lisp_Subr, PVEC_SUBR) -#define EXCURSIONP(x) TYPED_PSEUDOVECTORP (x, Lisp_Excursion, PVEC_EXCURSION) #define COMPILEDP(x) PSEUDOVECTORP (x, PVEC_COMPILED) #define BUFFERP(x) PSEUDOVECTORP (x, PVEC_BUFFER) #define CHAR_TABLE_P(x) PSEUDOVECTORP (x, PVEC_CHAR_TABLE) @@ -2949,15 +2914,11 @@ extern void clear_charpos_cache (struct buffer *); extern ptrdiff_t charpos_to_bytepos (ptrdiff_t); extern ptrdiff_t buf_charpos_to_bytepos (struct buffer *, ptrdiff_t); extern ptrdiff_t buf_bytepos_to_charpos (struct buffer *, ptrdiff_t); -extern void unchain_marker (struct Lisp_Marker *); +extern void unchain_marker (struct Lisp_Marker *marker); extern Lisp_Object set_marker_restricted (Lisp_Object, Lisp_Object, Lisp_Object); extern Lisp_Object set_marker_both (Lisp_Object, Lisp_Object, ptrdiff_t, ptrdiff_t); extern Lisp_Object set_marker_restricted_both (Lisp_Object, Lisp_Object, - ptrdiff_t, ptrdiff_t); -extern void init_marker (struct Lisp_Marker *, struct buffer *, - ptrdiff_t, ptrdiff_t, int); -extern void attach_marker (struct Lisp_Marker *, struct buffer *, - ptrdiff_t, ptrdiff_t); + ptrdiff_t, ptrdiff_t); extern Lisp_Object build_marker (struct buffer *, ptrdiff_t, ptrdiff_t); extern void syms_of_marker (void); diff --git a/src/marker.c b/src/marker.c index d63947d8c31..0a93f4c180f 100644 --- a/src/marker.c +++ b/src/marker.c @@ -425,28 +425,9 @@ Returns nil if MARKER points nowhere. */) return Qnil; } -/* Initialize just allocated Lisp_Marker. */ - -void -init_marker (struct Lisp_Marker *m, struct buffer *b, - ptrdiff_t charpos, ptrdiff_t bytepos, int type) -{ - m->buffer = b; - m->charpos = charpos; - m->bytepos = bytepos; - m->insertion_type = type; - if (b) - { - m->next = BUF_MARKERS (b); - BUF_MARKERS (b) = m; - } - else - m->next = NULL; -} - /* Change M so it points to B at CHARPOS and BYTEPOS. */ -void +static inline void attach_marker (struct Lisp_Marker *m, struct buffer *b, ptrdiff_t charpos, ptrdiff_t bytepos) { -- 2.39.2