aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog39
-rw-r--r--src/alloc.c73
-rw-r--r--src/dired.c2
-rw-r--r--src/editfns.c53
-rw-r--r--src/fileio.c39
-rw-r--r--src/font.c2
-rw-r--r--src/ftfont.c18
-rw-r--r--src/gtkutil.c2
-rw-r--r--src/keymap.c15
-rw-r--r--src/lisp.h21
-rw-r--r--src/lread.c2
-rw-r--r--src/nsmenu.m2
-rw-r--r--src/nsterm.h4
-rw-r--r--src/xfns.c2
-rw-r--r--src/xmenu.c11
-rw-r--r--src/xselect.c2
16 files changed, 173 insertions, 114 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 80f5875ef16..115b8d42915 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,42 @@
12013-01-15 Paul Eggert <eggert@cs.ucla.edu>
2
3 * alloc.c (free_save_value): Now static.
4
52013-01-15 Dmitry Antipov <dmantipov@yandex.ru>
6
7 * keymap.c (map_keymap_internal): Use format_save_value.
8 (map_keymap_char_table_item): Adjust accordingly.
9 * fileio.c (non_regular_fd, non_regular_inserted)
10 (non_regular_nbytes): Remove.
11 (Finsert_file_contents): Convert trytry to ptrdiff_t. Use
12 format_save_value to pass parameters to read_non_regular.
13 (read_non_regular): Use XSAVE_ macros to extract parameters.
14 Adjust comment.
15 * xmenu.c (xmenu_show) [!USE_X_TOOLKIT && !USE_GTK]: Use
16 format_save_value.
17 (pop_down_menu) [!USE_X_TOOLKIT && !USE_GTK]: Adjust user.
18
192013-01-15 Dmitry Antipov <dmantipov@yandex.ru>
20
21 * lisp.h (XSAVE_POINTER, XSAVE_INTEGER): Change to allow
22 extraction from any Lisp_Save_Value slot. Add type checking.
23 * alloc.c, dired.c, editfns.c, fileio.c, ftfont.c, gtkutil.c:
24 * keymap.c, lread.c, nsterm.h, nsmenu.c, xfns.c, xmenu.c:
25 * xselect.c: All users changed.
26
272013-01-15 Dmitry Antipov <dmantipov@yandex.ru>
28
29 Some convenient bits to deal with Lisp_Save_Values.
30 * lisp.h (XSAVE_OBJECT): New macro to extract saved objects.
31 (allocate_misc): Remove prototype.
32 (format_save_value): New prototype.
33 * alloc.c (allocate_misc): Revert back to static.
34 (format_save_value): New function to build Lisp_Save_Value
35 object with the specified internal structure.
36 (make_save_value): Reimplement using format_save_value.
37 * editfns.c (save_excursion_save): Use format_save_value.
38 (save_excursion_restore): Use XSAVE_OBJECT.
39
12013-01-14 Paul Eggert <eggert@cs.ucla.edu> 402013-01-14 Paul Eggert <eggert@cs.ucla.edu>
2 41
3 Avoid needless casts with XSAVE_POINTER. 42 Avoid needless casts with XSAVE_POINTER.
diff --git a/src/alloc.c b/src/alloc.c
index 3f1ccc82a58..7275a01bb73 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -209,6 +209,7 @@ Lisp_Object Qchar_table_extra_slots;
209 209
210static Lisp_Object Qpost_gc_hook; 210static Lisp_Object Qpost_gc_hook;
211 211
212static void free_save_value (Lisp_Object);
212static void mark_terminals (void); 213static void mark_terminals (void);
213static void gc_sweep (void); 214static void gc_sweep (void);
214static Lisp_Object make_pure_vector (ptrdiff_t); 215static Lisp_Object make_pure_vector (ptrdiff_t);
@@ -3302,7 +3303,7 @@ static union Lisp_Misc *marker_free_list;
3302 3303
3303/* Return a newly allocated Lisp_Misc object of specified TYPE. */ 3304/* Return a newly allocated Lisp_Misc object of specified TYPE. */
3304 3305
3305Lisp_Object 3306static Lisp_Object
3306allocate_misc (enum Lisp_Misc_Type type) 3307allocate_misc (enum Lisp_Misc_Type type)
3307{ 3308{
3308 Lisp_Object val; 3309 Lisp_Object val;
@@ -3350,6 +3351,59 @@ free_misc (Lisp_Object misc)
3350 total_free_markers++; 3351 total_free_markers++;
3351} 3352}
3352 3353
3354/* Return a Lisp_Save_Value object with the data saved according to
3355 FMT. Format specifiers are `i' for an integer, `p' for a pointer
3356 and `o' for Lisp_Object. Up to 4 objects can be specified. */
3357
3358Lisp_Object
3359format_save_value (const char *fmt, ...)
3360{
3361 va_list ap;
3362 int len = strlen (fmt);
3363 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3364 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3365
3366 eassert (0 < len && len < 5);
3367 va_start (ap, fmt);
3368
3369#define INITX(index) \
3370 do { \
3371 if (len <= index) \
3372 p->type ## index = SAVE_UNUSED; \
3373 else \
3374 { \
3375 if (fmt[index] == 'i') \
3376 { \
3377 p->type ## index = SAVE_INTEGER; \
3378 p->data[index].integer = va_arg (ap, ptrdiff_t); \
3379 } \
3380 else if (fmt[index] == 'p') \
3381 { \
3382 p->type ## index = SAVE_POINTER; \
3383 p->data[index].pointer = va_arg (ap, void *); \
3384 } \
3385 else if (fmt[index] == 'o') \
3386 { \
3387 p->type ## index = SAVE_OBJECT; \
3388 p->data[index].object = va_arg (ap, Lisp_Object); \
3389 } \
3390 else \
3391 emacs_abort (); \
3392 } \
3393 } while (0)
3394
3395 INITX (0);
3396 INITX (1);
3397 INITX (2);
3398 INITX (3);
3399
3400#undef INITX
3401
3402 va_end (ap);
3403 p->area = 0;
3404 return val;
3405}
3406
3353/* Return a Lisp_Save_Value object containing POINTER and INTEGER. 3407/* Return a Lisp_Save_Value object containing POINTER and INTEGER.
3354 Most code should use this to package C integers and pointers 3408 Most code should use this to package C integers and pointers
3355 to call record_unwind_protect. The unwind function can get the 3409 to call record_unwind_protect. The unwind function can get the
@@ -3358,27 +3412,16 @@ free_misc (Lisp_Object misc)
3358Lisp_Object 3412Lisp_Object
3359make_save_value (void *pointer, ptrdiff_t integer) 3413make_save_value (void *pointer, ptrdiff_t integer)
3360{ 3414{
3361 register Lisp_Object val; 3415 return format_save_value ("pi", pointer, integer);
3362 register struct Lisp_Save_Value *p;
3363
3364 val = allocate_misc (Lisp_Misc_Save_Value);
3365 p = XSAVE_VALUE (val);
3366 p->type0 = SAVE_POINTER;
3367 p->data[0].pointer = pointer;
3368 p->type1 = SAVE_INTEGER;
3369 p->data[1].integer = integer;
3370 p->type2 = p->type3 = SAVE_UNUSED;
3371 p->area = 0;
3372 return val;
3373} 3416}
3374 3417
3375/* Free a Lisp_Save_Value object. Do not use this function 3418/* Free a Lisp_Save_Value object. Do not use this function
3376 if SAVE contains pointer other than returned by xmalloc. */ 3419 if SAVE contains pointer other than returned by xmalloc. */
3377 3420
3378void 3421static void
3379free_save_value (Lisp_Object save) 3422free_save_value (Lisp_Object save)
3380{ 3423{
3381 xfree (XSAVE_POINTER (save)); 3424 xfree (XSAVE_POINTER (save, 0));
3382 free_misc (save); 3425 free_misc (save);
3383} 3426}
3384 3427
diff --git a/src/dired.c b/src/dired.c
index 8483721401a..3dca9d24f67 100644
--- a/src/dired.c
+++ b/src/dired.c
@@ -78,7 +78,7 @@ directory_files_internal_w32_unwind (Lisp_Object arg)
78static Lisp_Object 78static Lisp_Object
79directory_files_internal_unwind (Lisp_Object dh) 79directory_files_internal_unwind (Lisp_Object dh)
80{ 80{
81 DIR *d = XSAVE_POINTER (dh); 81 DIR *d = XSAVE_POINTER (dh, 0);
82 block_input (); 82 block_input ();
83 closedir (d); 83 closedir (d);
84 unblock_input (); 84 unblock_input ();
diff --git a/src/editfns.c b/src/editfns.c
index feac17f64b8..8910b66e4d3 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -833,31 +833,17 @@ This function does not move point. */)
833Lisp_Object 833Lisp_Object
834save_excursion_save (void) 834save_excursion_save (void)
835{ 835{
836 Lisp_Object save = allocate_misc (Lisp_Misc_Save_Value); 836 return format_save_value
837 register struct Lisp_Save_Value *v = XSAVE_VALUE (save); 837 ("oooo",
838 838 Fpoint_marker (),
839 /* Do not allocate extra space and pack everything in SAVE. */ 839 /* Do not copy the mark if it points to nowhere. */
840 v->area = 0; 840 (XMARKER (BVAR (current_buffer, mark))->buffer
841 841 ? Fcopy_marker (BVAR (current_buffer, mark), Qnil)
842 v->type0 = SAVE_OBJECT; 842 : Qnil),
843 v->data[0].object = Fpoint_marker (); 843 /* Selected window if current buffer is shown in it, nil otherwise. */
844 844 ((XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
845 /* Do not copy the mark if it points to nowhere. */ 845 ? selected_window : Qnil),
846 v->type1 = SAVE_OBJECT; 846 BVAR (current_buffer, mark_active));
847 v->data[1].object = (XMARKER (BVAR (current_buffer, mark))->buffer
848 ? Fcopy_marker (BVAR (current_buffer, mark), Qnil)
849 : Qnil);
850
851 /* Selected window if current buffer is shown in it, nil otherwise. */
852 v->type2 = SAVE_OBJECT;
853 v->data[2].object
854 = ((XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
855 ? selected_window : Qnil);
856
857 v->type3 = SAVE_OBJECT;
858 v->data[3].object = BVAR (current_buffer, mark_active);
859
860 return save;
861} 847}
862 848
863/* Restore saved buffer before leaving `save-excursion' special form. */ 849/* Restore saved buffer before leaving `save-excursion' special form. */
@@ -867,13 +853,8 @@ save_excursion_restore (Lisp_Object info)
867{ 853{
868 Lisp_Object tem, tem1, omark, nmark; 854 Lisp_Object tem, tem1, omark, nmark;
869 struct gcpro gcpro1, gcpro2, gcpro3; 855 struct gcpro gcpro1, gcpro2, gcpro3;
870 register struct Lisp_Save_Value *v = XSAVE_VALUE (info);
871
872 /* Paranoid. */
873 eassert (v->type0 == SAVE_OBJECT && v->type1 == SAVE_OBJECT
874 && v->type2 == SAVE_OBJECT && v->type3 == SAVE_OBJECT);
875 856
876 tem = Fmarker_buffer (v->data[0].object); 857 tem = Fmarker_buffer (XSAVE_OBJECT (info, 0));
877 /* If we're unwinding to top level, saved buffer may be deleted. This 858 /* If we're unwinding to top level, saved buffer may be deleted. This
878 means that all of its markers are unchained and so tem is nil. */ 859 means that all of its markers are unchained and so tem is nil. */
879 if (NILP (tem)) 860 if (NILP (tem))
@@ -885,12 +866,12 @@ save_excursion_restore (Lisp_Object info)
885 Fset_buffer (tem); 866 Fset_buffer (tem);
886 867
887 /* Point marker. */ 868 /* Point marker. */
888 tem = v->data[0].object; 869 tem = XSAVE_OBJECT (info, 0);
889 Fgoto_char (tem); 870 Fgoto_char (tem);
890 unchain_marker (XMARKER (tem)); 871 unchain_marker (XMARKER (tem));
891 872
892 /* Mark marker. */ 873 /* Mark marker. */
893 tem = v->data[1].object; 874 tem = XSAVE_OBJECT (info, 1);
894 omark = Fmarker_position (BVAR (current_buffer, mark)); 875 omark = Fmarker_position (BVAR (current_buffer, mark));
895 if (NILP (tem)) 876 if (NILP (tem))
896 unchain_marker (XMARKER (BVAR (current_buffer, mark))); 877 unchain_marker (XMARKER (BVAR (current_buffer, mark)));
@@ -902,7 +883,7 @@ save_excursion_restore (Lisp_Object info)
902 } 883 }
903 884
904 /* Mark active. */ 885 /* Mark active. */
905 tem = v->data[3].object; 886 tem = XSAVE_OBJECT (info, 3);
906 tem1 = BVAR (current_buffer, mark_active); 887 tem1 = BVAR (current_buffer, mark_active);
907 bset_mark_active (current_buffer, tem); 888 bset_mark_active (current_buffer, tem);
908 889
@@ -926,7 +907,7 @@ save_excursion_restore (Lisp_Object info)
926 /* If buffer was visible in a window, and a different window was 907 /* If buffer was visible in a window, and a different window was
927 selected, and the old selected window is still showing this 908 selected, and the old selected window is still showing this
928 buffer, restore point in that window. */ 909 buffer, restore point in that window. */
929 tem = v->data[2].object; 910 tem = XSAVE_OBJECT (info, 2);
930 if (WINDOWP (tem) 911 if (WINDOWP (tem)
931 && !EQ (tem, selected_window) 912 && !EQ (tem, selected_window)
932 && (tem1 = XWINDOW (tem)->buffer, 913 && (tem1 = XWINDOW (tem)->buffer,
@@ -4273,7 +4254,7 @@ usage: (format STRING &rest OBJECTS) */)
4273 memcpy (buf, initial_buffer, used); 4254 memcpy (buf, initial_buffer, used);
4274 } 4255 }
4275 else 4256 else
4276 XSAVE_POINTER (buf_save_value) = buf = xrealloc (buf, bufsize); 4257 XSAVE_POINTER (buf_save_value, 0) = buf = xrealloc (buf, bufsize);
4277 4258
4278 p = buf + used; 4259 p = buf + used;
4279 } 4260 }
diff --git a/src/fileio.c b/src/fileio.c
index d468576d639..87d945c1e5e 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3408,30 +3408,22 @@ decide_coding_unwind (Lisp_Object unwind_data)
3408 return Qnil; 3408 return Qnil;
3409} 3409}
3410 3410
3411 3411/* Read from a non-regular file. STATE is a Lisp_Save_Value
3412/* Used to pass values from insert-file-contents to read_non_regular. */ 3412 object where slot 0 is the file descriptor, slot 1 specifies
3413 3413 an offset to put the read bytes, and slot 2 is the maximum
3414static int non_regular_fd; 3414 amount of bytes to read. Value is the number of bytes read. */
3415static ptrdiff_t non_regular_inserted;
3416static int non_regular_nbytes;
3417
3418
3419/* Read from a non-regular file.
3420 Read non_regular_nbytes bytes max from non_regular_fd.
3421 Non_regular_inserted specifies where to put the read bytes.
3422 Value is the number of bytes read. */
3423 3415
3424static Lisp_Object 3416static Lisp_Object
3425read_non_regular (Lisp_Object ignore) 3417read_non_regular (Lisp_Object state)
3426{ 3418{
3427 int nbytes; 3419 int nbytes;
3428 3420
3429 immediate_quit = 1; 3421 immediate_quit = 1;
3430 QUIT; 3422 QUIT;
3431 nbytes = emacs_read (non_regular_fd, 3423 nbytes = emacs_read (XSAVE_INTEGER (state, 0),
3432 ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE 3424 ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE
3433 + non_regular_inserted), 3425 + XSAVE_INTEGER (state, 1)),
3434 non_regular_nbytes); 3426 XSAVE_INTEGER (state, 2));
3435 immediate_quit = 0; 3427 immediate_quit = 0;
3436 return make_number (nbytes); 3428 return make_number (nbytes);
3437} 3429}
@@ -4238,7 +4230,7 @@ by calling `format-decode', which see. */)
4238 while (how_much < total) 4230 while (how_much < total)
4239 { 4231 {
4240 /* try is reserved in some compilers (Microsoft C) */ 4232 /* try is reserved in some compilers (Microsoft C) */
4241 int trytry = min (total - how_much, READ_BUF_SIZE); 4233 ptrdiff_t trytry = min (total - how_much, READ_BUF_SIZE);
4242 ptrdiff_t this; 4234 ptrdiff_t this;
4243 4235
4244 if (not_regular) 4236 if (not_regular)
@@ -4255,12 +4247,11 @@ by calling `format-decode', which see. */)
4255 /* Read from the file, capturing `quit'. When an 4247 /* Read from the file, capturing `quit'. When an
4256 error occurs, end the loop, and arrange for a quit 4248 error occurs, end the loop, and arrange for a quit
4257 to be signaled after decoding the text we read. */ 4249 to be signaled after decoding the text we read. */
4258 non_regular_fd = fd; 4250 nbytes = internal_condition_case_1
4259 non_regular_inserted = inserted; 4251 (read_non_regular,
4260 non_regular_nbytes = trytry; 4252 format_save_value ("iii", (ptrdiff_t) fd, inserted, trytry),
4261 nbytes = internal_condition_case_1 (read_non_regular, 4253 Qerror, read_non_regular_quit);
4262 Qnil, Qerror, 4254
4263 read_non_regular_quit);
4264 if (NILP (nbytes)) 4255 if (NILP (nbytes))
4265 { 4256 {
4266 read_quit = 1; 4257 read_quit = 1;
@@ -5507,7 +5498,7 @@ static Lisp_Object
5507do_auto_save_unwind (Lisp_Object arg) /* used as unwind-protect function */ 5498do_auto_save_unwind (Lisp_Object arg) /* used as unwind-protect function */
5508 5499
5509{ 5500{
5510 FILE *stream = XSAVE_POINTER (arg); 5501 FILE *stream = XSAVE_POINTER (arg, 0);
5511 auto_saving = 0; 5502 auto_saving = 0;
5512 if (stream != NULL) 5503 if (stream != NULL)
5513 { 5504 {
diff --git a/src/font.c b/src/font.c
index c4153428147..89931f6ec76 100644
--- a/src/font.c
+++ b/src/font.c
@@ -1857,7 +1857,7 @@ otf_open (Lisp_Object file)
1857 OTF *otf; 1857 OTF *otf;
1858 1858
1859 if (! NILP (val)) 1859 if (! NILP (val))
1860 otf = XSAVE_POINTER (XCDR (val)); 1860 otf = XSAVE_POINTER (XCDR (val), 0);
1861 else 1861 else
1862 { 1862 {
1863 otf = STRINGP (file) ? OTF_open (SSDATA (file)) : NULL; 1863 otf = STRINGP (file) ? OTF_open (SSDATA (file)) : NULL;
diff --git a/src/ftfont.c b/src/ftfont.c
index 1d7678bfe09..5bf91832c7c 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -400,7 +400,7 @@ ftfont_lookup_cache (Lisp_Object key, enum ftfont_cache_for cache_for)
400 else 400 else
401 { 401 {
402 val = XCDR (cache); 402 val = XCDR (cache);
403 cache_data = XSAVE_POINTER (val); 403 cache_data = XSAVE_POINTER (val, 0);
404 } 404 }
405 405
406 if (cache_for == FTFONT_CACHE_FOR_ENTITY) 406 if (cache_for == FTFONT_CACHE_FOR_ENTITY)
@@ -466,7 +466,7 @@ ftfont_get_fc_charset (Lisp_Object entity)
466 466
467 cache = ftfont_lookup_cache (entity, FTFONT_CACHE_FOR_CHARSET); 467 cache = ftfont_lookup_cache (entity, FTFONT_CACHE_FOR_CHARSET);
468 val = XCDR (cache); 468 val = XCDR (cache);
469 cache_data = XSAVE_POINTER (val); 469 cache_data = XSAVE_POINTER (val, 0);
470 return cache_data->fc_charset; 470 return cache_data->fc_charset;
471} 471}
472 472
@@ -1198,9 +1198,9 @@ ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
1198 filename = XCAR (val); 1198 filename = XCAR (val);
1199 idx = XCDR (val); 1199 idx = XCDR (val);
1200 val = XCDR (cache); 1200 val = XCDR (cache);
1201 cache_data = XSAVE_POINTER (XCDR (cache)); 1201 cache_data = XSAVE_POINTER (XCDR (cache), 0);
1202 ft_face = cache_data->ft_face; 1202 ft_face = cache_data->ft_face;
1203 if (XSAVE_INTEGER (val) > 0) 1203 if (XSAVE_INTEGER (val, 1) > 0)
1204 { 1204 {
1205 /* FT_Face in this cache is already used by the different size. */ 1205 /* FT_Face in this cache is already used by the different size. */
1206 if (FT_New_Size (ft_face, &ft_size) != 0) 1206 if (FT_New_Size (ft_face, &ft_size) != 0)
@@ -1211,13 +1211,13 @@ ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
1211 return Qnil; 1211 return Qnil;
1212 } 1212 }
1213 } 1213 }
1214 XSAVE_INTEGER (val)++; 1214 XSAVE_INTEGER (val, 1)++;
1215 size = XINT (AREF (entity, FONT_SIZE_INDEX)); 1215 size = XINT (AREF (entity, FONT_SIZE_INDEX));
1216 if (size == 0) 1216 if (size == 0)
1217 size = pixel_size; 1217 size = pixel_size;
1218 if (FT_Set_Pixel_Sizes (ft_face, size, size) != 0) 1218 if (FT_Set_Pixel_Sizes (ft_face, size, size) != 0)
1219 { 1219 {
1220 if (XSAVE_INTEGER (val) == 0) 1220 if (XSAVE_INTEGER (val, 1) == 0)
1221 FT_Done_Face (ft_face); 1221 FT_Done_Face (ft_face);
1222 return Qnil; 1222 return Qnil;
1223 } 1223 }
@@ -1326,10 +1326,10 @@ ftfont_close (FRAME_PTR f, struct font *font)
1326 cache = ftfont_lookup_cache (val, FTFONT_CACHE_FOR_FACE); 1326 cache = ftfont_lookup_cache (val, FTFONT_CACHE_FOR_FACE);
1327 eassert (CONSP (cache)); 1327 eassert (CONSP (cache));
1328 val = XCDR (cache); 1328 val = XCDR (cache);
1329 (XSAVE_INTEGER (val))--; 1329 XSAVE_INTEGER (val, 1)--;
1330 if (XSAVE_INTEGER (val) == 0) 1330 if (XSAVE_INTEGER (val, 1) == 0)
1331 { 1331 {
1332 struct ftfont_cache_data *cache_data = XSAVE_POINTER (val); 1332 struct ftfont_cache_data *cache_data = XSAVE_POINTER (val, 0);
1333 1333
1334 FT_Done_Face (cache_data->ft_face); 1334 FT_Done_Face (cache_data->ft_face);
1335#ifdef HAVE_LIBOTF 1335#ifdef HAVE_LIBOTF
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 259e0e971fd..f045deacd33 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1650,7 +1650,7 @@ xg_dialog_response_cb (GtkDialog *w,
1650static Lisp_Object 1650static Lisp_Object
1651pop_down_dialog (Lisp_Object arg) 1651pop_down_dialog (Lisp_Object arg)
1652{ 1652{
1653 struct xg_dialog_data *dd = XSAVE_POINTER (arg); 1653 struct xg_dialog_data *dd = XSAVE_POINTER (arg, 0);
1654 1654
1655 block_input (); 1655 block_input ();
1656 if (dd->w) gtk_widget_destroy (dd->w); 1656 if (dd->w) gtk_widget_destroy (dd->w);
diff --git a/src/keymap.c b/src/keymap.c
index 82c9e980221..a9266120e86 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -565,14 +565,13 @@ map_keymap_char_table_item (Lisp_Object args, Lisp_Object key, Lisp_Object val)
565{ 565{
566 if (!NILP (val)) 566 if (!NILP (val))
567 { 567 {
568 map_keymap_function_t fun = XSAVE_POINTER (XCAR (args)); 568 map_keymap_function_t fun = XSAVE_POINTER (args, 0);
569 args = XCDR (args);
570 /* If the key is a range, make a copy since map_char_table modifies 569 /* If the key is a range, make a copy since map_char_table modifies
571 it in place. */ 570 it in place. */
572 if (CONSP (key)) 571 if (CONSP (key))
573 key = Fcons (XCAR (key), XCDR (key)); 572 key = Fcons (XCAR (key), XCDR (key));
574 map_keymap_item (fun, XCDR (args), key, val, 573 map_keymap_item (fun, XSAVE_OBJECT (args, 2), key,
575 XSAVE_POINTER (XCAR (args))); 574 val, XSAVE_POINTER (args, 1));
576 } 575 }
577} 576}
578 577
@@ -610,12 +609,8 @@ map_keymap_internal (Lisp_Object map,
610 } 609 }
611 } 610 }
612 else if (CHAR_TABLE_P (binding)) 611 else if (CHAR_TABLE_P (binding))
613 { 612 map_char_table (map_keymap_char_table_item, Qnil, binding,
614 map_char_table (map_keymap_char_table_item, Qnil, binding, 613 format_save_value ("ppo", fun, data, args));
615 Fcons (make_save_value ((void *) fun, 0),
616 Fcons (make_save_value (data, 0),
617 args)));
618 }
619 } 614 }
620 UNGCPRO; 615 UNGCPRO;
621 return tail; 616 return tail;
diff --git a/src/lisp.h b/src/lisp.h
index 3ac2bda94c5..31028e14679 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1418,13 +1418,25 @@ struct Lisp_Save_Value
1418 } data[4]; 1418 } data[4];
1419 }; 1419 };
1420 1420
1421/* Compatibility macro to set and extract saved pointer. */ 1421/* Macro to set and extract Nth saved pointer. Type
1422 checking is ugly because it's used as an lvalue. */
1422 1423
1423#define XSAVE_POINTER(obj) XSAVE_VALUE (obj)->data[0].pointer 1424#define XSAVE_POINTER(obj, n) \
1425 XSAVE_VALUE (obj)->data[(eassert (XSAVE_VALUE (obj)->type \
1426 ## n == SAVE_POINTER), n)].pointer
1424 1427
1425/* Likewise for the saved integer. */ 1428/* Likewise for the saved integer. */
1426 1429
1427#define XSAVE_INTEGER(obj) XSAVE_VALUE (obj)->data[1].integer 1430#define XSAVE_INTEGER(obj, n) \
1431 XSAVE_VALUE (obj)->data[(eassert (XSAVE_VALUE (obj)->type \
1432 ## n == SAVE_INTEGER), n)].integer
1433
1434/* Macro to extract Nth saved object. This is never used as
1435 an lvalue, so we can do more convenient type checking. */
1436
1437#define XSAVE_OBJECT(obj, n) \
1438 (eassert (XSAVE_VALUE (obj)->type ## n == SAVE_OBJECT), \
1439 XSAVE_VALUE (obj)->data[n].object)
1428 1440
1429/* A miscellaneous object, when it's on the free list. */ 1441/* A miscellaneous object, when it's on the free list. */
1430struct Lisp_Free 1442struct Lisp_Free
@@ -2926,7 +2938,6 @@ extern void memory_warnings (void *, void (*warnfun) (const char *));
2926 2938
2927/* Defined in alloc.c. */ 2939/* Defined in alloc.c. */
2928extern void check_pure_size (void); 2940extern void check_pure_size (void);
2929extern Lisp_Object allocate_misc (enum Lisp_Misc_Type);
2930extern void free_misc (Lisp_Object); 2941extern void free_misc (Lisp_Object);
2931extern void allocate_string_data (struct Lisp_String *, EMACS_INT, EMACS_INT); 2942extern void allocate_string_data (struct Lisp_String *, EMACS_INT, EMACS_INT);
2932extern void malloc_warning (const char *); 2943extern void malloc_warning (const char *);
@@ -3012,8 +3023,8 @@ extern bool abort_on_gc;
3012extern Lisp_Object make_float (double); 3023extern Lisp_Object make_float (double);
3013extern void display_malloc_warning (void); 3024extern void display_malloc_warning (void);
3014extern ptrdiff_t inhibit_garbage_collection (void); 3025extern ptrdiff_t inhibit_garbage_collection (void);
3026extern Lisp_Object format_save_value (const char *, ...);
3015extern Lisp_Object make_save_value (void *, ptrdiff_t); 3027extern Lisp_Object make_save_value (void *, ptrdiff_t);
3016extern void free_save_value (Lisp_Object);
3017extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); 3028extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);
3018extern void free_marker (Lisp_Object); 3029extern void free_marker (Lisp_Object);
3019extern void free_cons (struct Lisp_Cons *); 3030extern void free_cons (struct Lisp_Cons *);
diff --git a/src/lread.c b/src/lread.c
index ced690a77b0..a01cf099b49 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1357,7 +1357,7 @@ Return t if the file exists and loads successfully. */)
1357static Lisp_Object 1357static Lisp_Object
1358load_unwind (Lisp_Object arg) /* Used as unwind-protect function in load. */ 1358load_unwind (Lisp_Object arg) /* Used as unwind-protect function in load. */
1359{ 1359{
1360 FILE *stream = XSAVE_POINTER (arg); 1360 FILE *stream = XSAVE_POINTER (arg, 0);
1361 if (stream != NULL) 1361 if (stream != NULL)
1362 { 1362 {
1363 block_input (); 1363 block_input ();
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 3e6fa54b047..b0369e76a27 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -1347,7 +1347,7 @@ struct Popdown_data
1347static Lisp_Object 1347static Lisp_Object
1348pop_down_menu (Lisp_Object arg) 1348pop_down_menu (Lisp_Object arg)
1349{ 1349{
1350 struct Popdown_data *unwind_data = XSAVE_POINTER (arg); 1350 struct Popdown_data *unwind_data = XSAVE_POINTER (arg, 0);
1351 1351
1352 block_input (); 1352 block_input ();
1353 if (popup_activated_flag) 1353 if (popup_activated_flag)
diff --git a/src/nsterm.h b/src/nsterm.h
index 7732e6d27cc..0cf4aa60d08 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -675,9 +675,9 @@ struct x_output
675#define FRAME_FONT(f) ((f)->output_data.ns->font) 675#define FRAME_FONT(f) ((f)->output_data.ns->font)
676 676
677#ifdef __OBJC__ 677#ifdef __OBJC__
678#define XNS_SCROLL_BAR(vec) ((id) XSAVE_POINTER (vec)) 678#define XNS_SCROLL_BAR(vec) ((id) XSAVE_POINTER (vec, 0))
679#else 679#else
680#define XNS_SCROLL_BAR(vec) XSAVE_POINTER (vec) 680#define XNS_SCROLL_BAR(vec) XSAVE_POINTER (vec, 0)
681#endif 681#endif
682 682
683/* Compute pixel size for vertical scroll bars */ 683/* Compute pixel size for vertical scroll bars */
diff --git a/src/xfns.c b/src/xfns.c
index fe99d36f9f4..65148d1c9e1 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -5292,7 +5292,7 @@ file_dialog_unmap_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5292static Lisp_Object 5292static Lisp_Object
5293clean_up_file_dialog (Lisp_Object arg) 5293clean_up_file_dialog (Lisp_Object arg)
5294{ 5294{
5295 Widget dialog = XSAVE_POINTER (arg); 5295 Widget dialog = XSAVE_POINTER (arg, 0);
5296 5296
5297 /* Clean up. */ 5297 /* Clean up. */
5298 block_input (); 5298 block_input ();
diff --git a/src/xmenu.c b/src/xmenu.c
index 6d880993d19..7f6914d26ac 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -1413,7 +1413,7 @@ pop_down_menu (Lisp_Object arg)
1413{ 1413{
1414 popup_activated_flag = 0; 1414 popup_activated_flag = 0;
1415 block_input (); 1415 block_input ();
1416 gtk_widget_destroy (GTK_WIDGET (XSAVE_POINTER (arg))); 1416 gtk_widget_destroy (GTK_WIDGET (XSAVE_POINTER (arg, 0)));
1417 unblock_input (); 1417 unblock_input ();
1418 return Qnil; 1418 return Qnil;
1419} 1419}
@@ -1610,7 +1610,7 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv,
1610static Lisp_Object 1610static Lisp_Object
1611cleanup_widget_value_tree (Lisp_Object arg) 1611cleanup_widget_value_tree (Lisp_Object arg)
1612{ 1612{
1613 free_menubar_widget_value_tree (XSAVE_POINTER (arg)); 1613 free_menubar_widget_value_tree (XSAVE_POINTER (arg, 0));
1614 return Qnil; 1614 return Qnil;
1615} 1615}
1616 1616
@@ -2236,8 +2236,8 @@ menu_help_callback (char const *help_string, int pane, int item)
2236static Lisp_Object 2236static Lisp_Object
2237pop_down_menu (Lisp_Object arg) 2237pop_down_menu (Lisp_Object arg)
2238{ 2238{
2239 FRAME_PTR f = XSAVE_POINTER (Fcar (arg)); 2239 FRAME_PTR f = XSAVE_POINTER (arg, 0);
2240 XMenu *menu = XSAVE_POINTER (Fcdr (arg)); 2240 XMenu *menu = XSAVE_POINTER (arg, 1);
2241 2241
2242 block_input (); 2242 block_input ();
2243#ifndef MSDOS 2243#ifndef MSDOS
@@ -2479,8 +2479,7 @@ xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps,
2479#endif 2479#endif
2480 2480
2481 record_unwind_protect (pop_down_menu, 2481 record_unwind_protect (pop_down_menu,
2482 Fcons (make_save_value (f, 0), 2482 format_save_value ("pp", f, menu));
2483 make_save_value (menu, 0)));
2484 2483
2485 /* Help display under X won't work because XMenuActivate contains 2484 /* Help display under X won't work because XMenuActivate contains
2486 a loop that doesn't give Emacs a chance to process it. */ 2485 a loop that doesn't give Emacs a chance to process it. */
diff --git a/src/xselect.c b/src/xselect.c
index 9abfb2931f8..b7cdf70ff77 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -1120,7 +1120,7 @@ unexpect_property_change (struct prop_location *location)
1120static Lisp_Object 1120static Lisp_Object
1121wait_for_property_change_unwind (Lisp_Object loc) 1121wait_for_property_change_unwind (Lisp_Object loc)
1122{ 1122{
1123 struct prop_location *location = XSAVE_POINTER (loc); 1123 struct prop_location *location = XSAVE_POINTER (loc, 0);
1124 1124
1125 unexpect_property_change (location); 1125 unexpect_property_change (location);
1126 if (location == property_change_reply_object) 1126 if (location == property_change_reply_object)