# HG changeset patch # User Jason Rumney # Date 1230117632 0 # Node ID 01f68a925d1282b6f9c29e66d5d52600ec377db4 # Parent 38e7317321eac7e6b3a1f6b3d029e324e39a7cb1 * ralloc.c (r_alloc_reset_variable): New function. * buffer.c (Fbuffer_swap_text) [REL_ALLOC]: Reset ralloc's internal record of what points where. diff -r 38e7317321ea -r 01f68a925d12 src/ChangeLog --- a/src/ChangeLog Wed Dec 24 00:45:51 2008 +0000 +++ b/src/ChangeLog Wed Dec 24 11:20:32 2008 +0000 @@ -1,3 +1,10 @@ +2008-12-24 Jason Rumney + + * ralloc.c (r_alloc_reset_variable): New function. + + * buffer.c (Fbuffer_swap_text) [REL_ALLOC]: Reset ralloc's internal + record of what points where. + 2008-12-22 Dan Nicolaescu * minibuf.c (read_minibuf): Follow the non-interactive case when diff -r 38e7317321ea -r 01f68a925d12 src/buffer.c --- a/src/buffer.c Wed Dec 24 00:45:51 2008 +0000 +++ b/src/buffer.c Wed Dec 24 11:20:32 2008 +0000 @@ -2182,6 +2182,10 @@ return byte_pos; } +#ifdef REL_ALLOC +extern void r_alloc_reset_variable P_ ((PTR *, PTR *)); +#endif /* REL_ALLOC */ + DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, 1, 1, 0, doc: /* Swap the text between current buffer and BUFFER. */) @@ -2223,6 +2227,13 @@ swapfield (own_text, struct buffer_text); eassert (current_buffer->text == ¤t_buffer->own_text); eassert (other_buffer->text == &other_buffer->own_text); +#ifdef REL_ALLOC + r_alloc_reset_variable ((PTR *) ¤t_buffer->own_text.beg, + (PTR *) &other_buffer->own_text.beg); + r_alloc_reset_variable ((PTR *) &other_buffer->own_text.beg, + (PTR *) ¤t_buffer->own_text.beg); +#endif /* REL_ALLOC */ + swapfield (pt, EMACS_INT); swapfield (pt_byte, EMACS_INT); swapfield (begv, EMACS_INT); diff -r 38e7317321ea -r 01f68a925d12 src/ralloc.c --- a/src/ralloc.c Wed Dec 24 00:45:51 2008 +0000 +++ b/src/ralloc.c Wed Dec 24 11:20:32 2008 +0000 @@ -1223,6 +1223,34 @@ #endif /* DEBUG */ +/* Update the internal record of which variable points to some data to NEW. + Used by buffer-swap-text in Emacs to restore consistency after it + swaps the buffer text between two buffer objects. The OLD pointer + is checked to ensure that memory corruption does not occur due to + misuse. */ +void +r_alloc_reset_variable (old, new) + POINTER *old, *new; +{ + bloc_ptr bloc = first_bloc; + + /* Find the bloc that corresponds to the data pointed to by pointer. + find_bloc cannot be used, as it has internal consistency checks + which fail when the variable needs reseting. */ + while (bloc != NIL_BLOC) + { + if (bloc->data == *new) + break; + + bloc = bloc->next; + } + + if (bloc == NIL_BLOC || bloc->variable != old) + abort (); + + /* Update variable to point to the new location. */ + bloc->variable = new; +} /***********************************************************************