From 27e498e6e5fea8ac64c90ac13678b537b7b12302 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 16 Jul 2013 14:35:45 -0700 Subject: [PATCH] New unwind-protect flavors to better type-check C callbacks. This also lessens the need to write wrappers for callbacks, and the need for make_save_pointer. * alloca.c (free_save_value): * atimer.c (run_all_atimers): Now extern. * alloc.c (safe_alloca_unwind): * atimer.c (unwind_stop_other_atimers): * keyboard.c (cancel_hourglass_unwind) [HAVE_WINDOW_SYSTEM]: * menu.c (cleanup_popup_menu) [HAVE_NS]: * minibuf.c (choose_minibuf_frame_1): * process.c (make_serial_process_unwind): * xdisp.h (pop_message_unwind): * xselect.c (queue_selection_requests_unwind): Remove no-longer-needed wrapper. All uses replaced by the wrappee. * alloca.c (record_xmalloc): Prefer record_unwind_protect_ptr to record_unwind_protect with make_save_pointer. * alloca.c (Fgarbage_collect): Prefer record_unwind_protect_void to passing a dummy. * buffer.c (restore_buffer): * window.c (restore_window_configuration): * xfns.c, w32fns.c (do_unwind_create_frame) New wrapper. All record-unwind uses of wrappee changed. * buffer.c (set_buffer_if_live): * callproc.c (call_process_cleanup, delete_temp_file): * coding.c (code_conversion_restore): * dired.c (directory_files_internal_w32_unwind) [WINDOWSNT]: * editfns.c (save_excursion_restore) (subst_char_in_region_unwind, subst_char_in_region_unwind_1) (save_restriction_restore): * eval.c (restore_stack_limits, un_autoload): * fns.c (require_unwind): * keyboard.c (recursive_edit_unwind, tracking_off): * lread.c (record_load_unwind, load_warn_old_style_backquotes): * macros.c (pop_kbd_macro, restore_menu_items): * nsfns.m (unwind_create_frame): * print.c (print_unwind): * process.c (start_process_unwind): * search.c (unwind_set_match_data): * window.c (select_window_norecord, select_frame_norecord): * xdisp.c (unwind_with_echo_area_buffer, unwind_format_mode_line) (fast_set_selected_frame): * xfns.c, w32fns.c (unwind_create_tip_frame): Return void, not a dummy Lisp_Object. All uses changed. * buffer.h (set_buffer_if_live): Move decl here from lisp.h. * callproc.c (call_process_kill): * fileio.c (restore_point_unwind, decide_coding_unwind) (build_annotations_unwind): * insdel.c (Fcombine_after_change_execute_1): * keyboard.c (read_char_help_form_unwind): * menu.c (unuse_menu_items): * minibuf.c (run_exit_minibuf_hook, read_minibuf_unwind): * sound.c (sound_cleanup): * xdisp.c (unwind_redisplay): * xfns.c (clean_up_dialog): * xselect.c (x_selection_request_lisp_error, x_catch_errors_unwind): Accept no args and return void, instead of accepting and returning a dummy Lisp_Object. All uses changed. * cygw32.c (fchdir_unwind): * fileio.c (close_file_unwind): * keyboard.c (restore_kboard_configuration): * lread.c (readevalllop_1): * process.c (wait_reading_process_output_unwind): Accept int and return void, rather than accepting an Emacs integer and returning a dummy object. In some cases this fixes an unlikely bug when the corresponding int is outside Emacs integer range. All uses changed. * dired.c (directory_files_internal_unwind): * fileio.c (do_auto_save_unwind): * gtkutil.c (pop_down_dialog): * insdel.c (reset_var_on_error): * lread.c (load_unwind): * xfns.c (clean_up_file_dialog): * xmenu.c, nsmenu.m (pop_down_menu): * xmenu.c (cleanup_widget_value_tree): * xselect.c (wait_for_property_change_unwind): Accept pointer and return void, rather than accepting an Emacs save value encapsulating the pointer and returning a dummy object. All uses changed. * editfns.c (Fformat): Update the saved pointer directly via set_unwind_protect_ptr rather than indirectly via make_save_pointer. * eval.c (specpdl_func): Remove. All uses replaced by definiens. (unwind_body): New function. (record_unwind_protect): First arg is now a function returning void, not a dummy Lisp_Object. (record_unwind_protect_ptr, record_unwind_protect_int) (record_unwind_protect_void): New functions. (unbind_to): Support SPECPDL_UNWIND_PTR etc. * fileio.c (struct auto_save_unwind): New type. (do_auto_save_unwind): Use it. (do_auto_save_unwind_1): Remove; subsumed by new do_auto_save_unwind. * insdel.c (struct rvoe_arg): New type. (reset_var_on_error): Use it. * lisp.h (SPECPDL_UNWIND_PTR, SPECPDL_UNWIND_INT, SPECPDL_UNWIND_VOID): New constants. (specbinding_func): Remove; there are now several such functions. (union specbinding): New members unwind_ptr, unwind_int, unwind_void. (set_unwind_protect_ptr): New function. * xselect.c: Remove unnecessary forward decls, to simplify maintenance. --- src/ChangeLog | 101 +++++++++++++++++++++++++++++++++++++++++++++++++ src/alloc.c | 20 +++------- src/atimer.c | 12 +----- src/atimer.h | 2 +- src/buffer.c | 9 ++++- src/buffer.h | 2 + src/bytecode.c | 6 +-- src/callproc.c | 15 +++----- src/coding.c | 3 +- src/cygw32.c | 11 +++--- src/dired.c | 16 +++----- src/editfns.c | 21 ++++------ src/eval.c | 77 +++++++++++++++++++++++++++---------- src/fileio.c | 57 ++++++++++++---------------- src/fns.c | 4 +- src/gtkutil.c | 10 ++--- src/insdel.c | 36 +++++++++++------- src/keyboard.c | 52 ++++++++----------------- src/keyboard.h | 2 +- src/lisp.h | 74 ++++++++++++++++++++---------------- src/lread.c | 27 ++++++------- src/macros.c | 3 +- src/menu.c | 22 +++-------- src/minibuf.c | 33 ++++++---------- src/nsfns.m | 7 +--- src/nsmenu.m | 10 ++--- src/print.c | 3 +- src/process.c | 33 +++++----------- src/search.c | 4 +- src/sound.c | 10 ++--- src/w32fns.c | 12 ++++-- src/window.c | 20 ++++++---- src/window.h | 1 + src/xdisp.c | 40 +++++++------------- src/xfns.c | 35 +++++++++-------- src/xmenu.c | 34 +++++++---------- src/xselect.c | 53 ++++++-------------------- 37 files changed, 445 insertions(+), 432 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index f234fef84a..8474e8aa5e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,106 @@ 2013-07-16 Paul Eggert + New unwind-protect flavors to better type-check C callbacks. + This also lessens the need to write wrappers for callbacks, + and the need for make_save_pointer. + * alloca.c (free_save_value): + * atimer.c (run_all_atimers): + Now extern. + * alloc.c (safe_alloca_unwind): + * atimer.c (unwind_stop_other_atimers): + * keyboard.c (cancel_hourglass_unwind) [HAVE_WINDOW_SYSTEM]: + * menu.c (cleanup_popup_menu) [HAVE_NS]: + * minibuf.c (choose_minibuf_frame_1): + * process.c (make_serial_process_unwind): + * xdisp.h (pop_message_unwind): + * xselect.c (queue_selection_requests_unwind): + Remove no-longer-needed wrapper. All uses replaced by the wrappee. + * alloca.c (record_xmalloc): + Prefer record_unwind_protect_ptr to record_unwind_protect with + make_save_pointer. + * alloca.c (Fgarbage_collect): + Prefer record_unwind_protect_void to passing a dummy. + * buffer.c (restore_buffer): + * window.c (restore_window_configuration): + * xfns.c, w32fns.c (do_unwind_create_frame) + New wrapper. All record-unwind uses of wrappee changed. + * buffer.c (set_buffer_if_live): + * callproc.c (call_process_cleanup, delete_temp_file): + * coding.c (code_conversion_restore): + * dired.c (directory_files_internal_w32_unwind) [WINDOWSNT]: + * editfns.c (save_excursion_restore) + (subst_char_in_region_unwind, subst_char_in_region_unwind_1) + (save_restriction_restore): + * eval.c (restore_stack_limits, un_autoload): + * fns.c (require_unwind): + * keyboard.c (recursive_edit_unwind, tracking_off): + * lread.c (record_load_unwind, load_warn_old_style_backquotes): + * macros.c (pop_kbd_macro, restore_menu_items): + * nsfns.m (unwind_create_frame): + * print.c (print_unwind): + * process.c (start_process_unwind): + * search.c (unwind_set_match_data): + * window.c (select_window_norecord, select_frame_norecord): + * xdisp.c (unwind_with_echo_area_buffer, unwind_format_mode_line) + (fast_set_selected_frame): + * xfns.c, w32fns.c (unwind_create_tip_frame): + Return void, not a dummy Lisp_Object. All uses changed. + * buffer.h (set_buffer_if_live): Move decl here from lisp.h. + * callproc.c (call_process_kill): + * fileio.c (restore_point_unwind, decide_coding_unwind) + (build_annotations_unwind): + * insdel.c (Fcombine_after_change_execute_1): + * keyboard.c (read_char_help_form_unwind): + * menu.c (unuse_menu_items): + * minibuf.c (run_exit_minibuf_hook, read_minibuf_unwind): + * sound.c (sound_cleanup): + * xdisp.c (unwind_redisplay): + * xfns.c (clean_up_dialog): + * xselect.c (x_selection_request_lisp_error, x_catch_errors_unwind): + Accept no args and return void, instead of accepting and returning + a dummy Lisp_Object. All uses changed. + * cygw32.c (fchdir_unwind): + * fileio.c (close_file_unwind): + * keyboard.c (restore_kboard_configuration): + * lread.c (readevalllop_1): + * process.c (wait_reading_process_output_unwind): + Accept int and return void, rather than accepting an Emacs integer + and returning a dummy object. In some cases this fixes an + unlikely bug when the corresponding int is outside Emacs integer + range. All uses changed. + * dired.c (directory_files_internal_unwind): + * fileio.c (do_auto_save_unwind): + * gtkutil.c (pop_down_dialog): + * insdel.c (reset_var_on_error): + * lread.c (load_unwind): + * xfns.c (clean_up_file_dialog): + * xmenu.c, nsmenu.m (pop_down_menu): + * xmenu.c (cleanup_widget_value_tree): + * xselect.c (wait_for_property_change_unwind): + Accept pointer and return void, rather than accepting an Emacs + save value encapsulating the pointer and returning a dummy object. + All uses changed. + * editfns.c (Fformat): Update the saved pointer directly via + set_unwind_protect_ptr rather than indirectly via make_save_pointer. + * eval.c (specpdl_func): Remove. All uses replaced by definiens. + (unwind_body): New function. + (record_unwind_protect): First arg is now a function returning void, + not a dummy Lisp_Object. + (record_unwind_protect_ptr, record_unwind_protect_int) + (record_unwind_protect_void): New functions. + (unbind_to): Support SPECPDL_UNWIND_PTR etc. + * fileio.c (struct auto_save_unwind): New type. + (do_auto_save_unwind): Use it. + (do_auto_save_unwind_1): Remove; subsumed by new do_auto_save_unwind. + * insdel.c (struct rvoe_arg): New type. + (reset_var_on_error): Use it. + * lisp.h (SPECPDL_UNWIND_PTR, SPECPDL_UNWIND_INT, SPECPDL_UNWIND_VOID): + New constants. + (specbinding_func): Remove; there are now several such functions. + (union specbinding): New members unwind_ptr, unwind_int, unwind_void. + (set_unwind_protect_ptr): New function. + * xselect.c: Remove unnecessary forward decls, to simplify maintenance. + Be simpler and more consistent about reporting I/O errors. * fileio.c (Fcopy_file, Finsert_file_contents, Fwrite_region): Say "Read error" and "Write error", rather than "I/O error", or diff --git a/src/alloc.c b/src/alloc.c index b52e3de049..39f6a82b13 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -209,7 +209,6 @@ Lisp_Object Qchar_table_extra_slots; static Lisp_Object Qpost_gc_hook; -static void free_save_value (Lisp_Object); static void mark_terminals (void); static void gc_sweep (void); static Lisp_Object make_pure_vector (ptrdiff_t); @@ -813,22 +812,13 @@ xputenv (char const *string) memory_full (0); } -/* Unwind for SAFE_ALLOCA */ - -Lisp_Object -safe_alloca_unwind (Lisp_Object arg) -{ - free_save_value (arg); - return Qnil; -} - /* Return a newly allocated memory block of SIZE bytes, remembering to free it when unwinding. */ void * record_xmalloc (size_t size) { void *p = xmalloc (size); - record_unwind_protect (safe_alloca_unwind, make_save_pointer (p)); + record_unwind_protect_ptr (xfree, p); return p; } @@ -3397,7 +3387,9 @@ make_save_value (enum Lisp_Save_Type save_type, ...) return val; } -/* The most common task it to save just one C pointer. */ +/* Save just one C pointer. record_unwind_protect_ptr is simpler and + faster than combining this with record_unwind_protect, but + occasionally this function is useful for other reasons. */ Lisp_Object make_save_pointer (void *pointer) @@ -3412,7 +3404,7 @@ make_save_pointer (void *pointer) /* Free a Lisp_Save_Value object. Do not use this function if SAVE contains pointer other than returned by xmalloc. */ -static void +void free_save_value (Lisp_Object save) { xfree (XSAVE_POINTER (save, 0)); @@ -5227,7 +5219,7 @@ See Info node `(elisp)Garbage Collection'. */) /* Save what's currently displayed in the echo area. */ message_p = push_message (); - record_unwind_protect (pop_message_unwind, Qnil); + record_unwind_protect_void (pop_message_unwind); /* Save a copy of the contents of the stack, for debugging. */ #if MAX_SAVE_STACK > 0 diff --git a/src/atimer.c b/src/atimer.c index bb5294670d..219b3502ac 100644 --- a/src/atimer.c +++ b/src/atimer.c @@ -250,7 +250,7 @@ stop_other_atimers (struct atimer *t) /* Run all timers again, if some have been stopped with a call to stop_other_atimers. */ -static void +void run_all_atimers (void) { if (stopped_atimers) @@ -274,16 +274,6 @@ run_all_atimers (void) } -/* A version of run_all_atimers suitable for a record_unwind_protect. */ - -Lisp_Object -unwind_stop_other_atimers (Lisp_Object dummy) -{ - run_all_atimers (); - return Qnil; -} - - /* Arrange for a SIGALRM to arrive when the next timer is ripe. */ static void diff --git a/src/atimer.h b/src/atimer.h index 2a92f1bebe..a1825fc093 100644 --- a/src/atimer.h +++ b/src/atimer.h @@ -77,6 +77,6 @@ void do_pending_atimers (void); void init_atimer (void); void turn_on_atimers (bool); void stop_other_atimers (struct atimer *); -Lisp_Object unwind_stop_other_atimers (Lisp_Object); +void run_all_atimers (void); #endif /* EMACS_ATIMER_H */ diff --git a/src/buffer.c b/src/buffer.c index ae2398cb31..dfc6b8bcc0 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -2206,14 +2206,19 @@ ends when the current command terminates. Use `switch-to-buffer' or return buffer; } +void +restore_buffer (Lisp_Object buffer_or_name) +{ + Fset_buffer (buffer_or_name); +} + /* Set the current buffer to BUFFER provided if it is alive. */ -Lisp_Object +void set_buffer_if_live (Lisp_Object buffer) { if (BUFFER_LIVE_P (XBUFFER (buffer))) set_buffer_internal (XBUFFER (buffer)); - return Qnil; } DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only, diff --git a/src/buffer.h b/src/buffer.h index 276cca32e4..641a561caf 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -1073,6 +1073,8 @@ extern Lisp_Object buffer_local_value_1 (Lisp_Object, Lisp_Object); extern void record_buffer (Lisp_Object); extern void fix_overlays_before (struct buffer *, ptrdiff_t, ptrdiff_t); extern void mmap_set_vars (bool); +extern void restore_buffer (Lisp_Object); +extern void set_buffer_if_live (Lisp_Object); /* Set the current buffer to B. diff --git a/src/bytecode.c b/src/bytecode.c index be4fab4a53..e0e7b22ea1 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -1063,8 +1063,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, CASE (Bsave_window_excursion): /* Obsolete since 24.1. */ { - register ptrdiff_t count1 = SPECPDL_INDEX (); - record_unwind_protect (Fset_window_configuration, + ptrdiff_t count1 = SPECPDL_INDEX (); + record_unwind_protect (restore_window_configuration, Fcurrent_window_configuration (Qnil)); BEFORE_POTENTIAL_GC (); TOP = Fprogn (TOP); @@ -1089,7 +1089,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, } CASE (Bunwind_protect): /* FIXME: avoid closure for lexbind. */ - record_unwind_protect (Fprogn, POP); + record_unwind_protect (unwind_body, POP); NEXT; CASE (Bcondition_case): /* FIXME: ill-suited for lexbind. */ diff --git a/src/callproc.c b/src/callproc.c index f53750372d..f2c8c0c622 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -123,8 +123,8 @@ record_kill_process (struct Lisp_Process *p) /* Clean up when exiting call_process_cleanup. */ -static Lisp_Object -call_process_kill (Lisp_Object ignored) +static void +call_process_kill (void) { if (synch_process_fd >= 0) emacs_close (synch_process_fd); @@ -136,15 +136,13 @@ call_process_kill (Lisp_Object ignored) proc.pid = synch_process_pid; record_kill_process (&proc); } - - return Qnil; } /* Clean up when exiting Fcall_process. On MSDOS, delete the temporary file on any kind of termination. On Unix, kill the process and any children on termination by signal. */ -static Lisp_Object +static void call_process_cleanup (Lisp_Object arg) { #ifdef MSDOS @@ -162,7 +160,7 @@ call_process_cleanup (Lisp_Object arg) { ptrdiff_t count = SPECPDL_INDEX (); kill (-synch_process_pid, SIGINT); - record_unwind_protect (call_process_kill, make_number (0)); + record_unwind_protect_void (call_process_kill); message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); immediate_quit = 1; QUIT; @@ -183,8 +181,6 @@ call_process_cleanup (Lisp_Object arg) if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0')) unlink (SDATA (file)); #endif - - return Qnil; } #ifdef DOS_NT @@ -931,7 +927,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * return make_number (WEXITSTATUS (status)); } -static Lisp_Object +static void delete_temp_file (Lisp_Object name) { /* Suppress jka-compr handling, etc. */ @@ -953,7 +949,6 @@ delete_temp_file (Lisp_Object name) internal_delete_file (name); #endif unbind_to (count, Qnil); - return Qnil; } /* Create a temporary file suitable for storing the input data of diff --git a/src/coding.c b/src/coding.c index 8dcc4013c1..e779197bbd 100644 --- a/src/coding.c +++ b/src/coding.c @@ -7791,7 +7791,7 @@ make_conversion_work_buffer (bool multibyte) } -static Lisp_Object +static void code_conversion_restore (Lisp_Object arg) { Lisp_Object current, workbuf; @@ -7809,7 +7809,6 @@ code_conversion_restore (Lisp_Object arg) } set_buffer_internal (XBUFFER (current)); UNGCPRO; - return Qnil; } Lisp_Object diff --git a/src/cygw32.c b/src/cygw32.c index bbc3a49fd8..3e0f4ae180 100644 --- a/src/cygw32.c +++ b/src/cygw32.c @@ -23,12 +23,11 @@ along with GNU Emacs. If not, see . */ #include #include -static Lisp_Object -fchdir_unwind (Lisp_Object dir_fd) +static void +fchdir_unwind (int dir_fd) { - (void) fchdir (XFASTINT (dir_fd)); - (void) close (XFASTINT (dir_fd)); - return Qnil; + (void) fchdir (dir_fd); + (void) close (dir_fd); } static void @@ -40,7 +39,7 @@ chdir_to_default_directory () if (old_cwd_fd == -1) error ("could not open current directory: %s", strerror (errno)); - record_unwind_protect (fchdir_unwind, make_number (old_cwd_fd)); + record_unwind_protect_int (fchdir_unwind, old_cwd_fd); new_cwd = Funhandled_file_name_directory ( Fexpand_file_name (build_string ("."), Qnil)); diff --git a/src/dired.c b/src/dired.c index 42baa91534..2b79b54f2a 100644 --- a/src/dired.c +++ b/src/dired.c @@ -107,22 +107,20 @@ open_directory (char const *name, int *fdp) } #ifdef WINDOWSNT -Lisp_Object +void directory_files_internal_w32_unwind (Lisp_Object arg) { Vw32_get_true_file_attributes = arg; - return Qnil; } #endif -static Lisp_Object -directory_files_internal_unwind (Lisp_Object dh) +static void +directory_files_internal_unwind (void *dh) { - DIR *d = XSAVE_POINTER (dh, 0); + DIR *d = dh; block_input (); closedir (d); unblock_input (); - return Qnil; } /* Function shared by Fdirectory_files and Fdirectory_files_and_attributes. @@ -190,8 +188,7 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, /* Unfortunately, we can now invoke expand-file-name and file-attributes on filenames, both of which can throw, so we must do a proper unwind-protect. */ - record_unwind_protect (directory_files_internal_unwind, - make_save_pointer (d)); + record_unwind_protect_ptr (directory_files_internal_unwind, d); #ifdef WINDOWSNT if (attrs) @@ -490,8 +487,7 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag, if (!d) report_file_error ("Opening directory", dirname); - record_unwind_protect (directory_files_internal_unwind, - make_save_pointer (d)); + record_unwind_protect_ptr (directory_files_internal_unwind, d); /* Loop reading blocks */ /* (att3b compiler bug requires do a null comparison this way) */ diff --git a/src/editfns.c b/src/editfns.c index 1627ebd24b..b8fce7c193 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -853,7 +853,7 @@ save_excursion_save (void) /* Restore saved buffer before leaving `save-excursion' special form. */ -Lisp_Object +void save_excursion_restore (Lisp_Object info) { Lisp_Object tem, tem1, omark, nmark; @@ -927,7 +927,6 @@ save_excursion_restore (Lisp_Object info) out: free_misc (info); - return Qnil; } DEFUN ("save-excursion", Fsave_excursion, Ssave_excursion, 0, UNEVALLED, 0, @@ -2809,18 +2808,16 @@ determines whether case is significant or ignored. */) return make_number (0); } -static Lisp_Object +static void subst_char_in_region_unwind (Lisp_Object arg) { bset_undo_list (current_buffer, arg); - return arg; } -static Lisp_Object +static void subst_char_in_region_unwind_1 (Lisp_Object arg) { bset_filename (current_buffer, arg); - return arg; } DEFUN ("subst-char-in-region", Fsubst_char_in_region, @@ -3331,7 +3328,7 @@ save_restriction_save (void) } } -Lisp_Object +void save_restriction_restore (Lisp_Object data) { struct buffer *cur = NULL; @@ -3398,8 +3395,6 @@ save_restriction_restore (Lisp_Object data) if (cur) set_buffer_internal (cur); - - return Qnil; } DEFUN ("save-restriction", Fsave_restriction, Ssave_restriction, 0, UNEVALLED, 0, @@ -3627,7 +3622,7 @@ usage: (format STRING &rest OBJECTS) */) ptrdiff_t bufsize = sizeof initial_buffer; ptrdiff_t max_bufsize = STRING_BYTES_BOUND + 1; char *p; - Lisp_Object buf_save_value IF_LINT (= {0}); + ptrdiff_t buf_save_value_index IF_LINT (= 0); char *format, *end, *format_start; ptrdiff_t formatlen, nchars; /* True if the format is multibyte. */ @@ -4236,14 +4231,14 @@ usage: (format STRING &rest OBJECTS) */) { buf = xmalloc (bufsize); sa_must_free = 1; - buf_save_value = make_save_pointer (buf); - record_unwind_protect (safe_alloca_unwind, buf_save_value); + buf_save_value_index = SPECPDL_INDEX (); + record_unwind_protect_ptr (xfree, buf); memcpy (buf, initial_buffer, used); } else { buf = xrealloc (buf, bufsize); - set_save_pointer (buf_save_value, 0, buf); + set_unwind_protect_ptr (buf_save_value_index, buf); } p = buf + used; diff --git a/src/eval.c b/src/eval.c index 25cfc540ce..6632084146 100644 --- a/src/eval.c +++ b/src/eval.c @@ -152,13 +152,6 @@ specpdl_arg (union specbinding *pdl) return pdl->unwind.arg; } -static specbinding_func -specpdl_func (union specbinding *pdl) -{ - eassert (pdl->kind == SPECPDL_UNWIND); - return pdl->unwind.func; -} - Lisp_Object backtrace_function (union specbinding *pdl) { @@ -267,12 +260,11 @@ init_eval (void) /* Unwind-protect function used by call_debugger. */ -static Lisp_Object +static void restore_stack_limits (Lisp_Object data) { max_specpdl_size = XINT (XCAR (data)); max_lisp_eval_depth = XINT (XCDR (data)); - return Qnil; } /* Call the Lisp debugger, giving it argument ARG. */ @@ -450,23 +442,32 @@ usage: (cond CLAUSES...) */) DEFUN ("progn", Fprogn, Sprogn, 0, UNEVALLED, 0, doc: /* Eval BODY forms sequentially and return value of last one. usage: (progn BODY...) */) - (Lisp_Object args) + (Lisp_Object body) { - register Lisp_Object val = Qnil; + Lisp_Object val = Qnil; struct gcpro gcpro1; - GCPRO1 (args); + GCPRO1 (body); - while (CONSP (args)) + while (CONSP (body)) { - val = eval_sub (XCAR (args)); - args = XCDR (args); + val = eval_sub (XCAR (body)); + body = XCDR (body); } UNGCPRO; return val; } +/* Evaluate BODY sequentually, discarding its value. Suitable for + record_unwind_protect. */ + +void +unwind_body (Lisp_Object body) +{ + Fprogn (body); +} + DEFUN ("prog1", Fprog1, Sprog1, 1, UNEVALLED, 0, doc: /* Eval FIRST and BODY sequentially; return value from FIRST. The value of FIRST is saved during the evaluation of the remaining args, @@ -1149,7 +1150,7 @@ usage: (unwind-protect BODYFORM UNWINDFORMS...) */) Lisp_Object val; ptrdiff_t count = SPECPDL_INDEX (); - record_unwind_protect (Fprogn, Fcdr (args)); + record_unwind_protect (unwind_body, Fcdr (args)); val = eval_sub (Fcar (args)); return unbind_to (count, val); } @@ -1890,10 +1891,10 @@ this does nothing and returns nil. */) Qnil); } -Lisp_Object +void un_autoload (Lisp_Object oldqueue) { - register Lisp_Object queue, first, second; + Lisp_Object queue, first, second; /* Queue to unwind is current value of Vautoload_queue. oldqueue is the shadowed value to leave in Vautoload_queue. */ @@ -1910,7 +1911,6 @@ un_autoload (Lisp_Object oldqueue) Ffset (first, second); queue = XCDR (queue); } - return Qnil; } /* Load an autoloaded function. @@ -3191,7 +3191,7 @@ specbind (Lisp_Object symbol, Lisp_Object value) } void -record_unwind_protect (Lisp_Object (*function) (Lisp_Object), Lisp_Object arg) +record_unwind_protect (void (*function) (Lisp_Object), Lisp_Object arg) { specpdl_ptr->unwind.kind = SPECPDL_UNWIND; specpdl_ptr->unwind.func = function; @@ -3199,6 +3199,32 @@ record_unwind_protect (Lisp_Object (*function) (Lisp_Object), Lisp_Object arg) grow_specpdl (); } +void +record_unwind_protect_ptr (void (*function) (void *), void *arg) +{ + specpdl_ptr->unwind_ptr.kind = SPECPDL_UNWIND_PTR; + specpdl_ptr->unwind_ptr.func = function; + specpdl_ptr->unwind_ptr.arg = arg; + grow_specpdl (); +} + +void +record_unwind_protect_int (void (*function) (int), int arg) +{ + specpdl_ptr->unwind_int.kind = SPECPDL_UNWIND_INT; + specpdl_ptr->unwind_int.func = function; + specpdl_ptr->unwind_int.arg = arg; + grow_specpdl (); +} + +void +record_unwind_protect_void (void (*function) (void)) +{ + specpdl_ptr->unwind_void.kind = SPECPDL_UNWIND_VOID; + specpdl_ptr->unwind_void.func = function; + grow_specpdl (); +} + Lisp_Object unbind_to (ptrdiff_t count, Lisp_Object value) { @@ -3220,7 +3246,16 @@ unbind_to (ptrdiff_t count, Lisp_Object value) switch (specpdl_ptr->kind) { case SPECPDL_UNWIND: - specpdl_func (specpdl_ptr) (specpdl_arg (specpdl_ptr)); + specpdl_ptr->unwind.func (specpdl_ptr->unwind.arg); + break; + case SPECPDL_UNWIND_PTR: + specpdl_ptr->unwind_ptr.func (specpdl_ptr->unwind_ptr.arg); + break; + case SPECPDL_UNWIND_INT: + specpdl_ptr->unwind_int.func (specpdl_ptr->unwind_int.arg); + break; + case SPECPDL_UNWIND_VOID: + specpdl_ptr->unwind_void.func (); break; case SPECPDL_LET: /* If variable has a trivial value (no forwarding), we can diff --git a/src/fileio.c b/src/fileio.c index fba28f0927..1b5208e5f2 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -212,21 +212,19 @@ report_file_error (char const *string, Lisp_Object name) report_file_errno (string, name, errno); } -Lisp_Object -close_file_unwind (Lisp_Object fd) +void +close_file_unwind (int fd) { - emacs_close (XFASTINT (fd)); - return Qnil; + emacs_close (fd); } /* Restore point, having saved it as a marker. */ -Lisp_Object +void restore_point_unwind (Lisp_Object location) { Fgoto_char (location); Fset_marker (location, Qnil, Qnil); - return Qnil; } @@ -2078,7 +2076,7 @@ entries (depending on how Emacs was built). */) if (ifd < 0) report_file_error ("Opening input file", file); - record_unwind_protect (close_file_unwind, make_number (ifd)); + record_unwind_protect_int (close_file_unwind, ifd); if (fstat (ifd, &st) != 0) report_file_error ("Input file status", file); @@ -2119,7 +2117,7 @@ entries (depending on how Emacs was built). */) if (ofd < 0) report_file_error ("Opening output file", newname); - record_unwind_protect (close_file_unwind, make_number (ofd)); + record_unwind_protect_int (close_file_unwind, ofd); immediate_quit = 1; QUIT; @@ -3377,7 +3375,7 @@ verify (READ_BUF_SIZE <= INT_MAX); o remove all text properties. o set back the buffer multibyteness. */ -static Lisp_Object +static void decide_coding_unwind (Lisp_Object unwind_data) { Lisp_Object multibyte, undo_list, buffer; @@ -3396,8 +3394,6 @@ decide_coding_unwind (Lisp_Object unwind_data) /* Now we are safe to change the buffer's multibyteness directly. */ bset_enable_multibyte_characters (current_buffer, multibyte); bset_undo_list (current_buffer, undo_list); - - return Qnil; } /* Read from a non-regular file. STATE is a Lisp_Save_Value @@ -3573,7 +3569,7 @@ by calling `format-decode', which see. */) if (!NILP (replace)) record_unwind_protect (restore_point_unwind, Fpoint_marker ()); - record_unwind_protect (close_file_unwind, make_number (fd)); + record_unwind_protect_int (close_file_unwind, fd); if (fstat (fd, &st) != 0) report_file_error ("Input file status", orig_filename); @@ -4587,11 +4583,10 @@ by calling `format-decode', which see. */) static Lisp_Object build_annotations (Lisp_Object, Lisp_Object); -static Lisp_Object +static void build_annotations_unwind (Lisp_Object arg) { Vwrite_region_annotation_buffers = arg; - return Qnil; } /* Decide the coding-system to encode the data with. */ @@ -4901,7 +4896,7 @@ This calls `write-region-annotate-functions' at the start, and report_file_errno ("Opening output file", filename, open_errno); } - record_unwind_protect (close_file_unwind, make_number (desc)); + record_unwind_protect_int (close_file_unwind, desc); if (NUMBERP (append)) { @@ -5492,11 +5487,18 @@ auto_save_1 (void) Qnil, Qnil); } -static Lisp_Object -do_auto_save_unwind (Lisp_Object arg) /* used as unwind-protect function */ +struct auto_save_unwind +{ + FILE *stream; + bool auto_raise; +}; +static void +do_auto_save_unwind (void *arg) { - FILE *stream = XSAVE_POINTER (arg, 0); + struct auto_save_unwind *p = arg; + FILE *stream = p->stream; + minibuffer_auto_raise = p->auto_raise; auto_saving = 0; if (stream != NULL) { @@ -5504,15 +5506,6 @@ do_auto_save_unwind (Lisp_Object arg) /* used as unwind-protect function */ fclose (stream); unblock_input (); } - return Qnil; -} - -static Lisp_Object -do_auto_save_unwind_1 (Lisp_Object value) /* used as unwind-protect function */ - -{ - minibuffer_auto_raise = XINT (value); - return Qnil; } static Lisp_Object @@ -5555,6 +5548,7 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */) ptrdiff_t count = SPECPDL_INDEX (); bool orig_minibuffer_auto_raise = minibuffer_auto_raise; bool old_message_p = 0; + struct auto_save_unwind auto_save_unwind; struct gcpro gcpro1, gcpro2; if (max_specpdl_size < specpdl_size + 40) @@ -5566,7 +5560,7 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */) if (NILP (no_message)) { old_message_p = push_message (); - record_unwind_protect (pop_message_unwind, Qnil); + record_unwind_protect_void (pop_message_unwind); } /* Ordinarily don't quit within this function, @@ -5605,10 +5599,9 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */) stream = emacs_fopen (SSDATA (listfile), "w"); } - record_unwind_protect (do_auto_save_unwind, - make_save_pointer (stream)); - record_unwind_protect (do_auto_save_unwind_1, - make_number (minibuffer_auto_raise)); + auto_save_unwind.stream = stream; + auto_save_unwind.auto_raise = minibuffer_auto_raise; + record_unwind_protect_ptr (do_auto_save_unwind, &auto_save_unwind); minibuffer_auto_raise = 0; auto_saving = 1; auto_save_error_occurred = 0; diff --git a/src/fns.c b/src/fns.c index b056ecedb3..9fd0ad2a9d 100644 --- a/src/fns.c +++ b/src/fns.c @@ -2585,10 +2585,10 @@ particular subfeatures supported in this version of FEATURE. */) static Lisp_Object require_nesting_list; -static Lisp_Object +static void require_unwind (Lisp_Object old_value) { - return require_nesting_list = old_value; + require_nesting_list = old_value; } DEFUN ("require", Frequire, Srequire, 1, 3, 0, diff --git a/src/gtkutil.c b/src/gtkutil.c index 8ac58f1815..f8ddf6a90f 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -1650,10 +1650,10 @@ xg_dialog_response_cb (GtkDialog *w, /* Destroy the dialog. This makes it pop down. */ -static Lisp_Object -pop_down_dialog (Lisp_Object arg) +static void +pop_down_dialog (void *arg) { - struct xg_dialog_data *dd = XSAVE_POINTER (arg, 0); + struct xg_dialog_data *dd = arg; block_input (); if (dd->w) gtk_widget_destroy (dd->w); @@ -1663,8 +1663,6 @@ pop_down_dialog (Lisp_Object arg) g_main_loop_unref (dd->loop); unblock_input (); - - return Qnil; } /* If there are any emacs timers pending, add a timeout to main loop in DATA. @@ -1719,7 +1717,7 @@ xg_dialog_run (FRAME_PTR f, GtkWidget *w) g_signal_connect (G_OBJECT (w), "delete-event", G_CALLBACK (gtk_true), NULL); gtk_widget_show (w); - record_unwind_protect (pop_down_dialog, make_save_pointer (&dd)); + record_unwind_protect_ptr (pop_down_dialog, &dd); (void) xg_maybe_add_timer (&dd); g_main_loop_run (dd.loop); diff --git a/src/insdel.c b/src/insdel.c index ed68426424..15d585568a 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -1913,12 +1913,18 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, VARIABLE is the variable to maybe set to nil. NO-ERROR-FLAG is nil if there was an error, anything else meaning no error (so this function does nothing). */ -static Lisp_Object -reset_var_on_error (Lisp_Object val) +struct rvoe_arg { - if (NILP (XCDR (val))) - Fset (XCAR (val), Qnil); - return Qnil; + Lisp_Object *location; + bool errorp; +}; + +static void +reset_var_on_error (void *ptr) +{ + struct rvoe_arg *p = ptr; + if (p->errorp) + *p->location = Qnil; } /* Signal a change to the buffer immediately before it happens. @@ -1936,6 +1942,7 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t end_int, Lisp_Object preserve_marker; struct gcpro gcpro1, gcpro2, gcpro3; ptrdiff_t count = SPECPDL_INDEX (); + struct rvoe_arg rvoe_arg; if (inhibit_modification_hooks) return; @@ -1963,13 +1970,14 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t end_int, if (!NILP (Vbefore_change_functions)) { Lisp_Object args[3]; - Lisp_Object rvoe_arg = Fcons (Qbefore_change_functions, Qnil); + rvoe_arg.location = &Vbefore_change_functions; + rvoe_arg.errorp = 1; PRESERVE_VALUE; PRESERVE_START_END; /* Mark before-change-functions to be reset to nil in case of error. */ - record_unwind_protect (reset_var_on_error, rvoe_arg); + record_unwind_protect_ptr (reset_var_on_error, &rvoe_arg); /* Actually run the hook functions. */ args[0] = Qbefore_change_functions; @@ -1978,7 +1986,7 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t end_int, Frun_hook_with_args (3, args); /* There was no error: unarm the reset_on_error. */ - XSETCDR (rvoe_arg, Qt); + rvoe_arg.errorp = 0; } if (buffer_has_overlays ()) @@ -2009,6 +2017,8 @@ void signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins) { ptrdiff_t count = SPECPDL_INDEX (); + struct rvoe_arg rvoe_arg; + if (inhibit_modification_hooks) return; @@ -2042,10 +2052,11 @@ signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins) if (!NILP (Vafter_change_functions)) { Lisp_Object args[4]; - Lisp_Object rvoe_arg = Fcons (Qafter_change_functions, Qnil); + rvoe_arg.location = &Vafter_change_functions; + rvoe_arg.errorp = 1; /* Mark after-change-functions to be reset to nil in case of error. */ - record_unwind_protect (reset_var_on_error, rvoe_arg); + record_unwind_protect_ptr (reset_var_on_error, &rvoe_arg); /* Actually run the hook functions. */ args[0] = Qafter_change_functions; @@ -2055,7 +2066,7 @@ signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins) Frun_hook_with_args (4, args); /* There was no error: unarm the reset_on_error. */ - XSETCDR (rvoe_arg, Qt); + rvoe_arg.errorp = 0; } if (buffer_has_overlays ()) @@ -2075,11 +2086,10 @@ signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins) unbind_to (count, Qnil); } -static Lisp_Object +static void Fcombine_after_change_execute_1 (Lisp_Object val) { Vcombine_after_change_calls = val; - return val; } DEFUN ("combine-after-change-execute", Fcombine_after_change_execute, diff --git a/src/keyboard.c b/src/keyboard.c index e67da06ec2..07dce85ff2 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -357,7 +357,7 @@ Lisp_Object Qvertical_line; static Lisp_Object Qvertical_scroll_bar; Lisp_Object Qmenu_bar; -static Lisp_Object recursive_edit_unwind (Lisp_Object buffer); +static void recursive_edit_unwind (Lisp_Object buffer); static Lisp_Object command_loop (void); static Lisp_Object Qcommand_execute; EMACS_TIME timer_check (void); @@ -428,7 +428,7 @@ static void save_getcjmp (sys_jmp_buf); static void restore_getcjmp (sys_jmp_buf); static Lisp_Object apply_modifiers (int, Lisp_Object); static void clear_event (struct input_event *); -static Lisp_Object restore_kboard_configuration (Lisp_Object); +static void restore_kboard_configuration (int); #ifdef USABLE_SIGIO static void deliver_input_available_signal (int signo); #endif @@ -844,7 +844,7 @@ This function is called by the editor initialization to begin editing. */) return unbind_to (count, Qnil); } -Lisp_Object +void recursive_edit_unwind (Lisp_Object buffer) { if (BUFFERP (buffer)) @@ -852,7 +852,6 @@ recursive_edit_unwind (Lisp_Object buffer) command_loop_level--; update_mode_lines = 1; - return Qnil; } @@ -949,7 +948,7 @@ pop_kboard (void) from which further input is accepted. If F is non-nil, set its KBOARD as the current keyboard. - This function uses record_unwind_protect to return to the previous + This function uses record_unwind_protect_int to return to the previous state later. If Emacs is already in single_kboard mode, and F's keyboard is @@ -980,8 +979,7 @@ temporarily_switch_to_single_kboard (struct frame *f) else if (f != NULL) current_kboard = FRAME_KBOARD (f); single_kboard = 1; - record_unwind_protect (restore_kboard_configuration, - (was_locked ? Qt : Qnil)); + record_unwind_protect_int (restore_kboard_configuration, was_locked); } #if 0 /* This function is not needed anymore. */ @@ -990,26 +988,22 @@ record_single_kboard_state () { if (single_kboard) push_kboard (current_kboard); - record_unwind_protect (restore_kboard_configuration, - (single_kboard ? Qt : Qnil)); + record_unwind_protect_int (restore_kboard_configuration, single_kboard); } #endif -static Lisp_Object -restore_kboard_configuration (Lisp_Object was_locked) +static void +restore_kboard_configuration (int was_locked) { - if (NILP (was_locked)) - single_kboard = 0; - else + single_kboard = was_locked; + if (was_locked) { struct kboard *prev = current_kboard; - single_kboard = 1; pop_kboard (); /* The pop should not change the kboard. */ if (single_kboard && current_kboard != prev) emacs_abort (); } - return Qnil; } @@ -1237,7 +1231,7 @@ DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0, /* Restore mouse tracking enablement. See Ftrack_mouse for the only use of this function. */ -static Lisp_Object +static void tracking_off (Lisp_Object old_value) { do_mouse_tracking = old_value; @@ -1254,7 +1248,6 @@ tracking_off (Lisp_Object old_value) get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW); } } - return Qnil; } DEFUN ("track-mouse", Ftrack_mouse, Strack_mouse, 0, UNEVALLED, 0, @@ -1317,17 +1310,6 @@ static int read_key_sequence (Lisp_Object *, int, Lisp_Object, void safe_run_hooks (Lisp_Object); static void adjust_point_for_property (ptrdiff_t, bool); -/* Cancel hourglass from protect_unwind. - ARG is not used. */ -#ifdef HAVE_WINDOW_SYSTEM -static Lisp_Object -cancel_hourglass_unwind (Lisp_Object arg) -{ - cancel_hourglass (); - return Qnil; -} -#endif - /* The last boundary auto-added to buffer-undo-list. */ Lisp_Object last_undo_boundary; @@ -1562,7 +1544,7 @@ command_loop_1 (void) if (display_hourglass_p && NILP (Vexecuting_kbd_macro)) { - record_unwind_protect (cancel_hourglass_unwind, Qnil); + record_unwind_protect_void (cancel_hourglass); start_hourglass (); } #endif @@ -2204,14 +2186,13 @@ static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, bool *used_mouse_menu, static void record_char (Lisp_Object c); static Lisp_Object help_form_saved_window_configs; -static Lisp_Object -read_char_help_form_unwind (Lisp_Object arg) +static void +read_char_help_form_unwind (void) { Lisp_Object window_config = XCAR (help_form_saved_window_configs); help_form_saved_window_configs = XCDR (help_form_saved_window_configs); if (!NILP (window_config)) Fset_window_configuration (window_config); - return Qnil; } #define STOP_POLLING \ @@ -3199,7 +3180,7 @@ read_char (int commandflag, Lisp_Object map, help_form_saved_window_configs = Fcons (Fcurrent_window_configuration (Qnil), help_form_saved_window_configs); - record_unwind_protect (read_char_help_form_unwind, Qnil); + record_unwind_protect_void (read_char_help_form_unwind); call0 (Qhelp_form_show); cancel_echoing (); @@ -10193,8 +10174,7 @@ On such systems, Emacs starts a subshell instead of suspending. */) reset_all_sys_modes (); /* sys_suspend can get an error if it tries to fork a subshell and the system resources aren't available for that. */ - record_unwind_protect ((Lisp_Object (*) (Lisp_Object)) init_all_sys_modes, - Qnil); + record_unwind_protect_void (init_all_sys_modes); stuff_buffered_input (stuffstring); if (cannot_suspend) sys_subshell (); diff --git a/src/keyboard.h b/src/keyboard.h index 8bb1c409ef..daba94898d 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -341,7 +341,7 @@ enum menu_item_idx MENU_ITEMS_ITEM_LENGTH }; -extern Lisp_Object unuse_menu_items (Lisp_Object dummy); +extern void unuse_menu_items (void); /* This is how to deal with multibyte text if HAVE_MULTILINGUAL_MENU isn't defined. The use of HAVE_MULTILINGUAL_MENU could probably be diff --git a/src/lisp.h b/src/lisp.h index 6a551bb499..38413f831d 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -1814,23 +1814,8 @@ enum Lisp_Save_Type /* Special object used to hold a different values for later use. This is mostly used to package C integers and pointers to call - record_unwind_protect. A typical task is to pass just one C object - pointer to the unwind function. You should pack an object pointer with - make_save_pointer and then get it back with XSAVE_POINTER, e.g.: - - ... - struct my_data *md = get_my_data (); - record_unwind_protect (my_unwind, make_save_pointer (md)); - ... - - Lisp_Object my_unwind (Lisp_Object arg) - { - struct my_data *md = XSAVE_POINTER (arg, 0); - ... - } - - If you need to pass something else you can use make_save_value, - which allows you to pack up to SAVE_VALUE_SLOTS integers, pointers, + record_unwind_protect when two or more values need to be saved. + make_save_value lets you pack up to SAVE_VALUE_SLOTS integers, pointers, function pointers or Lisp_Objects and conveniently get them back with XSAVE_INTEGER, XSAVE_POINTER, XSAVE_FUNCPOINTER, and XSAVE_OBJECT macros: @@ -2701,10 +2686,11 @@ typedef jmp_buf sys_jmp_buf; used all over the place, needs to be fast, and needs to know the size of union specbinding. But only eval.c should access it. */ -typedef Lisp_Object (*specbinding_func) (Lisp_Object); - enum specbind_tag { - SPECPDL_UNWIND, /* An unwind_protect function. */ + SPECPDL_UNWIND, /* An unwind_protect function on Lisp_Object. */ + SPECPDL_UNWIND_PTR, /* Likewise, on void *. */ + SPECPDL_UNWIND_INT, /* Likewise, on int. */ + SPECPDL_UNWIND_VOID, /* Likewise, with no arg. */ SPECPDL_BACKTRACE, /* An element of the backtrace. */ SPECPDL_LET, /* A plain and simple dynamic let-binding. */ /* Tags greater than SPECPDL_LET must be "subkinds" of LET. */ @@ -2717,9 +2703,23 @@ union specbinding ENUM_BF (specbind_tag) kind : CHAR_BIT; struct { ENUM_BF (specbind_tag) kind : CHAR_BIT; + void (*func) (Lisp_Object); Lisp_Object arg; - specbinding_func func; } unwind; + struct { + ENUM_BF (specbind_tag) kind : CHAR_BIT; + void (*func) (void *); + void *arg; + } unwind_ptr; + struct { + ENUM_BF (specbind_tag) kind : CHAR_BIT; + void (*func) (int); + int arg; + } unwind_int; + struct { + ENUM_BF (specbind_tag) kind : CHAR_BIT; + void (*func) (void); + } unwind_void; struct { ENUM_BF (specbind_tag) kind : CHAR_BIT; /* `where' is not used in the case of SPECPDL_LET. */ @@ -2744,6 +2744,12 @@ SPECPDL_INDEX (void) return specpdl_ptr - specpdl; } +LISP_INLINE void +set_unwind_protect_ptr (ptrdiff_t count, void *arg) +{ + specpdl[count].unwind_ptr.arg = arg; +} + /* Everything needed to describe an active condition case. Members are volatile if their values need to survive _longjmp when @@ -3418,7 +3424,7 @@ extern void add_to_log (const char *, Lisp_Object, Lisp_Object); extern void check_message_stack (void); extern void setup_echo_area_for_printing (int); extern bool push_message (void); -extern Lisp_Object pop_message_unwind (Lisp_Object); +extern void pop_message_unwind (void); extern Lisp_Object restore_message_unwind (Lisp_Object); extern void restore_message (void); extern Lisp_Object current_message (void); @@ -3582,6 +3588,7 @@ extern void display_malloc_warning (void); extern ptrdiff_t inhibit_garbage_collection (void); extern Lisp_Object make_save_value (enum Lisp_Save_Type, ...); extern Lisp_Object make_save_pointer (void *); +extern void free_save_value (Lisp_Object); extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); extern void free_marker (Lisp_Object); extern void free_cons (struct Lisp_Cons *); @@ -3738,12 +3745,15 @@ extern Lisp_Object internal_condition_case_n (Lisp_Object (*) (ptrdiff_t, Lisp_Object *), ptrdiff_t, Lisp_Object *, Lisp_Object, Lisp_Object (*) (Lisp_Object, ptrdiff_t, Lisp_Object *)); extern void specbind (Lisp_Object, Lisp_Object); -extern void record_unwind_protect (Lisp_Object (*) (Lisp_Object), Lisp_Object); +extern void record_unwind_protect (void (*) (Lisp_Object), Lisp_Object); +extern void record_unwind_protect_int (void (*) (int), int); +extern void record_unwind_protect_ptr (void (*) (void *), void *); +extern void record_unwind_protect_void (void (*) (void)); extern Lisp_Object unbind_to (ptrdiff_t, Lisp_Object); extern _Noreturn void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2); extern _Noreturn void verror (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0); -extern Lisp_Object un_autoload (Lisp_Object); +extern void un_autoload (Lisp_Object); extern Lisp_Object call_debugger (Lisp_Object arg); extern void init_eval_once (void); extern Lisp_Object safe_call (ptrdiff_t, Lisp_Object, ...); @@ -3751,6 +3761,7 @@ extern Lisp_Object safe_call1 (Lisp_Object, Lisp_Object); extern Lisp_Object safe_call2 (Lisp_Object, Lisp_Object, Lisp_Object); extern void init_eval (void); extern void syms_of_eval (void); +extern void unwind_body (Lisp_Object); extern void record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs); extern void mark_specpdl (void); @@ -3766,8 +3777,8 @@ extern void insert1 (Lisp_Object); extern Lisp_Object format2 (const char *, Lisp_Object, Lisp_Object); extern Lisp_Object save_excursion_save (void); extern Lisp_Object save_restriction_save (void); -extern Lisp_Object save_excursion_restore (Lisp_Object); -extern Lisp_Object save_restriction_restore (Lisp_Object); +extern void save_excursion_restore (Lisp_Object); +extern void save_restriction_restore (Lisp_Object); extern _Noreturn void time_overflow (void); extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool); extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, @@ -3786,7 +3797,6 @@ extern void report_overlay_modification (Lisp_Object, Lisp_Object, bool, Lisp_Object, Lisp_Object, Lisp_Object); extern bool overlay_touches_p (ptrdiff_t); extern Lisp_Object Vbuffer_alist; -extern Lisp_Object set_buffer_if_live (Lisp_Object); extern Lisp_Object other_buffer_safely (Lisp_Object); extern Lisp_Object Qpriority, Qwindow, Qbefore_string, Qafter_string; extern Lisp_Object get_truename_buffer (Lisp_Object); @@ -3820,8 +3830,8 @@ extern Lisp_Object Qinsert_file_contents; extern Lisp_Object Qfile_name_history; extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object); EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */ -extern Lisp_Object close_file_unwind (Lisp_Object); -extern Lisp_Object restore_point_unwind (Lisp_Object); +extern void close_file_unwind (int); +extern void restore_point_unwind (Lisp_Object); extern _Noreturn void report_file_errno (const char *, Lisp_Object, int); extern _Noreturn void report_file_error (const char *, Lisp_Object); extern bool internal_delete_file (Lisp_Object); @@ -4258,7 +4268,6 @@ extern void init_system_name (void); enum MAX_ALLOCA { MAX_ALLOCA = 16 * 1024 }; -extern Lisp_Object safe_alloca_unwind (Lisp_Object); extern void *record_xmalloc (size_t); #define USE_SAFE_ALLOCA \ @@ -4282,8 +4291,7 @@ extern void *record_xmalloc (size_t); { \ (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \ sa_must_free = 1; \ - record_unwind_protect (safe_alloca_unwind, \ - make_save_pointer (buf)); \ + record_unwind_protect_ptr (xfree, buf); \ } \ } while (0) @@ -4310,7 +4318,7 @@ extern void *record_xmalloc (size_t); buf = xmalloc ((nelt) * word_size); \ arg_ = make_save_value (SAVE_TYPE_MEMORY, buf, nelt); \ sa_must_free = 1; \ - record_unwind_protect (safe_alloca_unwind, arg_); \ + record_unwind_protect (free_save_value, arg_); \ } \ else \ memory_full (SIZE_MAX); \ diff --git a/src/lread.c b/src/lread.c index a6c5b9c8a9..c4bc6fda81 100644 --- a/src/lread.c +++ b/src/lread.c @@ -145,7 +145,7 @@ static int read_emacs_mule_char (int, int (*) (int, Lisp_Object), static void readevalloop (Lisp_Object, FILE *, Lisp_Object, bool, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); -static Lisp_Object load_unwind (Lisp_Object); +static void load_unwind (void *); /* Functions that read one byte from the current source READCHARFUN or unreads one byte. If the integer argument C is -1, it returns @@ -952,10 +952,10 @@ safe_to_load_version (int fd) /* Callback for record_unwind_protect. Restore the old load list OLD, after loading a file successfully. */ -static Lisp_Object +static void record_load_unwind (Lisp_Object old) { - return Vloads_in_progress = old; + Vloads_in_progress = old; } /* This handler function is used via internal_condition_case_1. */ @@ -966,7 +966,7 @@ load_error_handler (Lisp_Object data) return Qnil; } -static Lisp_Object +static void load_warn_old_style_backquotes (Lisp_Object file) { if (!NILP (Vold_style_backquotes)) @@ -976,7 +976,6 @@ load_warn_old_style_backquotes (Lisp_Object file) args[1] = file; Fmessage (2, args); } - return Qnil; } DEFUN ("get-load-suffixes", Fget_load_suffixes, Sget_load_suffixes, 0, 0, 0, @@ -1323,7 +1322,7 @@ Return t if the file exists and loads successfully. */) message_with_string ("Loading %s...", file, 1); } - record_unwind_protect (load_unwind, make_save_pointer (stream)); + record_unwind_protect_ptr (load_unwind, stream); specbind (Qload_file_name, found); specbind (Qinhibit_file_name_operation, Qnil); specbind (Qload_in_progress, Qt); @@ -1376,17 +1375,16 @@ Return t if the file exists and loads successfully. */) return Qt; } -static Lisp_Object -load_unwind (Lisp_Object arg) /* Used as unwind-protect function in load. */ +static void +load_unwind (void *arg) { - FILE *stream = XSAVE_POINTER (arg, 0); + FILE *stream = arg; if (stream != NULL) { block_input (); fclose (stream); unblock_input (); } - return Qnil; } static bool @@ -1682,11 +1680,10 @@ build_load_history (Lisp_Object filename, bool entire) Vload_history); } -static Lisp_Object -readevalloop_1 (Lisp_Object old) +static void +readevalloop_1 (int old) { - load_convert_to_unibyte = ! NILP (old); - return Qnil; + load_convert_to_unibyte = old; } /* Signal an `end-of-file' error, if possible with file name @@ -1756,7 +1753,7 @@ readevalloop (Lisp_Object readcharfun, specbind (Qstandard_input, readcharfun); /* GCPROs readcharfun. */ specbind (Qcurrent_load_list, Qnil); - record_unwind_protect (readevalloop_1, load_convert_to_unibyte ? Qt : Qnil); + record_unwind_protect_int (readevalloop_1, load_convert_to_unibyte); load_convert_to_unibyte = !NILP (unibyte); /* If lexical binding is active (either because it was specified in diff --git a/src/macros.c b/src/macros.c index 48d23a977b..0c11efcdc9 100644 --- a/src/macros.c +++ b/src/macros.c @@ -279,7 +279,7 @@ each iteration of the macro. Iteration stops if LOOPFUNC returns nil. */) /* Restore Vexecuting_kbd_macro and executing_kbd_macro_index. Called when the unwind-protect in Fexecute_kbd_macro gets invoked. */ -static Lisp_Object +static void pop_kbd_macro (Lisp_Object info) { Lisp_Object tem; @@ -288,7 +288,6 @@ pop_kbd_macro (Lisp_Object info) executing_kbd_macro_index = XINT (XCAR (tem)); Vreal_this_command = XCDR (tem); Frun_hooks (1, &Qkbd_macro_termination_hook); - return Qnil; } DEFUN ("execute-kbd-macro", Fexecute_kbd_macro, Sexecute_kbd_macro, 1, 3, 0, diff --git a/src/menu.c b/src/menu.c index f5461326f3..6b4a22d305 100644 --- a/src/menu.c +++ b/src/menu.c @@ -102,10 +102,10 @@ finish_menu_items (void) { } -Lisp_Object -unuse_menu_items (Lisp_Object dummy) +void +unuse_menu_items (void) { - return menu_items_inuse = Qnil; + menu_items_inuse = Qnil; } /* Call when finished using the data for the current menu @@ -124,19 +124,10 @@ discard_menu_items (void) eassert (NILP (menu_items_inuse)); } -#ifdef HAVE_NS -static Lisp_Object -cleanup_popup_menu (Lisp_Object arg) -{ - discard_menu_items (); - return Qnil; -} -#endif - /* This undoes save_menu_items, and it is called by the specpdl unwind mechanism. */ -static Lisp_Object +static void restore_menu_items (Lisp_Object saved) { menu_items = XCAR (saved); @@ -148,7 +139,6 @@ restore_menu_items (Lisp_Object saved) menu_items_n_panes = XINT (XCAR (saved)); saved = XCDR (saved); menu_items_submenu_depth = XINT (XCAR (saved)); - return Qnil; } /* Push the whole state of menu_items processing onto the specpdl. @@ -1213,7 +1203,7 @@ no quit occurs and `x-popup-menu' returns nil. */) #endif /* HAVE_MENUS */ /* Now parse the lisp menus. */ - record_unwind_protect (unuse_menu_items, Qnil); + record_unwind_protect_void (unuse_menu_items); title = Qnil; GCPRO1 (title); @@ -1315,7 +1305,7 @@ no quit occurs and `x-popup-menu' returns nil. */) #endif #ifdef HAVE_NS /* FIXME: ns-specific, why? --Stef */ - record_unwind_protect (cleanup_popup_menu, Qnil); + record_unwind_protect_void (discard_menu_items); #endif /* Display them in a menu. */ diff --git a/src/minibuf.c b/src/minibuf.c index c51941a30b..2c33b83c11 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -137,13 +137,6 @@ choose_minibuf_frame (void) } } -static Lisp_Object -choose_minibuf_frame_1 (Lisp_Object ignore) -{ - choose_minibuf_frame (); - return Qnil; -} - DEFUN ("active-minibuffer-window", Factive_minibuffer_window, Sactive_minibuffer_window, 0, 0, 0, doc: /* Return the currently active minibuffer window, or nil if none. */) @@ -171,8 +164,8 @@ without invoking the usual minibuffer commands. */) /* Actual minibuffer invocation. */ -static Lisp_Object read_minibuf_unwind (Lisp_Object); -static Lisp_Object run_exit_minibuf_hook (Lisp_Object); +static void read_minibuf_unwind (void); +static void run_exit_minibuf_hook (void); /* Read a Lisp object from VAL and return it. If VAL is an empty @@ -474,20 +467,20 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, /* Prepare for restoring the current buffer since choose_minibuf_frame calling Fset_frame_selected_window may change it (Bug#12766). */ - record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); + record_unwind_protect (restore_buffer, Fcurrent_buffer ()); choose_minibuf_frame (); - record_unwind_protect (choose_minibuf_frame_1, Qnil); + record_unwind_protect_void (choose_minibuf_frame); - record_unwind_protect (Fset_window_configuration, + record_unwind_protect (restore_window_configuration, Fcurrent_window_configuration (Qnil)); /* If the minibuffer window is on a different frame, save that frame's configuration too. */ mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window)); if (!EQ (mini_frame, selected_frame)) - record_unwind_protect (Fset_window_configuration, + record_unwind_protect (restore_window_configuration, Fcurrent_window_configuration (mini_frame)); /* If the minibuffer is on an iconified or invisible frame, @@ -518,14 +511,14 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, Fcons (Vminibuffer_history_variable, minibuf_save_list)))))); - record_unwind_protect (read_minibuf_unwind, Qnil); + record_unwind_protect_void (read_minibuf_unwind); minibuf_level++; /* We are exiting the minibuffer one way or the other, so run the hook. It should be run before unwinding the minibuf settings. Do it separately from read_minibuf_unwind because we need to make sure that read_minibuf_unwind is fully executed even if exit-minibuffer-hook signals an error. --Stef */ - record_unwind_protect (run_exit_minibuf_hook, Qnil); + record_unwind_protect_void (run_exit_minibuf_hook); /* Now that we can restore all those variables, start changing them. */ @@ -821,18 +814,17 @@ get_minibuffer (EMACS_INT depth) return buf; } -static Lisp_Object -run_exit_minibuf_hook (Lisp_Object data) +static void +run_exit_minibuf_hook (void) { safe_run_hooks (Qminibuffer_exit_hook); - return Qnil; } /* This function is called on exiting minibuffer, whether normally or not, and it restores the current window, buffer, etc. */ -static Lisp_Object -read_minibuf_unwind (Lisp_Object data) +static void +read_minibuf_unwind (void) { Lisp_Object old_deactivate_mark; Lisp_Object window; @@ -895,7 +887,6 @@ read_minibuf_unwind (Lisp_Object data) to make sure we don't leave around bindings and stuff which only made sense during the read_minibuf invocation. */ call0 (intern ("minibuffer-inactive-mode")); - return Qnil; } diff --git a/src/nsfns.m b/src/nsfns.m index 291ab20dc5..121ac53964 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -981,7 +981,7 @@ frame_parm_handler ns_frame_parm_handlers[] = /* Handler for signals raised during x_create_frame. FRAME is the frame which is partially constructed. */ -static Lisp_Object +static void unwind_create_frame (Lisp_Object frame) { struct frame *f = XFRAME (frame); @@ -990,7 +990,7 @@ unwind_create_frame (Lisp_Object frame) display is disconnected after the frame has become official, but before x_create_frame removes the unwind protect. */ if (!FRAME_LIVE_P (f)) - return Qnil; + return; /* If frame is ``official'', nothing to do. */ if (NILP (Fmemq (frame, Vframe_list))) @@ -1006,10 +1006,7 @@ unwind_create_frame (Lisp_Object frame) /* Check that reference counts are indeed correct. */ eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount); #endif - return Qt; } - - return Qnil; } /* diff --git a/src/nsmenu.m b/src/nsmenu.m index c070411350..02fe0b04ca 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -1410,10 +1410,10 @@ struct Popdown_data EmacsDialogPanel *dialog; }; -static Lisp_Object -pop_down_menu (Lisp_Object arg) +static void +pop_down_menu (void *arg) { - struct Popdown_data *unwind_data = XSAVE_POINTER (arg, 0); + struct Popdown_data *unwind_data = arg; block_input (); if (popup_activated_flag) @@ -1427,8 +1427,6 @@ pop_down_menu (Lisp_Object arg) xfree (unwind_data); unblock_input (); - - return Qnil; } @@ -1506,7 +1504,7 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) unwind_data->pool = pool; unwind_data->dialog = dialog; - record_unwind_protect (pop_down_menu, make_save_pointer (unwind_data)); + record_unwind_protect_ptr (pop_down_menu, unwind_data); popup_activated_flag = 1; tem = [dialog runDialogAt: p]; unbind_to (specpdl_count, Qnil); /* calls pop_down_menu */ diff --git a/src/print.c b/src/print.c index 55659414b0..80f1bb6beb 100644 --- a/src/print.c +++ b/src/print.c @@ -199,11 +199,10 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1; /* This is used to restore the saved contents of print_buffer when there is a recursive call to print. */ -static Lisp_Object +static void print_unwind (Lisp_Object saved_text) { memcpy (print_buffer, SDATA (saved_text), SCHARS (saved_text)); - return Qnil; } diff --git a/src/process.c b/src/process.c index fe843ca2d9..42a625b7e5 100644 --- a/src/process.c +++ b/src/process.c @@ -1341,7 +1341,7 @@ DEFUN ("process-list", Fprocess_list, Sprocess_list, 0, 0, 0, /* Starting asynchronous inferior processes. */ -static Lisp_Object start_process_unwind (Lisp_Object proc); +static void start_process_unwind (Lisp_Object proc); DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0, doc: /* Start a program in a subprocess. Return the process object for it. @@ -1590,7 +1590,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) PROC doesn't have its pid set, then we know someone has signaled an error and the process wasn't started successfully, so we should remove it from the process list. */ -static Lisp_Object +static void start_process_unwind (Lisp_Object proc) { if (!PROCESSP (proc)) @@ -1600,8 +1600,6 @@ start_process_unwind (Lisp_Object proc) -2 is used for a pty with no process, eg for gdb. */ if (XPROCESS (proc)->pid <= 0 && XPROCESS (proc)->pid != -2) remove_process (proc); - - return Qnil; } static void @@ -2455,16 +2453,6 @@ usage: (serial-process-configure &rest ARGS) */) return Qnil; } -/* Used by make-serial-process to recover from errors. */ -static Lisp_Object -make_serial_process_unwind (Lisp_Object proc) -{ - if (!PROCESSP (proc)) - emacs_abort (); - remove_process (proc); - return Qnil; -} - DEFUN ("make-serial-process", Fmake_serial_process, Smake_serial_process, 0, MANY, 0, doc: /* Create and return a serial port process. @@ -2570,7 +2558,7 @@ usage: (make-serial-process &rest ARGS) */) CHECK_STRING (name); proc = make_process (name); specpdl_count = SPECPDL_INDEX (); - record_unwind_protect (make_serial_process_unwind, proc); + record_unwind_protect (remove_process, proc); p = XPROCESS (proc); fd = serial_open (port); @@ -3006,7 +2994,7 @@ usage: (make-network-process &rest ARGS) */) #ifdef POLL_FOR_INPUT if (socktype != SOCK_DGRAM) { - record_unwind_protect (unwind_stop_other_atimers, Qnil); + record_unwind_protect_void (run_all_atimers); bind_polling_period (10); } #endif @@ -3166,7 +3154,7 @@ usage: (make-network-process &rest ARGS) */) #endif /* Make us close S if quit. */ - record_unwind_protect (close_file_unwind, make_number (s)); + record_unwind_protect_int (close_file_unwind, s); /* Parse network options in the arg list. We simply ignore anything which isn't a known option (including other keywords). @@ -4176,11 +4164,10 @@ server_accept_connection (Lisp_Object server, int channel) when not inside wait_reading_process_output. */ static int waiting_for_user_input_p; -static Lisp_Object -wait_reading_process_output_unwind (Lisp_Object data) +static void +wait_reading_process_output_unwind (int data) { - waiting_for_user_input_p = XINT (data); - return Qnil; + waiting_for_user_input_p = data; } /* This is here so breakpoints can be put on it. */ @@ -4258,8 +4245,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, if (wait_proc != NULL) wait_channel = wait_proc->infd; - record_unwind_protect (wait_reading_process_output_unwind, - make_number (waiting_for_user_input_p)); + record_unwind_protect_int (wait_reading_process_output_unwind, + waiting_for_user_input_p); waiting_for_user_input_p = read_kbd; if (time_limit < 0) diff --git a/src/search.c b/src/search.c index 19cc08f84c..0f4d41586a 100644 --- a/src/search.c +++ b/src/search.c @@ -3016,11 +3016,11 @@ restore_search_regs (void) } } -static Lisp_Object +static void unwind_set_match_data (Lisp_Object list) { /* It is NOT ALWAYS safe to free (evaporate) the markers immediately. */ - return Fset_match_data (list, Qt); + Fset_match_data (list, Qt); } /* Called to unwind protect the match data. */ diff --git a/src/sound.c b/src/sound.c index c476b3095c..27e06b8aba 100644 --- a/src/sound.c +++ b/src/sound.c @@ -437,10 +437,10 @@ find_sound_type (struct sound *s) } -/* Function installed by play-sound-internal with record_unwind_protect. */ +/* Function installed by play-sound-internal with record_unwind_protect_void. */ -static Lisp_Object -sound_cleanup (Lisp_Object arg) +static void +sound_cleanup (void) { if (current_sound_device->close) current_sound_device->close (current_sound_device); @@ -448,8 +448,6 @@ sound_cleanup (Lisp_Object arg) emacs_close (current_sound->fd); xfree (current_sound_device); xfree (current_sound); - - return Qnil; } /*********************************************************************** @@ -1346,7 +1344,7 @@ Internal use only, use `play-sound' instead. */) GCPRO2 (sound, file); current_sound_device = xzalloc (sizeof *current_sound_device); current_sound = xzalloc (sizeof *current_sound); - record_unwind_protect (sound_cleanup, Qnil); + record_unwind_protect_void (sound_cleanup); current_sound->header = alloca (MAX_SOUND_HEADER_BYTES); if (STRINGP (attrs[SOUND_FILE])) diff --git a/src/w32fns.c b/src/w32fns.c index 3fa23c166e..eab8a6b8bd 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -4258,6 +4258,12 @@ unwind_create_frame (Lisp_Object frame) return Qnil; } +static void +do_unwind_create_frame (Lisp_Object frame) +{ + unwind_create_frame (frame); +} + static void x_default_font_parameter (struct frame *f, Lisp_Object parms) { @@ -4398,7 +4404,7 @@ This function is an internal primitive--use `make-frame' instead. */) /* FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */ /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */ - record_unwind_protect (unwind_create_frame, frame); + record_unwind_protect (do_unwind_create_frame, frame); #ifdef GLYPH_DEBUG image_cache_refcount = FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; @@ -5585,7 +5591,7 @@ Window tip_window; Lisp_Object last_show_tip_args; -static Lisp_Object +static void unwind_create_tip_frame (Lisp_Object frame) { Lisp_Object deleted; @@ -5596,8 +5602,6 @@ unwind_create_tip_frame (Lisp_Object frame) tip_window = NULL; tip_frame = Qnil; } - - return deleted; } diff --git a/src/window.c b/src/window.c index 22da72db2b..2ff149ed4f 100644 --- a/src/window.c +++ b/src/window.c @@ -3086,18 +3086,18 @@ run_funs (Lisp_Object funs) call0 (XCAR (funs)); } -static Lisp_Object +static void select_window_norecord (Lisp_Object window) { - return WINDOW_LIVE_P (window) - ? Fselect_window (window, Qt) : selected_window; + if (WINDOW_LIVE_P (window)) + Fselect_window (window, Qt); } -static Lisp_Object +static void select_frame_norecord (Lisp_Object frame) { - return FRAME_LIVE_P (XFRAME (frame)) - ? Fselect_frame (frame, Qt) : selected_frame; + if (FRAME_LIVE_P (XFRAME (frame))) + Fselect_frame (frame, Qt); } void @@ -3410,7 +3410,7 @@ temp_output_buffer_show (register Lisp_Object buf) Note: Both Fselect_window and select_window_norecord may set-buffer to the buffer displayed in the window, so we need to save the current buffer. --stef */ - record_unwind_protect (Fset_buffer, prev_buffer); + record_unwind_protect (restore_buffer, prev_buffer); record_unwind_protect (select_window_norecord, prev_window); Fselect_window (window, Qt); Fset_buffer (w->contents); @@ -5873,6 +5873,12 @@ the return value is nil. Otherwise the value is t. */) return (FRAME_LIVE_P (f) ? Qt : Qnil); } +void +restore_window_configuration (Lisp_Object configuration) +{ + Fset_window_configuration (configuration); +} + /* If WINDOW is an internal window, recursively delete all child windows reachable via the next and contents slots of WINDOW. Otherwise setup diff --git a/src/window.h b/src/window.h index 846831e43d..5da6165c48 100644 --- a/src/window.h +++ b/src/window.h @@ -886,6 +886,7 @@ extern Lisp_Object make_window (void); extern Lisp_Object window_from_coordinates (struct frame *, int, int, enum window_part *, bool); extern void resize_frame_windows (struct frame *, int, bool); +extern void restore_window_configuration (Lisp_Object); extern void delete_all_child_windows (Lisp_Object); extern void freeze_window_starts (struct frame *, bool); extern void grow_mini_window (struct window *, int); diff --git a/src/xdisp.c b/src/xdisp.c index 9f3b0263d6..1a7369d7a4 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -813,21 +813,20 @@ static void handle_stop (struct it *); static void handle_stop_backwards (struct it *, ptrdiff_t); static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0); static void ensure_echo_area_buffers (void); -static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object); +static void unwind_with_echo_area_buffer (Lisp_Object); static Lisp_Object with_echo_area_buffer_unwind_data (struct window *); static int with_echo_area_buffer (struct window *, int, int (*) (ptrdiff_t, Lisp_Object), ptrdiff_t, Lisp_Object); static void clear_garbaged_frames (void); static int current_message_1 (ptrdiff_t, Lisp_Object); -static void pop_message (void); static int truncate_message_1 (ptrdiff_t, Lisp_Object); static void set_message (Lisp_Object); static int set_message_1 (ptrdiff_t, Lisp_Object); static int display_echo_area (struct window *); static int display_echo_area_1 (ptrdiff_t, Lisp_Object); static int resize_mini_window_1 (ptrdiff_t, Lisp_Object); -static Lisp_Object unwind_redisplay (Lisp_Object); +static void unwind_redisplay (void); static int string_char_and_length (const unsigned char *, int *); static struct text_pos display_prop_end (struct it *, Lisp_Object, struct text_pos); @@ -10146,7 +10145,7 @@ with_echo_area_buffer_unwind_data (struct window *w) /* Restore global state from VECTOR which was created by with_echo_area_buffer_unwind_data. */ -static Lisp_Object +static void unwind_with_echo_area_buffer (Lisp_Object vector) { set_buffer_internal_1 (XBUFFER (AREF (vector, 0))); @@ -10171,7 +10170,6 @@ unwind_with_echo_area_buffer (Lisp_Object vector) } Vwith_echo_area_save_vector = vector; - return Qnil; } @@ -10570,20 +10568,12 @@ restore_message (void) } -/* Handler for record_unwind_protect calling pop_message. */ - -Lisp_Object -pop_message_unwind (Lisp_Object dummy) -{ - pop_message (); - return Qnil; -} - -/* Pop the top-most entry off Vmessage_stack. */ +/* Handler for unwind-protect calling pop_message. */ -static void -pop_message (void) +void +pop_message_unwind (void) { + /* Pop the top-most entry off Vmessage_stack. */ eassert (CONSP (Vmessage_stack)); Vmessage_stack = XCDR (Vmessage_stack); } @@ -10979,7 +10969,7 @@ format_mode_line_unwind_data (struct frame *target_frame, return vector; } -static Lisp_Object +static void unwind_format_mode_line (Lisp_Object vector) { Lisp_Object old_window = AREF (vector, 7); @@ -11022,7 +11012,6 @@ unwind_format_mode_line (Lisp_Object vector) } Vmode_line_unwind_vector = vector; - return Qnil; } @@ -11471,7 +11460,7 @@ int last_tool_bar_item; do_switch_frame. FIXME: Maybe do_switch_frame should be trimmed down similarly when `norecord' is set. */ -static Lisp_Object +static void fast_set_selected_frame (Lisp_Object frame) { if (!EQ (selected_frame, frame)) @@ -11479,7 +11468,6 @@ fast_set_selected_frame (Lisp_Object frame) selected_frame = frame; selected_window = XFRAME (frame)->selected_window; } - return Qnil; } /* Update the tool-bar item list for frame F. This has to be done @@ -12980,7 +12968,7 @@ redisplay_internal (void) /* Record a function that clears redisplaying_p when we leave this function. */ count = SPECPDL_INDEX (); - record_unwind_protect (unwind_redisplay, selected_frame); + record_unwind_protect_void (unwind_redisplay); redisplaying_p = 1; specbind (Qinhibit_free_realized_faces, Qnil); @@ -13660,14 +13648,12 @@ redisplay_preserve_echo_area (int from_where) } -/* Function registered with record_unwind_protect in redisplay_internal. - Clear redisplaying_p. Also select the previously selected frame. */ +/* Function registered with record_unwind_protect in redisplay_internal. */ -static Lisp_Object -unwind_redisplay (Lisp_Object old_frame) +static void +unwind_redisplay (void) { redisplaying_p = 0; - return Qnil; } diff --git a/src/xfns.c b/src/xfns.c index 30f58ba96e..a3eff1a5cc 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -2883,11 +2883,16 @@ unwind_create_frame (Lisp_Object frame) return Qnil; } -static Lisp_Object +static void +do_unwind_create_frame (Lisp_Object frame) +{ + unwind_create_frame (frame); +} + +static void unwind_create_frame_1 (Lisp_Object val) { inhibit_lisp_code = val; - return Qnil; } static void @@ -3090,7 +3095,7 @@ This function is an internal primitive--use `make-frame' instead. */) FRAME_X_DISPLAY_INFO (f) = dpyinfo; /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */ - record_unwind_protect (unwind_create_frame, frame); + record_unwind_protect (do_unwind_create_frame, frame); /* These colors will be set anyway later, but it's important to get the color reference counts right, so initialize them! */ @@ -4975,7 +4980,7 @@ Window tip_window; static Lisp_Object last_show_tip_args; -static Lisp_Object +static void unwind_create_tip_frame (Lisp_Object frame) { Lisp_Object deleted; @@ -4986,8 +4991,6 @@ unwind_create_tip_frame (Lisp_Object frame) tip_window = None; tip_frame = Qnil; } - - return deleted; } @@ -5764,10 +5767,10 @@ file_dialog_unmap_cb (Widget widget, XtPointer client_data, XtPointer call_data) *result = XmCR_CANCEL; } -static Lisp_Object -clean_up_file_dialog (Lisp_Object arg) +static void +clean_up_file_dialog (void *arg) { - Widget dialog = XSAVE_POINTER (arg, 0); + Widget dialog = arg; /* Clean up. */ block_input (); @@ -5775,8 +5778,6 @@ clean_up_file_dialog (Lisp_Object arg) XtDestroyWidget (dialog); x_menu_set_in_use (0); unblock_input (); - - return Qnil; } @@ -5891,7 +5892,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) XmStringFree (default_xmstring); } - record_unwind_protect (clean_up_file_dialog, make_save_pointer (dialog)); + record_unwind_protect_ptr (clean_up_file_dialog, dialog); /* Process events until the user presses Cancel or OK. */ x_menu_set_in_use (1); @@ -5945,12 +5946,10 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) #ifdef USE_GTK -static Lisp_Object -clean_up_dialog (Lisp_Object arg) +static void +clean_up_dialog (void) { x_menu_set_in_use (0); - - return Qnil; } DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0, @@ -5984,7 +5983,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) /* Prevent redisplay. */ specbind (Qinhibit_redisplay, Qt); - record_unwind_protect (clean_up_dialog, Qnil); + record_unwind_protect_void (clean_up_dialog); block_input (); @@ -6039,7 +6038,7 @@ nil, it defaults to the selected frame. */) /* Prevent redisplay. */ specbind (Qinhibit_redisplay, Qt); - record_unwind_protect (clean_up_dialog, Qnil); + record_unwind_protect_void (clean_up_dialog); block_input (); diff --git a/src/xmenu.c b/src/xmenu.c index 8349b0dfd2..1151dea440 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -311,7 +311,7 @@ for instance using the window manager, then this produces a quit and /* Decode the dialog items from what was specified. */ title = Fcar (contents); CHECK_STRING (title); - record_unwind_protect (unuse_menu_items, Qnil); + record_unwind_protect_void (unuse_menu_items); if (NILP (Fcar (Fcdr (contents)))) /* No buttons specified, add an "Ok" button so users can pop down @@ -1405,14 +1405,13 @@ popup_selection_callback (GtkWidget *widget, gpointer client_data) if (cb_data) menu_item_selection = (Lisp_Object *) cb_data->call_data; } -static Lisp_Object -pop_down_menu (Lisp_Object arg) +static void +pop_down_menu (void *arg) { popup_activated_flag = 0; block_input (); - gtk_widget_destroy (GTK_WIDGET (XSAVE_POINTER (arg, 0))); + gtk_widget_destroy (GTK_WIDGET (arg)); unblock_input (); - return Qnil; } /* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the @@ -1474,7 +1473,7 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, int x, int y, gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i, timestamp ? timestamp : gtk_get_current_event_time ()); - record_unwind_protect (pop_down_menu, make_save_pointer (menu)); + record_unwind_protect_ptr (pop_down_menu, menu); if (gtk_widget_get_mapped (menu)) { @@ -1513,7 +1512,7 @@ popup_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data) /* ARG is the LWLIB ID of the dialog box, represented as a Lisp object as (HIGHPART . LOWPART). */ -static Lisp_Object +static void pop_down_menu (Lisp_Object arg) { LWLIB_ID id = (XINT (XCAR (arg)) << 4 * sizeof (LWLIB_ID) @@ -1523,8 +1522,6 @@ pop_down_menu (Lisp_Object arg) lw_destroy_all_widgets (id); unblock_input (); popup_activated_flag = 0; - - return Qnil; } /* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the @@ -1604,11 +1601,10 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, #endif /* not USE_GTK */ -static Lisp_Object -cleanup_widget_value_tree (Lisp_Object arg) +static void +cleanup_widget_value_tree (void *arg) { - free_menubar_widget_value_tree (XSAVE_POINTER (arg, 0)); - return Qnil; + free_menubar_widget_value_tree (arg); } Lisp_Object @@ -1822,8 +1818,7 @@ xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps, /* Make sure to free the widget_value objects we used to specify the contents even with longjmp. */ - record_unwind_protect (cleanup_widget_value_tree, - make_save_pointer (first_wv)); + record_unwind_protect_ptr (cleanup_widget_value_tree, first_wv); /* Actually create and show the menu until popped down. */ create_and_show_popup_menu (f, first_wv, x, y, for_click, timestamp); @@ -1922,7 +1917,7 @@ create_and_show_dialog (FRAME_PTR f, widget_value *first_wv) if (menu) { ptrdiff_t specpdl_count = SPECPDL_INDEX (); - record_unwind_protect (pop_down_menu, make_save_pointer (menu)); + record_unwind_protect_ptr (pop_down_menu, menu); /* Display the menu. */ gtk_widget_show_all (menu); @@ -2132,8 +2127,7 @@ xdialog_show (FRAME_PTR f, /* Make sure to free the widget_value objects we used to specify the contents even with longjmp. */ - record_unwind_protect (cleanup_widget_value_tree, - make_save_pointer (first_wv)); + record_unwind_protect_ptr (cleanup_widget_value_tree, first_wv); /* Actually create and show the dialog. */ create_and_show_dialog (f, first_wv); @@ -2228,7 +2222,7 @@ menu_help_callback (char const *help_string, int pane, int item) Qnil, menu_object, make_number (item)); } -static Lisp_Object +static void pop_down_menu (Lisp_Object arg) { FRAME_PTR f = XSAVE_POINTER (arg, 0); @@ -2255,8 +2249,6 @@ pop_down_menu (Lisp_Object arg) #endif /* HAVE_X_WINDOWS */ unblock_input (); - - return Qnil; } diff --git a/src/xselect.c b/src/xselect.c index b422a22d68..6a80eddc82 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -45,26 +45,14 @@ along with GNU Emacs. If not, see . */ struct prop_location; struct selection_data; -static Lisp_Object x_atom_to_symbol (Display *dpy, Atom atom); -static Atom symbol_to_x_atom (struct x_display_info *, Lisp_Object); -static void x_own_selection (Lisp_Object, Lisp_Object, Lisp_Object); -static Lisp_Object x_get_local_selection (Lisp_Object, Lisp_Object, int, - struct x_display_info *); static void x_decline_selection_request (struct input_event *); -static Lisp_Object x_selection_request_lisp_error (Lisp_Object); -static Lisp_Object queue_selection_requests_unwind (Lisp_Object); -static Lisp_Object x_catch_errors_unwind (Lisp_Object); -static void x_reply_selection_request (struct input_event *, struct x_display_info *); static int x_convert_selection (struct input_event *, Lisp_Object, Lisp_Object, Atom, int, struct x_display_info *); static int waiting_for_other_props_on_window (Display *, Window); static struct prop_location *expect_property_change (Display *, Window, Atom, int); static void unexpect_property_change (struct prop_location *); -static Lisp_Object wait_for_property_change_unwind (Lisp_Object); static void wait_for_property_change (struct prop_location *); -static Lisp_Object x_get_foreign_selection (Lisp_Object, Lisp_Object, - Lisp_Object, Lisp_Object); static Lisp_Object x_get_window_property_as_lisp_data (Display *, Window, Atom, Lisp_Object, Atom); @@ -74,7 +62,6 @@ static Lisp_Object selection_data_to_lisp_data (Display *, static void lisp_data_to_selection_data (Display *, Lisp_Object, unsigned char **, Atom *, ptrdiff_t *, int *, int *); -static Lisp_Object clean_local_selection_data (Lisp_Object); /* Printing traces to stderr. */ @@ -513,8 +500,8 @@ static Atom conversion_fail_tag; an error, we tell the requestor that we were unable to do what they wanted before we throw to top-level or go into the debugger or whatever. */ -static Lisp_Object -x_selection_request_lisp_error (Lisp_Object ignore) +static void +x_selection_request_lisp_error (void) { struct selection_data *cs, *next; @@ -530,16 +517,14 @@ x_selection_request_lisp_error (Lisp_Object ignore) if (x_selection_current_request != 0 && selection_request_dpyinfo->display) x_decline_selection_request (x_selection_current_request); - return Qnil; } -static Lisp_Object -x_catch_errors_unwind (Lisp_Object dummy) +static void +x_catch_errors_unwind (void) { block_input (); x_uncatch_errors (); unblock_input (); - return Qnil; } @@ -560,11 +545,6 @@ struct prop_location struct prop_location *next; }; -static struct prop_location *expect_property_change (Display *display, Window window, Atom property, int state); -static void wait_for_property_change (struct prop_location *location); -static void unexpect_property_change (struct prop_location *location); -static int waiting_for_other_props_on_window (Display *display, Window window); - static int prop_location_identifier; static Lisp_Object property_change_reply; @@ -573,13 +553,6 @@ static struct prop_location *property_change_reply_object; static struct prop_location *property_change_wait_list; -static Lisp_Object -queue_selection_requests_unwind (Lisp_Object tem) -{ - x_stop_queuing_selection_requests (); - return Qnil; -} - /* Send the reply to a selection request event EVENT. */ @@ -614,7 +587,7 @@ x_reply_selection_request (struct input_event *event, /* The protected block contains wait_for_property_change, which can run random lisp code (process handlers) or signal. Therefore, we put the x_uncatch_errors call in an unwind. */ - record_unwind_protect (x_catch_errors_unwind, Qnil); + record_unwind_protect_void (x_catch_errors_unwind); x_catch_errors (display); /* Loop over converted selections, storing them in the requested @@ -805,12 +778,12 @@ x_handle_selection_request (struct input_event *event) x_selection_current_request = event; selection_request_dpyinfo = dpyinfo; - record_unwind_protect (x_selection_request_lisp_error, Qnil); + record_unwind_protect_void (x_selection_request_lisp_error); /* We might be able to handle nested x_handle_selection_requests, but this is difficult to test, and seems unimportant. */ x_start_queuing_selection_requests (); - record_unwind_protect (queue_selection_requests_unwind, Qnil); + record_unwind_protect_void (x_stop_queuing_selection_requests); TRACE2 ("x_handle_selection_request: selection=%s, target=%s", SDATA (SYMBOL_NAME (selection_symbol)), @@ -1117,15 +1090,14 @@ unexpect_property_change (struct prop_location *location) /* Remove the property change expectation element for IDENTIFIER. */ -static Lisp_Object -wait_for_property_change_unwind (Lisp_Object loc) +static void +wait_for_property_change_unwind (void *loc) { - struct prop_location *location = XSAVE_POINTER (loc, 0); + struct prop_location *location = loc; unexpect_property_change (location); if (location == property_change_reply_object) property_change_reply_object = 0; - return Qnil; } /* Actually wait for a property change. @@ -1140,8 +1112,7 @@ wait_for_property_change (struct prop_location *location) emacs_abort (); /* Make sure to do unexpect_property_change if we quit or err. */ - record_unwind_protect (wait_for_property_change_unwind, - make_save_pointer (location)); + record_unwind_protect_ptr (wait_for_property_change_unwind, location); XSETCAR (property_change_reply, Qnil); property_change_reply_object = location; @@ -1254,7 +1225,7 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type, SelectionNotify. */ #if 0 x_start_queuing_selection_requests (); - record_unwind_protect (queue_selection_requests_unwind, Qnil); + record_unwind_protect_void (x_stop_queuing_selection_requests); #endif unblock_input (); -- 2.20.1