Some convenient bits to deal with Lisp_Save_Values.

* lisp.h (XSAVE_OBJECT): New macro to extract saved objects.
(allocate_misc): Remove prototype.
(format_save_value): New prototype.
* alloc.c (allocate_misc): Revert back to static.
(format_save_value): New function to build Lisp_Save_Value
object with the specified internal structure.
(make_save_value): Reimplement using format_save_value.
* editfns.c (save_excursion_save): Use format_save_value.
(save_excursion_restore): Use XSAVE_OBJECT.
This commit is contained in:
Dmitry Antipov 2013-01-15 12:38:07 +04:00
parent cb9c0a53bc
commit 1b971ac155
4 changed files with 91 additions and 49 deletions

View file

@ -1,3 +1,16 @@
2013-01-15 Dmitry Antipov <dmantipov@yandex.ru>
Some convenient bits to deal with Lisp_Save_Values.
* lisp.h (XSAVE_OBJECT): New macro to extract saved objects.
(allocate_misc): Remove prototype.
(format_save_value): New prototype.
* alloc.c (allocate_misc): Revert back to static.
(format_save_value): New function to build Lisp_Save_Value
object with the specified internal structure.
(make_save_value): Reimplement using format_save_value.
* editfns.c (save_excursion_save): Use format_save_value.
(save_excursion_restore): Use XSAVE_OBJECT.
2013-01-14 Paul Eggert <eggert@cs.ucla.edu>
Avoid needless casts with XSAVE_POINTER.

View file

