emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master a8245e1220 1/3: Replace ptrdiff_t with new specpdl_ref type for s


From: Mattias Engdegård
Subject: master a8245e1220 1/3: Replace ptrdiff_t with new specpdl_ref type for specpdl references
Date: Sat, 12 Feb 2022 12:32:57 -0500 (EST)

branch: master
commit a8245e122075175df2f124b20e9e5b1b583eff89
Author: Mattias Engdegård <mattiase@acm.org>
Commit: Mattias Engdegård <mattiase@acm.org>

    Replace ptrdiff_t with new specpdl_ref type for specpdl references
    
    The specpdl_ref type is just an alias for ptrdiff_t; the compiled code
    remains the same.  All operations on specpdl_ref (arithmetic,
    comparison etc) now go through inline functions.
    
    The bulk of the change is almost completely mechanical.  It is done to
    prepare for a type-safe representation and subsequent performance
    improvement.
    
    * src/lisp.h (specpdl_ref, specpdl_count_to_ref, specpdl_ref_to_count)
    (specpdl_ref_eq, specpdl_ref_lt, specpdl_ref_valid_p)
    (make_invalid_specpdl_ref, specpdl_ref_add, specpdl_ref_to_ptr): New.
    (SPECPDL_INDEX, struct handler, USE_SAFE_ALLOCA, safe_free)
    (safe_free_unbind_to):
    * src/alloc.c (run_finalizer_function, inhibit_garbage_collection)
    (garbage_collect, Fgarbage_collect, which_symbols):
    * src/bidi.c (bidi_at_paragraph_end, bidi_find_paragraph_start):
    * src/buffer.c (Fkill_buffer, Fset_buffer_major_mode, Fmove_overlay)
    (Fdelete_overlay):
    * src/bytecode.c (exec_byte_code):
    * src/callint.c (Ffuncall_interactively, Fcall_interactively):
    * src/callproc.c (Fcall_process, call_process, create_temp_file)
    (Fcall_process_region):
    * src/charset.c (load_charset_map_from_file):
    * src/coding.c (decode_coding_gap, decode_coding_object)
    (encode_coding_object, Fread_coding_system):
    * src/comp.c (emit_static_object, helper_unbind_n, load_comp_unit):
    * src/composite.c (update_compositions, autocmp_chars):
    * src/cygw32.c (conv_filename_to_w32_unicode)
    (conv_filename_from_w32_unicode):
    * src/data.c (notify_variable_watchers):
    * src/decompress.c (Fzlib_decompress_region):
    * src/dired.c (directory_files_internal, file_name_completion)
    (file_attributes):
    * src/dispnew.c (Fredisplay):
    * src/doc.c (get_doc_string, Fsnarf_documentation):
    * src/editfns.c (Fsave_excursion, Fsave_current_buffer)
    (Freplace_buffer_contents, Fsubst_char_in_region, Fsave_restriction)
    (styled_format):
    * src/emacs-module.c (Fmodule_load, funcall_module):
    * src/emacs.c (init_cmdargs, Fdump_emacs):
    * src/eval.c (call_debugger, do_debug_on_call, FletX, Flet)
    (Ffuncall_with_delayed_message, Funwind_protect)
    (internal_lisp_condition_case, signal_or_quit)
    (load_with_autoload_queue, Feval, grow_specpdl_allocation)
    (record_in_backtrace, eval_sub, Ffuncall, apply_lambda)
    (funcall_lambda, clear_unwind_protect, set_unwind_protect)
    (set_unwind_protect_ptr, unbind_to, Fbacktrace_eval):
    * src/fileio.c (Fmake_temp_file_internal, Fcopy_file, Frename_file)
    (Finsert_file_contents, write_region, Fdo_auto_save):
    * src/fns.c (Fyes_or_no_p, Frequire, hash_table_user_defined_call):
    * src/fringe.c (update_window_fringes):
    * src/gtkutil.c (xg_dialog_run):
    * src/haiku_io.c (c_specpdl_idx_from_cxx):
    * src/haiku_support.cc (be_popup_file_dialog):
    * src/haiku_support.h (c_specpdl_idx_from_cxx):
    * src/haikufns.c (haiku_create_frame, haiku_create_tip_frame)
    (haiku_hide_tip, Fx_show_tip, Fhaiku_read_file_name):
    * src/haikumenu.c (haiku_popup_dialog, set_frame_menubar):
    * src/image.c (slurp_file):
    * src/indent.c (line_number_display_width, Fvertical_motion):
    * src/insdel.c (signal_before_change, signal_after_change)
    (Fcombine_after_change_execute):
    * src/intervals.c (get_local_map):
    * src/json.c (lisp_to_json_nonscalar_1, Fjson_serialize, Fjson_insert)
    (Fjson_parse_string, Fjson_parse_buffer):
    * src/keyboard.c (recursive_edit_1, Frecursive_edit, cmd_error)
    (Finternal_track_mouse, command_loop_1, read_menu_command)
    (safe_run_hooks, read_event_from_main_queue, read_char, timer_check_2)
    (menu_item_eval_property, read_key_sequence, read_key_sequence_vs)
    (Fsuspend_emacs):
    * src/keymap.c (Fcurrent_active_maps, Fdescribe_vector)
    (Fhelp__describe_vector):
    * src/lread.c (Fload, save_match_data_load, readevalloop)
    (Feval_buffer, Feval_region, grow_read_buffer, read_integer, read1):
    * src/macros.c (Fexecute_kbd_macro):
    * src/menu.c (x_popup_menu_1):
    * src/minibuf.c (read_minibuf, set_minibuffer_mode)
    (read_minibuf_unwind, Fread_string, Fread_buffer):
    * src/nsfns.m (Fx_create_frame, Fx_show_tip):
    * src/nsmenu.m (ns_update_menubar, ns_menu_show, ns_popup_dialog):
    * src/pdumper.c (Fdump_emacs_portable):
    * src/pgtkfns.c (Fx_create_frame, x_create_tip_frame, x_hide_tip)
    (Fx_show_tip, Fpgtk_print_frames_dialog, Fx_file_dialog, Fx_select_font):
    * src/pgtkmenu.c (set_frame_menubar, create_and_show_popup_menu)
    (pgtk_menu_show, create_and_show_dialog, pgtk_dialog_show)
    (pgtk_popup_dialog):
    * src/pgtkterm.c (pgtk_cr_export_frames):
    * src/print.c (PRINTPREPARE, temp_output_buffer_setup)
    (Fprin1_to_string, print_vectorlike):
    * src/process.c (Fmake_process, create_process, Fmake_pipe_process)
    (Fmake_serial_process, connect_network_socket, Fmake_network_process)
    (network_interface_info, server_accept_connection)
    (wait_reading_process_output, read_process_output, exec_sentinel):
    * src/regex-emacs.c (re_match_2_internal):
    * src/search.c (looking_at_1, fast_looking_at, search_buffer_re):
    * src/sound.c (Fplay_sound_internal):
    * src/sysdep.c (system_process_attributes):
    * src/term.c (tty_menu_show):
    * src/textprop.c (Fnext_single_char_property_change)
    (Fprevious_single_char_property_change, add_text_properties_1)
    (set_text_properties, set_text_properties_1, Fremove_text_properties)
    (Fremove_list_of_text_properties):
    * src/thread.c (Fmutex_lock, invoke_thread_function):
    * src/undo.c (truncate_undo_list):
    * src/w32fns.c (Fx_create_frame, w32_create_tip_frame, w32_hide_tip)
    (Fx_show_tip, Fx_file_dialog):
    * src/w32font.c (Fx_select_font):
    * src/w32menu.c (set_frame_menubar):
    * src/window.c (window_list, next_window, window_list_1)
    (run_window_configuration_change_hook, Frun_window_scroll_functions)
    (run_window_change_functions, set_window_buffer)
    (temp_output_buffer_show, window_scroll, scroll_command)
    (Fscroll_other_window, Fscroll_other_window_down):
    * src/xdisp.c (safe__call, handle_fontified_prop, handle_face_prop)
    (handle_single_display_spec, Fbuffer_text_pixel_size)
    (message_dolog, with_echo_area_buffer, setup_echo_area_for_printing)
    (display_echo_area, set_message, clear_message, echo_area_display)
    (gui_consider_frame_title, prepare_menu_bars, update_menu_bar)
    (update_tab_bar, update_tool_bar, redisplay_internal)
    (redisplay_preserve_echo_area, run_window_scroll_functions)
    (redisplay_window, extend_face_to_end_of_line)
    (display_count_lines_logically, display_count_lines_visually)
    (display_mode_lines, display_mode_line, Fformat_mode_line)
    (decode_mode_spec):
    * src/xfns.c (Fx_create_frame, x_create_tip_frame, x_hide_tip)
    (Fx_show_tip, Fx_file_dialog, Fx_select_font, Fx_print_frames_dialog):
    * src/xmenu.c (set_frame_menubar, create_and_show_popup_menu)
    (x_menu_show, create_and_show_dialog, x_dialog_show)
    (xw_popup_dialog):
    * src/xselect.c (x_get_local_selection, x_reply_selection_request)
    (x_handle_selection_request, wait_for_property_change):
    * src/xterm.c (x_cr_export_frames, x_connection_closed):
    Replace ptrdiff_t with specpdl_ref for referencing specpdl and use the
    corresponding functions instead of direct arithmetic.
---
 src/alloc.c          | 14 ++++-----
 src/bidi.c           |  4 +--
 src/buffer.c         |  9 +++---
 src/bytecode.c       | 16 +++++-----
 src/callint.c        |  8 ++---
 src/callproc.c       | 31 +++++++++---------
 src/charset.c        |  4 +--
 src/coding.c         | 10 +++---
 src/comp.c           |  6 ++--
 src/composite.c      |  4 +--
 src/cygw32.c         |  4 +--
 src/data.c           |  2 +-
 src/decompress.c     |  2 +-
 src/dired.c          |  8 ++---
 src/dispnew.c        |  4 +--
 src/doc.c            |  5 ++-
 src/editfns.c        | 12 +++----
 src/emacs-module.c   |  4 +--
 src/emacs.c          |  4 +--
 src/eval.c           | 89 +++++++++++++++++++++++++++-------------------------
 src/fileio.c         | 31 +++++++++---------
 src/fns.c            |  6 ++--
 src/fringe.c         |  2 +-
 src/gtkutil.c        |  2 +-
 src/haiku_io.c       |  4 +--
 src/haiku_support.cc |  2 +-
 src/haiku_support.h  |  5 ++-
 src/haikufns.c       | 15 ++++-----
 src/haikumenu.c      |  4 +--
 src/image.c          |  2 +-
 src/indent.c         |  4 +--
 src/insdel.c         |  6 ++--
 src/intervals.c      |  2 +-
 src/json.c           | 10 +++---
 src/keyboard.c       | 39 +++++++++++------------
 src/keymap.c         |  6 ++--
 src/lisp.h           | 85 ++++++++++++++++++++++++++++++++++++++++---------
 src/lread.c          | 22 ++++++-------
 src/macros.c         |  2 +-
 src/menu.c           |  2 +-
 src/minibuf.c        | 12 +++----
 src/nsfns.m          |  4 +--
 src/nsmenu.m         |  6 ++--
 src/pdumper.c        |  2 +-
 src/pgtkfns.c        | 19 +++++------
 src/pgtkmenu.c       | 12 +++----
 src/pgtkterm.c       |  2 +-
 src/print.c          |  8 ++---
 src/process.c        | 40 +++++++++++------------
 src/regex-emacs.c    |  2 +-
 src/search.c         |  6 ++--
 src/sound.c          |  2 +-
 src/sysdep.c         | 10 +++---
 src/term.c           |  2 +-
 src/textprop.c       | 14 ++++-----
 src/thread.c         |  4 +--
 src/undo.c           |  2 +-
 src/w32fns.c         | 14 ++++-----
 src/w32font.c        |  2 +-
 src/w32menu.c        |  2 +-
 src/window.c         | 26 +++++++--------
 src/xdisp.c          | 65 +++++++++++++++++++-------------------
 src/xfns.c           | 24 ++++++--------
 src/xmenu.c          | 18 +++++------
 src/xselect.c        |  8 ++---
 src/xterm.c          |  4 +--
 66 files changed, 418 insertions(+), 383 deletions(-)

diff --git a/src/alloc.c b/src/alloc.c
index 5d7b484f6e..a3410be7e2 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -3891,7 +3891,7 @@ run_finalizer_handler (Lisp_Object args)
 static void
 run_finalizer_function (Lisp_Object function)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 #ifdef HAVE_PDUMPER
   ++number_finalizers_run;
 #endif
@@ -5744,10 +5744,10 @@ allow_garbage_collection (intmax_t consing)
   garbage_collection_inhibited--;
 }
 
-ptrdiff_t
+specpdl_ref
 inhibit_garbage_collection (void)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   record_unwind_protect_intmax (allow_garbage_collection, consing_until_gc);
   garbage_collection_inhibited++;
   consing_until_gc = HI_THRESHOLD;
@@ -6107,7 +6107,7 @@ garbage_collect (void)
   Lisp_Object tail, buffer;
   char stack_top_variable;
   bool message_p;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   struct timespec start;
 
   eassert (weak_hash_tables == NULL);
@@ -6265,7 +6265,7 @@ garbage_collect (void)
 
   if (!NILP (Vpost_gc_hook))
     {
-      ptrdiff_t gc_count = inhibit_garbage_collection ();
+      specpdl_ref gc_count = inhibit_garbage_collection ();
       safe_run_hooks (Qpost_gc_hook);
       unbind_to (gc_count, Qnil);
     }
@@ -6318,7 +6318,7 @@ For further details, see Info node `(elisp)Garbage 
Collection'.  */)
   if (garbage_collection_inhibited)
     return Qnil;
 
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   specbind (Qsymbols_with_pos_enabled, Qnil);
   garbage_collect ();
   unbind_to (count, Qnil);
@@ -7421,7 +7421,7 @@ Lisp_Object
 which_symbols (Lisp_Object obj, EMACS_INT find_max)
 {
    struct symbol_block *sblk;
-   ptrdiff_t gc_count = inhibit_garbage_collection ();
+   specpdl_ref gc_count = inhibit_garbage_collection ();
    Lisp_Object found = Qnil;
 
    if (! deadp (obj))
diff --git a/src/bidi.c b/src/bidi.c
index d6ed607f14..16faf655b2 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -1462,7 +1462,7 @@ bidi_at_paragraph_end (ptrdiff_t charpos, ptrdiff_t 
bytepos)
 
   /* Prevent quitting inside re_match_2, as redisplay_window could
      have temporarily moved point.  */
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   specbind (Qinhibit_quit, Qt);
 
   val = fast_looking_at (sep_re, charpos, bytepos, ZV, ZV_BYTE, Qnil);
@@ -1552,7 +1552,7 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t 
pos_byte)
 
   /* Prevent quitting inside re_match_2, as redisplay_window could
      have temporarily moved point.  */
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   specbind (Qinhibit_quit, Qt);
 
   while (pos_byte > BEGV_BYTE
diff --git a/src/buffer.c b/src/buffer.c
index 0bdad086dd..91ff6b946f 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1774,7 +1774,7 @@ cleaning up all windows currently displaying the buffer 
to be killed. */)
 
   /* Run hooks with the buffer to be killed as the current buffer.  */
   {
-    ptrdiff_t count = SPECPDL_INDEX ();
+    specpdl_ref count = SPECPDL_INDEX ();
     bool modified;
 
     record_unwind_protect_excursion ();
@@ -2097,7 +2097,6 @@ Use this function before selecting the buffer, since it 
may need to inspect
 the current buffer's major mode.  */)
   (Lisp_Object buffer)
 {
-  ptrdiff_t count;
   Lisp_Object function;
 
   CHECK_BUFFER (buffer);
@@ -2120,7 +2119,7 @@ the current buffer's major mode.  */)
                           `hack-local-variables' get run. */
     return Qnil;
 
-  count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   /* To select a nonfundamental mode,
      select the buffer temporarily and then call the mode function.  */
