From 7b1123d824e51d40496c242e7a7f173de8936100 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 21 Mar 2013 13:56:22 -0700 Subject: [PATCH] Use functions and constants to manipulate Lisp_Save_Value objects. This replaces code that used macros and strings and token-pasting. The change makes the C source a bit easier to follow, and shrinks the Emacs executable a bit. * alloc.c: Verify some properties of Lisp_Save_Value's representation. (make_save_value): Change 1st arg from string to enum. All callers changed. (INTX): Remove. (mark_object): Use if, not #if, for GC_MARK_STACK. * lisp.h (SAVE_VALUEP, XSAVE_VALUE, XSAVE_POINTER, XSAVE_INTEGER) (XSAVE_OBJECT): Now functions, not macros. (STRING_BYTES_BOUND): Now just a macro, not a constant too; the constant was never used. (SAVE_SLOT_BITS, SAVE_VALUE_SLOTS, SAVE_TYPE_BITS, SAVE_TYPE_INT_INT) (SAVE_TYPE_INT_INT_INT, SAVE_TYPE_OBJ_OBJ, SAVE_TYPE_OBJ_OBJ_OBJ) (SAVE_TYPE_OBJ_OBJ_OBJ_OBJ, SAVE_TYPE_PTR_INT, SAVE_TYPE_PTR_OBJ) (SAVE_TYPE_PTR_PTR, SAVE_TYPE_PTR_PTR_OBJ, SAVE_TYPE_MEMORY): New constants. (struct Lisp_Save_Value): Replace members area, type0, type1, type2, type3 with a single member save_type. All uses changed. (save_type, set_save_pointer, set_save_integer): New functions. * print.c (PRINTX): Remove. --- src/ChangeLog | 23 ++++++++ src/alloc.c | 95 +++++++++++++------------------ src/editfns.c | 7 ++- src/fileio.c | 3 +- src/ftfont.c | 6 +- src/keymap.c | 3 +- src/lisp.h | 153 +++++++++++++++++++++++++++++++++++--------------- src/print.c | 69 ++++++++++++----------- src/xmenu.c | 2 +- 9 files changed, 220 insertions(+), 141 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index d6b50412f13..f65e08eb6fd 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,28 @@ 2013-03-21 Paul Eggert + Use functions and constants to manipulate Lisp_Save_Value objects. + This replaces code that used macros and strings and token-pasting. + The change makes the C source a bit easier to follow, + and shrinks the Emacs executable a bit. + * alloc.c: Verify some properties of Lisp_Save_Value's representation. + (make_save_value): Change 1st arg from string to enum. All callers + changed. + (INTX): Remove. + (mark_object): Use if, not #if, for GC_MARK_STACK. + * lisp.h (SAVE_VALUEP, XSAVE_VALUE, XSAVE_POINTER, XSAVE_INTEGER) + (XSAVE_OBJECT): Now functions, not macros. + (STRING_BYTES_BOUND): Now just a macro, not a constant too; + the constant was never used. + (SAVE_SLOT_BITS, SAVE_VALUE_SLOTS, SAVE_TYPE_BITS, SAVE_TYPE_INT_INT) + (SAVE_TYPE_INT_INT_INT, SAVE_TYPE_OBJ_OBJ, SAVE_TYPE_OBJ_OBJ_OBJ) + (SAVE_TYPE_OBJ_OBJ_OBJ_OBJ, SAVE_TYPE_PTR_INT, SAVE_TYPE_PTR_OBJ) + (SAVE_TYPE_PTR_PTR, SAVE_TYPE_PTR_PTR_OBJ, SAVE_TYPE_MEMORY): + New constants. + (struct Lisp_Save_Value): Replace members area, type0, type1, type2, + type3 with a single member save_type. All uses changed. + (save_type, set_save_pointer, set_save_integer): New functions. + * print.c (PRINTX): Remove. + * alloc.c: Remove redundant static declarations. 2013-03-20 Dmitry Antipov diff --git a/src/alloc.c b/src/alloc.c index 39379bc3bd7..4245b3069fa 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -3326,56 +3326,50 @@ free_misc (Lisp_Object misc) total_free_markers++; } +/* Verify properties of Lisp_Save_Value's representation + that are assumed here and elsewhere. */ + +verify (SAVE_UNUSED == 0); +verify ((SAVE_INTEGER | SAVE_POINTER | SAVE_OBJECT) >> SAVE_SLOT_BITS == 0); + /* 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. */ + DATA_TYPE. DATA_TYPE should be one of SAVE_TYPE_INT_INT, etc. */ Lisp_Object -make_save_value (const char *fmt, ...) +make_save_value (enum Lisp_Save_Type save_type, ...) { va_list ap; - int len = strlen (fmt); + int i; 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) + eassert (0 < save_type + && (save_type < 1 << (SAVE_TYPE_BITS - 1) + || save_type == SAVE_TYPE_MEMORY)); + p->save_type = save_type; + va_start (ap, save_type); + save_type &= ~ (1 << (SAVE_TYPE_BITS - 1)); + + for (i = 0; save_type; i++, save_type >>= SAVE_SLOT_BITS) + switch (save_type & ((1 << SAVE_SLOT_BITS) - 1)) + { + case SAVE_POINTER: + p->data[i].pointer = va_arg (ap, void *); + break; - INITX (0); - INITX (1); - INITX (2); - INITX (3); + case SAVE_INTEGER: + p->data[i].integer = va_arg (ap, ptrdiff_t); + break; -#undef INITX + case SAVE_OBJECT: + p->data[i].object = va_arg (ap, Lisp_Object); + break; + + default: + emacs_abort (); + } va_end (ap); - p->area = 0; return val; } @@ -3386,11 +3380,8 @@ make_save_pointer (void *pointer) { Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); struct Lisp_Save_Value *p = XSAVE_VALUE (val); - - p->area = 0; - p->type0 = SAVE_POINTER; + p->save_type = SAVE_POINTER; p->data[0].pointer = pointer; - p->type1 = p->type2 = p->type3 = SAVE_UNUSED; return val; } @@ -5958,12 +5949,11 @@ mark_object (Lisp_Object arg) case Lisp_Misc_Save_Value: XMISCANY (obj)->gcmarkbit = 1; { - register struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj); - /* If `area' is nonzero, `data[0].pointer' is the address + struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj); + /* If `save_type' is zero, `data[0].pointer' is the address of a memory area containing `data[1].integer' potential Lisp_Objects. */ -#if GC_MARK_STACK - if (ptr->area) + if (GC_MARK_STACK && ptr->save_type == SAVE_TYPE_MEMORY) { Lisp_Object *p = ptr->data[0].pointer; ptrdiff_t nelt; @@ -5971,17 +5961,12 @@ mark_object (Lisp_Object arg) mark_maybe_object (*p); } else -#endif /* GC_MARK_STACK */ { /* Find Lisp_Objects in `data[N]' slots and mark them. */ - if (ptr->type0 == SAVE_OBJECT) - mark_object (ptr->data[0].object); - if (ptr->type1 == SAVE_OBJECT) - mark_object (ptr->data[1].object); - if (ptr->type2 == SAVE_OBJECT) - mark_object (ptr->data[2].object); - if (ptr->type3 == SAVE_OBJECT) - mark_object (ptr->data[3].object); + int i; + for (i = 0; i < SAVE_VALUE_SLOTS; i++) + if (save_type (ptr, i) == SAVE_OBJECT) + mark_object (ptr->data[i].object); } } break; diff --git a/src/editfns.c b/src/editfns.c index f34c574cae3..6357a28e8ea 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -839,7 +839,7 @@ Lisp_Object save_excursion_save (void) { return make_save_value - ("oooo", + (SAVE_TYPE_OBJ_OBJ_OBJ_OBJ, Fpoint_marker (), /* Do not copy the mark if it points to nowhere. */ (XMARKER (BVAR (current_buffer, mark))->buffer @@ -4241,7 +4241,10 @@ usage: (format STRING &rest OBJECTS) */) memcpy (buf, initial_buffer, used); } else - XSAVE_POINTER (buf_save_value, 0) = buf = xrealloc (buf, bufsize); + { + buf = xrealloc (buf, bufsize); + set_save_pointer (buf_save_value, 0, buf); + } p = buf + used; } diff --git a/src/fileio.c b/src/fileio.c index 724250c8aaa..3d7bd9fe216 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -4218,7 +4218,8 @@ by calling `format-decode', which see. */) to be signaled after decoding the text we read. */ nbytes = internal_condition_case_1 (read_non_regular, - make_save_value ("iii", (ptrdiff_t) fd, inserted, trytry), + make_save_value (SAVE_TYPE_INT_INT_INT, (ptrdiff_t) fd, + inserted, trytry), Qerror, read_non_regular_quit); if (NILP (nbytes)) diff --git a/src/ftfont.c b/src/ftfont.c index 867e25a7a25..0ad173af98a 100644 --- a/src/ftfont.c +++ b/src/ftfont.c @@ -393,7 +393,7 @@ ftfont_lookup_cache (Lisp_Object key, enum ftfont_cache_for cache_for) cache_data = xmalloc (sizeof *cache_data); cache_data->ft_face = NULL; cache_data->fc_charset = NULL; - val = make_save_value ("pi", cache_data, 0); + val = make_save_value (SAVE_TYPE_PTR_INT, cache_data, 0); cache = Fcons (Qnil, val); Fputhash (key, cache, ft_face_cache); } @@ -1211,7 +1211,7 @@ ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size) return Qnil; } } - XSAVE_INTEGER (val, 1)++; + set_save_integer (val, 1, XSAVE_INTEGER (val, 1) + 1); size = XINT (AREF (entity, FONT_SIZE_INDEX)); if (size == 0) size = pixel_size; @@ -1326,7 +1326,7 @@ ftfont_close (FRAME_PTR f, struct font *font) cache = ftfont_lookup_cache (val, FTFONT_CACHE_FOR_FACE); eassert (CONSP (cache)); val = XCDR (cache); - XSAVE_INTEGER (val, 1)--; + set_save_integer (val, 1, XSAVE_INTEGER (val, 1) - 1); if (XSAVE_INTEGER (val, 1) == 0) { struct ftfont_cache_data *cache_data = XSAVE_POINTER (val, 0); diff --git a/src/keymap.c b/src/keymap.c index 00eefb375ef..34406a5fc70 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -611,7 +611,8 @@ map_keymap_internal (Lisp_Object map, } else if (CHAR_TABLE_P (binding)) map_char_table (map_keymap_char_table_item, Qnil, binding, - make_save_value ("ppo", fun, data, args)); + make_save_value (SAVE_TYPE_PTR_PTR_OBJ, + fun, data, args)); } UNGCPRO; return tail; diff --git a/src/lisp.h b/src/lisp.h index f526cd36a6f..6838d4a93cb 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -551,6 +551,12 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper) return num < lower ? lower : num <= upper ? num : upper; } + +/* Forward declarations. */ + +LISP_INLINE bool SAVE_VALUEP (Lisp_Object); +LISP_INLINE struct Lisp_Save_Value *XSAVE_VALUE (Lisp_Object); + /* Extract a value or address from a Lisp_Object. */ #define XCONS(a) (eassert (CONSP (a)), \ @@ -571,7 +577,6 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper) #define XMISCTYPE(a) (XMISCANY (a)->type) #define XMARKER(a) (eassert (MARKERP (a)), &(XMISC (a)->u_marker)) #define XOVERLAY(a) (eassert (OVERLAYP (a)), &(XMISC (a)->u_overlay)) -#define XSAVE_VALUE(a) (eassert (SAVE_VALUEP (a)), &(XMISC (a)->u_save_value)) /* Forwarding object types. */ @@ -781,13 +786,10 @@ extern ptrdiff_t string_bytes (struct Lisp_String *); would expose alloc.c internal details that we'd rather keep private. - This is a macro for use in static initializers, and a constant for - visibility to GDB. The cast to ptrdiff_t ensures that - the macro is signed. */ -static ptrdiff_t const STRING_BYTES_BOUND = + This is a macro for use in static initializers. The cast to + ptrdiff_t ensures that the macro is signed. */ #define STRING_BYTES_BOUND \ ((ptrdiff_t) min (MOST_POSITIVE_FIXNUM, min (SIZE_MAX, PTRDIFF_MAX) - 1)) - STRING_BYTES_BOUND; /* Mark STR as a unibyte string. */ #define STRING_SET_UNIBYTE(STR) \ @@ -1392,6 +1394,35 @@ enum SAVE_OBJECT }; +/* Number of bits needed to store one of the above values. */ +enum { SAVE_SLOT_BITS = 2 }; + +/* Number of slots in a save value where save_type is nonzero. */ +enum { SAVE_VALUE_SLOTS = 4 }; + +/* Bit-width and values for struct Lisp_Save_Value's save_type member. */ + +enum { SAVE_TYPE_BITS = SAVE_VALUE_SLOTS * SAVE_SLOT_BITS + 1 }; + +enum Lisp_Save_Type + { + SAVE_TYPE_INT_INT = SAVE_INTEGER + (SAVE_INTEGER << SAVE_SLOT_BITS), + SAVE_TYPE_INT_INT_INT + = (SAVE_INTEGER + (SAVE_TYPE_INT_INT << SAVE_SLOT_BITS)), + SAVE_TYPE_OBJ_OBJ = SAVE_OBJECT + (SAVE_OBJECT << SAVE_SLOT_BITS), + SAVE_TYPE_OBJ_OBJ_OBJ = SAVE_OBJECT + (SAVE_TYPE_OBJ_OBJ << SAVE_SLOT_BITS), + SAVE_TYPE_OBJ_OBJ_OBJ_OBJ + = SAVE_OBJECT + (SAVE_TYPE_OBJ_OBJ_OBJ << SAVE_SLOT_BITS), + SAVE_TYPE_PTR_INT = SAVE_POINTER + (SAVE_INTEGER << SAVE_SLOT_BITS), + SAVE_TYPE_PTR_OBJ = SAVE_POINTER + (SAVE_OBJECT << SAVE_SLOT_BITS), + SAVE_TYPE_PTR_PTR = SAVE_POINTER + (SAVE_POINTER << SAVE_SLOT_BITS), + SAVE_TYPE_PTR_PTR_OBJ + = SAVE_POINTER + (SAVE_TYPE_PTR_OBJ << SAVE_SLOT_BITS), + + /* This has an extra bit indicating it's raw memory. */ + SAVE_TYPE_MEMORY = SAVE_TYPE_PTR_INT + (1 << (SAVE_TYPE_BITS - 1)) + }; + /* Special object used to hold a different values for later use. This is mostly used to package C integers and pointers to call @@ -1412,73 +1443,96 @@ enum If yon need to pass more than just one C pointer, you should use make_save_value. This function allows you to pack up to - 4 integers, pointers or Lisp_Objects and conveniently get them - back with XSAVE_POINTER, XSAVE_INTEGER and XSAVE_OBJECT macros: + SAVE_VALUE_SLOTS integers, pointers or Lisp_Objects and + conveniently get them back with XSAVE_POINTER, XSAVE_INTEGER and + XSAVE_OBJECT macros: ... struct my_data *md = get_my_data (); - ptrdiff_t my_offset = get_my_offset (); Lisp_Object my_object = get_my_object (); record_unwind_protect - (my_unwind, make_save_value ("pio", md, my_offset, my_object)); + (my_unwind, make_save_value (SAVE_TYPE_PTR_OBJ, md, my_object)); ... Lisp_Object my_unwind (Lisp_Object arg) { struct my_data *md = XSAVE_POINTER (arg, 0); - ptrdiff_t my_offset = XSAVE_INTEGER (arg, 1); - Lisp_Object my_object = XSAVE_OBJECT (arg, 2); + Lisp_Object my_object = XSAVE_OBJECT (arg, 1); ... } If ENABLE_CHECKING is in effect, XSAVE_xxx macros do type checking of the saved objects and raise eassert if type of the saved object doesn't match the type which is extracted. In the example above, XSAVE_INTEGER (arg, 2) - or XSAVE_OBJECT (arg, 1) are wrong because integer was saved in slot 1 and - Lisp_Object was saved in slot 2 of ARG. */ + or XSAVE_OBJECT (arg, 0) are wrong because nothing was saved in slot 2 and + Lisp_Object was saved in slot 1 of ARG. */ struct Lisp_Save_Value { ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Save_Value */ unsigned gcmarkbit : 1; - int spacer : 6; - /* If `area' is nonzero, `data[0].pointer' is the address of a memory area - containing `data[1].integer' potential Lisp_Objects. The rest of `data' - fields are unused. */ - unsigned area : 1; - /* If `area' is zero, `data[N]' may hold different objects which type is - encoded in `typeN' fields as described by the anonymous enum above. - E.g. if `type0' is SAVE_INTEGER, `data[0].integer' is in use. */ - unsigned type0 : 2; - unsigned type1 : 2; - unsigned type2 : 2; - unsigned type3 : 2; + int spacer : 32 - (16 + 1 + SAVE_TYPE_BITS); + + /* DATA[N] may hold up to SAVE_VALUE_SLOTS entries. The type of + V's Ith entry is given by save_type (V, I). E.g., if save_type + (V, 3) == SAVE_INTEGER, V->data[3].integer is in use. + + If SAVE_TYPE == SAVE_TYPE_MEMORY, DATA[0].pointer is the address of + a memory area containing DATA[1].integer potential Lisp_Objects. */ + ENUM_BF (Lisp_Save_Type) save_type : SAVE_TYPE_BITS; union { void *pointer; ptrdiff_t integer; Lisp_Object object; - } data[4]; + } data[SAVE_VALUE_SLOTS]; }; -/* Macro to set and extract Nth saved pointer. Type - checking is ugly because it's used as an lvalue. */ +/* Return the type of V's Nth saved value. */ +LISP_INLINE int +save_type (struct Lisp_Save_Value *v, int n) +{ + eassert (0 <= n && n < SAVE_VALUE_SLOTS); + return (v->save_type >> (SAVE_SLOT_BITS * n) & ((1 << SAVE_SLOT_BITS) - 1)); +} + +/* Get and set the Nth saved pointer. */ -#define XSAVE_POINTER(obj, n) \ - XSAVE_VALUE (obj)->data[(eassert (XSAVE_VALUE (obj)->type \ - ## n == SAVE_POINTER), n)].pointer +LISP_INLINE void * +XSAVE_POINTER (Lisp_Object obj, int n) +{ + eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_POINTER); + return XSAVE_VALUE (obj)->data[n].pointer;; +} +LISP_INLINE void +set_save_pointer (Lisp_Object obj, int n, void *val) +{ + eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_POINTER); + XSAVE_VALUE (obj)->data[n].pointer = val; +} /* Likewise for the saved integer. */ -#define XSAVE_INTEGER(obj, n) \ - XSAVE_VALUE (obj)->data[(eassert (XSAVE_VALUE (obj)->type \ - ## n == SAVE_INTEGER), n)].integer +LISP_INLINE ptrdiff_t +XSAVE_INTEGER (Lisp_Object obj, int n) +{ + eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_INTEGER); + return XSAVE_VALUE (obj)->data[n].integer; +} +LISP_INLINE void +set_save_integer (Lisp_Object obj, int n, ptrdiff_t val) +{ + eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_INTEGER); + XSAVE_VALUE (obj)->data[n].integer = val; +} -/* Macro to extract Nth saved object. This is never used as - an lvalue, so we can do more convenient type checking. */ +/* Extract Nth saved object. */ -#define XSAVE_OBJECT(obj, n) \ - (eassert (XSAVE_VALUE (obj)->type ## n == SAVE_OBJECT), \ - XSAVE_VALUE (obj)->data[n].object) +LISP_INLINE Lisp_Object +XSAVE_OBJECT (Lisp_Object obj, int n) +{ + eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_OBJECT); + return XSAVE_VALUE (obj)->data[n].object; +} /* A miscellaneous object, when it's on the free list. */ struct Lisp_Free @@ -1501,6 +1555,13 @@ union Lisp_Misc struct Lisp_Save_Value u_save_value; }; +LISP_INLINE struct Lisp_Save_Value * +XSAVE_VALUE (Lisp_Object a) +{ + eassert (SAVE_VALUEP (a)); + return & XMISC (a)->u_save_value; +} + /* Forwarding pointer to an int variable. This is allowed only in the value cell of a symbol, and it means that the symbol's value really lives in the @@ -1786,7 +1847,12 @@ typedef struct { #define VECTORP(x) (VECTORLIKEP (x) && !(ASIZE (x) & PSEUDOVECTOR_FLAG)) #define OVERLAYP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay) #define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker) -#define SAVE_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value) + +LISP_INLINE bool +SAVE_VALUEP (Lisp_Object x) +{ + return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value; +} #define AUTOLOADP(x) (CONSP (x) && EQ (Qautoload, XCAR (x))) @@ -3105,7 +3171,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 make_save_value (const char *, ...); +extern Lisp_Object make_save_value (enum Lisp_Save_Type, ...); extern Lisp_Object make_save_pointer (void *); extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); extern void free_marker (Lisp_Object); @@ -3822,8 +3888,7 @@ extern void *record_xmalloc (size_t); { \ Lisp_Object arg_; \ buf = xmalloc ((nelt) * word_size); \ - arg_ = make_save_value ("pi", buf, nelt); \ - XSAVE_VALUE (arg_)->area = 1; \ + arg_ = make_save_value (SAVE_TYPE_MEMORY, buf, nelt); \ sa_must_free = 1; \ record_unwind_protect (safe_alloca_unwind, arg_); \ } \ diff --git a/src/print.c b/src/print.c index 53c0d99f836..4ab80fe1605 100644 --- a/src/print.c +++ b/src/print.c @@ -2042,17 +2042,15 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) strout ("#area) + if (v->save_type == SAVE_TYPE_MEMORY) { ptrdiff_t amount = v->data[1].integer; #if GC_MARK_STACK - /* If GC_MARK_STACK, valid_lisp_object_p is quite reliable, - and so we try to print up to 8 objects we have saved. - Although valid_lisp_object_p is slow, this shouldn't be - a real bottleneck because we do not use this code under - normal circumstances. */ + /* valid_lisp_object_p is reliable, so try to print up + to 8 saved objects. This code is rarely used, so + it's OK that valid_lisp_object_p is slow. */ int limit = min (amount, 8); Lisp_Object *area = v->data[0].pointer; @@ -2077,9 +2075,8 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) #else /* not GC_MARK_STACK */ - /* If !GC_MARK_STACK, we have no reliable way to find - whether Lisp_Object pointers points to an initialized - objects, and so we do not ever trying to print them. */ + /* There is no reliable way to determine whether the objects + are initialized, so do not try to print them. */ i = sprintf (buf, "with %"pD"d objects", amount); strout (buf, i, i, printcharfun); @@ -2088,33 +2085,37 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) } else { - /* Print each `data[N]' slot according to its type. */ - -#define PRINTX(index) \ - do { \ - i = 0; \ - if (v->type ## index == SAVE_UNUSED) \ - i = sprintf (buf, ""); \ - else if (v->type ## index == SAVE_INTEGER) \ - i = sprintf (buf, "", v->data[index].integer); \ - else if (v->type ## index == SAVE_POINTER) \ - i = sprintf (buf, "", v->data[index].pointer); \ - else /* SAVE_OBJECT */ \ - print_object (v->data[index].object, printcharfun, escapeflag); \ - if (i) \ - strout (buf, i, i, printcharfun); \ - } while (0) - - PRINTX (0); - PRINTCHAR (' '); - PRINTX (1); - PRINTCHAR (' '); - PRINTX (2); - PRINTCHAR (' '); - PRINTX (3); + /* Print each slot according to its type. */ + int index; + for (index = 0; index < SAVE_VALUE_SLOTS; index++) + { + if (index) + PRINTCHAR (' '); -#undef PRINTX + switch (save_type (v, index)) + { + case SAVE_UNUSED: + i = sprintf (buf, ""); + break; + + case SAVE_POINTER: + i = sprintf (buf, "", + v->data[index].pointer); + break; + + case SAVE_INTEGER: + i = sprintf (buf, "", + v->data[index].integer); + break; + + case SAVE_OBJECT: + print_object (v->data[index].object, printcharfun, + escapeflag); + continue; + } + strout (buf, i, i, printcharfun); + } } PRINTCHAR ('>'); } diff --git a/src/xmenu.c b/src/xmenu.c index 958cd220393..57cf27f955d 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -2479,7 +2479,7 @@ xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps, #endif record_unwind_protect (pop_down_menu, - make_save_value ("pp", f, menu)); + make_save_value (SAVE_TYPE_PTR_PTR, f, menu)); /* Help display under X won't work because XMenuActivate contains a loop that doesn't give Emacs a chance to process it. */ -- 2.39.2