diff options
| author | Paul Eggert | 2019-02-27 01:14:27 -0800 |
|---|---|---|
| committer | Paul Eggert | 2019-02-27 01:23:30 -0800 |
| commit | e828765d01313acddcf17279b6b43ae9f777f2a4 (patch) | |
| tree | 8dd465c5899c62ad5613fe97172fad1ddf419097 /src/eval.c | |
| parent | 2f7885a4b3609dec19e4595c6c24f3a21f33c5d6 (diff) | |
| download | emacs-e828765d01313acddcf17279b6b43ae9f777f2a4.tar.gz emacs-e828765d01313acddcf17279b6b43ae9f777f2a4.zip | |
DEFVAR_INT variables are now intmax_t
Formerly they were fixnums, which led to problems when dealing
with values that might not fit on 32-bit platforms, such as
string-chars-consed or floats_consed. 64-bit counters should
be good enough for these (for a while, anyway...).
While we’re at it, fix some unlikely integer overflow bugs
that have been in the code for a while.
* lib-src/make-docfile.c (write_globals):
* src/data.c (do_symval_forwarding, store_symval_forwarding):
* src/eval.c (restore_stack_limits, call_debugger):
* src/frame.h (struct frame.cost_calculation_baud_rate):
* src/keyboard.c (last_auto_save, bind_polling_period, read_char):
* src/lisp.h (struct Lisp_Intfwd.intvar):
* src/lread.c (defvar_int):
* src/pdumper.c (dump_fwd_int):
* src/thread.h (struct thread_state.m_lisp_eval_depth):
* src/undo.c (truncate_undo_list):
* src/xselect.c (wait_for_property_change)
(x_get_foreign_selection):
* src/xterm.c (x_emacs_to_x_modifiers):
DEFVAR_INT variables now have the C type intmax_t, not EMACS_INT.
* src/data.c (store_symval_forwarding):
* src/gnutls.c (Fgnutls_boot):
* src/keyboard.c (bind_polling_period):
* src/macros.c (pop_kbd_macro, Fexecute_kbd_macro):
* src/undo.c (truncate_undo_list):
Allow any integer that fits into intmax_t, instead of
requiring it to be a Lisp fixnum.
* src/dispnew.c (update_window):
* src/frame.c (x_figure_window_size):
* src/gnutls.c (init_gnutls_functions)
(emacs_gnutls_handle_error):
* src/keyboard.c (make_lisp_event):
* src/nsterm.m (ns_dumpglyphs_image):
* src/profiler.c (make_log):
* src/scroll.c (calculate_scrolling)
(calculate_direct_scrolling):
* src/termcap.c (tputs):
* src/xterm.c (x_draw_image_relief):
Avoid implementation-defined behavior on conversion of
out-of-range integers.
* src/eval.c (when_entered_debugger): Now intmax_t.
(max_ensure_room): New function, that avoids signed integer overflow.
(call_debugger, signal_or_quit): Use it.
* src/fileio.c (Fdo_auto_save):
* src/keyboard.c (make_lisp_event):
* src/term.c (calculate_costs):
* src/xdisp.c (build_desired_tool_bar_string)
(hscroll_window_tree, try_scrolling, decode_mode_spec)
(x_produce_glyphs):
Avoid signed integer overflow.
* src/lisp.h (clip_to_bounds): Generalize to intmax_t.
* src/pdumper.c (dump_emacs_reloc_immediate_emacs_int): Remove, ...
(dump_emacs_reloc_immediate_intmax_t): ... replacing with this
function. All uses changed.
* src/profiler.c (make_log): Omit args. All callers changed.
* src/termcap.c: Include stdlib.h, for atoi.
Include intprops.h.
* src/window.c (sanitize_next_screen_context_lines): New function.
(window_scroll_pixel_based, window_scroll_line_based):
Use it to avoid signed integer overflow.
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 56 |
1 files changed, 20 insertions, 36 deletions
diff --git a/src/eval.c b/src/eval.c index b6cdfc911d0..bf16a709b15 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -56,26 +56,6 @@ Lisp_Object Vautoload_queue; | |||
| 56 | is shutting down. */ | 56 | is shutting down. */ |
| 57 | Lisp_Object Vrun_hooks; | 57 | Lisp_Object Vrun_hooks; |
| 58 | 58 | ||
| 59 | /* The commented-out variables below are macros defined in thread.h. */ | ||
| 60 | |||
| 61 | /* Current number of specbindings allocated in specpdl, not counting | ||
| 62 | the dummy entry specpdl[-1]. */ | ||
| 63 | |||
| 64 | /* ptrdiff_t specpdl_size; */ | ||
| 65 | |||
| 66 | /* Pointer to beginning of specpdl. A dummy entry specpdl[-1] exists | ||
| 67 | only so that its address can be taken. */ | ||
| 68 | |||
| 69 | /* union specbinding *specpdl; */ | ||
| 70 | |||
| 71 | /* Pointer to first unused element in specpdl. */ | ||
| 72 | |||
| 73 | /* union specbinding *specpdl_ptr; */ | ||
| 74 | |||
| 75 | /* Depth in Lisp evaluations and function calls. */ | ||
| 76 | |||
| 77 | /* static EMACS_INT lisp_eval_depth; */ | ||
| 78 | |||
| 79 | /* The value of num_nonmacro_input_events as of the last time we | 59 | /* The value of num_nonmacro_input_events as of the last time we |
| 80 | started to enter the debugger. If we decide to enter the debugger | 60 | started to enter the debugger. If we decide to enter the debugger |
| 81 | again when this is still equal to num_nonmacro_input_events, then we | 61 | again when this is still equal to num_nonmacro_input_events, then we |
| @@ -83,7 +63,7 @@ Lisp_Object Vrun_hooks; | |||
| 83 | signal the error instead of entering an infinite loop of debugger | 63 | signal the error instead of entering an infinite loop of debugger |
| 84 | invocations. */ | 64 | invocations. */ |
| 85 | 65 | ||
| 86 | static EMACS_INT when_entered_debugger; | 66 | static intmax_t when_entered_debugger; |
| 87 | 67 | ||
| 88 | /* The function from which the last `signal' was called. Set in | 68 | /* The function from which the last `signal' was called. Set in |
| 89 | Fsignal. */ | 69 | Fsignal. */ |
| @@ -285,13 +265,23 @@ init_eval (void) | |||
| 285 | when_entered_debugger = -1; | 265 | when_entered_debugger = -1; |
| 286 | } | 266 | } |
| 287 | 267 | ||
| 268 | /* Ensure that *M is at least A + B if possible, or is its maximum | ||
| 269 | value otherwise. */ | ||
| 270 | |||
| 271 | static void | ||
| 272 | max_ensure_room (intmax_t *m, intmax_t a, intmax_t b) | ||
| 273 | { | ||
| 274 | intmax_t sum = INT_ADD_WRAPV (a, b, &sum) ? INTMAX_MAX : sum; | ||
| 275 | *m = max (*m, sum); | ||
| 276 | } | ||
| 277 | |||
| 288 | /* Unwind-protect function used by call_debugger. */ | 278 | /* Unwind-protect function used by call_debugger. */ |
| 289 | 279 | ||
| 290 | static void | 280 | static void |
| 291 | restore_stack_limits (Lisp_Object data) | 281 | restore_stack_limits (Lisp_Object data) |
| 292 | { | 282 | { |
| 293 | max_specpdl_size = XFIXNUM (XCAR (data)); | 283 | integer_to_intmax (XCAR (data), &max_specpdl_size); |
| 294 | max_lisp_eval_depth = XFIXNUM (XCDR (data)); | 284 | integer_to_intmax (XCDR (data), &max_lisp_eval_depth); |
| 295 | } | 285 | } |
| 296 | 286 | ||
| 297 | static void grow_specpdl (void); | 287 | static void grow_specpdl (void); |
| @@ -304,21 +294,19 @@ call_debugger (Lisp_Object arg) | |||
| 304 | bool debug_while_redisplaying; | 294 | bool debug_while_redisplaying; |
| 305 | ptrdiff_t count = SPECPDL_INDEX (); | 295 | ptrdiff_t count = SPECPDL_INDEX (); |
| 306 | Lisp_Object val; | 296 | Lisp_Object val; |
| 307 | EMACS_INT old_depth = max_lisp_eval_depth; | 297 | intmax_t old_depth = max_lisp_eval_depth; |
| 308 | /* Do not allow max_specpdl_size less than actual depth (Bug#16603). */ | 298 | /* Do not allow max_specpdl_size less than actual depth (Bug#16603). */ |
| 309 | EMACS_INT old_max = max (max_specpdl_size, count); | 299 | intmax_t old_max = max (max_specpdl_size, count); |
| 310 | 300 | ||
| 311 | /* The previous value of 40 is too small now that the debugger | 301 | /* The previous value of 40 is too small now that the debugger |
| 312 | prints using cl-prin1 instead of prin1. Printing lists nested 8 | 302 | prints using cl-prin1 instead of prin1. Printing lists nested 8 |
| 313 | deep (which is the value of print-level used in the debugger) | 303 | deep (which is the value of print-level used in the debugger) |
| 314 | currently requires 77 additional frames. See bug#31919. */ | 304 | currently requires 77 additional frames. See bug#31919. */ |
| 315 | if (lisp_eval_depth + 100 > max_lisp_eval_depth) | 305 | max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100); |
| 316 | max_lisp_eval_depth = lisp_eval_depth + 100; | ||
| 317 | 306 | ||
| 318 | /* While debugging Bug#16603, previous value of 100 was found | 307 | /* While debugging Bug#16603, previous value of 100 was found |
| 319 | too small to avoid specpdl overflow in the debugger itself. */ | 308 | too small to avoid specpdl overflow in the debugger itself. */ |
| 320 | if (max_specpdl_size - 200 < count) | 309 | max_ensure_room (&max_specpdl_size, count, 200); |
| 321 | max_specpdl_size = count + 200; | ||
| 322 | 310 | ||
| 323 | if (old_max == count) | 311 | if (old_max == count) |
| 324 | { | 312 | { |
| @@ -329,8 +317,7 @@ call_debugger (Lisp_Object arg) | |||
| 329 | 317 | ||
| 330 | /* Restore limits after leaving the debugger. */ | 318 | /* Restore limits after leaving the debugger. */ |
| 331 | record_unwind_protect (restore_stack_limits, | 319 | record_unwind_protect (restore_stack_limits, |
| 332 | Fcons (make_fixnum (old_max), | 320 | Fcons (make_int (old_max), make_int (old_depth))); |
| 333 | make_fixnum (old_depth))); | ||
| 334 | 321 | ||
| 335 | #ifdef HAVE_WINDOW_SYSTEM | 322 | #ifdef HAVE_WINDOW_SYSTEM |
| 336 | if (display_hourglass_p) | 323 | if (display_hourglass_p) |
| @@ -1654,11 +1641,8 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit) | |||
| 1654 | && specpdl_ptr < specpdl + specpdl_size) | 1641 | && specpdl_ptr < specpdl + specpdl_size) |
| 1655 | { | 1642 | { |
| 1656 | /* Edebug takes care of restoring these variables when it exits. */ | 1643 | /* Edebug takes care of restoring these variables when it exits. */ |
| 1657 | if (lisp_eval_depth + 20 > max_lisp_eval_depth) | 1644 | max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 20); |
| 1658 | max_lisp_eval_depth = lisp_eval_depth + 20; | 1645 | max_ensure_room (&max_specpdl_size, SPECPDL_INDEX (), 40); |
| 1659 | |||
| 1660 | if (SPECPDL_INDEX () + 40 > max_specpdl_size) | ||
| 1661 | max_specpdl_size = SPECPDL_INDEX () + 40; | ||
| 1662 | 1646 | ||
| 1663 | call2 (Vsignal_hook_function, error_symbol, data); | 1647 | call2 (Vsignal_hook_function, error_symbol, data); |
| 1664 | } | 1648 | } |