diff options
| author | Paul Eggert <eggert@cs.ucla.edu> | 2013-07-16 14:35:45 -0700 |
|---|---|---|
| committer | Paul Eggert <eggert@cs.ucla.edu> | 2013-07-16 14:35:45 -0700 |
| commit | 27e498e6e5fea8ac64c90ac13678b537b7b12302 (patch) | |
| tree | de676dbd21308870ecf762376135433e59161917 /src/lisp.h | |
| parent | ac72c08d12cb5b86e873148ce52c2403ef2159c6 (diff) | |
| download | emacs-27e498e6e5fea8ac64c90ac13678b537b7b12302.tar.gz | |
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.
Diffstat (limited to 'src/lisp.h')
| -rw-r--r-- | src/lisp.h | 74 |
1 files changed, 41 insertions, 33 deletions
diff --git a/src/lisp.h b/src/lisp.h index 6a551bb499d..38413f831dc 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,11 +2703,25 @@ 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. */ Lisp_Object symbol, old_value, where; } 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); \ |