@ -3302,7 +3302,7 @@ static union Lisp_Misc *marker_free_list;
/* Return a newly allocated Lisp_Misc object of specified TYPE. */
Lisp_Object
static Lisp_Object
allocate_misc (enum Lisp_Misc_Type type)
{
Lisp_Object val;
@ -3350,6 +3350,59 @@ free_misc (Lisp_Object misc)
total_free_markers++;
}
/* Return a Lisp_Save_Value object with the data saved according to
FMT. Format specifiers are `i' for an integer, `p' for a pointer
and `o' for Lisp_Object. Up to 4 objects can be specified. */
Lisp_Object
format_save_value (const char *fmt, ...)
{
va_list ap;
int len = strlen (fmt);
Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
struct Lisp_Save_Value *p = XSAVE_VALUE (val);
eassert (0 < len && len < 5);
va_start (ap, fmt);
#define INITX(index) \
do { \
if (len <= index) \
p->type ## index = SAVE_UNUSED; \
else \
{ \
if (fmt[index] == 'i') \
{ \
p->type ## index = SAVE_INTEGER; \
p->data[index].integer = va_arg (ap, ptrdiff_t); \
} \
else if (fmt[index] == 'p') \
{ \
p->type ## index = SAVE_POINTER; \
p->data[index].pointer = va_arg (ap, void *); \
} \
else if (fmt[index] == 'o') \
{ \
p->type ## index = SAVE_OBJECT; \
p->data[index].object = va_arg (ap, Lisp_Object); \
} \
else \
emacs_abort (); \
} \
} while (0)
INITX (0);
INITX (1);
INITX (2);
INITX (3);
#undef INITX
va_end (ap);
p->area = 0;
return val;
}
/* Return a Lisp_Save_Value object containing POINTER and INTEGER.
Most code should use this to package C integers and pointers
to call record_unwind_protect. The unwind function can get the
@ -3358,18 +3411,7 @@ free_misc (Lisp_Object misc)
Lisp_Object
make_save_value (void *pointer, ptrdiff_t integer)
{
register Lisp_Object val;
register struct Lisp_Save_Value *p;
val = allocate_misc (Lisp_Misc_Save_Value);
p = XSAVE_VALUE (val);
p->type0 = SAVE_POINTER;
p->data[0].pointer = pointer;
p->type1 = SAVE_INTEGER;
p->data[1].integer = integer;
p->type2 = p->type3 = SAVE_UNUSED;
p->area = 0;
return val;
return format_save_value ("pi", pointer, integer);
}
/* Free a Lisp_Save_Value object. Do not use this function

View file

@ -833,31 +833,17 @@ This function does not move point. */)
Lisp_Object
save_excursion_save (void)
{
Lisp_Object save = allocate_misc (Lisp_Misc_Save_Value);
register struct Lisp_Save_Value *v = XSAVE_VALUE (save);
/* Do not allocate extra space and pack everything in SAVE. */
v->area = 0;
v->type0 = SAVE_OBJECT;
v->data[0].object = Fpoint_marker ();
/* Do not copy the mark if it points to nowhere. */
v->type1 = SAVE_OBJECT;
v->data[1].object = (XMARKER (BVAR (current_buffer, mark))->buffer
? Fcopy_marker (BVAR (current_buffer, mark), Qnil)
: Qnil);
/* Selected window if current buffer is shown in it, nil otherwise. */
v->type2 = SAVE_OBJECT;
v->data[2].object
= ((XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
? selected_window : Qnil);
v->type3 = SAVE_OBJECT;
v->data[3].object = BVAR (current_buffer, mark_active);
return save;
return format_save_value
("oooo",
Fpoint_marker (),
/* Do not copy the mark if it points to nowhere. */
(XMARKER (BVAR (current_buffer, mark))->buffer
? Fcopy_marker (BVAR (current_buffer, mark), Qnil)
: Qnil),
/* Selected window if current buffer is shown in it, nil otherwise. */
((XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
? selected_window : Qnil),
BVAR (current_buffer, mark_active));
}
/* Restore saved buffer before leaving `save-excursion' special form. */
@ -867,13 +853,8 @@ save_excursion_restore (Lisp_Object info)
{
Lisp_Object tem, tem1, omark, nmark;
struct gcpro gcpro1, gcpro2, gcpro3;
register struct Lisp_Save_Value *v = XSAVE_VALUE (info);
/* Paranoid. */
eassert (v->type0 == SAVE_OBJECT && v->type1 == SAVE_OBJECT
&& v->type2 == SAVE_OBJECT && v->type3 == SAVE_OBJECT);
tem = Fmarker_buffer (v->data[0].object);
tem = Fmarker_buffer (XSAVE_OBJECT (info, 0));
/* If we're unwinding to top level, saved buffer may be deleted. This
means that all of its markers are unchained and so tem is nil. */
if (NILP (tem))
@ -885,12 +866,12 @@ save_excursion_restore (Lisp_Object info)
Fset_buffer (tem);
/* Point marker. */
tem = v->data[0].object;
tem = XSAVE_OBJECT (info, 0);
Fgoto_char (tem);
unchain_marker (XMARKER (tem));
/* Mark marker. */
tem = v->data[1].object;
tem = XSAVE_OBJECT (info, 1);
omark = Fmarker_position (BVAR (current_buffer, mark));
if (NILP (tem))
unchain_marker (XMARKER (BVAR (current_buffer, mark)));
@ -902,7 +883,7 @@ save_excursion_restore (Lisp_Object info)
}
/* Mark active. */
tem = v->data[3].object;
tem = XSAVE_OBJECT (info, 3);
tem1 = BVAR (current_buffer, mark_active);
bset_mark_active (current_buffer, tem);
@ -926,7 +907,7 @@ save_excursion_restore (Lisp_Object info)
/* 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 = v->data[2].object;
tem = XSAVE_OBJECT (info, 2);
if (WINDOWP (tem)
&& !EQ (tem, selected_window)
&& (tem1 = XWINDOW (tem)->buffer,

View file

@ -1421,6 +1421,12 @@ struct Lisp_Save_Value
#define XSAVE_INTEGER(obj) XSAVE_VALUE (obj)->data[1].integer
/* Macro to extract Nth saved object. */
#define XSAVE_OBJECT(obj, n) \
(eassert (XSAVE_VALUE (obj)->type ## n == SAVE_OBJECT), \
XSAVE_VALUE (obj)->data[n].object)
/* A miscellaneous object, when it's on the free list. */
struct Lisp_Free
{
@ -2921,7 +2927,6 @@ extern void memory_warnings (void *, void (*warnfun) (const char *));
/* Defined in alloc.c. */
extern void check_pure_size (void);
extern Lisp_Object allocate_misc (enum Lisp_Misc_Type);
extern void free_misc (Lisp_Object);
extern void allocate_string_data (struct Lisp_String *, EMACS_INT, EMACS_INT);
extern void malloc_warning (const char *);
@ -3007,6 +3012,7 @@ extern bool abort_on_gc;
extern Lisp_Object make_float (double);
extern void display_malloc_warning (void);
extern ptrdiff_t inhibit_garbage_collection (void);
extern Lisp_Object format_save_value (const char *, ...);
extern Lisp_Object make_save_value (void *, ptrdiff_t);
extern void free_save_value (Lisp_Object);
extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);