@@ -4035,7 +4034,7 @@ buffer.  */)
 {
   struct buffer *b, *ob = 0;
   Lisp_Object obuffer;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   ptrdiff_t n_beg, n_end;
   ptrdiff_t o_beg UNINIT, o_end UNINIT;
 
@@ -4156,7 +4155,7 @@ DEFUN ("delete-overlay", Fdelete_overlay, 
Sdelete_overlay, 1, 1, 0,
 {
   Lisp_Object buffer;
   struct buffer *b;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   CHECK_OVERLAY (overlay);
 
diff --git a/src/bytecode.c b/src/bytecode.c
index da1855d6ba..1018e81d24 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -382,7 +382,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, 
Lisp_Object maxdepth,
   unsigned char const *bytestr_data = SDATA (bytestr);
   unsigned char const *pc = bytestr_data;
 #if BYTE_CODE_SAFE || !defined NDEBUG
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 #endif
 
   /* ARGS_TEMPLATE is composed of bit fields:
@@ -650,7 +650,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, 
Lisp_Object maxdepth,
            Lisp_Object fun = TOP;
            Lisp_Object *args = &TOP + 1;
 
-           ptrdiff_t count1 = record_in_backtrace (fun, args, numargs);
+           specpdl_ref count1 = record_in_backtrace (fun, args, numargs);
            maybe_gc ();
            if (debug_on_next_call)
              do_debug_on_call (Qlambda, count1);
@@ -678,7 +678,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, 
Lisp_Object maxdepth,
              val = funcall_general (original_fun, numargs, args);
 
            lisp_eval_depth--;
-           if (backtrace_debug_on_exit (specpdl + count1))
+           if (backtrace_debug_on_exit (specpdl_ref_to_ptr (count1)))
              val = call_debugger (list2 (Qexit, val));
            specpdl_ptr--;
 
@@ -702,7 +702,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, 
Lisp_Object maxdepth,
        CASE (Bunbind5):
          op -= Bunbind;
        dounbind:
-         unbind_to (SPECPDL_INDEX () - op, Qnil);
+         unbind_to (specpdl_ref_add (SPECPDL_INDEX (), -op), Qnil);
          NEXT;
 
        CASE (Bgoto):
@@ -796,7 +796,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, 
Lisp_Object maxdepth,
 
        CASE (Bsave_window_excursion): /* Obsolete since 24.1.  */
          {
-           ptrdiff_t count1 = SPECPDL_INDEX ();
+           specpdl_ref count1 = SPECPDL_INDEX ();
            record_unwind_protect (restore_window_configuration,
                                   Fcurrent_window_configuration (Qnil));
            TOP = Fprogn (TOP);
@@ -872,7 +872,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, 
Lisp_Object maxdepth,
            temp_output_buffer_show (TOP);
            TOP = v1;
            /* pop binding of standard-output */
-           unbind_to (SPECPDL_INDEX () - 1, Qnil);
+           unbind_to (specpdl_ref_add (SPECPDL_INDEX (), -1), Qnil);
            NEXT;
          }
 
@@ -1585,10 +1585,10 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object 
vector, Lisp_Object maxdepth,
  exit:
 
 #if BYTE_CODE_SAFE || !defined NDEBUG
-  if (SPECPDL_INDEX () != count)
+  if (!specpdl_ref_eq (SPECPDL_INDEX (), count))
     {
       /* Binds and unbinds are supposed to be compiled balanced.  */
-      if (SPECPDL_INDEX () > count)
+      if (specpdl_ref_lt (count, SPECPDL_INDEX ()))
        unbind_to (count, Qnil);
       error ("binding stack not balanced (serious byte compiler bug)");
     }
diff --git a/src/callint.c b/src/callint.c
index ce77c893f4..31919d6bb8 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -251,7 +251,7 @@ return non-nil.
 usage: (funcall-interactively FUNCTION &rest ARGUMENTS)  */)
      (ptrdiff_t nargs, Lisp_Object *args)
 {
-  ptrdiff_t speccount = SPECPDL_INDEX ();
+  specpdl_ref speccount = SPECPDL_INDEX ();
   temporarily_switch_to_single_kboard (NULL);
 
   /* Nothing special to do here, all the work is inside
@@ -279,7 +279,7 @@ invoke it (via an `interactive' spec that contains, for 
instance, an
 `this-command-keys-vector' is used.  */)
   (Lisp_Object function, Lisp_Object record_flag, Lisp_Object keys)
 {
-  ptrdiff_t speccount = SPECPDL_INDEX ();
+  specpdl_ref speccount = SPECPDL_INDEX ();
 
   bool arg_from_tty = false;
   ptrdiff_t key_count;
@@ -541,7 +541,7 @@ invoke it (via an `interactive' spec that contains, for 
instance, an
 
        case 'k':               /* Key sequence.  */
          {
-           ptrdiff_t speccount1 = SPECPDL_INDEX ();
+           specpdl_ref speccount1 = SPECPDL_INDEX ();
            specbind (Qcursor_in_echo_area, Qt);
            /* Prompt in `minibuffer-prompt' face.  */
            Fput_text_property (make_fixnum (0),
@@ -571,7 +571,7 @@ invoke it (via an `interactive' spec that contains, for 
instance, an
 
        case 'K':               /* Key sequence to be defined.  */
          {
-           ptrdiff_t speccount1 = SPECPDL_INDEX ();
+           specpdl_ref speccount1 = SPECPDL_INDEX ();
            specbind (Qcursor_in_echo_area, Qt);
            /* Prompt in `minibuffer-prompt' face.  */
            Fput_text_property (make_fixnum (0),
diff --git a/src/callproc.c b/src/callproc.c
index dcee740043..018c9ce690 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -122,7 +122,7 @@ enum
     CALLPROC_FDS
   };
 
-static Lisp_Object call_process (ptrdiff_t, Lisp_Object *, int, ptrdiff_t);
+static Lisp_Object call_process (ptrdiff_t, Lisp_Object *, int, specpdl_ref);
 
 #ifdef DOS_NT
 # define CHILD_SETUP_TYPE int
@@ -289,7 +289,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION 
DISPLAY &rest ARGS)  *
 {
   Lisp_Object infile, encoded_infile;
   int filefd;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   if (nargs >= 2 && ! NILP (args[1]))
     {
@@ -310,12 +310,13 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION 
DISPLAY &rest ARGS)  *
   if (filefd < 0)
     report_file_error ("Opening process input file", infile);
   record_unwind_protect_int (close_file_unwind, filefd);
-  return unbind_to (count, call_process (nargs, args, filefd, -1));
+  return unbind_to (count, call_process (nargs, args, filefd,
+                                        make_invalid_specpdl_ref ()));
 }
 
 /* Like Fcall_process (NARGS, ARGS), except use FILEFD as the input file.
 
-   If TEMPFILE_INDEX is nonnegative, it is the specpdl index of an
+   If TEMPFILE_INDEX is valid, it is the specpdl index of an
    unwinder that is intended to remove the input temporary file; in
    this case NARGS must be at least 2 and ARGS[1] is the file's name.
 
@@ -323,7 +324,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION 
DISPLAY &rest ARGS)  *
 
 static Lisp_Object
 call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
-             ptrdiff_t tempfile_index)
+             specpdl_ref tempfile_index)
 {
   Lisp_Object buffer, current_dir, path;
   bool display_p;
@@ -331,7 +332,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int 
filefd,
   int callproc_fd[CALLPROC_FDS];
   int status;
   ptrdiff_t i;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   USE_SAFE_ALLOCA;
 
   char **new_argv;
@@ -616,7 +617,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int 
filefd,
        callproc_fd[i] = -1;
       }
   emacs_close (filefd);
-  clear_unwind_protect (count - 1);
+  clear_unwind_protect (specpdl_ref_add (count, -1));
 
   if (tempfile)
     {
@@ -654,7 +655,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int 
filefd,
 
       if (FIXNUMP (buffer))
        {
-         if (tempfile_index < 0)
+         if (!specpdl_ref_valid_p (tempfile_index))
            record_deleted_pid (pid, Qnil);
          else
            {
@@ -681,7 +682,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int 
filefd,
        callproc_fd[i] = -1;
       }
   emacs_close (filefd);
-  clear_unwind_protect (count - 1);
+  clear_unwind_protect (specpdl_ref_add (count, -1));
 
 #endif /* not MSDOS */
 
@@ -813,7 +814,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int 
filefd,
          else
            {                   /* We have to decode the input.  */
              Lisp_Object curbuf;
-             ptrdiff_t count1 = SPECPDL_INDEX ();
+             specpdl_ref count1 = SPECPDL_INDEX ();
 
              XSETBUFFER (curbuf, current_buffer);
              /* We cannot allow after-change-functions be run
@@ -957,7 +958,6 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args,
   {
     Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir);
     char *tempfile;
-    ptrdiff_t count;
 
 #ifdef WINDOWSNT
     /* Cannot use the result of Fexpand_file_name, because it
@@ -977,7 +977,7 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args,
     filename_string = Fcopy_sequence (ENCODE_FILE (pattern));
     tempfile = SSDATA (filename_string);
 
-    count = SPECPDL_INDEX ();
+    specpdl_ref count = SPECPDL_INDEX ();
     record_unwind_protect_nothing ();
     fd = mkostemp (tempfile, O_BINARY | O_CLOEXEC);
     if (fd < 0)
@@ -1009,7 +1009,7 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args,
   val = complement_process_encoding_system (val);
 
   {
-    ptrdiff_t count1 = SPECPDL_INDEX ();
+    specpdl_ref count1 = SPECPDL_INDEX ();
 
     specbind (intern ("coding-system-for-write"), val);
     /* POSIX lets mk[s]temp use "."; don't invoke jka-compr if we
@@ -1069,7 +1069,7 @@ usage: (call-process-region START END PROGRAM &optional 
DELETE BUFFER DISPLAY &r
   (ptrdiff_t nargs, Lisp_Object *args)
 {
   Lisp_Object infile, val;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object start = args[0];
   Lisp_Object end = args[1];
   bool empty_input;
@@ -1123,7 +1123,8 @@ usage: (call-process-region START END PROGRAM &optional 
DELETE BUFFER DISPLAY &r
     }
   args[1] = infile;
 
-  val = call_process (nargs, args, fd, empty_input ? -1 : count);
+  val = call_process (nargs, args, fd,
+                     empty_input ? make_invalid_specpdl_ref () : count);
   return unbind_to (count, val);
 }
 
diff --git a/src/charset.c b/src/charset.c
index dec9d56df2..d0cfe60952 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -483,7 +483,7 @@ load_charset_map_from_file (struct charset *charset, 
Lisp_Object mapfile,
   AUTO_STRING (map, ".map");
   AUTO_STRING (txt, ".txt");
   AUTO_LIST2 (suffixes, map, txt);
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   record_unwind_protect_nothing ();
   specbind (Qfile_name_handler_alist, Qnil);
   fd = openp (Vcharset_map_path, mapfile, suffixes, NULL, Qnil, false, false);
@@ -495,7 +495,7 @@ load_charset_map_from_file (struct charset *charset, 
Lisp_Object mapfile,
       report_file_errno ("Loading charset map", mapfile, open_errno);
     }
   set_unwind_protect_ptr (count, fclose_unwind, fp);
-  unbind_to (count + 1, Qnil);
+  unbind_to (specpdl_ref_add (count, 1), Qnil);
 
   /* Use record_xmalloc, as `charset_map_entries' is
      large (larger than MAX_ALLOCA).  */
diff --git a/src/coding.c b/src/coding.c
index df6c423caa..c16598d275 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -7907,7 +7907,7 @@ coding_restore_undo_list (Lisp_Object arg)
 void
 decode_coding_gap (struct coding_system *coding, ptrdiff_t bytes)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object attrs;
 
   eassert (GPT_BYTE == PT_BYTE);
@@ -8071,7 +8071,7 @@ decode_coding_object (struct coding_system *coding,
                      ptrdiff_t to, ptrdiff_t to_byte,
                      Lisp_Object dst_object)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   unsigned char *destination UNINIT;
   ptrdiff_t dst_bytes UNINIT;
   ptrdiff_t chars = to - from;
@@ -8170,7 +8170,7 @@ decode_coding_object (struct coding_system *coding,
       ptrdiff_t prev_Z = Z, prev_Z_BYTE = Z_BYTE;
       Lisp_Object val;
       Lisp_Object undo_list = BVAR (current_buffer, undo_list);
-      ptrdiff_t count1 = SPECPDL_INDEX ();
+      specpdl_ref count1 = SPECPDL_INDEX ();
 
       record_unwind_protect (coding_restore_undo_list,
                             Fcons (undo_list, Fcurrent_buffer ()));
@@ -8290,7 +8290,7 @@ encode_coding_object (struct coding_system *coding,
                      ptrdiff_t to, ptrdiff_t to_byte,
                      Lisp_Object dst_object)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   ptrdiff_t chars = to - from;
   ptrdiff_t bytes = to_byte - from_byte;
   Lisp_Object attrs;
@@ -8584,7 +8584,7 @@ are lower-case).  */)
   (Lisp_Object prompt, Lisp_Object default_coding_system)
 {
   Lisp_Object val;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   if (SYMBOLP (default_coding_system))
     default_coding_system = SYMBOL_NAME (default_coding_system);
diff --git a/src/comp.c b/src/comp.c
index 251613dc3d..6449eedb27 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -2639,7 +2639,7 @@ emit_static_object (const char *name, Lisp_Object obj)
      strings cause of this funny bug that will affect all pre gcc10 era gccs:
      https://gcc.gnu.org/ml/jit/2019-q3/msg00013.html  */
 
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   /* Preserve uninterned symbols, this is specifically necessary for
      CL macro expansion in dynamic scope code (bug#42088).  See
      `byte-compile-output-file-form'.  */
@@ -4995,7 +4995,7 @@ helper_temp_output_buffer_setup (Lisp_Object x)
 Lisp_Object
 helper_unbind_n (Lisp_Object n)
 {
-  return unbind_to (SPECPDL_INDEX () - XFIXNUM (n), Qnil);
+  return unbind_to (specpdl_ref_add (SPECPDL_INDEX (), -XFIXNUM (n)), Qnil);
 }
 
 void
@@ -5270,7 +5270,7 @@ load_comp_unit (struct Lisp_Native_Comp_Unit *comp_u, 
bool loading_dump,
      identify is we have at least another load active on it.  */
   bool recursive_load = comp_u->load_ongoing;
   comp_u->load_ongoing = true;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   if (!recursive_load)
     record_unwind_protect (unset_cu_load_ongoing, comp_u_lisp_obj);
 
diff --git a/src/composite.c b/src/composite.c
index a4db66b92d..17563201e2 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -575,7 +575,7 @@ update_compositions (ptrdiff_t from, ptrdiff_t to, int 
check_mask)
     }
   if (min_pos < max_pos)
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
 
       specbind (Qinhibit_read_only, Qt);
       specbind (Qinhibit_modification_hooks, Qt);
@@ -892,7 +892,7 @@ autocmp_chars (Lisp_Object rule, ptrdiff_t charpos, 
ptrdiff_t bytepos,
               ptrdiff_t limit, struct window *win, struct face *face,
               Lisp_Object string, Lisp_Object direction, int ch)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object pos = make_fixnum (charpos);
   ptrdiff_t to;
   ptrdiff_t pt = PT, pt_byte = PT_BYTE;
diff --git a/src/cygw32.c b/src/cygw32.c
index 399c1f91b9..759d9af94d 100644
--- a/src/cygw32.c
+++ b/src/cygw32.c
@@ -56,7 +56,7 @@ conv_filename_to_w32_unicode (Lisp_Object in, int absolute_p)
   ssize_t converted_len;
   Lisp_Object converted;
   unsigned flags;
-  int count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   chdir_to_default_directory ();
 
@@ -85,7 +85,7 @@ conv_filename_from_w32_unicode (const wchar_t* in, int 
absolute_p)
   ssize_t converted_len;
   Lisp_Object converted;
   unsigned flags;
-  int count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   chdir_to_default_directory ();
 
diff --git a/src/data.c b/src/data.c
index 95d29ac9e9..1526cc0c73 100644
--- a/src/data.c
+++ b/src/data.c
@@ -1837,7 +1837,7 @@ notify_variable_watchers (Lisp_Object symbol,
 {
   symbol = Findirect_variable (symbol);
 
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   record_unwind_protect (restore_symbol_trapped_write, symbol);
   /* Avoid recursion.  */
   set_symbol_trapped_write (symbol, SYMBOL_UNTRAPPED_WRITE);
diff --git a/src/decompress.c b/src/decompress.c
index 60f8bfd6a2..ddd8abbf27 100644
--- a/src/decompress.c
+++ b/src/decompress.c
@@ -239,7 +239,7 @@ This function can be called only in unibyte buffers.  */)
   z_stream stream;
   int inflate_status;
   struct decompress_unwind_data unwind_data;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   validate_region (&start, &end);
 
diff --git a/src/dired.c b/src/dired.c
index 7fb54f2f67..cd50012ddc 100644
--- a/src/dired.c
+++ b/src/dired.c
@@ -195,7 +195,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.  */
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   record_unwind_protect_ptr (directory_files_internal_unwind, d);
 
 #ifdef WINDOWSNT
@@ -289,7 +289,7 @@ directory_files_internal (Lisp_Object directory, 
Lisp_Object full,
 #endif
 
   /* Discard the unwind protect.  */
-  specpdl_ptr = specpdl + count;
+  specpdl_ptr = specpdl_ref_to_ptr (count);
 
   if (NILP (nosort))
     list = Fsort (Fnreverse (list),
@@ -455,7 +455,7 @@ file_name_completion (Lisp_Object file, Lisp_Object 
dirname, bool all_flag,
      anything.  */
   bool includeall = 1;
   bool check_decoded = false;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   elt = Qnil;
 
@@ -944,7 +944,7 @@ file_attributes (int fd, char const *name,
                 Lisp_Object dirname, Lisp_Object filename,
                 Lisp_Object id_format)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   struct stat s;
 
   /* An array to hold the mode string generated by filemodestring,
diff --git a/src/dispnew.c b/src/dispnew.c
index 6337bcf130..0d959047f3 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -6176,15 +6176,13 @@ Return t if redisplay was performed, nil if redisplay 
was preempted
 immediately by pending input.  */)
   (Lisp_Object force)
 {
-  ptrdiff_t count;
-
   swallow_events (true);
   if ((detect_input_pending_run_timers (1)
        && NILP (force) && !redisplay_dont_pause)
       || !NILP (Vexecuting_kbd_macro))
     return Qnil;
 
-  count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   if (!NILP (force) && !redisplay_dont_pause)
     specbind (Qredisplay_dont_pause, Qt);
   redisplay_preserve_echo_area (2);
diff --git a/src/doc.c b/src/doc.c
index 0b12eb154d..a9f77b25bf 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -83,7 +83,7 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool 
definition)
 {
   char *from, *to, *name, *p, *p1;
   Lisp_Object file, pos;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object dir;
   USE_SAFE_ALLOCA;
 
@@ -545,7 +545,6 @@ the same file name is found in the `doc-directory'.  */)
   EMACS_INT pos;
   Lisp_Object sym;
   char *p, *name;
-  ptrdiff_t count;
   char const *dirname;
   ptrdiff_t dirlen;
   /* Preloaded defcustoms using custom-initialize-delay are added to
@@ -569,7 +568,7 @@ the same file name is found in the `doc-directory'.  */)
       dirlen = SBYTES (Vdoc_directory);
     }
 
-  count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   USE_SAFE_ALLOCA;
   name = SAFE_ALLOCA (dirlen + SBYTES (filename) + 1);
   lispstpcpy (stpcpy (name, dirname), filename);       /*** Add this line ***/
diff --git a/src/editfns.c b/src/editfns.c
index 790f66e3a0..6cb684d4d8 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -847,7 +847,7 @@ usage: (save-excursion &rest BODY)  */)
   (Lisp_Object args)
 {
   register Lisp_Object val;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   record_unwind_protect_excursion ();
 
@@ -861,7 +861,7 @@ BODY is executed just like `progn'.
 usage: (save-current-buffer &rest BODY)  */)
   (Lisp_Object args)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   record_unwind_current_buffer ();
   return unbind_to (count, Fprogn (args));
@@ -2022,7 +2022,7 @@ nil.  */)
       return Qt;
     }
 
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
 
   ptrdiff_t diags = size_a + size_b + 3;
@@ -2247,7 +2247,7 @@ Both characters must have the same length of multi-byte 
form.  */)
   ptrdiff_t changed = 0;
   unsigned char fromstr[MAX_MULTIBYTE_LENGTH], tostr[MAX_MULTIBYTE_LENGTH];
   unsigned char *p;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 #define COMBINING_NO    0
 #define COMBINING_BEFORE 1
 #define COMBINING_AFTER  2
@@ -2820,7 +2820,7 @@ usage: (save-restriction &rest BODY)  */)
   (Lisp_Object body)
 {
   register Lisp_Object val;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   record_unwind_protect (save_restriction_restore, save_restriction_save ());
   val = Fprogn (body);
@@ -3112,7 +3112,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool 
message)
   ptrdiff_t bufsize = sizeof initial_buffer;
   ptrdiff_t max_bufsize = STRING_BYTES_BOUND + 1;
   char *p;
-  ptrdiff_t buf_save_value_index UNINIT;
+  specpdl_ref buf_save_value_index UNINIT;
   char *format, *end;
   ptrdiff_t nchars;
   /* When we make a multibyte string, we must pay attention to the
diff --git a/src/emacs-module.c b/src/emacs-module.c
index 392b3ba965..0974a199e5 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -1137,7 +1137,7 @@ DEFUN ("module-load", Fmodule_load, Smodule_load, 1, 1, 0,
   rt->private_members = &rt_priv;
   rt->get_environment = module_get_environment;
 
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   record_unwind_protect_module (SPECPDL_MODULE_RUNTIME, rt);
   record_unwind_protect_module (SPECPDL_MODULE_ENVIRONMENT, rt_priv.env);
 
@@ -1166,7 +1166,7 @@ funcall_module (Lisp_Object function, ptrdiff_t nargs, 
Lisp_Object *arglist)
   emacs_env pub;
   struct emacs_env_private priv;
   emacs_env *env = initialize_environment (&pub, &priv);
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   record_unwind_protect_module (SPECPDL_MODULE_ENVIRONMENT, env);
 
   USE_SAFE_ALLOCA;
diff --git a/src/emacs.c b/src/emacs.c
index 31cc2078bd..d1060bca0b 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -456,7 +456,7 @@ init_cmdargs (int argc, char **argv, int skip_args, char 
const *original_pwd)
 {
   int i;
   Lisp_Object name, dir, handler;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object raw_name;
   AUTO_STRING (slash_colon, "/:");
 
@@ -2904,7 +2904,7 @@ You must run Emacs in batch mode in order to dump it.  */)
 {
   Lisp_Object tem;
   Lisp_Object symbol;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   check_pure_size ();
 
diff --git a/src/eval.c b/src/eval.c
index ae9b18da0b..d1c45fca56 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -65,7 +65,7 @@ union specbinding *backtrace_next (union specbinding *) 
EXTERNALLY_VISIBLE;
 union specbinding *backtrace_top (void) EXTERNALLY_VISIBLE;
 
 static Lisp_Object funcall_lambda (Lisp_Object, ptrdiff_t, Lisp_Object *);
-static Lisp_Object apply_lambda (Lisp_Object, Lisp_Object, ptrdiff_t);
+static Lisp_Object apply_lambda (Lisp_Object, Lisp_Object, specpdl_ref);
 static Lisp_Object lambda_arity (Lisp_Object);
 
 static Lisp_Object
@@ -282,11 +282,12 @@ Lisp_Object
 call_debugger (Lisp_Object arg)
 {
   bool debug_while_redisplaying;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object val;
   intmax_t old_depth = max_lisp_eval_depth;
   /* Do not allow max_specpdl_size less than actual depth (Bug#16603).  */
-  intmax_t old_max = max (max_specpdl_size, count);
+  ptrdiff_t counti = specpdl_ref_to_count (count);
+  intmax_t old_max = max (max_specpdl_size, counti);
 
   /* The previous value of 40 is too small now that the debugger
      prints using cl-prin1 instead of prin1.  Printing lists nested 8
@@ -296,9 +297,9 @@ call_debugger (Lisp_Object arg)
 
   /* While debugging Bug#16603, previous value of 100 was found
      too small to avoid specpdl overflow in the debugger itself.  */
-  max_ensure_room (&max_specpdl_size, count, 200);
+  max_ensure_room (&max_specpdl_size, counti, 200);
 
-  if (old_max == count)
+  if (old_max == counti)
     {
       /* We can enter the debugger due to specpdl overflow (Bug#16603).  */
       specpdl_ptr--;
@@ -348,10 +349,10 @@ call_debugger (Lisp_Object arg)
 }
 
 void
-do_debug_on_call (Lisp_Object code, ptrdiff_t count)
+do_debug_on_call (Lisp_Object code, specpdl_ref count)
 {
   debug_on_next_call = 0;
-  set_backtrace_debug_on_exit (specpdl + count, true);
+  set_backtrace_debug_on_exit (specpdl_ref_to_ptr (count), true);
   call_debugger (list1 (code));
 }
 
@@ -929,7 +930,7 @@ usage: (let* VARLIST BODY...)  */)
   (Lisp_Object args)
 {
   Lisp_Object var, val, elt, lexenv;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   lexenv = Vinternal_interpreter_environment;
 
@@ -989,7 +990,7 @@ usage: (let VARLIST BODY...)  */)
 {
   Lisp_Object *temps, tem, lexenv;
   Lisp_Object elt;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   ptrdiff_t argnum;
   USE_SAFE_ALLOCA;
 
@@ -1093,7 +1094,7 @@ If FUNCTION takes less time to execute than TIMEOUT 
seconds, MESSAGE
 is not displayed.  */)
   (Lisp_Object timeout, Lisp_Object message, Lisp_Object function)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   CHECK_NUMBER (timeout);
   CHECK_STRING (message);
@@ -1306,7 +1307,7 @@ usage: (unwind-protect BODYFORM UNWINDFORMS...)  */)
   (Lisp_Object args)
 {
   Lisp_Object val;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   record_unwind_protect (prog_ignore, XCDR (args));
   val = eval_sub (XCAR (args));
@@ -1430,7 +1431,7 @@ internal_lisp_condition_case (Lisp_Object var, 
Lisp_Object bodyform,
          /* Bind HANDLER_VAR to VAL while evaluating HANDLER_BODY.
             The unbind_to undoes just this binding; whoever longjumped
             to us unwound the stack to C->pdlcount before throwing.  */
-         ptrdiff_t count = SPECPDL_INDEX ();
+         specpdl_ref count = SPECPDL_INDEX ();
          specbind (handler_var, val);
          return unbind_to (count, Fprogn (handler_body));
        }
@@ -1451,7 +1452,7 @@ internal_lisp_condition_case (Lisp_Object var, 
Lisp_Object bodyform,
          handler_var = Qinternal_interpreter_environment;
        }
 
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       specbind (handler_var, result);
       return unbind_to (count, Fprogn (success_handler));
     }
@@ -1815,7 +1816,8 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object 
data, bool keyboard_quit)
     {
       /* Edebug takes care of restoring these variables when it exits.  */
       max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 20);
-      max_ensure_room (&max_specpdl_size, SPECPDL_INDEX (), 40);
+      ptrdiff_t counti = specpdl_ref_to_count (SPECPDL_INDEX ());
+      max_ensure_room (&max_specpdl_size, counti, 40);
 
       call2 (Vsignal_hook_function, error_symbol, data);
     }
@@ -1883,8 +1885,9 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object 
data, bool keyboard_quit)
       && !NILP (Ffboundp (Qdebug_early)))
     {
       max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100);
-      max_ensure_room (&max_specpdl_size, SPECPDL_INDEX (), 200);
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
+      ptrdiff_t counti = specpdl_ref_to_count (count);
+      max_ensure_room (&max_specpdl_size, counti, 200);
       specbind (Qdebugger, Qdebug_early);
       call_debugger (list2 (Qerror, Fcons (error_symbol, data)));
       unbind_to (count, Qnil);
@@ -2271,7 +2274,7 @@ load_with_autoload_queue
   (Lisp_Object file, Lisp_Object noerror, Lisp_Object nomessage,
    Lisp_Object nosuffix, Lisp_Object must_suffix)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   /* If autoloading gets an error (which includes the error of failing
      to define the function being called), we use Vautoload_queue
@@ -2350,7 +2353,7 @@ LEXICAL can also be an actual lexical environment, in the 
form of an
 alist mapping symbols to their value.  */)
   (Lisp_Object form, Lisp_Object lexical)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   specbind (Qinternal_interpreter_environment,
            CONSP (lexical) || NILP (lexical) ? lexical : list1 (Qt));
   return unbind_to (count, eval_sub (form));
@@ -2361,7 +2364,7 @@ grow_specpdl_allocation (void)
 {
   eassert (specpdl_ptr == specpdl + specpdl_size);
 
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   ptrdiff_t max_size = min (max_specpdl_size, PTRDIFF_MAX - 1000);
   union specbinding *pdlvec = specpdl - 1;
   ptrdiff_t pdlvecsize = specpdl_size + 1;
@@ -2375,7 +2378,7 @@ grow_specpdl_allocation (void)
   pdlvec = xpalloc (pdlvec, &pdlvecsize, 1, max_size + 1, sizeof *specpdl);
   specpdl = pdlvec + 1;
   specpdl_size = pdlvecsize - 1;
-  specpdl_ptr = specpdl + count;
+  specpdl_ptr = specpdl_ref_to_ptr (count);
 }
 
 /* Grow the specpdl stack by one entry.
@@ -2396,10 +2399,10 @@ grow_specpdl (void)
     grow_specpdl_allocation ();
 }
 
-ptrdiff_t
+specpdl_ref
 record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   eassert (nargs >= UNEVALLED);
   specpdl_ptr->bt.kind = SPECPDL_BACKTRACE;
@@ -2449,7 +2452,7 @@ eval_sub (Lisp_Object form)
   CHECK_LIST (original_args);
 
   /* This also protects them from gc.  */
-  ptrdiff_t count
+  specpdl_ref count
     = record_in_backtrace (original_fun, &original_args, UNEVALLED);
 
   if (debug_on_next_call)
@@ -2498,13 +2501,13 @@ eval_sub (Lisp_Object form)
              vals[argnum++] = eval_sub (arg);
            }
 
-         set_backtrace_args (specpdl + count, vals, argnum);
+         set_backtrace_args (specpdl_ref_to_ptr (count), vals, argnum);
 
          val = XSUBR (fun)->function.aMANY (argnum, vals);
 
          lisp_eval_depth--;
          /* Do the debug-on-exit now, while VALS still exists.  */
-         if (backtrace_debug_on_exit (specpdl + count))
+         if (backtrace_debug_on_exit (specpdl_ref_to_ptr (count)))
            val = call_debugger (list2 (Qexit, val));
          SAFE_FREE ();
          specpdl_ptr--;
@@ -2520,7 +2523,7 @@ eval_sub (Lisp_Object form)
              args_left = Fcdr (args_left);
            }
 
-         set_backtrace_args (specpdl + count, argvals, numargs);
+         set_backtrace_args (specpdl_ref_to_ptr (count), argvals, numargs);
 
          switch (i)
            {
@@ -2592,7 +2595,7 @@ eval_sub (Lisp_Object form)
        }
       if (EQ (funcar, Qmacro))
        {
-         ptrdiff_t count1 = SPECPDL_INDEX ();
+         specpdl_ref count1 = SPECPDL_INDEX ();
          Lisp_Object exp;
          /* Bind lexical-binding during expansion of the macro, so the
             macro can know reliably if the code it outputs will be
@@ -2624,7 +2627,7 @@ eval_sub (Lisp_Object form)
     }
 
   lisp_eval_depth--;
-  if (backtrace_debug_on_exit (specpdl + count))
+  if (backtrace_debug_on_exit (specpdl_ref_to_ptr (count)))
     val = call_debugger (list2 (Qexit, val));
   specpdl_ptr--;
 
@@ -3070,7 +3073,7 @@ Thus, (funcall \\='cons \\='x \\='y) returns (x . y).
 usage: (funcall FUNCTION &rest ARGUMENTS)  */)
   (ptrdiff_t nargs, Lisp_Object *args)
 {
-  ptrdiff_t count;
+  specpdl_ref count;
 
   maybe_quit ();
 
@@ -3092,7 +3095,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS)  */)
   Lisp_Object val = funcall_general (args[0], nargs - 1, args + 1);
 
   lisp_eval_depth--;
-  if (backtrace_debug_on_exit (specpdl + count))
+  if (backtrace_debug_on_exit (specpdl_ref_to_ptr (count)))
     val = call_debugger (list2 (Qexit, val));
   specpdl_ptr--;
   return val;
@@ -3183,7 +3186,7 @@ fetch_and_exec_byte_code (Lisp_Object fun, ptrdiff_t 
args_template,
 }
 
 static Lisp_Object
-apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count)
+apply_lambda (Lisp_Object fun, Lisp_Object args, specpdl_ref count)
 {
   Lisp_Object *arg_vector;
   Lisp_Object tem;
@@ -3200,12 +3203,12 @@ apply_lambda (Lisp_Object fun, Lisp_Object args, 
ptrdiff_t count)
       arg_vector[i] = tem;
     }
 
-  set_backtrace_args (specpdl + count, arg_vector, numargs);
+  set_backtrace_args (specpdl_ref_to_ptr (count), arg_vector, numargs);
   tem = funcall_lambda (fun, numargs, arg_vector);
 
   lisp_eval_depth--;
   /* Do the debug-on-exit now, while arg_vector still exists.  */
-  if (backtrace_debug_on_exit (specpdl + count))
+  if (backtrace_debug_on_exit (specpdl_ref_to_ptr (count)))
     tem = call_debugger (list2 (Qexit, tem));
   SAFE_FREE ();
   specpdl_ptr--;
@@ -3222,7 +3225,7 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs,
                register Lisp_Object *arg_vector)
 {
   Lisp_Object val, syms_left, next, lexenv;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   ptrdiff_t i;
   bool optional, rest;
 
@@ -3820,9 +3823,9 @@ record_unwind_protect_nothing (void)
    It need not be at the top of the stack.  */
 
 void
-clear_unwind_protect (ptrdiff_t count)
+clear_unwind_protect (specpdl_ref count)
 {
-  union specbinding *p = specpdl + count;
+  union specbinding *p = specpdl_ref_to_ptr (count);
   p->unwind_void.kind = SPECPDL_UNWIND_VOID;
   p->unwind_void.func = do_nothing;
 }
@@ -3832,10 +3835,10 @@ clear_unwind_protect (ptrdiff_t count)
    previous value without invoking it.  */
 
 void
-set_unwind_protect (ptrdiff_t count, void (*func) (Lisp_Object),
+set_unwind_protect (specpdl_ref count, void (*func) (Lisp_Object),
                    Lisp_Object arg)
 {
-  union specbinding *p = specpdl + count;
+  union specbinding *p = specpdl_ref_to_ptr (count);
   p->unwind.kind = SPECPDL_UNWIND;
   p->unwind.func = func;
   p->unwind.arg = arg;
@@ -3843,9 +3846,9 @@ set_unwind_protect (ptrdiff_t count, void (*func) 
(Lisp_Object),
 }
 
 void
-set_unwind_protect_ptr (ptrdiff_t count, void (*func) (void *), void *arg)
+set_unwind_protect_ptr (specpdl_ref count, void (*func) (void *), void *arg)
 {
-  union specbinding *p = specpdl + count;
+  union specbinding *p = specpdl_ref_to_ptr (count);
   p->unwind_ptr.kind = SPECPDL_UNWIND_PTR;
   p->unwind_ptr.func = func;
   p->unwind_ptr.arg = arg;
@@ -3855,13 +3858,13 @@ set_unwind_protect_ptr (ptrdiff_t count, void (*func) 
(void *), void *arg)
    depth COUNT is reached.  Return VALUE.  */
 
 Lisp_Object
-unbind_to (ptrdiff_t count, Lisp_Object value)
+unbind_to (specpdl_ref count, Lisp_Object value)
 {
   Lisp_Object quitf = Vquit_flag;
 
   Vquit_flag = Qnil;
 
-  while (specpdl_ptr != specpdl + count)
+  while (specpdl_ptr != specpdl_ref_to_ptr (count))
     {
       /* Copy the binding, and decrement specpdl_ptr, before we do
         the work to unbind it.  We decrement first
@@ -4152,7 +4155,7 @@ NFRAMES and BASE specify the activation frame to use, as 
in `backtrace-frame'.
      (Lisp_Object exp, Lisp_Object nframes, Lisp_Object base)
 {
   union specbinding *pdl = get_backtrace_frame (nframes, base);
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   ptrdiff_t distance = specpdl_ptr - pdl;
   eassert (distance >= 0);
 
diff --git a/src/fileio.c b/src/fileio.c
index 9c50cbb35a..243a87a482 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -714,14 +714,14 @@ This function does not grok magic file names.  */)
   bool failed = fd < 0;
   if (!failed)
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       record_unwind_protect_int (close_file_unwind, fd);
       val = DECODE_FILE (val);
       if (STRINGP (text) && SBYTES (text) != 0)
        write_region (text, Qnil, val, Qnil, Qnil, Qnil, Qnil, fd);
       failed = NILP (dir_flag) && emacs_close (fd) != 0;
       /* Discard the unwind protect.  */
-      specpdl_ptr = specpdl + count;
+      specpdl_ptr = specpdl_ref_to_ptr (count);
     }
   if (failed)
     {
@@ -2165,7 +2165,7 @@ permissions.  */)
    Lisp_Object preserve_permissions)
 {
   Lisp_Object handler;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object encoded_file, encoded_newname;
 #if HAVE_LIBSELINUX
   char *con;
@@ -2416,7 +2416,7 @@ permissions.  */)
 #endif /* not WINDOWSNT */
 
   /* Discard the unwind protects.  */
-  specpdl_ptr = specpdl + count;
+  specpdl_ptr = specpdl_ref_to_ptr (count);
 
   return Qnil;
 }
@@ -2718,7 +2718,7 @@ This is what happens in interactive use with M-x.  */)
        Fcopy_file (file, newname, ok_if_already_exists, Qt, Qt, Qt);
     }
 
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   specbind (Qdelete_by_moving_to_trash, Qnil);
   if (dirp)
     call2 (Qdelete_directory, file, Qt);
@@ -3903,7 +3903,7 @@ by calling `format-decode', which see.  */)
   ptrdiff_t how_much;
   off_t beg_offset, end_offset;
   int unprocessed;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object handler, val, insval, orig_filename, old_undo;
   Lisp_Object p;
   ptrdiff_t total = 0;
@@ -3922,7 +3922,6 @@ by calling `format-decode', which see.  */)
        && BEG == Z);
   Lisp_Object old_Vdeactivate_mark = Vdeactivate_mark;
   bool we_locked_file = false;
-  ptrdiff_t fd_index;
   Lisp_Object window_markers = Qnil;
   /* same_at_start and same_at_end count bytes, because file access counts
      bytes and BEG and END count bytes.  */
@@ -3984,7 +3983,7 @@ by calling `format-decode', which see.  */)
       goto notfound;
     }
 
-  fd_index = SPECPDL_INDEX ();
+  specpdl_ref fd_index = SPECPDL_INDEX ();
   record_unwind_protect_int (close_file_unwind, fd);
 
   /* Replacement should preserve point as it preserves markers.  */
@@ -4327,7 +4326,7 @@ by calling `format-decode', which see.  */)
       if (! giveup_match_end)
        {
          ptrdiff_t temp;
-          ptrdiff_t this_count = SPECPDL_INDEX ();
+          specpdl_ref this_count = SPECPDL_INDEX ();
 
          /* We win!  We can handle REPLACE the optimized way.  */
 
@@ -4398,7 +4397,7 @@ by calling `format-decode', which see.  */)
       unsigned char *decoded;
       ptrdiff_t temp;
       ptrdiff_t this = 0;
-      ptrdiff_t this_count = SPECPDL_INDEX ();
+      specpdl_ref this_count = SPECPDL_INDEX ();
       bool multibyte
        = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
       Lisp_Object conversion_buffer;
@@ -4704,7 +4703,7 @@ by calling `format-decode', which see.  */)
             = Fcons (multibyte,
                      Fcons (BVAR (current_buffer, undo_list),
                            Fcurrent_buffer ()));
-         ptrdiff_t count1 = SPECPDL_INDEX ();
+         specpdl_ref count1 = SPECPDL_INDEX ();
 
          bset_enable_multibyte_characters (current_buffer, Qnil);
          bset_undo_list (current_buffer, Qt);
@@ -4855,7 +4854,7 @@ by calling `format-decode', which see.  */)
   if (inserted > 0)
     {
       /* Don't run point motion or modification hooks when decoding.  */
-      ptrdiff_t count1 = SPECPDL_INDEX ();
+      specpdl_ref count1 = SPECPDL_INDEX ();
       ptrdiff_t old_inserted = inserted;
       specbind (Qinhibit_point_motion_hooks, Qt);
       specbind (Qinhibit_modification_hooks, Qt);
@@ -5186,8 +5185,8 @@ write_region (Lisp_Object start, Lisp_Object end, 
Lisp_Object filename,
   const char *fn;
   struct stat st;
   struct timespec modtime;
-  ptrdiff_t count = SPECPDL_INDEX ();
-  ptrdiff_t count1 UNINIT;
+  specpdl_ref count = SPECPDL_INDEX ();
+  specpdl_ref count1 UNINIT;
   Lisp_Object handler;
   Lisp_Object visit_file;
   Lisp_Object annotations;
@@ -5390,7 +5389,7 @@ write_region (Lisp_Object start, Lisp_Object end, 
Lisp_Object filename,
        ok = 0, save_errno = errno;
 
       /* Discard the unwind protect for close_file_unwind.  */
-      specpdl_ptr = specpdl + count1;
+      specpdl_ptr = specpdl_ref_to_ptr (count1);
     }
 
   /* Some file systems have a bug where st_mtime is not updated
@@ -5969,7 +5968,7 @@ A non-nil CURRENT-ONLY argument means save only current 
buffer.  */)
   int do_handled_files;
   Lisp_Object oquit;
   FILE *stream = NULL;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   bool orig_minibuffer_auto_raise = minibuffer_auto_raise;
   bool old_message_p = 0;
   struct auto_save_unwind auto_save_unwind;
diff --git a/src/fns.c b/src/fns.c
index c67871da74..ea8428fd98 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -3060,7 +3060,7 @@ if `last-nonmenu-event' is nil, and `use-dialog-box' is 
non-nil.  */)
   AUTO_STRING (yes_or_no, "(yes or no) ");
   prompt = CALLN (Fconcat, prompt, yes_or_no);
 
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   specbind (Qenable_recursive_minibuffers, Qt);
 
   while (1)
@@ -3222,7 +3222,7 @@ FILENAME are suppressed.  */)
 
   if (NILP (tem))
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       int nesting = 0;
 
       /* This is to make sure that loadup.el gives a clear picture
@@ -4223,7 +4223,7 @@ hash_table_user_defined_call (ptrdiff_t nargs, 
Lisp_Object *args,
 {
   if (!h->mutable)
     return Ffuncall (nargs, args);
-  ptrdiff_t count = inhibit_garbage_collection ();
+  specpdl_ref count = inhibit_garbage_collection ();
   record_unwind_protect_ptr (restore_mutability, h);
   h->mutable = false;
   return unbind_to (count, Ffuncall (nargs, args));
diff --git a/src/fringe.c b/src/fringe.c
index 1f4dd46ec5..4ea368d215 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -971,7 +971,7 @@ update_window_fringes (struct window *w, bool 
keep_current_p)
   if (w->pseudo_window_p)
     return 0;
 
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   /* This function could be called for redisplaying non-selected
      windows, in which case point has been temporarily moved to that
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 95c422bbd9..5e41863c0a 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -2382,7 +2382,7 @@ xg_maybe_add_timer (gpointer data)
 static int
 xg_dialog_run (struct frame *f, GtkWidget *w)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   struct xg_dialog_data dd;
 
   xg_set_screen (w, f);
diff --git a/src/haiku_io.c b/src/haiku_io.c
index 185bd5e9ff..f47ba00d5f 100644
--- a/src/haiku_io.c
+++ b/src/haiku_io.c
@@ -207,7 +207,7 @@ record_c_unwind_protect_from_cxx (void (*fn) (void *), void 
*r)
 }
 
 /* SPECPDL_IDX that is safe from C++ code.  */
-ptrdiff_t
+specpdl_ref
 c_specpdl_idx_from_cxx (void)
 {
   return SPECPDL_INDEX ();
@@ -215,7 +215,7 @@ c_specpdl_idx_from_cxx (void)
 
 /* unbind_to (IDX, Qnil), but safe from C++ code.  */
 void
-c_unbind_to_nil_from_cxx (ptrdiff_t idx)
+c_unbind_to_nil_from_cxx (specpdl_ref idx)
 {
   unbind_to (idx, Qnil);
 }
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index 28bf2ac8b6..5feb56b9f9 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -2948,7 +2948,7 @@ be_popup_file_dialog (int open_p, const char 
*default_dir, int must_match_p, int
                      void (*unblock_input_function) (void),
                      void (*maybe_quit_function) (void))
 {
-  ptrdiff_t idx = c_specpdl_idx_from_cxx ();
+  specpdl_ref idx = c_specpdl_idx_from_cxx ();
   /* setjmp/longjmp is UB with automatic objects. */
   block_input_function ();
   BWindow *w = (BWindow *) window;
diff --git a/src/haiku_support.h b/src/haiku_support.h
index e50d347009..f20b2e766c 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -787,11 +787,10 @@ extern "C"
   extern void
   record_c_unwind_protect_from_cxx (void (*) (void *), void *);
 
-  extern ptrdiff_t
-  c_specpdl_idx_from_cxx (void);
+  extern specpdl_ref c_specpdl_idx_from_cxx (void);
 
   extern void
-  c_unbind_to_nil_from_cxx (ptrdiff_t idx);
+  c_unbind_to_nil_from_cxx (specpdl_ref idx);
 
   extern void
   BWindow_zoom (void *window);
diff --git a/src/haikufns.c b/src/haikufns.c
index 91e0d392ac..3f60aa807f 100644
--- a/src/haikufns.c
+++ b/src/haikufns.c
@@ -570,7 +570,7 @@ haiku_create_frame (Lisp_Object parms)
   Lisp_Object name;
   bool minibuffer_only = false;
   long window_prompting = 0;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object display;
   struct haiku_display_info *dpyinfo = NULL;
   struct kboard *kb;
@@ -908,7 +908,7 @@ haiku_create_tip_frame (Lisp_Object parms)
   struct frame *f;
   Lisp_Object frame;
   Lisp_Object name;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   bool face_change_before = face_change;
   struct haiku_display_info *dpyinfo = x_display_list;
 
@@ -1204,10 +1204,9 @@ haiku_hide_tip (bool delete)
     return Qnil;
   else
     {
-      ptrdiff_t count;
       Lisp_Object was_open = Qnil;
 
-      count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       specbind (Qinhibit_redisplay, Qt);
       specbind (Qinhibit_quit, Qt);
 
@@ -1939,8 +1938,7 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
   struct text_pos pos;
   int width, height;
   int old_windows_or_buffers_changed = windows_or_buffers_changed;
-  ptrdiff_t count = SPECPDL_INDEX ();
-  ptrdiff_t count_1;
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object window, size, tip_buf;
   AUTO_STRING (tip, " *tip*");
 
@@ -2156,7 +2154,7 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
 
   /* Insert STRING into root window's buffer and fit the frame to the
      buffer.  */
-  count_1 = SPECPDL_INDEX ();
+  specpdl_ref count_1 = SPECPDL_INDEX ();
   old_buffer = current_buffer;
   set_buffer_internal_1 (XBUFFER (w->contents));
   bset_truncate_lines (current_buffer, Qnil);
@@ -2415,7 +2413,6 @@ Optional arg SAVE_TEXT, if non-nil, specifies some text 
to show in the entry fie
    Lisp_Object dir, Lisp_Object mustmatch,
    Lisp_Object dir_only_p, Lisp_Object save_text)
 {
-  ptrdiff_t idx;
   if (!x_display_list)
     error ("Be windowing not initialized");
 
@@ -2433,7 +2430,7 @@ Optional arg SAVE_TEXT, if non-nil, specifies some text 
to show in the entry fie
   CHECK_LIVE_FRAME (frame);
   check_window_system (XFRAME (frame));
 
-  idx = SPECPDL_INDEX ();
+  specpdl_ref idx = SPECPDL_INDEX ();
   record_unwind_protect_void (unwind_popup);
 
   struct frame *f = XFRAME (frame);
diff --git a/src/haikumenu.c b/src/haikumenu.c
index 26eb3dbfe1..002898de7a 100644
--- a/src/haikumenu.c
+++ b/src/haikumenu.c
@@ -273,7 +273,7 @@ haiku_popup_dialog (struct frame *f, Lisp_Object header, 
Lisp_Object contents)
   Lisp_Object title;
   const char *error_name = NULL;
   Lisp_Object selection;
-  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+  specpdl_ref specpdl_count = SPECPDL_INDEX ();
 
   check_window_system (f);
 
@@ -480,7 +480,7 @@ set_frame_menubar (struct frame *f, bool deep_p)
   Lisp_Object items;
   struct buffer *prev = current_buffer;
   Lisp_Object buffer;
-  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+  specpdl_ref specpdl_count = SPECPDL_INDEX ();
   int previous_menu_items_used = f->menu_bar_items_used;
   Lisp_Object *previous_items
     = alloca (previous_menu_items_used * sizeof *previous_items);
diff --git a/src/image.c b/src/image.c
index 7f2bd77781..3c521e413a 100644
--- a/src/image.c
+++ b/src/image.c
@@ -3401,7 +3401,7 @@ slurp_file (int fd, ptrdiff_t *size)
 
   if (fp)
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       record_unwind_protect_ptr (fclose_unwind, fp);
 
       if (fstat (fileno (fp), &st) == 0
diff --git a/src/indent.c b/src/indent.c
index efeb9e74f4..d5ad02ae3a 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -1979,7 +1979,7 @@ line_number_display_width (struct window *w, int *width, 
int *pixel_width)
       struct text_pos startpos;
       bool saved_restriction = false;
       struct buffer *old_buf = current_buffer;
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       SET_TEXT_POS_FROM_MARKER (startpos, w->start);
       void *itdata = bidi_shelve_cache ();
 
@@ -2116,7 +2116,7 @@ whether or not it is currently displayed in some window.  
*/)
   struct window *w;
   Lisp_Object lcols = Qnil;
   void *itdata = NULL;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   /* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES).  */
   if (CONSP (lines))
diff --git a/src/insdel.c b/src/insdel.c
index d9ba222b1d..6f180ac580 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -2134,7 +2134,7 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t 
end_int,
   Lisp_Object start, end;
   Lisp_Object start_marker, end_marker;
   Lisp_Object preserve_marker;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   struct rvoe_arg rvoe_arg;
 
   start = make_fixnum (start_int);
@@ -2201,7 +2201,7 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t 
end_int,
 void
 signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   struct rvoe_arg rvoe_arg;
   Lisp_Object tmp, save_insert_behind_hooks, save_insert_in_from_hooks;
 
@@ -2298,7 +2298,7 @@ DEFUN ("combine-after-change-execute", 
Fcombine_after_change_execute,
        doc: /* This function is for use internally in the function 
`combine-after-change-calls'.  */)
   (void)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   ptrdiff_t beg, end, change;
   ptrdiff_t begpos, endpos;
   Lisp_Object tail;
diff --git a/src/intervals.c b/src/intervals.c
index ed374f16b5..687b237b9e 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -2180,7 +2180,7 @@ get_local_map (ptrdiff_t position, struct buffer *buffer, 
Lisp_Object type)
 {
   Lisp_Object prop, lispy_position, lispy_buffer;
   ptrdiff_t old_begv, old_zv, old_begv_byte, old_zv_byte;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   position = clip_to_bounds (BUF_BEGV (buffer), position, BUF_ZV (buffer));
 
diff --git a/src/json.c b/src/json.c
index 21a6df6785..db1be07f19 100644
--- a/src/json.c
+++ b/src/json.c
@@ -337,7 +337,7 @@ lisp_to_json_nonscalar_1 (Lisp_Object lisp,
                           const struct json_configuration *conf)
 {
   json_t *json;
-  ptrdiff_t count;
+  specpdl_ref count;
 
   if (VECTORP (lisp))
     {
@@ -584,7 +584,7 @@ any JSON false values.
 usage: (json-serialize OBJECT &rest ARGS)  */)
      (ptrdiff_t nargs, Lisp_Object *args)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
 #ifdef WINDOWSNT
   if (!json_initialized)
@@ -693,7 +693,7 @@ OBJECT.
 usage: (json-insert OBJECT &rest ARGS)  */)
      (ptrdiff_t nargs, Lisp_Object *args)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
 #ifdef WINDOWSNT
   if (!json_initialized)
@@ -950,7 +950,7 @@ represent a JSON false value.  It defaults to `:false'.
 usage: (json-parse-string STRING &rest ARGS) */)
   (ptrdiff_t nargs, Lisp_Object *args)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
 #ifdef WINDOWSNT
   if (!json_initialized)
@@ -1047,7 +1047,7 @@ represent a JSON false value.  It defaults to `:false'.
 usage: (json-parse-buffer &rest args) */)
      (ptrdiff_t nargs, Lisp_Object *args)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
 #ifdef WINDOWSNT
   if (!json_initialized)
diff --git a/src/keyboard.c b/src/keyboard.c
index 441c23e10c..6b66a71593 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -682,7 +682,7 @@ add_command_key (Lisp_Object key)
 Lisp_Object
 recursive_edit_1 (void)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object val;
 
   if (command_loop_level > 0)
@@ -776,7 +776,7 @@ throwing to \\='exit:
 This function is called by the editor initialization to begin editing.  */)
   (void)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object buffer;
 
   /* If we enter while input is blocked, don't lock up here.
@@ -939,7 +939,7 @@ static Lisp_Object
 cmd_error (Lisp_Object data)
 {
   Lisp_Object old_level, old_length;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object conditions;
   char macroerror[sizeof "After..kbd macro iterations: "
                  + INT_STRLEN_BOUND (EMACS_INT)];
@@ -1232,7 +1232,7 @@ DEFUN ("internal--track-mouse", Finternal_track_mouse, 
Sinternal_track_mouse,
        doc: /* Call BODYFUN with mouse movement events enabled.  */)
   (Lisp_Object bodyfun)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object val;
 
   record_unwind_protect (tracking_off, track_mouse);
@@ -1355,7 +1355,7 @@ command_loop_1 (void)
        {
          /* Bind inhibit-quit to t so that C-g gets read in
             rather than quitting back to the minibuffer.  */
-         ptrdiff_t count = SPECPDL_INDEX ();
+         specpdl_ref count = SPECPDL_INDEX ();
          specbind (Qinhibit_quit, Qt);
 
          sit_for (Vminibuffer_message_timeout, 0, 2);
@@ -1487,7 +1487,7 @@ command_loop_1 (void)
          /* Here for a command that isn't executed directly.  */
 
 #ifdef HAVE_WINDOW_SYSTEM
-            ptrdiff_t scount = SPECPDL_INDEX ();
+            specpdl_ref scount = SPECPDL_INDEX ();
 
             if (display_hourglass_p
                 && NILP (Vexecuting_kbd_macro))
@@ -1633,7 +1633,7 @@ command_loop_1 (void)
 Lisp_Object
 read_menu_command (void)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   /* We don't want to echo the keystrokes while navigating the
      menus.  */
@@ -1878,7 +1878,7 @@ safe_run_hook_funcall (ptrdiff_t nargs, Lisp_Object *args)
 void
 safe_run_hooks (Lisp_Object hook)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   specbind (Qinhibit_quit, Qt);
   run_hook_with_args (2, ((Lisp_Object []) {hook, hook}), 
safe_run_hook_funcall);
@@ -2211,7 +2211,7 @@ read_event_from_main_queue (struct timespec *end_time,
     return c;
 
   /* Actually read a character, waiting if necessary.  */
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   save_getcjmp (save_jump);
   record_unwind_protect_ptr (restore_getcjmp, save_jump);
   restore_getcjmp (local_getcjmp);
@@ -2413,7 +2413,6 @@ read_char (int commandflag, Lisp_Object map,
           bool *used_mouse_menu, struct timespec *end_time)
 {
   Lisp_Object c;
-  ptrdiff_t jmpcount;
   sys_jmp_buf local_getcjmp;
   sys_jmp_buf save_jump;
   Lisp_Object tem, save;
@@ -2655,7 +2654,7 @@ read_char (int commandflag, Lisp_Object map,
      around any call to sit_for or kbd_buffer_get_event;
      it *must not* be in effect when we call redisplay.  */
 
-  jmpcount = SPECPDL_INDEX ();
+  specpdl_ref jmpcount = SPECPDL_INDEX ();
   if (sys_setjmp (local_getcjmp))
     {
       /* Handle quits while reading the keyboard.  */
@@ -2738,7 +2737,7 @@ read_char (int commandflag, Lisp_Object map,
        {
          Lisp_Object tem0;
 
-         ptrdiff_t count = SPECPDL_INDEX ();
+         specpdl_ref count = SPECPDL_INDEX ();
          save_getcjmp (save_jump);
          record_unwind_protect_ptr (restore_getcjmp, save_jump);
          restore_getcjmp (local_getcjmp);
@@ -2815,7 +2814,7 @@ read_char (int commandflag, Lisp_Object map,
 
          timeout = min (timeout, MOST_POSITIVE_FIXNUM / delay_level * 4);
          timeout = delay_level * timeout / 4;
-         ptrdiff_t count1 = SPECPDL_INDEX ();
+         specpdl_ref count1 = SPECPDL_INDEX ();
          save_getcjmp (save_jump);
          record_unwind_protect_ptr (restore_getcjmp, save_jump);
          restore_getcjmp (local_getcjmp);
@@ -3098,7 +3097,7 @@ read_char (int commandflag, Lisp_Object map,
       Lisp_Object keys;
       ptrdiff_t key_count;
       ptrdiff_t command_key_start;
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
 
       /* Save the echo status.  */
       bool saved_immediate_echo = current_kboard->immediate_echo;
@@ -3223,7 +3222,7 @@ read_char (int commandflag, Lisp_Object map,
   /* Process the help character specially if enabled.  */
   if (!NILP (Vhelp_form) && help_char_p (c))
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
 
       help_form_saved_window_configs
        = Fcons (Fcurrent_window_configuration (Qnil),
@@ -4439,7 +4438,7 @@ timer_check_2 (Lisp_Object timers, Lisp_Object 
idle_timers)
        {
          if (NILP (AREF (chosen_timer, 0)))
            {
-             ptrdiff_t count = SPECPDL_INDEX ();
+             specpdl_ref count = SPECPDL_INDEX ();
              Lisp_Object old_deactivate_mark = Vdeactivate_mark;
 
              /* Mark the timer as triggered to prevent problems if the lisp
@@ -7852,7 +7851,7 @@ eval_dyn (Lisp_Object form)
 Lisp_Object
 menu_item_eval_property (Lisp_Object sexpr)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object val;
   specbind (Qinhibit_redisplay, Qt);
   val = internal_condition_case_1 (eval_dyn, sexpr, Qerror,
@@ -9519,7 +9518,7 @@ read_key_sequence (Lisp_Object *keybuf, Lisp_Object 
prompt,
                   bool dont_downcase_last, bool can_return_switch_frame,
                   bool fix_current_buffer, bool prevent_redisplay)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   /* How many keys there are in the current key sequence.  */
   int t;
@@ -10455,7 +10454,7 @@ read_key_sequence_vs (Lisp_Object prompt, Lisp_Object 
continue_echo,
                      Lisp_Object can_return_switch_frame,
                      Lisp_Object cmd_loop, bool allow_string)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   if (!NILP (prompt))
     CHECK_STRING (prompt);
@@ -10923,7 +10922,7 @@ Some operating systems cannot stop the Emacs process 
and resume it later.
 On such systems, Emacs starts a subshell instead of suspending.  */)
   (Lisp_Object stuffstring)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   int old_height, old_width;
   int width, height;
 
diff --git a/src/keymap.c b/src/keymap.c
index ed69b1c427..83c54e2630 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -1650,7 +1650,7 @@ OLP if non-nil indicates that we should obey 
`overriding-local-map' and
 like in the respective argument of `key-binding'.  */)
   (Lisp_Object olp, Lisp_Object position)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   Lisp_Object keymaps = list1 (current_global_map);
 
@@ -3031,7 +3031,7 @@ This is text showing the elements of vector matched 
against indices.
 DESCRIBER is the output function used; nil means use `princ'.  */)
   (Lisp_Object vector, Lisp_Object describer)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   if (NILP (describer))
     describer = intern ("princ");
   specbind (Qstandard_output, Fcurrent_buffer ());
@@ -3077,7 +3077,7 @@ the one in this keymap, we ignore this one.  */)
    Lisp_Object partial, Lisp_Object shadow, Lisp_Object entire_map,
    Lisp_Object mention_shadow)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   specbind (Qstandard_output, Fcurrent_buffer ());
   CHECK_VECTOR_OR_CHAR_TABLE (vector);
 
diff --git a/src/lisp.h b/src/lisp.h
index 10f45057d5..3ff9dccc4e 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3350,10 +3350,66 @@ union specbinding
     } bt;
   };
 
+/* Abstract reference to to a specpdl entry.  */
+typedef ptrdiff_t specpdl_ref;
+
+INLINE specpdl_ref
+specpdl_count_to_ref (ptrdiff_t count)
+{
+  return count;
+}
+
 INLINE ptrdiff_t
+specpdl_ref_to_count (specpdl_ref ref)
+{
+  return ref;
+}
+
+/* Whether two `specpdl_ref' refer to the same entry.  */
+INLINE bool
+specpdl_ref_eq (specpdl_ref a, specpdl_ref b)
+{
+  return a == b;
+}
+
+/* Whether `a' refers to an earlier entry than `b'.  */
+INLINE bool
+specpdl_ref_lt (specpdl_ref a, specpdl_ref b)
+{
+  return a < b;
+}
+
+INLINE bool
+specpdl_ref_valid_p (specpdl_ref ref)
+{
+  return specpdl_ref_to_count (ref) >= 0;
+}
+
+INLINE specpdl_ref
+make_invalid_specpdl_ref (void)
+{
+  return specpdl_count_to_ref (-1);
+}
+
+/* Return a reference that is `delta' steps more recent than `ref'.
+   `delta' may be negative or zero.  */
+INLINE specpdl_ref
+specpdl_ref_add (specpdl_ref ref, ptrdiff_t delta)
+{
+  return specpdl_count_to_ref (specpdl_ref_to_count (ref) + delta);
+}
+
+INLINE union specbinding *
+specpdl_ref_to_ptr (specpdl_ref ref)
+{
+  return specpdl + specpdl_ref_to_count (ref);
+}
+
+/* Return a reference to the most recent specpdl entry.  */
+INLINE specpdl_ref
 SPECPDL_INDEX (void)
 {
-  return specpdl_ptr - specpdl;
+  return specpdl_count_to_ref (specpdl_ptr - specpdl);
 }
 
 INLINE bool
@@ -3419,7 +3475,7 @@ struct handler
      but a few others are handled by storing their value here.  */
   sys_jmp_buf jmp;
   EMACS_INT f_lisp_eval_depth;
-  ptrdiff_t pdlcount;
+  specpdl_ref pdlcount;
   int poll_suppress_count;
   int interrupt_input_blocked;
 };
@@ -4178,7 +4234,7 @@ extern struct Lisp_Vector *allocate_pseudovector (int, 
int, int,
 extern bool gc_in_progress;
 extern Lisp_Object make_float (double);
 extern void display_malloc_warning (void);
-extern ptrdiff_t inhibit_garbage_collection (void);
+extern specpdl_ref inhibit_garbage_collection (void);
 extern Lisp_Object build_symbol_with_pos (Lisp_Object, Lisp_Object);
 extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);
 extern void free_cons (struct Lisp_Cons *);
@@ -4356,10 +4412,11 @@ extern void record_unwind_protect_void (void (*) 
(void));
 extern void record_unwind_protect_excursion (void);
 extern void record_unwind_protect_nothing (void);
 extern void record_unwind_protect_module (enum specbind_tag, void *);
-extern void clear_unwind_protect (ptrdiff_t);
-extern void set_unwind_protect (ptrdiff_t, void (*) (Lisp_Object), 
Lisp_Object);
-extern void set_unwind_protect_ptr (ptrdiff_t, void (*) (void *), void *);
-extern Lisp_Object unbind_to (ptrdiff_t, Lisp_Object);
+extern void clear_unwind_protect (specpdl_ref);
+extern void set_unwind_protect (specpdl_ref, void (*) (Lisp_Object),
+                               Lisp_Object);
+extern void set_unwind_protect_ptr (specpdl_ref, void (*) (void *), void *);
+extern Lisp_Object unbind_to (specpdl_ref, Lisp_Object);
 extern void rebind_for_thread_switch (void);
 extern void unbind_for_thread_switch (struct thread_state *);
 extern AVOID error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2);
@@ -4378,12 +4435,12 @@ extern Lisp_Object safe_call2 (Lisp_Object, 
Lisp_Object, Lisp_Object);
 extern void init_eval (void);
 extern void syms_of_eval (void);
 extern void prog_ignore (Lisp_Object);
-extern ptrdiff_t record_in_backtrace (Lisp_Object, Lisp_Object *, ptrdiff_t);
+extern specpdl_ref record_in_backtrace (Lisp_Object, Lisp_Object *, ptrdiff_t);
 extern void mark_specpdl (union specbinding *first, union specbinding *ptr);
 extern void get_backtrace (Lisp_Object array);
 Lisp_Object backtrace_top_function (void);
 extern bool let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol);
-void do_debug_on_call (Lisp_Object code, ptrdiff_t count);
+void do_debug_on_call (Lisp_Object code, specpdl_ref count);
 Lisp_Object funcall_general (Lisp_Object fun,
                             ptrdiff_t numargs, Lisp_Object *args);
 
@@ -5054,7 +5111,7 @@ extern void *record_xmalloc (size_t)
 
 #define USE_SAFE_ALLOCA                        \
   ptrdiff_t sa_avail = MAX_ALLOCA;     \
-  ptrdiff_t sa_count = SPECPDL_INDEX ()
+  specpdl_ref sa_count = SPECPDL_INDEX ()
 
 #define AVAIL_ALLOCA(size) (sa_avail -= (size), alloca (size))
 
@@ -5092,9 +5149,9 @@ extern void *record_xmalloc (size_t)
 #define SAFE_FREE() safe_free (sa_count)
 
 INLINE void
-safe_free (ptrdiff_t sa_count)
+safe_free (specpdl_ref sa_count)
 {
-  while (specpdl_ptr != specpdl + sa_count)
+  while (specpdl_ptr != specpdl_ref_to_ptr (sa_count))
     {
       specpdl_ptr--;
       if (specpdl_ptr->kind == SPECPDL_UNWIND_PTR)
@@ -5120,9 +5177,9 @@ safe_free (ptrdiff_t sa_count)
   safe_free_unbind_to (count, sa_count, val)
 
 INLINE Lisp_Object
-safe_free_unbind_to (ptrdiff_t count, ptrdiff_t sa_count, Lisp_Object val)
+safe_free_unbind_to (specpdl_ref count, specpdl_ref sa_count, Lisp_Object val)
 {
-  eassert (count <= sa_count);
+  eassert (!specpdl_ref_lt (sa_count, count));
   return unbind_to (count, val);
 }
 
diff --git a/src/lread.c b/src/lread.c
index 713c03243c..502db1a8de 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1219,8 +1219,8 @@ Return t if the file exists and loads successfully.  */)
 {
   FILE *stream UNINIT;
   int fd;
-  int fd_index UNINIT;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref fd_index UNINIT;
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object found, efound, hist_file_name;
   /* True means we printed the ".el is newer" message.  */
   bool newer = 0;
@@ -1628,7 +1628,7 @@ save_match_data_load (Lisp_Object file, Lisp_Object 
noerror,
                      Lisp_Object nomessage, Lisp_Object nosuffix,
                      Lisp_Object must_suffix)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   record_unwind_save_match_data ();
   Lisp_Object result = Fload (file, noerror, nomessage, nosuffix, must_suffix);
   return unbind_to (count, result);
@@ -2164,7 +2164,7 @@ readevalloop (Lisp_Object readcharfun,
 {
   int c;
   Lisp_Object val;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   struct buffer *b = 0;
   bool continue_reading_p;
   Lisp_Object lex_bound;
@@ -2220,7 +2220,7 @@ readevalloop (Lisp_Object readcharfun,
   continue_reading_p = 1;
   while (continue_reading_p)
     {
-      ptrdiff_t count1 = SPECPDL_INDEX ();
+      specpdl_ref count1 = SPECPDL_INDEX ();
 
       if (b != 0 && !BUFFER_LIVE_P (b))
        error ("Reading from killed buffer");
@@ -2375,7 +2375,7 @@ will be evaluated without lexical binding.
 This function preserves the position of point.  */)
   (Lisp_Object buffer, Lisp_Object printflag, Lisp_Object filename, 
Lisp_Object unibyte, Lisp_Object do_allow_print)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object tem, buf;
 
   if (NILP (buffer))
@@ -2420,7 +2420,7 @@ This function does not move point.  */)
   (Lisp_Object start, Lisp_Object end, Lisp_Object printflag, Lisp_Object 
read_function)
 {
   /* FIXME: Do the eval-sexp-add-defvars dance!  */
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object tem, cbuf;
 
   cbuf = Fcurrent_buffer ();
@@ -2595,7 +2595,7 @@ read0 (Lisp_Object readcharfun, bool locate_syms)
 
 static char *
 grow_read_buffer (char *buf, ptrdiff_t offset,
-                 char **buf_addr, ptrdiff_t *buf_size, ptrdiff_t count)
+                 char **buf_addr, ptrdiff_t *buf_size, specpdl_ref count)
 {
   char *p = xpalloc (*buf_addr, buf_size, MAX_MULTIBYTE_LENGTH, -1, 1);
   if (!*buf_addr)
@@ -2948,7 +2948,7 @@ read_integer (Lisp_Object readcharfun, int radix,
   char *p = read_buffer;
   char *heapbuf = NULL;
   int valid = -1; /* 1 if valid, 0 if not, -1 if incomplete.  */
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   int c = READCHAR;
   if (c == '-' || c == '+')
@@ -3608,7 +3608,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list, bool locate_syms)
 
     case '"':
       {
-       ptrdiff_t count = SPECPDL_INDEX ();
+       specpdl_ref count = SPECPDL_INDEX ();
        char *read_buffer = stackbuf;
        ptrdiff_t read_buffer_size = sizeof stackbuf;
        char *heapbuf = NULL;
@@ -3752,7 +3752,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list, bool locate_syms)
 
     read_symbol:
       {
-       ptrdiff_t count = SPECPDL_INDEX ();
+       specpdl_ref count = SPECPDL_INDEX ();
        char *read_buffer = stackbuf;
        ptrdiff_t read_buffer_size = sizeof stackbuf;
        char *heapbuf = NULL;
diff --git a/src/macros.c b/src/macros.c
index 3d00c28838..0447a367fd 100644
--- a/src/macros.c
+++ b/src/macros.c
@@ -287,7 +287,7 @@ buffer before the macro is executed.  */)
 {
   Lisp_Object final;
   Lisp_Object tem;
-  ptrdiff_t pdlcount = SPECPDL_INDEX ();
+  specpdl_ref pdlcount = SPECPDL_INDEX ();
   EMACS_INT repeat = 1;
   EMACS_INT success_count = 0;
 
diff --git a/src/menu.c b/src/menu.c
index 449f0b44ae..ad4e3abe9f 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -1121,7 +1121,7 @@ x_popup_menu_1 (Lisp_Object position, Lisp_Object menu)
   struct frame *f = NULL;
   Lisp_Object x, y, window;
   int menuflags = 0;
-  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+  specpdl_ref specpdl_count = SPECPDL_INDEX ();
 
   if (NILP (position))
     /* This is an obsolete call, which wants us to precompute the
diff --git a/src/minibuf.c b/src/minibuf.c
index d0e58b61f2..bab8830646 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -578,7 +578,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, 
Lisp_Object prompt,
              bool allow_props, bool inherit_input_method)
 {
   Lisp_Object val;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object mini_frame, ambient_dir, minibuffer, input_method;
   Lisp_Object calling_frame = selected_frame;
   Lisp_Object calling_window = selected_window;
@@ -833,7 +833,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, 
Lisp_Object prompt,
 
   /* Erase the buffer.  */
   {
-    ptrdiff_t count1 = SPECPDL_INDEX ();
+    specpdl_ref count1 = SPECPDL_INDEX ();
     specbind (Qinhibit_read_only, Qt);
     specbind (Qinhibit_modification_hooks, Qt);
     Ferase_buffer ();
@@ -991,7 +991,7 @@ nth_minibuffer (EMACS_INT depth)
 static void
 set_minibuffer_mode (Lisp_Object buf, EMACS_INT depth)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   record_unwind_current_buffer ();
   Fset_buffer (buf);
@@ -1155,7 +1155,7 @@ read_minibuf_unwind (void)
 
   /* Erase the minibuffer we were using at this level.  */
   {
-    ptrdiff_t count = SPECPDL_INDEX ();
+    specpdl_ref count = SPECPDL_INDEX ();
     /* Prevent error in erase-buffer.  */
     specbind (Qinhibit_read_only, Qt);
     specbind (Qinhibit_modification_hooks, Qt);
@@ -1384,7 +1384,7 @@ Fifth arg INHERIT-INPUT-METHOD, if non-nil, means the 
minibuffer inherits
   (Lisp_Object prompt, Lisp_Object initial_input, Lisp_Object history, 
Lisp_Object default_value, Lisp_Object inherit_input_method)
 {
   Lisp_Object val;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   /* Just in case we're in a recursive minibuffer, make it clear that the
      previous minibuffer's completion table does not apply to the new
@@ -1483,7 +1483,7 @@ function, instead of the usual behavior.  */)
   Lisp_Object result;
   char *s;
   ptrdiff_t len;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   if (BUFFERP (def))
     def = BVAR (XBUFFER (def), name);
diff --git a/src/nsfns.m b/src/nsfns.m
index 467e56ece4..1900616b9d 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -1106,7 +1106,7 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
   Lisp_Object name;
   int minibuffer_only = 0;
   long window_prompting = 0;
-  ptrdiff_t count = specpdl_ptr - specpdl;
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object display;
   struct ns_display_info *dpyinfo = NULL;
   Lisp_Object parent, parent_frame;
@@ -2823,7 +2823,7 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
      (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object 
timeout, Lisp_Object dx, Lisp_Object dy)
 {
   int root_x, root_y;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   struct frame *f;
   char *str;
   NSSize size;
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 5df391bcbe..81d7cd2da1 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -164,7 +164,7 @@ ns_update_menubar (struct frame *f, bool deep_p)
 
       struct buffer *prev = current_buffer;
       Lisp_Object buffer;
-      ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+      specpdl_ref specpdl_count = SPECPDL_INDEX ();
       int previous_menu_items_used = f->menu_bar_items_used;
       Lisp_Object *previous_items
        = alloca (previous_menu_items_used * sizeof *previous_items);
@@ -854,7 +854,7 @@ ns_menu_show (struct frame *f, int x, int y, int menuflags,
   EmacsMenu *pmenu;
   NSPoint p;
   Lisp_Object tem;
-  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+  specpdl_ref specpdl_count = SPECPDL_INDEX ();
   widget_value *wv, *first_wv = 0;
   bool keymaps = (menuflags & MENU_KEYMAPS);
 
@@ -1552,7 +1552,7 @@ ns_popup_dialog (struct frame *f, Lisp_Object header, 
Lisp_Object contents)
                                            isQuestion: isQ];
 
   {
-    ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+    specpdl_ref specpdl_count = SPECPDL_INDEX ();
 
     record_unwind_protect_ptr (pop_down_menu, dialog);
     popup_activated_flag = 1;
diff --git a/src/pdumper.c b/src/pdumper.c
index f4e8e4af28..f14239f863 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -4046,7 +4046,7 @@ types.  */)
     }
   while (number_finalizers_run);
 
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   /* Bind `command-line-processed' to nil before dumping,
      so that the dumped Emacs will process its command line
diff --git a/src/pgtkfns.c b/src/pgtkfns.c
index baadc41308..1a6fd941de 100644
--- a/src/pgtkfns.c
+++ b/src/pgtkfns.c
@@ -1244,7 +1244,7 @@ This function is an internal primitive--use `make-frame' 
instead.  */ )
   bool minibuffer_only = false;
   bool undecorated = false, override_redirect = false;
   long window_prompting = 0;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object display;
   struct pgtk_display_info *dpyinfo = NULL;
   Lisp_Object parent, parent_frame;
@@ -2722,7 +2722,7 @@ x_create_tip_frame (struct pgtk_display_info *dpyinfo, 
Lisp_Object parms, struct
   struct frame *f;
   Lisp_Object frame;
   Lisp_Object name;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   bool face_change_before = face_change;
 
   if (!dpyinfo->terminal->name)
@@ -3090,10 +3090,9 @@ x_hide_tip (bool delete)
     return Qnil;
   else
     {
-      ptrdiff_t count;
       Lisp_Object was_open = Qnil;
 
-      count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       specbind (Qinhibit_redisplay, Qt);
       specbind (Qinhibit_quit, Qt);
 
@@ -3185,8 +3184,7 @@ Text larger than the specified size is clipped.  */)
   struct text_pos pos;
   int width, height;
   int old_windows_or_buffers_changed = windows_or_buffers_changed;
-  ptrdiff_t count = SPECPDL_INDEX ();
-  ptrdiff_t count_1;
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object window, size, tip_buf;
   AUTO_STRING (tip, " *tip*");
 
@@ -3381,7 +3379,7 @@ Text larger than the specified size is clipped.  */)
 
   /* Insert STRING into root window's buffer and fit the frame to the
      buffer.  */
-  count_1 = SPECPDL_INDEX ();
+  specpdl_ref count_1 = SPECPDL_INDEX ();
   old_buffer = current_buffer;
   set_buffer_internal_1 (XBUFFER (w->contents));
   bset_truncate_lines (current_buffer, Qnil);
@@ -3698,7 +3696,6 @@ visible.  */)
   (Lisp_Object frames)
 {
   Lisp_Object rest, tmp;
-  int count;
 
   if (!CONSP (frames))
     frames = list1 (frames);
@@ -3717,7 +3714,7 @@ visible.  */)
   frames = Fnreverse (tmp);
 
   /* Make sure the current matrices are up-to-date.  */
-  count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   specbind (Qredisplay_dont_pause, Qt);
   redisplay_preserve_echo_area (32);
   unbind_to (count, Qnil);
@@ -3755,7 +3752,7 @@ value of DIR as in previous invocations; this is standard 
MS Windows behavior.
   char *fn;
   Lisp_Object file = Qnil;
   Lisp_Object decoded_file;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   char *cdef_file;
 
   check_window_system (f);
@@ -3823,7 +3820,7 @@ nil, it defaults to the selected frame. */)
   Lisp_Object font;
   Lisp_Object font_param;
   char *default_name = NULL;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   if (popup_activated ())
     error ("Trying to use a menu from within a menu-entry");
diff --git a/src/pgtkmenu.c b/src/pgtkmenu.c
index 18aaf57302..7a3bfea451 100644
--- a/src/pgtkmenu.c
+++ b/src/pgtkmenu.c
@@ -263,7 +263,7 @@ set_frame_menubar (struct frame *f, bool deep_p)
     {
       struct buffer *prev = current_buffer;
       Lisp_Object buffer;
-      ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+      specpdl_ref specpdl_count = SPECPDL_INDEX ();
       int previous_menu_items_used = f->menu_bar_items_used;
       Lisp_Object *previous_items
        = alloca (previous_menu_items_used * sizeof *previous_items);
@@ -542,7 +542,7 @@ create_and_show_popup_menu (struct frame *f, widget_value * 
first_wv,
                            int x, int y, bool for_click)
 {
   GtkWidget *menu;
-  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+  specpdl_ref specpdl_count = SPECPDL_INDEX ();
 
   eassert (FRAME_PGTK_P (f));
 
@@ -609,7 +609,7 @@ pgtk_menu_show (struct frame *f, int x, int y, int 
menuflags,
     = alloca (menu_items_used * sizeof *subprefix_stack);
   int submenu_depth = 0;
 
-  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+  specpdl_ref specpdl_count = SPECPDL_INDEX ();
 
   eassert (FRAME_PGTK_P (f));
 
@@ -886,7 +886,7 @@ create_and_show_dialog (struct frame *f, widget_value 
*first_wv)
 
   if (menu)
     {
-      ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+      specpdl_ref specpdl_count = SPECPDL_INDEX ();
       record_unwind_protect_ptr (pop_down_menu, menu);
 
       /* Display the menu.  */
@@ -918,7 +918,7 @@ pgtk_dialog_show (struct frame *f, Lisp_Object title,
   /* Whether we've seen the boundary between left-hand elts and right-hand.  */
   bool boundary_seen = false;
 
-  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+  specpdl_ref specpdl_count = SPECPDL_INDEX ();
 
   eassert (FRAME_PGTK_P (f));
 
@@ -1071,7 +1071,7 @@ pgtk_popup_dialog (struct frame *f, Lisp_Object header, 
Lisp_Object contents)
   Lisp_Object title;
   const char *error_name;
   Lisp_Object selection;
-  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+  specpdl_ref specpdl_count = SPECPDL_INDEX ();
 
   check_window_system (f);
 
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index 43c475f2a7..65408801cf 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -7115,7 +7115,7 @@ pgtk_cr_export_frames (Lisp_Object frames, 
cairo_surface_type_t surface_type)
   int width, height;
   void (*surface_set_size_func) (cairo_surface_t *, double, double) = NULL;
   Lisp_Object acc = Qnil;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   specbind (Qredisplay_dont_pause, Qt);
   redisplay_preserve_echo_area (31);
diff --git a/src/print.c b/src/print.c
index 04a271ce45..8cce8a1ad8 100644
--- a/src/print.c
+++ b/src/print.c
@@ -101,7 +101,7 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1;
    struct buffer *old = current_buffer;                                        
\
    ptrdiff_t old_point = -1, start_point = -1;                         \
    ptrdiff_t old_point_byte = -1, start_point_byte = -1;               \
-   ptrdiff_t specpdl_count = SPECPDL_INDEX ();                         \
+   specpdl_ref specpdl_count = SPECPDL_INDEX ();                       \
    bool free_print_buffer = 0;                                         \
    bool multibyte                                                      \
      = !NILP (BVAR (current_buffer, enable_multibyte_characters));     \
@@ -556,7 +556,7 @@ write_string (const char *data, Lisp_Object printcharfun)
 void
 temp_output_buffer_setup (const char *bufname)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   register struct buffer *old = current_buffer;
   register Lisp_Object buf;
 
@@ -669,7 +669,7 @@ a list, a buffer, a window, a frame, etc.
 A printed representation of an object is text which describes that object.  */)
   (Lisp_Object object, Lisp_Object noescape)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   specbind (Qinhibit_modification_hooks, Qt);
 
@@ -1612,7 +1612,7 @@ print_vectorlike (Lisp_Object obj, Lisp_Object 
printcharfun, bool escapeflag,
   if (!NILP (Vprint_unreadable_function)
       && FUNCTIONP (Vprint_unreadable_function))
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       /* Bind `print-unreadable-function' to nil to avoid accidental
         infinite recursion in the function called.  */
       Lisp_Object func = Vprint_unreadable_function;
diff --git a/src/process.c b/src/process.c
index e912595393..94cc880097 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1752,7 +1752,7 @@ usage: (make-process &rest ARGS)  */)
 {
   Lisp_Object buffer, name, command, program, proc, contact, current_dir, tem;
   Lisp_Object xstderr, stderrproc;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   if (nargs == 0)
     return Qnil;
@@ -2173,7 +2173,7 @@ create_process (Lisp_Object process, char **new_argv, 
Lisp_Object current_dir)
       && !EQ (p->filter, Qt))
     add_process_read_fd (inchannel);
 
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   /* This may signal an error.  */
   setup_process_coding_systems (process);
@@ -2340,7 +2340,6 @@ usage:  (make-pipe-process &rest ARGS)  */)
   struct Lisp_Process *p;
   Lisp_Object name, buffer;
   Lisp_Object tem;
-  ptrdiff_t specpdl_count;
   int inchannel, outchannel;
 
   if (nargs == 0)
@@ -2351,7 +2350,7 @@ usage:  (make-pipe-process &rest ARGS)  */)
   name = Fplist_get (contact, QCname);
   CHECK_STRING (name);
   proc = make_process (name);
-  specpdl_count = SPECPDL_INDEX ();
+  specpdl_ref specpdl_count = SPECPDL_INDEX ();
   record_unwind_protect (remove_process, proc);
   p = XPROCESS (proc);
 
@@ -2471,7 +2470,7 @@ usage:  (make-pipe-process &rest ARGS)  */)
   eassert (p->decoding_carryover == 0);
   pset_encoding_buf (p, empty_unibyte_string);
 
-  specpdl_ptr = specpdl + specpdl_count;
+  specpdl_ptr = specpdl_ref_to_ptr (specpdl_count);
 
   return proc;
 }
@@ -3079,7 +3078,6 @@ usage:  (make-serial-process &rest ARGS)  */)
   struct Lisp_Process *p;
   Lisp_Object name, buffer;
   Lisp_Object tem, val;
-  ptrdiff_t specpdl_count;
 
   if (nargs == 0)
     return Qnil;
@@ -3101,7 +3099,7 @@ usage:  (make-serial-process &rest ARGS)  */)
     name = port;
   CHECK_STRING (name);
   proc = make_process (name);
-  specpdl_count = SPECPDL_INDEX ();
+  specpdl_ref specpdl_count = SPECPDL_INDEX ();
   record_unwind_protect (remove_process, proc);
   p = XPROCESS (proc);
 
@@ -3179,7 +3177,7 @@ usage:  (make-serial-process &rest ARGS)  */)
 
   Fserial_process_configure (nargs, args);
 
-  specpdl_ptr = specpdl + specpdl_count;
+  specpdl_ptr = specpdl_ref_to_ptr (specpdl_count);
 
   return proc;
 }
@@ -3341,9 +3339,9 @@ connect_network_socket (Lisp_Object proc, Lisp_Object 
addrinfos,
   s = -1;
 
   struct sockaddr *sa = NULL;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   record_unwind_protect_nothing ();
-  ptrdiff_t count1 = SPECPDL_INDEX ();
+  specpdl_ref count1 = SPECPDL_INDEX ();
 
   while (!NILP (addrinfos))
     {
@@ -3528,7 +3526,7 @@ connect_network_socket (Lisp_Object proc, Lisp_Object 
addrinfos,
 #endif /* !WINDOWSNT */
 
       /* Discard the unwind protect closing S.  */
-      specpdl_ptr = specpdl + count1;
+      specpdl_ptr = specpdl_ref_to_ptr (count1);
       emacs_close (s);
       s = -1;
       if (0 <= socket_to_use)
@@ -3621,7 +3619,7 @@ connect_network_socket (Lisp_Object proc, Lisp_Object 
addrinfos,
   p->outfd = outch;
 
   /* Discard the unwind protect for closing S, if any.  */
-  specpdl_ptr = specpdl + count1;
+  specpdl_ptr = specpdl_ref_to_ptr (count1);
 
   if (p->is_server && p->socktype != SOCK_DGRAM)
     pset_status (p, Qlisten);
@@ -3879,7 +3877,7 @@ usage: (make-network-process &rest ARGS)  */)
 #ifdef HAVE_GETADDRINFO_A
   struct gaicb *dns_request = NULL;
 #endif
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   if (nargs == 0)
     return Qnil;
@@ -4208,7 +4206,7 @@ usage: (make-network-process &rest ARGS)  */)
   if (! postpone_connection)
     connect_network_socket (proc, addrinfos, use_external_socket_p);
 
-  specpdl_ptr = specpdl + count;
+  specpdl_ptr = specpdl_ref_to_ptr (count);
   return proc;
 }
 
@@ -4380,7 +4378,6 @@ network_interface_info (Lisp_Object ifname)
   Lisp_Object elt;
   int s;
   bool any = false;
-  ptrdiff_t count;
 #if (! (defined SIOCGIFHWADDR && defined HAVE_STRUCT_IFREQ_IFR_HWADDR) \
      && defined HAVE_GETIFADDRS && defined LLADDR)
   struct ifaddrs *ifap;
@@ -4395,7 +4392,7 @@ network_interface_info (Lisp_Object ifname)
   s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
   if (s < 0)
     return Qnil;
-  count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   record_unwind_protect_int (close_file_unwind, s);
 
   elt = Qnil;
@@ -4839,7 +4836,6 @@ server_accept_connection (Lisp_Object server, int channel)
   int s;
   union u_sockaddr saddr;
   socklen_t len = sizeof saddr;
-  ptrdiff_t count;
 
   s = accept4 (channel, &saddr.sa, &len, SOCK_CLOEXEC);
 
@@ -4861,7 +4857,7 @@ server_accept_connection (Lisp_Object server, int channel)
       return;
     }
 
-  count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   record_unwind_protect_int (close_file_unwind, s);
 
   connect_counter++;
@@ -4980,7 +4976,7 @@ server_accept_connection (Lisp_Object server, int channel)
   eassert (p->pid == 0);
 
   /* Discard the unwind protect for closing S.  */
-  specpdl_ptr = specpdl + count;
+  specpdl_ptr = specpdl_ref_to_ptr (count);
 
   p->open_fd[SUBPROCESS_STDIN] = s;
   p->infd  = s;
@@ -5177,7 +5173,7 @@ wait_reading_process_output (intmax_t time_limit, int 
nsecs, int read_kbd,
 #if defined HAVE_GETADDRINFO_A || defined HAVE_GNUTLS
   bool retry_for_async;
 #endif
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   /* Close to the current time if known, an invalid timespec otherwise.  */
   struct timespec now = invalid_timespec ();
@@ -6027,7 +6023,7 @@ read_process_output (Lisp_Object proc, int channel)
   struct coding_system *coding = proc_decode_coding_system[channel];
   int carryover = p->decoding_carryover;
   ptrdiff_t readmax = clip_to_bounds (1, read_process_output_max, PTRDIFF_MAX);
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object odeactivate;
   char *chars;
 
@@ -7438,7 +7434,7 @@ exec_sentinel (Lisp_Object proc, Lisp_Object reason)
 {
   Lisp_Object sentinel, odeactivate;
   struct Lisp_Process *p = XPROCESS (proc);
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   bool outer_running_asynch_code = running_asynch_code;
   int waiting = waiting_for_user_input_p;
 
diff --git a/src/regex-emacs.c b/src/regex-emacs.c
index 7c172fe63a..700a6c357d 100644
--- a/src/regex-emacs.c
+++ b/src/regex-emacs.c
@@ -3963,7 +3963,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
 
   INIT_FAIL_STACK ();
 
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   /* Prevent shrinking and relocation of buffer text if GC happens
      while we are inside this function.  The calls to
diff --git a/src/search.c b/src/search.c
index 80541921de..816a757c18 100644
--- a/src/search.c
+++ b/src/search.c
@@ -310,7 +310,7 @@ looking_at_1 (Lisp_Object string, bool posix, bool 
modify_data)
       s2 = 0;
     }
 
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   freeze_buffer_relocation ();
   freeze_pattern (cache_entry);
   re_match_object = Qnil;
@@ -568,7 +568,7 @@ fast_looking_at (Lisp_Object regexp, ptrdiff_t pos, 
ptrdiff_t pos_byte,
 
   struct regexp_cache *cache_entry =
     compile_pattern (regexp, 0, Qnil, 0, multibyte);
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   freeze_buffer_relocation ();
   freeze_pattern (cache_entry);
   re_match_object = STRINGP (string) ? string : Qnil;
@@ -1198,7 +1198,7 @@ search_buffer_re (Lisp_Object string, ptrdiff_t pos, 
ptrdiff_t pos_byte,
       s2 = 0;
     }
 
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   freeze_buffer_relocation ();
   freeze_pattern (cache_entry);
 
diff --git a/src/sound.c b/src/sound.c
index 9681a136e4..93c84a03b1 100644
--- a/src/sound.c
+++ b/src/sound.c
@@ -1359,7 +1359,7 @@ Internal use only, use `play-sound' instead.  */)
   (Lisp_Object sound)
 {
   Lisp_Object attrs[SOUND_ATTR_SENTINEL];
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
 #ifdef WINDOWSNT
   unsigned long ui_volume_tmp = UINT_MAX;
diff --git a/src/sysdep.c b/src/sysdep.c
index c772aff6a0..95f77febcb 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -3365,7 +3365,6 @@ system_process_attributes (Lisp_Object pid)
   double pcpu, pmem;
   Lisp_Object attrs = Qnil;
   Lisp_Object decoded_cmd;
-  ptrdiff_t count;
 
   CHECK_NUMBER (pid);
   CONS_TO_INTEGER (pid, pid_t, proc_id);
@@ -3390,7 +3389,7 @@ system_process_attributes (Lisp_Object pid)
   if (gr)
     attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
 
-  count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   strcpy (fn, procfn);
   procfn_end = fn + strlen (fn);
   strcpy (procfn_end, "/stat");
@@ -3512,7 +3511,7 @@ system_process_attributes (Lisp_Object pid)
       do
        {
          cmdline = xpalloc (cmdline, &cmdline_size, 2, STRING_BYTES_BOUND, 1);
-         set_unwind_protect_ptr (count + 1, xfree, cmdline);
+         set_unwind_protect_ptr (specpdl_ref_add (count, 1), xfree, cmdline);
 
          /* Leave room even if every byte needs escaping below.  */
          readsize = (cmdline_size >> 1) - nread;
@@ -3546,7 +3545,7 @@ system_process_attributes (Lisp_Object pid)
          nread = cmdsize + 2;
          cmdline_size = nread + 1;
          q = cmdline = xrealloc (cmdline, cmdline_size);
-         set_unwind_protect_ptr (count + 1, xfree, cmdline);
+         set_unwind_protect_ptr (specpdl_ref_add (count, 1), xfree, cmdline);
          sprintf (cmdline, "[%.*s]", cmdsize, cmd);
        }
       /* Command line is encoded in locale-coding-system; decode it.  */
@@ -3595,7 +3594,6 @@ system_process_attributes (Lisp_Object pid)
   gid_t gid;
   Lisp_Object attrs = Qnil;
   Lisp_Object decoded_cmd;
-  ptrdiff_t count;
 
   CHECK_NUMBER (pid);
   CONS_TO_INTEGER (pid, pid_t, proc_id);
@@ -3620,7 +3618,7 @@ system_process_attributes (Lisp_Object pid)
   if (gr)
     attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
 
-  count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   strcpy (fn, procfn);
   procfn_end = fn + strlen (fn);
   strcpy (procfn_end, "/psinfo");
diff --git a/src/term.c b/src/term.c
index ddf0e8e2f2..bad1127c93 100644
--- a/src/term.c
+++ b/src/term.c
@@ -3504,7 +3504,7 @@ tty_menu_show (struct frame *f, int x, int y, int 
menuflags,
   int dispwidth, dispheight;
   int i, j, lines, maxlines;
   int maxwidth;
-  ptrdiff_t specpdl_count;
+  specpdl_ref specpdl_count;
 
   eassert (FRAME_TERMCAP_P (f));
 
diff --git a/src/textprop.c b/src/textprop.c
index 2d1e34d586..c6c9e102e3 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -792,7 +792,7 @@ The property values are compared with `eq'.  */)
   else
     {
       Lisp_Object initial_value, value;
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
 
       if (! NILP (object))
        CHECK_BUFFER (object);
@@ -879,7 +879,7 @@ first valid position in OBJECT.  */)
     }
   else
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
 
       if (! NILP (object))
        CHECK_BUFFER (object);
@@ -1164,7 +1164,7 @@ add_text_properties_1 (Lisp_Object start, Lisp_Object end,
      buffers is slow and often unnecessary.  */
   if (BUFFERP (object) && XBUFFER (object) != current_buffer)
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       record_unwind_current_buffer ();
       set_buffer_internal (XBUFFER (object));
       return unbind_to (count, add_text_properties_1 (start, end, properties,
@@ -1379,7 +1379,7 @@ set_text_properties (Lisp_Object start, Lisp_Object end, 
Lisp_Object properties,
      buffers is slow and often unnecessary.  */
   if (BUFFERP (object) && XBUFFER (object) != current_buffer)
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       record_unwind_current_buffer ();
       set_buffer_internal (XBUFFER (object));
       return unbind_to (count,
@@ -1462,7 +1462,7 @@ set_text_properties_1 (Lisp_Object start, Lisp_Object end,
      buffers is slow and often unnecessary.  */
   if (BUFFERP (object) && XBUFFER (object) != current_buffer)
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       record_unwind_current_buffer ();
       set_buffer_internal (XBUFFER (object));
 
@@ -1558,7 +1558,7 @@ Use `set-text-properties' if you want to remove all text 
properties.  */)
      buffers is slow and often unnecessary.  */
   if (BUFFERP (object) && XBUFFER (object) != current_buffer)
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       record_unwind_current_buffer ();
       set_buffer_internal (XBUFFER (object));
       return unbind_to (count,
@@ -1683,7 +1683,7 @@ Return t if any property was actually removed, nil 
otherwise.  */)
      buffers is slow and often unnecessary.  */
   if (BUFFERP (object) && XBUFFER (object) != current_buffer)
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       record_unwind_current_buffer ();
       set_buffer_internal (XBUFFER (object));
       return unbind_to (count,
diff --git a/src/thread.c b/src/thread.c
index bfcac91982..8a6a2de18b 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -329,7 +329,7 @@ Note that calls to `mutex-lock' and `mutex-unlock' must be 
paired.  */)
   (Lisp_Object mutex)
 {
   struct Lisp_Mutex *lmutex;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   CHECK_MUTEX (mutex);
   lmutex = XMUTEX (mutex);
@@ -709,7 +709,7 @@ DEFUN ("thread-yield", Fthread_yield, Sthread_yield, 0, 0, 
0,
 static Lisp_Object
 invoke_thread_function (void)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   current_thread->result = Ffuncall (1, &current_thread->function);
   return unbind_to (count, Qnil);
diff --git a/src/undo.c b/src/undo.c
index 5d705945c4..36664d1642 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -295,7 +295,7 @@ truncate_undo_list (struct buffer *b)
 
   /* Make sure that calling undo-outer-limit-function
      won't cause another GC.  */
-  ptrdiff_t count = inhibit_garbage_collection ();
+  specpdl_ref count = inhibit_garbage_collection ();
 
   /* Make the buffer current to get its local values of variables such
      as undo_limit.  Also so that Vundo_outer_limit_function can
diff --git a/src/w32fns.c b/src/w32fns.c
index 009855602e..a880136d0a 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -5771,7 +5771,7 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
   Lisp_Object name;
   bool minibuffer_only = false;
   long window_prompting = 0;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object display;
   struct w32_display_info *dpyinfo = NULL;
   Lisp_Object parent, parent_frame;
@@ -6946,7 +6946,7 @@ w32_create_tip_frame (struct w32_display_info *dpyinfo, 
Lisp_Object parms)
   struct frame *f;
   Lisp_Object frame;
   Lisp_Object name;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   struct kboard *kb;
   bool face_change_before = face_change;
 
@@ -7273,10 +7273,9 @@ w32_hide_tip (bool delete)
     return Qnil;
   else
     {
-      ptrdiff_t count;
       Lisp_Object was_open = Qnil;
 
-      count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       specbind (Qinhibit_redisplay, Qt);
       specbind (Qinhibit_quit, Qt);
 
@@ -7317,8 +7316,7 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
   struct text_pos pos;
   int width, height;
   int old_windows_or_buffers_changed = windows_or_buffers_changed;
-  ptrdiff_t count = SPECPDL_INDEX ();
-  ptrdiff_t count_1;
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object window, size, tip_buf;
   AUTO_STRING (tip, " *tip*");
 
@@ -7517,7 +7515,7 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
 
   /* Insert STRING into the root window's buffer and fit the frame to
      the buffer.  */
-  count_1 = SPECPDL_INDEX ();
+  specpdl_ref count_1 = SPECPDL_INDEX ();
   old_buffer = current_buffer;
   set_buffer_internal_1 (XBUFFER (w->contents));
   bset_truncate_lines (current_buffer, Qnil);
@@ -7952,7 +7950,7 @@ DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 
2, 5, 0,
 #endif /* !NTGUI_UNICODE */
 
     {
-      int count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
 
       w32_dialog_in_progress (Qt);
 
diff --git a/src/w32font.c b/src/w32font.c
index c4a89446b9..1f93f6d5e0 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -2660,7 +2660,7 @@ in the font selection dialog. */)
   ReleaseDC (FRAME_W32_WINDOW (f), hdc);
 
   {
-    int count = SPECPDL_INDEX ();
+    specpdl_ref count = SPECPDL_INDEX ();
     Lisp_Object value = Qnil;
 
     w32_dialog_in_progress (Qt);
diff --git a/src/w32menu.c b/src/w32menu.c
index 57f6762c2f..5cd6c3310e 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -285,7 +285,7 @@ set_frame_menubar (struct frame *f, bool deep_p)
 
       struct buffer *prev = current_buffer;
       Lisp_Object buffer;
-      ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+      specpdl_ref specpdl_count = SPECPDL_INDEX ();
       int previous_menu_items_used = f->menu_bar_items_used;
       Lisp_Object *previous_items
        = (Lisp_Object *) alloca (previous_menu_items_used
diff --git a/src/window.c b/src/window.c
index 449f2b0cc5..59e21f11cb 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2576,7 +2576,7 @@ window_list (void)
   if (!CONSP (Vwindow_list))
     {
       Lisp_Object tail, frame;
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
 
       Vwindow_list = Qnil;
       /*  Don't allow quitting in Fnconc.  Otherwise we might end up
@@ -2734,7 +2734,7 @@ static Lisp_Object
 next_window (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames,
             bool next_p)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   decode_next_window_args (&window, &minibuf, &all_frames);
 
@@ -2888,7 +2888,7 @@ static Lisp_Object
 window_list_1 (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames)
 {
   Lisp_Object tail, list, rest;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   decode_next_window_args (&window, &minibuf, &all_frames);
   list = Qnil;
@@ -3507,7 +3507,7 @@ select_frame_norecord (Lisp_Object frame)
 static void
 run_window_configuration_change_hook (struct frame *f)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object frame, global_wcch
     = Fdefault_value (Qwindow_configuration_change_hook);
   XSETFRAME (frame, f);
@@ -3540,7 +3540,7 @@ run_window_configuration_change_hook (struct frame *f)
        if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook,
                                      buffer)))
          {
-           ptrdiff_t inner_count = SPECPDL_INDEX ();
+           specpdl_ref inner_count = SPECPDL_INDEX ();
            record_unwind_protect (select_window_norecord, selected_window);
            select_window_norecord (window);
            run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook,
@@ -3577,7 +3577,7 @@ has established the size of the new window.  */)
   (Lisp_Object window)
 {
   struct window *w = decode_live_window (window);
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   record_unwind_current_buffer ();
   Fset_buffer (w->contents);
@@ -3817,7 +3817,7 @@ run_window_change_functions (void)
   Lisp_Object tail, frame;
   bool selected_frame_change = !EQ (selected_frame, old_selected_frame);
   bool run_window_state_change_hook = false;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   window_change_record_frames = false;
   record_unwind_protect_void (window_change_record);
@@ -4014,7 +4014,7 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
 {
   struct window *w = XWINDOW (window);
   struct buffer *b = XBUFFER (buffer);
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   bool samebuf = EQ (buffer, w->contents);
 
   wset_buffer (w, buffer);
@@ -4234,7 +4234,7 @@ temp_output_buffer_show (register Lisp_Object buf)
       /* Run temp-buffer-show-hook, with the chosen window selected
         and its buffer current.  */
       {
-        ptrdiff_t count = SPECPDL_INDEX ();
+        specpdl_ref count = SPECPDL_INDEX ();
         Lisp_Object prev_window, prev_buffer;
         prev_window = selected_window;
         XSETBUFFER (prev_buffer, old);
@@ -5488,7 +5488,7 @@ window_internal_height (struct window *w)
 static void
 window_scroll (Lisp_Object window, EMACS_INT n, bool whole, bool noerror)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   n = clip_to_bounds (INT_MIN, n, INT_MAX);
 
@@ -6214,7 +6214,7 @@ scroll_command (Lisp_Object window, Lisp_Object n, int 
direction)
 {
   struct window *w;
   bool other_window;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   eassert (eabs (direction) == 1);
 
@@ -6345,7 +6345,7 @@ It is determined by the function 
`other-window-for-scrolling',
 which see.  */)
   (Lisp_Object arg)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   scroll_command (Fother_window_for_scrolling (), arg, 1);
   return unbind_to (count, Qnil);
 }
@@ -6356,7 +6356,7 @@ DEFUN ("scroll-other-window-down", 
Fscroll_other_window_down,
 For more details, see the documentation for `scroll-other-window'.  */)
   (Lisp_Object arg)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   scroll_command (Fother_window_for_scrolling (), arg, -1);
   return unbind_to (count, Qnil);
 }
diff --git a/src/xdisp.c b/src/xdisp.c
index cafc50e755..cc1da24aca 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2998,7 +2998,7 @@ safe__call (bool inhibit_quit, ptrdiff_t nargs, 
Lisp_Object func, va_list ap)
   else
     {
       ptrdiff_t i;
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       Lisp_Object *args;
       USE_SAFE_ALLOCA;
       SAFE_ALLOCA_LISP (args, nargs);
@@ -4304,7 +4304,7 @@ handle_fontified_prop (struct it *it)
             no amount of fontifying will be able to change it.  */
          NILP (prop) && IT_CHARPOS (*it) < Z))
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       Lisp_Object val;
       struct buffer *obuf = current_buffer;
       ptrdiff_t begv = BEGV, zv = ZV;
@@ -4499,7 +4499,7 @@ face_at_pos (const struct it *it, enum 
lface_attribute_index attr_filter)
 static enum prop_handled
 handle_face_prop (struct it *it)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   /* Don't allow the user to quit out of face-merging code, in case
      this is called when redisplaying a non-selected window, with
      point temporarily moved to window-point.  */
@@ -5544,7 +5544,7 @@ handle_single_display_spec (struct it *it, Lisp_Object 
spec, Lisp_Object object,
     form = Qnil;
   if (!NILP (form) && !EQ (form, Qt))
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
 
       /* Bind `object' to the object having the `display' property, a
         buffer or string.  Bind `position' to the position in the
@@ -5621,7 +5621,7 @@ handle_single_display_spec (struct it *it, Lisp_Object 
spec, Lisp_Object object,
                {
                  /* Evaluate IT->font_height with `height' bound to the
                     current specified height to get the new height.  */
-                 ptrdiff_t count = SPECPDL_INDEX ();
+                 specpdl_ref count = SPECPDL_INDEX ();
                  struct face *face = FACE_FROM_ID (it->f, it->face_id);
 
                  specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
@@ -5822,7 +5822,7 @@ handle_single_display_spec (struct it *it, Lisp_Object 
spec, Lisp_Object object,
              /* Don't allow quitting from lookup_derived_face, for when
                 we are displaying a non-selected window, and the buffer's
                 point was temporarily moved to the window-point.  */
-             ptrdiff_t count1 = SPECPDL_INDEX ();
+             specpdl_ref count1 = SPECPDL_INDEX ();
              specbind (Qinhibit_quit, Qt);
              face_id2 = lookup_derived_face (it->w, it->f, face_name,
                                              FRINGE_FACE_ID, false);
@@ -5995,7 +5995,7 @@ handle_single_display_spec (struct it *it, Lisp_Object 
spec, Lisp_Object object,
 #ifdef HAVE_WINDOW_SYSTEM
       else
        {
-         ptrdiff_t count = SPECPDL_INDEX ();
+         specpdl_ref count = SPECPDL_INDEX ();
 
          it->what = IT_IMAGE;
          /* Don't allow quitting from lookup_image, for when we are
@@ -11212,7 +11212,7 @@ WINDOW.  */)
                      ? current_buffer
                      : XBUFFER (Fget_buffer (buffer_or_name)));
   Lisp_Object buffer, value;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   XSETBUFFER (buffer, b);
 
@@ -11448,7 +11448,7 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool 
nlflag, bool multibyte)
              we aren't prepared to run modification hooks (we could
              end up calling modification hooks from another buffer and
              only with AFTER=t, Bug#21824).  */
-          ptrdiff_t count = SPECPDL_INDEX ();
+          specpdl_ref count = SPECPDL_INDEX ();
           specbind (Qinhibit_modification_hooks, Qt);
 
          insert_1_both ("\n", 1, 1, true, false, false);
@@ -11903,7 +11903,7 @@ with_echo_area_buffer (struct window *w, int which,
 {
   Lisp_Object buffer;
   bool this_one, the_other, clear_buffer_p, rc;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   /* If buffers aren't live, make new ones.  */
   ensure_echo_area_buffers ();
@@ -12088,7 +12088,7 @@ setup_echo_area_for_printing (bool multibyte_p)
 
       if (Z > BEG)
        {
-         ptrdiff_t count = SPECPDL_INDEX ();
+         specpdl_ref count = SPECPDL_INDEX ();
          specbind (Qinhibit_read_only, Qt);
          /* Note that undo recording is always disabled.  */
          del_range (BEG, Z);
@@ -12156,7 +12156,7 @@ display_echo_area (struct window *w)
      That message would modify the echo area buffer's contents while a
      redisplay of the buffer is going on, and seriously confuse
      redisplay.  */
-  ptrdiff_t count = inhibit_garbage_collection ();
+  specpdl_ref count = inhibit_garbage_collection ();
 
   /* If there is no message, we must call display_echo_area_1
      nevertheless because it resizes the window.  But we will have to
@@ -12536,7 +12536,7 @@ set_message (Lisp_Object string)
 
   if (FUNCTIONP (Vset_message_function))
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       specbind (Qinhibit_quit, Qt);
       message = safe_call1 (Vset_message_function, string);
       unbind_to (count, Qnil);
@@ -12614,7 +12614,7 @@ clear_message (bool current_p, bool last_displayed_p)
 
       if (FUNCTIONP (Vclear_message_function))
         {
-          ptrdiff_t count = SPECPDL_INDEX ();
+          specpdl_ref count = SPECPDL_INDEX ();
           specbind (Qinhibit_quit, Qt);
           safe_call (1, Vclear_message_function);
           unbind_to (count, Qnil);
@@ -12749,7 +12749,7 @@ echo_area_display (bool update_frame_p)
              /* Must update other windows.  Likewise as in other
                 cases, don't let this update be interrupted by
                 pending input.  */
-             ptrdiff_t count = SPECPDL_INDEX ();
+             specpdl_ref count = SPECPDL_INDEX ();
              specbind (Qredisplay_dont_pause, Qt);
              fset_redisplay (f);
              redisplay_internal ();
@@ -13085,7 +13085,7 @@ gui_consider_frame_title (Lisp_Object frame)
       char *title;
       ptrdiff_t len;
       struct it it;
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
 
       FOR_EACH_FRAME (tail, other_frame)
        {
@@ -13243,7 +13243,7 @@ prepare_menu_bars (void)
   if (all_windows)
     {
       Lisp_Object tail, frame;
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       /* True means that update_menu_bar has run its hooks
         so any further calls to update_menu_bar shouldn't do so again.  */
       bool menu_bar_hooks_run = false;
@@ -13340,7 +13340,7 @@ update_menu_bar (struct frame *f, bool save_match_data, 
bool hooks_run)
          || window_buffer_changed (w))
        {
          struct buffer *prev = current_buffer;
-         ptrdiff_t count = SPECPDL_INDEX ();
+         specpdl_ref count = SPECPDL_INDEX ();
 
          specbind (Qinhibit_menubar_update, Qt);
 
@@ -13510,7 +13510,7 @@ update_tab_bar (struct frame *f, bool save_match_data)
          || window_buffer_changed (w))
        {
          struct buffer *prev = current_buffer;
-         ptrdiff_t count = SPECPDL_INDEX ();
+         specpdl_ref count = SPECPDL_INDEX ();
          Lisp_Object new_tab_bar;
           int new_n_tab_bar;
 
@@ -14423,7 +14423,7 @@ update_tool_bar (struct frame *f, bool save_match_data)
          || window_buffer_changed (w))
        {
          struct buffer *prev = current_buffer;
-         ptrdiff_t count = SPECPDL_INDEX ();
+         specpdl_ref count = SPECPDL_INDEX ();
          Lisp_Object frame, new_tool_bar;
           int new_n_tool_bar;
 
@@ -15974,7 +15974,6 @@ redisplay_internal (void)
   bool must_finish = false, match_p;
   struct text_pos tlbufpos, tlendpos;
   int number_of_visible_frames;
-  ptrdiff_t count;
   struct frame *sf;
   bool polling_stopped_here = false;
   Lisp_Object tail, frame;
@@ -16037,7 +16036,7 @@ redisplay_internal (void)
 
   /* Record a function that clears redisplaying_p
      when we leave this function.  */
-  count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   record_unwind_protect_void (unwind_redisplay);
   redisplaying_p = true;
   block_buffer_flips ();
@@ -16826,7 +16825,7 @@ redisplay_preserve_echo_area (int from_where)
   redisplay_trace ("redisplay_preserve_echo_area (%d)\n", from_where);
 
   block_input ();
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   record_unwind_protect_void (unwind_redisplay_preserve_echo_area);
   block_buffer_flips ();
   unblock_input ();
@@ -17700,7 +17699,7 @@ run_window_scroll_functions (Lisp_Object window, struct 
text_pos startp)
 
   if (!NILP (Vwindow_scroll_functions))
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       specbind (Qinhibit_quit, Qt);
       run_hook_with_args_2 (Qwindow_scroll_functions, window,
                            make_fixnum (CHARPOS (startp)));
@@ -18835,7 +18834,7 @@ redisplay_window (Lisp_Object window, bool 
just_this_one_p)
      It indicates that the buffer contents and narrowing are unchanged.  */
   bool buffer_unchanged_p = false;
   bool temp_scroll_step = false;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   int rc;
   int centering_position = -1;
   bool last_line_misfit = false;
@@ -19781,7 +19780,7 @@ redisplay_window (Lisp_Object window, bool 
just_this_one_p)
          || window_wants_header_line (w)
          || window_wants_tab_line (w)))
     {
-      ptrdiff_t count1 = SPECPDL_INDEX ();
+      specpdl_ref count1 = SPECPDL_INDEX ();
 
       specbind (Qinhibit_quit, Qt);
       display_mode_lines (w);
@@ -22601,7 +22600,7 @@ extend_face_to_end_of_line (struct it *it)
           || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0))
     return;
 
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   /* Don't allow the user to quit out of face-merging code, in case
      this is called when redisplaying a non-selected window, with
@@ -23499,7 +23498,7 @@ display_count_lines_logically (ptrdiff_t start_byte, 
ptrdiff_t limit_byte,
     return display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
 
   ptrdiff_t val;
-  ptrdiff_t pdl_count = SPECPDL_INDEX ();
+  specpdl_ref pdl_count = SPECPDL_INDEX ();
   record_unwind_protect (save_restriction_restore, save_restriction_save ());
   Fwiden ();
   val = display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
@@ -23525,7 +23524,7 @@ display_count_lines_visually (struct it *it)
     return it->lnum + 1;
   else
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
 
       if (IT_CHARPOS (*it) <= PT)
        {
@@ -25961,7 +25960,7 @@ display_mode_lines (struct window *w)
 {
   Lisp_Object old_selected_window = selected_window;
   Lisp_Object new_frame = w->frame;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   int n = 0;
 
   record_unwind_protect (restore_selected_window, selected_window);
@@ -26053,7 +26052,7 @@ display_mode_line (struct window *w, enum face_id 
face_id, Lisp_Object format)
 {
   struct it it;
   struct face *face;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   init_iterator (&it, w, -1, -1, NULL, face_id);
   /* Don't extend on a previously drawn mode-line.
@@ -26818,7 +26817,7 @@ are the selected window and the WINDOW's buffer).  */)
   struct buffer *old_buffer = NULL;
   int face_id;
   bool no_props = FIXNUMP (face);
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object str;
   int string_start = 0;
 
@@ -27531,7 +27530,7 @@ decode_mode_spec (struct window *w, register int c, int 
field_width,
 
     case '@':
       {
-       ptrdiff_t count = inhibit_garbage_collection ();
+       specpdl_ref count = inhibit_garbage_collection ();
        Lisp_Object curdir = BVAR (current_buffer, directory);
        Lisp_Object val = Qnil;
 
diff --git a/src/xfns.c b/src/xfns.c
index 6226f4063a..6d4a4f47cf 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -4302,7 +4302,7 @@ This function is an internal primitive--use `make-frame' 
instead.  */)
   bool minibuffer_only = false;
   bool undecorated = false, override_redirect = false;
   long window_prompting = 0;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object display;
   struct x_display_info *dpyinfo = NULL;
   Lisp_Object parent, parent_frame;
@@ -7136,7 +7136,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo, 
Lisp_Object parms)
   struct frame *f;
   Lisp_Object frame;
   Lisp_Object name;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   bool face_change_before = face_change;
 
   if (!dpyinfo->terminal->name)
@@ -7637,10 +7637,9 @@ x_hide_tip (bool delete)
     return Qnil;
   else
     {
-      ptrdiff_t count;
       Lisp_Object was_open = Qnil;
 
-      count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       specbind (Qinhibit_redisplay, Qt);
       specbind (Qinhibit_quit, Qt);
 
@@ -7699,10 +7698,9 @@ x_hide_tip (bool delete)
     return Qnil;
   else
     {
-      ptrdiff_t count;
       Lisp_Object was_open = Qnil;
 
-      count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       specbind (Qinhibit_redisplay, Qt);
       specbind (Qinhibit_quit, Qt);
 
@@ -7797,8 +7795,7 @@ Text larger than the specified size is clipped.  */)
   struct text_pos pos;
   int width, height;
   int old_windows_or_buffers_changed = windows_or_buffers_changed;
-  ptrdiff_t count = SPECPDL_INDEX ();
-  ptrdiff_t count_1;
+  specpdl_ref count = SPECPDL_INDEX ();
   Lisp_Object window, size, tip_buf;
   Window child;
   XWindowAttributes child_attrs;
@@ -8001,7 +7998,7 @@ Text larger than the specified size is clipped.  */)
 
   /* Insert STRING into root window's buffer and fit the frame to the
      buffer.  */
-  count_1 = SPECPDL_INDEX ();
+  specpdl_ref count_1 = SPECPDL_INDEX ();
   old_buffer = current_buffer;
   set_buffer_internal_1 (XBUFFER (w->contents));
   bset_truncate_lines (current_buffer, Qnil);
@@ -8190,7 +8187,7 @@ DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 
2, 5, 0,
   Arg al[10];
   int ac = 0;
   XmString dir_xmstring, pattern_xmstring;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   check_window_system (f);
 
@@ -8357,7 +8354,7 @@ value of DIR as in previous invocations; this is standard 
MS Windows behavior.
   char *fn;
   Lisp_Object file = Qnil;
   Lisp_Object decoded_file;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   char *cdef_file;
 
   check_window_system (f);
@@ -8418,7 +8415,7 @@ nil, it defaults to the selected frame. */)
   Lisp_Object font;
   Lisp_Object font_param;
   char *default_name = NULL;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   if (popup_activated ())
     error ("Trying to use a menu from within a menu-entry");
@@ -8670,7 +8667,6 @@ Note: Text drawn with the `x' font backend is shown with 
hollow boxes.  */)
      (Lisp_Object frames)
 {
   Lisp_Object rest, tmp;
-  int count;
 
   if (!CONSP (frames))
     frames = list1 (frames);
@@ -8689,7 +8685,7 @@ Note: Text drawn with the `x' font backend is shown with 
hollow boxes.  */)
   frames = Fnreverse (tmp);
 
   /* Make sure the current matrices are up-to-date.  */
-  count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   specbind (Qredisplay_dont_pause, Qt);
   redisplay_preserve_echo_area (32);
   unbind_to (count, Qnil);
diff --git a/src/xmenu.c b/src/xmenu.c
index 28fafa108d..21e8f0f9ec 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -861,7 +861,7 @@ set_frame_menubar (struct frame *f, bool deep_p)
 
       struct buffer *prev = current_buffer;
       Lisp_Object buffer;
-      ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+      specpdl_ref specpdl_count = SPECPDL_INDEX ();
       int previous_menu_items_used = f->menu_bar_items_used;
       Lisp_Object *previous_items
        = alloca (previous_menu_items_used * sizeof *previous_items);
@@ -1401,7 +1401,7 @@ create_and_show_popup_menu (struct frame *f, widget_value 
*first_wv,
   GtkWidget *menu;
   GtkMenuPositionFunc pos_func = 0;  /* Pop up at pointer.  */
   struct next_popup_x_y popup_x_y;
-  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+  specpdl_ref specpdl_count = SPECPDL_INDEX ();
   bool use_pos_func = ! for_click;
 
 #ifdef HAVE_GTK3
@@ -1634,7 +1634,7 @@ create_and_show_popup_menu (struct frame *f, widget_value 
*first_wv,
   x_activate_timeout_atimer ();
 
   {
-    ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+    specpdl_ref specpdl_count = SPECPDL_INDEX ();
 
     record_unwind_protect_int (pop_down_menu, (int) menu_id);
 
@@ -1665,7 +1665,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
     = alloca (menu_items_used * sizeof *subprefix_stack);
   int submenu_depth = 0;
 
-  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+  specpdl_ref specpdl_count = SPECPDL_INDEX ();
 
   eassert (FRAME_X_P (f));
 
@@ -1952,7 +1952,7 @@ create_and_show_dialog (struct frame *f, widget_value 
*first_wv)
 
   if (menu)
     {
-      ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+      specpdl_ref specpdl_count = SPECPDL_INDEX ();
       record_unwind_protect_ptr (pop_down_menu, menu);
 
       /* Display the menu.  */
@@ -2007,7 +2007,7 @@ create_and_show_dialog (struct frame *f, widget_value 
*first_wv)
   /* Process events that apply to the dialog box.
      Also handle timers.  */
   {
-    ptrdiff_t count = SPECPDL_INDEX ();
+    specpdl_ref count = SPECPDL_INDEX ();
 
     /* xdialog_show_unwind is responsible for popping the dialog box down.  */
 
@@ -2039,7 +2039,7 @@ x_dialog_show (struct frame *f, Lisp_Object title,
   /* Whether we've seen the boundary between left-hand elts and right-hand.  */
   bool boundary_seen = false;
 
-  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+  specpdl_ref specpdl_count = SPECPDL_INDEX ();
 
   eassert (FRAME_X_P (f));
 
@@ -2191,7 +2191,7 @@ xw_popup_dialog (struct frame *f, Lisp_Object header, 
Lisp_Object contents)
   Lisp_Object title;
   const char *error_name;
   Lisp_Object selection;
-  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+  specpdl_ref specpdl_count = SPECPDL_INDEX ();
 
   check_window_system (f);
 
@@ -2312,7 +2312,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
   int maxwidth;
   int dummy_int;
   unsigned int dummy_uint;
-  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+  specpdl_ref specpdl_count = SPECPDL_INDEX ();
 
   eassert (FRAME_X_P (f) || FRAME_MSDOS_P (f));
 
diff --git a/src/xselect.c b/src/xselect.c
index f2a64dd953..979f454948 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -376,7 +376,7 @@ x_get_local_selection (Lisp_Object selection_symbol, 
Lisp_Object target_type,
       /* Don't allow a quit within the converter.
         When the user types C-g, he would be surprised
         if by luck it came during a converter.  */
-      ptrdiff_t count = SPECPDL_INDEX ();
+      specpdl_ref count = SPECPDL_INDEX ();
       specbind (Qinhibit_quit, Qt);
 
       CHECK_SYMBOL (target_type);
@@ -564,7 +564,7 @@ x_reply_selection_request (struct selection_input_event 
*event,
   Window window = SELECTION_EVENT_REQUESTOR (event);
   ptrdiff_t bytes_remaining;
   int max_bytes = selection_quantum (display);
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
   struct selection_data *cs;
 
   reply->type = SelectionNotify;
@@ -758,7 +758,7 @@ x_handle_selection_request (struct selection_input_event 
*event)
   Atom property = SELECTION_EVENT_PROPERTY (event);
   Lisp_Object local_selection_data;
   bool success = false;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   if (!dpyinfo) goto DONE;
 
@@ -1082,7 +1082,7 @@ wait_for_property_change_unwind (void *loc)
 static void
 wait_for_property_change (struct prop_location *location)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   /* Make sure to do unexpect_property_change if we quit or err.  */
   record_unwind_protect_ptr (wait_for_property_change_unwind, location);
diff --git a/src/xterm.c b/src/xterm.c
index 20ea746820..7195311737 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1202,7 +1202,7 @@ x_cr_export_frames (Lisp_Object frames, 
cairo_surface_type_t surface_type)
   int width, height;
   void (*surface_set_size_func) (cairo_surface_t *, double, double) = NULL;
   Lisp_Object acc = Qnil;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  specpdl_ref count = SPECPDL_INDEX ();
 
   specbind (Qredisplay_dont_pause, Qt);
   redisplay_preserve_echo_area (31);
@@ -12912,7 +12912,7 @@ x_connection_closed (Display *dpy, const char 
*error_message, bool ioerror)
 {
   struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
   Lisp_Object frame, tail;
-  ptrdiff_t idx = SPECPDL_INDEX ();
+  specpdl_ref idx = SPECPDL_INDEX ();
 
   error_msg = alloca (strlen (error_message) + 1);
   strcpy (error_msg, error_message);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]