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.
This commit is contained in:
Paul Eggert 2019-02-27 01:14:27 -08:00
parent 2f7885a4b3
commit e828765d01
24 changed files with 189 additions and 189 deletions

View file

@ -700,7 +700,7 @@ write_globals (void)
switch (globals[i].type)
{
case EMACS_INTEGER:
type = "EMACS_INT";
type = "intmax_t";
break;
case BOOLEAN:
type = "bool";

View file

@ -985,7 +985,7 @@ do_symval_forwarding (union Lisp_Fwd *valcontents)
switch (XFWDTYPE (valcontents))
{
case Lisp_Fwd_Int:
return make_fixnum (*XFIXNUMFWD (valcontents)->intvar);
return make_int (*XFIXNUMFWD (valcontents)->intvar);
case Lisp_Fwd_Bool:
return (*XBOOLFWD (valcontents)->boolvar ? Qt : Qnil);
@ -1076,8 +1076,13 @@ store_symval_forwarding (union Lisp_Fwd *valcontents, register Lisp_Object newva
switch (XFWDTYPE (valcontents))
{
case Lisp_Fwd_Int:
CHECK_FIXNUM (newval);
*XFIXNUMFWD (valcontents)->intvar = XFIXNUM (newval);
{
intmax_t i;
CHECK_INTEGER (newval);
if (! integer_to_intmax (newval, &i))
xsignal1 (Qoverflow_error, newval);
*XFIXNUMFWD (valcontents)->intvar = i;
}
break;
case Lisp_Fwd_Bool:

View file

@ -3389,7 +3389,7 @@ update_window (struct window *w, bool force_p)
{
struct glyph_matrix *desired_matrix = w->desired_matrix;
bool paused_p;
int preempt_count = baud_rate / 2400 + 1;
int preempt_count = clip_to_bounds (1, baud_rate / 2400 + 1, INT_MAX);
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
#ifdef GLYPH_DEBUG
/* Check that W's frame doesn't have glyph matrices. */
@ -4485,16 +4485,13 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p,
struct glyph_matrix *desired_matrix = f->desired_matrix;
int i;
bool pause_p;
int preempt_count = baud_rate / 2400 + 1;
int preempt_count = clip_to_bounds (1, baud_rate / 2400 + 1, INT_MAX);
eassert (current_matrix && desired_matrix);
if (baud_rate != FRAME_COST_BAUD_RATE (f))
calculate_costs (f);
if (preempt_count <= 0)
preempt_count = 1;
if (!force_p && detect_input_pending_ignore_squeezables ())
{
pause_p = 1;

View file

@ -56,26 +56,6 @@ Lisp_Object Vautoload_queue;
is shutting down. */
Lisp_Object Vrun_hooks;
/* The commented-out variables below are macros defined in thread.h. */
/* Current number of specbindings allocated in specpdl, not counting
the dummy entry specpdl[-1]. */
/* ptrdiff_t specpdl_size; */
/* Pointer to beginning of specpdl. A dummy entry specpdl[-1] exists
only so that its address can be taken. */
/* union specbinding *specpdl; */
/* Pointer to first unused element in specpdl. */
/* union specbinding *specpdl_ptr; */
/* Depth in Lisp evaluations and function calls. */
/* static EMACS_INT lisp_eval_depth; */
/* The value of num_nonmacro_input_events as of the last time we
started to enter the debugger. If we decide to enter the debugger
again when this is still equal to num_nonmacro_input_events, then we
@ -83,7 +63,7 @@ Lisp_Object Vrun_hooks;
signal the error instead of entering an infinite loop of debugger
invocations. */
static EMACS_INT when_entered_debugger;
static intmax_t when_entered_debugger;
/* The function from which the last `signal' was called. Set in
Fsignal. */
@ -285,13 +265,23 @@ init_eval (void)
when_entered_debugger = -1;
}
/* Ensure that *M is at least A + B if possible, or is its maximum
value otherwise. */
static void
max_ensure_room (intmax_t *m, intmax_t a, intmax_t b)
{
intmax_t sum = INT_ADD_WRAPV (a, b, &sum) ? INTMAX_MAX : sum;
*m = max (*m, sum);
}
/* Unwind-protect function used by call_debugger. */
static void
restore_stack_limits (Lisp_Object data)
{
max_specpdl_size = XFIXNUM (XCAR (data));
max_lisp_eval_depth = XFIXNUM (XCDR (data));
integer_to_intmax (XCAR (data), &max_specpdl_size);
integer_to_intmax (XCDR (data), &max_lisp_eval_depth);
}
static void grow_specpdl (void);
@ -304,21 +294,19 @@ call_debugger (Lisp_Object arg)
bool debug_while_redisplaying;
ptrdiff_t count = SPECPDL_INDEX ();
Lisp_Object val;
EMACS_INT old_depth = max_lisp_eval_depth;
intmax_t old_depth = max_lisp_eval_depth;
/* Do not allow max_specpdl_size less than actual depth (Bug#16603). */
EMACS_INT old_max = max (max_specpdl_size, count);
intmax_t old_max = max (max_specpdl_size, count);
/* The previous value of 40 is too small now that the debugger
prints using cl-prin1 instead of prin1. Printing lists nested 8
deep (which is the value of print-level used in the debugger)
currently requires 77 additional frames. See bug#31919. */
if (lisp_eval_depth + 100 > max_lisp_eval_depth)
max_lisp_eval_depth = lisp_eval_depth + 100;
max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100);
/* While debugging Bug#16603, previous value of 100 was found
too small to avoid specpdl overflow in the debugger itself. */
if (max_specpdl_size - 200 < count)
max_specpdl_size = count + 200;
max_ensure_room (&max_specpdl_size, count, 200);
if (old_max == count)
{
@ -329,8 +317,7 @@ call_debugger (Lisp_Object arg)
/* Restore limits after leaving the debugger. */
record_unwind_protect (restore_stack_limits,
Fcons (make_fixnum (old_max),
make_fixnum (old_depth)));
Fcons (make_int (old_max), make_int (old_depth)));
#ifdef HAVE_WINDOW_SYSTEM
if (display_hourglass_p)
@ -1654,11 +1641,8 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
&& specpdl_ptr < specpdl + specpdl_size)
{
/* Edebug takes care of restoring these variables when it exits. */
if (lisp_eval_depth + 20 > max_lisp_eval_depth)
max_lisp_eval_depth = lisp_eval_depth + 20;
if (SPECPDL_INDEX () + 40 > max_specpdl_size)
max_specpdl_size = SPECPDL_INDEX () + 40;
max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 20);
max_ensure_room (&max_specpdl_size, SPECPDL_INDEX (), 40);
call2 (Vsignal_hook_function, error_symbol, data);
}

View file

@ -5706,8 +5706,9 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
bool old_message_p = 0;
struct auto_save_unwind auto_save_unwind;
if (max_specpdl_size < specpdl_size + 40)
max_specpdl_size = specpdl_size + 40;
intmax_t sum = INT_ADD_WRAPV (specpdl_size, 40, &sum) ? INTMAX_MAX : sum;
if (max_specpdl_size < sum)
max_specpdl_size = sum;
if (minibuf_level)
no_message = Qt;

View file

@ -5309,9 +5309,9 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x
{
int margin, relief;
relief = (tool_bar_button_relief >= 0
? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF);
relief = (tool_bar_button_relief < 0
? DEFAULT_TOOL_BAR_BUTTON_RELIEF
: min (tool_bar_button_relief, 1000000));
if (RANGED_FIXNUMP (1, Vtool_bar_button_margin, INT_MAX))
margin = XFIXNAT (Vtool_bar_button_margin);

View file

@ -580,7 +580,7 @@ struct frame
int config_scroll_bar_lines;
/* The baud rate that was used to calculate costs for this frame. */
int cost_calculation_baud_rate;
intmax_t cost_calculation_baud_rate;
/* Frame opacity
alpha[0]: alpha transparency of the active frame

View file

@ -395,8 +395,7 @@ init_gnutls_functions (void)
# endif
# endif /* HAVE_GNUTLS3 */
max_log_level = global_gnutls_log_level;
max_log_level = clip_to_bounds (INT_MIN, global_gnutls_log_level, INT_MAX);
{
Lisp_Object name = CAR_SAFE (Fget (Qgnutls, QCloaded_from));
GNUTLS_LOG2 (1, max_log_level, "GnuTLS library loaded:",
@ -760,7 +759,8 @@ emacs_gnutls_handle_error (gnutls_session_t session, int err)
check_memory_full (err);
int max_log_level = global_gnutls_log_level;
int max_log_level
= clip_to_bounds (INT_MIN, global_gnutls_log_level, INT_MAX);
/* TODO: use gnutls-error-fatalp and gnutls-error-string. */
@ -1691,14 +1691,17 @@ one trustfile (usually a CA bundle). */)
state = XPROCESS (proc)->gnutls_state;
if (TYPE_RANGED_FIXNUMP (int, loglevel))
if (INTEGERP (loglevel))
{
gnutls_global_set_log_function (gnutls_log_function);
# ifdef HAVE_GNUTLS3
gnutls_global_set_audit_log_function (gnutls_audit_log_function);
# endif
gnutls_global_set_log_level (XFIXNUM (loglevel));
max_log_level = XFIXNUM (loglevel);
int level = (FIXNUMP (loglevel)
? clip_to_bounds (INT_MIN, XFIXNUM (loglevel), INT_MAX)
: NILP (Fnatnump (loglevel)) ? INT_MIN : INT_MAX);
gnutls_global_set_log_level (level);
max_log_level = level;
XPROCESS (proc)->gnutls_log_level = max_log_level;
}

View file

@ -208,7 +208,7 @@ struct buffer *buffer_before_last_command_or_undo;
/* Value of num_nonmacro_input_events as of last auto save. */
static EMACS_INT last_auto_save;
static intmax_t last_auto_save;
/* The value of point when the last command was started. */
static ptrdiff_t last_point_position;
@ -1213,7 +1213,7 @@ some_mouse_moved (void)
if (ignore_mouse_drag_p)
{
/* ignore_mouse_drag_p = 0; */
/* ignore_mouse_drag_p = false; */
return 0;
}
@ -1301,7 +1301,7 @@ command_loop_1 (void)
loop. (This flag is set in xdisp.c whenever the tool bar is
resized, because the resize moves text up or down, and would
generate false mouse drag events if we don't ignore them.) */
ignore_mouse_drag_p = 0;
ignore_mouse_drag_p = false;
/* If minibuffer on and echo area in use,
wait a short time and redraw minibuffer. */
@ -1966,14 +1966,14 @@ void
bind_polling_period (int n)
{
#ifdef POLL_FOR_INPUT
EMACS_INT new = polling_period;
intmax_t new = polling_period;
if (n > new)
new = n;
stop_other_atimers (poll_timer);
stop_polling ();
specbind (Qpolling_period, make_fixnum (new));
specbind (Qpolling_period, make_int (new));
/* Start a new alarm with the new period. */
start_polling ();
#endif
@ -2422,7 +2422,7 @@ read_char (int commandflag, Lisp_Object map,
goto exit;
}
c = Faref (Vexecuting_kbd_macro, make_fixnum (executing_kbd_macro_index));
c = Faref (Vexecuting_kbd_macro, make_int (executing_kbd_macro_index));
if (STRINGP (Vexecuting_kbd_macro)
&& (XFIXNAT (c) & 0x80) && (XFIXNAT (c) <= 0xff))
XSETFASTINT (c, CHAR_META | (XFIXNAT (c) & ~0x80));
@ -5585,7 +5585,7 @@ make_lispy_event (struct input_event *event)
double-click-fuzz as is. On other frames, interpret it
as a multiple of 1/8 characters. */
struct frame *f;
int fuzz;
intmax_t fuzz;
if (WINDOWP (event->frame_or_window))
f = XFRAME (XWINDOW (event->frame_or_window)->frame);
@ -5628,7 +5628,7 @@ make_lispy_event (struct input_event *event)
double_click_count = 1;
button_down_time = event->timestamp;
*start_pos_ptr = Fcopy_alist (position);
ignore_mouse_drag_p = 0;
ignore_mouse_drag_p = false;
}
/* Now we're releasing a button - check the co-ordinates to
@ -5644,11 +5644,14 @@ make_lispy_event (struct input_event *event)
if (!CONSP (start_pos))
return Qnil;
event->modifiers &= ~up_modifier;
unsigned click_or_drag_modifier = click_modifier;
if (ignore_mouse_drag_p)
ignore_mouse_drag_p = false;
else
{
Lisp_Object new_down, down;
EMACS_INT xdiff = double_click_fuzz, ydiff = double_click_fuzz;
intmax_t xdiff = double_click_fuzz, ydiff = double_click_fuzz;
/* The third element of every position
should be the (x,y) pair. */
@ -5662,39 +5665,37 @@ make_lispy_event (struct input_event *event)
ydiff = XFIXNUM (XCDR (new_down)) - XFIXNUM (XCDR (down));
}
if (ignore_mouse_drag_p)
{
event->modifiers |= click_modifier;
ignore_mouse_drag_p = 0;
}
else if (xdiff < double_click_fuzz && xdiff > - double_click_fuzz
&& ydiff < double_click_fuzz && ydiff > - double_click_fuzz
/* Maybe the mouse has moved a lot, caused scrolling, and
eventually ended up at the same screen position (but
not buffer position) in which case it is a drag, not
a click. */
/* FIXME: OTOH if the buffer position has changed
because of a timer or process filter rather than
because of mouse movement, it should be considered as
a click. But mouse-drag-region completely ignores
this case and it hasn't caused any real problem, so
it's probably OK to ignore it as well. */
&& EQ (Fcar (Fcdr (start_pos)), Fcar (Fcdr (position))))
/* Mouse hasn't moved (much). */
event->modifiers |= click_modifier;
else
if (! (0 < double_click_fuzz
&& - double_click_fuzz < xdiff
&& xdiff < double_click_fuzz
&& - double_click_fuzz < ydiff
&& ydiff < double_click_fuzz
/* Maybe the mouse has moved a lot, caused scrolling, and
eventually ended up at the same screen position (but
not buffer position) in which case it is a drag, not
a click. */
/* FIXME: OTOH if the buffer position has changed
because of a timer or process filter rather than
because of mouse movement, it should be considered as
a click. But mouse-drag-region completely ignores
this case and it hasn't caused any real problem, so
it's probably OK to ignore it as well. */
&& EQ (Fcar (Fcdr (start_pos)), Fcar (Fcdr (position)))))
{
/* Mouse has moved enough. */
button_down_time = 0;
event->modifiers |= drag_modifier;
click_or_drag_modifier = drag_modifier;
}
/* Don't check is_double; treat this as multiple
if the down-event was multiple. */
if (double_click_count > 1)
event->modifiers |= ((double_click_count > 2)
? triple_modifier
: double_modifier);
}
/* Don't check is_double; treat this as multiple if the
down-event was multiple. */
event->modifiers
= ((event->modifiers & ~up_modifier)
| click_or_drag_modifier
| (double_click_count < 2 ? 0
: double_click_count == 2 ? double_modifier
: triple_modifier));
}
else
/* Every mouse event should either have the down_modifier or
@ -5743,7 +5744,7 @@ make_lispy_event (struct input_event *event)
double-click-fuzz as is. On other frames, interpret it
as a multiple of 1/8 characters. */
struct frame *fr;
int fuzz;
intmax_t fuzz;
int symbol_num;
bool is_double;

View file

@ -1260,8 +1260,8 @@ INLINE bool
#define FIXNUM_OVERFLOW_P(i) \
(! ((0 <= (i) || MOST_NEGATIVE_FIXNUM <= (i)) && (i) <= MOST_POSITIVE_FIXNUM))
INLINE ptrdiff_t
clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper)
INLINE intmax_t
clip_to_bounds (intmax_t lower, intmax_t num, intmax_t upper)
{
return num < lower ? lower : num <= upper ? num : upper;
}
@ -2664,7 +2664,7 @@ make_uint (uintmax_t n)
struct Lisp_Intfwd
{
enum Lisp_Fwd_Type type; /* = Lisp_Fwd_Int */
EMACS_INT *intvar;
intmax_t *intvar;
};
/* Boolean forwarding pointer to an int variable.
@ -3099,7 +3099,7 @@ enum maxargs
extern void defvar_lisp (struct Lisp_Objfwd *, const char *, Lisp_Object *);
extern void defvar_lisp_nopro (struct Lisp_Objfwd *, const char *, Lisp_Object *);
extern void defvar_bool (struct Lisp_Boolfwd *, const char *, bool *);
extern void defvar_int (struct Lisp_Intfwd *, const char *, EMACS_INT *);
extern void defvar_int (struct Lisp_Intfwd *, const char *, intmax_t *);
extern void defvar_kboard (struct Lisp_Kboard_Objfwd *, const char *, int);
/* Macros we use to define forwarded Lisp variables.

View file

@ -4422,11 +4422,11 @@ defalias (struct Lisp_Subr *sname, char *string)
#endif /* NOTDEF */
/* Define an "integer variable"; a symbol whose value is forwarded to a
C variable of type EMACS_INT. Sample call (with "xx" to fool make-docfile):
C variable of type intmax_t. Sample call (with "xx" to fool make-docfile):
DEFxxVAR_INT ("emacs-priority", &emacs_priority, "Documentation"); */
void
defvar_int (struct Lisp_Intfwd *i_fwd,
const char *namestring, EMACS_INT *address)
const char *namestring, intmax_t *address)
{
Lisp_Object sym;
sym = intern_c_string (namestring);

View file

@ -267,7 +267,7 @@ pop_kbd_macro (Lisp_Object info)
Lisp_Object tem;
Vexecuting_kbd_macro = XCAR (info);
tem = XCDR (info);
executing_kbd_macro_index = XFIXNUM (XCAR (tem));
integer_to_intmax (XCAR (tem), &executing_kbd_macro_index);
Vreal_this_command = XCDR (tem);
run_hook (Qkbd_macro_termination_hook);
}
@ -301,7 +301,7 @@ each iteration of the macro. Iteration stops if LOOPFUNC returns nil. */)
error ("Keyboard macros must be strings or vectors");
tem = Fcons (Vexecuting_kbd_macro,
Fcons (make_fixnum (executing_kbd_macro_index),
Fcons (make_int (executing_kbd_macro_index),
Vreal_this_command));
record_unwind_protect (pop_kbd_macro, tem);

View file

@ -3911,8 +3911,9 @@ Function modeled after x_draw_glyph_string_box ().
{
if (s->hl == DRAW_IMAGE_SUNKEN || s->hl == DRAW_IMAGE_RAISED)
{
th = tool_bar_button_relief >= 0 ?
tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
th = (tool_bar_button_relief < 0
? DEFAULT_TOOL_BAR_BUTTON_RELIEF
: min (tool_bar_button_relief, 1000000));
raised_p = (s->hl == DRAW_IMAGE_RAISED);
}
else

View file

@ -1615,7 +1615,7 @@ dump_emacs_reloc_immediate (struct dump_context *ctx,
DEFINE_EMACS_IMMEDIATE_FN (dump_emacs_reloc_immediate_lv, Lisp_Object);
DEFINE_EMACS_IMMEDIATE_FN (dump_emacs_reloc_immediate_ptrdiff_t, ptrdiff_t);
DEFINE_EMACS_IMMEDIATE_FN (dump_emacs_reloc_immediate_emacs_int, EMACS_INT);
DEFINE_EMACS_IMMEDIATE_FN (dump_emacs_reloc_immediate_intmax_t, intmax_t);
DEFINE_EMACS_IMMEDIATE_FN (dump_emacs_reloc_immediate_int, int);
DEFINE_EMACS_IMMEDIATE_FN (dump_emacs_reloc_immediate_bool, bool);
@ -2286,10 +2286,10 @@ dump_float (struct dump_context *ctx, const struct Lisp_Float *lfloat)
static dump_off
dump_fwd_int (struct dump_context *ctx, const struct Lisp_Intfwd *intfwd)
{
#if CHECK_STRUCTS && !defined (HASH_Lisp_Intfwd_1225FA32CC)
#if CHECK_STRUCTS && !defined HASH_Lisp_Intfwd_4D887A7387
# error "Lisp_Intfwd changed. See CHECK_STRUCTS comment."
#endif
dump_emacs_reloc_immediate_emacs_int (ctx, intfwd->intvar, *intfwd->intvar);
dump_emacs_reloc_immediate_intmax_t (ctx, intfwd->intvar, *intfwd->intvar);
struct Lisp_Intfwd out;
dump_object_start (ctx, &out, sizeof (out));
DUMP_FIELD_COPY (&out, intfwd, type);

View file

@ -52,12 +52,16 @@ static const struct hash_table_test hashtest_profiler =
};
static Lisp_Object
make_log (EMACS_INT heap_size, EMACS_INT max_stack_depth)
make_log (void)
{
/* We use a standard Elisp hash-table object, but we use it in
a special way. This is OK as long as the object is not exposed
to Elisp, i.e. until it is returned by *-profiler-log, after which
it can't be used any more. */
EMACS_INT heap_size
= clip_to_bounds (0, profiler_log_size, MOST_POSITIVE_FIXNUM);
ptrdiff_t max_stack_depth
= clip_to_bounds (0, profiler_max_stack_depth, PTRDIFF_MAX);;
Lisp_Object log = make_hash_table (hashtest_profiler, heap_size,
DEFAULT_REHASH_SIZE,
DEFAULT_REHASH_THRESHOLD,
@ -342,8 +346,7 @@ See also `profiler-log-size' and `profiler-max-stack-depth'. */)
if (NILP (cpu_log))
{
cpu_gc_count = 0;
cpu_log = make_log (profiler_log_size,
profiler_max_stack_depth);
cpu_log = make_log ();
}
int status = setup_cpu_timer (sampling_interval);
@ -419,9 +422,7 @@ Before returning, a new log is allocated for future samples. */)
/* Here we're making the log visible to Elisp, so it's not safe any
more for our use afterwards since we can't rely on its special
pre-allocated keys anymore. So we have to allocate a new one. */
cpu_log = (profiler_cpu_running
? make_log (profiler_log_size, profiler_max_stack_depth)
: Qnil);
cpu_log = profiler_cpu_running ? make_log () : Qnil;
Fputhash (make_vector (1, QAutomatic_GC),
make_fixnum (cpu_gc_count),
result);
@ -450,8 +451,7 @@ See also `profiler-log-size' and `profiler-max-stack-depth'. */)
error ("Memory profiler is already running");
if (NILP (memory_log))
memory_log = make_log (profiler_log_size,
profiler_max_stack_depth);
memory_log = make_log ();
profiler_memory_running = true;
@ -494,9 +494,7 @@ Before returning, a new log is allocated for future samples. */)
/* Here we're making the log visible to Elisp , so it's not safe any
more for our use afterwards since we can't rely on its special
pre-allocated keys anymore. So we have to allocate a new one. */
memory_log = (profiler_memory_running
? make_log (profiler_log_size, profiler_max_stack_depth)
: Qnil);
memory_log = profiler_memory_running ? make_log () : Qnil;
return result;
}

View file

@ -107,10 +107,8 @@ calculate_scrolling (struct frame *frame,
/* Discourage long scrolls on fast lines.
Don't scroll nearly a full frame height unless it saves
at least 1/4 second. */
int extra_cost = baud_rate / (10 * 4 * frame_total_lines);
if (baud_rate <= 0)
extra_cost = 1;
int extra_cost
= clip_to_bounds (1, baud_rate / (10 * 4) / frame_total_lines, INT_MAX / 2);
/* initialize the top left corner of the matrix */
matrix->writecost = 0;
@ -446,10 +444,8 @@ calculate_direct_scrolling (struct frame *frame,
/* Discourage long scrolls on fast lines.
Don't scroll nearly a full frame height unless it saves
at least 1/4 second. */
int extra_cost = baud_rate / (10 * 4 * frame_total_lines);
if (baud_rate <= 0)
extra_cost = 1;
int extra_cost
= clip_to_bounds (1, baud_rate / (10 * 4) / frame_total_lines, INT_MAX / 2);
/* Overhead of setting the scroll window, plus the extra
cost of scrolling by a distance of one. The extra cost is

View file

@ -1201,7 +1201,9 @@ calculate_costs (struct frame *frame)
calculate_ins_del_char_costs (frame);
/* Don't use TS_repeat if its padding is worse than sending the chars */
if (tty->TS_repeat && per_line_cost (tty->TS_repeat) * baud_rate < 9000)
if (tty->TS_repeat
&& (baud_rate <= 0
|| per_line_cost (tty->TS_repeat) < 9000 / baud_rate))
tty->RPov = string_cost (tty->TS_repeat);
else
tty->RPov = FRAME_COLS (frame) * 2;

View file

@ -20,10 +20,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* Emacs config.h may rename various library functions such as malloc. */
#include <config.h>
#include <stdlib.h>
#include <sys/file.h>
#include <fcntl.h>
#include <unistd.h>
#include <intprops.h>
#include "lisp.h"
#include "tparam.h"
#ifdef MSDOS
@ -265,14 +269,7 @@ char PC;
void
tputs (register const char *str, int nlines, int (*outfun) (int))
{
register int padcount = 0;
register int speed;
speed = baud_rate;
/* For quite high speeds, convert to the smaller
units to avoid overflow. */
if (speed > 10000)
speed = - speed / 100;
int padcount = 0;
if (!str)
return;
@ -296,21 +293,13 @@ tputs (register const char *str, int nlines, int (*outfun) (int))
(*outfun) (*str++);
/* PADCOUNT is now in units of tenths of msec.
SPEED is measured in characters per 10 seconds
or in characters per .1 seconds (if negative).
We use the smaller units for larger speeds to avoid overflow. */
padcount *= speed;
padcount += 500;
padcount /= 1000;
if (speed < 0)
padcount = -padcount;
else
{
padcount += 50;
padcount /= 100;
}
BAUD_RATE is measured in characters per 10 seconds.
Compute PADFACTOR = 100000 * (how many padding bytes are needed). */
intmax_t padfactor;
if (INT_MULTIPLY_WRAPV (padcount, baud_rate, &padfactor))
padfactor = baud_rate < 0 ? INTMAX_MIN : INTMAX_MAX;
while (padcount-- > 0)
for (; 50000 <= padfactor; padfactor -= 100000)
(*outfun) (PC);
}
@ -426,7 +415,7 @@ tgetent (char *bp, const char *name)
}
if (!termcap_name || !filep)
termcap_name = TERMCAP_FILE;
termcap_name = (char *) TERMCAP_FILE;
/* Here we know we must search a file and termcap_name has its name. */

View file

@ -104,7 +104,7 @@ struct thread_state
#define specpdl_ptr (current_thread->m_specpdl_ptr)
/* Depth in Lisp evaluations and function calls. */
EMACS_INT m_lisp_eval_depth;
intmax_t m_lisp_eval_depth;
#define lisp_eval_depth (current_thread->m_lisp_eval_depth)
/* This points to the current buffer. */

View file

@ -291,7 +291,7 @@ truncate_undo_list (struct buffer *b)
{
Lisp_Object list;
Lisp_Object prev, next, last_boundary;
EMACS_INT size_so_far = 0;
intmax_t size_so_far = 0;
/* Make sure that calling undo-outer-limit-function
won't cause another GC. */
@ -348,14 +348,17 @@ truncate_undo_list (struct buffer *b)
/* If by the first boundary we have already passed undo_outer_limit,
we're heading for memory full, so offer to clear out the list. */
if (FIXNUMP (Vundo_outer_limit)
&& size_so_far > XFIXNUM (Vundo_outer_limit)
intmax_t undo_outer_limit;
if ((INTEGERP (Vundo_outer_limit)
&& (integer_to_intmax (Vundo_outer_limit, &undo_outer_limit)
? undo_outer_limit < size_so_far
: NILP (Fnatnump (Vundo_outer_limit))))
&& !NILP (Vundo_outer_limit_function))
{
Lisp_Object tem;
/* Normally the function this calls is undo-outer-limit-truncate. */
tem = call1 (Vundo_outer_limit_function, make_fixnum (size_so_far));
tem = call1 (Vundo_outer_limit_function, make_int (size_so_far));
if (! NILP (tem))
{
/* The function is responsible for making

View file

@ -5445,6 +5445,11 @@ window_scroll_margin (struct window *window, enum margin_unit unit)
return 0;
}
static int
sanitize_next_screen_context_lines (void)
{
return clip_to_bounds (0, next_screen_context_lines, 1000000);
}
/* Implementation of window_scroll that works based on pixel line
heights. See the comment of window_scroll for parameter
@ -5515,9 +5520,11 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
height. This is important to ensure we get back to the
same position when scrolling up, then down. */
if (whole)
dy = max ((window_box_height (w) / dy
- next_screen_context_lines) * dy,
dy);
{
int ht = window_box_height (w);
int nscls = sanitize_next_screen_context_lines ();
dy = max (dy, (ht / dy - nscls) * dy);
}
dy *= n;
if (n < 0)
@ -5598,13 +5605,14 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
{
ptrdiff_t start_pos = IT_CHARPOS (it);
int dy = frame_line_height;
int ht = window_box_height (w);
int nscls = sanitize_next_screen_context_lines ();
/* In the below we divide the window box height by the frame's
line height to make the result predictable when the window
box is not an integral multiple of the line height. This is
important to ensure we get back to the same position when
scrolling up, then down. */
dy = max ((window_box_height (w) / dy - next_screen_context_lines) * dy,
dy) * n;
dy = n * max (dy, (ht / dy - nscls) * dy);
/* Note that move_it_vertically always moves the iterator to the
start of a line. So, if the last line doesn't have a newline,
@ -5902,7 +5910,10 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror)
/* If scrolling screen-fulls, compute the number of lines to
scroll from the window's height. */
if (whole)
n *= max (1, ht - next_screen_context_lines);
{
int nscls = sanitize_next_screen_context_lines ();
n *= max (1, ht - nscls);
}
if (!NILP (Vscroll_preserve_screen_position))
{

View file

@ -12533,7 +12533,8 @@ build_desired_tool_bar_string (struct frame *f)
/* Compute margin and relief to draw. */
relief = (tool_bar_button_relief >= 0
? tool_bar_button_relief
? min (tool_bar_button_relief,
min (INT_MAX, MOST_POSITIVE_FIXNUM))
: DEFAULT_TOOL_BAR_BUTTON_RELIEF);
hmargin = vmargin = relief;
@ -13334,7 +13335,8 @@ hscroll_window_tree (Lisp_Object window)
text_area_width = window_box_width (w, TEXT_AREA);
/* Scroll when cursor is inside this scroll margin. */
h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
h_margin = (clip_to_bounds (0, hscroll_margin, 1000000)
* WINDOW_FRAME_COLUMN_WIDTH (w));
/* If the position of this window's point has explicitly
changed, no more suspend auto hscrolling. */
@ -15765,7 +15767,7 @@ enum
static int
try_scrolling (Lisp_Object window, bool just_this_one_p,
ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
intmax_t arg_scroll_conservatively, intmax_t scroll_step,
bool temp_scroll_step, bool last_line_misfit)
{
struct window *w = XWINDOW (window);
@ -15797,12 +15799,15 @@ try_scrolling (Lisp_Object window, bool just_this_one_p,
arg_scroll_conservatively = scroll_limit + 1;
scroll_max = scroll_limit * frame_line_height;
}
else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
else if (0 < scroll_step || 0 < arg_scroll_conservatively || temp_scroll_step)
/* Compute how much we should try to scroll maximally to bring
point into view. */
scroll_max = (max (scroll_step,
max (arg_scroll_conservatively, temp_scroll_step))
* frame_line_height);
{
intmax_t scroll_lines_max
= max (scroll_step, max (arg_scroll_conservatively, temp_scroll_step));
int scroll_lines = clip_to_bounds (0, scroll_lines_max, 1000000);
scroll_max = scroll_lines * frame_line_height;
}
else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
|| NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
/* We're trying to scroll because of aggressive scrolling but no
@ -17295,8 +17300,8 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
}
/* Try to scroll by specified few lines. */
if ((scroll_conservatively
|| emacs_scroll_step
if ((0 < scroll_conservatively
|| 0 < emacs_scroll_step
|| temp_scroll_step
|| NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
|| NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
@ -24749,8 +24754,12 @@ decode_mode_spec (struct window *w, register int c, int field_width,
ptrdiff_t limit = BUF_BEGV (b);
ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
ptrdiff_t position;
ptrdiff_t distance =
(height * 2 + 30) * line_number_display_limit_width;
ptrdiff_t distance
= (line_number_display_limit_width < 0 ? 0
: INT_MULTIPLY_WRAPV (line_number_display_limit_width,
height * 2 + 30,
&distance)
? PTRDIFF_MAX : distance);
if (startpos - distance > limit)
{
@ -28377,7 +28386,7 @@ x_produce_glyphs (struct it *it)
/* If face has an overline, add the height of the overline
(1 pixel) and a 1 pixel margin to the character height. */
if (face->overline_p)
it->ascent += overline_margin;
it->ascent += clip_to_bounds (0, overline_margin, 1000000);
if (it->constrain_row_ascent_descent_p)
{
@ -28918,7 +28927,7 @@ x_produce_glyphs (struct it *it)
/* If face has an overline, add the height of the overline
(1 pixel) and a 1 pixel margin to the character height. */
if (face->overline_p)
it->ascent += overline_margin;
it->ascent += clip_to_bounds (0, overline_margin, 1000000);
take_vertical_position_into_account (it);
if (it->ascent < 0)
@ -28967,7 +28976,7 @@ x_produce_glyphs (struct it *it)
/* If face has an overline, add the height of the overline
(1 pixel) and a 1 pixel margin to the character height. */
if (face->overline_p)
it->ascent += overline_margin;
it->ascent += clip_to_bounds (0, overline_margin, 1000000);
take_vertical_position_into_account (it);
if (it->ascent < 0)
it->ascent = 0;

View file

@ -1085,10 +1085,10 @@ wait_for_property_change (struct prop_location *location)
property_change_reply, because property_change_reply_object says so. */
if (! location->arrived)
{
EMACS_INT timeout = max (0, x_selection_timeout);
EMACS_INT secs = timeout / 1000;
intmax_t timeout = max (0, x_selection_timeout);
intmax_t secs = timeout / 1000;
int nsecs = (timeout % 1000) * 1000000;
TRACE2 (" Waiting %"pI"d secs, %d nsecs", secs, nsecs);
TRACE2 (" Waiting %"PRIdMAX" secs, %d nsecs", secs, nsecs);
wait_reading_process_output (secs, nsecs, 0, false,
property_change_reply, NULL, 0);
@ -1158,8 +1158,6 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
Atom type_atom = (CONSP (target_type)
? symbol_to_x_atom (dpyinfo, XCAR (target_type))
: symbol_to_x_atom (dpyinfo, target_type));
EMACS_INT timeout, secs;
int nsecs;
if (!FRAME_LIVE_P (f))
return Qnil;
@ -1195,10 +1193,10 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
unblock_input ();
/* This allows quits. Also, don't wait forever. */
timeout = max (0, x_selection_timeout);
secs = timeout / 1000;
nsecs = (timeout % 1000) * 1000000;
TRACE1 (" Start waiting %"pI"d secs for SelectionNotify", secs);
intmax_t timeout = max (0, x_selection_timeout);
intmax_t secs = timeout / 1000;
int nsecs = (timeout % 1000) * 1000000;
TRACE1 (" Start waiting %"PRIdMAX" secs for SelectionNotify", secs);
wait_reading_process_output (secs, nsecs, 0, false,
reading_selection_reply, NULL, 0);
TRACE1 (" Got event = %d", !NILP (XCAR (reading_selection_reply)));

View file

@ -3131,7 +3131,9 @@ x_draw_image_relief (struct glyph_string *s)
if (s->hl == DRAW_IMAGE_SUNKEN
|| s->hl == DRAW_IMAGE_RAISED)
{
thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
thick = (tool_bar_button_relief < 0
? DEFAULT_TOOL_BAR_BUTTON_RELIEF
: min (tool_bar_button_relief, 1000000));
raised_p = s->hl == DRAW_IMAGE_RAISED;
}
else
@ -4884,7 +4886,7 @@ x_x_to_emacs_modifiers (struct x_display_info *dpyinfo, int state)
}
static int
x_emacs_to_x_modifiers (struct x_display_info *dpyinfo, EMACS_INT state)
x_emacs_to_x_modifiers (struct x_display_info *dpyinfo, intmax_t state)
{
EMACS_INT mod_ctrl = ctrl_modifier;
EMACS_INT mod_meta = meta_modifier;