GNU bug report logs - #76427
31.0.50; feature/igc: terminate_due_to_signal (sig=sig@entry=6, backtrace_limit=backtrace_limit@entry=2147483647) at ./src/emacs.c:425

Previous Next

Package: emacs;

Reported by: Gregor Zattler <telegraph <at> gmx.net>

Date: Wed, 19 Feb 2025 23:20:02 UTC

Severity: normal

Found in version 31.0.50

To reply to this bug, email your comments to 76427 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#76427; Package emacs. (Wed, 19 Feb 2025 23:20:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Gregor Zattler <telegraph <at> gmx.net>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Wed, 19 Feb 2025 23:20:03 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Gregor Zattler <telegraph <at> gmx.net>
To: bug-gnu-emacs <at> gnu.org
Subject: 31.0.50; feature/igc: terminate_due_to_signal (sig=sig <at> entry=6,
 backtrace_limit=backtrace_limit <at> entry=2147483647) at ./src/emacs.c:425
Date: Thu, 20 Feb 2025 00:18:54 +0100
Dear Emacs developers, while working
with org-noter and pdf-tools, Emacs
crashed.

I would not know how to reproduce.

The session is still in GDB but only
till 15:00 Berlin local time.

Till then I will try to answer
operationalised questions regarding this
session. 

First information regarding this build
and configuration, below that you'll
find GDB output.

HTH, Gregor


In GNU Emacs 31.0.50 (build 5,
 x86_64-pc-linux-gnu, cairo version
 1.16.0) of 2025-02-16 built on no
Repository revision: 69a10f10de51a448a71c8cc8947f85f3902c894e
Repository branch: feature/igc
Windowing system distributor 'The X.Org Foundation', version 11.0.12101007
System Description: Debian GNU/Linux 12 (bookworm)

Configured using:
 'configure
 --infodir=/usr/share/info/emacs
 --with-json
 --with-file-notification=yes
 --with-libsystemd --with-cairo
 --with-x=yes --with-x-toolkit=no
 --without-toolkit-scroll-bars
 --without-gsettings
 --enable-check-lisp-object-type
 --enable-checking=yes,glyphs
 --with-native-compilation=yes
 --with-mps=yes 'CFLAGS=-ggdb3 -O3
 -ffile-prefix-map=/home/grfz/src/emacs-igc=. -fstack-protector-strong
 -Wformat -Werror=format-security
 -fno-omit-frame-pointer'
 'CPPFLAGS=-I/home/grfz/mps-artifacts
 -Wdate-time -D_FORTIFY_SOURCE=2'
 'LDFLAGS=-L/home/grfz/mps-artifacts
 -Wl,-z,relro''

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP
GNUTLS GPM HARFBUZZ JPEG LCMS2 LIBOTF
LIBSELINUX LIBSYSTEMD LIBXML2 M17N_FLT
MODULES MPS NATIVE_COMP NOTIFY INOTIFY
OLDXMENU PDUMPER PNG RSVG SECCOMP SOUND
SQLITE3 THREADS TIFF WEBP X11 XDBE XIM
XINPUT2 XPM ZLIB

Important settings:
  value of $LC_ALL: 
  value of $LC_COLLATE: de_DE.utf8
  value of $LC_CTYPE: de_DE.utf8
  value of $LC_MESSAGES: POSIX
  value of $LC_MONETARY: de_DE.utf8
  value of $LC_NUMERIC: de_DE.utf8
  value of $LC_TIME: de_DE.utf8
  value of $LANG: de_DE.utf8
  locale-coding-system: utf-8-unix

Major mode: Lisp Interaction

Minor modes in effect:
  rainbow-delimiters-mode: t
  winner-mode: t
  pdf-occur-global-minor-mode: t
  mail-abbrevs-mode: t
  savehist-mode: t
  ws-butler-global-mode: t
  ws-butler-mode: t
  delete-selection-mode: t
  minibuffer-depth-indicate-mode: t
  which-function-mode: t
  windmove-mode: t
  xterm-mouse-mode: t
  key-chord-mode: t
  which-key-mode: t
  find-function-mode: t
  override-global-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  minibuffer-regexp-mode: t
  size-indication-mode: t
  column-number-mode: t
  line-number-mode: t
  transient-mark-mode: (only . t)
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t

Load-path shadows:
~/src/notmuch/emacs/notmuch-address hides /home/grfz/.config/emacs/elisp/notmuch-address
/home/grfz/src/ol-notmuch/ol-notmuch hides /home/grfz/.config/emacs/elisp/ol-notmuch
/home/grfz/.config/emacs/elpa-31.0/magit-4.3.0/magit-autorevert hides /home/grfz/.config/emacs/elpa-31.0/magit-section-4.3.0/magit-autorevert
~/src/notmuch/emacs/notmuch-lib hides /usr/local/share/emacs/site-lisp/notmuch-lib
~/src/notmuch/emacs/coolj hides /usr/local/share/emacs/site-lisp/coolj
~/src/notmuch/emacs/notmuch-address hides /usr/local/share/emacs/site-lisp/notmuch-address
~/src/notmuch/emacs/notmuch-hello hides /usr/local/share/emacs/site-lisp/notmuch-hello
~/src/notmuch/emacs/notmuch-parser hides /usr/local/share/emacs/site-lisp/notmuch-parser
~/src/notmuch/emacs/notmuch-show hides /usr/local/share/emacs/site-lisp/notmuch-show
~/src/notmuch/emacs/notmuch-wash hides /usr/local/share/emacs/site-lisp/notmuch-wash
~/src/notmuch/emacs/notmuch-draft hides /usr/local/share/emacs/site-lisp/notmuch-draft
~/src/notmuch/emacs/notmuch-tree hides /usr/local/share/emacs/site-lisp/notmuch-tree
~/src/notmuch/emacs/notmuch-version hides /usr/local/share/emacs/site-lisp/notmuch-version
~/src/notmuch/emacs/notmuch-jump hides /usr/local/share/emacs/site-lisp/notmuch-jump
~/src/notmuch/emacs/notmuch-company hides /usr/local/share/emacs/site-lisp/notmuch-company
~/src/notmuch/emacs/notmuch hides /usr/local/share/emacs/site-lisp/notmuch
~/src/notmuch/emacs/notmuch-crypto hides /usr/local/share/emacs/site-lisp/notmuch-crypto
~/src/notmuch/emacs/notmuch-compat hides /usr/local/share/emacs/site-lisp/notmuch-compat
~/src/notmuch/emacs/notmuch-maildir-fcc hides /usr/local/share/emacs/site-lisp/notmuch-maildir-fcc
~/src/notmuch/emacs/notmuch-tag hides /usr/local/share/emacs/site-lisp/notmuch-tag
~/src/notmuch/emacs/notmuch-message hides /usr/local/share/emacs/site-lisp/notmuch-message
~/src/notmuch/emacs/notmuch-print hides /usr/local/share/emacs/site-lisp/notmuch-print
~/src/notmuch/emacs/notmuch-mua hides /usr/local/share/emacs/site-lisp/notmuch-mua
~/src/notmuch/emacs/notmuch-query hides /usr/local/share/emacs/site-lisp/notmuch-query
/home/grfz/.config/emacs/elpa-31.0/transient-0.8.4/transient hides /home/grfz/src/emacs-igc/lisp/transient
/home/grfz/.config/emacs/elpa-31.0/window-tool-bar-0.3/window-tool-bar hides /home/grfz/src/emacs-igc/lisp/window-tool-bar
/home/grfz/.config/emacs/elpa-31.0/idlwave-6.5.1/idlw-shell hides /home/grfz/src/emacs-igc/lisp/obsolete/idlw-shell
/home/grfz/.config/emacs/elpa-31.0/idlwave-6.5.1/idlwave hides /home/grfz/src/emacs-igc/lisp/obsolete/idlwave
/home/grfz/.config/emacs/elpa-31.0/idlwave-6.5.1/idlw-toolbar hides /home/grfz/src/emacs-igc/lisp/obsolete/idlw-toolbar
/home/grfz/.config/emacs/elpa-31.0/idlwave-6.5.1/idlw-help hides /home/grfz/src/emacs-igc/lisp/obsolete/idlw-help
/home/grfz/.config/emacs/elpa-31.0/idlwave-6.5.1/idlw-complete-structtag hides /home/grfz/src/emacs-igc/lisp/obsolete/idlw-complete-structtag

Features:
(shadow sort orgalist wcheck-mode
ecomplete mail-extr emacsbug tramp
trampver tramp-integration files-x
tramp-message tramp-compat shell
parse-time iso8601 tramp-loaddefs
add-log rainbow-delimiters cus-start
winner pdf-occur ibuf-ext ibuffer
ibuffer-loaddefs tablist tablist-filter
semantic/wisent/comp semantic/wisent
semantic/wisent/wisent
semantic/util-modes semantic/util
semantic semantic/tag semantic/lex
semantic/fw mode-local cedet pdf-isearch
let-alist pdf-misc pdf-tools compile
pdf-view bookmark jka-compr pdf-cache
pdf-info tq pdf-util pdf-macs image-mode
exif ol-notmuch notmuch notmuch-tree
notmuch-jump notmuch-hello notmuch-show
notmuch-print notmuch-crypto notmuch-mua
notmuch-message notmuch-draft
notmuch-maildir-fcc notmuch-address
notmuch-company notmuch-parser
notmuch-wash diff-mode track-changes
coolj goto-addr icalendar diary-lib
diary-loaddefs notmuch-tag crm
notmuch-lib notmuch-version
notmuch-compat hl-line mm-view mml-smime
smime gnutls dig compat org-contrib
org-crypt org-protocol org-clock dbus
xml ob-plantuml gnus-alias advice
message yank-media puny dired
dired-loaddefs rfc822 mml mml-sec epa
derived epg rfc6068 epg-config gnus-util
text-property-search mm-decode mm-bodies
mm-encode mail-parse rfc2231 gmm-utils
mailheader sendmail rfc2047 rfc2045
ietf-drums mm-util mail-prsvr mail-utils
mailabbrev savehist auth-source-pass
holidays holiday-loaddefs ws-butler
delsel modus-operandi-theme modus-themes
mb-depth which-func imenu windmove
xt-mouse edmacro kmacro key-chord
which-key comp comp-cstr cl-extra
help-mode warnings comp-run comp-common
org ob ob-ref ob-lob ob-table ob-exp
org-macro org-pcomplete pcomplete
org-list org-footnote org-faces
org-entities time-date noutline outline
ob-emacs-lisp org-table org-loaddefs
thingatpt find-func cal-menu calendar
cal-loaddefs ob-tangle ol org-src
sh-script rx smie treesit executable
org-keys oc ob-comint comint ansi-osc
ansi-color ring ob-core org-cycle
org-fold org-fold-core org-compat
ob-eval org-version org-macs format-spec
use-package use-package-ensure
use-package-delight use-package-diminish
use-package-bind-key bind-key easy-mmode
use-package-core async-autoloads
csv-mode-autoloads dash-autoloads
debbugs-autoloads
dired-git-info-autoloads
git-timemachine-autoloads
hyperbole-autoloads kotl-autoloads hact
set hhist idlwave-autoloads
key-chord-autoloads magit-autoloads
pcase magit-section-autoloads
llama-autoloads
minibuffer-line-autoloads
org-contrib-autoloads
org-noter-autoloads org-autoloads
orgalist-autoloads paredit-autoloads
pdf-tools-autoloads qpdf.el-autoloads
finder-inf rainbow-delimiters-autoloads
tablist-autoloads transient-autoloads
wcheck-mode-autoloads
window-tool-bar-autoloads info
with-editor-autoloads
ws-butler-autoloads package browse-url
xdg url url-proxy url-privacy url-expand
url-methods url-history url-cookie
generate-lisp-file url-domsuf url-util
mailcap url-handlers url-parse
auth-source cl-seq eieio eieio-core
cl-macs password-cache json subr-x map
byte-opt gv bytecomp byte-compile
url-vars cus-edit pp cus-load icons
wid-edit cl-loaddefs cl-lib rmc
iso-transl tooltip cconv eldoc paren
electric uniquify ediff-hook vc-hooks
lisp-float-type elisp-mode mwheel
term/x-win x-win term/common-win x-dnd
touch-screen tool-bar dnd fontset image
regexp-opt fringe tabulated-list replace
newcomment text-mode lisp-mode prog-mode
register page tab-bar menu-bar
rfn-eshadow isearch easymenu timer
select scroll-bar mouse jit-lock
font-lock syntax font-core
term/tty-colors frame minibuffer nadvice
seq simple cl-generic indonesian
philippine cham georgian utf-8-lang
misc-lang vietnamese tibetan thai
tai-viet lao korean japanese eucjp-ms
cp51932 hebrew greek romanian slovak
czech european ethiopic indian cyrillic
chinese composite emoji-zwj charscript
charprop case-table epa-hook
jka-cmpr-hook help abbrev obarray
oclosure cl-preloaded button loaddefs
theme-loaddefs faces cus-face macroexp
files window text-properties overlay
sha1 md5 base64 format env code-pages
mule custom widget keymap
hashtable-print-readable backquote
threads dbusbind inotify lcms2
dynamic-setting font-render-setting
cairo xinput2 x multi-tty move-toolbar
make-network-process tty-child-frames
native-compile mps emacs)

Memory information:
((conses 24 0 0) (symbols 56 0 0) (strings 40 0 0) (string-bytes 1 0)
 (vectors 24 0) (vector-slots 8 0 0) (floats 24 0 0) (intervals 64 0 0)
 (buffers 992 0))




Starting program: /home/grfz/src/emacs-igc/src/emacs --debug-init -xrm --init-directory="${USER_EMACS_DIRECTORY}" --fg-daemon="${EMACS_SERVER_NAME}"
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[Detaching after vfork from child process 4476]
[Detaching after vfork from child process 4477]
[Detaching after vfork from child process 4478]
[Detaching after vfork from child process 4479]
[Detaching after vfork from child process 4580]
[Detaching after vfork from child process 4594]
[Detaching after vfork from child process 4706]
[Detaching after vfork from child process 4707]
[Detaching after vfork from child process 5085]

Program received signal SIGSEGV, Segmentation fault.


[... 17 Zeilen gelöscht ...]

Program received signal SIGSEGV, Segmentation fault.
[Detaching after vfork from child process 5113]
[Detaching after vfork from child process 5114]
[Detaching after vfork from child process 5115]
[Detaching after vfork from child process 5116]
[Detaching after vfork from child process 5117]
[Detaching after vfork from child process 5118]
[Detaching after vfork from child process 5146]
[Detaching after vfork from child process 5147]
[Detaching after vfork from child process 5148]
[Detaching after vfork from child process 5149]
[Detaching after vfork from child process 5151]
[Detaching after vfork from child process 5152]
[Detaching after vfork from child process 5153]
[Detaching after vfork from child process 5154]
[Detaching after vfork from child process 5155]
[Detaching after vfork from child process 5156]
[Detaching after vfork from child process 5157]
[Detaching after vfork from child process 5158]
[Detaching after vfork from child process 5159]
[Detaching after vfork from child process 5160]
[Detaching after vfork from child process 5161]
[Detaching after vfork from child process 5292]
[Detaching after vfork from child process 5293]
[Detaching after vfork from child process 5294]
[Detaching after vfork from child process 5295]
[Detaching after vfork from child process 5296]
[Detaching after vfork from child process 5297]

Program received signal SIGSEGV, Segmentation fault.

[... 468 Zeilen gelöscht ...]

Program received signal SIGSEGV, Segmentation fault.
[Detaching after vfork from child process 18435]
[Detaching after vfork from child process 19736]
[Detaching after vfork from child process 30493]
[Detaching after vfork from child process 30494]
[Detaching after vfork from child process 30495]
[Detaching after vfork from child process 30496]
[Detaching after vfork from child process 30515]
[Detaching after vfork from child process 30522]
[Detaching after vfork from child process 30525]
[Detaching after vfork from child process 31602]
[Detaching after vfork from child process 31603]
[Detaching after vfork from child process 32693]
[Detaching after vfork from child process 32696]
[Detaching after vfork from child process 33796]
[Detaching after vfork from child process 33798]

Program received signal SIGSEGV, Segmentation fault.

Program received signal SIGSEGV, Segmentation fault.
[Detaching after vfork from child process 34941]
[Detaching after vfork from child process 34944]
[Detaching after vfork from child process 36031]
[Detaching after vfork from child process 36034]
[Detaching after vfork from child process 37184]
[Detaching after vfork from child process 37185]
[Detaching after vfork from child process 38283]
[Detaching after vfork from child process 38285]
[Detaching after vfork from child process 39390]
[Detaching after vfork from child process 39392]
[Detaching after vfork from child process 40535]
[Detaching after vfork from child process 40538]
[Detaching after vfork from child process 41640]
[Detaching after vfork from child process 41642]
[Detaching after vfork from child process 41909]
[Detaching after vfork from child process 42728]
[Detaching after vfork from child process 42729]
[Detaching after vfork from child process 43878]
[Detaching after vfork from child process 43879]
[Detaching after vfork from child process 44448]
[Detaching after vfork from child process 44449]
[Detaching after vfork from child process 44450]
[Detaching after vfork from child process 44451]
[Detaching after vfork from child process 44452]

Breakpoint 1, terminate_due_to_signal (sig=sig <at> entry=6, backtrace_limit=backtrace_limit <at> entry=2147483647) at ./src/emacs.c:425
425	{
+bt
#0  terminate_due_to_signal (sig=sig <at> entry=6, backtrace_limit=backtrace_limit <at> entry=2147483647) at ./src/emacs.c:425
#1  0x00005555555b8f4f in die (msg=msg <at> entry=0x5555559b50d0 "BUFFERP (a)", file=file <at> entry=0x5555559b50c7 "buffer.h", line=line <at> entry=829) at ./src/alloc.c:7709
#2  0x00005555555a0bda in XBUFFER (a=Python Exception <class 'gdb.error'>: value has been optimized out
) at ./src/buffer.h:829
#3  0x00005555555a4370 in XBUFFER (a=Python Exception <class 'gdb.error'>: value has been optimized out
) at ./src/xdisp.c:17024
#4  prepare_menu_bars () at ./src/xdisp.c:14041
#5  redisplay_internal () at ./src/xdisp.c:17103
#6  0x000055555564ed35 in redisplay () at ./src/xdisp.c:16675
#7  0x000055555577bb25 in read_char (commandflag=1, map=Python Exception <class 'gdb.error'>: value has been optimized out
, map <at> entry=XIL(0x7fffb569cfd3), prev_event=Python Exception <class 'gdb.error'>: value has been optimized out
, used_mouse_menu=used_mouse_menu <at> entry=0x7fffffffcb0b, end_time=end_time <at> entry=0x0) at ./src/keyboard.c:2683
#8  0x000055555577e1bb in read_key_sequence (keybuf=keybuf <at> entry=0x7fffffffcc70, prompt=Python Exception <class 'gdb.error'>: value has been optimized out
, prompt <at> entry=XIL(0), dont_downcase_last=dont_downcase_last <at> entry=false, can_return_switch_frame=can_return_switch_frame <at> entry=true, fix_current_buffer=fix_current_buffer <at> entry=true, prevent_redisplay=prevent_redisplay <at> entry=false, disable_text_conversion_p=<optimized out>) at ./src/keyboard.c:10790
#9  0x000055555577fee7 in command_loop_1 () at ./src/lisp.h:1184
#10 0x000055555581e956 in internal_condition_case (bfun=bfun <at> entry=0x55555577fc90 <command_loop_1>, handlers=handlers <at> entry=XIL(0xa8), hfun=hfun <at> entry=0x555555763ec0 <cmd_error>) at ./src/eval.c:1626
#11 0x0000555555762afe in command_loop_2 (handlers=handlers <at> entry=XIL(0xa8)) at ./src/keyboard.c:1174
#12 0x000055555581e6df in internal_catch (tag=tag <at> entry=XIL(0x15498), func=func <at> entry=0x555555762ad0 <command_loop_2>, arg=Python Exception <class 'gdb.error'>: value has been optimized out
, arg <at> entry=XIL(0xa8)) at ./src/eval.c:1305
#13 0x0000555555762a99 in command_loop () at ./src/lisp.h:1184
#14 0x000055555576f5b5 in recursive_edit_1 () at ./src/keyboard.c:760
#15 0x000055555576f965 in Frecursive_edit () at ./src/keyboard.c:843
#16 0x00005555555d1fd7 in main (argc=5, argv=<optimized out>) at ./src/emacs.c:2580

Lisp Backtrace:
"redisplay_internal (C function)" (0x0)
+xbacktrace
"redisplay_internal (C function)" (0x0)
+bt full
#0  terminate_due_to_signal (sig=sig <at> entry=6, backtrace_limit=backtrace_limit <at> entry=2147483647) at ./src/emacs.c:425
#1  0x00005555555b8f4f in die (msg=msg <at> entry=0x5555559b50d0 "BUFFERP (a)", file=file <at> entry=0x5555559b50c7 "buffer.h", line=line <at> entry=829) at ./src/alloc.c:7709
#2  0x00005555555a0bda in XBUFFER (a=Python Exception <class 'gdb.error'>: value has been optimized out
) at ./src/buffer.h:829
#3  0x00005555555a4370 in XBUFFER (a=Python Exception <class 'gdb.error'>: value has been optimized out
) at ./src/xdisp.c:17024
        f = <optimized out>
        tail = Python Exception <class 'gdb.error'>: value has been optimized out

        frame = Python Exception <class 'gdb.error'>: value has been optimized out

        all_windows = <optimized out>
        some_windows = <optimized out>
        w = <optimized out>
        sw = <optimized out>
        must_finish = <optimized out>
        match_p = <optimized out>
        tlbufpos = {
          charpos = <optimized out>,
          bytepos = <optimized out>
        }
        tlendpos = {
          charpos = <optimized out>,
          bytepos = <optimized out>
        }
        number_of_visible_frames = <optimized out>
        sf = <optimized out>
        polling_stopped_here = <optimized out>
        tail = Python Exception <class 'gdb.error'>: value has been optimized out

        frame = Python Exception <class 'gdb.error'>: value has been optimized out

        hscroll_retries = <optimized out>
        garbaged_frame_retries = <optimized out>
        consider_all_windows_p = <optimized out>
        update_miniwindow_p = <optimized out>
        previous_frame = <optimized out>
        current_matrices_cleared = <optimized out>
        new_count = <optimized out>
#4  prepare_menu_bars () at ./src/xdisp.c:14041
        f = <optimized out>
        tail = Python Exception <class 'gdb.error'>: value has been optimized out

        frame = Python Exception <class 'gdb.error'>: value has been optimized out

        all_windows = <optimized out>
        some_windows = <optimized out>
        w = <optimized out>
        sw = <optimized out>
        must_finish = <optimized out>
        match_p = <optimized out>
        tlbufpos = {
          charpos = <optimized out>,
          bytepos = <optimized out>
        }
        tlendpos = {
          charpos = <optimized out>,
          bytepos = <optimized out>
        }
        number_of_visible_frames = <optimized out>
        sf = <optimized out>
        polling_stopped_here = <optimized out>
        tail = Python Exception <class 'gdb.error'>: value has been optimized out

        frame = Python Exception <class 'gdb.error'>: value has been optimized out

        hscroll_retries = <optimized out>
        garbaged_frame_retries = <optimized out>
        consider_all_windows_p = <optimized out>
        update_miniwindow_p = <optimized out>
        previous_frame = <optimized out>
        current_matrices_cleared = <optimized out>
        new_count = <optimized out>
#5  redisplay_internal () at ./src/xdisp.c:17103
        w = <optimized out>
        sw = <optimized out>
        must_finish = <optimized out>
        match_p = <optimized out>
        tlbufpos = {
          charpos = <optimized out>,
          bytepos = <optimized out>
        }
        tlendpos = {
          charpos = <optimized out>,
          bytepos = <optimized out>
        }
        number_of_visible_frames = <optimized out>
        sf = <optimized out>
        polling_stopped_here = <optimized out>
        tail = Python Exception <class 'gdb.error'>: value has been optimized out

        frame = Python Exception <class 'gdb.error'>: value has been optimized out

        hscroll_retries = <optimized out>
        garbaged_frame_retries = <optimized out>
        consider_all_windows_p = <optimized out>
        update_miniwindow_p = <optimized out>
        previous_frame = <optimized out>
        current_matrices_cleared = <optimized out>
        new_count = <optimized out>
#6  0x000055555564ed35 in redisplay () at ./src/xdisp.c:16675
#7  0x000055555577bb25 in read_char (commandflag=1, map=Python Exception <class 'gdb.error'>: value has been optimized out
, map <at> entry=XIL(0x7fffb569cfd3), prev_event=Python Exception <class 'gdb.error'>: value has been optimized out
, used_mouse_menu=used_mouse_menu <at> entry=0x7fffffffcb0b, end_time=end_time <at> entry=0x0) at ./src/keyboard.c:2683
        echo_current = true
        c = XIL(0xe70fec18)
        local_getcjmp = {{
            __jmpbuf = {140736179668459, 140736179668456, 140737488340880, 93824995807319, 140736306686045, 0, 140737098294339, 56448},
            __mask_was_saved = -14448,
            __saved_mask = {
              __val = {0, 56448, 0, 140736179668459, 140736179668456, 140737488340976, 93824995807319, 56448, 8589920320, 140737488340976, 0, 56448, 140737488341056, 140736568339357, 140737049900221, 140737488341248}
            }
          }}
        save_jump = {{
            __jmpbuf = {140737049900221, 93824995844760, 140737049900216, 140737488341104, 140737049900216, 0, 0, 93824995067072},
            __mask_was_saved = 0,
            __saved_mask = {
              __val = {93824995066104, 482611, 942677809896941312, 0, 128, 0, 0, 52192, 93824996983776, 140736671565200, 140736659015216, 140737488341184, 93824995063105, 6, 140736659013363, 140737488341360}
            }
          }}
        tem = Python Exception <class 'gdb.error'>: value has been optimized out

        save = Python Exception <class 'gdb.error'>: value has been optimized out

        previous_echo_area_message = XIL(0)
        also_record = XIL(0)
        reread = false
        recorded = false
        polling_stopped_here = false
        orig_kboard = 0x5555560926c0
        c_volatile = make_fixnum(0)
#8  0x000055555577e1bb in read_key_sequence (keybuf=keybuf <at> entry=0x7fffffffcc70, prompt=Python Exception <class 'gdb.error'>: value has been optimized out
, prompt <at> entry=XIL(0), dont_downcase_last=dont_downcase_last <at> entry=false, can_return_switch_frame=can_return_switch_frame <at> entry=true, fix_current_buffer=fix_current_buffer <at> entry=true, prevent_redisplay=prevent_redisplay <at> entry=false, disable_text_conversion_p=<optimized out>) at ./src/keyboard.c:10790
        interrupted_kboard = 0x5555560926c0
        interrupted_frame = 0x7fffe70fec18
        key = Python Exception <class 'gdb.error'>: value has been optimized out

        used_mouse_menu = false
        echo_local_start = 0
        last_real_key_start = 0
        keys_local_start = 0
        new_binding = Python Exception <class 'gdb.error'>: value has been optimized out

        t = 0
        echo_start = 0
        keys_start = 0
        current_binding = XIL(0x7fffb569cfd3)
        first_unbound = 31
        mock_input = 0
        used_mouse_menu_history = {false <repeats 30 times>}
        fkey = {
          parent = XIL(0x7fffe6e2b8cb),
          map = XIL(0x7fffe6e2b8cb),
          start = 0,
          end = 0
        }
        keytran = {
          parent = XIL(0x7fffcc24a24b),
          map = XIL(0x7fffcc24a24b),
          start = 0,
          end = 0
        }
        indec = {
          parent = XIL(0x7fffe6e2b8b3),
          map = XIL(0x7fffe6e2b8b3),
          start = 0,
          end = 0
        }
        shift_translated = false
        delayed_switch_frame = XIL(0)
        original_uppercase = XIL(0)
        original_uppercase_position = -1
        disabled_conversion = false
        fake_prefixed_keys = XIL(0)
        first_event = XIL(0)
#9  0x000055555577fee7 in command_loop_1 () at ./src/lisp.h:1184
        cmd = Python Exception <class 'gdb.error'>: value has been optimized out

        keybuf = {XIL(0x16928), make_fixnum(53), make_fixnum(48), XIL(0), XIL(0x140b0), XIL(0x5555559dc3e0), XIL(0x7fffffffcd10), XIL(0x555555820753), XIL(0x7fffffffcf3c), XIL(0x3), XIL(0xc), XIL(0x140b0), XIL(0x38), XIL(0x7fffe5bf922d), XIL(0x7fffffffcd10), XIL(0x7fffffffcd50), XIL(0x60), XIL(0x555555763ec0), XIL(0x7fffffffcf3c), XIL(0x7fffffffd638), XIL(0x7fffffffcda0), XIL(0x5555557640b7), XIL(0), XIL(0), XIL(0x2aaa76727f88), XIL(0x7fffb291480b), XIL(0x7fffe8c00004), XIL(0), XIL(0x7fffffffcd00), XIL(0x555555820753)}
        i = <optimized out>
        last_pt = <optimized out>
        prev_modiff = 23738
        prev_buffer = 0x7fffe5ddb4b8
#10 0x000055555581e956 in internal_condition_case (bfun=bfun <at> entry=0x55555577fc90 <command_loop_1>, handlers=handlers <at> entry=XIL(0xa8), hfun=hfun <at> entry=0x555555763ec0 <cmd_error>) at ./src/eval.c:1626
        val = make_fixnum(16)
        c = 0x7fffe1f91f68
#11 0x0000555555762afe in command_loop_2 (handlers=handlers <at> entry=XIL(0xa8)) at ./src/keyboard.c:1174
#12 0x000055555581e6df in internal_catch (tag=tag <at> entry=XIL(0x15498), func=func <at> entry=0x555555762ad0 <command_loop_2>, arg=Python Exception <class 'gdb.error'>: value has been optimized out
, arg <at> entry=XIL(0xa8)) at ./src/eval.c:1305
        val = make_fixnum(16)
        c = 0x7fffe1f6c0f8
#13 0x0000555555762a99 in command_loop () at ./src/lisp.h:1184
#14 0x000055555576f5b5 in recursive_edit_1 () at ./src/keyboard.c:760
        val = Python Exception <class 'gdb.error'>: value has been optimized out

#15 0x000055555576f965 in Frecursive_edit () at ./src/keyboard.c:843
#16 0x00005555555d1fd7 in main (argc=5, argv=<optimized out>) at ./src/emacs.c:2580
        stack_bottom_variable = 0x7ffff3e92c60
        old_argc = <optimized out>
        no_loadup = <optimized out>
        junk = 0x0
        dname_arg = 0x7fffffffd69a "EMACS-MPS=yes"
        ch_to_dir = 0x0
        original_pwd = <optimized out>
        dump_mode = <optimized out>
        skip_args = 1
        temacs = 0x0
        attempt_load_pdump = <optimized out>
        only_version = <optimized out>
        rlim = {
          rlim_cur = 10022912,
          rlim_max = 18446744073709551615
        }
        lc_all = <optimized out>
        sockfd = <optimized out>
        module_assertions = <optimized out>

+i reg
rax            0x42                66
rbx            0x555555606a60      93824992963168
rcx            0x0                 0
rdx            0x0                 0
rsi            0x7fffffff          2147483647
rdi            0x6                 6
rbp            0x7fffffffaf80      0x7fffffffaf80
rsp            0x7fffffffaf78      0x7fffffffaf78
r8             0x0                 0
r9             0x73                115
r10            0x0                 0
r11            0x202               514
r12            0x555555671790      93824993400720
r13            0x7fffe5ddb4b8      140737049900216
r14            0xe                 14
r15            0x77be0             490464
rip            0x5555555b1374      0x5555555b1374 <terminate_due_to_signal>
eflags         0x206               [ PF IF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76427; Package emacs. (Thu, 20 Feb 2025 07:06:02 GMT) Full text and rfc822 format available.

Message #8 received at 76427 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Gregor Zattler <telegraph <at> gmx.net>
Cc: 76427 <at> debbugs.gnu.org
Subject: Re: bug#76427: 31.0.50;
 feature/igc: terminate_due_to_signal (sig=sig <at> entry=6,
 backtrace_limit=backtrace_limit <at> entry=2147483647) at ./src/emacs.c:425
Date: Thu, 20 Feb 2025 09:05:30 +0200
> Date: Thu, 20 Feb 2025 00:18:54 +0100
> From:  Gregor Zattler via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
> 
> Dear Emacs developers, while working
> with org-noter and pdf-tools, Emacs
> crashed.

It isn't a crash, it's an assertion violation, here:

      FOR_EACH_FRAME (tail, frame)
	{
	  struct frame *f = XFRAME (frame);
	  struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
	  if (some_windows
	      && !f->redisplay
	      && !w->redisplay
	      && !XBUFFER (w->contents)->text->redisplay) <<<<<<<<<<<<<<<<
	    continue;

> I would not know how to reproduce.

Like so:

 (gdb) fr 4
 (gdb) pp Vframe_list

This should show a list such as below:

  (#<frame xdisp.c 1115b968> #<frame *scratch* 0b6ac718>)

where each member shows the buffer and the C pointer to the frame
structure.  What does it show in your case?  The assertion violation
seems to imply that one of the frames has its selected window be
either corrupted or not a leaf window (which should never happen) or
maybe not a window object at all.

Given the above value of Vframe_list, please show the value of the
'->contents' field of each frame's selected window.  Like this:

  (gdb) p XWINDOW(((struct frame *)0x1115b968)->selected_window)->contents
  $4 = XIL(0xa00000000b6a7a10)
  (gdb) xtype
  Lisp_Vectorlike
  PVEC_BUFFER

Here, the value 0x1115b968 was taken from the first member of
Vframe_list shown above; it will be different in your case.  The
results in my case are that the ->contents field of the window is a
buffer, as expected.  But in your case, for one of the frames in the
list the ->contents field will be something other than a buffer, which
is what triggers the assertion.  So keep typing the above commands for
every frame in the Vframe_list list until you get to the problematic
frame.  (It would be easier to do all this using the frame pointer in
the local variable 'f', but since you are using an optimized build,
that variable is "optimized out" (which is a GDB euphemism for "I
don't know where its value is stored"), so we cannot use that.)

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76427; Package emacs. (Thu, 20 Feb 2025 08:38:02 GMT) Full text and rfc822 format available.

Message #11 received at 76427 <at> debbugs.gnu.org (full text, mbox):

From: Gregor Zattler <telegraph <at> gmx.net>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 76427 <at> debbugs.gnu.org
Subject: Re: bug#76427: 31.0.50; feature/igc: terminate_due_to_signal
 (sig=sig <at> entry=6, backtrace_limit=backtrace_limit <at> entry=2147483647) at
 ./src/emacs.c:425
Date: Thu, 20 Feb 2025 09:36:46 +0100
Hi Eli, Emacs developers,
* Eli Zaretskii <eliz <at> gnu.org> [2025-02-20; 09:05 +02]:
>> Date: Thu, 20 Feb 2025 00:18:54 +0100
>> From:  Gregor Zattler via "Bug reports for GNU Emacs,
>>  the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
>>
>> Dear Emacs developers, while working
>> with org-noter and pdf-tools, Emacs
>> crashed.
>
> It isn't a crash, it's an assertion violation, here:
>
>       FOR_EACH_FRAME (tail, frame)
> 	{
> 	  struct frame *f = XFRAME (frame);
> 	  struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
> 	  if (some_windows
> 	      && !f->redisplay
> 	      && !w->redisplay
> 	      && !XBUFFER (w->contents)->text->redisplay) <<<<<<<<<<<<<<<<
> 	    continue;
>
>> I would not know how to reproduce.
>
> Like so:
[...]

Thanks for your detailed explanations.
Sadly the Laptop turned off, therefore
the GDB session is no more.

I'm sorry to have caused extra work.

Ciao; Gregor
--
 -... --- .-. . -.. ..--.. ...-.-




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76427; Package emacs. (Thu, 20 Feb 2025 11:50:02 GMT) Full text and rfc822 format available.

Message #14 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> protonmail.com>
To: bug-gnu-emacs <at> gnu.org, 76427 <at> debbugs.gnu.org,
 Gregor Zattler <telegraph <at> gmx.net>
Subject: Re: bug#76427: 31.0.50;
 feature/igc: terminate_due_to_signal (sig=sig <at> entry=6,
 backtrace_limit=backtrace_limit <at> entry=2147483647) at ./src/emacs.c:425
Date: Thu, 20 Feb 2025 11:49:18 +0000
"Gregor Zattler via \"Bug reports for GNU Emacs, the Swiss army knife of text editors\"" <bug-gnu-emacs <at> gnu.org> writes:

> Dear Emacs developers, while working
> with org-noter and pdf-tools, Emacs
> crashed.
>
> I would not know how to reproduce.
>
> The session is still in GDB but only
> till 15:00 Berlin local time.
>
> Till then I will try to answer
> operationalised questions regarding this
> session.
>
> First information regarding this build
> and configuration, below that you'll
> find GDB output.
>
> HTH, Gregor
>
>
> In GNU Emacs 31.0.50 (build 5,
>  x86_64-pc-linux-gnu, cairo version
>  1.16.0) of 2025-02-16 built on no
> Repository revision: 69a10f10de51a448a71c8cc8947f85f3902c894e

It's unlikely, but the specpdl fix in
17fae285d5126d3d7c1462ea469eddc996e3cc5c may have fixed this crash,
too.  Please try rebuilding with a more recent version, and ensure you
generate a core file (using the gdb command "gcore") before you close
the session.  It's not as good as a live session, but it will allow us
to inspect the data.

Pip





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76427; Package emacs. (Thu, 20 Feb 2025 11:50:03 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76427; Package emacs. (Sat, 22 Feb 2025 16:23:02 GMT) Full text and rfc822 format available.

Message #20 received at 76427 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> protonmail.com>
To: 76427 <at> debbugs.gnu.org, Gregor Zattler <telegraph <at> gmx.net>
Subject: Re: bug#76427: 31.0.50;
 feature/igc: terminate_due_to_signal (sig=sig <at> entry=6,
 backtrace_limit=backtrace_limit <at> entry=2147483647) at ./src/emacs.c:425
Date: Sat, 22 Feb 2025 16:22:42 +0000
"Gregor Zattler via \"Bug reports for GNU Emacs, the Swiss army knife of text editors\"" <bug-gnu-emacs <at> gnu.org> writes:

> Dear Emacs developers, while working
> with org-noter and pdf-tools, Emacs
> crashed.

Do you still have the Emacs binary?  I understand you no longer have the
session or the coredump file, but I have a theory...

>         local_getcjmp = {{
>             __jmpbuf = {140736179668459, 140736179668456, 140737488340880, 93824995807319, 140736306686045, 0, 140737098294339, 56448},
>             __mask_was_saved = -14448,
>             __saved_mask = {
>               __val = {0, 56448, 0, 140736179668459, 140736179668456, 140737488340976, 93824995807319, 56448, 8589920320, 140737488340976, 0, 56448, 140737488341056, 140736568339357, 140737049900221, 140737488341248}
>             }
>           }}
>         save_jump = {{
>             __jmpbuf = {140737049900221, 93824995844760, 140737049900216, 140737488341104, 140737049900216, 0, 0, 93824995067072},
                                                           ^^^^^^^^^^^^^^^                   ^^^^^^^^^^^^^^^

This pointer appears twice in save_jump, but it doesn't appear in
local_getcjmp.  IIUC, that means that it's temporarily stored in
main_thread.s.m_getcjmp, but I don't see how the pointers in m_getcjmp
are protected from GC.

We've changed the other jmp_bufs to be allocated using
igc_xzalloc_ambig, but not this one.  (return_to_command_loop should be
similarly protected, as should xterm.c's x_dnd_disconnect_handler.  The
nativecomp code seems fine as it goes through push_handler).

Maybe I'm missing something, but I think that means some callee-saved
registers can be resurrected from main_thread.s.m_getcjmp but weren't
traced in the meantime.

I think while everything works fine without any inlining, aggressive
inlining may make GCC reuse the stack space for the stack copy of the
jump buffer, leaving only the heap copy.

This problem should affect MPS builds, Emacs 29 builds, and master
builds equally, and it may very well be related to bug#76327, which has
this suspicious error report in its valgrind logs:

==1884847== Invalid read of size 8
==1884847==    at 0x48536DF: memmove (vg_replace_strmem.c:1414)
==1884847==    by 0x34EC86: do_one_unbind (eval.c:3636)
==1884847==    by 0x34EC86: unbind_to (eval.c:3764)
==1884847==    by 0x2C4376: read_char (keyboard.c:2725)
==1884847==    by 0x2C646C: read_key_sequence (keyboard.c:10084)
==1884847==    by 0x2C8525: command_loop_1 (keyboard.c:1384)
==1884847==    by 0x34D785: internal_condition_case (eval.c:1474)
==1884847==    by 0x2B273E: command_loop_2 (keyboard.c:1133)
==1884847==    by 0x34D6D7: internal_catch (eval.c:1197)
==1884847==    by 0x2B26C4: command_loop (keyboard.c:1111)
==1884847==    by 0x2BA460: recursive_edit_1 (keyboard.c:720)
==1884847==    by 0x2BA83C: Frecursive_edit (keyboard.c:803)
==1884847==    by 0x1720E5: main (emacs.c:2521)
==1884847==  Address 0x1ffeffef70 is on thread 1's stack
==1884847==  136 bytes below stack pointer

indicating that read_char restored a jump buffer from stack space that
was no longer reserved.

> +i reg
> rax            0x42                66
> rbx            0x555555606a60      93824992963168
> rcx            0x0                 0
> rdx            0x0                 0
> rsi            0x7fffffff          2147483647
> rdi            0x6                 6
> rbp            0x7fffffffaf80      0x7fffffffaf80
> rsp            0x7fffffffaf78      0x7fffffffaf78
> r8             0x0                 0
> r9             0x73                115
> r10            0x0                 0
> r11            0x202               514
> r12            0x555555671790      93824993400720
> r13            0x7fffe5ddb4b8      140737049900216
                                     ^^^^^^^^^^^^^^^

And here's the pointer again, restored in a callee-saved register.

Gregor, can you please disassemble these functions in your Emacs binary
(please use disass/s if it works, as that makes reading the code
easier):

disass/s read_char
disass/s prepare_menu_bars
disass/s 0x00005555555a4270,0x00005555555a4470
disass/s 0x00005555555a0ada,0x00005555555a0cda

While the bug is tricky and potentially happens only very rarely, with
strange GCC optimization/hardening options, the fix is simple enough,
and should be totally harmless if applied but unnecessary (Famous Last
Words, I know).

Maybe it's a good idea to look at this for Emacs 30.

The one major side effect of the fix is that the thread structure would
no longer require 16-byte alignment on win64, reducing LISP_ALIGNMENT to
8 rather than 16, and saving 4 bytes on average per vector on that
platform.  However, it's possible some other place or module relies on
the larger LISP_ALIGNMENt on this platform....

Pip





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76427; Package emacs. (Sat, 22 Feb 2025 22:18:01 GMT) Full text and rfc822 format available.

Message #23 received at 76427 <at> debbugs.gnu.org (full text, mbox):

From: Gregor Zattler <telegraph <at> gmx.net>
To: Pip Cet <pipcet <at> protonmail.com>, 76427 <at> debbugs.gnu.org
Subject: Re: bug#76427: 31.0.50; feature/igc: terminate_due_to_signal
 (sig=sig <at> entry=6, backtrace_limit=backtrace_limit <at> entry=2147483647) at
 ./src/emacs.c:425
Date: Sat, 22 Feb 2025 23:16:38 +0100
Hi Pip,
* Pip Cet <pipcet <at> protonmail.com> [2025-02-22; 16:22 GMT]:
> "Gregor Zattler via \"Bug reports for GNU Emacs, the Swiss army knife of text editors\"" <bug-gnu-emacs <at> gnu.org> writes:
>
>> Dear Emacs developers, while working
>> with org-noter and pdf-tools, Emacs
>> crashed.
>
> Do you still have the Emacs binary?  I understand you no longer have the
> session or the coredump file, but I have a theory...

I should be able to find it in my
backups but on Tuesday earliest.

Will report in a few days.

Ciao; Gregor




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76427; Package emacs. (Tue, 25 Feb 2025 18:54:01 GMT) Full text and rfc822 format available.

Message #26 received at 76427 <at> debbugs.gnu.org (full text, mbox):

From: Gregor Zattler <telegraph <at> gmx.net>
To: Pip Cet <pipcet <at> protonmail.com>, 76427 <at> debbugs.gnu.org
Subject: Re: bug#76427: 31.0.50; feature/igc: terminate_due_to_signal
 (sig=sig <at> entry=6, backtrace_limit=backtrace_limit <at> entry=2147483647) at
 ./src/emacs.c:425
Date: Tue, 25 Feb 2025 19:53:09 +0100
Hi Pip,
* Pip Cet <pipcet <at> protonmail.com> [2025-02-22; 16:22 GMT]:
> "Gregor Zattler via \"Bug reports for GNU Emacs, the Swiss army knife of text editors\"" <bug-gnu-emacs <at> gnu.org> writes:
>
>> Dear Emacs developers, while working
>> with org-noter and pdf-tools, Emacs
>> crashed.
>
> Do you still have the Emacs binary?  I understand you no longer have the
> session or the coredump file, but I have a theory...
>
>>         local_getcjmp = {{
>>             __jmpbuf = {140736179668459, 140736179668456, 140737488340880, 93824995807319, 140736306686045, 0, 140737098294339, 56448},
>>             __mask_was_saved = -14448,
>>             __saved_mask = {
>>               __val = {0, 56448, 0, 140736179668459, 140736179668456, 140737488340976, 93824995807319, 56448, 8589920320, 140737488340976, 0, 56448, 140737488341056, 140736568339357, 140737049900221, 140737488341248}
>>             }
>>           }}
>>         save_jump = {{
>>             __jmpbuf = {140737049900221, 93824995844760, 140737049900216, 140737488341104, 140737049900216, 0, 0, 93824995067072},
>                                                            ^^^^^^^^^^^^^^^                   ^^^^^^^^^^^^^^^
>
> This pointer appears twice in save_jump, but it doesn't appear in
> local_getcjmp.  IIUC, that means that it's temporarily stored in
> main_thread.s.m_getcjmp, but I don't see how the pointers in m_getcjmp
> are protected from GC.
>
> We've changed the other jmp_bufs to be allocated using
> igc_xzalloc_ambig, but not this one.  (return_to_command_loop should be
> similarly protected, as should xterm.c's x_dnd_disconnect_handler.  The
> nativecomp code seems fine as it goes through push_handler).
>
> Maybe I'm missing something, but I think that means some callee-saved
> registers can be resurrected from main_thread.s.m_getcjmp but weren't
> traced in the meantime.
>
> I think while everything works fine without any inlining, aggressive
> inlining may make GCC reuse the stack space for the stack copy of the
> jump buffer, leaving only the heap copy.
>
> This problem should affect MPS builds, Emacs 29 builds, and master
> builds equally, and it may very well be related to bug#76327, which has
> this suspicious error report in its valgrind logs:
>
> ==1884847== Invalid read of size 8
> ==1884847==    at 0x48536DF: memmove (vg_replace_strmem.c:1414)
> ==1884847==    by 0x34EC86: do_one_unbind (eval.c:3636)
> ==1884847==    by 0x34EC86: unbind_to (eval.c:3764)
> ==1884847==    by 0x2C4376: read_char (keyboard.c:2725)
> ==1884847==    by 0x2C646C: read_key_sequence (keyboard.c:10084)
> ==1884847==    by 0x2C8525: command_loop_1 (keyboard.c:1384)
> ==1884847==    by 0x34D785: internal_condition_case (eval.c:1474)
> ==1884847==    by 0x2B273E: command_loop_2 (keyboard.c:1133)
> ==1884847==    by 0x34D6D7: internal_catch (eval.c:1197)
> ==1884847==    by 0x2B26C4: command_loop (keyboard.c:1111)
> ==1884847==    by 0x2BA460: recursive_edit_1 (keyboard.c:720)
> ==1884847==    by 0x2BA83C: Frecursive_edit (keyboard.c:803)
> ==1884847==    by 0x1720E5: main (emacs.c:2521)
> ==1884847==  Address 0x1ffeffef70 is on thread 1's stack
> ==1884847==  136 bytes below stack pointer
>
> indicating that read_char restored a jump buffer from stack space that
> was no longer reserved.
>
>> +i reg
>> rax            0x42                66
>> rbx            0x555555606a60      93824992963168
>> rcx            0x0                 0
>> rdx            0x0                 0
>> rsi            0x7fffffff          2147483647
>> rdi            0x6                 6
>> rbp            0x7fffffffaf80      0x7fffffffaf80
>> rsp            0x7fffffffaf78      0x7fffffffaf78
>> r8             0x0                 0
>> r9             0x73                115
>> r10            0x0                 0
>> r11            0x202               514
>> r12            0x555555671790      93824993400720
>> r13            0x7fffe5ddb4b8      140737049900216
>                                      ^^^^^^^^^^^^^^^
>
> And here's the pointer again, restored in a callee-saved register.
>
> Gregor, can you please disassemble these functions in your Emacs binary
> (please use disass/s if it works, as that makes reading the code
> easier):
>
> disass/s read_char
> disass/s prepare_menu_bars
> disass/s 0x00005555555a4270,0x00005555555a4470
> disass/s 0x00005555555a0ada,0x00005555555a0cda
>
> While the bug is tricky and potentially happens only very rarely, with
> strange GCC optimization/hardening options, the fix is simple enough,
> and should be totally harmless if applied but unnecessary (Famous Last
> Words, I know).
>
> Maybe it's a good idea to look at this for Emacs 30.
>
> The one major side effect of the fix is that the thread structure would
> no longer require 16-byte alignment on win64, reducing LISP_ALIGNMENT to
> 8 rather than 16, and saving 4 bytes on average per vector on that
> platform.  However, it's possible some other place or module relies on
> the larger LISP_ALIGNMENt on this platform....


I started the binary in question as
usual as a daemon, opened a graphical
frame, opened the PDF with org-noter and
pdf-tools, then killed the Emacs process
in order to be able to feed in the
commands you gave.  This is the result:


Starting program: /home/grfz/src/emacs-igc/src/emacs --debug-init -xrm --init-directory="${USER_EMACS_DIRECTORY}" --fg-daemon="${EMACS_SERVER_NAME}"
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[Detaching after vfork from child process 737973]
[Detaching after vfork from child process 737974]
[Detaching after vfork from child process 737975]
[Detaching after vfork from child process 737976]
[Detaching after vfork from child process 737977]
[Detaching after vfork from child process 737979]
[Detaching after vfork from child process 737986]
[Detaching after vfork from child process 737987]
[Detaching after vfork from child process 738065]

Program received signal SIGSEGV, Segmentation fault.

Program received signal SIGSEGV, Segmentation fault.

Program received signal SIGSEGV, Segmentation fault.

Program received signal SIGSEGV, Segmentation fault.
[Detaching after vfork from child process 738069]
[Detaching after vfork from child process 738070]
[Detaching after vfork from child process 738071]
[Detaching after vfork from child process 738072]
[Detaching after vfork from child process 738073]
[Detaching after vfork from child process 738074]
[Detaching after vfork from child process 738079]
[Detaching after vfork from child process 738080]
[Detaching after vfork from child process 738081]
[Detaching after vfork from child process 738082]
[Detaching after vfork from child process 738083]
[Detaching after vfork from child process 738084]
[Detaching after vfork from child process 738085]
[Detaching after vfork from child process 738086]
[Detaching after vfork from child process 738087]
[Detaching after vfork from child process 738088]
[Detaching after vfork from child process 738089]
[Detaching after vfork from child process 738090]
[Detaching after vfork from child process 738091]
[Detaching after vfork from child process 738092]
[Detaching after vfork from child process 738093]
[Detaching after vfork from child process 738094]

Program received signal SIGSEGV, Segmentation fault.

[... 2733 lines deleted ...]

Program received signal SIGSEGV, Segmentation fault.
[Detaching after vfork from child process 738099]
[Detaching after vfork from child process 738100]
[Detaching after vfork from child process 738105]
[Detaching after vfork from child process 738109]
[Detaching after vfork from child process 738113]
[Detaching after vfork from child process 738395]
[Detaching after vfork from child process 738520]
[Detaching after vfork from child process 738634]
[Detaching after vfork from child process 738694]
[Detaching after vfork from child process 738698]
[Detaching after vfork from child process 738702]
[Detaching after vfork from child process 738708]
[Detaching after vfork from child process 738709]
[Detaching after vfork from child process 738711]
[Detaching after vfork from child process 738713]
[Detaching after vfork from child process 738714]
[Detaching after vfork from child process 738715]
[Detaching after vfork from child process 738716]
[Detaching after vfork from child process 738720]
[Detaching after vfork from child process 738725]
[Detaching after vfork from child process 738749]
[Detaching after vfork from child process 738758]

Program received signal SIGTERM, Terminated.
0x00007ffff3dbea5c in pselect () from /lib/x86_64-linux-gnu/libc.so.6
Dump of assembler code for function read_char:
Address range 0x555555778850 to 0x55555577d122:
./src/keyboard.c:
2530	{
   0x0000555555778850 <+0>:	push   %rbp
   0x0000555555778851 <+1>:	mov    %rsp,%rbp
   0x0000555555778854 <+4>:	push   %r15
   0x0000555555778856 <+6>:	push   %r14
   0x0000555555778858 <+8>:	push   %r13
   0x000055555577885a <+10>:	push   %r12
   0x000055555577885c <+12>:	push   %rbx
   0x000055555577885d <+13>:	sub    $0x668,%rsp
   0x0000555555778864 <+20>:	mov    %rsi,-0x4b0(%rbp)
   0x000055555577886b <+27>:	mov    %rdx,-0x4c0(%rbp)
   0x0000555555778872 <+34>:	mov    %rcx,-0x4d0(%rbp)
   0x0000555555778879 <+41>:	mov    %r8,-0x4a8(%rbp)
   0x0000555555778880 <+48>:	mov    %fs:0x28,%rax
   0x0000555555778889 <+57>:	mov    %rax,-0x38(%rbp)
   0x000055555577888d <+61>:	xor    %eax,%eax

2531	  Lisp_Object c;
2532	  sys_jmp_buf local_getcjmp;
2533	  sys_jmp_buf save_jump;
2534	  Lisp_Object tem, save;
2535	  volatile Lisp_Object previous_echo_area_message;
2536	  volatile Lisp_Object also_record;
2537	  volatile bool reread, recorded;
2538	  bool volatile polling_stopped_here = false;
   0x000055555577888f <+63>:	mov    0x38d9ca(%rip),%rax        # 0x555555b06260 <current_kboard>
   0x0000555555778896 <+70>:	movb   $0x0,-0x485(%rbp)

2539	  struct kboard *orig_kboard = current_kboard;
   0x000055555577889d <+77>:	mov    %edi,-0x4dc(%rbp)
   0x00005555557788a3 <+83>:	mov    %rax,-0x4c8(%rbp)

2540
2541	  also_record = Qnil;
   0x00005555557788aa <+90>:	lea    0x2(%rdi),%eax

2864		}
2865	    }
2866
2867	  /* Maybe auto save due to number of keystrokes.  */
2868
2869	  if (commandflag != 0 && commandflag != -2
   0x00005555557788ad <+93>:	movq   $0x0,-0x478(%rbp)

./src/lisp.h:
1198	  return make_lisp_symbol_internal (&lispsym[index]);
   0x00005555557788b8 <+104>:	and    $0xfffffffd,%eax
   0x00005555557788bb <+107>:	mov    %eax,-0x4b4(%rbp)

/usr/include/x86_64-linux-gnu/bits/string_fortified.h:
29	  return __builtin___memcpy_chk (__dest, __src, __len,
   0x00005555557788c1 <+113>:	lea    -0x170(%rbp),%rax
   0x00005555557788c8 <+120>:	movq   $0x0,-0x480(%rbp)
   0x00005555557788d3 <+131>:	mov    %rax,-0x4d8(%rbp)

./src/keyboard.c:
2548	  recorded = false;
   0x00005555557788da <+138>:	mov    0x3a87a7(%rip),%rax        # 0x555555b21088 <globals+3144>
   0x00005555557788e1 <+145>:	movb   $0x0,-0x486(%rbp)

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x00005555557788e8 <+152>:	lea    -0x3(%rax),%edx

./src/keyboard.c:
2550	  if (CONSP (Vunread_post_input_method_events))
   0x00005555557788eb <+155>:	and    $0x7,%edx
   0x00005555557788ee <+158>:	je     0x555555778ac0 <read_char+624>

2565	    }
2566	  else
2567	    reread = false;
   0x00005555557788f4 <+164>:	mov    0x3a877d(%rip),%rax        # 0x555555b21078 <globals+3128>
   0x00005555557788fb <+171>:	movb   $0x0,-0x487(%rbp)

2568
2569	  Vlast_event_device = Qnil;
   0x0000555555778902 <+178>:	movq   $0x0,0x3a8183(%rip)        # 0x555555b20a90 <globals+1616>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577890d <+189>:	lea    -0x3(%rax),%edx

./src/keyboard.c:
2571	  if (CONSP (Vunread_command_events))
   0x0000555555778910 <+192>:	and    $0x7,%edx
   0x0000555555778913 <+195>:	je     0x555555778b88 <read_char+824>

2611
2612	      goto reread_for_input_method;
2613	    }
2614
2615	  if (CONSP (Vunread_input_method_events))
   0x0000555555778919 <+201>:	mov    0x3a8760(%rip),%rax        # 0x555555b21080 <globals+3136>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555778920 <+208>:	lea    -0x3(%rax),%edx

./src/keyboard.c:
2615	  if (CONSP (Vunread_input_method_events))
   0x0000555555778923 <+211>:	and    $0x7,%edx
   0x0000555555778926 <+214>:	je     0x555555778c40 <read_char+1008>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577892c <+220>:	cmpq   $0x0,0x3a7efc(%rip)        # 0x555555b20830 <globals+1008>
   0x0000555555778934 <+228>:	je     0x555555778a00 <read_char+432>

./src/keyboard.c:
2631	  if (!NILP (Vexecuting_kbd_macro) && !at_end_of_macro_p ())
   0x000055555577893a <+234>:	call   0x555555784f40 <at_end_of_macro_p>
   0x000055555577893f <+239>:	test   %al,%al
   0x0000555555778941 <+241>:	jne    0x555555778a00 <read_char+432>

2632	    {
2633	      /* We set this to Qmacro; since that's not a frame, nobody will
2634		 try to switch frames on us, and the selected window will
2635		 remain unchanged.
2636
2637	         Since this event came from a macro, it would be misleading to
2638		 leave internal_last_event_frame set to wherever the last
2639		 real event came from.  Normally, a switch-frame event selects
2640		 internal_last_event_frame after each command is read, but
2641		 events read from a macro should never cause a new frame to be
2642		 selected.  */
2643	      Vlast_event_frame = internal_last_event_frame = Qmacro;
   0x0000555555778947 <+247>:	mov    0x3a8ada(%rip),%rdi        # 0x555555b21428 <globals+4072>

./src/lisp.h:
3285	  return FIXNUM_OVERFLOW_P (n) ? make_bigint (n) : make_fixnum (n);
   0x000055555577894e <+254>:	movabs $0x2000000000000000,%rax

./src/keyboard.c:
2643	      Vlast_event_frame = internal_last_event_frame = Qmacro;
   0x0000555555778958 <+264>:	movq   $0xeb28,0x38d7c5(%rip)        # 0x555555b06128 <internal_last_event_frame>
   0x0000555555778963 <+275>:	movq   $0xeb28,0x3a812a(%rip)        # 0x555555b20a98 <globals+1624>

./src/lisp.h:
3285	  return FIXNUM_OVERFLOW_P (n) ? make_bigint (n) : make_fixnum (n);
   0x000055555577896e <+286>:	add    %rdi,%rax

1232	  return lisp_h_make_fixnum_wrap (n);
   0x0000555555778971 <+289>:	lea    0x2(,%rdi,4),%rsi

3279	}
3280
3281	/* Return a Lisp integer with value taken from N.  */
3282	INLINE Lisp_Object
3283	make_int (intmax_t n)
3284	{
3285	  return FIXNUM_OVERFLOW_P (n) ? make_bigint (n) : make_fixnum (n);
   0x0000555555778979 <+297>:	shr    $0x3e,%rax
   0x000055555577897d <+301>:	jne    0x55555577be93 <read_char+13891>

./src/keyboard.c:
2645	      c = Faref (Vexecuting_kbd_macro, make_int (executing_kbd_macro_index));
   0x0000555555778983 <+307>:	mov    0x3a7ea6(%rip),%rdi        # 0x555555b20830 <globals+1008>
   0x000055555577898a <+314>:	call   0x5555558046f0 <Faref>
   0x000055555577898f <+319>:	mov    %rax,%r14

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555778992 <+322>:	mov    0x3a7e98(%rip),%eax        # 0x555555b20830 <globals+1008>
   0x0000555555778998 <+328>:	sub    $0x4,%eax

./src/keyboard.c:
2646	      if (STRINGP (Vexecuting_kbd_macro)
   0x000055555577899b <+331>:	test   $0x7,%al
   0x000055555577899d <+333>:	je     0x55555577b430 <read_char+11232>
   0x00005555557789a3 <+339>:	mov    %r14,%rbx

2649
2650	      executing_kbd_macro_index++;
   0x00005555557789a6 <+342>:	addq   $0x1,0x3a8a7a(%rip)        # 0x555555b21428 <globals+4072>

2651
2652	      goto from_macro;
   0x00005555557789ae <+350>:	lea    -0x2(%rbx),%r12d

./src/lisp.h:
1310	  return lisp_h_FIXNUMP (x);
   0x00005555557789b2 <+354>:	and    $0x3,%r12d
   0x00005555557789b6 <+358>:	cs nopw 0x0(%rax,%rax,1)

740	  return lisp_h_XLI (o);
   0x00005555557789c0 <+368>:	test   %r12d,%r12d
   0x00005555557789c3 <+371>:	jne    0x5555557789dd <read_char+397>
   0x00005555557789c5 <+373>:	cmpq   $0x0,0x3a8043(%rip)        # 0x555555b20a10 <globals+1488>
   0x00005555557789cd <+381>:	je     0x5555557789dd <read_char+397>

./src/keyboard.c:
3231	      && NILP (prev_event)
   0x00005555557789cf <+383>:	cmpq   $0x0,-0x4c0(%rbp)
   0x00005555557789d7 <+391>:	je     0x55555577af0d <read_char+9917>

3303	    }
3304	  /* When we consume events from the various unread-*-events lists, we
3305	     bypass the code that records input, so record these events now if
3306	     they were not recorded already.  */
3307	  if (!recorded)
   0x00005555557789dd <+397>:	movzbl -0x486(%rbp),%eax
   0x00005555557789e4 <+404>:	test   %al,%al
   0x00005555557789e6 <+406>:	je     0x55555577a7b6 <read_char+8038>

./src/lisp.h:
774	  return lisp_h_TAGGEDP (a, tag);
   0x00005555557789ec <+412>:	lea    -0x3(%r14),%eax
   0x00005555557789f0 <+416>:	mov    %r14,%r12
   0x00005555557789f3 <+419>:	and    $0x7,%eax
   0x00005555557789f6 <+422>:	jmp    0x555555778a30 <read_char+480>
   0x00005555557789f8 <+424>:	nopl   0x0(%rax,%rax,1)

./src/keyboard.c:
2655	  if (!NILP (unread_switch_frame))
   0x0000555555778a00 <+432>:	mov    0x38d741(%rip),%r12        # 0x555555b06148 <unread_switch_frame>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555778a07 <+439>:	test   %r12,%r12
   0x0000555555778a0a <+442>:	je     0x555555778cd2 <read_char+1154>

./src/keyboard.c:
2657	      c = unread_switch_frame;
   0x0000555555778a10 <+448>:	movq   $0x0,0x38d72d(%rip)        # 0x555555b06148 <unread_switch_frame>

./src/lisp.h:
774	  return lisp_h_TAGGEDP (a, tag);
   0x0000555555778a1b <+459>:	lea    -0x3(%r12),%eax

./src/keyboard.c:
2657	      c = unread_switch_frame;
   0x0000555555778a20 <+464>:	mov    %r12,%r14

2658	      unread_switch_frame = Qnil;
2659
2660	      /* This event should make it into this_command_keys, and get echoed
2661		 again, so we do not set `reread'.  */
2662	      goto reread_first;
   0x0000555555778a23 <+467>:	and    $0x7,%eax
   0x0000555555778a26 <+470>:	cs nopw 0x0(%rax,%rax,1)

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555778a30 <+480>:	test   %eax,%eax
   0x0000555555778a32 <+482>:	jne    0x555555778ae9 <read_char+665>

1517	  igc_check_fwd (c, false);
1518	  return c;
   0x0000555555778a38 <+488>:	mov    0x5(%r12),%rdi

./src/keyboard.c:
3316	  if (CONSP (c) && EQ (XCAR (c), Qhelp_echo))
   0x0000555555778a3d <+493>:	mov    $0xc208,%esi
   0x0000555555778a42 <+498>:	call   0x555555764470 <EQ>
   0x0000555555778a47 <+503>:	test   %al,%al
   0x0000555555778a49 <+505>:	jne    0x55555577ab81 <read_char+9009>

3336	    }
3337
3338	  if ((! reread || this_command_key_count == 0)
   0x0000555555778a4f <+511>:	movzbl -0x487(%rbp),%eax
   0x0000555555778a56 <+518>:	test   %al,%al
   0x0000555555778a58 <+520>:	jne    0x55555577ab68 <read_char+8984>

3339	      && !end_time)
   0x0000555555778a5e <+526>:	cmpq   $0x0,-0x4a8(%rbp)
   0x0000555555778a66 <+534>:	jne    0x555555778b06 <read_char+694>

./src/lisp.h:
1184	  return a;
   0x0000555555778a6c <+540>:	mov    %r14,%rdi
   0x0000555555778a6f <+543>:	call   0x555555763090 <XCAR>

./src/keyboard.c:
3344		     && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement)))
   0x0000555555778a74 <+548>:	mov    $0x9338,%esi
   0x0000555555778a79 <+553>:	mov    %rax,%rdi
   0x0000555555778a7c <+556>:	call   0x555555838da0 <Fget>
   0x0000555555778a81 <+561>:	mov    $0xfe68,%esi
   0x0000555555778a86 <+566>:	mov    %rax,%rdi
   0x0000555555778a89 <+569>:	call   0x555555764470 <EQ>

3343	      if (! (EVENT_HAS_PARAMETERS (c)
   0x0000555555778a8e <+574>:	test   %al,%al
   0x0000555555778a90 <+576>:	je     0x555555779084 <read_char+2100>

3348
3349	      /* Record this character as part of the current key.  */
3350	      add_command_key (c);
   0x0000555555778a96 <+582>:	mov    %r14,%rdi
   0x0000555555778a99 <+585>:	call   0x555555764930 <add_command_key>

3351	      if (! NILP (also_record))
   0x0000555555778a9e <+590>:	mov    -0x478(%rbp),%rax
   0x0000555555778aa5 <+597>:	test   %rax,%rax
   0x0000555555778aa8 <+600>:	je     0x555555778ab6 <read_char+614>

3352		add_command_key (also_record);
   0x0000555555778aaa <+602>:	mov    -0x478(%rbp),%rdi
   0x0000555555778ab1 <+609>:	call   0x555555764930 <add_command_key>

3353
3354	      echo_update ();
   0x0000555555778ab6 <+614>:	call   0x555555767920 <echo_update>
   0x0000555555778abb <+619>:	jmp    0x555555778b06 <read_char+694>
   0x0000555555778abd <+621>:	nopl   (%rax)

./src/lisp.h:
1518	  return c;
   0x0000555555778ac0 <+624>:	mov    0x5(%rax),%r14

1516	  struct Lisp_Cons *c = XUNTAG (a, Lisp_Cons, struct Lisp_Cons);
   0x0000555555778ac4 <+628>:	sub    $0x3,%rax

./src/keyboard.c:
2554		= XCDR (Vunread_post_input_method_events);
   0x0000555555778ac8 <+632>:	mov    0x10(%rax),%rax
   0x0000555555778acc <+636>:	mov    %r14,%r12

./src/lisp.h:
1550	  return lisp_h_XCDR (c);
   0x0000555555778acf <+639>:	mov    %rax,0x3a85b2(%rip)        # 0x555555b21088 <globals+3144>

740	  return lisp_h_XLI (o);
   0x0000555555778ad6 <+646>:	lea    -0x3(%r14),%eax

./src/keyboard.c:
2558	      if (CONSP (c)
   0x0000555555778ada <+650>:	test   $0x7,%al
   0x0000555555778adc <+652>:	je     0x555555778bfa <read_char+938>

2562
2563	      reread = true;
   0x0000555555778ae2 <+658>:	movb   $0x1,-0x487(%rbp)

3336	    }
3337
3338	  if ((! reread || this_command_key_count == 0)
   0x0000555555778ae9 <+665>:	movzbl -0x487(%rbp),%eax
   0x0000555555778af0 <+672>:	test   %al,%al
   0x0000555555778af2 <+674>:	jne    0x555555779070 <read_char+2080>

3339	      && !end_time)
   0x0000555555778af8 <+680>:	cmpq   $0x0,-0x4a8(%rbp)
   0x0000555555778b00 <+688>:	je     0x555555779084 <read_char+2100>

3355	    }
3356
3357	  last_input_event = c;
   0x0000555555778b06 <+694>:	addq   $0x1,0x38d632(%rip)        # 0x555555b06140 <num_input_events>

3358	  num_input_events++;
3359
3360	  /* Process the help character specially if enabled.  */
3361	  if (!NILP (Vhelp_form) && help_char_p (c))
   0x0000555555778b0e <+702>:	cmpq   $0x0,0x3a7e42(%rip)        # 0x555555b20958 <globals+1304>

3357	  last_input_event = c;
   0x0000555555778b16 <+710>:	mov    %r14,0x3a886b(%rip)        # 0x555555b21388 <globals+3912>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555778b1d <+717>:	je     0x555555778b30 <read_char+736>

./src/keyboard.c:
3361	  if (!NILP (Vhelp_form) && help_char_p (c))
   0x0000555555778b1f <+719>:	mov    %r14,%rdi
   0x0000555555778b22 <+722>:	call   0x555555766240 <help_char_p>
   0x0000555555778b27 <+727>:	test   %al,%al
   0x0000555555778b29 <+729>:	jne    0x55555577a8c0 <read_char+8304>
   0x0000555555778b2f <+735>:	nop

3390		  while (BUFFERP (c));
3391		}
3392	    }
3393
3394	 exit:
3395	  RESUME_POLLING;
   0x0000555555778b30 <+736>:	movzbl -0x485(%rbp),%eax
   0x0000555555778b37 <+743>:	test   %al,%al
   0x0000555555778b39 <+745>:	je     0x555555778b48 <read_char+760>

2052	  if (!interrupt_input)
   0x0000555555778b3b <+747>:	cmpb   $0x0,0x34d5b8(%rip)        # 0x555555ac60fa <interrupt_input>
   0x0000555555778b42 <+754>:	je     0x55555577a4e0 <read_char+7312>

3390		  while (BUFFERP (c));
3391		}
3392	    }
3393
3394	 exit:
3395	  RESUME_POLLING;
   0x0000555555778b48 <+760>:	movzbl 0x38d5d2(%rip),%eax        # 0x555555b06121 <input_pending>
   0x0000555555778b4f <+767>:	movb   $0x0,-0x485(%rbp)

3396	  input_was_pending = input_pending;
   0x0000555555778b56 <+774>:	mov    %al,0x38d5c4(%rip)        # 0x555555b06120 <input_was_pending>

3397	  return c;
   0x0000555555778b5c <+780>:	mov    %r14,%rax

3398	}
   0x0000555555778b5f <+783>:	mov    -0x38(%rbp),%rdx
   0x0000555555778b63 <+787>:	sub    %fs:0x28,%rdx
   0x0000555555778b6c <+796>:	jne    0x55555577d05b <read_char+18443>
   0x0000555555778b72 <+802>:	lea    -0x28(%rbp),%rsp
   0x0000555555778b76 <+806>:	pop    %rbx
   0x0000555555778b77 <+807>:	pop    %r12
   0x0000555555778b79 <+809>:	pop    %r13
   0x0000555555778b7b <+811>:	pop    %r14
   0x0000555555778b7d <+813>:	pop    %r15
   0x0000555555778b7f <+815>:	pop    %rbp
   0x0000555555778b80 <+816>:	ret
   0x0000555555778b81 <+817>:	nopl   0x0(%rax)

./src/lisp.h:
1518	  return c;
   0x0000555555778b88 <+824>:	mov    0x5(%rax),%r14

1516	  struct Lisp_Cons *c = XUNTAG (a, Lisp_Cons, struct Lisp_Cons);
   0x0000555555778b8c <+828>:	sub    $0x3,%rax

1545	}
1546
1547	INLINE Lisp_Object
1548	(XCDR) (Lisp_Object c)
1549	{
1550	  return lisp_h_XCDR (c);
   0x0000555555778b90 <+832>:	mov    0x10(%rax),%rax
   0x0000555555778b94 <+836>:	mov    %rax,0x3a84dd(%rip)        # 0x555555b21078 <globals+3128>

740	  return lisp_h_XLI (o);
   0x0000555555778b9b <+843>:	lea    -0x3(%r14),%eax

./src/keyboard.c:
2581	      if (CONSP (c) && EQ (XCAR (c), Qt))
   0x0000555555778b9f <+847>:	test   $0x7,%al
   0x0000555555778ba1 <+849>:	je     0x555555778fac <read_char+1884>

2589		    }
2590		  reread = true;
   0x0000555555778ba7 <+855>:	movb   $0x1,-0x487(%rbp)

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555778bae <+862>:	xor    %ebx,%ebx

./src/keyboard.c:
2605	      if (used_mouse_menu
   0x0000555555778bb0 <+864>:	cmpq   $0x0,-0x4d0(%rbp)
   0x0000555555778bb8 <+872>:	je     0x555555778bea <read_char+922>

./src/lisp.h:
1184	  return a;
   0x0000555555778bba <+874>:	mov    $0x15230,%esi

./src/keyboard.c:
2608		  && (EQ (c, Qtool_bar) || EQ (c, Qtab_bar) || EQ (c, Qmenu_bar)
   0x0000555555778bbf <+879>:	mov    %r14,%rdi
   0x0000555555778bc2 <+882>:	call   0x555555764470 <EQ>
   0x0000555555778bc7 <+887>:	test   %al,%al
   0x0000555555778bc9 <+889>:	jne    0x555555778be0 <read_char+912>

./src/lisp.h:
1184	  return a;
   0x0000555555778bcb <+891>:	mov    $0x14b30,%esi
   0x0000555555778bd0 <+896>:	mov    %r14,%rdi
   0x0000555555778bd3 <+899>:	call   0x555555764470 <EQ>

./src/keyboard.c:
2608		  && (EQ (c, Qtool_bar) || EQ (c, Qtab_bar) || EQ (c, Qmenu_bar)
   0x0000555555778bd8 <+904>:	test   %al,%al
   0x0000555555778bda <+906>:	je     0x55555577b47e <read_char+11310>

2610		*used_mouse_menu = true;
   0x0000555555778be0 <+912>:	mov    -0x4d0(%rbp),%rax
   0x0000555555778be7 <+919>:	movb   $0x1,(%rax)

./src/lisp.h:
1310	  return lisp_h_FIXNUMP (x);
   0x0000555555778bea <+922>:	lea    -0x2(%r14),%r12d

740	  return lisp_h_XLI (o);
   0x0000555555778bee <+926>:	mov    %r14,%rbx

1239	}
1240
1241	INLINE Lisp_Object
1242	make_ufixnum (EMACS_INT n)
1243	{
1244	  eassert (0 <= n && n <= INTMASK);
1245	  return lisp_h_make_fixnum_wrap (n);
1246	}
1247
1248	#else /* ! USE_LSB_TAG */
1249
1250	/* Although compiled only if ! USE_LSB_TAG, the following functions
1251	   also work when USE_LSB_TAG; this is to aid future maintenance when
1252	   the lisp_h_* macros are eventually removed.  */
1253
1254	/* Make a fixnum representing the value of the low order bits of N.  */
1255	INLINE Lisp_Object
1256	make_fixnum (EMACS_INT n)
1257	{
1258	  eassert (! FIXNUM_OVERFLOW_P (n));
1259	  EMACS_INT int0 = Lisp_Int0;
1260	  if (USE_LSB_TAG)
1261	    {
1262	      EMACS_UINT u = n;
1263	      n = u << INTTYPEBITS;
1264	      n += int0;
1265	    }
1266	  else
1267	    {
1268	      n &= INTMASK;
1269	      n += (int0 << VALBITS);
1270	    }
1271	  return XIL (n);
1272	}
1273
1274	/* Extract A's value as a signed integer.  Unlike XFIXNUM, this works
1275	   on any Lisp object, although the resulting integer is useful only
1276	   for things like hashing when A is not a fixnum.  */
1277	INLINE EMACS_INT
1278	XFIXNUM_RAW (Lisp_Object a)
1279	{
1280	  EMACS_INT i = XLI (a);
1281	  if (! USE_LSB_TAG)
1282	    {
1283	      EMACS_UINT u = i;
1284	      i = u << INTTYPEBITS;
1285	    }
1286	  return i >> INTTYPEBITS;
1287	}
1288
1289	INLINE Lisp_Object
1290	make_ufixnum (EMACS_INT n)
1291	{
1292	  eassert (0 <= n && n <= INTMASK);
1293	  EMACS_INT int0 = Lisp_Int0;
1294	  if (USE_LSB_TAG)
1295	    {
1296	      EMACS_UINT u = n;
1297	      n = u << INTTYPEBITS;
1298	      n += int0;
1299	    }
1300	  else
1301	    n += int0 << VALBITS;
1302	  return XIL (n);
1303	}
1304
1305	#endif /* ! USE_LSB_TAG */
1306
1307	INLINE bool
1308	(FIXNUMP) (Lisp_Object x)
1309	{
1310	  return lisp_h_FIXNUMP (x);
   0x0000555555778bf1 <+929>:	and    $0x3,%r12d
   0x0000555555778bf5 <+933>:	jmp    0x5555557789c0 <read_char+368>

1516	  struct Lisp_Cons *c = XUNTAG (a, Lisp_Cons, struct Lisp_Cons);
   0x0000555555778bfa <+938>:	mov    0x5(%r14),%rax
   0x0000555555778bfe <+942>:	lea    -0x3(%r14),%rbx

740	  return lisp_h_XLI (o);
   0x0000555555778c02 <+946>:	test   $0x7,%al
   0x0000555555778c04 <+948>:	je     0x555555778c22 <read_char+978>
   0x0000555555778c06 <+950>:	cmpb   $0x0,0x3a89ec(%rip)        # 0x555555b215f9 <globals+4537>
   0x0000555555778c0d <+957>:	jne    0x55555577b0e5 <read_char+10389>

./src/keyboard.c:
2559		  && (SYMBOLP (XCAR (c)) || FIXNUMP (XCAR (c)))
   0x0000555555778c13 <+963>:	mov    %r14,%rdi
   0x0000555555778c16 <+966>:	call   0x555555763090 <XCAR>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555778c1b <+971>:	sub    $0x2,%eax

./src/keyboard.c:
2559		  && (SYMBOLP (XCAR (c)) || FIXNUMP (XCAR (c)))
   0x0000555555778c1e <+974>:	test   $0x3,%al
   0x0000555555778c20 <+976>:	jne    0x555555778c2d <read_char+989>

./src/lisp.h:
1550	  return lisp_h_XCDR (c);
   0x0000555555778c22 <+978>:	cmpq   $0x0,0x10(%rbx)
   0x0000555555778c27 <+983>:	je     0x55555577bb7c <read_char+13100>

./src/keyboard.c:
2563	      reread = true;
   0x0000555555778c2d <+989>:	movb   $0x1,-0x487(%rbp)

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555778c34 <+996>:	jmp    0x555555778a38 <read_char+488>
   0x0000555555778c39 <+1001>:	nopl   0x0(%rax)

1517	  igc_check_fwd (c, false);
1518	  return c;
   0x0000555555778c40 <+1008>:	mov    0x5(%rax),%r14

1516	  struct Lisp_Cons *c = XUNTAG (a, Lisp_Cons, struct Lisp_Cons);
   0x0000555555778c44 <+1012>:	sub    $0x3,%rax

1545	}
1546
1547	INLINE Lisp_Object
1548	(XCDR) (Lisp_Object c)
1549	{
1550	  return lisp_h_XCDR (c);
   0x0000555555778c48 <+1016>:	mov    0x10(%rax),%rax

740	  return lisp_h_XLI (o);
   0x0000555555778c4c <+1020>:	mov    %r14,%rbx

747	}
748
749	INLINE void *
750	(XLP) (Lisp_Object o)
751	{
752	  return lisp_h_XLP (o);
753	}
754
755	/* Extract A's type.  */
756
757	INLINE enum Lisp_Type
758	(XTYPE) (Lisp_Object a)
759	{
760	#if USE_LSB_TAG
761	  return lisp_h_XTYPE (a);
762	#else
763	  EMACS_UINT i = XLI (a);
764	  return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
765	#endif
766	}
767
768	/* True if A has type tag TAG.
769	   Equivalent to XTYPE (a) == TAG, but often faster.  */
770
771	INLINE bool
772	(TAGGEDP) (Lisp_Object a, enum Lisp_Type tag)
773	{
774	  return lisp_h_TAGGEDP (a, tag);
   0x0000555555778c4f <+1023>:	mov    %r14d,%r12d

./src/keyboard.c:
2618	      Vunread_input_method_events = XCDR (Vunread_input_method_events);
   0x0000555555778c52 <+1026>:	mov    %rax,0x3a8427(%rip)        # 0x555555b21080 <globals+3136>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555778c59 <+1033>:	lea    -0x3(%r14),%eax

./src/keyboard.c:
2622	      if (CONSP (c)
   0x0000555555778c5d <+1037>:	test   $0x7,%al
   0x0000555555778c5f <+1039>:	jne    0x555555778cbe <read_char+1134>

2623		  && (SYMBOLP (XCAR (c)) || FIXNUMP (XCAR (c)))
   0x0000555555778c61 <+1041>:	mov    %r14,%rdi
   0x0000555555778c64 <+1044>:	call   0x555555763090 <XCAR>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555778c69 <+1049>:	test   $0x7,%al
   0x0000555555778c6b <+1051>:	je     0x555555778cad <read_char+1117>
   0x0000555555778c6d <+1053>:	cmpb   $0x0,0x3a8985(%rip)        # 0x555555b215f9 <globals+4537>
   0x0000555555778c74 <+1060>:	je     0x555555778c9e <read_char+1102>

747	}
748
749	INLINE void *
750	(XLP) (Lisp_Object o)
751	{
752	  return lisp_h_XLP (o);
753	}
754
755	/* Extract A's type.  */
756
757	INLINE enum Lisp_Type
758	(XTYPE) (Lisp_Object a)
759	{
760	#if USE_LSB_TAG
761	  return lisp_h_XTYPE (a);
762	#else
763	  EMACS_UINT i = XLI (a);
764	  return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
765	#endif
766	}
767
768	/* True if A has type tag TAG.
769	   Equivalent to XTYPE (a) == TAG, but often faster.  */
770
771	INLINE bool
772	(TAGGEDP) (Lisp_Object a, enum Lisp_Type tag)
773	{
774	  return lisp_h_TAGGEDP (a, tag);
   0x0000555555778c76 <+1062>:	lea    -0x5(%rax),%edx

775	}
776
777	INLINE void
778	(CHECK_TYPE) (int ok, Lisp_Object predicate, Lisp_Object x)
779	{
780	  lisp_h_CHECK_TYPE (ok, predicate, x);
781	}
782
783	/* Extract A's pointer value, assuming A's Lisp type is TYPE and the
784	   extracted pointer's type is CTYPE *.  When !USE_LSB_TAG this simply
785	   extracts A's low-order bits, as (uintptr_t) LISP_WORD_TAG (type) is
786	   always zero then.  */
787	#define XUNTAG(a, type, ctype) \
788	  ((ctype *) ((uintptr_t) XLP (a) - (uintptr_t) LISP_WORD_TAG (type)))
789
790	/* A forwarding pointer to a value.  It uses a generic pointer to
791	   avoid alignment bugs that could occur if it used a pointer to a
792	   union of the possible values (struct Lisp_Objfwd, struct
793	   Lisp_Intfwd, etc.).  The pointer is packaged inside a struct to
794	   help static checking.  */
795	typedef const struct Lisp_Fwd *lispfwd;
796	^L
797	/* Interned state of a symbol.  */
798
799	enum symbol_interned
800	{
801	  SYMBOL_UNINTERNED,		      /* not interned anywhere */
802	  SYMBOL_INTERNED,		      /* interned but not in initial obarray */
803	  SYMBOL_INTERNED_IN_INITIAL_OBARRAY  /* interned in initial obarray */
804	};
805
806	enum symbol_redirect
807	{
808	  SYMBOL_PLAINVAL,   /* plain var, value is in the `value' field */
809	  SYMBOL_VARALIAS,   /* var alias, value is really in the `alias' symbol */
810	  SYMBOL_LOCALIZED,  /* localized var, value is in the `blv' object */
811	  SYMBOL_FORWARDED   /* forwarding var, value is in `forward' */
812	};
813
814	enum symbol_trapped_write
815	{
816	  SYMBOL_UNTRAPPED_WRITE,  /* normal case, just set the value */
817	  SYMBOL_NOWRITE,          /* constant, cannot set, e.g. nil, t, :keyword */
818	  SYMBOL_TRAPPED_WRITE     /* trap the write, call watcher functions */
819	};
820
821	struct Lisp_Symbol
822	{
823	  GC_HEADER
824	  union
825	  {
826	    struct
827	    {
828	      bool_bf gcmarkbit : 1;
829
830	      /* Indicates where the value can be found.  */
831	      ENUM_BF (symbol_redirect) redirect : 2;
832
833	      ENUM_BF (symbol_trapped_write) trapped_write : 2;
834
835	      /* Interned state of the symbol.  */
836	      ENUM_BF (symbol_interned) interned : 2;
837
838	      /* True means that this variable has been explicitly declared
839		 special (with `defvar' etc), and shouldn't be lexically bound.  */
840	      bool_bf declared_special : 1;
841
842	      /* The symbol's name, as a Lisp string.  */
843	      Lisp_Object name;
844
845	      /* Value of the symbol or Qunbound if unbound.  Which alternative of the
846		 union is used depends on the `redirect' field above.  */
847	      union {
848		Lisp_Object value;
849		struct Lisp_Symbol *alias;
850		struct Lisp_Buffer_Local_Value *blv;
851		lispfwd fwd;
852	      } val;
853
854	      /* Function value of the symbol or Qnil if not fboundp.  */
855	      Lisp_Object function;
856
857	      /* The symbol's property list.  */
858	      Lisp_Object plist;
859
860	      /* Next symbol in obarray bucket, if the symbol is interned.  */
861	      struct Lisp_Symbol *next;
862	    } s;
863	    GCALIGNED_UNION_MEMBER
864	  } u;
865	};
866	static_assert (GCALIGNED (struct Lisp_Symbol));
867
868	/* Declare a Lisp-callable function.  The MAXARGS parameter has the same
869	   meaning as in the DEFUN macro, and is used to construct a prototype.  */
870	/* We can use the same trick as in the DEFUN macro to generate the
871	   appropriate prototype.  */
872	#define EXFUN(fnname, maxargs) \
873	  extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs
874
875	/* Note that the weird token-substitution semantics of ANSI C makes
876	   this work for MANY and UNEVALLED.  */
877	#define DEFUN_ARGS_MANY		(ptrdiff_t, Lisp_Object *)
878	#define DEFUN_ARGS_UNEVALLED	(Lisp_Object)
879	#define DEFUN_ARGS_0	(void)
880	#define DEFUN_ARGS_1	(Lisp_Object)
881	#define DEFUN_ARGS_2	(Lisp_Object, Lisp_Object)
882	#define DEFUN_ARGS_3	(Lisp_Object, Lisp_Object, Lisp_Object)
883	#define DEFUN_ARGS_4	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
884	#define DEFUN_ARGS_5	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
885				 Lisp_Object)
886	#define DEFUN_ARGS_6	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
887				 Lisp_Object, Lisp_Object)
888	#define DEFUN_ARGS_7	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
889				 Lisp_Object, Lisp_Object, Lisp_Object)
890	#define DEFUN_ARGS_8	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
891				 Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
892
893	/* Lisp_Word_tag is big enough for a possibly-shifted tag, to be
894	   added to a pointer value for conversion to a Lisp_Word.  */
895	#if LISP_WORDS_ARE_POINTERS
896	typedef uintptr_t Lisp_Word_tag;
897	#else
898	typedef EMACS_UINT Lisp_Word_tag;
899	#endif
900
901	/* A integer value tagged with TAG, and otherwise all zero.  */
902	#define LISP_WORD_TAG(tag) \
903	  ((Lisp_Word_tag) (tag) << (USE_LSB_TAG ? 0 : VALBITS))
904
905	/* An initializer for a Lisp_Object that contains TAG along with P.
906	   P can be a pointer or an integer.  The result is usable in a static
907	   initializer if TAG and P are both integer constant expressions.  */
908	#define TAG_PTR_INITIALLY(tag, p) \
909	  LISP_INITIALLY ((Lisp_Word) ((uintptr_t) (p) + LISP_WORD_TAG (tag)))
910
911	/* LISPSYM_INITIALLY (Qfoo) is equivalent to Qfoo except it is
912	   designed for use as a (possibly static) initializer.  */
913	#define LISPSYM_INITIALLY(name) \
914	  TAG_PTR_INITIALLY (Lisp_Symbol, (intptr_t) ((i##name) * sizeof *lispsym))
915
916	/* Declare extern constants for Lisp symbols.  These can be helpful
917	   when using a debugger like GDB, on older platforms where the debug
918	   format does not represent C macros.  However, they are unbounded
919	   and would just be asking for trouble if checking pointer bounds.  */
920	#define DEFINE_LISP_SYMBOL(name) \
921	  DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) \
922	  DEFINE_GDB_SYMBOL_END (LISPSYM_INITIALLY (name))
923
924	/* The index of the C-defined Lisp symbol SYM.
925	   This can be used in a static initializer.  */
926	#define SYMBOL_INDEX(sym) i##sym
927
928	/* By default, define macros for Qt, etc., as this leads to a bit
929	   better performance in the core Emacs interpreter.  A plugin can
930	   define DEFINE_NON_NIL_Q_SYMBOL_MACROS to be false, to be portable to
931	   other Emacs instances that assign different values to Qt, etc.  */
932	#ifndef DEFINE_NON_NIL_Q_SYMBOL_MACROS
933	# define DEFINE_NON_NIL_Q_SYMBOL_MACROS true
934	#endif
935
936	/* True if N is a power of 2.  N should be positive.  */
937
938	#define POWER_OF_2(n) (((n) & ((n) - 1)) == 0)
939
940	/* Return X rounded to the next multiple of Y.  Y should be positive,
941	   and Y - 1 + X should not overflow.  Arguments should not have side
942	   effects, as they are evaluated more than once.  Tune for Y being a
943	   power of 2.  */
944
945	#define ROUNDUP(x, y) (POWER_OF_2 (y)					\
946	                       ? ((y) - 1 + (x)) & ~ ((y) - 1)			\
947	                       : ((y) - 1 + (x)) - ((y) - 1 + (x)) % (y))
948
949	#include <globals.h>
950
951	/* Header of vector-like objects.  This documents the layout constraints on
952	   vectors and pseudovectors (objects of PVEC_xxx subtype).  It also prevents
953	   compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR
954	   and PSEUDOVECTORP cast their pointers to struct vectorlike_header *,
955	   because when two such pointers potentially alias, a compiler won't
956	   incorrectly reorder loads and stores to their size fields.  See
957	   Bug#8546.   */
958	struct vectorlike_header
959	  {
960	    /* The `size' header word, W bits wide, has one of two forms
961	       discriminated by the second-highest bit (PSEUDOVECTOR_FLAG):
962
963	         1   1                    W-2
964	       +---+---+-------------------------------------+
965	       | M | 0 |                 SIZE                |  vector
966	       +---+---+-------------------------------------+
967
968	         1   1    W-32      6       12         12
969	       +---+---+--------+------+----------+----------+
970	       | M | 1 | unused | TYPE | RESTSIZE | LISPSIZE |  pseudovector
971	       +---+---+--------+------+----------+----------+
972
973	       M (ARRAY_MARK_FLAG) holds the GC mark bit.
974
975	       SIZE     is the length (number of slots) of a regular Lisp vector,
976	                and the object layout is struct Lisp_Vector.
977
978	       TYPE     is the pseudovector subtype (enum pvec_type).
979
980	       LISPSIZE is the number of Lisp_Object fields at the beginning of the
981	                object (after the header).  These are always traced by the GC.
982
983	       RESTSIZE is the number of fields (in word_size units) following.
984	                These are not automatically traced by the GC.
985	                For PVEC_BOOL and statically allocated PVEC_SUBR, RESTSIZE is 0.
986	                (The block size for PVEC_BOOL is computed from its own size
987	                field, to avoid being restricted by the 12-bit RESTSIZE field.)
988	    */
989	    GC_HEADER
990	    ptrdiff_t size;
991	  };
992
993	struct Lisp_Symbol_With_Pos
994	{
995	  struct vectorlike_header header;
996	  Lisp_Object sym;              /* A symbol */
997	  Lisp_Object pos;              /* A fixnum */
998	} GCALIGNED_STRUCT;
999
1000	/* In the size word of a vector, this bit means the vector has been marked.  */
1001
1002	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG)
1003	# define ARRAY_MARK_FLAG PTRDIFF_MIN
1004	DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG)
1005
1006	/* In the size word of a struct Lisp_Vector, this bit means it's really
1007	   some other vector-like object.  */
1008	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG)
1009	# define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2)
1010	DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
1011
1012	/* In a pseudovector, the size field actually contains a word with one
1013	   PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
1014	   with PVEC_TYPE_MASK to indicate the actual type.  */
1015	enum pvec_type
1016	{
1017	  PVEC_NORMAL_VECTOR,	/* Should be first, for sxhash_obj.  */
1018	  PVEC_FREE,
1019	  PVEC_BIGNUM,
1020	  PVEC_MARKER,
1021	  PVEC_OVERLAY,
1022	  PVEC_FINALIZER,
1023	  PVEC_SYMBOL_WITH_POS,
1024	  PVEC_MISC_PTR,
1025	  PVEC_USER_PTR,
1026	  PVEC_PROCESS,
1027	  PVEC_FRAME,
1028	  PVEC_WINDOW,
1029	  PVEC_BOOL_VECTOR,
1030	  PVEC_BUFFER,
1031	  PVEC_HASH_TABLE,
1032	#ifdef HAVE_MPS
1033	  PVEC_WEAK_HASH_TABLE,
1034	#endif
1035	  PVEC_OBARRAY,
1036	  PVEC_TERMINAL,
1037	  PVEC_WINDOW_CONFIGURATION,
1038	  PVEC_SUBR,
1039	  PVEC_OTHER,            /* Should never be visible to Elisp code.  */
1040	  PVEC_XWIDGET,
1041	  PVEC_XWIDGET_VIEW,
1042	  PVEC_THREAD,
1043	  PVEC_MUTEX,
1044	  PVEC_CONDVAR,
1045	  PVEC_MODULE_FUNCTION,
1046	  PVEC_MODULE_GLOBAL_REFERENCE,
1047	  PVEC_NATIVE_COMP_UNIT,
1048	  PVEC_TS_PARSER,
1049	  PVEC_TS_NODE,
1050	  PVEC_TS_COMPILED_QUERY,
1051	  PVEC_SQLITE,
1052
1053	  /* These should be last, for internal_equal and sxhash_obj.  */
1054	  PVEC_CLOSURE,
1055	  PVEC_CHAR_TABLE,
1056	  PVEC_SUB_CHAR_TABLE,
1057	  PVEC_RECORD,
1058	  PVEC_FONT,
1059	  PVEC_TAG_MAX = PVEC_FONT  /* Keep this equal to the highest member.  */
1060	};
1061
1062	enum More_Lisp_Bits
1063	  {
1064	    /* For convenience, we also store the number of elements in these bits.
1065	       Note that this size is not necessarily the memory-footprint size, but
1066	       only the number of Lisp_Object fields (that need to be traced by GC).
1067	       The distinction is used, e.g., by Lisp_Process, which places extra
1068	       non-Lisp_Object fields at the end of the structure.  */
1069	    PSEUDOVECTOR_SIZE_BITS = 12,
1070	    PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1,
1071
1072	    /* To calculate the memory footprint of the pseudovector, it's useful
1073	       to store the size of non-Lisp area in word_size units here.  */
1074	    PSEUDOVECTOR_REST_BITS = 12,
1075	    PSEUDOVECTOR_REST_MASK = (((1 << PSEUDOVECTOR_REST_BITS) - 1)
1076				      << PSEUDOVECTOR_SIZE_BITS),
1077
1078	    /* Used to extract pseudovector subtype information.  */
1079	    PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS,
1080	    PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS
1081	  };
1082	^L
1083	/* These functions extract various sorts of values from a Lisp_Object.
1084	   For example, if tem is a Lisp_Object whose type is Lisp_Cons,
1085	   XCONS (tem) is the struct Lisp_Cons * pointing to the memory for
1086	   that cons.  */
1087
1088	/* Largest and smallest representable fixnum values.  These are the C
1089	   values.  They are macros for use in #if and static initializers.  */
1090	#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
1091	#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
1092	^L
1093	INLINE bool
1094	PSEUDOVECTORP (Lisp_Object a, int code)
1095	{
1096	  return (lisp_h_VECTORLIKEP (a)
1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x0000555555778c79 <+1065>:	and    $0x7,%edx
   0x0000555555778c7c <+1068>:	jne    0x555555778c9e <read_char+1102>

1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x0000555555778c7e <+1070>:	movabs $0x400000003f000000,%rdx
   0x0000555555778c88 <+1080>:	and    0x3(%rax),%rdx
   0x0000555555778c8c <+1084>:	mov    %rdx,%rax

1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x0000555555778c8f <+1087>:	movabs $0x4000000006000000,%rdx
   0x0000555555778c99 <+1097>:	cmp    %rdx,%rax
   0x0000555555778c9c <+1100>:	je     0x555555778cad <read_char+1117>

./src/keyboard.c:
2623		  && (SYMBOLP (XCAR (c)) || FIXNUMP (XCAR (c)))
   0x0000555555778c9e <+1102>:	mov    %r14,%rdi
   0x0000555555778ca1 <+1105>:	call   0x555555763090 <XCAR>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555778ca6 <+1110>:	sub    $0x2,%eax

./src/keyboard.c:
2623		  && (SYMBOLP (XCAR (c)) || FIXNUMP (XCAR (c)))
   0x0000555555778ca9 <+1113>:	test   $0x3,%al
   0x0000555555778cab <+1115>:	jne    0x555555778cbe <read_char+1134>

2624		  && NILP (XCDR (c)))
   0x0000555555778cad <+1117>:	mov    %r14,%rdi
   0x0000555555778cb0 <+1120>:	call   0x5555557630d0 <XCDR>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555778cb5 <+1125>:	test   %rax,%rax
   0x0000555555778cb8 <+1128>:	je     0x55555577b68d <read_char+11837>

./src/keyboard.c:
2626	      reread = true;
   0x0000555555778cbe <+1134>:	sub    $0x2,%r12d
   0x0000555555778cc2 <+1138>:	movb   $0x1,-0x487(%rbp)

2627	      goto reread_for_input_method;
   0x0000555555778cc9 <+1145>:	and    $0x3,%r12d
   0x0000555555778ccd <+1149>:	jmp    0x5555557789c0 <read_char+368>

2663	    }
2664
2665	  /* If redisplay was requested.  */
2666	  if (commandflag >= 0)
   0x0000555555778cd2 <+1154>:	mov    -0x4dc(%rbp),%r8d
   0x0000555555778cd9 <+1161>:	test   %r8d,%r8d
   0x0000555555778cdc <+1164>:	jns    0x55555577ba5b <read_char+12811>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555778ce2 <+1170>:	cmpq   $0x0,0x3368a6(%rip)        # 0x555555aaf590 <echo_area_buffer>
   0x0000555555778cea <+1178>:	je     0x55555577bbe6 <read_char+13206>

./src/keyboard.c:
2730		  echo_kboard != current_kboard
   0x0000555555778cf0 <+1184>:	mov    0x38d569(%rip),%rax        # 0x555555b06260 <current_kboard>

2729	      && (/* It's an echo from a different kboard.  */
   0x0000555555778cf7 <+1191>:	cmp    %rax,0x38d46a(%rip)        # 0x555555b06168 <echo_kboard>
   0x0000555555778cfe <+1198>:	je     0x55555577bbd8 <read_char+13192>

672	  current_kboard->immediate_echo = false;
   0x0000555555778d04 <+1204>:	andb   $0xfe,0xb9(%rax)

450	  kb->echo_prompt_ = val;
   0x0000555555778d0b <+1211>:	movq   $0x0,0xc0(%rax)

445	  kb->echo_string_ = val;
   0x0000555555778d16 <+1222>:	movq   $0x0,0xb0(%rax)

673	  kset_echo_prompt (current_kboard, Qnil);
674	  kset_echo_string (current_kboard, Qnil);
675	  ok_to_echo_at_next_pause = NULL;
   0x0000555555778d21 <+1233>:	movq   $0x0,0x38d8c4(%rip)        # 0x555555b065f0 <ok_to_echo_at_next_pause>

676	  echo_kboard = NULL;
   0x0000555555778d2c <+1244>:	movq   $0x0,0x38d431(%rip)        # 0x555555b06168 <echo_kboard>

677	  echo_message_buffer = Qnil;
   0x0000555555778d37 <+1255>:	movq   $0x0,0x38d41e(%rip)        # 0x555555b06160 <echo_message_buffer>

./src/lisp.h:
1184	  return a;
   0x0000555555778d42 <+1266>:	mov    -0x4b0(%rbp),%rdi
   0x0000555555778d49 <+1273>:	xor    %edx,%edx
   0x0000555555778d4b <+1275>:	xor    %esi,%esi

./src/keyboard.c:
2743	  if (KEYMAPP (map) && INTERACTIVE
   0x0000555555778d4d <+1277>:	xor    %r14d,%r14d
   0x0000555555778d50 <+1280>:	call   0x55555578ab50 <get_keymap>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555778d55 <+1285>:	test   %rax,%rax
   0x0000555555778d58 <+1288>:	je     0x555555778d68 <read_char+1304>
   0x0000555555778d5a <+1290>:	cmpq   $0x0,0x3a7ace(%rip)        # 0x555555b20830 <globals+1008>
   0x0000555555778d62 <+1298>:	je     0x55555577bf33 <read_char+14051>

3913	#else
3914	  return bytes;
3915	#endif
3916	}
3917
3918	/* Internal use only.  */
3919	INLINE ptrdiff_t
3920	unwrap_specpdl_ref (specpdl_ref ref)
3921	{
3922	#ifdef WRAP_SPECPDL_REF
3923	  return ref.bytes;
3924	#else
3925	  return ref;
3926	#endif
3927	}
3928
3929	INLINE specpdl_ref
3930	specpdl_count_to_ref (ptrdiff_t count)
3931	{
3932	  return wrap_specpdl_ref (count * sizeof (union specbinding));
3933	}
3934
3935	INLINE ptrdiff_t
3936	specpdl_ref_to_count (specpdl_ref ref)
3937	{
3938	  return unwrap_specpdl_ref (ref) / sizeof (union specbinding);
3939	}
3940
3941	/* Whether two `specpdl_ref' refer to the same entry.  */
3942	INLINE bool
3943	specpdl_ref_eq (specpdl_ref a, specpdl_ref b)
3944	{
3945	  return unwrap_specpdl_ref (a) == unwrap_specpdl_ref (b);
3946	}
3947
3948	/* Whether `a' refers to an earlier entry than `b'.  */
3949	INLINE bool
3950	specpdl_ref_lt (specpdl_ref a, specpdl_ref b)
3951	{
3952	  return unwrap_specpdl_ref (a) < unwrap_specpdl_ref (b);
3953	}
3954
3955	INLINE bool
3956	specpdl_ref_valid_p (specpdl_ref ref)
3957	{
3958	  return unwrap_specpdl_ref (ref) >= 0;
3959	}
3960
3961	INLINE specpdl_ref
3962	make_invalid_specpdl_ref (void)
3963	{
3964	  return wrap_specpdl_ref (-1);
3965	}
3966
3967	/* Return a reference that is `delta' steps more recent than `ref'.
3968	   `delta' may be negative or zero.  */
3969	INLINE specpdl_ref
3970	specpdl_ref_add (specpdl_ref ref, ptrdiff_t delta)
3971	{
3972	  return wrap_specpdl_ref (unwrap_specpdl_ref (ref)
3973				   + delta * sizeof (union specbinding));
3974	}
3975
3976	INLINE union specbinding *
3977	specpdl_ref_to_ptr (specpdl_ref ref)
3978	{
3979	  return (union specbinding *)((char *)specpdl + unwrap_specpdl_ref (ref));
3980	}
3981
3982	/* Return a reference to the most recent specpdl entry.  */
3983	INLINE specpdl_ref
3984	SPECPDL_INDEX (void)
3985	{
3986	  return wrap_specpdl_ref ((char *)specpdl_ptr - (char *)specpdl);
   0x0000555555778d68 <+1304>:	mov    0x30ebf1(%rip),%rax        # 0x555555a87960 <current_thread>

3912	  return (specpdl_ref){.bytes = bytes};
   0x0000555555778d6f <+1311>:	lea    -0x310(%rbp),%rdi

./src/keyboard.c:
2765	  Lisp_Object volatile c_volatile = c;
   0x0000555555778d76 <+1318>:	mov    %r14,-0x470(%rbp)

./src/lisp.h:
3986	  return wrap_specpdl_ref ((char *)specpdl_ptr - (char *)specpdl);
   0x0000555555778d7d <+1325>:	mov    0x88(%rax),%rdx
   0x0000555555778d84 <+1332>:	sub    0x78(%rax),%rdx
   0x0000555555778d88 <+1336>:	mov    %rdx,-0x500(%rbp)

./src/keyboard.c:
2766	  if (sys_setjmp (local_getcjmp))
   0x0000555555778d8f <+1343>:	call   0x555555599690 <_setjmp <at> plt>
   0x0000555555778d94 <+1348>:	mov    %eax,%r12d
   0x0000555555778d97 <+1351>:	test   %eax,%eax
   0x0000555555778d99 <+1353>:	jne    0x5555557790ac <read_char+2140>

2807	            return make_fixnum (-2); /* wrong_kboard_jmpbuf */
2808		  }
2809	      }
2810	      goto non_reread;
2811	    }
2812
2813	#if GCC_LINT && __GNUC__ && !__clang__
2814	  /* This useless assignment pacifies GCC 14.2.1 x86-64
2815	     <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21161>.  */
2816	  c = c_volatile;
   0x0000555555778d9f <+1359>:	cmpq   $0x0,-0x4a8(%rbp)
   0x0000555555778da7 <+1367>:	mov    -0x470(%rbp),%r14

2817	#endif
2818
2819	  /* Start idle timers if no time limit is supplied.  We don't do it
2820	     if a time limit is supplied to avoid an infinite recursion in the
2821	     situation where an idle timer calls `sit-for'.  */
2822
2823	  if (!end_time)
   0x0000555555778dae <+1374>:	je     0x55555577a1e8 <read_char+6552>

2864		}
2865	    }
2866
2867	  /* Maybe auto save due to number of keystrokes.  */
2868
2869	  if (commandflag != 0 && commandflag != -2
   0x0000555555778db4 <+1380>:	mov    -0x4b4(%rbp),%esi
   0x0000555555778dba <+1386>:	test   %esi,%esi
   0x0000555555778dbc <+1388>:	je     0x555555778ded <read_char+1437>

2870	      && auto_save_interval > 0
   0x0000555555778dbe <+1390>:	mov    0x3a861b(%rip),%rax        # 0x555555b213e0 <globals+4000>
   0x0000555555778dc5 <+1397>:	test   %rax,%rax
   0x0000555555778dc8 <+1400>:	jle    0x555555778ded <read_char+1437>

2871	      && num_nonmacro_input_events - last_auto_save > max (auto_save_interval, 20)
   0x0000555555778dca <+1402>:	mov    $0x14,%ecx
   0x0000555555778dcf <+1407>:	mov    0x3a86f2(%rip),%rdx        # 0x555555b214c8 <globals+4232>
   0x0000555555778dd6 <+1414>:	sub    0x38d803(%rip),%rdx        # 0x555555b065e0 <last_auto_save>
   0x0000555555778ddd <+1421>:	cmp    %rcx,%rax
   0x0000555555778de0 <+1424>:	cmovl  %rcx,%rax
   0x0000555555778de4 <+1428>:	cmp    %rax,%rdx
   0x0000555555778de7 <+1431>:	jg     0x55555577a737 <read_char+7911>

2877	    }
2878
2879	  /* Try reading using an X menu.
2880	     This is never confused with reading using the minibuf
2881	     because the recursive call of read_char in read_char_minibuf_menu_prompt
2882	     does not pass on any keymaps.  */
2883
2884	  if (KEYMAPP (map) && INTERACTIVE
   0x0000555555778ded <+1437>:	mov    -0x4b0(%rbp),%rdi
   0x0000555555778df4 <+1444>:	xor    %edx,%edx
   0x0000555555778df6 <+1446>:	xor    %esi,%esi
   0x0000555555778df8 <+1448>:	call   0x55555578ab50 <get_keymap>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555778dfd <+1453>:	mov    0x3a7a2c(%rip),%rdx        # 0x555555b20830 <globals+1008>

./src/keyboard.c:
2884	  if (KEYMAPP (map) && INTERACTIVE
   0x0000555555778e04 <+1460>:	test   %rax,%rax
   0x0000555555778e07 <+1463>:	je     0x5555557792a0 <read_char+2640>
   0x0000555555778e0d <+1469>:	test   %rdx,%rdx
   0x0000555555778e10 <+1472>:	je     0x55555577a4b0 <read_char+7264>

2897		timer_stop_idle ();
2898
2899	      goto exit;
2900	    }
2901
2902	  /* Maybe autosave and/or garbage collect due to idleness.  */
2903
2904	  if (INTERACTIVE && NILP (c))
   0x0000555555778e16 <+1478>:	mov    %r14,%rbx

2949		maybe_gc ();
2950	    }
2951
2952	  /* Notify the caller if an autosave hook, or a timer, sentinel or
2953	     filter in the sit_for calls above have changed the current
2954	     kboard.  This could happen if they use the minibuffer or start a
2955	     recursive edit, like the fancy splash screen in server.el's
2956	     filter.  If this longjmp wasn't here, read_key_sequence would
2957	     interpret the next key sequence using the wrong translation
2958	     tables and function keymaps.  */
2959	  if (NILP (c) && current_kboard != orig_kboard)
   0x0000555555778e19 <+1481>:	test   %rbx,%rbx
   0x0000555555778e1c <+1484>:	je     0x555555779368 <read_char+2840>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555778e22 <+1490>:	mov    0x3a8250(%rip),%eax        # 0x555555b21078 <globals+3128>

747	}
748
749	INLINE void *
750	(XLP) (Lisp_Object o)
751	{
752	  return lisp_h_XLP (o);
753	}
754
755	/* Extract A's type.  */
756
757	INLINE enum Lisp_Type
758	(XTYPE) (Lisp_Object a)
759	{
760	#if USE_LSB_TAG
761	  return lisp_h_XTYPE (a);
762	#else
763	  EMACS_UINT i = XLI (a);
764	  return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
765	#endif
766	}
767
768	/* True if A has type tag TAG.
769	   Equivalent to XTYPE (a) == TAG, but often faster.  */
770
771	INLINE bool
772	(TAGGEDP) (Lisp_Object a, enum Lisp_Type tag)
773	{
774	  return lisp_h_TAGGEDP (a, tag);
   0x0000555555778e28 <+1496>:	sub    $0x3,%eax

./src/keyboard.c:
2964	  if (CONSP (Vunread_command_events))
   0x0000555555778e2b <+1499>:	test   $0x7,%al
   0x0000555555778e2d <+1501>:	je     0x55555577938c <read_char+2876>

3022		  }
3023	    }
3024
3025	 wrong_kboard:
3026
3027	  STOP_POLLING;
   0x0000555555778e33 <+1507>:	movzbl -0x485(%rbp),%eax
   0x0000555555778e3a <+1514>:	test   %al,%al
   0x0000555555778e3c <+1516>:	jne    0x5555557790a0 <read_char+2128>

2107	  if (!interrupt_input)
   0x0000555555778e42 <+1522>:	cmpb   $0x0,0x34d2b1(%rip)        # 0x555555ac60fa <interrupt_input>
   0x0000555555778e49 <+1529>:	jne    0x5555557790a0 <read_char+2128>

2108	    ++poll_suppress_count;
   0x0000555555778e4f <+1535>:	addl   $0x1,0x34d29e(%rip)        # 0x555555ac60f4 <poll_suppress_count>

3022		  }
3023	    }
3024
3025	 wrong_kboard:
3026
3027	  STOP_POLLING;
   0x0000555555778e56 <+1542>:	movb   $0x1,-0x485(%rbp)

3028
3029	  if (NILP (c))
   0x0000555555778e5d <+1549>:	nopl   (%rax)

3051	  }
3052
3053	 non_reread:
3054
3055	  if (!end_time)
   0x0000555555778e60 <+1552>:	cmpq   $0x0,-0x4a8(%rbp)
   0x0000555555778e68 <+1560>:	je     0x55555577b4ab <read_char+11355>

3056	    timer_stop_idle ();
3057	  RESUME_POLLING;
   0x0000555555778e6e <+1566>:	movzbl -0x485(%rbp),%eax
   0x0000555555778e75 <+1573>:	test   %al,%al
   0x0000555555778e77 <+1575>:	je     0x555555778e86 <read_char+1590>

2052	  if (!interrupt_input)
   0x0000555555778e79 <+1577>:	cmpb   $0x0,0x34d27a(%rip)        # 0x555555ac60fa <interrupt_input>
   0x0000555555778e80 <+1584>:	je     0x55555577b683 <read_char+11827>

3056	    timer_stop_idle ();
3057	  RESUME_POLLING;
   0x0000555555778e86 <+1590>:	movb   $0x0,-0x485(%rbp)

3058
3059	  if (NILP (c))
   0x0000555555778e8d <+1597>:	mov    %r14,%rbx

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555778e90 <+1600>:	test   %r14,%r14
   0x0000555555778e93 <+1603>:	je     0x55555577bb9c <read_char+13132>
   0x0000555555778e99 <+1609>:	lea    -0x5(%r14),%eax
   0x0000555555778e9d <+1613>:	mov    %r14,%r15

747	}
748
749	INLINE void *
750	(XLP) (Lisp_Object o)
751	{
752	  return lisp_h_XLP (o);
753	}
754
755	/* Extract A's type.  */
756
757	INLINE enum Lisp_Type
758	(XTYPE) (Lisp_Object a)
759	{
760	#if USE_LSB_TAG
761	  return lisp_h_XTYPE (a);
762	#else
763	  EMACS_UINT i = XLI (a);
764	  return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
765	#endif
766	}
767
768	/* True if A has type tag TAG.
769	   Equivalent to XTYPE (a) == TAG, but often faster.  */
770
771	INLINE bool
772	(TAGGEDP) (Lisp_Object a, enum Lisp_Type tag)
773	{
774	  return lisp_h_TAGGEDP (a, tag);
   0x0000555555778ea0 <+1616>:	mov    %r14d,%r13d

775	}
776
777	INLINE void
778	(CHECK_TYPE) (int ok, Lisp_Object predicate, Lisp_Object x)
779	{
780	  lisp_h_CHECK_TYPE (ok, predicate, x);
781	}
782
783	/* Extract A's pointer value, assuming A's Lisp type is TYPE and the
784	   extracted pointer's type is CTYPE *.  When !USE_LSB_TAG this simply
785	   extracts A's low-order bits, as (uintptr_t) LISP_WORD_TAG (type) is
786	   always zero then.  */
787	#define XUNTAG(a, type, ctype) \
788	  ((ctype *) ((uintptr_t) XLP (a) - (uintptr_t) LISP_WORD_TAG (type)))
789
790	/* A forwarding pointer to a value.  It uses a generic pointer to
791	   avoid alignment bugs that could occur if it used a pointer to a
792	   union of the possible values (struct Lisp_Objfwd, struct
793	   Lisp_Intfwd, etc.).  The pointer is packaged inside a struct to
794	   help static checking.  */
795	typedef const struct Lisp_Fwd *lispfwd;
796	^L
797	/* Interned state of a symbol.  */
798
799	enum symbol_interned
800	{
801	  SYMBOL_UNINTERNED,		      /* not interned anywhere */
802	  SYMBOL_INTERNED,		      /* interned but not in initial obarray */
803	  SYMBOL_INTERNED_IN_INITIAL_OBARRAY  /* interned in initial obarray */
804	};
805
806	enum symbol_redirect
807	{
808	  SYMBOL_PLAINVAL,   /* plain var, value is in the `value' field */
809	  SYMBOL_VARALIAS,   /* var alias, value is really in the `alias' symbol */
810	  SYMBOL_LOCALIZED,  /* localized var, value is in the `blv' object */
811	  SYMBOL_FORWARDED   /* forwarding var, value is in `forward' */
812	};
813
814	enum symbol_trapped_write
815	{
816	  SYMBOL_UNTRAPPED_WRITE,  /* normal case, just set the value */
817	  SYMBOL_NOWRITE,          /* constant, cannot set, e.g. nil, t, :keyword */
818	  SYMBOL_TRAPPED_WRITE     /* trap the write, call watcher functions */
819	};
820
821	struct Lisp_Symbol
822	{
823	  GC_HEADER
824	  union
825	  {
826	    struct
827	    {
828	      bool_bf gcmarkbit : 1;
829
830	      /* Indicates where the value can be found.  */
831	      ENUM_BF (symbol_redirect) redirect : 2;
832
833	      ENUM_BF (symbol_trapped_write) trapped_write : 2;
834
835	      /* Interned state of the symbol.  */
836	      ENUM_BF (symbol_interned) interned : 2;
837
838	      /* True means that this variable has been explicitly declared
839		 special (with `defvar' etc), and shouldn't be lexically bound.  */
840	      bool_bf declared_special : 1;
841
842	      /* The symbol's name, as a Lisp string.  */
843	      Lisp_Object name;
844
845	      /* Value of the symbol or Qunbound if unbound.  Which alternative of the
846		 union is used depends on the `redirect' field above.  */
847	      union {
848		Lisp_Object value;
849		struct Lisp_Symbol *alias;
850		struct Lisp_Buffer_Local_Value *blv;
851		lispfwd fwd;
852	      } val;
853
854	      /* Function value of the symbol or Qnil if not fboundp.  */
855	      Lisp_Object function;
856
857	      /* The symbol's property list.  */
858	      Lisp_Object plist;
859
860	      /* Next symbol in obarray bucket, if the symbol is interned.  */
861	      struct Lisp_Symbol *next;
862	    } s;
863	    GCALIGNED_UNION_MEMBER
864	  } u;
865	};
866	static_assert (GCALIGNED (struct Lisp_Symbol));
867
868	/* Declare a Lisp-callable function.  The MAXARGS parameter has the same
869	   meaning as in the DEFUN macro, and is used to construct a prototype.  */
870	/* We can use the same trick as in the DEFUN macro to generate the
871	   appropriate prototype.  */
872	#define EXFUN(fnname, maxargs) \
873	  extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs
874
875	/* Note that the weird token-substitution semantics of ANSI C makes
876	   this work for MANY and UNEVALLED.  */
877	#define DEFUN_ARGS_MANY		(ptrdiff_t, Lisp_Object *)
878	#define DEFUN_ARGS_UNEVALLED	(Lisp_Object)
879	#define DEFUN_ARGS_0	(void)
880	#define DEFUN_ARGS_1	(Lisp_Object)
881	#define DEFUN_ARGS_2	(Lisp_Object, Lisp_Object)
882	#define DEFUN_ARGS_3	(Lisp_Object, Lisp_Object, Lisp_Object)
883	#define DEFUN_ARGS_4	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
884	#define DEFUN_ARGS_5	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
885				 Lisp_Object)
886	#define DEFUN_ARGS_6	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
887				 Lisp_Object, Lisp_Object)
888	#define DEFUN_ARGS_7	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
889				 Lisp_Object, Lisp_Object, Lisp_Object)
890	#define DEFUN_ARGS_8	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
891				 Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
892
893	/* Lisp_Word_tag is big enough for a possibly-shifted tag, to be
894	   added to a pointer value for conversion to a Lisp_Word.  */
895	#if LISP_WORDS_ARE_POINTERS
896	typedef uintptr_t Lisp_Word_tag;
897	#else
898	typedef EMACS_UINT Lisp_Word_tag;
899	#endif
900
901	/* A integer value tagged with TAG, and otherwise all zero.  */
902	#define LISP_WORD_TAG(tag) \
903	  ((Lisp_Word_tag) (tag) << (USE_LSB_TAG ? 0 : VALBITS))
904
905	/* An initializer for a Lisp_Object that contains TAG along with P.
906	   P can be a pointer or an integer.  The result is usable in a static
907	   initializer if TAG and P are both integer constant expressions.  */
908	#define TAG_PTR_INITIALLY(tag, p) \
909	  LISP_INITIALLY ((Lisp_Word) ((uintptr_t) (p) + LISP_WORD_TAG (tag)))
910
911	/* LISPSYM_INITIALLY (Qfoo) is equivalent to Qfoo except it is
912	   designed for use as a (possibly static) initializer.  */
913	#define LISPSYM_INITIALLY(name) \
914	  TAG_PTR_INITIALLY (Lisp_Symbol, (intptr_t) ((i##name) * sizeof *lispsym))
915
916	/* Declare extern constants for Lisp symbols.  These can be helpful
917	   when using a debugger like GDB, on older platforms where the debug
918	   format does not represent C macros.  However, they are unbounded
919	   and would just be asking for trouble if checking pointer bounds.  */
920	#define DEFINE_LISP_SYMBOL(name) \
921	  DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) \
922	  DEFINE_GDB_SYMBOL_END (LISPSYM_INITIALLY (name))
923
924	/* The index of the C-defined Lisp symbol SYM.
925	   This can be used in a static initializer.  */
926	#define SYMBOL_INDEX(sym) i##sym
927
928	/* By default, define macros for Qt, etc., as this leads to a bit
929	   better performance in the core Emacs interpreter.  A plugin can
930	   define DEFINE_NON_NIL_Q_SYMBOL_MACROS to be false, to be portable to
931	   other Emacs instances that assign different values to Qt, etc.  */
932	#ifndef DEFINE_NON_NIL_Q_SYMBOL_MACROS
933	# define DEFINE_NON_NIL_Q_SYMBOL_MACROS true
934	#endif
935
936	/* True if N is a power of 2.  N should be positive.  */
937
938	#define POWER_OF_2(n) (((n) & ((n) - 1)) == 0)
939
940	/* Return X rounded to the next multiple of Y.  Y should be positive,
941	   and Y - 1 + X should not overflow.  Arguments should not have side
942	   effects, as they are evaluated more than once.  Tune for Y being a
943	   power of 2.  */
944
945	#define ROUNDUP(x, y) (POWER_OF_2 (y)					\
946	                       ? ((y) - 1 + (x)) & ~ ((y) - 1)			\
947	                       : ((y) - 1 + (x)) - ((y) - 1 + (x)) % (y))
948
949	#include <globals.h>
950
951	/* Header of vector-like objects.  This documents the layout constraints on
952	   vectors and pseudovectors (objects of PVEC_xxx subtype).  It also prevents
953	   compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR
954	   and PSEUDOVECTORP cast their pointers to struct vectorlike_header *,
955	   because when two such pointers potentially alias, a compiler won't
956	   incorrectly reorder loads and stores to their size fields.  See
957	   Bug#8546.   */
958	struct vectorlike_header
959	  {
960	    /* The `size' header word, W bits wide, has one of two forms
961	       discriminated by the second-highest bit (PSEUDOVECTOR_FLAG):
962
963	         1   1                    W-2
964	       +---+---+-------------------------------------+
965	       | M | 0 |                 SIZE                |  vector
966	       +---+---+-------------------------------------+
967
968	         1   1    W-32      6       12         12
969	       +---+---+--------+------+----------+----------+
970	       | M | 1 | unused | TYPE | RESTSIZE | LISPSIZE |  pseudovector
971	       +---+---+--------+------+----------+----------+
972
973	       M (ARRAY_MARK_FLAG) holds the GC mark bit.
974
975	       SIZE     is the length (number of slots) of a regular Lisp vector,
976	                and the object layout is struct Lisp_Vector.
977
978	       TYPE     is the pseudovector subtype (enum pvec_type).
979
980	       LISPSIZE is the number of Lisp_Object fields at the beginning of the
981	                object (after the header).  These are always traced by the GC.
982
983	       RESTSIZE is the number of fields (in word_size units) following.
984	                These are not automatically traced by the GC.
985	                For PVEC_BOOL and statically allocated PVEC_SUBR, RESTSIZE is 0.
986	                (The block size for PVEC_BOOL is computed from its own size
987	                field, to avoid being restricted by the 12-bit RESTSIZE field.)
988	    */
989	    GC_HEADER
990	    ptrdiff_t size;
991	  };
992
993	struct Lisp_Symbol_With_Pos
994	{
995	  struct vectorlike_header header;
996	  Lisp_Object sym;              /* A symbol */
997	  Lisp_Object pos;              /* A fixnum */
998	} GCALIGNED_STRUCT;
999
1000	/* In the size word of a vector, this bit means the vector has been marked.  */
1001
1002	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG)
1003	# define ARRAY_MARK_FLAG PTRDIFF_MIN
1004	DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG)
1005
1006	/* In the size word of a struct Lisp_Vector, this bit means it's really
1007	   some other vector-like object.  */
1008	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG)
1009	# define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2)
1010	DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
1011
1012	/* In a pseudovector, the size field actually contains a word with one
1013	   PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
1014	   with PVEC_TYPE_MASK to indicate the actual type.  */
1015	enum pvec_type
1016	{
1017	  PVEC_NORMAL_VECTOR,	/* Should be first, for sxhash_obj.  */
1018	  PVEC_FREE,
1019	  PVEC_BIGNUM,
1020	  PVEC_MARKER,
1021	  PVEC_OVERLAY,
1022	  PVEC_FINALIZER,
1023	  PVEC_SYMBOL_WITH_POS,
1024	  PVEC_MISC_PTR,
1025	  PVEC_USER_PTR,
1026	  PVEC_PROCESS,
1027	  PVEC_FRAME,
1028	  PVEC_WINDOW,
1029	  PVEC_BOOL_VECTOR,
1030	  PVEC_BUFFER,
1031	  PVEC_HASH_TABLE,
1032	#ifdef HAVE_MPS
1033	  PVEC_WEAK_HASH_TABLE,
1034	#endif
1035	  PVEC_OBARRAY,
1036	  PVEC_TERMINAL,
1037	  PVEC_WINDOW_CONFIGURATION,
1038	  PVEC_SUBR,
1039	  PVEC_OTHER,            /* Should never be visible to Elisp code.  */
1040	  PVEC_XWIDGET,
1041	  PVEC_XWIDGET_VIEW,
1042	  PVEC_THREAD,
1043	  PVEC_MUTEX,
1044	  PVEC_CONDVAR,
1045	  PVEC_MODULE_FUNCTION,
1046	  PVEC_MODULE_GLOBAL_REFERENCE,
1047	  PVEC_NATIVE_COMP_UNIT,
1048	  PVEC_TS_PARSER,
1049	  PVEC_TS_NODE,
1050	  PVEC_TS_COMPILED_QUERY,
1051	  PVEC_SQLITE,
1052
1053	  /* These should be last, for internal_equal and sxhash_obj.  */
1054	  PVEC_CLOSURE,
1055	  PVEC_CHAR_TABLE,
1056	  PVEC_SUB_CHAR_TABLE,
1057	  PVEC_RECORD,
1058	  PVEC_FONT,
1059	  PVEC_TAG_MAX = PVEC_FONT  /* Keep this equal to the highest member.  */
1060	};
1061
1062	enum More_Lisp_Bits
1063	  {
1064	    /* For convenience, we also store the number of elements in these bits.
1065	       Note that this size is not necessarily the memory-footprint size, but
1066	       only the number of Lisp_Object fields (that need to be traced by GC).
1067	       The distinction is used, e.g., by Lisp_Process, which places extra
1068	       non-Lisp_Object fields at the end of the structure.  */
1069	    PSEUDOVECTOR_SIZE_BITS = 12,
1070	    PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1,
1071
1072	    /* To calculate the memory footprint of the pseudovector, it's useful
1073	       to store the size of non-Lisp area in word_size units here.  */
1074	    PSEUDOVECTOR_REST_BITS = 12,
1075	    PSEUDOVECTOR_REST_MASK = (((1 << PSEUDOVECTOR_REST_BITS) - 1)
1076				      << PSEUDOVECTOR_SIZE_BITS),
1077
1078	    /* Used to extract pseudovector subtype information.  */
1079	    PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS,
1080	    PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS
1081	  };
1082	^L
1083	/* These functions extract various sorts of values from a Lisp_Object.
1084	   For example, if tem is a Lisp_Object whose type is Lisp_Cons,
1085	   XCONS (tem) is the struct Lisp_Cons * pointing to the memory for
1086	   that cons.  */
1087
1088	/* Largest and smallest representable fixnum values.  These are the C
1089	   values.  They are macros for use in #if and static initializers.  */
1090	#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
1091	#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
1092	^L
1093	INLINE bool
1094	PSEUDOVECTORP (Lisp_Object a, int code)
1095	{
1096	  return (lisp_h_VECTORLIKEP (a)
1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x0000555555778ea3 <+1619>:	test   $0x7,%al
   0x0000555555778ea5 <+1621>:	jne    0x555555778ec8 <read_char+1656>

1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x0000555555778ea7 <+1623>:	movabs $0x400000003f000000,%rax
   0x0000555555778eb1 <+1633>:	and    0x3(%r14),%rax

1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x0000555555778eb5 <+1637>:	movabs $0x400000000d000000,%rdx
   0x0000555555778ebf <+1647>:	cmp    %rdx,%rax
   0x0000555555778ec2 <+1650>:	je     0x555555778b30 <read_char+736>

./src/keyboard.c:
3076	  save = Vquit_flag;
   0x0000555555778ec8 <+1656>:	mov    0x3a8009(%rip),%rdi        # 0x555555b20ed8 <globals+2712>
   0x0000555555778ecf <+1663>:	mov    $0x1,%edx
   0x0000555555778ed4 <+1668>:	xor    %esi,%esi
   0x0000555555778ed6 <+1670>:	mov    0x3a7eeb(%rip),%r12        # 0x555555b20dc8 <globals+2440>

3077	  Vquit_flag = Qnil;
   0x0000555555778edd <+1677>:	movq   $0x0,0x3a7ee0(%rip)        # 0x555555b20dc8 <globals+2440>

3078	  tem = access_keymap (get_keymap (Vspecial_event_map, 0, 1), c, 0, 0, 1);
   0x0000555555778ee8 <+1688>:	call   0x55555578ab50 <get_keymap>
   0x0000555555778eed <+1693>:	xor    %edx,%edx
   0x0000555555778eef <+1695>:	mov    $0x1,%r8d
   0x0000555555778ef5 <+1701>:	xor    %ecx,%ecx
   0x0000555555778ef7 <+1703>:	mov    %rax,%rdi
   0x0000555555778efa <+1706>:	mov    %r14,%rsi
   0x0000555555778efd <+1709>:	call   0x55555578ada0 <access_keymap>

3079	  Vquit_flag = save;
   0x0000555555778f02 <+1714>:	mov    %r12,0x3a7ebf(%rip)        # 0x555555b20dc8 <globals+2440>

3078	  tem = access_keymap (get_keymap (Vspecial_event_map, 0, 1), c, 0, 0, 1);
   0x0000555555778f09 <+1721>:	mov    %rax,%rdx

3080
3081	  if (!NILP (tem))
   0x0000555555778f0c <+1724>:	mov    %rax,%r12

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555778f0f <+1727>:	test   %rax,%rax
   0x0000555555778f12 <+1730>:	je     0x55555577b4bf <read_char+11375>

./src/keyboard.c:
3083	      struct buffer *prev_buffer = current_buffer;
   0x0000555555778f18 <+1736>:	mov    0x30ea41(%rip),%rax        # 0x555555a87960 <current_thread>

3085
3086	      calln (Qcommand_execute, tem, Qnil, Fvector (1, &last_input_event), Qt);
   0x0000555555778f1f <+1743>:	mov    $0x1,%edi

./src/lisp.h:
774	  return lisp_h_TAGGEDP (a, tag);
   0x0000555555778f24 <+1748>:	sub    $0x3,%r13d

./src/keyboard.c:
3086	      calln (Qcommand_execute, tem, Qnil, Fvector (1, &last_input_event), Qt);
   0x0000555555778f28 <+1752>:	lea    0x3a8459(%rip),%rsi        # 0x555555b21388 <globals+3912>
   0x0000555555778f2f <+1759>:	mov    %rdx,-0x3b8(%rbp)

3083	      struct buffer *prev_buffer = current_buffer;
   0x0000555555778f36 <+1766>:	mov    0x98(%rax),%rbx

3084	      last_input_event = c;
   0x0000555555778f3d <+1773>:	movq   $0x6b68,-0x3c0(%rbp)
   0x0000555555778f48 <+1784>:	mov    %r14,0x3a8439(%rip)        # 0x555555b21388 <globals+3912>

3085
3086	      calln (Qcommand_execute, tem, Qnil, Fvector (1, &last_input_event), Qt);
   0x0000555555778f4f <+1791>:	movq   $0x0,-0x3b0(%rbp)
   0x0000555555778f5a <+1802>:	call   0x5555557f04c0 <Fvector>
   0x0000555555778f5f <+1807>:	lea    -0x3c0(%rbp),%rsi
   0x0000555555778f66 <+1814>:	mov    $0x5,%edi
   0x0000555555778f6b <+1819>:	movq   $0x38,-0x3a0(%rbp)
   0x0000555555778f76 <+1830>:	mov    %rax,-0x3a8(%rbp)
   0x0000555555778f7d <+1837>:	call   0x555555820950 <Ffuncall>

./src/lisp.h:
774	  return lisp_h_TAGGEDP (a, tag);
   0x0000555555778f82 <+1842>:	and    $0x7,%r13d
   0x0000555555778f86 <+1846>:	je     0x55555577c13e <read_char+14574>

./src/keyboard.c:
3102	      if (current_buffer != prev_buffer)
   0x0000555555778f8c <+1852>:	mov    0x30e9cd(%rip),%rax        # 0x555555a87960 <current_thread>
   0x0000555555778f93 <+1859>:	cmp    %rbx,0x98(%rax)
   0x0000555555778f9a <+1866>:	je     0x5555557788da <read_char+138>

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x0000555555778fa0 <+1872>:	mov    $0xfffffffffffffffa,%r14

./src/keyboard.c:
3108		  goto exit;
   0x0000555555778fa7 <+1879>:	jmp    0x555555778b30 <read_char+736>

./src/lisp.h:
1184	  return a;
   0x0000555555778fac <+1884>:	mov    %r14,%rdi
   0x0000555555778faf <+1887>:	call   0x555555763090 <XCAR>

./src/keyboard.c:
2581	      if (CONSP (c) && EQ (XCAR (c), Qt))
   0x0000555555778fb4 <+1892>:	mov    $0x38,%esi
   0x0000555555778fb9 <+1897>:	mov    %rax,%rdi
   0x0000555555778fbc <+1900>:	call   0x555555764470 <EQ>

2582		c = XCDR (c);
   0x0000555555778fc1 <+1905>:	mov    %r14,%rdi

2581	      if (CONSP (c) && EQ (XCAR (c), Qt))
   0x0000555555778fc4 <+1908>:	test   %al,%al
   0x0000555555778fc6 <+1910>:	jne    0x55555577bf13 <read_char+14019>

./src/lisp.h:
1184	  return a;
   0x0000555555778fcc <+1916>:	call   0x555555763090 <XCAR>
   0x0000555555778fd1 <+1921>:	mov    $0x10760,%esi
   0x0000555555778fd6 <+1926>:	mov    %rax,%rdi
   0x0000555555778fd9 <+1929>:	call   0x555555764470 <EQ>

./src/keyboard.c:
2585		  if (CONSP (c) && EQ (XCAR (c), Qno_record))
   0x0000555555778fde <+1934>:	test   %al,%al
   0x0000555555778fe0 <+1936>:	jne    0x55555577b657 <read_char+11783>

2589		    }
2590		  reread = true;
   0x0000555555778fe6 <+1942>:	movb   $0x1,-0x487(%rbp)

./src/lisp.h:
1184	  return a;
   0x0000555555778fed <+1949>:	mov    %r14,%rdi
   0x0000555555778ff0 <+1952>:	call   0x5555557630d0 <XCDR>
   0x0000555555778ff5 <+1957>:	mov    $0x8378,%esi
   0x0000555555778ffa <+1962>:	mov    %rax,%rdi
   0x0000555555778ffd <+1965>:	call   0x555555764470 <EQ>
   0x0000555555779002 <+1970>:	mov    %eax,%ebx

./src/keyboard.c:
2596		  && EQ (XCDR (c), Qdisabled)
   0x0000555555779004 <+1972>:	test   %al,%al
   0x0000555555779006 <+1974>:	je     0x555555778bae <read_char+862>

2597		  && (SYMBOLP (XCAR (c)) || FIXNUMP (XCAR (c))))
   0x000055555577900c <+1980>:	mov    %r14,%rdi
   0x000055555577900f <+1983>:	call   0x555555763090 <XCAR>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555779014 <+1988>:	test   $0x7,%al
   0x0000555555779016 <+1990>:	je     0x55555577905c <read_char+2060>
   0x0000555555779018 <+1992>:	cmpb   $0x0,0x3a85da(%rip)        # 0x555555b215f9 <globals+4537>
   0x000055555577901f <+1999>:	je     0x555555779049 <read_char+2041>

747	}
748
749	INLINE void *
750	(XLP) (Lisp_Object o)
751	{
752	  return lisp_h_XLP (o);
753	}
754
755	/* Extract A's type.  */
756
757	INLINE enum Lisp_Type
758	(XTYPE) (Lisp_Object a)
759	{
760	#if USE_LSB_TAG
761	  return lisp_h_XTYPE (a);
762	#else
763	  EMACS_UINT i = XLI (a);
764	  return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
765	#endif
766	}
767
768	/* True if A has type tag TAG.
769	   Equivalent to XTYPE (a) == TAG, but often faster.  */
770
771	INLINE bool
772	(TAGGEDP) (Lisp_Object a, enum Lisp_Type tag)
773	{
774	  return lisp_h_TAGGEDP (a, tag);
   0x0000555555779021 <+2001>:	lea    -0x5(%rax),%edx

775	}
776
777	INLINE void
778	(CHECK_TYPE) (int ok, Lisp_Object predicate, Lisp_Object x)
779	{
780	  lisp_h_CHECK_TYPE (ok, predicate, x);
781	}
782
783	/* Extract A's pointer value, assuming A's Lisp type is TYPE and the
784	   extracted pointer's type is CTYPE *.  When !USE_LSB_TAG this simply
785	   extracts A's low-order bits, as (uintptr_t) LISP_WORD_TAG (type) is
786	   always zero then.  */
787	#define XUNTAG(a, type, ctype) \
788	  ((ctype *) ((uintptr_t) XLP (a) - (uintptr_t) LISP_WORD_TAG (type)))
789
790	/* A forwarding pointer to a value.  It uses a generic pointer to
791	   avoid alignment bugs that could occur if it used a pointer to a
792	   union of the possible values (struct Lisp_Objfwd, struct
793	   Lisp_Intfwd, etc.).  The pointer is packaged inside a struct to
794	   help static checking.  */
795	typedef const struct Lisp_Fwd *lispfwd;
796	^L
797	/* Interned state of a symbol.  */
798
799	enum symbol_interned
800	{
801	  SYMBOL_UNINTERNED,		      /* not interned anywhere */
802	  SYMBOL_INTERNED,		      /* interned but not in initial obarray */
803	  SYMBOL_INTERNED_IN_INITIAL_OBARRAY  /* interned in initial obarray */
804	};
805
806	enum symbol_redirect
807	{
808	  SYMBOL_PLAINVAL,   /* plain var, value is in the `value' field */
809	  SYMBOL_VARALIAS,   /* var alias, value is really in the `alias' symbol */
810	  SYMBOL_LOCALIZED,  /* localized var, value is in the `blv' object */
811	  SYMBOL_FORWARDED   /* forwarding var, value is in `forward' */
812	};
813
814	enum symbol_trapped_write
815	{
816	  SYMBOL_UNTRAPPED_WRITE,  /* normal case, just set the value */
817	  SYMBOL_NOWRITE,          /* constant, cannot set, e.g. nil, t, :keyword */
818	  SYMBOL_TRAPPED_WRITE     /* trap the write, call watcher functions */
819	};
820
821	struct Lisp_Symbol
822	{
823	  GC_HEADER
824	  union
825	  {
826	    struct
827	    {
828	      bool_bf gcmarkbit : 1;
829
830	      /* Indicates where the value can be found.  */
831	      ENUM_BF (symbol_redirect) redirect : 2;
832
833	      ENUM_BF (symbol_trapped_write) trapped_write : 2;
834
835	      /* Interned state of the symbol.  */
836	      ENUM_BF (symbol_interned) interned : 2;
837
838	      /* True means that this variable has been explicitly declared
839		 special (with `defvar' etc), and shouldn't be lexically bound.  */
840	      bool_bf declared_special : 1;
841
842	      /* The symbol's name, as a Lisp string.  */
843	      Lisp_Object name;
844
845	      /* Value of the symbol or Qunbound if unbound.  Which alternative of the
846		 union is used depends on the `redirect' field above.  */
847	      union {
848		Lisp_Object value;
849		struct Lisp_Symbol *alias;
850		struct Lisp_Buffer_Local_Value *blv;
851		lispfwd fwd;
852	      } val;
853
854	      /* Function value of the symbol or Qnil if not fboundp.  */
855	      Lisp_Object function;
856
857	      /* The symbol's property list.  */
858	      Lisp_Object plist;
859
860	      /* Next symbol in obarray bucket, if the symbol is interned.  */
861	      struct Lisp_Symbol *next;
862	    } s;
863	    GCALIGNED_UNION_MEMBER
864	  } u;
865	};
866	static_assert (GCALIGNED (struct Lisp_Symbol));
867
868	/* Declare a Lisp-callable function.  The MAXARGS parameter has the same
869	   meaning as in the DEFUN macro, and is used to construct a prototype.  */
870	/* We can use the same trick as in the DEFUN macro to generate the
871	   appropriate prototype.  */
872	#define EXFUN(fnname, maxargs) \
873	  extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs
874
875	/* Note that the weird token-substitution semantics of ANSI C makes
876	   this work for MANY and UNEVALLED.  */
877	#define DEFUN_ARGS_MANY		(ptrdiff_t, Lisp_Object *)
878	#define DEFUN_ARGS_UNEVALLED	(Lisp_Object)
879	#define DEFUN_ARGS_0	(void)
880	#define DEFUN_ARGS_1	(Lisp_Object)
881	#define DEFUN_ARGS_2	(Lisp_Object, Lisp_Object)
882	#define DEFUN_ARGS_3	(Lisp_Object, Lisp_Object, Lisp_Object)
883	#define DEFUN_ARGS_4	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
884	#define DEFUN_ARGS_5	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
885				 Lisp_Object)
886	#define DEFUN_ARGS_6	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
887				 Lisp_Object, Lisp_Object)
888	#define DEFUN_ARGS_7	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
889				 Lisp_Object, Lisp_Object, Lisp_Object)
890	#define DEFUN_ARGS_8	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
891				 Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
892
893	/* Lisp_Word_tag is big enough for a possibly-shifted tag, to be
894	   added to a pointer value for conversion to a Lisp_Word.  */
895	#if LISP_WORDS_ARE_POINTERS
896	typedef uintptr_t Lisp_Word_tag;
897	#else
898	typedef EMACS_UINT Lisp_Word_tag;
899	#endif
900
901	/* A integer value tagged with TAG, and otherwise all zero.  */
902	#define LISP_WORD_TAG(tag) \
903	  ((Lisp_Word_tag) (tag) << (USE_LSB_TAG ? 0 : VALBITS))
904
905	/* An initializer for a Lisp_Object that contains TAG along with P.
906	   P can be a pointer or an integer.  The result is usable in a static
907	   initializer if TAG and P are both integer constant expressions.  */
908	#define TAG_PTR_INITIALLY(tag, p) \
909	  LISP_INITIALLY ((Lisp_Word) ((uintptr_t) (p) + LISP_WORD_TAG (tag)))
910
911	/* LISPSYM_INITIALLY (Qfoo) is equivalent to Qfoo except it is
912	   designed for use as a (possibly static) initializer.  */
913	#define LISPSYM_INITIALLY(name) \
914	  TAG_PTR_INITIALLY (Lisp_Symbol, (intptr_t) ((i##name) * sizeof *lispsym))
915
916	/* Declare extern constants for Lisp symbols.  These can be helpful
917	   when using a debugger like GDB, on older platforms where the debug
918	   format does not represent C macros.  However, they are unbounded
919	   and would just be asking for trouble if checking pointer bounds.  */
920	#define DEFINE_LISP_SYMBOL(name) \
921	  DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) \
922	  DEFINE_GDB_SYMBOL_END (LISPSYM_INITIALLY (name))
923
924	/* The index of the C-defined Lisp symbol SYM.
925	   This can be used in a static initializer.  */
926	#define SYMBOL_INDEX(sym) i##sym
927
928	/* By default, define macros for Qt, etc., as this leads to a bit
929	   better performance in the core Emacs interpreter.  A plugin can
930	   define DEFINE_NON_NIL_Q_SYMBOL_MACROS to be false, to be portable to
931	   other Emacs instances that assign different values to Qt, etc.  */
932	#ifndef DEFINE_NON_NIL_Q_SYMBOL_MACROS
933	# define DEFINE_NON_NIL_Q_SYMBOL_MACROS true
934	#endif
935
936	/* True if N is a power of 2.  N should be positive.  */
937
938	#define POWER_OF_2(n) (((n) & ((n) - 1)) == 0)
939
940	/* Return X rounded to the next multiple of Y.  Y should be positive,
941	   and Y - 1 + X should not overflow.  Arguments should not have side
942	   effects, as they are evaluated more than once.  Tune for Y being a
943	   power of 2.  */
944
945	#define ROUNDUP(x, y) (POWER_OF_2 (y)					\
946	                       ? ((y) - 1 + (x)) & ~ ((y) - 1)			\
947	                       : ((y) - 1 + (x)) - ((y) - 1 + (x)) % (y))
948
949	#include <globals.h>
950
951	/* Header of vector-like objects.  This documents the layout constraints on
952	   vectors and pseudovectors (objects of PVEC_xxx subtype).  It also prevents
953	   compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR
954	   and PSEUDOVECTORP cast their pointers to struct vectorlike_header *,
955	   because when two such pointers potentially alias, a compiler won't
956	   incorrectly reorder loads and stores to their size fields.  See
957	   Bug#8546.   */
958	struct vectorlike_header
959	  {
960	    /* The `size' header word, W bits wide, has one of two forms
961	       discriminated by the second-highest bit (PSEUDOVECTOR_FLAG):
962
963	         1   1                    W-2
964	       +---+---+-------------------------------------+
965	       | M | 0 |                 SIZE                |  vector
966	       +---+---+-------------------------------------+
967
968	         1   1    W-32      6       12         12
969	       +---+---+--------+------+----------+----------+
970	       | M | 1 | unused | TYPE | RESTSIZE | LISPSIZE |  pseudovector
971	       +---+---+--------+------+----------+----------+
972
973	       M (ARRAY_MARK_FLAG) holds the GC mark bit.
974
975	       SIZE     is the length (number of slots) of a regular Lisp vector,
976	                and the object layout is struct Lisp_Vector.
977
978	       TYPE     is the pseudovector subtype (enum pvec_type).
979
980	       LISPSIZE is the number of Lisp_Object fields at the beginning of the
981	                object (after the header).  These are always traced by the GC.
982
983	       RESTSIZE is the number of fields (in word_size units) following.
984	                These are not automatically traced by the GC.
985	                For PVEC_BOOL and statically allocated PVEC_SUBR, RESTSIZE is 0.
986	                (The block size for PVEC_BOOL is computed from its own size
987	                field, to avoid being restricted by the 12-bit RESTSIZE field.)
988	    */
989	    GC_HEADER
990	    ptrdiff_t size;
991	  };
992
993	struct Lisp_Symbol_With_Pos
994	{
995	  struct vectorlike_header header;
996	  Lisp_Object sym;              /* A symbol */
997	  Lisp_Object pos;              /* A fixnum */
998	} GCALIGNED_STRUCT;
999
1000	/* In the size word of a vector, this bit means the vector has been marked.  */
1001
1002	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG)
1003	# define ARRAY_MARK_FLAG PTRDIFF_MIN
1004	DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG)
1005
1006	/* In the size word of a struct Lisp_Vector, this bit means it's really
1007	   some other vector-like object.  */
1008	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG)
1009	# define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2)
1010	DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
1011
1012	/* In a pseudovector, the size field actually contains a word with one
1013	   PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
1014	   with PVEC_TYPE_MASK to indicate the actual type.  */
1015	enum pvec_type
1016	{
1017	  PVEC_NORMAL_VECTOR,	/* Should be first, for sxhash_obj.  */
1018	  PVEC_FREE,
1019	  PVEC_BIGNUM,
1020	  PVEC_MARKER,
1021	  PVEC_OVERLAY,
1022	  PVEC_FINALIZER,
1023	  PVEC_SYMBOL_WITH_POS,
1024	  PVEC_MISC_PTR,
1025	  PVEC_USER_PTR,
1026	  PVEC_PROCESS,
1027	  PVEC_FRAME,
1028	  PVEC_WINDOW,
1029	  PVEC_BOOL_VECTOR,
1030	  PVEC_BUFFER,
1031	  PVEC_HASH_TABLE,
1032	#ifdef HAVE_MPS
1033	  PVEC_WEAK_HASH_TABLE,
1034	#endif
1035	  PVEC_OBARRAY,
1036	  PVEC_TERMINAL,
1037	  PVEC_WINDOW_CONFIGURATION,
1038	  PVEC_SUBR,
1039	  PVEC_OTHER,            /* Should never be visible to Elisp code.  */
1040	  PVEC_XWIDGET,
1041	  PVEC_XWIDGET_VIEW,
1042	  PVEC_THREAD,
1043	  PVEC_MUTEX,
1044	  PVEC_CONDVAR,
1045	  PVEC_MODULE_FUNCTION,
1046	  PVEC_MODULE_GLOBAL_REFERENCE,
1047	  PVEC_NATIVE_COMP_UNIT,
1048	  PVEC_TS_PARSER,
1049	  PVEC_TS_NODE,
1050	  PVEC_TS_COMPILED_QUERY,
1051	  PVEC_SQLITE,
1052
1053	  /* These should be last, for internal_equal and sxhash_obj.  */
1054	  PVEC_CLOSURE,
1055	  PVEC_CHAR_TABLE,
1056	  PVEC_SUB_CHAR_TABLE,
1057	  PVEC_RECORD,
1058	  PVEC_FONT,
1059	  PVEC_TAG_MAX = PVEC_FONT  /* Keep this equal to the highest member.  */
1060	};
1061
1062	enum More_Lisp_Bits
1063	  {
1064	    /* For convenience, we also store the number of elements in these bits.
1065	       Note that this size is not necessarily the memory-footprint size, but
1066	       only the number of Lisp_Object fields (that need to be traced by GC).
1067	       The distinction is used, e.g., by Lisp_Process, which places extra
1068	       non-Lisp_Object fields at the end of the structure.  */
1069	    PSEUDOVECTOR_SIZE_BITS = 12,
1070	    PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1,
1071
1072	    /* To calculate the memory footprint of the pseudovector, it's useful
1073	       to store the size of non-Lisp area in word_size units here.  */
1074	    PSEUDOVECTOR_REST_BITS = 12,
1075	    PSEUDOVECTOR_REST_MASK = (((1 << PSEUDOVECTOR_REST_BITS) - 1)
1076				      << PSEUDOVECTOR_SIZE_BITS),
1077
1078	    /* Used to extract pseudovector subtype information.  */
1079	    PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS,
1080	    PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS
1081	  };
1082	^L
1083	/* These functions extract various sorts of values from a Lisp_Object.
1084	   For example, if tem is a Lisp_Object whose type is Lisp_Cons,
1085	   XCONS (tem) is the struct Lisp_Cons * pointing to the memory for
1086	   that cons.  */
1087
1088	/* Largest and smallest representable fixnum values.  These are the C
1089	   values.  They are macros for use in #if and static initializers.  */
1090	#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
1091	#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
1092	^L
1093	INLINE bool
1094	PSEUDOVECTORP (Lisp_Object a, int code)
1095	{
1096	  return (lisp_h_VECTORLIKEP (a)
1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x0000555555779024 <+2004>:	and    $0x7,%edx
   0x0000555555779027 <+2007>:	jne    0x555555779049 <read_char+2041>

1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x0000555555779029 <+2009>:	movabs $0x400000003f000000,%rdx
   0x0000555555779033 <+2019>:	and    0x3(%rax),%rdx
   0x0000555555779037 <+2023>:	mov    %rdx,%rax

1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577903a <+2026>:	movabs $0x4000000006000000,%rdx
   0x0000555555779044 <+2036>:	cmp    %rdx,%rax
   0x0000555555779047 <+2039>:	je     0x55555577905c <read_char+2060>

./src/keyboard.c:
2597		  && (SYMBOLP (XCAR (c)) || FIXNUMP (XCAR (c))))
   0x0000555555779049 <+2041>:	mov    %r14,%rdi
   0x000055555577904c <+2044>:	call   0x555555763090 <XCAR>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555779051 <+2049>:	sub    $0x2,%eax

./src/keyboard.c:
2597		  && (SYMBOLP (XCAR (c)) || FIXNUMP (XCAR (c))))
   0x0000555555779054 <+2052>:	test   $0x3,%al
   0x0000555555779056 <+2054>:	jne    0x555555778bae <read_char+862>

2598		{
2599		  was_disabled = true;
2600		  c = XCAR (c);
   0x000055555577905c <+2060>:	mov    %r14,%rdi
   0x000055555577905f <+2063>:	call   0x555555763090 <XCAR>
   0x0000555555779064 <+2068>:	mov    %rax,%r14
   0x0000555555779067 <+2071>:	jmp    0x555555778bb0 <read_char+864>
   0x000055555577906c <+2076>:	nopl   0x0(%rax)

3339	      && !end_time)
   0x0000555555779070 <+2080>:	mov    -0x4a8(%rbp),%rax
   0x0000555555779077 <+2087>:	or     0x38d1ca(%rip),%rax        # 0x555555b06248 <this_command_key_count>
   0x000055555577907e <+2094>:	jne    0x555555778b06 <read_char+694>

3345		/* Once we reread a character, echoing can happen
3346		   the next time we pause to read a new one.  */
3347		ok_to_echo_at_next_pause = current_kboard;
   0x0000555555779084 <+2100>:	mov    0x38d1d5(%rip),%rax        # 0x555555b06260 <current_kboard>
   0x000055555577908b <+2107>:	mov    %rax,0x38d55e(%rip)        # 0x555555b065f0 <ok_to_echo_at_next_pause>
   0x0000555555779092 <+2114>:	jmp    0x555555778a96 <read_char+582>
   0x0000555555779097 <+2119>:	nopw   0x0(%rax,%rax,1)

3027	  STOP_POLLING;
   0x00005555557790a0 <+2128>:	movb   $0x1,-0x485(%rbp)

3028
3029	  if (NILP (c))
   0x00005555557790a7 <+2135>:	jmp    0x555555778e60 <read_char+1552>

2768	      c = c_volatile;
   0x00005555557790ac <+2140>:	mov    0x30e8ad(%rip),%rdx        # 0x555555a87960 <current_thread>
   0x00005555557790b3 <+2147>:	movdqa -0x240(%rbp),%xmm4

2769	      /* Handle quits while reading the keyboard.  */
2770	      /* We must have saved the outer value of getcjmp here,
2771		 so restore it now.  */
2772	      restore_getcjmp (save_jump);
2773	      pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
   0x00005555557790bb <+2155>:	lea    0x38d5fe(%rip),%rsi        # 0x555555b066c0 <empty_mask>
   0x00005555557790c2 <+2162>:	mov    $0x2,%edi

/usr/include/x86_64-linux-gnu/bits/string_fortified.h:
29	  return __builtin___memcpy_chk (__dest, __src, __len,
   0x00005555557790c7 <+2167>:	movdqa -0x230(%rbp),%xmm5

./src/keyboard.c:
2768	      c = c_volatile;
   0x00005555557790cf <+2175>:	mov    -0x470(%rbp),%r14

/usr/include/x86_64-linux-gnu/bits/string_fortified.h:
29	  return __builtin___memcpy_chk (__dest, __src, __len,
   0x00005555557790d6 <+2182>:	movups %xmm4,0xd8(%rdx)
   0x00005555557790dd <+2189>:	movdqa -0x220(%rbp),%xmm6
   0x00005555557790e5 <+2197>:	lea    0xd8(%rdx),%rax
   0x00005555557790ec <+2204>:	movups %xmm5,0xe8(%rdx)
   0x00005555557790f3 <+2211>:	movdqa -0x210(%rbp),%xmm7
   0x00005555557790fb <+2219>:	movups %xmm6,0xf8(%rdx)
   0x0000555555779102 <+2226>:	movdqa -0x200(%rbp),%xmm3
   0x000055555577910a <+2234>:	movups %xmm7,0x108(%rdx)
   0x0000555555779111 <+2241>:	movdqa -0x1f0(%rbp),%xmm2
   0x0000555555779119 <+2249>:	movups %xmm3,0x118(%rdx)
   0x0000555555779120 <+2256>:	movdqa -0x1e0(%rbp),%xmm1
   0x0000555555779128 <+2264>:	movups %xmm2,0x128(%rdx)
   0x000055555577912f <+2271>:	movdqa -0x1d0(%rbp),%xmm4
   0x0000555555779137 <+2279>:	movups %xmm1,0x138(%rdx)
   0x000055555577913e <+2286>:	movdqa -0x1c0(%rbp),%xmm5
   0x0000555555779146 <+2294>:	movups %xmm4,0x148(%rdx)
   0x000055555577914d <+2301>:	movdqa -0x1b0(%rbp),%xmm6
   0x0000555555779155 <+2309>:	movups %xmm5,0x158(%rdx)
   0x000055555577915c <+2316>:	movdqa -0x1a0(%rbp),%xmm7
   0x0000555555779164 <+2324>:	movups %xmm6,0x168(%rdx)
   0x000055555577916b <+2331>:	movdqa -0x190(%rbp),%xmm3
   0x0000555555779173 <+2339>:	movups %xmm7,0x178(%rdx)
   0x000055555577917a <+2346>:	movups %xmm3,0x188(%rdx)
   0x0000555555779181 <+2353>:	mov    -0x180(%rbp),%rdx
   0x0000555555779188 <+2360>:	mov    %rdx,0xc0(%rax)

./src/keyboard.c:
2773	      pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
   0x000055555577918f <+2367>:	xor    %edx,%edx
   0x0000555555779191 <+2369>:	call   0x555555599780 <pthread_sigmask <at> plt>

./src/lisp.h:
1184	  return a;
   0x0000555555779196 <+2374>:	mov    -0x500(%rbp),%rdi
   0x000055555577919d <+2381>:	xor    %esi,%esi
   0x000055555577919f <+2383>:	call   0x5555558204b0 <unbind_to>

./src/keyboard.c:
2777	      if (!EQ (Vquit_flag, Vthrow_on_input))
   0x00005555557791a4 <+2388>:	mov    0x3a7e15(%rip),%rsi        # 0x555555b20fc0 <globals+2944>
   0x00005555557791ab <+2395>:	mov    0x3a7c16(%rip),%rdi        # 0x555555b20dc8 <globals+2440>
   0x00005555557791b2 <+2402>:	call   0x555555764470 <EQ>
   0x00005555557791b7 <+2407>:	test   %al,%al
   0x00005555557791b9 <+2409>:	jne    0x5555557791ca <read_char+2426>

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x00005555557791bb <+2411>:	movslq 0x38cf96(%rip),%rax        # 0x555555b06158 <quit_char>

1232	  return lisp_h_make_fixnum_wrap (n);
   0x00005555557791c2 <+2418>:	lea    0x2(,%rax,4),%r14

./src/keyboard.c:
2779	      internal_last_event_frame = selected_frame;
   0x00005555557791ca <+2426>:	mov    0x336357(%rip),%rax        # 0x555555aaf528 <selected_frame>

2781	      /* If we report the quit char as an event,
2782		 don't do so more than once.  */
2783	      if (!NILP (Vinhibit_quit))
   0x00005555557791d1 <+2433>:	cmpq   $0x0,0x3a780f(%rip)        # 0x555555b209e8 <globals+1448>

2779	      internal_last_event_frame = selected_frame;
   0x00005555557791d9 <+2441>:	mov    %rax,0x38cf48(%rip)        # 0x555555b06128 <internal_last_event_frame>

2780	      Vlast_event_frame = internal_last_event_frame;
   0x00005555557791e0 <+2448>:	mov    %rax,0x3a78b1(%rip)        # 0x555555b20a98 <globals+1624>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x00005555557791e7 <+2455>:	je     0x5555557791f4 <read_char+2468>

./src/keyboard.c:
2784		Vquit_flag = Qnil;
   0x00005555557791e9 <+2457>:	movq   $0x0,0x3a7bd4(%rip)        # 0x555555b20dc8 <globals+2440>

2785
2786	      {
2787		KBOARD *kb = FRAME_KBOARD (XFRAME (selected_frame));
   0x00005555557791f4 <+2468>:	movzbl 0x3a3185(%rip),%edx        # 0x555555b1c380 <suppress_checking>
   0x00005555557791fb <+2475>:	mov    0x336326(%rip),%rax        # 0x555555aaf528 <selected_frame>
   0x0000555555779202 <+2482>:	test   %dl,%dl
   0x0000555555779204 <+2484>:	jne    0x55555577a4a0 <read_char+7248>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577920a <+2490>:	lea    -0x5(%rax),%ecx

775	}
776
777	INLINE void
778	(CHECK_TYPE) (int ok, Lisp_Object predicate, Lisp_Object x)
779	{
780	  lisp_h_CHECK_TYPE (ok, predicate, x);
781	}
782
783	/* Extract A's pointer value, assuming A's Lisp type is TYPE and the
784	   extracted pointer's type is CTYPE *.  When !USE_LSB_TAG this simply
785	   extracts A's low-order bits, as (uintptr_t) LISP_WORD_TAG (type) is
786	   always zero then.  */
787	#define XUNTAG(a, type, ctype) \
788	  ((ctype *) ((uintptr_t) XLP (a) - (uintptr_t) LISP_WORD_TAG (type)))
789
790	/* A forwarding pointer to a value.  It uses a generic pointer to
791	   avoid alignment bugs that could occur if it used a pointer to a
792	   union of the possible values (struct Lisp_Objfwd, struct
793	   Lisp_Intfwd, etc.).  The pointer is packaged inside a struct to
794	   help static checking.  */
795	typedef const struct Lisp_Fwd *lispfwd;
796	^L
797	/* Interned state of a symbol.  */
798
799	enum symbol_interned
800	{
801	  SYMBOL_UNINTERNED,		      /* not interned anywhere */
802	  SYMBOL_INTERNED,		      /* interned but not in initial obarray */
803	  SYMBOL_INTERNED_IN_INITIAL_OBARRAY  /* interned in initial obarray */
804	};
805
806	enum symbol_redirect
807	{
808	  SYMBOL_PLAINVAL,   /* plain var, value is in the `value' field */
809	  SYMBOL_VARALIAS,   /* var alias, value is really in the `alias' symbol */
810	  SYMBOL_LOCALIZED,  /* localized var, value is in the `blv' object */
811	  SYMBOL_FORWARDED   /* forwarding var, value is in `forward' */
812	};
813
814	enum symbol_trapped_write
815	{
816	  SYMBOL_UNTRAPPED_WRITE,  /* normal case, just set the value */
817	  SYMBOL_NOWRITE,          /* constant, cannot set, e.g. nil, t, :keyword */
818	  SYMBOL_TRAPPED_WRITE     /* trap the write, call watcher functions */
819	};
820
821	struct Lisp_Symbol
822	{
823	  GC_HEADER
824	  union
825	  {
826	    struct
827	    {
828	      bool_bf gcmarkbit : 1;
829
830	      /* Indicates where the value can be found.  */
831	      ENUM_BF (symbol_redirect) redirect : 2;
832
833	      ENUM_BF (symbol_trapped_write) trapped_write : 2;
834
835	      /* Interned state of the symbol.  */
836	      ENUM_BF (symbol_interned) interned : 2;
837
838	      /* True means that this variable has been explicitly declared
839		 special (with `defvar' etc), and shouldn't be lexically bound.  */
840	      bool_bf declared_special : 1;
841
842	      /* The symbol's name, as a Lisp string.  */
843	      Lisp_Object name;
844
845	      /* Value of the symbol or Qunbound if unbound.  Which alternative of the
846		 union is used depends on the `redirect' field above.  */
847	      union {
848		Lisp_Object value;
849		struct Lisp_Symbol *alias;
850		struct Lisp_Buffer_Local_Value *blv;
851		lispfwd fwd;
852	      } val;
853
854	      /* Function value of the symbol or Qnil if not fboundp.  */
855	      Lisp_Object function;
856
857	      /* The symbol's property list.  */
858	      Lisp_Object plist;
859
860	      /* Next symbol in obarray bucket, if the symbol is interned.  */
861	      struct Lisp_Symbol *next;
862	    } s;
863	    GCALIGNED_UNION_MEMBER
864	  } u;
865	};
866	static_assert (GCALIGNED (struct Lisp_Symbol));
867
868	/* Declare a Lisp-callable function.  The MAXARGS parameter has the same
869	   meaning as in the DEFUN macro, and is used to construct a prototype.  */
870	/* We can use the same trick as in the DEFUN macro to generate the
871	   appropriate prototype.  */
872	#define EXFUN(fnname, maxargs) \
873	  extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs
874
875	/* Note that the weird token-substitution semantics of ANSI C makes
876	   this work for MANY and UNEVALLED.  */
877	#define DEFUN_ARGS_MANY		(ptrdiff_t, Lisp_Object *)
878	#define DEFUN_ARGS_UNEVALLED	(Lisp_Object)
879	#define DEFUN_ARGS_0	(void)
880	#define DEFUN_ARGS_1	(Lisp_Object)
881	#define DEFUN_ARGS_2	(Lisp_Object, Lisp_Object)
882	#define DEFUN_ARGS_3	(Lisp_Object, Lisp_Object, Lisp_Object)
883	#define DEFUN_ARGS_4	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
884	#define DEFUN_ARGS_5	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
885				 Lisp_Object)
886	#define DEFUN_ARGS_6	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
887				 Lisp_Object, Lisp_Object)
888	#define DEFUN_ARGS_7	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
889				 Lisp_Object, Lisp_Object, Lisp_Object)
890	#define DEFUN_ARGS_8	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
891				 Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
892
893	/* Lisp_Word_tag is big enough for a possibly-shifted tag, to be
894	   added to a pointer value for conversion to a Lisp_Word.  */
895	#if LISP_WORDS_ARE_POINTERS
896	typedef uintptr_t Lisp_Word_tag;
897	#else
898	typedef EMACS_UINT Lisp_Word_tag;
899	#endif
900
901	/* A integer value tagged with TAG, and otherwise all zero.  */
902	#define LISP_WORD_TAG(tag) \
903	  ((Lisp_Word_tag) (tag) << (USE_LSB_TAG ? 0 : VALBITS))
904
905	/* An initializer for a Lisp_Object that contains TAG along with P.
906	   P can be a pointer or an integer.  The result is usable in a static
907	   initializer if TAG and P are both integer constant expressions.  */
908	#define TAG_PTR_INITIALLY(tag, p) \
909	  LISP_INITIALLY ((Lisp_Word) ((uintptr_t) (p) + LISP_WORD_TAG (tag)))
910
911	/* LISPSYM_INITIALLY (Qfoo) is equivalent to Qfoo except it is
912	   designed for use as a (possibly static) initializer.  */
913	#define LISPSYM_INITIALLY(name) \
914	  TAG_PTR_INITIALLY (Lisp_Symbol, (intptr_t) ((i##name) * sizeof *lispsym))
915
916	/* Declare extern constants for Lisp symbols.  These can be helpful
917	   when using a debugger like GDB, on older platforms where the debug
918	   format does not represent C macros.  However, they are unbounded
919	   and would just be asking for trouble if checking pointer bounds.  */
920	#define DEFINE_LISP_SYMBOL(name) \
921	  DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) \
922	  DEFINE_GDB_SYMBOL_END (LISPSYM_INITIALLY (name))
923
924	/* The index of the C-defined Lisp symbol SYM.
925	   This can be used in a static initializer.  */
926	#define SYMBOL_INDEX(sym) i##sym
927
928	/* By default, define macros for Qt, etc., as this leads to a bit
929	   better performance in the core Emacs interpreter.  A plugin can
930	   define DEFINE_NON_NIL_Q_SYMBOL_MACROS to be false, to be portable to
931	   other Emacs instances that assign different values to Qt, etc.  */
932	#ifndef DEFINE_NON_NIL_Q_SYMBOL_MACROS
933	# define DEFINE_NON_NIL_Q_SYMBOL_MACROS true
934	#endif
935
936	/* True if N is a power of 2.  N should be positive.  */
937
938	#define POWER_OF_2(n) (((n) & ((n) - 1)) == 0)
939
940	/* Return X rounded to the next multiple of Y.  Y should be positive,
941	   and Y - 1 + X should not overflow.  Arguments should not have side
942	   effects, as they are evaluated more than once.  Tune for Y being a
943	   power of 2.  */
944
945	#define ROUNDUP(x, y) (POWER_OF_2 (y)					\
946	                       ? ((y) - 1 + (x)) & ~ ((y) - 1)			\
947	                       : ((y) - 1 + (x)) - ((y) - 1 + (x)) % (y))
948
949	#include <globals.h>
950
951	/* Header of vector-like objects.  This documents the layout constraints on
952	   vectors and pseudovectors (objects of PVEC_xxx subtype).  It also prevents
953	   compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR
954	   and PSEUDOVECTORP cast their pointers to struct vectorlike_header *,
955	   because when two such pointers potentially alias, a compiler won't
956	   incorrectly reorder loads and stores to their size fields.  See
957	   Bug#8546.   */
958	struct vectorlike_header
959	  {
960	    /* The `size' header word, W bits wide, has one of two forms
961	       discriminated by the second-highest bit (PSEUDOVECTOR_FLAG):
962
963	         1   1                    W-2
964	       +---+---+-------------------------------------+
965	       | M | 0 |                 SIZE                |  vector
966	       +---+---+-------------------------------------+
967
968	         1   1    W-32      6       12         12
969	       +---+---+--------+------+----------+----------+
970	       | M | 1 | unused | TYPE | RESTSIZE | LISPSIZE |  pseudovector
971	       +---+---+--------+------+----------+----------+
972
973	       M (ARRAY_MARK_FLAG) holds the GC mark bit.
974
975	       SIZE     is the length (number of slots) of a regular Lisp vector,
976	                and the object layout is struct Lisp_Vector.
977
978	       TYPE     is the pseudovector subtype (enum pvec_type).
979
980	       LISPSIZE is the number of Lisp_Object fields at the beginning of the
981	                object (after the header).  These are always traced by the GC.
982
983	       RESTSIZE is the number of fields (in word_size units) following.
984	                These are not automatically traced by the GC.
985	                For PVEC_BOOL and statically allocated PVEC_SUBR, RESTSIZE is 0.
986	                (The block size for PVEC_BOOL is computed from its own size
987	                field, to avoid being restricted by the 12-bit RESTSIZE field.)
988	    */
989	    GC_HEADER
990	    ptrdiff_t size;
991	  };
992
993	struct Lisp_Symbol_With_Pos
994	{
995	  struct vectorlike_header header;
996	  Lisp_Object sym;              /* A symbol */
997	  Lisp_Object pos;              /* A fixnum */
998	} GCALIGNED_STRUCT;
999
1000	/* In the size word of a vector, this bit means the vector has been marked.  */
1001
1002	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG)
1003	# define ARRAY_MARK_FLAG PTRDIFF_MIN
1004	DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG)
1005
1006	/* In the size word of a struct Lisp_Vector, this bit means it's really
1007	   some other vector-like object.  */
1008	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG)
1009	# define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2)
1010	DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
1011
1012	/* In a pseudovector, the size field actually contains a word with one
1013	   PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
1014	   with PVEC_TYPE_MASK to indicate the actual type.  */
1015	enum pvec_type
1016	{
1017	  PVEC_NORMAL_VECTOR,	/* Should be first, for sxhash_obj.  */
1018	  PVEC_FREE,
1019	  PVEC_BIGNUM,
1020	  PVEC_MARKER,
1021	  PVEC_OVERLAY,
1022	  PVEC_FINALIZER,
1023	  PVEC_SYMBOL_WITH_POS,
1024	  PVEC_MISC_PTR,
1025	  PVEC_USER_PTR,
1026	  PVEC_PROCESS,
1027	  PVEC_FRAME,
1028	  PVEC_WINDOW,
1029	  PVEC_BOOL_VECTOR,
1030	  PVEC_BUFFER,
1031	  PVEC_HASH_TABLE,
1032	#ifdef HAVE_MPS
1033	  PVEC_WEAK_HASH_TABLE,
1034	#endif
1035	  PVEC_OBARRAY,
1036	  PVEC_TERMINAL,
1037	  PVEC_WINDOW_CONFIGURATION,
1038	  PVEC_SUBR,
1039	  PVEC_OTHER,            /* Should never be visible to Elisp code.  */
1040	  PVEC_XWIDGET,
1041	  PVEC_XWIDGET_VIEW,
1042	  PVEC_THREAD,
1043	  PVEC_MUTEX,
1044	  PVEC_CONDVAR,
1045	  PVEC_MODULE_FUNCTION,
1046	  PVEC_MODULE_GLOBAL_REFERENCE,
1047	  PVEC_NATIVE_COMP_UNIT,
1048	  PVEC_TS_PARSER,
1049	  PVEC_TS_NODE,
1050	  PVEC_TS_COMPILED_QUERY,
1051	  PVEC_SQLITE,
1052
1053	  /* These should be last, for internal_equal and sxhash_obj.  */
1054	  PVEC_CLOSURE,
1055	  PVEC_CHAR_TABLE,
1056	  PVEC_SUB_CHAR_TABLE,
1057	  PVEC_RECORD,
1058	  PVEC_FONT,
1059	  PVEC_TAG_MAX = PVEC_FONT  /* Keep this equal to the highest member.  */
1060	};
1061
1062	enum More_Lisp_Bits
1063	  {
1064	    /* For convenience, we also store the number of elements in these bits.
1065	       Note that this size is not necessarily the memory-footprint size, but
1066	       only the number of Lisp_Object fields (that need to be traced by GC).
1067	       The distinction is used, e.g., by Lisp_Process, which places extra
1068	       non-Lisp_Object fields at the end of the structure.  */
1069	    PSEUDOVECTOR_SIZE_BITS = 12,
1070	    PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1,
1071
1072	    /* To calculate the memory footprint of the pseudovector, it's useful
1073	       to store the size of non-Lisp area in word_size units here.  */
1074	    PSEUDOVECTOR_REST_BITS = 12,
1075	    PSEUDOVECTOR_REST_MASK = (((1 << PSEUDOVECTOR_REST_BITS) - 1)
1076				      << PSEUDOVECTOR_SIZE_BITS),
1077
1078	    /* Used to extract pseudovector subtype information.  */
1079	    PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS,
1080	    PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS
1081	  };
1082	^L
1083	/* These functions extract various sorts of values from a Lisp_Object.
1084	   For example, if tem is a Lisp_Object whose type is Lisp_Cons,
1085	   XCONS (tem) is the struct Lisp_Cons * pointing to the memory for
1086	   that cons.  */
1087
1088	/* Largest and smallest representable fixnum values.  These are the C
1089	   values.  They are macros for use in #if and static initializers.  */
1090	#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
1091	#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
1092	^L
1093	INLINE bool
1094	PSEUDOVECTORP (Lisp_Object a, int code)
1095	{
1096	  return (lisp_h_VECTORLIKEP (a)
1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577920d <+2493>:	and    $0x7,%ecx
   0x0000555555779210 <+2496>:	jne    0x5555555b289e <read_char-1859506>

1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x0000555555779216 <+2502>:	movabs $0x400000003f000000,%rsi
   0x0000555555779220 <+2512>:	and    0x3(%rax),%rsi

1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x0000555555779224 <+2516>:	lea    -0x5(%rax),%rcx

1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x0000555555779228 <+2520>:	mov    %rsi,%rax

1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577922b <+2523>:	movabs $0x400000000a000000,%rsi
   0x0000555555779235 <+2533>:	cmp    %rsi,%rax
   0x0000555555779238 <+2536>:	jne    0x5555555b289e <read_char-1859506>

./src/keyboard.c:
2787		KBOARD *kb = FRAME_KBOARD (XFRAME (selected_frame));
   0x000055555577923e <+2542>:	mov    0x208(%rcx),%rax
   0x0000555555779245 <+2549>:	mov    0x50(%rax),%r12

2788		if (kb != current_kboard)
   0x0000555555779249 <+2553>:	cmp    %r12,0x38d010(%rip)        # 0x555555b06260 <current_kboard>
   0x0000555555779250 <+2560>:	je     0x555555778e60 <read_char+1552>

2789		  {
2790		    Lisp_Object last = KVAR (kb, kbd_queue);
   0x0000555555779256 <+2566>:	cmpb   $0x0,0x38d3db(%rip)        # 0x555555b06638 <single_kboard>
   0x000055555577925d <+2573>:	mov    0x40(%r12),%rax

2791		    /* We shouldn't get here if we were in single-kboard mode!  */
2792		    if (single_kboard)
   0x0000555555779262 <+2578>:	jne    0x5555555b2899 <read_char-1859511>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555779268 <+2584>:	lea    -0x3(%rax),%ecx

./src/keyboard.c:
2794		    if (CONSP (last))
   0x000055555577926b <+2587>:	and    $0x7,%ecx
   0x000055555577926e <+2590>:	je     0x55555577a7f4 <read_char+8100>

2802		      kset_kbd_queue (kb, list1 (c));
   0x0000555555779274 <+2596>:	mov    %r14,%rdi
   0x0000555555779277 <+2599>:	call   0x5555557ef5c0 <list1>

455	  kb->kbd_queue_ = val;
   0x000055555577927c <+2604>:	mov    %rax,0x40(%r12)

2805		    kb->kbd_queue_has_data = true;
   0x0000555555779281 <+2609>:	movb   $0x1,0xb8(%r12)

2806		    current_kboard = kb;
   0x000055555577928a <+2618>:	mov    $0xfffffffffffffffa,%rax
   0x0000555555779291 <+2625>:	mov    %r12,0x38cfc8(%rip)        # 0x555555b06260 <current_kboard>

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x0000555555779298 <+2632>:	jmp    0x555555778b5f <read_char+783>
   0x000055555577929d <+2637>:	nopl   (%rax)

./src/keyboard.c:
2904	  if (INTERACTIVE && NILP (c))
   0x00005555557792a0 <+2640>:	mov    %r14,%rbx
   0x00005555557792a3 <+2643>:	test   %rdx,%rdx
   0x00005555557792a6 <+2646>:	jne    0x555555778e19 <read_char+1481>
   0x00005555557792ac <+2652>:	cmpb   $0x0,0x34cde3(%rip)        # 0x555555ac6096 <noninteractive>
   0x00005555557792b3 <+2659>:	jne    0x555555778e19 <read_char+1481>
   0x00005555557792b9 <+2665>:	test   %rbx,%rbx
   0x00005555557792bc <+2668>:	jne    0x555555778e22 <read_char+1490>

2905	    {
2906	      int delay_level;
2907	      ptrdiff_t buffer_size;
2908
2909	      /* Slow down auto saves logarithmically in size of current buffer,
2910		 and garbage collect while we're at it.  */
2911	      if (! MINI_WINDOW_P (XWINDOW (selected_window)))
   0x00005555557792c2 <+2674>:	mov    0x337ba7(%rip),%rdi        # 0x555555ab0e70 <selected_window>
   0x00005555557792c9 <+2681>:	call   0x555555763130 <XWINDOW>
   0x00005555557792ce <+2686>:	testb  $0x1,0x214(%rax)
   0x00005555557792d5 <+2693>:	je     0x55555577bfe7 <read_char+14231>

2913	      buffer_size = (last_non_minibuf_size >> 8) + 1;
   0x00005555557792db <+2699>:	mov    0x38d306(%rip),%rax        # 0x555555b065e8 <last_non_minibuf_size>
   0x00005555557792e2 <+2706>:	sar    $0x8,%rax
   0x00005555557792e6 <+2710>:	add    $0x1,%rax

2914	      delay_level = 0;
2915	      while (buffer_size > 64)
   0x00005555557792ea <+2714>:	cmp    $0x40,%rax
   0x00005555557792ee <+2718>:	jle    0x55555577c37e <read_char+15150>
   0x00005555557792f4 <+2724>:	nopl   0x0(%rax)

2916		delay_level++, buffer_size -= buffer_size >> 2;
   0x00005555557792f8 <+2728>:	mov    %rax,%rdx
   0x00005555557792fb <+2731>:	add    $0x1,%r12d
   0x00005555557792ff <+2735>:	sar    $0x2,%rdx
   0x0000555555779303 <+2739>:	sub    %rdx,%rax

2915	      while (buffer_size > 64)
   0x0000555555779306 <+2742>:	cmp    $0x40,%rax
   0x000055555577930a <+2746>:	jg     0x5555557792f8 <read_char+2728>

2917	      if (delay_level < 4) delay_level = 4;
   0x000055555577930c <+2748>:	mov    $0x4,%ecx
   0x0000555555779311 <+2753>:	cmp    %ecx,%r12d
   0x0000555555779314 <+2756>:	cmovl  %ecx,%r12d

2918	      /* delay_level is 4 for files under around 50k, 7 at 100k,
2919		 9 at 200k, 11 at 300k, and 12 at 500k.  It is 15 at 1 meg.  */
2920
2921	      /* Auto save if enough time goes by without input.  */
2922	      if (commandflag != 0 && commandflag != -2
   0x0000555555779318 <+2760>:	mov    -0x4b4(%rbp),%ecx
   0x000055555577931e <+2766>:	test   %ecx,%ecx
   0x0000555555779320 <+2768>:	je     0x55555577934a <read_char+2810>

2923		  && num_nonmacro_input_events > last_auto_save
   0x0000555555779322 <+2770>:	mov    0x38d2b7(%rip),%rax        # 0x555555b065e0 <last_auto_save>
   0x0000555555779329 <+2777>:	cmp    %rax,0x3a8198(%rip)        # 0x555555b214c8 <globals+4232>
   0x0000555555779330 <+2784>:	jle    0x55555577934a <read_char+2810>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555779332 <+2786>:	mov    0x3a7187(%rip),%rdi        # 0x555555b204c0 <globals+128>

1239	}
1240
1241	INLINE Lisp_Object
1242	make_ufixnum (EMACS_INT n)
1243	{
1244	  eassert (0 <= n && n <= INTMASK);
1245	  return lisp_h_make_fixnum_wrap (n);
1246	}
1247
1248	#else /* ! USE_LSB_TAG */
1249
1250	/* Although compiled only if ! USE_LSB_TAG, the following functions
1251	   also work when USE_LSB_TAG; this is to aid future maintenance when
1252	   the lisp_h_* macros are eventually removed.  */
1253
1254	/* Make a fixnum representing the value of the low order bits of N.  */
1255	INLINE Lisp_Object
1256	make_fixnum (EMACS_INT n)
1257	{
1258	  eassert (! FIXNUM_OVERFLOW_P (n));
1259	  EMACS_INT int0 = Lisp_Int0;
1260	  if (USE_LSB_TAG)
1261	    {
1262	      EMACS_UINT u = n;
1263	      n = u << INTTYPEBITS;
1264	      n += int0;
1265	    }
1266	  else
1267	    {
1268	      n &= INTMASK;
1269	      n += (int0 << VALBITS);
1270	    }
1271	  return XIL (n);
1272	}
1273
1274	/* Extract A's value as a signed integer.  Unlike XFIXNUM, this works
1275	   on any Lisp object, although the resulting integer is useful only
1276	   for things like hashing when A is not a fixnum.  */
1277	INLINE EMACS_INT
1278	XFIXNUM_RAW (Lisp_Object a)
1279	{
1280	  EMACS_INT i = XLI (a);
1281	  if (! USE_LSB_TAG)
1282	    {
1283	      EMACS_UINT u = i;
1284	      i = u << INTTYPEBITS;
1285	    }
1286	  return i >> INTTYPEBITS;
1287	}
1288
1289	INLINE Lisp_Object
1290	make_ufixnum (EMACS_INT n)
1291	{
1292	  eassert (0 <= n && n <= INTMASK);
1293	  EMACS_INT int0 = Lisp_Int0;
1294	  if (USE_LSB_TAG)
1295	    {
1296	      EMACS_UINT u = n;
1297	      n = u << INTTYPEBITS;
1298	      n += int0;
1299	    }
1300	  else
1301	    n += int0 << VALBITS;
1302	  return XIL (n);
1303	}
1304
1305	#endif /* ! USE_LSB_TAG */
1306
1307	INLINE bool
1308	(FIXNUMP) (Lisp_Object x)
1309	{
1310	  return lisp_h_FIXNUMP (x);
   0x0000555555779339 <+2793>:	lea    -0x2(%rdi),%eax

./src/keyboard.c:
2924		  && FIXNUMP (Vauto_save_timeout)
   0x000055555577933c <+2796>:	test   $0x3,%al
   0x000055555577933e <+2798>:	jne    0x55555577934a <read_char+2810>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x0000555555779340 <+2800>:	cmp    $0x3,%rdi
   0x0000555555779344 <+2804>:	jg     0x55555577c60c <read_char+15804>

./src/keyboard.c:
2948	      if (!detect_input_pending_run_timers (0))
   0x000055555577934a <+2810>:	xor    %edi,%edi
   0x000055555577934c <+2812>:	call   0x5555557786a0 <detect_input_pending_run_timers>
   0x0000555555779351 <+2817>:	test   %al,%al
   0x0000555555779353 <+2819>:	jne    0x555555779368 <read_char+2840>

./src/lisp.h:
6282	  if (consing_until_gc < 0)
   0x0000555555779355 <+2821>:	cmpq   $0x0,0x3a70db(%rip)        # 0x555555b20438 <consing_until_gc>
   0x000055555577935d <+2829>:	jns    0x555555779368 <read_char+2840>

6283	    maybe_garbage_collect ();
   0x000055555577935f <+2831>:	call   0x5555557ef980 <maybe_garbage_collect>
   0x0000555555779364 <+2836>:	nopl   0x0(%rax)

./src/keyboard.c:
2959	  if (NILP (c) && current_kboard != orig_kboard)
   0x0000555555779368 <+2840>:	mov    0x38cef1(%rip),%rbx        # 0x555555b06260 <current_kboard>
   0x000055555577936f <+2847>:	mov    -0x4c8(%rbp),%rax
   0x0000555555779376 <+2854>:	cmp    %rax,%rbx
   0x0000555555779379 <+2857>:	jne    0x55555577ab5c <read_char+8972>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577937f <+2863>:	mov    0x3a7cf3(%rip),%eax        # 0x555555b21078 <globals+3128>
   0x0000555555779385 <+2869>:	sub    $0x3,%eax

./src/keyboard.c:
2964	  if (CONSP (Vunread_command_events))
   0x0000555555779388 <+2872>:	test   $0x7,%al
   0x000055555577938a <+2874>:	jne    0x5555557793db <read_char+2955>

2965	    {
2966	      c = XCAR (Vunread_command_events);
   0x000055555577938c <+2876>:	mov    0x3a7ce5(%rip),%rbx        # 0x555555b21078 <globals+3128>
   0x0000555555779393 <+2883>:	mov    %rbx,%rdi
   0x0000555555779396 <+2886>:	call   0x555555763090 <XCAR>

2967	      Vunread_command_events = XCDR (Vunread_command_events);
   0x000055555577939b <+2891>:	mov    %rbx,%rdi

2966	      c = XCAR (Vunread_command_events);
   0x000055555577939e <+2894>:	mov    %rax,%r14

2967	      Vunread_command_events = XCDR (Vunread_command_events);
   0x00005555557793a1 <+2897>:	call   0x5555557630d0 <XCDR>

./src/lisp.h:
774	  return lisp_h_TAGGEDP (a, tag);
   0x00005555557793a6 <+2902>:	lea    -0x3(%r14),%edx

./src/keyboard.c:
2969	      if (CONSP (c) && EQ (XCAR (c), Qt))
   0x00005555557793aa <+2906>:	and    $0x7,%edx

2967	      Vunread_command_events = XCDR (Vunread_command_events);
   0x00005555557793ad <+2909>:	mov    %rax,0x3a7cc4(%rip)        # 0x555555b21078 <globals+3128>

2968
2969	      if (CONSP (c) && EQ (XCAR (c), Qt))
   0x00005555557793b4 <+2916>:	mov    %r14,%rax

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x00005555557793b7 <+2919>:	je     0x55555577a873 <read_char+8227>

./src/keyboard.c:
2978		  reread = true;
   0x00005555557793bd <+2925>:	movb   $0x1,-0x487(%rbp)

2979		}
2980
2981	      c_volatile = c;
   0x00005555557793c4 <+2932>:	mov    %r14,-0x470(%rbp)

2982	    }
2983
2984	  /* Read something from current KBOARD's side queue, if possible.  */
2985
2986	  if (NILP (c))
   0x00005555557793cb <+2939>:	mov    0x38ce8e(%rip),%rbx        # 0x555555b06260 <current_kboard>
   0x00005555557793d2 <+2946>:	test   %rax,%rax
   0x00005555557793d5 <+2949>:	jne    0x555555778e33 <read_char+1507>

2987	    {
2988	      if (current_kboard->kbd_queue_has_data)
   0x00005555557793db <+2955>:	cmpb   $0x0,0xb8(%rbx)
   0x00005555557793e2 <+2962>:	je     0x55555577944a <read_char+3066>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x00005555557793e4 <+2964>:	mov    0x40(%rbx),%r12

747	}
748
749	INLINE void *
750	(XLP) (Lisp_Object o)
751	{
752	  return lisp_h_XLP (o);
753	}
754
755	/* Extract A's type.  */
756
757	INLINE enum Lisp_Type
758	(XTYPE) (Lisp_Object a)
759	{
760	#if USE_LSB_TAG
761	  return lisp_h_XTYPE (a);
762	#else
763	  EMACS_UINT i = XLI (a);
764	  return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
765	#endif
766	}
767
768	/* True if A has type tag TAG.
769	   Equivalent to XTYPE (a) == TAG, but often faster.  */
770
771	INLINE bool
772	(TAGGEDP) (Lisp_Object a, enum Lisp_Type tag)
773	{
774	  return lisp_h_TAGGEDP (a, tag);
   0x00005555557793e8 <+2968>:	lea    -0x3(%r12),%eax

./src/keyboard.c:
2990		  if (!CONSP (KVAR (current_kboard, kbd_queue)))
   0x00005555557793ed <+2973>:	test   $0x7,%al
   0x00005555557793ef <+2975>:	jne    0x5555555b2850 <read_char-1859584>

2991		    emacs_abort ();
2992		  c = XCAR (KVAR (current_kboard, kbd_queue));
   0x00005555557793f5 <+2981>:	mov    %r12,%rdi
   0x00005555557793f8 <+2984>:	call   0x555555763090 <XCAR>

2994		  kset_kbd_queue (current_kboard,
   0x00005555557793fd <+2989>:	mov    %r12,%rdi

2993		  c_volatile = c;
   0x0000555555779400 <+2992>:	mov    %rax,-0x470(%rbp)

2992		  c = XCAR (KVAR (current_kboard, kbd_queue));
   0x0000555555779407 <+2999>:	mov    %rax,%r14

2994		  kset_kbd_queue (current_kboard,
   0x000055555577940a <+3002>:	call   0x5555557630d0 <XCDR>

455	  kb->kbd_queue_ = val;
   0x000055555577940f <+3007>:	mov    %rax,0x40(%rbx)

2995				  XCDR (KVAR (current_kboard, kbd_queue)));
2996		  if (NILP (KVAR (current_kboard, kbd_queue)))
   0x0000555555779413 <+3011>:	test   %rax,%rax
   0x0000555555779416 <+3014>:	je     0x55555577ae2d <read_char+9693>

2998		  input_pending = readable_events (0);
   0x000055555577941c <+3020>:	call   0x555555763910 <readable_events>
   0x0000555555779421 <+3025>:	mov    %al,0x38ccfa(%rip)        # 0x555555b06121 <input_pending>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555779427 <+3031>:	lea    -0x3(%r14),%eax

./src/keyboard.c:
2999		  if (EVENT_HAS_PARAMETERS (c)
   0x000055555577942b <+3035>:	test   $0x7,%al
   0x000055555577942d <+3037>:	je     0x55555577adf0 <read_char+9632>

3002		  Vlast_event_frame = internal_last_event_frame;
   0x0000555555779433 <+3043>:	mov    0x38ccee(%rip),%rax        # 0x555555b06128 <internal_last_event_frame>
   0x000055555577943a <+3050>:	mov    %rax,0x3a7657(%rip)        # 0x555555b20a98 <globals+1624>

3003		}
3004	    }
3005
3006	  /* If current_kboard's side queue is empty check the other kboards.
3007	     If one of them has data that we have not yet seen here,
3008	     switch to it and process the data waiting for it.
3009
3010	     Note: if the events queued up for another kboard
3011	     have already been seen here, and therefore are not a complete command,
3012	     the kbd_queue_has_data field is 0, so we skip that kboard here.
3013	     That's to avoid an infinite loop switching between kboards here.  */
3014	  if (NILP (c) && !single_kboard)
   0x0000555555779441 <+3057>:	test   %r14,%r14
   0x0000555555779444 <+3060>:	jne    0x555555778e33 <read_char+1507>
   0x000055555577944a <+3066>:	cmpb   $0x0,0x38d1e7(%rip)        # 0x555555b06638 <single_kboard>
   0x0000555555779451 <+3073>:	je     0x55555577ab2f <read_char+8927>

3022		  }
3023	    }
3024
3025	 wrong_kboard:
3026
3027	  STOP_POLLING;
   0x0000555555779457 <+3079>:	movzbl -0x485(%rbp),%eax
   0x000055555577945e <+3086>:	test   %al,%al
   0x0000555555779460 <+3088>:	jne    0x555555779472 <read_char+3106>

2107	  if (!interrupt_input)
   0x0000555555779462 <+3090>:	cmpb   $0x0,0x34cc91(%rip)        # 0x555555ac60fa <interrupt_input>
   0x0000555555779469 <+3097>:	jne    0x555555779472 <read_char+3106>

2108	    ++poll_suppress_count;
   0x000055555577946b <+3099>:	addl   $0x1,0x34cc82(%rip)        # 0x555555ac60f4 <poll_suppress_count>

3022		  }
3023	    }
3024
3025	 wrong_kboard:
3026
3027	  STOP_POLLING;
   0x0000555555779472 <+3106>:	movb   $0x1,-0x485(%rbp)

3028
3029	  if (NILP (c))
   0x0000555555779479 <+3113>:	xor    %r15d,%r15d

./src/lisp.h:
1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x000055555577947c <+3116>:	movabs $0x400000003f000000,%r13

./src/keyboard.c:
2942		      Fdo_auto_save (auto_save_no_message ? Qt : Qnil, Qnil);
   0x0000555555779486 <+3126>:	movq   $0x1,-0x4e8(%rbp)

2313	read_event_from_main_queue (struct timespec *end_time,
   0x0000555555779491 <+3137>:	mov    %r15,-0x508(%rbp)
   0x0000555555779498 <+3144>:	mov    -0x4a8(%rbp),%r12

4626	    redisplay_preserve_echo_area (7);
4627	}
4628	^L
4629	/* Record the start of when Emacs is idle,
4630	   for the sake of running idle-time timers.  */
4631
4632	static void
4633	timer_start_idle (void)
4634	{
4635	  /* If we are already in the idle state, do nothing.  */
4636	  if (timespec_valid_p (timer_idleness_start_time))
   0x000055555577949f <+3151>:	mov    -0x4d8(%rbp),%r15
   0x00005555557794a6 <+3158>:	cs nopw 0x0(%rax,%rax,1)

2326	  if (end_time && timespec_cmp (*end_time, current_timespec ()) <= 0)
   0x00005555557794b0 <+3168>:	test   %r12,%r12
   0x00005555557794b3 <+3171>:	je     0x5555557794ef <read_char+3231>
   0x00005555557794b5 <+3173>:	call   0x555555936cd0 <current_timespec>
   0x00005555557794ba <+3178>:	mov    %rax,%rcx
   0x00005555557794bd <+3181>:	mov    %rdx,%rax

../lib/timespec.h:
66	  return 2 * _GL_CMP (a.tv_sec, b.tv_sec) + _GL_CMP (a.tv_nsec, b.tv_nsec);
   0x00005555557794c0 <+3184>:	xor    %edx,%edx
   0x00005555557794c2 <+3186>:	cmp    %rcx,(%r12)
   0x00005555557794c6 <+3190>:	setl   %cl
   0x00005555557794c9 <+3193>:	setg   %dl
   0x00005555557794cc <+3196>:	movzbl %cl,%ecx
   0x00005555557794cf <+3199>:	sub    %ecx,%edx
   0x00005555557794d1 <+3201>:	cmp    %rax,0x8(%r12)
   0x00005555557794d6 <+3206>:	setg   %al
   0x00005555557794d9 <+3209>:	setl   %cl
   0x00005555557794dc <+3212>:	movzbl %al,%eax
   0x00005555557794df <+3215>:	movzbl %cl,%ecx
   0x00005555557794e2 <+3218>:	sub    %ecx,%eax
   0x00005555557794e4 <+3220>:	lea    (%rax,%rdx,2),%eax

./src/keyboard.c:
2326	  if (end_time && timespec_cmp (*end_time, current_timespec ()) <= 0)
   0x00005555557794e7 <+3223>:	test   %eax,%eax
   0x00005555557794e9 <+3225>:	jle    0x55555577ae39 <read_char+9705>

./src/lisp.h:
3986	  return wrap_specpdl_ref ((char *)specpdl_ptr - (char *)specpdl);
   0x00005555557794ef <+3231>:	mov    0x30e46a(%rip),%rdx        # 0x555555a87960 <current_thread>

3912	  return (specpdl_ref){.bytes = bytes};
   0x00005555557794f6 <+3238>:	mov    %r15,%rsi
   0x00005555557794f9 <+3241>:	lea    -0x167c0(%rip),%rdi        # 0x555555762d40 <restore_getcjmp>

/usr/include/x86_64-linux-gnu/bits/string_fortified.h:
29	  return __builtin___memcpy_chk (__dest, __src, __len,
   0x0000555555779500 <+3248>:	movdqu 0xd8(%rdx),%xmm4
   0x0000555555779508 <+3256>:	movdqu 0xe8(%rdx),%xmm5
   0x0000555555779510 <+3264>:	movdqu 0xf8(%rdx),%xmm6
   0x0000555555779518 <+3272>:	movdqu 0x108(%rdx),%xmm7

./src/lisp.h:
3986	  return wrap_specpdl_ref ((char *)specpdl_ptr - (char *)specpdl);
   0x0000555555779520 <+3280>:	mov    0x88(%rdx),%rax
   0x0000555555779527 <+3287>:	sub    0x78(%rdx),%rax

/usr/include/x86_64-linux-gnu/bits/string_fortified.h:
29	  return __builtin___memcpy_chk (__dest, __src, __len,
   0x000055555577952b <+3291>:	movaps %xmm4,(%r15)
   0x000055555577952f <+3295>:	movdqu 0x118(%rdx),%xmm3
   0x0000555555779537 <+3303>:	movdqu 0x128(%rdx),%xmm2

./src/lisp.h:
3986	  return wrap_specpdl_ref ((char *)specpdl_ptr - (char *)specpdl);
   0x000055555577953f <+3311>:	mov    %rax,-0x4a0(%rbp)

/usr/include/x86_64-linux-gnu/bits/string_fortified.h:
29	  return __builtin___memcpy_chk (__dest, __src, __len,
   0x0000555555779546 <+3318>:	movdqu 0x138(%rdx),%xmm1
   0x000055555577954e <+3326>:	movdqu 0x148(%rdx),%xmm0
   0x0000555555779556 <+3334>:	movaps %xmm5,0x10(%r15)
   0x000055555577955b <+3339>:	movdqu 0x158(%rdx),%xmm4
   0x0000555555779563 <+3347>:	movdqu 0x168(%rdx),%xmm5
   0x000055555577956b <+3355>:	movaps %xmm6,0x20(%r15)
   0x0000555555779570 <+3360>:	mov    0x198(%rdx),%rax
   0x0000555555779577 <+3367>:	movdqu 0x178(%rdx),%xmm6
   0x000055555577957f <+3375>:	movaps %xmm7,0x30(%r15)
   0x0000555555779584 <+3380>:	movdqu 0x188(%rdx),%xmm7
   0x000055555577958c <+3388>:	movaps %xmm3,0x40(%r15)
   0x0000555555779591 <+3393>:	mov    %rax,0xc0(%r15)

./src/keyboard.c:
2332	  record_unwind_protect_ptr (restore_getcjmp, save_jump);
   0x0000555555779598 <+3400>:	movaps %xmm2,0x50(%r15)
   0x000055555577959d <+3405>:	movaps %xmm1,0x60(%r15)
   0x00005555557795a2 <+3410>:	movaps %xmm0,0x70(%r15)
   0x00005555557795a7 <+3415>:	movaps %xmm4,0x80(%r15)
   0x00005555557795af <+3423>:	movaps %xmm5,0x90(%r15)
   0x00005555557795b7 <+3431>:	movaps %xmm6,0xa0(%r15)
   0x00005555557795bf <+3439>:	movaps %xmm7,0xb0(%r15)
   0x00005555557795c7 <+3447>:	call   0x5555558201a0 <record_unwind_protect_ptr>

/usr/include/x86_64-linux-gnu/bits/string_fortified.h:
29	  return __builtin___memcpy_chk (__dest, __src, __len,
   0x00005555557795cc <+3452>:	mov    0x30e38d(%rip),%rdx        # 0x555555a87960 <current_thread>
   0x00005555557795d3 <+3459>:	movdqa -0x310(%rbp),%xmm3
   0x00005555557795db <+3467>:	movdqa -0x300(%rbp),%xmm2
   0x00005555557795e3 <+3475>:	movups %xmm3,0xd8(%rdx)
   0x00005555557795ea <+3482>:	movdqa -0x2f0(%rbp),%xmm1
   0x00005555557795f2 <+3490>:	lea    0xd8(%rdx),%rax
   0x00005555557795f9 <+3497>:	movups %xmm2,0xe8(%rdx)
   0x0000555555779600 <+3504>:	movdqa -0x2e0(%rbp),%xmm0
   0x0000555555779608 <+3512>:	movups %xmm1,0xf8(%rdx)
   0x000055555577960f <+3519>:	movdqa -0x2d0(%rbp),%xmm4
   0x0000555555779617 <+3527>:	movups %xmm0,0x108(%rdx)
   0x000055555577961e <+3534>:	movdqa -0x2c0(%rbp),%xmm5
   0x0000555555779626 <+3542>:	movups %xmm4,0x118(%rdx)
   0x000055555577962d <+3549>:	movdqa -0x2b0(%rbp),%xmm6
   0x0000555555779635 <+3557>:	movups %xmm5,0x128(%rdx)
   0x000055555577963c <+3564>:	movdqa -0x2a0(%rbp),%xmm7
   0x0000555555779644 <+3572>:	movups %xmm6,0x138(%rdx)
   0x000055555577964b <+3579>:	movdqa -0x290(%rbp),%xmm3
   0x0000555555779653 <+3587>:	movups %xmm7,0x148(%rdx)
   0x000055555577965a <+3594>:	movdqa -0x280(%rbp),%xmm2
   0x0000555555779662 <+3602>:	movups %xmm3,0x158(%rdx)
   0x0000555555779669 <+3609>:	movdqa -0x270(%rbp),%xmm1
   0x0000555555779671 <+3617>:	movups %xmm2,0x168(%rdx)
   0x0000555555779678 <+3624>:	movdqa -0x260(%rbp),%xmm0
   0x0000555555779680 <+3632>:	movups %xmm1,0x178(%rdx)
   0x0000555555779687 <+3639>:	movups %xmm0,0x188(%rdx)
   0x000055555577968e <+3646>:	mov    -0x250(%rbp),%rdx
   0x0000555555779695 <+3653>:	mov    %rdx,0xc0(%rax)

./src/keyboard.c:
2334	  if (!end_time)
   0x000055555577969c <+3660>:	test   %r12,%r12
   0x000055555577969f <+3663>:	je     0x555555779ed0 <read_char+5760>

3964	}
3965
3966	static Lisp_Object
3967	kbd_buffer_get_event_1 (Lisp_Object arg)
3968	{
3969	  Lisp_Object coding_system = Fget_text_property (make_fixnum (0),
3970							  Qcoding, arg);
3971
3972	  if (EQ (coding_system, Qt))
3973	    return arg;
3974
3975	  return code_convert_string (arg, (!NILP (coding_system)
3976					    ? coding_system
3977					    : Vlocale_coding_system),
3978				      Qnil, 0, false, 0);
3979	}
3980
3981	static Lisp_Object
3982	kbd_buffer_get_event_2 (Lisp_Object val)
3983	{
3984	  return Qnil;
3985	}
3986
3987	/* Read one event from the event buffer, waiting if necessary.
3988	   The value is a Lisp object representing the event.
3989	   The value is nil for an event that should be ignored,
3990	   or that was handled here.
3991	   We always read and discard one event.  */
3992
3993	static Lisp_Object
3994	kbd_buffer_get_event (KBOARD **kbp,
3995	                      bool *used_mouse_menu,
3996	                      struct timespec *end_time)
3997	{
3998	  Lisp_Object obj, str;
3999	#ifdef HAVE_X_WINDOWS
4000	  bool had_pending_selection_requests;
4001
4002	  had_pending_selection_requests = false;
4003	#endif
4004	#ifdef HAVE_TEXT_CONVERSION
4005	  bool had_pending_conversion_events;
4006
4007	  had_pending_conversion_events = false;
4008	#endif
4009
4010	#ifdef subprocesses
4011	  if (kbd_on_hold_p () && kbd_buffer_nr_stored () < KBD_BUFFER_SIZE / 4)
   0x00005555557796a5 <+3669>:	call   0x5555558a75a0 <kbd_on_hold_p>
   0x00005555557796aa <+3674>:	test   %al,%al
   0x00005555557796ac <+3676>:	je     0x5555557796d8 <read_char+3720>

3717	  int n = kbd_store_ptr - kbd_fetch_ptr;
   0x00005555557796ae <+3678>:	mov    0x34ca5b(%rip),%rax        # 0x555555ac6110 <kbd_store_ptr>
   0x00005555557796b5 <+3685>:	sub    0x34ca5c(%rip),%rax        # 0x555555ac6118 <kbd_fetch_ptr>
   0x00005555557796bc <+3692>:	sar    $0x6,%rax

3718	  return n + (n < 0 ? KBD_BUFFER_SIZE : 0);
   0x00005555557796c0 <+3696>:	mov    %eax,%edx
   0x00005555557796c2 <+3698>:	sar    $0x13,%edx
   0x00005555557796c5 <+3701>:	and    $0x1000,%edx
   0x00005555557796cb <+3707>:	add    %edx,%eax

3964	}
3965
3966	static Lisp_Object
3967	kbd_buffer_get_event_1 (Lisp_Object arg)
3968	{
3969	  Lisp_Object coding_system = Fget_text_property (make_fixnum (0),
3970							  Qcoding, arg);
3971
3972	  if (EQ (coding_system, Qt))
3973	    return arg;
3974
3975	  return code_convert_string (arg, (!NILP (coding_system)
3976					    ? coding_system
3977					    : Vlocale_coding_system),
3978				      Qnil, 0, false, 0);
3979	}
3980
3981	static Lisp_Object
3982	kbd_buffer_get_event_2 (Lisp_Object val)
3983	{
3984	  return Qnil;
3985	}
3986
3987	/* Read one event from the event buffer, waiting if necessary.
3988	   The value is a Lisp object representing the event.
3989	   The value is nil for an event that should be ignored,
3990	   or that was handled here.
3991	   We always read and discard one event.  */
3992
3993	static Lisp_Object
3994	kbd_buffer_get_event (KBOARD **kbp,
3995	                      bool *used_mouse_menu,
3996	                      struct timespec *end_time)
3997	{
3998	  Lisp_Object obj, str;
3999	#ifdef HAVE_X_WINDOWS
4000	  bool had_pending_selection_requests;
4001
4002	  had_pending_selection_requests = false;
4003	#endif
4004	#ifdef HAVE_TEXT_CONVERSION
4005	  bool had_pending_conversion_events;
4006
4007	  had_pending_conversion_events = false;
4008	#endif
4009
4010	#ifdef subprocesses
4011	  if (kbd_on_hold_p () && kbd_buffer_nr_stored () < KBD_BUFFER_SIZE / 4)
   0x00005555557796cd <+3709>:	cmp    $0x3ff,%eax
   0x00005555557796d2 <+3714>:	jle    0x555555779fa0 <read_char+5968>

4017	      start_polling ();
4018	    }
4019	#endif	/* subprocesses */
4020
4021	#if !defined HAVE_DBUS && !defined USE_FILE_NOTIFY && !defined THREADS_ENABLED
4022	  if (noninteractive
4023	      /* In case we are running as a daemon, only do this before
4024		 detaching from the terminal.  */
4025	      || (IS_DAEMON && DAEMON_RUNNING))
4026	    {
4027	      int c = getchar ();
4028	      XSETINT (obj, c);
4029	      *kbp = current_kboard;
4030	      return obj;
4031	    }
4032	#endif	/* !defined HAVE_DBUS && !defined USE_FILE_NOTIFY && !defined THREADS_ENABLED  */
4033
4034	  *kbp = current_kboard;
   0x00005555557796d8 <+3720>:	mov    0x38cb81(%rip),%rax        # 0x555555b06260 <current_kboard>
   0x00005555557796df <+3727>:	mov    0x3a7992(%rip),%rdx        # 0x555555b21078 <globals+3128>
   0x00005555557796e6 <+3734>:	lea    0x3a6d53(%rip),%r14        # 0x555555b20440 <globals>
   0x00005555557796ed <+3741>:	mov    %rax,-0x498(%rbp)

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x00005555557796f4 <+3748>:	lea    -0x3(%rdx),%eax

./src/keyboard.c:
4042	      if (CONSP (Vunread_command_events))
   0x00005555557796f7 <+3751>:	test   $0x7,%al
   0x00005555557796f9 <+3753>:	jne    0x5555557797a4 <read_char+3924>
   0x00005555557796ff <+3759>:	jmp    0x555555779eb6 <read_char+5734>
   0x0000555555779704 <+3764>:	nopl   0x0(%rax)

4087		{
4088		  struct timespec now = current_timespec ();
   0x0000555555779708 <+3768>:	call   0x555555936cd0 <current_timespec>
   0x000055555577970d <+3773>:	mov    (%r12),%rdi

../lib/timespec.h:
66	  return 2 * _GL_CMP (a.tv_sec, b.tv_sec) + _GL_CMP (a.tv_nsec, b.tv_nsec);
   0x0000555555779711 <+3777>:	xor    %esi,%esi
   0x0000555555779713 <+3779>:	mov    0x8(%r12),%r8

./src/keyboard.c:
4088		  struct timespec now = current_timespec ();
   0x0000555555779718 <+3784>:	mov    %rdx,%rcx

../lib/timespec.h:
66	  return 2 * _GL_CMP (a.tv_sec, b.tv_sec) + _GL_CMP (a.tv_nsec, b.tv_nsec);
   0x000055555577971b <+3787>:	cmp    %rax,%rdi
   0x000055555577971e <+3790>:	setl   %dl
   0x0000555555779721 <+3793>:	setg   %sil
   0x0000555555779725 <+3797>:	movzbl %dl,%edx
   0x0000555555779728 <+3800>:	sub    %edx,%esi
   0x000055555577972a <+3802>:	xor    %edx,%edx
   0x000055555577972c <+3804>:	cmp    %rcx,%r8
   0x000055555577972f <+3807>:	setl   %r9b
   0x0000555555779733 <+3811>:	setg   %dl
   0x0000555555779736 <+3814>:	movzbl %r9b,%r9d
   0x000055555577973a <+3818>:	sub    %r9d,%edx
   0x000055555577973d <+3821>:	lea    (%rdx,%rsi,2),%edx

./src/keyboard.c:
4089		  if (timespec_cmp (*end_time, now) <= 0)
   0x0000555555779740 <+3824>:	test   %edx,%edx
   0x0000555555779742 <+3826>:	jle    0x55555577a706 <read_char+7862>

4090		    return Qnil;	/* Finished waiting.  */
4091		  else
4092		    {
4093		      struct timespec duration = timespec_sub (*end_time, now);
   0x0000555555779748 <+3832>:	mov    %r8,%rsi
   0x000055555577974b <+3835>:	mov    %rax,%rdx
   0x000055555577974e <+3838>:	call   0x55555593a9c0 <timespec_sub>

./src/lisp.h:
1184	  return a;
   0x0000555555779753 <+3843>:	sub    $0x8,%rsp
   0x0000555555779757 <+3847>:	xor    %r9d,%r9d
   0x000055555577975a <+3850>:	xor    %r8d,%r8d
   0x000055555577975d <+3853>:	push   $0x0
   0x000055555577975f <+3855>:	mov    %edx,%esi

./src/keyboard.c:
4093		      struct timespec duration = timespec_sub (*end_time, now);
   0x0000555555779761 <+3857>:	mov    %rax,%rdi

4094		      wait_reading_process_output (min (duration.tv_sec,
   0x0000555555779764 <+3860>:	mov    $0xffffffff,%edx
   0x0000555555779769 <+3865>:	mov    $0x1,%ecx
   0x000055555577976e <+3870>:	call   0x5555558a0d10 <wait_reading_process_output>
   0x0000555555779773 <+3875>:	pop    %rax
   0x0000555555779774 <+3876>:	pop    %rdx

4116		}
4117
4118	      if (!interrupt_input && kbd_fetch_ptr == kbd_store_ptr)
   0x0000555555779775 <+3877>:	cmpb   $0x0,0x34c97e(%rip)        # 0x555555ac60fa <interrupt_input>
   0x000055555577977c <+3884>:	jne    0x555555779792 <read_char+3906>
   0x000055555577977e <+3886>:	mov    0x34c98b(%rip),%rax        # 0x555555ac6110 <kbd_store_ptr>
   0x0000555555779785 <+3893>:	cmp    %rax,0x34c98c(%rip)        # 0x555555ac6118 <kbd_fetch_ptr>
   0x000055555577978c <+3900>:	je     0x555555779e70 <read_char+5664>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555779792 <+3906>:	mov    0xc38(%r14),%eax
   0x0000555555779799 <+3913>:	sub    $0x3,%eax

./src/keyboard.c:
4042	      if (CONSP (Vunread_command_events))
   0x000055555577979c <+3916>:	test   $0x7,%al
   0x000055555577979e <+3918>:	je     0x5555557798c0 <read_char+4208>

4043		break;
4044
4045	#ifdef HAVE_TEXT_CONVERSION
4046	      /* That text conversion events take priority over keyboard
4047		 events, since input methods frequently send them immediately
4048		 after edits, with the assumption that this order of events
4049		 will be observed.  */
4050
4051	      if (detect_conversion_events ())
   0x00005555557797a4 <+3924>:	call   0x5555559269f0 <detect_conversion_events>
   0x00005555557797a9 <+3929>:	mov    %eax,%ebx
   0x00005555557797ab <+3931>:	test   %al,%al
   0x00005555557797ad <+3933>:	jne    0x55555577a560 <read_char+7440>

4052		{
4053		  had_pending_conversion_events = true;
4054		  break;
4055		}
4056	#endif /* HAVE_TEXT_CONVERSION */
4057
4058	      if (kbd_fetch_ptr != kbd_store_ptr)
   0x00005555557797b3 <+3939>:	mov    0x34c956(%rip),%rax        # 0x555555ac6110 <kbd_store_ptr>
   0x00005555557797ba <+3946>:	cmp    %rax,0x34c957(%rip)        # 0x555555ac6118 <kbd_fetch_ptr>
   0x00005555557797c1 <+3953>:	jne    0x5555557798c0 <read_char+4208>

4059		break;
4060	      if (some_mouse_moved ())
   0x00005555557797c7 <+3959>:	call   0x555555763840 <some_mouse_moved>
   0x00005555557797cc <+3964>:	test   %rax,%rax
   0x00005555557797cf <+3967>:	jne    0x5555557798c0 <read_char+4208>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x00005555557797d5 <+3973>:	cmpq   $0x0,0x988(%r14)
   0x00005555557797dd <+3981>:	jne    0x5555555b2849 <read_char-1859591>

./src/keyboard.c:
4072	      gobble_input ();
   0x00005555557797e3 <+3987>:	call   0x555555771b00 <gobble_input>

4073	#endif
4074
4075	      if (kbd_fetch_ptr != kbd_store_ptr)
   0x00005555557797e8 <+3992>:	mov    0x34c921(%rip),%rax        # 0x555555ac6110 <kbd_store_ptr>
   0x00005555557797ef <+3999>:	cmp    %rax,0x34c922(%rip)        # 0x555555ac6118 <kbd_fetch_ptr>
   0x00005555557797f6 <+4006>:	jne    0x5555557798c0 <read_char+4208>

4076		break;
4077	      if (some_mouse_moved ())
   0x00005555557797fc <+4012>:	call   0x555555763840 <some_mouse_moved>
   0x0000555555779801 <+4017>:	test   %rax,%rax
   0x0000555555779804 <+4020>:	jne    0x5555557798c0 <read_char+4208>

4078		break;
4079	#ifdef HAVE_X_WINDOWS
4080	      if (x_detect_pending_selection_requests ())
   0x000055555577980a <+4026>:	call   0x55555571a8a0 <x_detect_pending_selection_requests>
   0x000055555577980f <+4031>:	test   %al,%al
   0x0000555555779811 <+4033>:	jne    0x555555779e80 <read_char+5680>

4081		{
4082		  had_pending_selection_requests = true;
4083		  break;
4084		}
4085	#endif
4086	      if (end_time)
   0x0000555555779817 <+4039>:	test   %r12,%r12
   0x000055555577981a <+4042>:	jne    0x555555779708 <read_char+3768>

4095							WAIT_READING_MAX),
4096						   duration.tv_nsec,
4097						   -1, 1, Qnil, NULL, 0);
4098		    }
4099		}
4100	      else
4101		{
4102		  bool do_display = true;
4103
4104		  if (FRAME_TERMCAP_P (SELECTED_FRAME ()))
   0x0000555555779820 <+4048>:	mov    0x335d01(%rip),%rax        # 0x555555aaf528 <selected_frame>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555779827 <+4055>:	lea    -0x5(%rax),%edx

775	}
776
777	INLINE void
778	(CHECK_TYPE) (int ok, Lisp_Object predicate, Lisp_Object x)
779	{
780	  lisp_h_CHECK_TYPE (ok, predicate, x);
781	}
782
783	/* Extract A's pointer value, assuming A's Lisp type is TYPE and the
784	   extracted pointer's type is CTYPE *.  When !USE_LSB_TAG this simply
785	   extracts A's low-order bits, as (uintptr_t) LISP_WORD_TAG (type) is
786	   always zero then.  */
787	#define XUNTAG(a, type, ctype) \
788	  ((ctype *) ((uintptr_t) XLP (a) - (uintptr_t) LISP_WORD_TAG (type)))
789
790	/* A forwarding pointer to a value.  It uses a generic pointer to
791	   avoid alignment bugs that could occur if it used a pointer to a
792	   union of the possible values (struct Lisp_Objfwd, struct
793	   Lisp_Intfwd, etc.).  The pointer is packaged inside a struct to
794	   help static checking.  */
795	typedef const struct Lisp_Fwd *lispfwd;
796	^L
797	/* Interned state of a symbol.  */
798
799	enum symbol_interned
800	{
801	  SYMBOL_UNINTERNED,		      /* not interned anywhere */
802	  SYMBOL_INTERNED,		      /* interned but not in initial obarray */
803	  SYMBOL_INTERNED_IN_INITIAL_OBARRAY  /* interned in initial obarray */
804	};
805
806	enum symbol_redirect
807	{
808	  SYMBOL_PLAINVAL,   /* plain var, value is in the `value' field */
809	  SYMBOL_VARALIAS,   /* var alias, value is really in the `alias' symbol */
810	  SYMBOL_LOCALIZED,  /* localized var, value is in the `blv' object */
811	  SYMBOL_FORWARDED   /* forwarding var, value is in `forward' */
812	};
813
814	enum symbol_trapped_write
815	{
816	  SYMBOL_UNTRAPPED_WRITE,  /* normal case, just set the value */
817	  SYMBOL_NOWRITE,          /* constant, cannot set, e.g. nil, t, :keyword */
818	  SYMBOL_TRAPPED_WRITE     /* trap the write, call watcher functions */
819	};
820
821	struct Lisp_Symbol
822	{
823	  GC_HEADER
824	  union
825	  {
826	    struct
827	    {
828	      bool_bf gcmarkbit : 1;
829
830	      /* Indicates where the value can be found.  */
831	      ENUM_BF (symbol_redirect) redirect : 2;
832
833	      ENUM_BF (symbol_trapped_write) trapped_write : 2;
834
835	      /* Interned state of the symbol.  */
836	      ENUM_BF (symbol_interned) interned : 2;
837
838	      /* True means that this variable has been explicitly declared
839		 special (with `defvar' etc), and shouldn't be lexically bound.  */
840	      bool_bf declared_special : 1;
841
842	      /* The symbol's name, as a Lisp string.  */
843	      Lisp_Object name;
844
845	      /* Value of the symbol or Qunbound if unbound.  Which alternative of the
846		 union is used depends on the `redirect' field above.  */
847	      union {
848		Lisp_Object value;
849		struct Lisp_Symbol *alias;
850		struct Lisp_Buffer_Local_Value *blv;
851		lispfwd fwd;
852	      } val;
853
854	      /* Function value of the symbol or Qnil if not fboundp.  */
855	      Lisp_Object function;
856
857	      /* The symbol's property list.  */
858	      Lisp_Object plist;
859
860	      /* Next symbol in obarray bucket, if the symbol is interned.  */
861	      struct Lisp_Symbol *next;
862	    } s;
863	    GCALIGNED_UNION_MEMBER
864	  } u;
865	};
866	static_assert (GCALIGNED (struct Lisp_Symbol));
867
868	/* Declare a Lisp-callable function.  The MAXARGS parameter has the same
869	   meaning as in the DEFUN macro, and is used to construct a prototype.  */
870	/* We can use the same trick as in the DEFUN macro to generate the
871	   appropriate prototype.  */
872	#define EXFUN(fnname, maxargs) \
873	  extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs
874
875	/* Note that the weird token-substitution semantics of ANSI C makes
876	   this work for MANY and UNEVALLED.  */
877	#define DEFUN_ARGS_MANY		(ptrdiff_t, Lisp_Object *)
878	#define DEFUN_ARGS_UNEVALLED	(Lisp_Object)
879	#define DEFUN_ARGS_0	(void)
880	#define DEFUN_ARGS_1	(Lisp_Object)
881	#define DEFUN_ARGS_2	(Lisp_Object, Lisp_Object)
882	#define DEFUN_ARGS_3	(Lisp_Object, Lisp_Object, Lisp_Object)
883	#define DEFUN_ARGS_4	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
884	#define DEFUN_ARGS_5	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
885				 Lisp_Object)
886	#define DEFUN_ARGS_6	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
887				 Lisp_Object, Lisp_Object)
888	#define DEFUN_ARGS_7	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
889				 Lisp_Object, Lisp_Object, Lisp_Object)
890	#define DEFUN_ARGS_8	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
891				 Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
892
893	/* Lisp_Word_tag is big enough for a possibly-shifted tag, to be
894	   added to a pointer value for conversion to a Lisp_Word.  */
895	#if LISP_WORDS_ARE_POINTERS
896	typedef uintptr_t Lisp_Word_tag;
897	#else
898	typedef EMACS_UINT Lisp_Word_tag;
899	#endif
900
901	/* A integer value tagged with TAG, and otherwise all zero.  */
902	#define LISP_WORD_TAG(tag) \
903	  ((Lisp_Word_tag) (tag) << (USE_LSB_TAG ? 0 : VALBITS))
904
905	/* An initializer for a Lisp_Object that contains TAG along with P.
906	   P can be a pointer or an integer.  The result is usable in a static
907	   initializer if TAG and P are both integer constant expressions.  */
908	#define TAG_PTR_INITIALLY(tag, p) \
909	  LISP_INITIALLY ((Lisp_Word) ((uintptr_t) (p) + LISP_WORD_TAG (tag)))
910
911	/* LISPSYM_INITIALLY (Qfoo) is equivalent to Qfoo except it is
912	   designed for use as a (possibly static) initializer.  */
913	#define LISPSYM_INITIALLY(name) \
914	  TAG_PTR_INITIALLY (Lisp_Symbol, (intptr_t) ((i##name) * sizeof *lispsym))
915
916	/* Declare extern constants for Lisp symbols.  These can be helpful
917	   when using a debugger like GDB, on older platforms where the debug
918	   format does not represent C macros.  However, they are unbounded
919	   and would just be asking for trouble if checking pointer bounds.  */
920	#define DEFINE_LISP_SYMBOL(name) \
921	  DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) \
922	  DEFINE_GDB_SYMBOL_END (LISPSYM_INITIALLY (name))
923
924	/* The index of the C-defined Lisp symbol SYM.
925	   This can be used in a static initializer.  */
926	#define SYMBOL_INDEX(sym) i##sym
927
928	/* By default, define macros for Qt, etc., as this leads to a bit
929	   better performance in the core Emacs interpreter.  A plugin can
930	   define DEFINE_NON_NIL_Q_SYMBOL_MACROS to be false, to be portable to
931	   other Emacs instances that assign different values to Qt, etc.  */
932	#ifndef DEFINE_NON_NIL_Q_SYMBOL_MACROS
933	# define DEFINE_NON_NIL_Q_SYMBOL_MACROS true
934	#endif
935
936	/* True if N is a power of 2.  N should be positive.  */
937
938	#define POWER_OF_2(n) (((n) & ((n) - 1)) == 0)
939
940	/* Return X rounded to the next multiple of Y.  Y should be positive,
941	   and Y - 1 + X should not overflow.  Arguments should not have side
942	   effects, as they are evaluated more than once.  Tune for Y being a
943	   power of 2.  */
944
945	#define ROUNDUP(x, y) (POWER_OF_2 (y)					\
946	                       ? ((y) - 1 + (x)) & ~ ((y) - 1)			\
947	                       : ((y) - 1 + (x)) - ((y) - 1 + (x)) % (y))
948
949	#include <globals.h>
950
951	/* Header of vector-like objects.  This documents the layout constraints on
952	   vectors and pseudovectors (objects of PVEC_xxx subtype).  It also prevents
953	   compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR
954	   and PSEUDOVECTORP cast their pointers to struct vectorlike_header *,
955	   because when two such pointers potentially alias, a compiler won't
956	   incorrectly reorder loads and stores to their size fields.  See
957	   Bug#8546.   */
958	struct vectorlike_header
959	  {
960	    /* The `size' header word, W bits wide, has one of two forms
961	       discriminated by the second-highest bit (PSEUDOVECTOR_FLAG):
962
963	         1   1                    W-2
964	       +---+---+-------------------------------------+
965	       | M | 0 |                 SIZE                |  vector
966	       +---+---+-------------------------------------+
967
968	         1   1    W-32      6       12         12
969	       +---+---+--------+------+----------+----------+
970	       | M | 1 | unused | TYPE | RESTSIZE | LISPSIZE |  pseudovector
971	       +---+---+--------+------+----------+----------+
972
973	       M (ARRAY_MARK_FLAG) holds the GC mark bit.
974
975	       SIZE     is the length (number of slots) of a regular Lisp vector,
976	                and the object layout is struct Lisp_Vector.
977
978	       TYPE     is the pseudovector subtype (enum pvec_type).
979
980	       LISPSIZE is the number of Lisp_Object fields at the beginning of the
981	                object (after the header).  These are always traced by the GC.
982
983	       RESTSIZE is the number of fields (in word_size units) following.
984	                These are not automatically traced by the GC.
985	                For PVEC_BOOL and statically allocated PVEC_SUBR, RESTSIZE is 0.
986	                (The block size for PVEC_BOOL is computed from its own size
987	                field, to avoid being restricted by the 12-bit RESTSIZE field.)
988	    */
989	    GC_HEADER
990	    ptrdiff_t size;
991	  };
992
993	struct Lisp_Symbol_With_Pos
994	{
995	  struct vectorlike_header header;
996	  Lisp_Object sym;              /* A symbol */
997	  Lisp_Object pos;              /* A fixnum */
998	} GCALIGNED_STRUCT;
999
1000	/* In the size word of a vector, this bit means the vector has been marked.  */
1001
1002	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG)
1003	# define ARRAY_MARK_FLAG PTRDIFF_MIN
1004	DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG)
1005
1006	/* In the size word of a struct Lisp_Vector, this bit means it's really
1007	   some other vector-like object.  */
1008	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG)
1009	# define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2)
1010	DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
1011
1012	/* In a pseudovector, the size field actually contains a word with one
1013	   PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
1014	   with PVEC_TYPE_MASK to indicate the actual type.  */
1015	enum pvec_type
1016	{
1017	  PVEC_NORMAL_VECTOR,	/* Should be first, for sxhash_obj.  */
1018	  PVEC_FREE,
1019	  PVEC_BIGNUM,
1020	  PVEC_MARKER,
1021	  PVEC_OVERLAY,
1022	  PVEC_FINALIZER,
1023	  PVEC_SYMBOL_WITH_POS,
1024	  PVEC_MISC_PTR,
1025	  PVEC_USER_PTR,
1026	  PVEC_PROCESS,
1027	  PVEC_FRAME,
1028	  PVEC_WINDOW,
1029	  PVEC_BOOL_VECTOR,
1030	  PVEC_BUFFER,
1031	  PVEC_HASH_TABLE,
1032	#ifdef HAVE_MPS
1033	  PVEC_WEAK_HASH_TABLE,
1034	#endif
1035	  PVEC_OBARRAY,
1036	  PVEC_TERMINAL,
1037	  PVEC_WINDOW_CONFIGURATION,
1038	  PVEC_SUBR,
1039	  PVEC_OTHER,            /* Should never be visible to Elisp code.  */
1040	  PVEC_XWIDGET,
1041	  PVEC_XWIDGET_VIEW,
1042	  PVEC_THREAD,
1043	  PVEC_MUTEX,
1044	  PVEC_CONDVAR,
1045	  PVEC_MODULE_FUNCTION,
1046	  PVEC_MODULE_GLOBAL_REFERENCE,
1047	  PVEC_NATIVE_COMP_UNIT,
1048	  PVEC_TS_PARSER,
1049	  PVEC_TS_NODE,
1050	  PVEC_TS_COMPILED_QUERY,
1051	  PVEC_SQLITE,
1052
1053	  /* These should be last, for internal_equal and sxhash_obj.  */
1054	  PVEC_CLOSURE,
1055	  PVEC_CHAR_TABLE,
1056	  PVEC_SUB_CHAR_TABLE,
1057	  PVEC_RECORD,
1058	  PVEC_FONT,
1059	  PVEC_TAG_MAX = PVEC_FONT  /* Keep this equal to the highest member.  */
1060	};
1061
1062	enum More_Lisp_Bits
1063	  {
1064	    /* For convenience, we also store the number of elements in these bits.
1065	       Note that this size is not necessarily the memory-footprint size, but
1066	       only the number of Lisp_Object fields (that need to be traced by GC).
1067	       The distinction is used, e.g., by Lisp_Process, which places extra
1068	       non-Lisp_Object fields at the end of the structure.  */
1069	    PSEUDOVECTOR_SIZE_BITS = 12,
1070	    PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1,
1071
1072	    /* To calculate the memory footprint of the pseudovector, it's useful
1073	       to store the size of non-Lisp area in word_size units here.  */
1074	    PSEUDOVECTOR_REST_BITS = 12,
1075	    PSEUDOVECTOR_REST_MASK = (((1 << PSEUDOVECTOR_REST_BITS) - 1)
1076				      << PSEUDOVECTOR_SIZE_BITS),
1077
1078	    /* Used to extract pseudovector subtype information.  */
1079	    PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS,
1080	    PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS
1081	  };
1082	^L
1083	/* These functions extract various sorts of values from a Lisp_Object.
1084	   For example, if tem is a Lisp_Object whose type is Lisp_Cons,
1085	   XCONS (tem) is the struct Lisp_Cons * pointing to the memory for
1086	   that cons.  */
1087
1088	/* Largest and smallest representable fixnum values.  These are the C
1089	   values.  They are macros for use in #if and static initializers.  */
1090	#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
1091	#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
1092	^L
1093	INLINE bool
1094	PSEUDOVECTORP (Lisp_Object a, int code)
1095	{
1096	  return (lisp_h_VECTORLIKEP (a)
1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577982a <+4058>:	and    $0x7,%edx
   0x000055555577982d <+4061>:	jne    0x5555555b2855 <read_char-1859579>

1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x0000555555779833 <+4067>:	mov    0x3(%rax),%rsi

1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x0000555555779837 <+4071>:	lea    -0x5(%rax),%rdx
   0x000055555577983b <+4075>:	movabs $0x400000000a000000,%rdi

1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x0000555555779845 <+4085>:	and    %r13,%rsi

1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x0000555555779848 <+4088>:	cmp    %rdi,%rsi
   0x000055555577984b <+4091>:	jne    0x5555555b2855 <read_char-1859579>

./src/keyboard.c:
4104		  if (FRAME_TERMCAP_P (SELECTED_FRAME ()))
   0x0000555555779851 <+4097>:	mov    0x208(%rdx),%rcx
   0x0000555555779858 <+4104>:	test   %rcx,%rcx
   0x000055555577985b <+4107>:	je     0x5555555b2855 <read_char-1859579>
   0x0000555555779861 <+4113>:	movzbl 0x143(%rdx),%eax
   0x0000555555779868 <+4120>:	and    $0xf,%eax
   0x000055555577986b <+4123>:	cmp    $0x1,%al
   0x000055555577986d <+4125>:	je     0x5555557798a0 <read_char+4176>
   0x000055555577986f <+4127>:	mov    $0x1,%ecx

./src/lisp.h:
1184	  return a;
   0x0000555555779874 <+4132>:	sub    $0x8,%rsp
   0x0000555555779878 <+4136>:	xor    %r9d,%r9d
   0x000055555577987b <+4139>:	xor    %r8d,%r8d
   0x000055555577987e <+4142>:	mov    $0xffffffff,%edx
   0x0000555555779883 <+4147>:	push   $0x0
   0x0000555555779885 <+4149>:	xor    %esi,%esi
   0x0000555555779887 <+4151>:	xor    %edi,%edi
   0x0000555555779889 <+4153>:	call   0x5555558a0d10 <wait_reading_process_output>
   0x000055555577988e <+4158>:	pop    %r10
   0x0000555555779890 <+4160>:	pop    %r11
   0x0000555555779892 <+4162>:	jmp    0x555555779775 <read_char+3877>
   0x0000555555779897 <+4167>:	nopw   0x0(%rax,%rax,1)

./src/keyboard.c:
4111		      if (tty->showing_menu)
   0x00005555557798a0 <+4176>:	mov    0x58(%rcx),%rax
   0x00005555557798a4 <+4180>:	movzbl 0x2270(%rax),%ecx
   0x00005555557798ab <+4187>:	shr    $0x2,%cl
   0x00005555557798ae <+4190>:	xor    $0x1,%ecx

4112			do_display = false;
4113		    }
4114
4115		  wait_reading_process_output (0, 0, -1, do_display, Qnil, NULL, 0);
   0x00005555557798b1 <+4193>:	and    $0x1,%ecx
   0x00005555557798b4 <+4196>:	jmp    0x555555779874 <read_char+4132>
   0x00005555557798b6 <+4198>:	cs nopw 0x0(%rax,%rax,1)

4130	#endif
4131
4132	  if (CONSP (Vunread_command_events))
   0x00005555557798c0 <+4208>:	mov    0x3a77b1(%rip),%rdx        # 0x555555b21078 <globals+3128>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x00005555557798c7 <+4215>:	lea    -0x3(%rdx),%eax

./src/keyboard.c:
4132	  if (CONSP (Vunread_command_events))
   0x00005555557798ca <+4218>:	test   $0x7,%al
   0x00005555557798cc <+4220>:	je     0x555555779ea8 <read_char+5720>

4154		  || NILP (Vtext_conversion_edits))
4155		obj = Qnil;
4156	    }
4157	  else
4158	#endif
4159	  /* At this point, we know that there is a readable event available
4160	     somewhere.  If the event queue is empty, then there must be a
4161	     mouse movement enabled and available.  */
4162	  if (kbd_fetch_ptr != kbd_store_ptr)
   0x00005555557798d2 <+4226>:	mov    0x34c83f(%rip),%r8        # 0x555555ac6118 <kbd_fetch_ptr>
   0x00005555557798d9 <+4233>:	mov    0x34c830(%rip),%rdx        # 0x555555ac6110 <kbd_store_ptr>
   0x00005555557798e0 <+4240>:	cmp    %rdx,%r8
   0x00005555557798e3 <+4243>:	je     0x555555779fc8 <read_char+6008>

4163	    {
4164	      union buffered_input_event *event = kbd_fetch_ptr;
4165
4166	      *kbp = event_to_kboard (&event->ie);
   0x00005555557798e9 <+4249>:	mov    %r8,%rdi
   0x00005555557798ec <+4252>:	call   0x5555557652d0 <event_to_kboard>

4167	      if (*kbp == 0)
   0x00005555557798f1 <+4257>:	movzwl (%r8),%ecx

4168		*kbp = current_kboard;  /* Better than returning null ptr?  */
   0x00005555557798f5 <+4261>:	test   %rax,%rax
   0x00005555557798f8 <+4264>:	cmove  0x38c960(%rip),%rax        # 0x555555b06260 <current_kboard>
   0x0000555555779900 <+4272>:	mov    %rax,-0x498(%rbp)

4169
4170	      obj = Qnil;
4171
4172	      /* These two kinds of events get special handling
4173		 and don't actually appear to the command loop.
4174		 We return nil for them.  */
4175	      switch (event->kind)
   0x0000555555779907 <+4279>:	cmp    $0x25,%cx
   0x000055555577990b <+4283>:	ja     0x555555779933 <read_char+4323>
   0x000055555577990d <+4285>:	mov    $0x1,%eax
   0x0000555555779912 <+4290>:	shl    %cl,%rax
   0x0000555555779915 <+4293>:	test   $0xffc8d001,%eax
   0x000055555577991a <+4298>:	jne    0x55555577a630 <read_char+7648>
   0x0000555555779920 <+4304>:	test   $0xc,%ah
   0x0000555555779923 <+4307>:	jne    0x55555577a5ae <read_char+7518>
   0x0000555555779929 <+4313>:	cmp    $0x25,%cx
   0x000055555577992d <+4317>:	je     0x55555577a4ea <read_char+7322>

4289	          kbd_fetch_ptr = next_kbd_event (event);
4290	        }
4291	        break;
4292	      default:
4293		{
4294		  /* If this event is on a different frame, return a
4295		     switch-frame this time, and leave the event in the queue
4296		     for next time.  */
4297		  Lisp_Object frame;
4298		  Lisp_Object focus;
4299
4300		  frame = event->ie.frame_or_window;
   0x0000555555779933 <+4323>:	mov    0x28(%r8),%rdi

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555779937 <+4327>:	lea    -0x3(%rdi),%eax

./src/keyboard.c:
4301		  if (CONSP (frame))
   0x000055555577993a <+4330>:	test   $0x7,%al
   0x000055555577993c <+4332>:	je     0x55555577ac7a <read_char+9258>

./src/lisp.h:
774	  return lisp_h_TAGGEDP (a, tag);
   0x0000555555779942 <+4338>:	lea    -0x5(%rdi),%eax

775	}
776
777	INLINE void
778	(CHECK_TYPE) (int ok, Lisp_Object predicate, Lisp_Object x)
779	{
780	  lisp_h_CHECK_TYPE (ok, predicate, x);
781	}
782
783	/* Extract A's pointer value, assuming A's Lisp type is TYPE and the
784	   extracted pointer's type is CTYPE *.  When !USE_LSB_TAG this simply
785	   extracts A's low-order bits, as (uintptr_t) LISP_WORD_TAG (type) is
786	   always zero then.  */
787	#define XUNTAG(a, type, ctype) \
788	  ((ctype *) ((uintptr_t) XLP (a) - (uintptr_t) LISP_WORD_TAG (type)))
789
790	/* A forwarding pointer to a value.  It uses a generic pointer to
791	   avoid alignment bugs that could occur if it used a pointer to a
792	   union of the possible values (struct Lisp_Objfwd, struct
793	   Lisp_Intfwd, etc.).  The pointer is packaged inside a struct to
794	   help static checking.  */
795	typedef const struct Lisp_Fwd *lispfwd;
796	^L
797	/* Interned state of a symbol.  */
798
799	enum symbol_interned
800	{
801	  SYMBOL_UNINTERNED,		      /* not interned anywhere */
802	  SYMBOL_INTERNED,		      /* interned but not in initial obarray */
803	  SYMBOL_INTERNED_IN_INITIAL_OBARRAY  /* interned in initial obarray */
804	};
805
806	enum symbol_redirect
807	{
808	  SYMBOL_PLAINVAL,   /* plain var, value is in the `value' field */
809	  SYMBOL_VARALIAS,   /* var alias, value is really in the `alias' symbol */
810	  SYMBOL_LOCALIZED,  /* localized var, value is in the `blv' object */
811	  SYMBOL_FORWARDED   /* forwarding var, value is in `forward' */
812	};
813
814	enum symbol_trapped_write
815	{
816	  SYMBOL_UNTRAPPED_WRITE,  /* normal case, just set the value */
817	  SYMBOL_NOWRITE,          /* constant, cannot set, e.g. nil, t, :keyword */
818	  SYMBOL_TRAPPED_WRITE     /* trap the write, call watcher functions */
819	};
820
821	struct Lisp_Symbol
822	{
823	  GC_HEADER
824	  union
825	  {
826	    struct
827	    {
828	      bool_bf gcmarkbit : 1;
829
830	      /* Indicates where the value can be found.  */
831	      ENUM_BF (symbol_redirect) redirect : 2;
832
833	      ENUM_BF (symbol_trapped_write) trapped_write : 2;
834
835	      /* Interned state of the symbol.  */
836	      ENUM_BF (symbol_interned) interned : 2;
837
838	      /* True means that this variable has been explicitly declared
839		 special (with `defvar' etc), and shouldn't be lexically bound.  */
840	      bool_bf declared_special : 1;
841
842	      /* The symbol's name, as a Lisp string.  */
843	      Lisp_Object name;
844
845	      /* Value of the symbol or Qunbound if unbound.  Which alternative of the
846		 union is used depends on the `redirect' field above.  */
847	      union {
848		Lisp_Object value;
849		struct Lisp_Symbol *alias;
850		struct Lisp_Buffer_Local_Value *blv;
851		lispfwd fwd;
852	      } val;
853
854	      /* Function value of the symbol or Qnil if not fboundp.  */
855	      Lisp_Object function;
856
857	      /* The symbol's property list.  */
858	      Lisp_Object plist;
859
860	      /* Next symbol in obarray bucket, if the symbol is interned.  */
861	      struct Lisp_Symbol *next;
862	    } s;
863	    GCALIGNED_UNION_MEMBER
864	  } u;
865	};
866	static_assert (GCALIGNED (struct Lisp_Symbol));
867
868	/* Declare a Lisp-callable function.  The MAXARGS parameter has the same
869	   meaning as in the DEFUN macro, and is used to construct a prototype.  */
870	/* We can use the same trick as in the DEFUN macro to generate the
871	   appropriate prototype.  */
872	#define EXFUN(fnname, maxargs) \
873	  extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs
874
875	/* Note that the weird token-substitution semantics of ANSI C makes
876	   this work for MANY and UNEVALLED.  */
877	#define DEFUN_ARGS_MANY		(ptrdiff_t, Lisp_Object *)
878	#define DEFUN_ARGS_UNEVALLED	(Lisp_Object)
879	#define DEFUN_ARGS_0	(void)
880	#define DEFUN_ARGS_1	(Lisp_Object)
881	#define DEFUN_ARGS_2	(Lisp_Object, Lisp_Object)
882	#define DEFUN_ARGS_3	(Lisp_Object, Lisp_Object, Lisp_Object)
883	#define DEFUN_ARGS_4	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
884	#define DEFUN_ARGS_5	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
885				 Lisp_Object)
886	#define DEFUN_ARGS_6	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
887				 Lisp_Object, Lisp_Object)
888	#define DEFUN_ARGS_7	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
889				 Lisp_Object, Lisp_Object, Lisp_Object)
890	#define DEFUN_ARGS_8	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
891				 Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
892
893	/* Lisp_Word_tag is big enough for a possibly-shifted tag, to be
894	   added to a pointer value for conversion to a Lisp_Word.  */
895	#if LISP_WORDS_ARE_POINTERS
896	typedef uintptr_t Lisp_Word_tag;
897	#else
898	typedef EMACS_UINT Lisp_Word_tag;
899	#endif
900
901	/* A integer value tagged with TAG, and otherwise all zero.  */
902	#define LISP_WORD_TAG(tag) \
903	  ((Lisp_Word_tag) (tag) << (USE_LSB_TAG ? 0 : VALBITS))
904
905	/* An initializer for a Lisp_Object that contains TAG along with P.
906	   P can be a pointer or an integer.  The result is usable in a static
907	   initializer if TAG and P are both integer constant expressions.  */
908	#define TAG_PTR_INITIALLY(tag, p) \
909	  LISP_INITIALLY ((Lisp_Word) ((uintptr_t) (p) + LISP_WORD_TAG (tag)))
910
911	/* LISPSYM_INITIALLY (Qfoo) is equivalent to Qfoo except it is
912	   designed for use as a (possibly static) initializer.  */
913	#define LISPSYM_INITIALLY(name) \
914	  TAG_PTR_INITIALLY (Lisp_Symbol, (intptr_t) ((i##name) * sizeof *lispsym))
915
916	/* Declare extern constants for Lisp symbols.  These can be helpful
917	   when using a debugger like GDB, on older platforms where the debug
918	   format does not represent C macros.  However, they are unbounded
919	   and would just be asking for trouble if checking pointer bounds.  */
920	#define DEFINE_LISP_SYMBOL(name) \
921	  DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) \
922	  DEFINE_GDB_SYMBOL_END (LISPSYM_INITIALLY (name))
923
924	/* The index of the C-defined Lisp symbol SYM.
925	   This can be used in a static initializer.  */
926	#define SYMBOL_INDEX(sym) i##sym
927
928	/* By default, define macros for Qt, etc., as this leads to a bit
929	   better performance in the core Emacs interpreter.  A plugin can
930	   define DEFINE_NON_NIL_Q_SYMBOL_MACROS to be false, to be portable to
931	   other Emacs instances that assign different values to Qt, etc.  */
932	#ifndef DEFINE_NON_NIL_Q_SYMBOL_MACROS
933	# define DEFINE_NON_NIL_Q_SYMBOL_MACROS true
934	#endif
935
936	/* True if N is a power of 2.  N should be positive.  */
937
938	#define POWER_OF_2(n) (((n) & ((n) - 1)) == 0)
939
940	/* Return X rounded to the next multiple of Y.  Y should be positive,
941	   and Y - 1 + X should not overflow.  Arguments should not have side
942	   effects, as they are evaluated more than once.  Tune for Y being a
943	   power of 2.  */
944
945	#define ROUNDUP(x, y) (POWER_OF_2 (y)					\
946	                       ? ((y) - 1 + (x)) & ~ ((y) - 1)			\
947	                       : ((y) - 1 + (x)) - ((y) - 1 + (x)) % (y))
948
949	#include <globals.h>
950
951	/* Header of vector-like objects.  This documents the layout constraints on
952	   vectors and pseudovectors (objects of PVEC_xxx subtype).  It also prevents
953	   compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR
954	   and PSEUDOVECTORP cast their pointers to struct vectorlike_header *,
955	   because when two such pointers potentially alias, a compiler won't
956	   incorrectly reorder loads and stores to their size fields.  See
957	   Bug#8546.   */
958	struct vectorlike_header
959	  {
960	    /* The `size' header word, W bits wide, has one of two forms
961	       discriminated by the second-highest bit (PSEUDOVECTOR_FLAG):
962
963	         1   1                    W-2
964	       +---+---+-------------------------------------+
965	       | M | 0 |                 SIZE                |  vector
966	       +---+---+-------------------------------------+
967
968	         1   1    W-32      6       12         12
969	       +---+---+--------+------+----------+----------+
970	       | M | 1 | unused | TYPE | RESTSIZE | LISPSIZE |  pseudovector
971	       +---+---+--------+------+----------+----------+
972
973	       M (ARRAY_MARK_FLAG) holds the GC mark bit.
974
975	       SIZE     is the length (number of slots) of a regular Lisp vector,
976	                and the object layout is struct Lisp_Vector.
977
978	       TYPE     is the pseudovector subtype (enum pvec_type).
979
980	       LISPSIZE is the number of Lisp_Object fields at the beginning of the
981	                object (after the header).  These are always traced by the GC.
982
983	       RESTSIZE is the number of fields (in word_size units) following.
984	                These are not automatically traced by the GC.
985	                For PVEC_BOOL and statically allocated PVEC_SUBR, RESTSIZE is 0.
986	                (The block size for PVEC_BOOL is computed from its own size
987	                field, to avoid being restricted by the 12-bit RESTSIZE field.)
988	    */
989	    GC_HEADER
990	    ptrdiff_t size;
991	  };
992
993	struct Lisp_Symbol_With_Pos
994	{
995	  struct vectorlike_header header;
996	  Lisp_Object sym;              /* A symbol */
997	  Lisp_Object pos;              /* A fixnum */
998	} GCALIGNED_STRUCT;
999
1000	/* In the size word of a vector, this bit means the vector has been marked.  */
1001
1002	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG)
1003	# define ARRAY_MARK_FLAG PTRDIFF_MIN
1004	DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG)
1005
1006	/* In the size word of a struct Lisp_Vector, this bit means it's really
1007	   some other vector-like object.  */
1008	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG)
1009	# define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2)
1010	DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
1011
1012	/* In a pseudovector, the size field actually contains a word with one
1013	   PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
1014	   with PVEC_TYPE_MASK to indicate the actual type.  */
1015	enum pvec_type
1016	{
1017	  PVEC_NORMAL_VECTOR,	/* Should be first, for sxhash_obj.  */
1018	  PVEC_FREE,
1019	  PVEC_BIGNUM,
1020	  PVEC_MARKER,
1021	  PVEC_OVERLAY,
1022	  PVEC_FINALIZER,
1023	  PVEC_SYMBOL_WITH_POS,
1024	  PVEC_MISC_PTR,
1025	  PVEC_USER_PTR,
1026	  PVEC_PROCESS,
1027	  PVEC_FRAME,
1028	  PVEC_WINDOW,
1029	  PVEC_BOOL_VECTOR,
1030	  PVEC_BUFFER,
1031	  PVEC_HASH_TABLE,
1032	#ifdef HAVE_MPS
1033	  PVEC_WEAK_HASH_TABLE,
1034	#endif
1035	  PVEC_OBARRAY,
1036	  PVEC_TERMINAL,
1037	  PVEC_WINDOW_CONFIGURATION,
1038	  PVEC_SUBR,
1039	  PVEC_OTHER,            /* Should never be visible to Elisp code.  */
1040	  PVEC_XWIDGET,
1041	  PVEC_XWIDGET_VIEW,
1042	  PVEC_THREAD,
1043	  PVEC_MUTEX,
1044	  PVEC_CONDVAR,
1045	  PVEC_MODULE_FUNCTION,
1046	  PVEC_MODULE_GLOBAL_REFERENCE,
1047	  PVEC_NATIVE_COMP_UNIT,
1048	  PVEC_TS_PARSER,
1049	  PVEC_TS_NODE,
1050	  PVEC_TS_COMPILED_QUERY,
1051	  PVEC_SQLITE,
1052
1053	  /* These should be last, for internal_equal and sxhash_obj.  */
1054	  PVEC_CLOSURE,
1055	  PVEC_CHAR_TABLE,
1056	  PVEC_SUB_CHAR_TABLE,
1057	  PVEC_RECORD,
1058	  PVEC_FONT,
1059	  PVEC_TAG_MAX = PVEC_FONT  /* Keep this equal to the highest member.  */
1060	};
1061
1062	enum More_Lisp_Bits
1063	  {
1064	    /* For convenience, we also store the number of elements in these bits.
1065	       Note that this size is not necessarily the memory-footprint size, but
1066	       only the number of Lisp_Object fields (that need to be traced by GC).
1067	       The distinction is used, e.g., by Lisp_Process, which places extra
1068	       non-Lisp_Object fields at the end of the structure.  */
1069	    PSEUDOVECTOR_SIZE_BITS = 12,
1070	    PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1,
1071
1072	    /* To calculate the memory footprint of the pseudovector, it's useful
1073	       to store the size of non-Lisp area in word_size units here.  */
1074	    PSEUDOVECTOR_REST_BITS = 12,
1075	    PSEUDOVECTOR_REST_MASK = (((1 << PSEUDOVECTOR_REST_BITS) - 1)
1076				      << PSEUDOVECTOR_SIZE_BITS),
1077
1078	    /* Used to extract pseudovector subtype information.  */
1079	    PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS,
1080	    PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS
1081	  };
1082	^L
1083	/* These functions extract various sorts of values from a Lisp_Object.
1084	   For example, if tem is a Lisp_Object whose type is Lisp_Cons,
1085	   XCONS (tem) is the struct Lisp_Cons * pointing to the memory for
1086	   that cons.  */
1087
1088	/* Largest and smallest representable fixnum values.  These are the C
1089	   values.  They are macros for use in #if and static initializers.  */
1090	#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
1091	#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
1092	^L
1093	INLINE bool
1094	PSEUDOVECTORP (Lisp_Object a, int code)
1095	{
1096	  return (lisp_h_VECTORLIKEP (a)
1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x0000555555779945 <+4341>:	test   $0x7,%al
   0x0000555555779947 <+4343>:	jne    0x55555577ac64 <read_char+9236>

1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x000055555577994d <+4349>:	movabs $0x400000003f000000,%rax
   0x0000555555779957 <+4359>:	and    0x3(%rdi),%rax

1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577995b <+4363>:	lea    -0x5(%rdi),%rdx
   0x000055555577995f <+4367>:	movabs $0x400000000b000000,%rcx
   0x0000555555779969 <+4377>:	cmp    %rcx,%rax
   0x000055555577996c <+4380>:	je     0x55555577bd30 <read_char+13536>

./src/keyboard.c:
4306		  focus = FRAME_FOCUS_FRAME (XFRAME (frame));
   0x0000555555779972 <+4386>:	cmpb   $0x0,0x3a2a07(%rip)        # 0x555555b1c380 <suppress_checking>
   0x0000555555779979 <+4393>:	jne    0x55555577998e <read_char+4414>

./src/lisp.h:
1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577997b <+4395>:	movabs $0x400000000a000000,%rcx
   0x0000555555779985 <+4405>:	cmp    %rcx,%rax
   0x0000555555779988 <+4408>:	jne    0x55555577d109 <read_char+18617>

./src/keyboard.c:
4306		  focus = FRAME_FOCUS_FRAME (XFRAME (frame));
   0x000055555577998e <+4414>:	mov    0x38(%rdx),%rbx

4308		    frame = focus;
4309
4310		  if (!EQ (frame, internal_last_event_frame)
   0x0000555555779992 <+4418>:	mov    0x38c78f(%rip),%rsi        # 0x555555b06128 <internal_last_event_frame>
   0x0000555555779999 <+4425>:	mov    %r8,-0x520(%rbp)

4307		  if (! NILP (focus))
   0x00005555557799a0 <+4432>:	test   %rbx,%rbx
   0x00005555557799a3 <+4435>:	cmove  %rdi,%rbx

4308		    frame = focus;
4309
4310		  if (!EQ (frame, internal_last_event_frame)
   0x00005555557799a7 <+4439>:	xor    %r14d,%r14d
   0x00005555557799aa <+4442>:	mov    %rbx,%rdi
   0x00005555557799ad <+4445>:	call   0x555555764470 <EQ>
   0x00005555557799b2 <+4450>:	mov    -0x520(%rbp),%r8
   0x00005555557799b9 <+4457>:	test   %al,%al
   0x00005555557799bb <+4459>:	je     0x55555577ac1c <read_char+9164>

4312		    obj = make_lispy_switch_frame (frame);
4313		  internal_last_event_frame = frame;
   0x00005555557799c1 <+4465>:	mov    %rbx,0x38c760(%rip)        # 0x555555b06128 <internal_last_event_frame>

./src/lisp.h:
1184	  return a;
   0x00005555557799c8 <+4472>:	mov    0x38(%r8),%rbx

./src/keyboard.c:
4315		  if (EQ (event->ie.device, Qt))
   0x00005555557799cc <+4476>:	mov    $0x38,%esi
   0x00005555557799d1 <+4481>:	mov    %r8,-0x528(%rbp)
   0x00005555557799d8 <+4488>:	mov    %rbx,%rdi
   0x00005555557799db <+4491>:	call   0x555555764470 <EQ>
   0x00005555557799e0 <+4496>:	mov    -0x528(%rbp),%r8
   0x00005555557799e7 <+4503>:	test   %al,%al
   0x00005555557799e9 <+4505>:	je     0x55555577aac8 <read_char+8824>

4316		    Vlast_event_device = ((event->ie.kind == ASCII_KEYSTROKE_EVENT
   0x00005555557799ef <+4511>:	movzwl (%r8),%eax

4317					   || event->ie.kind == MULTIBYTE_CHAR_KEYSTROKE_EVENT
4318					   || event->ie.kind == NON_ASCII_KEYSTROKE_EVENT)
   0x00005555557799f3 <+4515>:	lea    -0x1(%rax),%edx

4319					  ? virtual_core_keyboard_name
4320					  : virtual_core_pointer_name);
   0x00005555557799f6 <+4518>:	cmp    $0x2,%dx
   0x00005555557799fa <+4522>:	ja     0x55555577addd <read_char+9613>

4316		    Vlast_event_device = ((event->ie.kind == ASCII_KEYSTROKE_EVENT
   0x0000555555779a00 <+4528>:	mov    0x38cb89(%rip),%rdx        # 0x555555b06590 <virtual_core_keyboard_name>
   0x0000555555779a07 <+4535>:	mov    %rdx,0x3a7082(%rip)        # 0x555555b20a90 <globals+1616>

4323
4324		  /* If we didn't decide to make a switch-frame event, go ahead
4325		     and build a real event from the queue entry.  */
4326		  if (NILP (obj))
   0x0000555555779a0e <+4542>:	test   %r14,%r14
   0x0000555555779a11 <+4545>:	je     0x55555577aae6 <read_char+8854>

3621	  if (kbd_fetch_ptr != kbd_store_ptr)
   0x0000555555779a17 <+4551>:	mov    0x34c6fa(%rip),%r8        # 0x555555ac6118 <kbd_fetch_ptr>
   0x0000555555779a1e <+4558>:	mov    0x34c6eb(%rip),%rdx        # 0x555555ac6110 <kbd_store_ptr>
   0x0000555555779a25 <+4565>:	mov    $0x1,%eax
   0x0000555555779a2a <+4570>:	cmp    %rdx,%r8
   0x0000555555779a2d <+4573>:	je     0x55555577a198 <read_char+6472>

4515	    obj = Qnil;
4516	#endif
4517	  else
4518	    /* We were promised by the above while loop that there was
4519	       something for us to read!  */
4520	    emacs_abort ();
4521
4522	  input_pending = readable_events (0);
   0x0000555555779a33 <+4579>:	mov    %al,0x38c6e8(%rip)        # 0x555555b06121 <input_pending>

4523
4524	  Vlast_event_frame = internal_last_event_frame;
   0x0000555555779a39 <+4585>:	mov    0x38c6e8(%rip),%rax        # 0x555555b06128 <internal_last_event_frame>
   0x0000555555779a40 <+4592>:	mov    %rax,0x3a7051(%rip)        # 0x555555b20a98 <globals+1624>

./src/lisp.h:
1184	  return a;
   0x0000555555779a47 <+4599>:	mov    -0x4a0(%rbp),%rdi
   0x0000555555779a4e <+4606>:	xor    %esi,%esi
   0x0000555555779a50 <+4608>:	call   0x5555558204b0 <unbind_to>

./src/keyboard.c:
2339	  if (! NILP (c) && (kb != current_kboard))
   0x0000555555779a55 <+4613>:	test   %r14,%r14
   0x0000555555779a58 <+4616>:	je     0x55555577bfdb <read_char+14219>
   0x0000555555779a5e <+4622>:	mov    -0x498(%rbp),%rax
   0x0000555555779a65 <+4629>:	cmp    %rax,0x38c7f4(%rip)        # 0x555555b06260 <current_kboard>
   0x0000555555779a6c <+4636>:	je     0x55555577acbb <read_char+9323>

2340	    {
2341	      Lisp_Object last = KVAR (kb, kbd_queue);
   0x0000555555779a72 <+4642>:	mov    0x40(%rax),%rax

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555779a76 <+4646>:	lea    -0x3(%rax),%edx

./src/keyboard.c:
2342	      if (CONSP (last))
   0x0000555555779a79 <+4649>:	and    $0x7,%edx
   0x0000555555779a7c <+4652>:	je     0x555555779f28 <read_char+5848>

2350	        kset_kbd_queue (kb, list1 (c));
   0x0000555555779a82 <+4658>:	mov    %r14,%rdi
   0x0000555555779a85 <+4661>:	call   0x5555557ef5c0 <list1>

455	  kb->kbd_queue_ = val;
   0x0000555555779a8a <+4666>:	mov    -0x498(%rbp),%rbx
   0x0000555555779a91 <+4673>:	mov    %rax,0x40(%rbx)

2353	      kb->kbd_queue_has_data = true;
   0x0000555555779a95 <+4677>:	mov    -0x498(%rbp),%rax

2354	      c = Qnil;
2355	      if (single_kboard)
   0x0000555555779a9c <+4684>:	cmpb   $0x0,0x38cb95(%rip)        # 0x555555b06638 <single_kboard>

2353	      kb->kbd_queue_has_data = true;
   0x0000555555779aa3 <+4691>:	movb   $0x1,0xb8(%rax)

2354	      c = Qnil;
2355	      if (single_kboard)
   0x0000555555779aaa <+4698>:	jne    0x5555557794b0 <read_char+3168>

2356	        goto start;
2357	      current_kboard = kb;
   0x0000555555779ab0 <+4704>:	mov    %rax,0x38c7a9(%rip)        # 0x555555b06260 <current_kboard>
   0x0000555555779ab7 <+4711>:	mov    -0x508(%rbp),%r15

2358	      return make_fixnum (-2);
   0x0000555555779abe <+4718>:	mov    $0xfffffffffffffffa,%r14
   0x0000555555779ac5 <+4725>:	movzbl 0x3a28b4(%rip),%eax        # 0x555555b1c380 <suppress_checking>

2377	    }
2378
2379	  return c;
2380	}
2381
2382
2383
2384	/* Like `read_event_from_main_queue' but applies keyboard-coding-system
2385	   to tty input.  */
2386	static Lisp_Object
2387	read_decoded_event_from_main_queue (struct timespec *end_time,
2388	                                    sys_jmp_buf local_getcjmp,
2389	                                    Lisp_Object prev_event,
2390	                                    bool *used_mouse_menu)
2391	{
2392	#ifndef WINDOWSNT
2393	#define MAX_ENCODED_BYTES 16
2394	  Lisp_Object events[MAX_ENCODED_BYTES];
2395	  int n = 0;
2396	#endif
2397	  while (true)
2398	    {
2399	      Lisp_Object nextevt
2400	        = read_event_from_main_queue (end_time, local_getcjmp,
2401	                                      used_mouse_menu);
2402	#ifdef WINDOWSNT
2403	      /* w32_console already returns decoded events.  It either reads
2404		 Unicode characters from the Windows keyboard input, or
2405		 converts characters encoded in the current codepage into
2406		 Unicode.  See w32inevt.c:key_event, near its end.  */
2407	      return nextevt;
2408	#else
2409	      struct frame *frame = XFRAME (selected_frame);
   0x0000555555779acc <+4732>:	mov    0x335a55(%rip),%rdx        # 0x555555aaf528 <selected_frame>
   0x0000555555779ad3 <+4739>:	test   %al,%al
   0x0000555555779ad5 <+4741>:	jne    0x55555577a7e6 <read_char+8086>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555779adb <+4747>:	lea    -0x5(%rdx),%eax

775	}
776
777	INLINE void
778	(CHECK_TYPE) (int ok, Lisp_Object predicate, Lisp_Object x)
779	{
780	  lisp_h_CHECK_TYPE (ok, predicate, x);
781	}
782
783	/* Extract A's pointer value, assuming A's Lisp type is TYPE and the
784	   extracted pointer's type is CTYPE *.  When !USE_LSB_TAG this simply
785	   extracts A's low-order bits, as (uintptr_t) LISP_WORD_TAG (type) is
786	   always zero then.  */
787	#define XUNTAG(a, type, ctype) \
788	  ((ctype *) ((uintptr_t) XLP (a) - (uintptr_t) LISP_WORD_TAG (type)))
789
790	/* A forwarding pointer to a value.  It uses a generic pointer to
791	   avoid alignment bugs that could occur if it used a pointer to a
792	   union of the possible values (struct Lisp_Objfwd, struct
793	   Lisp_Intfwd, etc.).  The pointer is packaged inside a struct to
794	   help static checking.  */
795	typedef const struct Lisp_Fwd *lispfwd;
796	^L
797	/* Interned state of a symbol.  */
798
799	enum symbol_interned
800	{
801	  SYMBOL_UNINTERNED,		      /* not interned anywhere */
802	  SYMBOL_INTERNED,		      /* interned but not in initial obarray */
803	  SYMBOL_INTERNED_IN_INITIAL_OBARRAY  /* interned in initial obarray */
804	};
805
806	enum symbol_redirect
807	{
808	  SYMBOL_PLAINVAL,   /* plain var, value is in the `value' field */
809	  SYMBOL_VARALIAS,   /* var alias, value is really in the `alias' symbol */
810	  SYMBOL_LOCALIZED,  /* localized var, value is in the `blv' object */
811	  SYMBOL_FORWARDED   /* forwarding var, value is in `forward' */
812	};
813
814	enum symbol_trapped_write
815	{
816	  SYMBOL_UNTRAPPED_WRITE,  /* normal case, just set the value */
817	  SYMBOL_NOWRITE,          /* constant, cannot set, e.g. nil, t, :keyword */
818	  SYMBOL_TRAPPED_WRITE     /* trap the write, call watcher functions */
819	};
820
821	struct Lisp_Symbol
822	{
823	  GC_HEADER
824	  union
825	  {
826	    struct
827	    {
828	      bool_bf gcmarkbit : 1;
829
830	      /* Indicates where the value can be found.  */
831	      ENUM_BF (symbol_redirect) redirect : 2;
832
833	      ENUM_BF (symbol_trapped_write) trapped_write : 2;
834
835	      /* Interned state of the symbol.  */
836	      ENUM_BF (symbol_interned) interned : 2;
837
838	      /* True means that this variable has been explicitly declared
839		 special (with `defvar' etc), and shouldn't be lexically bound.  */
840	      bool_bf declared_special : 1;
841
842	      /* The symbol's name, as a Lisp string.  */
843	      Lisp_Object name;
844
845	      /* Value of the symbol or Qunbound if unbound.  Which alternative of the
846		 union is used depends on the `redirect' field above.  */
847	      union {
848		Lisp_Object value;
849		struct Lisp_Symbol *alias;
850		struct Lisp_Buffer_Local_Value *blv;
851		lispfwd fwd;
852	      } val;
853
854	      /* Function value of the symbol or Qnil if not fboundp.  */
855	      Lisp_Object function;
856
857	      /* The symbol's property list.  */
858	      Lisp_Object plist;
859
860	      /* Next symbol in obarray bucket, if the symbol is interned.  */
861	      struct Lisp_Symbol *next;
862	    } s;
863	    GCALIGNED_UNION_MEMBER
864	  } u;
865	};
866	static_assert (GCALIGNED (struct Lisp_Symbol));
867
868	/* Declare a Lisp-callable function.  The MAXARGS parameter has the same
869	   meaning as in the DEFUN macro, and is used to construct a prototype.  */
870	/* We can use the same trick as in the DEFUN macro to generate the
871	   appropriate prototype.  */
872	#define EXFUN(fnname, maxargs) \
873	  extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs
874
875	/* Note that the weird token-substitution semantics of ANSI C makes
876	   this work for MANY and UNEVALLED.  */
877	#define DEFUN_ARGS_MANY		(ptrdiff_t, Lisp_Object *)
878	#define DEFUN_ARGS_UNEVALLED	(Lisp_Object)
879	#define DEFUN_ARGS_0	(void)
880	#define DEFUN_ARGS_1	(Lisp_Object)
881	#define DEFUN_ARGS_2	(Lisp_Object, Lisp_Object)
882	#define DEFUN_ARGS_3	(Lisp_Object, Lisp_Object, Lisp_Object)
883	#define DEFUN_ARGS_4	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
884	#define DEFUN_ARGS_5	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
885				 Lisp_Object)
886	#define DEFUN_ARGS_6	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
887				 Lisp_Object, Lisp_Object)
888	#define DEFUN_ARGS_7	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
889				 Lisp_Object, Lisp_Object, Lisp_Object)
890	#define DEFUN_ARGS_8	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
891				 Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
892
893	/* Lisp_Word_tag is big enough for a possibly-shifted tag, to be
894	   added to a pointer value for conversion to a Lisp_Word.  */
895	#if LISP_WORDS_ARE_POINTERS
896	typedef uintptr_t Lisp_Word_tag;
897	#else
898	typedef EMACS_UINT Lisp_Word_tag;
899	#endif
900
901	/* A integer value tagged with TAG, and otherwise all zero.  */
902	#define LISP_WORD_TAG(tag) \
903	  ((Lisp_Word_tag) (tag) << (USE_LSB_TAG ? 0 : VALBITS))
904
905	/* An initializer for a Lisp_Object that contains TAG along with P.
906	   P can be a pointer or an integer.  The result is usable in a static
907	   initializer if TAG and P are both integer constant expressions.  */
908	#define TAG_PTR_INITIALLY(tag, p) \
909	  LISP_INITIALLY ((Lisp_Word) ((uintptr_t) (p) + LISP_WORD_TAG (tag)))
910
911	/* LISPSYM_INITIALLY (Qfoo) is equivalent to Qfoo except it is
912	   designed for use as a (possibly static) initializer.  */
913	#define LISPSYM_INITIALLY(name) \
914	  TAG_PTR_INITIALLY (Lisp_Symbol, (intptr_t) ((i##name) * sizeof *lispsym))
915
916	/* Declare extern constants for Lisp symbols.  These can be helpful
917	   when using a debugger like GDB, on older platforms where the debug
918	   format does not represent C macros.  However, they are unbounded
919	   and would just be asking for trouble if checking pointer bounds.  */
920	#define DEFINE_LISP_SYMBOL(name) \
921	  DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) \
922	  DEFINE_GDB_SYMBOL_END (LISPSYM_INITIALLY (name))
923
924	/* The index of the C-defined Lisp symbol SYM.
925	   This can be used in a static initializer.  */
926	#define SYMBOL_INDEX(sym) i##sym
927
928	/* By default, define macros for Qt, etc., as this leads to a bit
929	   better performance in the core Emacs interpreter.  A plugin can
930	   define DEFINE_NON_NIL_Q_SYMBOL_MACROS to be false, to be portable to
931	   other Emacs instances that assign different values to Qt, etc.  */
932	#ifndef DEFINE_NON_NIL_Q_SYMBOL_MACROS
933	# define DEFINE_NON_NIL_Q_SYMBOL_MACROS true
934	#endif
935
936	/* True if N is a power of 2.  N should be positive.  */
937
938	#define POWER_OF_2(n) (((n) & ((n) - 1)) == 0)
939
940	/* Return X rounded to the next multiple of Y.  Y should be positive,
941	   and Y - 1 + X should not overflow.  Arguments should not have side
942	   effects, as they are evaluated more than once.  Tune for Y being a
943	   power of 2.  */
944
945	#define ROUNDUP(x, y) (POWER_OF_2 (y)					\
946	                       ? ((y) - 1 + (x)) & ~ ((y) - 1)			\
947	                       : ((y) - 1 + (x)) - ((y) - 1 + (x)) % (y))
948
949	#include <globals.h>
950
951	/* Header of vector-like objects.  This documents the layout constraints on
952	   vectors and pseudovectors (objects of PVEC_xxx subtype).  It also prevents
953	   compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR
954	   and PSEUDOVECTORP cast their pointers to struct vectorlike_header *,
955	   because when two such pointers potentially alias, a compiler won't
956	   incorrectly reorder loads and stores to their size fields.  See
957	   Bug#8546.   */
958	struct vectorlike_header
959	  {
960	    /* The `size' header word, W bits wide, has one of two forms
961	       discriminated by the second-highest bit (PSEUDOVECTOR_FLAG):
962
963	         1   1                    W-2
964	       +---+---+-------------------------------------+
965	       | M | 0 |                 SIZE                |  vector
966	       +---+---+-------------------------------------+
967
968	         1   1    W-32      6       12         12
969	       +---+---+--------+------+----------+----------+
970	       | M | 1 | unused | TYPE | RESTSIZE | LISPSIZE |  pseudovector
971	       +---+---+--------+------+----------+----------+
972
973	       M (ARRAY_MARK_FLAG) holds the GC mark bit.
974
975	       SIZE     is the length (number of slots) of a regular Lisp vector,
976	                and the object layout is struct Lisp_Vector.
977
978	       TYPE     is the pseudovector subtype (enum pvec_type).
979
980	       LISPSIZE is the number of Lisp_Object fields at the beginning of the
981	                object (after the header).  These are always traced by the GC.
982
983	       RESTSIZE is the number of fields (in word_size units) following.
984	                These are not automatically traced by the GC.
985	                For PVEC_BOOL and statically allocated PVEC_SUBR, RESTSIZE is 0.
986	                (The block size for PVEC_BOOL is computed from its own size
987	                field, to avoid being restricted by the 12-bit RESTSIZE field.)
988	    */
989	    GC_HEADER
990	    ptrdiff_t size;
991	  };
992
993	struct Lisp_Symbol_With_Pos
994	{
995	  struct vectorlike_header header;
996	  Lisp_Object sym;              /* A symbol */
997	  Lisp_Object pos;              /* A fixnum */
998	} GCALIGNED_STRUCT;
999
1000	/* In the size word of a vector, this bit means the vector has been marked.  */
1001
1002	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG)
1003	# define ARRAY_MARK_FLAG PTRDIFF_MIN
1004	DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG)
1005
1006	/* In the size word of a struct Lisp_Vector, this bit means it's really
1007	   some other vector-like object.  */
1008	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG)
1009	# define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2)
1010	DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
1011
1012	/* In a pseudovector, the size field actually contains a word with one
1013	   PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
1014	   with PVEC_TYPE_MASK to indicate the actual type.  */
1015	enum pvec_type
1016	{
1017	  PVEC_NORMAL_VECTOR,	/* Should be first, for sxhash_obj.  */
1018	  PVEC_FREE,
1019	  PVEC_BIGNUM,
1020	  PVEC_MARKER,
1021	  PVEC_OVERLAY,
1022	  PVEC_FINALIZER,
1023	  PVEC_SYMBOL_WITH_POS,
1024	  PVEC_MISC_PTR,
1025	  PVEC_USER_PTR,
1026	  PVEC_PROCESS,
1027	  PVEC_FRAME,
1028	  PVEC_WINDOW,
1029	  PVEC_BOOL_VECTOR,
1030	  PVEC_BUFFER,
1031	  PVEC_HASH_TABLE,
1032	#ifdef HAVE_MPS
1033	  PVEC_WEAK_HASH_TABLE,
1034	#endif
1035	  PVEC_OBARRAY,
1036	  PVEC_TERMINAL,
1037	  PVEC_WINDOW_CONFIGURATION,
1038	  PVEC_SUBR,
1039	  PVEC_OTHER,            /* Should never be visible to Elisp code.  */
1040	  PVEC_XWIDGET,
1041	  PVEC_XWIDGET_VIEW,
1042	  PVEC_THREAD,
1043	  PVEC_MUTEX,
1044	  PVEC_CONDVAR,
1045	  PVEC_MODULE_FUNCTION,
1046	  PVEC_MODULE_GLOBAL_REFERENCE,
1047	  PVEC_NATIVE_COMP_UNIT,
1048	  PVEC_TS_PARSER,
1049	  PVEC_TS_NODE,
1050	  PVEC_TS_COMPILED_QUERY,
1051	  PVEC_SQLITE,
1052
1053	  /* These should be last, for internal_equal and sxhash_obj.  */
1054	  PVEC_CLOSURE,
1055	  PVEC_CHAR_TABLE,
1056	  PVEC_SUB_CHAR_TABLE,
1057	  PVEC_RECORD,
1058	  PVEC_FONT,
1059	  PVEC_TAG_MAX = PVEC_FONT  /* Keep this equal to the highest member.  */
1060	};
1061
1062	enum More_Lisp_Bits
1063	  {
1064	    /* For convenience, we also store the number of elements in these bits.
1065	       Note that this size is not necessarily the memory-footprint size, but
1066	       only the number of Lisp_Object fields (that need to be traced by GC).
1067	       The distinction is used, e.g., by Lisp_Process, which places extra
1068	       non-Lisp_Object fields at the end of the structure.  */
1069	    PSEUDOVECTOR_SIZE_BITS = 12,
1070	    PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1,
1071
1072	    /* To calculate the memory footprint of the pseudovector, it's useful
1073	       to store the size of non-Lisp area in word_size units here.  */
1074	    PSEUDOVECTOR_REST_BITS = 12,
1075	    PSEUDOVECTOR_REST_MASK = (((1 << PSEUDOVECTOR_REST_BITS) - 1)
1076				      << PSEUDOVECTOR_SIZE_BITS),
1077
1078	    /* Used to extract pseudovector subtype information.  */
1079	    PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS,
1080	    PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS
1081	  };
1082	^L
1083	/* These functions extract various sorts of values from a Lisp_Object.
1084	   For example, if tem is a Lisp_Object whose type is Lisp_Cons,
1085	   XCONS (tem) is the struct Lisp_Cons * pointing to the memory for
1086	   that cons.  */
1087
1088	/* Largest and smallest representable fixnum values.  These are the C
1089	   values.  They are macros for use in #if and static initializers.  */
1090	#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
1091	#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
1092	^L
1093	INLINE bool
1094	PSEUDOVECTORP (Lisp_Object a, int code)
1095	{
1096	  return (lisp_h_VECTORLIKEP (a)
1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x0000555555779ade <+4750>:	test   $0x7,%al
   0x0000555555779ae0 <+4752>:	jne    0x5555555b279f <read_char-1859761>

1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x0000555555779ae6 <+4758>:	movabs $0x400000003f000000,%rcx
   0x0000555555779af0 <+4768>:	and    0x3(%rdx),%rcx

1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x0000555555779af4 <+4772>:	lea    -0x5(%rdx),%rax

1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x0000555555779af8 <+4776>:	mov    %rcx,%rdx

1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x0000555555779afb <+4779>:	movabs $0x400000000a000000,%rcx
   0x0000555555779b05 <+4789>:	cmp    %rcx,%rdx
   0x0000555555779b08 <+4792>:	jne    0x5555555b279f <read_char-1859761>
   0x0000555555779b0e <+4798>:	xor    %ecx,%ecx

./src/keyboard.c:
2410	      struct terminal *terminal = frame->terminal;
   0x0000555555779b10 <+4800>:	mov    0x208(%rax),%rdx

2411	      if (!((FRAME_TERMCAP_P (frame) || FRAME_MSDOS_P (frame))
   0x0000555555779b17 <+4807>:	movzbl 0x143(%rax),%eax
   0x0000555555779b1e <+4814>:	and    $0xf,%eax
   0x0000555555779b21 <+4817>:	cmp    $0x1,%al
   0x0000555555779b23 <+4819>:	jne    0x55555577a6a5 <read_char+7765>

./src/lisp.h:
1364	  return BASE_EQ ((__builtin_expect (symbols_with_pos_enabled, false)
   0x0000555555779b29 <+4825>:	cmpb   $0x0,0x3a7ac9(%rip)        # 0x555555b215f9 <globals+4537>
   0x0000555555779b30 <+4832>:	mov    -0x4c0(%rbp),%rax
   0x0000555555779b37 <+4839>:	jne    0x55555577bce0 <read_char+13456>

./src/keyboard.c:
2415	            && (!EQ (prev_event, Qt))
   0x0000555555779b3d <+4845>:	cmp    $0x38,%rax
   0x0000555555779b41 <+4849>:	je     0x55555577a6a5 <read_char+7765>

2416		    && (TERMINAL_KEYBOARD_CODING (terminal)->common_flags
   0x0000555555779b47 <+4855>:	mov    0x68(%rdx),%r10

2411	      if (!((FRAME_TERMCAP_P (frame) || FRAME_MSDOS_P (frame))
   0x0000555555779b4b <+4859>:	testb  $0x4,0x9(%r10)
   0x0000555555779b50 <+4864>:	je     0x55555577a6a5 <read_char+7765>

2417			& CODING_REQUIRE_DECODING_MASK)))
2418		return nextevt;		/* No decoding needed.  */
2419	      else
2420		{
2421		  int meta_key = terminal->display_info.tty->meta_key;
   0x0000555555779b56 <+4870>:	mov    0x58(%rdx),%rax

2422		  eassert (n < MAX_ENCODED_BYTES);
2423		  events[n++] = nextevt;
   0x0000555555779b5a <+4874>:	lea    -0x390(%rbp),%rdx
   0x0000555555779b61 <+4881>:	mov    -0x4e8(%rbp),%esi
   0x0000555555779b67 <+4887>:	mov    %r14,(%rdx,%r15,8)

2421		  int meta_key = terminal->display_info.tty->meta_key;
   0x0000555555779b6b <+4891>:	mov    0x2268(%rax),%ebx

2422		  eassert (n < MAX_ENCODED_BYTES);
2423		  events[n++] = nextevt;
   0x0000555555779b71 <+4897>:	lea    -0x2(%r14),%eax
   0x0000555555779b75 <+4901>:	mov    %rdx,-0x548(%rbp)

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555779b7c <+4908>:	and    $0x3,%eax
   0x0000555555779b7f <+4911>:	mov    %eax,-0x4e0(%rbp)
   0x0000555555779b85 <+4917>:	jne    0x55555577a66e <read_char+7710>

1233	}
1234
1235	INLINE EMACS_INT
1236	(XFIXNUM_RAW) (Lisp_Object a)
1237	{
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x0000555555779b8b <+4923>:	sar    $0x2,%r14
   0x0000555555779b8f <+4927>:	js     0x55555577a66e <read_char+7710>

./src/keyboard.c:
2425		      && XFIXNUM (nextevt) < (meta_key == 1 ? 0x80 : 0x100))
   0x0000555555779b95 <+4933>:	cmp    $0x1,%ebx
   0x0000555555779b98 <+4936>:	mov    $0x80,%eax
   0x0000555555779b9d <+4941>:	mov    $0x100,%edi
   0x0000555555779ba2 <+4946>:	cmovne %rdi,%rax
   0x0000555555779ba6 <+4950>:	cmp    %rax,%r14
   0x0000555555779ba9 <+4953>:	jge    0x55555577a66e <read_char+7710>

2426		    { /* An encoded byte sequence, let's try to decode it.  */
2427		      struct coding_system *coding
2428			= TERMINAL_KEYBOARD_CODING (terminal);
2429
2430		      if (raw_text_coding_system_p (coding))
   0x0000555555779baf <+4959>:	mov    %r10,%rdi
   0x0000555555779bb2 <+4962>:	mov    %esi,-0x584(%rbp)
   0x0000555555779bb8 <+4968>:	mov    %r10,-0x580(%rbp)
   0x0000555555779bbf <+4975>:	call   0x5555556c3650 <raw_text_coding_system_p>
   0x0000555555779bc4 <+4980>:	mov    -0x580(%rbp),%r10
   0x0000555555779bcb <+4987>:	mov    -0x584(%rbp),%esi
   0x0000555555779bd1 <+4993>:	test   %al,%al
   0x0000555555779bd3 <+4995>:	mov    -0x4e0(%rbp),%ecx
   0x0000555555779bd9 <+5001>:	mov    -0x548(%rbp),%rdx
   0x0000555555779be0 <+5008>:	jne    0x55555577caeb <read_char+17051>
   0x0000555555779be6 <+5014>:	cmpb   $0x0,0x3a2793(%rip)        # 0x555555b1c380 <suppress_checking>
   0x0000555555779bed <+5021>:	mov    %r15d,%eax
   0x0000555555779bf0 <+5024>:	jne    0x55555577b11a <read_char+10442>

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x0000555555779bf6 <+5030>:	mov    -0x390(%rbp),%rdx

740	  return lisp_h_XLI (o);
   0x0000555555779bfd <+5037>:	lea    -0x2(%rdx),%esi

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x0000555555779c00 <+5040>:	and    $0x3,%esi
   0x0000555555779c03 <+5043>:	jne    0x5555555b283f <read_char-1859601>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x0000555555779c09 <+5049>:	sar    $0x2,%rdx

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x0000555555779c0d <+5053>:	mov    %dl,-0xa0(%rbp)

2451			  for (i = 0; i < n; i++)
   0x0000555555779c13 <+5059>:	test   %r15d,%r15d
   0x0000555555779c16 <+5062>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x0000555555779c1c <+5068>:	mov    -0x388(%rbp),%rsi

740	  return lisp_h_XLI (o);
   0x0000555555779c23 <+5075>:	lea    -0x2(%rsi),%edi

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x0000555555779c26 <+5078>:	and    $0x3,%edi
   0x0000555555779c29 <+5081>:	jne    0x5555555b283f <read_char-1859601>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x0000555555779c2f <+5087>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x0000555555779c33 <+5091>:	mov    %sil,-0x9f(%rbp)

2451			  for (i = 0; i < n; i++)
   0x0000555555779c3a <+5098>:	cmp    $0x1,%r15d
   0x0000555555779c3e <+5102>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x0000555555779c44 <+5108>:	mov    -0x380(%rbp),%rsi

740	  return lisp_h_XLI (o);
   0x0000555555779c4b <+5115>:	lea    -0x2(%rsi),%edi

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x0000555555779c4e <+5118>:	and    $0x3,%edi
   0x0000555555779c51 <+5121>:	jne    0x5555555b283f <read_char-1859601>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x0000555555779c57 <+5127>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x0000555555779c5b <+5131>:	mov    %sil,-0x9e(%rbp)

2451			  for (i = 0; i < n; i++)
   0x0000555555779c62 <+5138>:	cmp    $0x2,%r15d
   0x0000555555779c66 <+5142>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x0000555555779c6c <+5148>:	mov    -0x378(%rbp),%rsi

740	  return lisp_h_XLI (o);
   0x0000555555779c73 <+5155>:	lea    -0x2(%rsi),%edi

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x0000555555779c76 <+5158>:	and    $0x3,%edi
   0x0000555555779c79 <+5161>:	jne    0x5555555b283f <read_char-1859601>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x0000555555779c7f <+5167>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x0000555555779c83 <+5171>:	mov    %sil,-0x9d(%rbp)

2451			  for (i = 0; i < n; i++)
   0x0000555555779c8a <+5178>:	cmp    $0x3,%r15d
   0x0000555555779c8e <+5182>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x0000555555779c94 <+5188>:	mov    -0x370(%rbp),%rsi

740	  return lisp_h_XLI (o);
   0x0000555555779c9b <+5195>:	lea    -0x2(%rsi),%edi

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x0000555555779c9e <+5198>:	and    $0x3,%edi
   0x0000555555779ca1 <+5201>:	jne    0x5555555b283f <read_char-1859601>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x0000555555779ca7 <+5207>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x0000555555779cab <+5211>:	mov    %sil,-0x9c(%rbp)

2451			  for (i = 0; i < n; i++)
   0x0000555555779cb2 <+5218>:	cmp    $0x4,%r15d
   0x0000555555779cb6 <+5222>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x0000555555779cbc <+5228>:	mov    -0x368(%rbp),%rsi

740	  return lisp_h_XLI (o);
   0x0000555555779cc3 <+5235>:	lea    -0x2(%rsi),%edi

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x0000555555779cc6 <+5238>:	and    $0x3,%edi
   0x0000555555779cc9 <+5241>:	jne    0x5555555b283f <read_char-1859601>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x0000555555779ccf <+5247>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x0000555555779cd3 <+5251>:	mov    %sil,-0x9b(%rbp)

2451			  for (i = 0; i < n; i++)
   0x0000555555779cda <+5258>:	cmp    $0x5,%r15d
   0x0000555555779cde <+5262>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x0000555555779ce4 <+5268>:	mov    -0x360(%rbp),%rsi

740	  return lisp_h_XLI (o);
   0x0000555555779ceb <+5275>:	lea    -0x2(%rsi),%edi

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x0000555555779cee <+5278>:	and    $0x3,%edi
   0x0000555555779cf1 <+5281>:	jne    0x5555555b283f <read_char-1859601>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x0000555555779cf7 <+5287>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x0000555555779cfb <+5291>:	mov    %sil,-0x9a(%rbp)

2451			  for (i = 0; i < n; i++)
   0x0000555555779d02 <+5298>:	cmp    $0x6,%r15d
   0x0000555555779d06 <+5302>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x0000555555779d0c <+5308>:	mov    -0x358(%rbp),%rsi

740	  return lisp_h_XLI (o);
   0x0000555555779d13 <+5315>:	lea    -0x2(%rsi),%edi

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x0000555555779d16 <+5318>:	and    $0x3,%edi
   0x0000555555779d19 <+5321>:	jne    0x5555555b283f <read_char-1859601>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x0000555555779d1f <+5327>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x0000555555779d23 <+5331>:	mov    %sil,-0x99(%rbp)

2451			  for (i = 0; i < n; i++)
   0x0000555555779d2a <+5338>:	cmp    $0x7,%r15d
   0x0000555555779d2e <+5342>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x0000555555779d34 <+5348>:	mov    -0x350(%rbp),%rsi

740	  return lisp_h_XLI (o);
   0x0000555555779d3b <+5355>:	lea    -0x2(%rsi),%edi

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x0000555555779d3e <+5358>:	and    $0x3,%edi
   0x0000555555779d41 <+5361>:	jne    0x5555555b283f <read_char-1859601>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x0000555555779d47 <+5367>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x0000555555779d4b <+5371>:	mov    %sil,-0x98(%rbp)

2451			  for (i = 0; i < n; i++)
   0x0000555555779d52 <+5378>:	cmp    $0x8,%r15d
   0x0000555555779d56 <+5382>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x0000555555779d5c <+5388>:	mov    -0x348(%rbp),%rsi

740	  return lisp_h_XLI (o);
   0x0000555555779d63 <+5395>:	lea    -0x2(%rsi),%edi

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x0000555555779d66 <+5398>:	and    $0x3,%edi
   0x0000555555779d69 <+5401>:	jne    0x5555555b283f <read_char-1859601>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x0000555555779d6f <+5407>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x0000555555779d73 <+5411>:	mov    %sil,-0x97(%rbp)

2451			  for (i = 0; i < n; i++)
   0x0000555555779d7a <+5418>:	cmp    $0x9,%r15d
   0x0000555555779d7e <+5422>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x0000555555779d84 <+5428>:	mov    -0x340(%rbp),%rsi

740	  return lisp_h_XLI (o);
   0x0000555555779d8b <+5435>:	lea    -0x2(%rsi),%edi

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x0000555555779d8e <+5438>:	and    $0x3,%edi
   0x0000555555779d91 <+5441>:	jne    0x5555555b283f <read_char-1859601>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x0000555555779d97 <+5447>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x0000555555779d9b <+5451>:	mov    %sil,-0x96(%rbp)

2451			  for (i = 0; i < n; i++)
   0x0000555555779da2 <+5458>:	cmp    $0xa,%r15d
   0x0000555555779da6 <+5462>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x0000555555779dac <+5468>:	mov    -0x338(%rbp),%rsi

740	  return lisp_h_XLI (o);
   0x0000555555779db3 <+5475>:	lea    -0x2(%rsi),%edi

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x0000555555779db6 <+5478>:	and    $0x3,%edi
   0x0000555555779db9 <+5481>:	jne    0x5555555b283f <read_char-1859601>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x0000555555779dbf <+5487>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x0000555555779dc3 <+5491>:	mov    %sil,-0x95(%rbp)

2451			  for (i = 0; i < n; i++)
   0x0000555555779dca <+5498>:	cmp    $0xb,%r15d
   0x0000555555779dce <+5502>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x0000555555779dd4 <+5508>:	mov    -0x330(%rbp),%rsi

740	  return lisp_h_XLI (o);
   0x0000555555779ddb <+5515>:	lea    -0x2(%rsi),%edi

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x0000555555779dde <+5518>:	and    $0x3,%edi
   0x0000555555779de1 <+5521>:	jne    0x5555555b283f <read_char-1859601>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x0000555555779de7 <+5527>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x0000555555779deb <+5531>:	mov    %sil,-0x94(%rbp)

2451			  for (i = 0; i < n; i++)
   0x0000555555779df2 <+5538>:	cmp    $0xc,%r15d
   0x0000555555779df6 <+5542>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x0000555555779dfc <+5548>:	mov    -0x328(%rbp),%rsi

740	  return lisp_h_XLI (o);
   0x0000555555779e03 <+5555>:	lea    -0x2(%rsi),%edi

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x0000555555779e06 <+5558>:	and    $0x3,%edi
   0x0000555555779e09 <+5561>:	jne    0x5555555b283f <read_char-1859601>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x0000555555779e0f <+5567>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x0000555555779e13 <+5571>:	mov    %sil,-0x93(%rbp)

2451			  for (i = 0; i < n; i++)
   0x0000555555779e1a <+5578>:	cmp    $0xd,%r15d
   0x0000555555779e1e <+5582>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x0000555555779e24 <+5588>:	mov    -0x320(%rbp),%rsi

740	  return lisp_h_XLI (o);
   0x0000555555779e2b <+5595>:	lea    -0x2(%rsi),%edi

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x0000555555779e2e <+5598>:	and    $0x3,%edi
   0x0000555555779e31 <+5601>:	jne    0x5555555b283f <read_char-1859601>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x0000555555779e37 <+5607>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x0000555555779e3b <+5611>:	mov    %sil,-0x92(%rbp)

2451			  for (i = 0; i < n; i++)
   0x0000555555779e42 <+5618>:	cmp    $0xf,%r15d
   0x0000555555779e46 <+5622>:	jne    0x55555577b35c <read_char+11020>

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x0000555555779e4c <+5628>:	mov    -0x318(%rbp),%rdx

740	  return lisp_h_XLI (o);
   0x0000555555779e53 <+5635>:	lea    -0x2(%rdx),%esi

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x0000555555779e56 <+5638>:	and    $0x3,%esi
   0x0000555555779e59 <+5641>:	jne    0x5555555b283f <read_char-1859601>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x0000555555779e5f <+5647>:	sar    $0x2,%rdx

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x0000555555779e63 <+5651>:	mov    %dl,-0x91(%rbp)

2451			  for (i = 0; i < n; i++)
   0x0000555555779e69 <+5657>:	jmp    0x55555577b35c <read_char+11020>
   0x0000555555779e6e <+5662>:	xchg   %ax,%ax

4119		gobble_input ();
   0x0000555555779e70 <+5664>:	call   0x555555771b00 <gobble_input>
   0x0000555555779e75 <+5669>:	jmp    0x555555779792 <read_char+3906>
   0x0000555555779e7a <+5674>:	nopw   0x0(%rax,%rax,1)

4120	    }
4121
4122	#ifdef HAVE_X_WINDOWS
4123	  /* Handle pending selection requests.  This can happen if Emacs
4124	     enters a recursive edit inside a nested event loop (probably
4125	     because the debugger opened) or someone called
4126	     `read-char'.  */
4127
4128	  if (had_pending_selection_requests)
4129	    x_handle_pending_selection_requests ();
   0x0000555555779e80 <+5680>:	mov    %al,-0x4b5(%rbp)
   0x0000555555779e86 <+5686>:	call   0x55555571a7e0 <x_handle_pending_selection_requests>

4130	#endif
4131
4132	  if (CONSP (Vunread_command_events))
   0x0000555555779e8b <+5691>:	mov    0x3a71e6(%rip),%rdx        # 0x555555b21078 <globals+3128>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x0000555555779e92 <+5698>:	movzbl -0x4b5(%rbp),%ebx

747	}
748
749	INLINE void *
750	(XLP) (Lisp_Object o)
751	{
752	  return lisp_h_XLP (o);
753	}
754
755	/* Extract A's type.  */
756
757	INLINE enum Lisp_Type
758	(XTYPE) (Lisp_Object a)
759	{
760	#if USE_LSB_TAG
761	  return lisp_h_XTYPE (a);
762	#else
763	  EMACS_UINT i = XLI (a);
764	  return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
765	#endif
766	}
767
768	/* True if A has type tag TAG.
769	   Equivalent to XTYPE (a) == TAG, but often faster.  */
770
771	INLINE bool
772	(TAGGEDP) (Lisp_Object a, enum Lisp_Type tag)
773	{
774	  return lisp_h_TAGGEDP (a, tag);
   0x0000555555779e99 <+5705>:	lea    -0x3(%rdx),%ecx

./src/keyboard.c:
4132	  if (CONSP (Vunread_command_events))
   0x0000555555779e9c <+5708>:	and    $0x7,%ecx
   0x0000555555779e9f <+5711>:	jne    0x5555557798d2 <read_char+4226>
   0x0000555555779ea5 <+5717>:	nopl   (%rax)

4168		*kbp = current_kboard;  /* Better than returning null ptr?  */
   0x0000555555779ea8 <+5720>:	mov    0x38c3b1(%rip),%rax        # 0x555555b06260 <current_kboard>
   0x0000555555779eaf <+5727>:	mov    %rax,-0x498(%rbp)

./src/lisp.h:
1518	  return c;
   0x0000555555779eb6 <+5734>:	mov    0xd(%rdx),%rax

1519	}
1520
1521	/* Take the car or cdr of something known to be a cons cell.  */
1522	/* The _addr functions shouldn't be used outside of the minimal set
1523	   of code that has to know what a cons cell looks like.  Other code not
1524	   part of the basic lisp implementation should assume that the car and cdr
1525	   fields are not accessible.  (What if we want to switch to
1526	   a copying collector someday?  Cached cons cell field addresses may be
1527	   invalidated at arbitrary points.)  */
1528	INLINE Lisp_Object *
1529	xcar_addr (Lisp_Object c)
1530	{
1531	  return &XCONS (c)->u.s.car;
1532	}
1533	INLINE Lisp_Object *
1534	xcdr_addr (Lisp_Object c)
1535	{
1536	  return &XCONS (c)->u.s.u.cdr;
1537	}
1538
1539	/* Use these from normal code.  */
1540
1541	INLINE Lisp_Object
1542	(XCAR) (Lisp_Object c)
1543	{
1544	  return lisp_h_XCAR (c);
   0x0000555555779eba <+5738>:	mov    0x5(%rdx),%r14

1545	}
1546
1547	INLINE Lisp_Object
1548	(XCDR) (Lisp_Object c)
1549	{
1550	  return lisp_h_XCDR (c);
   0x0000555555779ebe <+5742>:	mov    %rax,0x3a71b3(%rip)        # 0x555555b21078 <globals+3128>

./src/keyboard.c:
4138	      return first;
   0x0000555555779ec5 <+5749>:	jmp    0x555555779a47 <read_char+4599>
   0x0000555555779eca <+5754>:	nopw   0x0(%rax,%rax,1)

./src/systime.h:
70	  return t.tv_nsec >= 0;
   0x0000555555779ed0 <+5760>:	lea    0x38c6d9(%rip),%rax        # 0x555555b065b0 <timer_idleness_start_time>
   0x0000555555779ed7 <+5767>:	cmpq   $0x0,0x8(%rax)
   0x0000555555779edc <+5772>:	jns    0x5555557796a5 <read_char+3669>

./src/keyboard.c:
4639	  timer_idleness_start_time = current_timespec ();
   0x0000555555779ee2 <+5778>:	call   0x555555936cd0 <current_timespec>

./src/lisp.h:
3726	  return calln (fn);
   0x0000555555779ee7 <+5783>:	lea    -0x3e8(%rbp),%rsi
   0x0000555555779eee <+5790>:	mov    $0x1,%edi
   0x0000555555779ef3 <+5795>:	movq   $0xd318,-0x3e8(%rbp)

./src/keyboard.c:
4639	  timer_idleness_start_time = current_timespec ();
   0x0000555555779efe <+5806>:	mov    %rdx,0x38c6b3(%rip)        # 0x555555b065b8 <timer_idleness_start_time+8>

4640	  timer_last_idleness_start_time = timer_idleness_start_time;
   0x0000555555779f05 <+5813>:	mov    %rdx,0x38c69c(%rip)        # 0x555555b065a8 <timer_last_idleness_start_time+8>

./src/lisp.h:
3726	  return calln (fn);
   0x0000555555779f0c <+5820>:	mov    %rax,0x38c69d(%rip)        # 0x555555b065b0 <timer_idleness_start_time>

./src/keyboard.c:
4640	  timer_last_idleness_start_time = timer_idleness_start_time;
   0x0000555555779f13 <+5827>:	mov    %rax,0x38c686(%rip)        # 0x555555b065a0 <timer_last_idleness_start_time>

./src/lisp.h:
3726	  return calln (fn);
   0x0000555555779f1a <+5834>:	call   0x555555820950 <Ffuncall>
   0x0000555555779f1f <+5839>:	jmp    0x5555557796a5 <read_char+3669>
   0x0000555555779f24 <+5844>:	nopl   0x0(%rax)
   0x0000555555779f28 <+5848>:	cmpb   $0x0,0x3a2451(%rip)        # 0x555555b1c380 <suppress_checking>
   0x0000555555779f2f <+5855>:	jne    0x555555779f60 <read_char+5904>
   0x0000555555779f31 <+5857>:	nopl   0x0(%rax)

740	  return lisp_h_XLI (o);
   0x0000555555779f38 <+5864>:	lea    -0x3(%rax),%edx

1384	}
1385
1386	#define XSETINT(a, b) ((a) = make_fixnum (b))
1387	#define XSETFASTINT(a, b) ((a) = make_fixed_natnum (b))
1388	#define XSETCONS(a, b) ((a) = make_lisp_ptr (b, Lisp_Cons))
1389	#define XSETVECTOR(a, b) ((a) = make_lisp_ptr (b, Lisp_Vectorlike))
1390	#define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String))
1391	#define XSETSYMBOL(a, b) ((a) = make_lisp_symbol (b))
1392	#define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float))
1393
1394	/* Return a Lisp_Object value that does not correspond to any object.
1395	   This can make some Lisp objects on free lists recognizable in O(1).  */
1396
1397	INLINE Lisp_Object
1398	dead_object (void)
1399	{
1400	  return make_lisp_ptr (NULL, Lisp_String);
1401	}
1402
1403	/* Pseudovector types.  */
1404
1405	#define XSETPVECTYPE(v, code)						\
1406	  ((v)->header.size |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS))
1407	#define PVECHEADERSIZE(code, lispsize, restsize) \
1408	  (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS) \
1409	   | ((restsize) << PSEUDOVECTOR_SIZE_BITS) | (lispsize))
1410	#define XSETPVECTYPESIZE(v, code, lispsize, restsize)		\
1411	  ((v)->header.size = PVECHEADERSIZE (code, lispsize, restsize))
1412
1413	/* The cast to struct vectorlike_header * avoids aliasing issues.  */
1414	#define XSETPSEUDOVECTOR(a, b, code) \
1415	  XSETTYPED_PSEUDOVECTOR (a, b,					\
1416				  (XUNTAG (a, Lisp_Vectorlike,		\
1417					   struct vectorlike_header)	\
1418				   ->size),				\
1419				  code)
1420	#define XSETTYPED_PSEUDOVECTOR(a, b, size, code)			\
1421	  (XSETVECTOR (a, b),							\
1422	   eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))		\
1423		    == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS))))
1424
1425	#define XSETWINDOW_CONFIGURATION(a, b) \
1426	  XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION)
1427	#define XSETPROCESS(a, b) XSETPSEUDOVECTOR (a, b, PVEC_PROCESS)
1428	#define XSETWINDOW(a, b) XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)
1429	#define XSETTERMINAL(a, b) XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)
1430	#define XSETSUBR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_SUBR)
1431	#define XSETBUFFER(a, b) XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)
1432	#define XSETCHAR_TABLE(a, b) XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)
1433	#define XSETBOOL_VECTOR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR)
1434	#define XSETSUB_CHAR_TABLE(a, b) XSETPSEUDOVECTOR (a, b, PVEC_SUB_CHAR_TABLE)
1435	#define XSETTHREAD(a, b) XSETPSEUDOVECTOR (a, b, PVEC_THREAD)
1436	#define XSETMUTEX(a, b) XSETPSEUDOVECTOR (a, b, PVEC_MUTEX)
1437	#define XSETCONDVAR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_CONDVAR)
1438	#define XSETNATIVE_COMP_UNIT(a, b) XSETPSEUDOVECTOR (a, b, PVEC_NATIVE_COMP_UNIT)
1439
1440	/* Efficiently convert a pointer to a Lisp object and back.  The
1441	   pointer is represented as a fixnum, so the garbage collector
1442	   does not know about it.  The pointer should not have both Lisp_Int1
1443	   bits set, which makes this conversion inherently unportable.  */
1444
1445	INLINE void *
1446	XFIXNUMPTR (Lisp_Object a)
1447	{
1448	  return XUNTAG (a, Lisp_Int0, char);
1449	}
1450
1451	INLINE Lisp_Object
1452	make_pointer_integer_unsafe (void *p)
1453	{
1454	  Lisp_Object a = TAG_PTR_INITIALLY (Lisp_Int0, p);
1455	  return a;
1456	}
1457
1458	INLINE Lisp_Object
1459	make_pointer_integer (void *p)
1460	{
1461	  Lisp_Object a = make_pointer_integer_unsafe (p);
1462	  eassert (FIXNUMP (a) && XFIXNUMPTR (a) == p);
1463	  return a;
1464	}
1465
1466	/* See the macros in intervals.h.  */
1467
1468	typedef struct interval *INTERVAL;
1469
1470	struct Lisp_Cons
1471	{
1472	  GC_HEADER
1473	  union
1474	  {
1475	    struct
1476	    {
1477	      /* Car of this cons cell.  */
1478	      Lisp_Object car;
1479
1480	      union
1481	      {
1482		/* Cdr of this cons cell.  */
1483		Lisp_Object cdr;
1484
1485		/* Used to chain conses on a free list.  */
1486		struct Lisp_Cons *chain;
1487	      } u;
1488	    } s;
1489	    GCALIGNED_UNION_MEMBER
1490	  } u;
1491	};
1492	static_assert (GCALIGNED (struct Lisp_Cons));
1493
1494	INLINE bool
1495	(NILP) (Lisp_Object x)
1496	{
1497	  return lisp_h_NILP (x);
1498	}
1499
1500	INLINE bool
1501	(CONSP) (Lisp_Object x)
1502	{
1503	  return lisp_h_CONSP (x);
1504	}
1505
1506	INLINE void
1507	CHECK_CONS (Lisp_Object x)
1508	{
1509	  CHECK_TYPE (CONSP (x), Qconsp, x);
1510	}
1511
1512	INLINE struct Lisp_Cons *
1513	XCONS (Lisp_Object a)
1514	{
1515	  eassert (CONSP (a));
   0x0000555555779f3b <+5867>:	and    $0x7,%edx
   0x0000555555779f3e <+5870>:	jne    0x5555555b28b6 <read_char-1859482>

1516	  struct Lisp_Cons *c = XUNTAG (a, Lisp_Cons, struct Lisp_Cons);
   0x0000555555779f44 <+5876>:	lea    -0x3(%rax),%rbx

1517	  igc_check_fwd (c, false);
1518	  return c;
   0x0000555555779f48 <+5880>:	mov    0x10(%rbx),%rax

740	  return lisp_h_XLI (o);
   0x0000555555779f4c <+5884>:	lea    -0x3(%rax),%edx

./src/keyboard.c:
2344	          while (CONSP (XCDR (last)))
   0x0000555555779f4f <+5887>:	and    $0x7,%edx
   0x0000555555779f52 <+5890>:	je     0x555555779f38 <read_char+5864>

./src/lisp.h:
1518	  return c;
   0x0000555555779f54 <+5892>:	test   %rax,%rax
   0x0000555555779f57 <+5895>:	je     0x555555779f88 <read_char+5944>
   0x0000555555779f59 <+5897>:	jmp    0x5555555b28c0 <read_char-1859472>
   0x0000555555779f5e <+5902>:	xchg   %ax,%ax

1516	  struct Lisp_Cons *c = XUNTAG (a, Lisp_Cons, struct Lisp_Cons);
   0x0000555555779f60 <+5904>:	lea    -0x3(%rax),%rbx

1517	  igc_check_fwd (c, false);
1518	  return c;
   0x0000555555779f64 <+5908>:	mov    %rax,%rcx

1545	}
1546
1547	INLINE Lisp_Object
1548	(XCDR) (Lisp_Object c)
1549	{
1550	  return lisp_h_XCDR (c);
   0x0000555555779f67 <+5911>:	mov    0x10(%rbx),%rax

740	  return lisp_h_XLI (o);
   0x0000555555779f6b <+5915>:	lea    -0x3(%rax),%edx

./src/keyboard.c:
2344	          while (CONSP (XCDR (last)))
   0x0000555555779f6e <+5918>:	and    $0x7,%edx
   0x0000555555779f71 <+5921>:	je     0x555555779f60 <read_char+5904>

./src/lisp.h:
1518	  return c;
   0x0000555555779f73 <+5923>:	test   %rax,%rax
   0x0000555555779f76 <+5926>:	jne    0x55555577d113 <read_char+18627>

740	  return lisp_h_XLI (o);
   0x0000555555779f7c <+5932>:	sub    $0x3,%ecx

./src/keyboard.c:
2349	      if (!CONSP (last))
   0x0000555555779f7f <+5935>:	and    $0x7,%ecx
   0x0000555555779f82 <+5938>:	jne    0x555555779a82 <read_char+4658>

2351	      else
2352	        XSETCDR (last, list1 (c));
   0x0000555555779f88 <+5944>:	mov    %r14,%rdi
   0x0000555555779f8b <+5947>:	call   0x5555557ef5c0 <list1>

./src/lisp.h:
1565	  *xcdr_addr (c) = n;
   0x0000555555779f90 <+5952>:	mov    %rax,0x10(%rbx)
   0x0000555555779f94 <+5956>:	jmp    0x555555779a95 <read_char+4677>
   0x0000555555779f99 <+5961>:	nopl   0x0(%rax)

./src/keyboard.c:
4015	      unhold_keyboard_input ();
   0x0000555555779fa0 <+5968>:	call   0x5555558a7590 <unhold_keyboard_input>

4016	      request_sigio ();
   0x0000555555779fa5 <+5973>:	call   0x5555557911c0 <request_sigio>

2052	  if (!interrupt_input)
   0x0000555555779faa <+5978>:	cmpb   $0x0,0x34c149(%rip)        # 0x555555ac60fa <interrupt_input>
   0x0000555555779fb1 <+5985>:	jne    0x5555557796d8 <read_char+3720>
   0x0000555555779fb7 <+5991>:	call   0x555555764a20 <start_polling>
   0x0000555555779fbc <+5996>:	jmp    0x5555557796d8 <read_char+3720>
   0x0000555555779fc1 <+6001>:	nopl   0x0(%rax)
   0x0000555555779fc8 <+6008>:	mov    %rdx,-0x4f8(%rbp)
   0x0000555555779fcf <+6015>:	mov    %r8,-0x4f0(%rbp)

4458			}
4459		    }
4460		}
4461	      }
4462	    }
4463	  /* Try generating a mouse motion event.  */
4464	  else if (some_mouse_moved ())
   0x0000555555779fd6 <+6022>:	call   0x555555763840 <some_mouse_moved>
   0x0000555555779fdb <+6027>:	mov    %rax,%r14
   0x0000555555779fde <+6030>:	test   %rax,%rax
   0x0000555555779fe1 <+6033>:	je     0x55555577aab4 <read_char+8804>

4465	    {
4466	      struct frame *f, *movement_frame = some_mouse_moved ();
4467	      Lisp_Object bar_window;
4468	      enum scroll_bar_part part;
4469	      Lisp_Object x, y;
4470	      Time t;
4471
4472	      f = movement_frame;
   0x0000555555779fe7 <+6039>:	mov    %rax,-0x468(%rbp)

4473	      *kbp = current_kboard;
   0x0000555555779fee <+6046>:	mov    0x38c26b(%rip),%rax        # 0x555555b06260 <current_kboard>

4478
4479	      /* XXX Can f or mouse_position_hook be NULL here?  */
4480	      if (f && FRAME_TERMINAL (f)->mouse_position_hook)
   0x0000555555779ff5 <+6053>:	mov    -0x4f0(%rbp),%r8
   0x0000555555779ffc <+6060>:	mov    -0x4f8(%rbp),%rdx

4477	      x = Qnil;
   0x000055555577a003 <+6067>:	movq   $0x0,-0x458(%rbp)

4473	      *kbp = current_kboard;
   0x000055555577a00e <+6078>:	mov    %rax,-0x498(%rbp)

4478
4479	      /* XXX Can f or mouse_position_hook be NULL here?  */
4480	      if (f && FRAME_TERMINAL (f)->mouse_position_hook)
   0x000055555577a015 <+6085>:	mov    0x208(%r14),%rax
   0x000055555577a01c <+6092>:	mov    0x110(%rax),%rax
   0x000055555577a023 <+6099>:	test   %rax,%rax
   0x000055555577a026 <+6102>:	je     0x55555577a184 <read_char+6452>

4481	        (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, 0, &bar_window,
   0x000055555577a02c <+6108>:	sub    $0x8,%rsp
   0x000055555577a030 <+6112>:	lea    -0x448(%rbp),%rsi
   0x000055555577a037 <+6119>:	lea    -0x468(%rbp),%rdi
   0x000055555577a03e <+6126>:	push   %rsi
   0x000055555577a03f <+6127>:	lea    -0x484(%rbp),%rcx
   0x000055555577a046 <+6134>:	xor    %esi,%esi
   0x000055555577a048 <+6136>:	lea    -0x460(%rbp),%rdx
   0x000055555577a04f <+6143>:	lea    -0x450(%rbp),%r9
   0x000055555577a056 <+6150>:	lea    -0x458(%rbp),%r8
   0x000055555577a05d <+6157>:	call   *%rax

4482	                                                    &part, &x, &y, &t);
4483
4484	      obj = Qnil;
4485
4486	      /* Decide if we should generate a switch-frame event.  Don't
4487		 generate switch-frame events for motion outside of all Emacs
4488		 frames.  */
4489	      if (!NILP (x) && f)
   0x000055555577a05f <+6159>:	cmpq   $0x0,-0x458(%rbp)

4481	        (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, 0, &bar_window,
   0x000055555577a067 <+6167>:	pop    %rsi
   0x000055555577a068 <+6168>:	pop    %rdi

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577a069 <+6169>:	je     0x55555577a176 <read_char+6438>

./src/keyboard.c:
4489	      if (!NILP (x) && f)
   0x000055555577a06f <+6175>:	mov    -0x468(%rbp),%rbx
   0x000055555577a076 <+6182>:	test   %rbx,%rbx
   0x000055555577a079 <+6185>:	je     0x55555577bbf0 <read_char+13216>

4490		{
4491		  Lisp_Object frame;
4492
4493		  frame = FRAME_FOCUS_FRAME (f);
   0x000055555577a07f <+6191>:	mov    0x38(%rbx),%rdx

4494		  if (NILP (frame))
   0x000055555577a083 <+6195>:	test   %rdx,%rdx
   0x000055555577a086 <+6198>:	je     0x55555577ad33 <read_char+9443>

4495		    XSETFRAME (frame, f);
4496
4497		  if (!EQ (frame, internal_last_event_frame)
   0x000055555577a08c <+6204>:	mov    0x38c095(%rip),%rsi        # 0x555555b06128 <internal_last_event_frame>
   0x000055555577a093 <+6211>:	mov    %rdx,%rdi
   0x000055555577a096 <+6214>:	mov    %rdx,-0x550(%rbp)
   0x000055555577a09d <+6221>:	call   0x555555764470 <EQ>
   0x000055555577a0a2 <+6226>:	mov    -0x550(%rbp),%rdx
   0x000055555577a0a9 <+6233>:	test   %al,%al
   0x000055555577a0ab <+6235>:	je     0x55555577ae7c <read_char+9772>

4499		    obj = make_lispy_switch_frame (frame);
4500		  internal_last_event_frame = frame;
   0x000055555577a0b1 <+6241>:	mov    %rdx,0x38c070(%rip)        # 0x555555b06128 <internal_last_event_frame>

4506		obj = make_lispy_movement (f, bar_window, part, x, y, t);
   0x000055555577a0b8 <+6248>:	mov    -0x448(%rbp),%rcx
   0x000055555577a0bf <+6255>:	mov    -0x484(%rbp),%esi
   0x000055555577a0c5 <+6261>:	mov    -0x460(%rbp),%r9
   0x000055555577a0cc <+6268>:	mov    -0x458(%rbp),%rax
   0x000055555577a0d3 <+6275>:	mov    -0x450(%rbp),%rdx

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577a0da <+6282>:	test   %r9,%r9
   0x000055555577a0dd <+6285>:	je     0x55555577bc05 <read_char+13237>

1183	  Lisp_Object a = TAG_PTR_INITIALLY (Lisp_Symbol, symoffset);
1184	  return a;
   0x000055555577a0e3 <+6291>:	lea    0x256df6(%rip),%rdi        # 0x5555559d0ee0 <scroll_bar_parts>
   0x000055555577a0ea <+6298>:	movswq (%rdi,%rsi,2),%rsi

1182	  char *symoffset = (char *) ((char *) sym - (char *) lispsym);
   0x000055555577a0ef <+6303>:	lea    0x0(,%rsi,8),%rbx
   0x000055555577a0f7 <+6311>:	sub    %rsi,%rbx
   0x000055555577a0fa <+6314>:	shl    $0x3,%rbx

1199	}
1200
1201	INLINE bool
1202	c_symbol_p (struct Lisp_Symbol *sym)
1203	{
1204	  char *bp = (char *) lispsym;
1205	  char *sp = (char *) sym;
1206	  if (PTRDIFF_MAX < INTPTR_MAX)
1207	    return bp <= sp && sp < bp + sizeof lispsym;
1208	  else
1209	    {
1210	      ptrdiff_t offset = sp - bp;
1211	      return 0 <= offset && offset < sizeof lispsym;
1212	    }
1213	}
1214
1215	INLINE void
1216	(CHECK_SYMBOL) (Lisp_Object x)
1217	{
1218	  lisp_h_CHECK_SYMBOL (x);
1219	}
1220
1221	/* True if the possibly-unsigned integer I doesn't fit in a fixnum.  */
1222
1223	#define FIXNUM_OVERFLOW_P(i) \
1224	  (! ((0 <= (i) || MOST_NEGATIVE_FIXNUM <= (i)) && (i) <= MOST_POSITIVE_FIXNUM))
1225
1226	#if USE_LSB_TAG
1227
1228	INLINE Lisp_Object
1229	(make_fixnum) (EMACS_INT n)
1230	{
1231	  eassert (!FIXNUM_OVERFLOW_P (n));
   0x000055555577a0fe <+6318>:	cmpb   $0x0,0x3a227b(%rip)        # 0x555555b1c380 <suppress_checking>
   0x000055555577a105 <+6325>:	jne    0x55555577a11e <read_char+6350>
   0x000055555577a107 <+6327>:	movabs $0x2000000000000000,%rsi
   0x000055555577a111 <+6337>:	add    %rcx,%rsi
   0x000055555577a114 <+6340>:	shr    $0x3e,%rsi
   0x000055555577a118 <+6344>:	jne    0x5555555b279a <read_char-1859766>

1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577a11e <+6350>:	lea    0x2(,%rcx,4),%rcx

./src/keyboard.c:
7151	      return list2 (Qscroll_bar_movement,
   0x000055555577a126 <+6358>:	mov    %rdx,%rsi
   0x000055555577a129 <+6361>:	mov    %rax,%rdi
   0x000055555577a12c <+6364>:	mov    %r9,-0x680(%rbp)

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577a133 <+6371>:	mov    %rcx,-0x678(%rbp)

./src/keyboard.c:
7151	      return list2 (Qscroll_bar_movement,
   0x000055555577a13a <+6378>:	call   0x5555557ef2b0 <Fcons>
   0x000055555577a13f <+6383>:	mov    -0x678(%rbp),%rcx
   0x000055555577a146 <+6390>:	mov    %rbx,%r8
   0x000055555577a149 <+6393>:	mov    -0x680(%rbp),%rdi
   0x000055555577a150 <+6400>:	mov    %rax,%rdx

./src/lisp.h:
1184	  return a;
   0x000055555577a153 <+6403>:	mov    $0x17060,%esi
   0x000055555577a158 <+6408>:	call   0x5555557ef690 <list5>
   0x000055555577a15d <+6413>:	mov    $0x132e8,%edi
   0x000055555577a162 <+6418>:	mov    %rax,%rsi
   0x000055555577a165 <+6421>:	call   0x5555557ef5d0 <list2>
   0x000055555577a16a <+6426>:	mov    %rax,%rcx

./src/keyboard.c:
4508	      if (!NILP (obj))
   0x000055555577a16d <+6429>:	test   %rcx,%rcx
   0x000055555577a170 <+6432>:	jne    0x55555577aedd <read_char+9869>

3621	  if (kbd_fetch_ptr != kbd_store_ptr)
   0x000055555577a176 <+6438>:	mov    0x34bf9b(%rip),%r8        # 0x555555ac6118 <kbd_fetch_ptr>
   0x000055555577a17d <+6445>:	mov    0x34bf8c(%rip),%rdx        # 0x555555ac6110 <kbd_store_ptr>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577a184 <+6452>:	xor    %r14d,%r14d

./src/keyboard.c:
3621	  if (kbd_fetch_ptr != kbd_store_ptr)
   0x000055555577a187 <+6455>:	mov    $0x1,%eax
   0x000055555577a18c <+6460>:	cmp    %rdx,%r8
   0x000055555577a18f <+6463>:	jne    0x555555779a33 <read_char+4579>
   0x000055555577a195 <+6469>:	nopl   (%rax)

3653		      event = next_kbd_event (event);
3654		    }
3655		  while (event != kbd_store_ptr);
3656	        }
3657	      else
3658		return 1;
3659	    }
3660
3661	#ifdef HAVE_X_WINDOWS
3662	  if (x_detect_pending_selection_requests ())
   0x000055555577a198 <+6472>:	call   0x55555571a8a0 <x_detect_pending_selection_requests>
   0x000055555577a19d <+6477>:	test   %al,%al
   0x000055555577a19f <+6479>:	jne    0x55555577a1b8 <read_char+6504>

3663	    return 1;
3664	#endif
3665
3666	#ifdef HAVE_TEXT_CONVERSION
3667	  if (detect_conversion_events ())
   0x000055555577a1a1 <+6481>:	call   0x5555559269f0 <detect_conversion_events>
   0x000055555577a1a6 <+6486>:	test   %al,%al
   0x000055555577a1a8 <+6488>:	jne    0x55555577a1b8 <read_char+6504>

3668	    return 1;
3669	#endif
3670
3671	  if (!(flags & READABLE_EVENTS_IGNORE_SQUEEZABLES) && some_mouse_moved ())
   0x000055555577a1aa <+6490>:	call   0x555555763840 <some_mouse_moved>
   0x000055555577a1af <+6495>:	test   %rax,%rax
   0x000055555577a1b2 <+6498>:	je     0x55555577a1c2 <read_char+6514>
   0x000055555577a1b4 <+6500>:	nopl   0x0(%rax)

3652			return 1;
   0x000055555577a1b8 <+6504>:	mov    $0x1,%eax
   0x000055555577a1bd <+6509>:	jmp    0x555555779a33 <read_char+4579>

3672	    return 1;
3673	  if (single_kboard)
   0x000055555577a1c2 <+6514>:	movzbl 0x38c46f(%rip),%eax        # 0x555555b06638 <single_kboard>
   0x000055555577a1c9 <+6521>:	test   %al,%al
   0x000055555577a1cb <+6523>:	je     0x55555577ae4f <read_char+9727>

3674	    {
3675	      if (current_kboard->kbd_queue_has_data)
   0x000055555577a1d1 <+6529>:	mov    0x38c088(%rip),%rax        # 0x555555b06260 <current_kboard>
   0x000055555577a1d8 <+6536>:	movzbl 0xb8(%rax),%eax
   0x000055555577a1df <+6543>:	jmp    0x555555779a33 <read_char+4579>
   0x000055555577a1e4 <+6548>:	nopl   0x0(%rax)

./src/systime.h:
70	  return t.tv_nsec >= 0;
   0x000055555577a1e8 <+6552>:	cmpq   $0x0,0x38c3c8(%rip)        # 0x555555b065b8 <timer_idleness_start_time+8>
   0x000055555577a1f0 <+6560>:	js     0x55555577a766 <read_char+7958>

./src/keyboard.c:
2829	  if (minibuf_level == 0
   0x000055555577a1f6 <+6566>:	cmpq   $0x0,0x3a03b2(%rip)        # 0x555555b1a5b0 <minibuf_level>
   0x000055555577a1fe <+6574>:	jne    0x555555778db4 <read_char+1380>

2830	      && !end_time
2831	      && !current_kboard->immediate_echo
   0x000055555577a204 <+6580>:	mov    0x38c055(%rip),%rax        # 0x555555b06260 <current_kboard>
   0x000055555577a20b <+6587>:	testb  $0x1,0xb9(%rax)
   0x000055555577a212 <+6594>:	jne    0x555555778db4 <read_char+1380>

2832	      && (this_command_key_count > 0
   0x000055555577a218 <+6600>:	cmpq   $0x0,0x38c028(%rip)        # 0x555555b06248 <this_command_key_count>
   0x000055555577a220 <+6608>:	jle    0x55555577bea0 <read_char+13904>

2834	      && ! noninteractive
   0x000055555577a226 <+6614>:	cmpb   $0x0,0x34be69(%rip)        # 0x555555ac6096 <noninteractive>
   0x000055555577a22d <+6621>:	jne    0x555555778db4 <read_char+1380>

2835	      && echo_keystrokes_p ()
   0x000055555577a233 <+6627>:	call   0x5555557639a0 <echo_keystrokes_p>
   0x000055555577a238 <+6632>:	test   %al,%al
   0x000055555577a23a <+6634>:	je     0x555555778db4 <read_char+1380>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577a240 <+6640>:	cmpq   $0x0,0x335348(%rip)        # 0x555555aaf590 <echo_area_buffer>
   0x000055555577a248 <+6648>:	je     0x55555577a284 <read_char+6708>

./src/keyboard.c:
2839		  || (BUF_BEG (XBUFFER (echo_area_buffer[0]))
   0x000055555577a24a <+6650>:	mov    0x33533f(%rip),%rdi        # 0x555555aaf590 <echo_area_buffer>
   0x000055555577a251 <+6657>:	call   0x555555763180 <XBUFFER>

2840		      == BUF_Z (XBUFFER (echo_area_buffer[0])))
   0x000055555577a256 <+6662>:	mov    0x2f8(%rax),%rax

2839		  || (BUF_BEG (XBUFFER (echo_area_buffer[0]))
   0x000055555577a25d <+6669>:	cmpq   $0x1,0x10(%rax)
   0x000055555577a262 <+6674>:	je     0x55555577a284 <read_char+6708>

2841		  /* Or already echoing from same kboard.  */
2842		  || (echo_kboard && ok_to_echo_at_next_pause == echo_kboard)
   0x000055555577a264 <+6676>:	mov    0x38befd(%rip),%rdx        # 0x555555b06168 <echo_kboard>
   0x000055555577a26b <+6683>:	mov    0x38c37e(%rip),%rax        # 0x555555b065f0 <ok_to_echo_at_next_pause>
   0x000055555577a272 <+6690>:	test   %rdx,%rdx
   0x000055555577a275 <+6693>:	je     0x55555577ca68 <read_char+16920>
   0x000055555577a27b <+6699>:	cmp    %rax,%rdx
   0x000055555577a27e <+6702>:	jne    0x555555778db4 <read_char+1380>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577a284 <+6708>:	mov    -0x4c0(%rbp),%eax
   0x000055555577a28a <+6714>:	sub    $0x3,%eax

./src/keyboard.c:
2849	      if (EVENT_HAS_PARAMETERS (prev_event))
   0x000055555577a28d <+6717>:	test   $0x7,%al
   0x000055555577a28f <+6719>:	je     0x55555577a495 <read_char+7237>

./src/lisp.h:
3986	  return wrap_specpdl_ref ((char *)specpdl_ptr - (char *)specpdl);
   0x000055555577a295 <+6725>:	mov    0x30d6c4(%rip),%rdx        # 0x555555a87960 <current_thread>

3912	  return (specpdl_ref){.bytes = bytes};
   0x000055555577a29c <+6732>:	lea    -0x240(%rbp),%rsi
   0x000055555577a2a3 <+6739>:	lea    -0x1756a(%rip),%rdi        # 0x555555762d40 <restore_getcjmp>

/usr/include/x86_64-linux-gnu/bits/string_fortified.h:
29	  return __builtin___memcpy_chk (__dest, __src, __len,
   0x000055555577a2aa <+6746>:	movdqu 0xd8(%rdx),%xmm7

./src/lisp.h:
3986	  return wrap_specpdl_ref ((char *)specpdl_ptr - (char *)specpdl);
   0x000055555577a2b2 <+6754>:	mov    0x88(%rdx),%rbx
   0x000055555577a2b9 <+6761>:	sub    0x78(%rdx),%rbx

/usr/include/x86_64-linux-gnu/bits/string_fortified.h:
29	  return __builtin___memcpy_chk (__dest, __src, __len,
   0x000055555577a2bd <+6765>:	movdqu 0x108(%rdx),%xmm3
   0x000055555577a2c5 <+6773>:	movaps %xmm7,-0x240(%rbp)
   0x000055555577a2cc <+6780>:	movdqu 0xe8(%rdx),%xmm7
   0x000055555577a2d4 <+6788>:	movdqu 0x128(%rdx),%xmm6
   0x000055555577a2dc <+6796>:	movaps %xmm3,-0x210(%rbp)
   0x000055555577a2e3 <+6803>:	movdqu 0x138(%rdx),%xmm3
   0x000055555577a2eb <+6811>:	movdqu 0x168(%rdx),%xmm2
   0x000055555577a2f3 <+6819>:	movaps %xmm7,-0x230(%rbp)
   0x000055555577a2fa <+6826>:	movdqu 0xf8(%rdx),%xmm7
   0x000055555577a302 <+6834>:	mov    0x198(%rdx),%rax
   0x000055555577a309 <+6841>:	movaps %xmm6,-0x1f0(%rbp)
   0x000055555577a310 <+6848>:	movdqu 0x158(%rdx),%xmm6
   0x000055555577a318 <+6856>:	movaps %xmm7,-0x220(%rbp)
   0x000055555577a31f <+6863>:	movdqu 0x118(%rdx),%xmm7
   0x000055555577a327 <+6871>:	movaps %xmm3,-0x1e0(%rbp)
   0x000055555577a32e <+6878>:	movdqu 0x178(%rdx),%xmm3
   0x000055555577a336 <+6886>:	movaps %xmm7,-0x200(%rbp)
   0x000055555577a33d <+6893>:	movdqu 0x148(%rdx),%xmm7
   0x000055555577a345 <+6901>:	movaps %xmm6,-0x1c0(%rbp)
   0x000055555577a34c <+6908>:	movaps %xmm7,-0x1d0(%rbp)
   0x000055555577a353 <+6915>:	movdqu 0x188(%rdx),%xmm7
   0x000055555577a35b <+6923>:	mov    %rax,-0x180(%rbp)

./src/keyboard.c:
2857		  record_unwind_protect_ptr (restore_getcjmp, save_jump);
   0x000055555577a362 <+6930>:	movaps %xmm2,-0x1b0(%rbp)
   0x000055555577a369 <+6937>:	movaps %xmm3,-0x1a0(%rbp)
   0x000055555577a370 <+6944>:	movaps %xmm7,-0x190(%rbp)
   0x000055555577a377 <+6951>:	call   0x5555558201a0 <record_unwind_protect_ptr>

/usr/include/x86_64-linux-gnu/bits/string_fortified.h:
29	  return __builtin___memcpy_chk (__dest, __src, __len,
   0x000055555577a37c <+6956>:	mov    0x30d5dd(%rip),%rdx        # 0x555555a87960 <current_thread>

./src/keyboard.c:
2859		  tem0 = sit_for (Vecho_keystrokes, 1, 1);
   0x000055555577a383 <+6963>:	mov    $0x1,%esi

/usr/include/x86_64-linux-gnu/bits/string_fortified.h:
29	  return __builtin___memcpy_chk (__dest, __src, __len,
   0x000055555577a388 <+6968>:	movdqa -0x310(%rbp),%xmm6
   0x000055555577a390 <+6976>:	movdqa -0x300(%rbp),%xmm2
   0x000055555577a398 <+6984>:	movups %xmm6,0xd8(%rdx)
   0x000055555577a39f <+6991>:	movdqa -0x2f0(%rbp),%xmm3
   0x000055555577a3a7 <+6999>:	lea    0xd8(%rdx),%rax
   0x000055555577a3ae <+7006>:	movups %xmm2,0xe8(%rdx)
   0x000055555577a3b5 <+7013>:	movdqa -0x2e0(%rbp),%xmm7
   0x000055555577a3bd <+7021>:	movups %xmm3,0xf8(%rdx)
   0x000055555577a3c4 <+7028>:	movdqa -0x2d0(%rbp),%xmm6
   0x000055555577a3cc <+7036>:	movups %xmm7,0x108(%rdx)
   0x000055555577a3d3 <+7043>:	movdqa -0x2c0(%rbp),%xmm2
   0x000055555577a3db <+7051>:	movups %xmm6,0x118(%rdx)
   0x000055555577a3e2 <+7058>:	movdqa -0x2b0(%rbp),%xmm3
   0x000055555577a3ea <+7066>:	movups %xmm2,0x128(%rdx)
   0x000055555577a3f1 <+7073>:	movdqa -0x2a0(%rbp),%xmm7
   0x000055555577a3f9 <+7081>:	movups %xmm3,0x138(%rdx)
   0x000055555577a400 <+7088>:	movdqa -0x290(%rbp),%xmm6
   0x000055555577a408 <+7096>:	movups %xmm7,0x148(%rdx)
   0x000055555577a40f <+7103>:	movdqa -0x280(%rbp),%xmm2
   0x000055555577a417 <+7111>:	movups %xmm6,0x158(%rdx)
   0x000055555577a41e <+7118>:	movdqa -0x270(%rbp),%xmm3
   0x000055555577a426 <+7126>:	movups %xmm2,0x168(%rdx)
   0x000055555577a42d <+7133>:	movdqa -0x260(%rbp),%xmm7
   0x000055555577a435 <+7141>:	movups %xmm3,0x178(%rdx)
   0x000055555577a43c <+7148>:	movups %xmm7,0x188(%rdx)
   0x000055555577a443 <+7155>:	mov    -0x250(%rbp),%rdx
   0x000055555577a44a <+7162>:	mov    %rdx,0xc0(%rax)

./src/keyboard.c:
2859		  tem0 = sit_for (Vecho_keystrokes, 1, 1);
   0x000055555577a451 <+7169>:	mov    0x3a6378(%rip),%rdi        # 0x555555b207d0 <globals+912>
   0x000055555577a458 <+7176>:	mov    $0x1,%edx
   0x000055555577a45d <+7181>:	call   0x5555555e5750 <sit_for>

2860		  unbind_to (count, Qnil);
   0x000055555577a462 <+7186>:	xor    %esi,%esi
   0x000055555577a464 <+7188>:	mov    %rbx,%rdi

2859		  tem0 = sit_for (Vecho_keystrokes, 1, 1);
   0x000055555577a467 <+7191>:	mov    %rax,%r13

./src/lisp.h:
1184	  return a;
   0x000055555577a46a <+7194>:	call   0x5555558204b0 <unbind_to>
   0x000055555577a46f <+7199>:	mov    $0x38,%esi

./src/keyboard.c:
2861		  if (EQ (tem0, Qt)
   0x000055555577a474 <+7204>:	mov    %r13,%rdi
   0x000055555577a477 <+7207>:	call   0x555555764470 <EQ>
   0x000055555577a47c <+7212>:	test   %al,%al
   0x000055555577a47e <+7214>:	je     0x555555778db4 <read_char+1380>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577a484 <+7220>:	mov    0x3a6bee(%rip),%eax        # 0x555555b21078 <globals+3128>
   0x000055555577a48a <+7226>:	sub    $0x3,%eax

./src/keyboard.c:
2862		      && ! CONSP (Vunread_command_events))
   0x000055555577a48d <+7229>:	test   $0x7,%al
   0x000055555577a48f <+7231>:	je     0x555555778db4 <read_char+1380>

2863		    echo_now ();
   0x000055555577a495 <+7237>:	call   0x555555767ae0 <echo_now>
   0x000055555577a49a <+7242>:	jmp    0x555555778db4 <read_char+1380>
   0x000055555577a49f <+7247>:	nop

2787		KBOARD *kb = FRAME_KBOARD (XFRAME (selected_frame));
   0x000055555577a4a0 <+7248>:	lea    -0x5(%rax),%rcx
   0x000055555577a4a4 <+7252>:	jmp    0x55555577923e <read_char+2542>
   0x000055555577a4a9 <+7257>:	nopl   0x0(%rax)

2877	    }
2878
2879	  /* Try reading using an X menu.
2880	     This is never confused with reading using the minibuf
2881	     because the recursive call of read_char in read_char_minibuf_menu_prompt
2882	     does not pass on any keymaps.  */
2883
2884	  if (KEYMAPP (map) && INTERACTIVE
   0x000055555577a4b0 <+7264>:	cmpb   $0x0,0x34bbdf(%rip)        # 0x555555ac6096 <noninteractive>
   0x000055555577a4b7 <+7271>:	jne    0x555555778e16 <read_char+1478>

2885	      && !NILP (prev_event)
   0x000055555577a4bd <+7277>:	mov    -0x4c0(%rbp),%rax
   0x000055555577a4c4 <+7284>:	test   %rax,%rax
   0x000055555577a4c7 <+7287>:	je     0x55555577a4d4 <read_char+7300>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577a4c9 <+7289>:	sub    $0x3,%eax

./src/keyboard.c:
2886	      && EVENT_HAS_PARAMETERS (prev_event)
   0x000055555577a4cc <+7292>:	test   $0x7,%al
   0x000055555577a4ce <+7294>:	je     0x55555577bc25 <read_char+13269>

2897		timer_stop_idle ();
2898
2899	      goto exit;
2900	    }
2901
2902	  /* Maybe autosave and/or garbage collect due to idleness.  */
2903
2904	  if (INTERACTIVE && NILP (c))
   0x000055555577a4d4 <+7300>:	mov    %r14,%rbx
   0x000055555577a4d7 <+7303>:	jmp    0x5555557792b9 <read_char+2665>
   0x000055555577a4dc <+7308>:	nopl   0x0(%rax)
   0x000055555577a4e0 <+7312>:	call   0x555555764a20 <start_polling>
   0x000055555577a4e5 <+7317>:	jmp    0x555555778b48 <read_char+760>

429	  return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1;
   0x000055555577a4ea <+7322>:	lea    0x38bbef(%rip),%rdx        # 0x555555b060e0 <kbd_buffer+262080>
   0x000055555577a4f1 <+7329>:	lea    0x40(%r8),%rax
   0x000055555577a4f5 <+7333>:	mov    %r8,-0x510(%rbp)
   0x000055555577a4fc <+7340>:	cmp    %rdx,%r8
   0x000055555577a4ff <+7343>:	lea    -0x3ffc0(%rdx),%rdx
   0x000055555577a506 <+7350>:	cmove  %rdx,%rax

3399
3400	/* Record a key that came from a mouse menu.
3401	   Record it for echoing, for this-command-keys, and so on.  */
3402
3403	static void
3404	record_menu_key (Lisp_Object c)
3405	{
3406	  /* Wipe the echo area.  */
3407	  clear_message (1, 0);
3408
3409	  record_char (c);
3410
3411	  /* Once we reread a character, echoing can happen
3412	     the next time we pause to read a new one.  */
3413	  ok_to_echo_at_next_pause = NULL;
3414
3415	  /* Record this character as part of the current key.  */
3416	  add_command_key (c);
3417	  echo_update ();
3418
3419	  /* Re-reading in the middle of a command.  */
3420	  last_input_event = c;
3421	  num_input_events++;
3422	}
3423
3424	/* Return true if should recognize C as "the help character".  */
3425
3426	static bool
3427	help_char_p (Lisp_Object c)
3428	{
3429	  if (EQ (c, Vhelp_char))
3430	    return true;
3431	  Lisp_Object tail = Vhelp_event_list;
3432	  FOR_EACH_TAIL_SAFE (tail)
3433	    if (EQ (c, XCAR (tail)))
3434	      return true;
3435	  return false;
3436	}
3437
3438	/* Record the input event C in various ways.  */
3439
3440	static void
3441	record_char (Lisp_Object c)
3442	{
3443	  /* subr.el/read-passwd binds inhibit_record_char to avoid recording
3444	     passwords.  */
3445	  if (!record_all_keys && inhibit_record_char)
3446	    return;
3447
3448	  int recorded = 0;
3449
3450	  if (CONSP (c) && (EQ (XCAR (c), Qhelp_echo) || EQ (XCAR (c), Qmouse_movement)))
3451	    {
3452	      /* To avoid filling recent_keys with help-echo and mouse-movement
3453		 events, we filter out repeated help-echo events, only store the
3454		 first and last in a series of mouse-movement events, and don't
3455		 store repeated help-echo events which are only separated by
3456		 mouse-movement events.  */
3457
3458	      Lisp_Object ev1, ev2, ev3;
3459	      int ix1, ix2, ix3;
3460
3461	      if ((ix1 = recent_keys_index - 1) < 0)
3462		ix1 = lossage_limit - 1;
3463	      ev1 = AREF (recent_keys, ix1);
3464
3465	      if ((ix2 = ix1 - 1) < 0)
3466		ix2 = lossage_limit - 1;
3467	      ev2 = AREF (recent_keys, ix2);
3468
3469	      if ((ix3 = ix2 - 1) < 0)
3470		ix3 = lossage_limit - 1;
3471	      ev3 = AREF (recent_keys, ix3);
3472
3473	      if (EQ (XCAR (c), Qhelp_echo))
3474		{
3475		  /* Don't record `help-echo' in recent_keys unless it shows some help
3476		     message, and a different help than the previously recorded
3477		     event.  */
3478		  Lisp_Object help, last_help;
3479
3480		  help = Fcar_safe (Fcdr_safe (XCDR (c)));
3481		  if (!STRINGP (help))
3482		    recorded = 1;
3483		  else if (CONSP (ev1) && EQ (XCAR (ev1), Qhelp_echo)
3484			   && (last_help = Fcar_safe (Fcdr_safe (XCDR (ev1))), EQ (last_help, help)))
3485		    recorded = 1;
3486		  else if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
3487			   && CONSP (ev2) && EQ (XCAR (ev2), Qhelp_echo)
3488			   && (last_help = Fcar_safe (Fcdr_safe (XCDR (ev2))), EQ (last_help, help)))
3489		    recorded = -1;
3490		  else if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
3491			   && CONSP (ev2) && EQ (XCAR (ev2), Qmouse_movement)
3492			   && CONSP (ev3) && EQ (XCAR (ev3), Qhelp_echo)
3493			   && (last_help = Fcar_safe (Fcdr_safe (XCDR (ev3))), EQ (last_help, help)))
3494		    recorded = -2;
3495		}
3496	      else if (EQ (XCAR (c), Qmouse_movement))
3497		{
3498		  /* Only record one pair of `mouse-movement' on a window in recent_keys.
3499		     So additional mouse movement events replace the last element.  */
3500		  Lisp_Object last_window, window;
3501
3502		  window = Fcar_safe (Fcar_safe (XCDR (c)));
3503		  if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
3504		      && (last_window = Fcar_safe (Fcar_safe (XCDR (ev1))), EQ (last_window, window))
3505		      && CONSP (ev2) && EQ (XCAR (ev2), Qmouse_movement)
3506		      && (last_window = Fcar_safe (Fcar_safe (XCDR (ev2))), EQ (last_window, window)))
3507		    {
3508		      ASET (recent_keys, ix1, c);
3509		      recorded = 1;
3510		    }
3511		}
3512	    }
3513	  else if (NILP (Vexecuting_kbd_macro))
3514	    store_kbd_macro_char (c);
3515
3516	  /* recent_keys should not include events from keyboard macros.  */
3517	  if (NILP (Vexecuting_kbd_macro))
3518	    {
3519	      if (!recorded)
3520		{
3521		  total_keys += total_keys < lossage_limit;
3522		  ASET (recent_keys, recent_keys_index,
3523	                /* Copy the event, in case it gets modified by side-effect
3524	                   by some remapping function (bug#30955).  */
3525	                CONSP (c) ? Fcopy_sequence (c) : c);
3526		  if (++recent_keys_index >= lossage_limit)
3527		    recent_keys_index = 0;
3528		}
3529	      else if (recorded < 0)
3530		{
3531		  /* We need to remove one or two events from recent_keys.
3532		     To do this, we simply put nil at those events and move the
3533		     recent_keys_index backwards over those events.  Usually,
3534		     users will never see those nil events, as they will be
3535		     overwritten by the command keys entered to see recent_keys
3536		     (e.g. C-h l).  */
3537
3538		  while (recorded++ < 0 && total_keys > 0)
3539		    {
3540		      if (total_keys < lossage_limit)
3541			total_keys--;
3542		      if (--recent_keys_index < 0)
3543			recent_keys_index = lossage_limit - 1;
3544		      ASET (recent_keys, recent_keys_index, Qnil);
3545		    }
3546		}
3547
3548	      num_nonmacro_input_events++;
3549	    }
3550
3551	  /* Write c to the dribble file.  If c is a lispy event, write
3552	     the event's symbol to the dribble file, in <brackets>.  Bleaugh.
3553	     If you, dear reader, have a better idea, you've got the source.  :-) */
3554	  if (dribble && NILP (Vexecuting_kbd_macro))
3555	    {
3556	      block_input ();
3557	      if (FIXNUMP (c))
3558		{
3559		  if (XUFIXNUM (c) < 0x100)
3560		    putc (XUFIXNUM (c), dribble);
3561		  else
3562		    fprintf (dribble, " 0x%"pI"x", XUFIXNUM (c));
3563		}
3564	      else
3565		{
3566		  Lisp_Object dribblee;
3567
3568		  /* If it's a structured event, take the event header.  */
3569		  dribblee = EVENT_HEAD (c);
3570
3571		  if (SYMBOLP (dribblee))
3572		    {
3573		      putc ('<', dribble);
3574		      fwrite (SDATA (SYMBOL_NAME (dribblee)), sizeof (char),
3575			      SBYTES (SYMBOL_NAME (dribblee)), dribble);
3576		      putc ('>', dribble);
3577		    }
3578		}
3579
3580	      fflush (dribble);
3581	      unblock_input ();
3582	    }
3583	}
3584
3585	/* Copy out or in the info on where C-g should throw to.
3586	   This is used when running Lisp code from within get_char,
3587	   in case get_char is called recursively.
3588	   See read_process_output.  */
3589
3590	static void
3591	save_getcjmp (sys_jmp_buf temp)
3592	{
3593	  memcpy (temp, getcjmp, sizeof getcjmp);
3594	}
3595
3596	static void
3597	restore_getcjmp (void *temp)
3598	{
3599	  memcpy (getcjmp, temp, sizeof getcjmp);
3600	}
3601	^L
3602	/* Low level keyboard/mouse input.
3603	   kbd_buffer_store_event places events in kbd_buffer, and
3604	   kbd_buffer_get_event retrieves them.  */
3605
3606	/* Return true if there are any events in the queue that read-char
3607	   would return.  If this returns false, a read-char would block.  */
3608	static bool
3609	readable_events (int flags)
3610	{
3611	  if (flags & READABLE_EVENTS_DO_TIMERS_NOW)
3612	    timer_check ();
3613
3614	  /* READABLE_EVENTS_FILTER_EVENTS is meant to be used only by
3615	     input-pending-p and similar callers, which aren't interested in
3616	     some input events.  If this flag is set, and
3617	     input-pending-p-filter-events is non-nil, ignore events in
3618	     while-no-input-ignore-events.  If the flag is set and
3619	     input-pending-p-filter-events is nil, ignore only
3620	     FOCUS_IN/OUT_EVENT events.  */
3621	  if (kbd_fetch_ptr != kbd_store_ptr)
   0x000055555577a50a <+7354>:	xor    %r14d,%r14d

4201	#else
4202	      case SELECTION_REQUEST_EVENT:
4203		emacs_abort ();
4204
4205	      case SELECTION_CLEAR_EVENT:
4206		{
4207		  struct input_event copy = event->ie;
4208
4209		  kbd_fetch_ptr = next_kbd_event (event);
4210		  input_pending = readable_events (0);
4211		  haiku_handle_selection_clear (&copy);
4212		}
4213		break;
4214	#endif
4215
4216	      case MONITORS_CHANGED_EVENT:
4217		{
4218		  kbd_fetch_ptr = next_kbd_event (event);
   0x000055555577a50d <+7357>:	mov    %rax,0x34bc04(%rip)        # 0x555555ac6118 <kbd_fetch_ptr>

4219		  input_pending = readable_events (0);
   0x000055555577a514 <+7364>:	call   0x555555763910 <readable_events>

4220
4221		  CALLN (Frun_hook_with_args,
   0x000055555577a519 <+7369>:	mov    -0x510(%rbp),%r8
   0x000055555577a520 <+7376>:	mov    $0x2,%edi
   0x000055555577a525 <+7381>:	lea    -0x3d0(%rbp),%rsi

4219		  input_pending = readable_events (0);
   0x000055555577a52c <+7388>:	mov    %al,0x38bbef(%rip)        # 0x555555b06121 <input_pending>

4220
4221		  CALLN (Frun_hook_with_args,
   0x000055555577a532 <+7394>:	movq   $0x85e0,-0x3d0(%rbp)
   0x000055555577a53d <+7405>:	mov    0x30(%r8),%rax
   0x000055555577a541 <+7409>:	mov    %rax,-0x3c8(%rbp)
   0x000055555577a548 <+7416>:	call   0x555555821740 <Frun_hook_with_args>

4222			 Qdisplay_monitors_changed_functions,
4223			 event->ie.arg);
4224
4225		  break;
   0x000055555577a54d <+7421>:	mov    0x34bbc4(%rip),%r8        # 0x555555ac6118 <kbd_fetch_ptr>
   0x000055555577a554 <+7428>:	mov    0x34bbb5(%rip),%rdx        # 0x555555ac6110 <kbd_store_ptr>
   0x000055555577a55b <+7435>:	jmp    0x555555779a25 <read_char+4565>

4132	  if (CONSP (Vunread_command_events))
   0x000055555577a560 <+7440>:	mov    0x3a6b11(%rip),%rdx        # 0x555555b21078 <globals+3128>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577a567 <+7447>:	lea    -0x3(%rdx),%eax

./src/keyboard.c:
4132	  if (CONSP (Vunread_command_events))
   0x000055555577a56a <+7450>:	test   $0x7,%al
   0x000055555577a56c <+7452>:	je     0x555555779ea8 <read_char+5720>

4139	    }
4140
4141	#ifdef HAVE_TEXT_CONVERSION
4142	  /* There are pending text conversion operations.  Text conversion
4143	     events should be generated before processing any other keyboard
4144	     input.  */
4145	  if (had_pending_conversion_events)
4146	    {
4147	      handle_pending_conversion_events ();
   0x000055555577a572 <+7458>:	call   0x555555926b40 <handle_pending_conversion_events>

4148	      obj = Qtext_conversion;
4149
4150	      /* See the comment in handle_pending_conversion_events_1.
4151	         Note that in addition, text conversion events are not
4152	         generated if no edits were actually made.  */
4153	      if (conversion_disabled_p ()
   0x000055555577a577 <+7463>:	xor    %r14d,%r14d
   0x000055555577a57a <+7466>:	call   0x55555592a080 <conversion_disabled_p>

3621	  if (kbd_fetch_ptr != kbd_store_ptr)
   0x000055555577a57f <+7471>:	mov    0x34bb92(%rip),%r8        # 0x555555ac6118 <kbd_fetch_ptr>
   0x000055555577a586 <+7478>:	mov    0x34bb83(%rip),%rdx        # 0x555555ac6110 <kbd_store_ptr>

4148	      obj = Qtext_conversion;
4149
4150	      /* See the comment in handle_pending_conversion_events_1.
4151	         Note that in addition, text conversion events are not
4152	         generated if no edits were actually made.  */
4153	      if (conversion_disabled_p ()
   0x000055555577a58d <+7485>:	test   %al,%al
   0x000055555577a58f <+7487>:	jne    0x555555779a25 <read_char+4565>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577a595 <+7493>:	mov    0x3a69ec(%rip),%rax        # 0x555555b20f88 <globals+2888>
   0x000055555577a59c <+7500>:	neg    %rax
   0x000055555577a59f <+7503>:	sbb    %r14,%r14
   0x000055555577a5a2 <+7506>:	and    $0x14e08,%r14d
   0x000055555577a5a9 <+7513>:	jmp    0x555555779a25 <read_char+4565>

./src/keyboard.c:
4185		  struct selection_input_event copy = event->sie;
   0x000055555577a5ae <+7518>:	movdqu (%r8),%xmm2

429	  return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1;
   0x000055555577a5b3 <+7523>:	lea    0x38bb26(%rip),%rdx        # 0x555555b060e0 <kbd_buffer+262080>
   0x000055555577a5ba <+7530>:	cmp    %rdx,%r8
   0x000055555577a5bd <+7533>:	lea    -0x3ffc0(%rdx),%rdx

4176	      {
4177	#ifndef HAVE_HAIKU
4178	      case SELECTION_REQUEST_EVENT:
4179	      case SELECTION_CLEAR_EVENT:
4180		{
4181	#if defined HAVE_X11 || HAVE_PGTK
4182		  /* Remove it from the buffer before processing it,
4183		     since otherwise swallow_events will see it
4184		     and process it again.  */
4185		  struct selection_input_event copy = event->sie;
   0x000055555577a5c4 <+7540>:	movaps %xmm2,-0x440(%rbp)
   0x000055555577a5cb <+7547>:	movdqu 0x10(%r8),%xmm1
   0x000055555577a5d1 <+7553>:	movaps %xmm1,-0x430(%rbp)
   0x000055555577a5d8 <+7560>:	movdqu 0x20(%r8),%xmm2
   0x000055555577a5de <+7566>:	movaps %xmm2,-0x420(%rbp)
   0x000055555577a5e5 <+7573>:	mov    0x30(%r8),%rax
   0x000055555577a5e9 <+7577>:	mov    %rax,-0x410(%rbp)

429	  return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1;
   0x000055555577a5f0 <+7584>:	lea    0x40(%r8),%rax
   0x000055555577a5f4 <+7588>:	cmove  %rdx,%rax

4191	#else
4192		  pgtk_handle_selection_event (&copy);
4193	#endif
4194	#else
4195		  /* We're getting selection request events, but we don't have
4196	             a window system.  */
4197		  emacs_abort ();
4198	#endif
4199		}
4200	        break;
   0x000055555577a5f8 <+7592>:	xor    %r14d,%r14d

4186		  kbd_fetch_ptr = next_kbd_event (event);
   0x000055555577a5fb <+7595>:	mov    %rax,0x34bb16(%rip)        # 0x555555ac6118 <kbd_fetch_ptr>

4187		  input_pending = readable_events (0);
   0x000055555577a602 <+7602>:	call   0x555555763910 <readable_events>

4188
4189	#ifdef HAVE_X11
4190		  x_handle_selection_event (&copy);
   0x000055555577a607 <+7607>:	lea    -0x440(%rbp),%rdi

4187		  input_pending = readable_events (0);
   0x000055555577a60e <+7614>:	mov    %al,0x38bb0d(%rip)        # 0x555555b06121 <input_pending>

4188
4189	#ifdef HAVE_X11
4190		  x_handle_selection_event (&copy);
   0x000055555577a614 <+7620>:	call   0x555555753b30 <x_handle_selection_event>

4191	#else
4192		  pgtk_handle_selection_event (&copy);
4193	#endif
4194	#else
4195		  /* We're getting selection request events, but we don't have
4196	             a window system.  */
4197		  emacs_abort ();
4198	#endif
4199		}
4200	        break;
   0x000055555577a619 <+7625>:	mov    0x34baf8(%rip),%r8        # 0x555555ac6118 <kbd_fetch_ptr>
   0x000055555577a620 <+7632>:	mov    0x34bae9(%rip),%rdx        # 0x555555ac6110 <kbd_store_ptr>
   0x000055555577a627 <+7639>:	jmp    0x555555779a25 <read_char+4565>
   0x000055555577a62c <+7644>:	nopl   0x0(%rax)

4226		}
4227
4228	#ifdef HAVE_ANDROID
4229	      case NOTIFICATION_EVENT:
4230	        {
4231		  kbd_fetch_ptr = next_kbd_event (event);
4232		  input_pending = readable_events (0);
4233		  CALLN (Fapply, XCAR (event->ie.arg), XCDR (event->ie.arg));
4234		  break;
4235		}
4236	#endif /* HAVE_ANDROID */
4237
4238	#ifdef HAVE_EXT_MENU_BAR
4239	      case MENU_BAR_ACTIVATE_EVENT:
4240		{
4241	          struct frame *f;
4242		  kbd_fetch_ptr = next_kbd_event (event);
4243		  input_pending = readable_events (0);
4244	          f = (XFRAME (event->ie.frame_or_window));
4245		  if (FRAME_LIVE_P (f) && FRAME_TERMINAL (f)->activate_menubar_hook)
4246		    FRAME_TERMINAL (f)->activate_menubar_hook (f);
4247		}
4248	        break;
4249	#endif
4250	#if defined (HAVE_NS)
4251	      case NS_TEXT_EVENT:
4252		if (used_mouse_menu)
4253		  *used_mouse_menu = true;
4254		FALLTHROUGH;
4255	#endif
4256	      case PREEDIT_TEXT_EVENT:
4257	#ifdef HAVE_NTGUI
4258	      case END_SESSION_EVENT:
4259	      case LANGUAGE_CHANGE_EVENT:
4260	#endif
4261	#ifdef HAVE_WINDOW_SYSTEM
4262	      case DELETE_WINDOW_EVENT:
4263	      case ICONIFY_EVENT:
4264	      case DEICONIFY_EVENT:
4265	      case MOVE_FRAME_EVENT:
4266	#endif
4267	#ifdef USE_FILE_NOTIFY
4268	      case FILE_NOTIFY_EVENT:
4269	#endif
4270	#ifdef HAVE_DBUS
4271	      case DBUS_EVENT:
4272	#endif
4273	#ifdef THREADS_ENABLED
4274	      case THREAD_EVENT:
4275	#endif
4276	#ifdef HAVE_XWIDGETS
4277	      case XWIDGET_EVENT:
4278	      case XWIDGET_DISPLAY_EVENT:
4279	#endif
4280	      case SAVE_SESSION_EVENT:
4281	      case NO_EVENT:
4282	      case HELP_EVENT:
4283	      case FOCUS_IN_EVENT:
4284	      case CONFIG_CHANGED_EVENT:
4285	      case FOCUS_OUT_EVENT:
4286	      case SELECT_WINDOW_EVENT:
4287	        {
4288	          obj = make_lispy_event (&event->ie);
   0x000055555577a630 <+7648>:	mov    %r8,%rdi
   0x000055555577a633 <+7651>:	mov    %r8,-0x518(%rbp)
   0x000055555577a63a <+7658>:	call   0x55555576bb10 <make_lispy_event>

429	  return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1;
   0x000055555577a63f <+7663>:	mov    -0x518(%rbp),%r8

4226		}
4227
4228	#ifdef HAVE_ANDROID
4229	      case NOTIFICATION_EVENT:
4230	        {
4231		  kbd_fetch_ptr = next_kbd_event (event);
4232		  input_pending = readable_events (0);
4233		  CALLN (Fapply, XCAR (event->ie.arg), XCDR (event->ie.arg));
4234		  break;
4235		}
4236	#endif /* HAVE_ANDROID */
4237
4238	#ifdef HAVE_EXT_MENU_BAR
4239	      case MENU_BAR_ACTIVATE_EVENT:
4240		{
4241	          struct frame *f;
4242		  kbd_fetch_ptr = next_kbd_event (event);
4243		  input_pending = readable_events (0);
4244	          f = (XFRAME (event->ie.frame_or_window));
4245		  if (FRAME_LIVE_P (f) && FRAME_TERMINAL (f)->activate_menubar_hook)
4246		    FRAME_TERMINAL (f)->activate_menubar_hook (f);
4247		}
4248	        break;
4249	#endif
4250	#if defined (HAVE_NS)
4251	      case NS_TEXT_EVENT:
4252		if (used_mouse_menu)
4253		  *used_mouse_menu = true;
4254		FALLTHROUGH;
4255	#endif
4256	      case PREEDIT_TEXT_EVENT:
4257	#ifdef HAVE_NTGUI
4258	      case END_SESSION_EVENT:
4259	      case LANGUAGE_CHANGE_EVENT:
4260	#endif
4261	#ifdef HAVE_WINDOW_SYSTEM
4262	      case DELETE_WINDOW_EVENT:
4263	      case ICONIFY_EVENT:
4264	      case DEICONIFY_EVENT:
4265	      case MOVE_FRAME_EVENT:
4266	#endif
4267	#ifdef USE_FILE_NOTIFY
4268	      case FILE_NOTIFY_EVENT:
4269	#endif
4270	#ifdef HAVE_DBUS
4271	      case DBUS_EVENT:
4272	#endif
4273	#ifdef THREADS_ENABLED
4274	      case THREAD_EVENT:
4275	#endif
4276	#ifdef HAVE_XWIDGETS
4277	      case XWIDGET_EVENT:
4278	      case XWIDGET_DISPLAY_EVENT:
4279	#endif
4280	      case SAVE_SESSION_EVENT:
4281	      case NO_EVENT:
4282	      case HELP_EVENT:
4283	      case FOCUS_IN_EVENT:
4284	      case CONFIG_CHANGED_EVENT:
4285	      case FOCUS_OUT_EVENT:
4286	      case SELECT_WINDOW_EVENT:
4287	        {
4288	          obj = make_lispy_event (&event->ie);
   0x000055555577a646 <+7670>:	mov    %rax,%r14

429	  return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1;
   0x000055555577a649 <+7673>:	lea    0x38ba90(%rip),%rdx        # 0x555555b060e0 <kbd_buffer+262080>
   0x000055555577a650 <+7680>:	lea    0x40(%r8),%rax
   0x000055555577a654 <+7684>:	cmp    %rdx,%r8
   0x000055555577a657 <+7687>:	lea    -0x3ffc0(%rdx),%r8
   0x000055555577a65e <+7694>:	cmovne %rax,%r8

4454			{
4455			  /* Wipe out this event, to catch bugs.  */
4456			  clear_event (&event->ie);
4457			  kbd_fetch_ptr = next_kbd_event (event);
   0x000055555577a662 <+7698>:	mov    %r8,0x34baaf(%rip)        # 0x555555ac6118 <kbd_fetch_ptr>
   0x000055555577a669 <+7705>:	jmp    0x555555779a1e <read_char+4558>
   0x000055555577a66e <+7710>:	mov    %esi,%ebx
   0x000055555577a670 <+7712>:	jmp    0x55555577a699 <read_char+7753>
   0x000055555577a672 <+7714>:	nopw   0x0(%rax,%rax,1)

2491		    Vunread_command_events
   0x000055555577a678 <+7720>:	sub    $0x1,%ebx

2492		      = Fcons (events[--n], Vunread_command_events);
   0x000055555577a67b <+7723>:	mov    0x3a69f6(%rip),%rsi        # 0x555555b21078 <globals+3128>
   0x000055555577a682 <+7730>:	movslq %ebx,%rax
   0x000055555577a685 <+7733>:	mov    -0x390(%rbp,%rax,8),%rdi
   0x000055555577a68d <+7741>:	call   0x5555557ef2b0 <Fcons>
   0x000055555577a692 <+7746>:	mov    %rax,0x3a69df(%rip)        # 0x555555b21078 <globals+3128>

2490		  while (n > 1)
   0x000055555577a699 <+7753>:	cmp    $0x1,%ebx
   0x000055555577a69c <+7756>:	jg     0x55555577a678 <read_char+7720>

2493		  return events[0];
   0x000055555577a69e <+7758>:	mov    -0x390(%rbp),%r14

3030	    {
3031	      c = read_decoded_event_from_main_queue (end_time, local_getcjmp,
3032	                                              prev_event, used_mouse_menu);
3033	      if (NILP (c) && end_time
   0x000055555577a6a5 <+7765>:	test   %r14,%r14
   0x000055555577a6a8 <+7768>:	je     0x55555577ad80 <read_char+9520>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577a6ae <+7774>:	cmp    $0xfffffffffffffffa,%r14
   0x000055555577a6b2 <+7778>:	je     0x555555778b5c <read_char+780>

747	}
748
749	INLINE void *
750	(XLP) (Lisp_Object o)
751	{
752	  return lisp_h_XLP (o);
753	}
754
755	/* Extract A's type.  */
756
757	INLINE enum Lisp_Type
758	(XTYPE) (Lisp_Object a)
759	{
760	#if USE_LSB_TAG
761	  return lisp_h_XTYPE (a);
762	#else
763	  EMACS_UINT i = XLI (a);
764	  return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
765	#endif
766	}
767
768	/* True if A has type tag TAG.
769	   Equivalent to XTYPE (a) == TAG, but often faster.  */
770
771	INLINE bool
772	(TAGGEDP) (Lisp_Object a, enum Lisp_Type tag)
773	{
774	  return lisp_h_TAGGEDP (a, tag);
   0x000055555577a6b8 <+7784>:	lea    -0x3(%r14),%eax

./src/keyboard.c:
3042	      if (CONSP (c) && EQ (XCAR (c), Qt))
   0x000055555577a6bc <+7788>:	test   $0x7,%al
   0x000055555577a6be <+7790>:	jne    0x55555577a6fa <read_char+7850>

./src/lisp.h:
1184	  return a;
   0x000055555577a6c0 <+7792>:	mov    %r14,%rdi
   0x000055555577a6c3 <+7795>:	call   0x555555763090 <XCAR>
   0x000055555577a6c8 <+7800>:	mov    $0x38,%esi
   0x000055555577a6cd <+7805>:	mov    %rax,%rdi
   0x000055555577a6d0 <+7808>:	call   0x555555764470 <EQ>

./src/keyboard.c:
3043		c = XCDR (c);
   0x000055555577a6d5 <+7813>:	mov    %r14,%rdi

3042	      if (CONSP (c) && EQ (XCAR (c), Qt))
   0x000055555577a6d8 <+7816>:	test   %al,%al
   0x000055555577a6da <+7818>:	jne    0x55555577bf26 <read_char+14038>

./src/lisp.h:
1184	  return a;
   0x000055555577a6e0 <+7824>:	call   0x555555763090 <XCAR>
   0x000055555577a6e5 <+7829>:	mov    $0x10760,%esi
   0x000055555577a6ea <+7834>:	mov    %rax,%rdi
   0x000055555577a6ed <+7837>:	call   0x555555764470 <EQ>

./src/keyboard.c:
3044	      else if (CONSP (c) && EQ (XCAR (c), Qno_record))
   0x000055555577a6f2 <+7842>:	test   %al,%al
   0x000055555577a6f4 <+7844>:	jne    0x55555577b640 <read_char+11760>

3048		}
3049
3050	      c_volatile = c;
   0x000055555577a6fa <+7850>:	mov    %r14,-0x470(%rbp)
   0x000055555577a701 <+7857>:	jmp    0x555555778e60 <read_char+1552>

2337	  unbind_to (count, Qnil);
   0x000055555577a706 <+7862>:	mov    -0x4a0(%rbp),%rdi
   0x000055555577a70d <+7869>:	xor    %esi,%esi
   0x000055555577a70f <+7871>:	mov    -0x508(%rbp),%r15

./src/lisp.h:
1184	  return a;
   0x000055555577a716 <+7878>:	call   0x5555558204b0 <unbind_to>

./src/keyboard.c:
2362	  if (noninteractive && FIXNUMP (c) && XFIXNUM (c) < 0)
   0x000055555577a71b <+7883>:	cmpb   $0x0,0x34b974(%rip)        # 0x555555ac6096 <noninteractive>
   0x000055555577a722 <+7890>:	jne    0x55555577ab20 <read_char+8912>

2363	    Fkill_emacs (make_fixnum (1), Qnil);
2364
2365	  if (FIXNUMP (c))
   0x000055555577a728 <+7896>:	movzbl 0x3a1c51(%rip),%eax        # 0x555555b1c380 <suppress_checking>

2336	  c = kbd_buffer_get_event (&kb, used_mouse_menu, end_time);
   0x000055555577a72f <+7903>:	xor    %r14d,%r14d
   0x000055555577a732 <+7906>:	jmp    0x555555779acc <read_char+4732>

2872	      && !detect_input_pending_run_timers (0))
   0x000055555577a737 <+7911>:	xor    %edi,%edi
   0x000055555577a739 <+7913>:	call   0x5555557786a0 <detect_input_pending_run_timers>
   0x000055555577a73e <+7918>:	test   %al,%al
   0x000055555577a740 <+7920>:	jne    0x555555778ded <read_char+1437>

./src/lisp.h:
1184	  return a;
   0x000055555577a746 <+7926>:	movzbl 0x3a6e3f(%rip),%eax        # 0x555555b2158c <globals+4428>
   0x000055555577a74d <+7933>:	neg    %al
   0x000055555577a74f <+7935>:	sbb    %rdi,%rdi
   0x000055555577a752 <+7938>:	xor    %esi,%esi
   0x000055555577a754 <+7940>:	and    $0x38,%edi
   0x000055555577a757 <+7943>:	call   0x5555557bf870 <Fdo_auto_save>

./src/keyboard.c:
2876	      redisplay ();
   0x000055555577a75c <+7948>:	call   0x55555564ed30 <redisplay>
   0x000055555577a761 <+7953>:	jmp    0x555555778ded <read_char+1437>

4637	    return;
4638
4639	  timer_idleness_start_time = current_timespec ();
   0x000055555577a766 <+7958>:	call   0x555555936cd0 <current_timespec>

./src/lisp.h:
3726	  return calln (fn);
   0x000055555577a76b <+7963>:	lea    -0x3f0(%rbp),%rsi
   0x000055555577a772 <+7970>:	mov    $0x1,%edi
   0x000055555577a777 <+7975>:	movq   $0xd318,-0x3f0(%rbp)

./src/keyboard.c:
4639	  timer_idleness_start_time = current_timespec ();
   0x000055555577a782 <+7986>:	mov    %rax,0x38be27(%rip)        # 0x555555b065b0 <timer_idleness_start_time>
   0x000055555577a789 <+7993>:	mov    %rdx,0x38be28(%rip)        # 0x555555b065b8 <timer_idleness_start_time+8>

4640	  timer_last_idleness_start_time = timer_idleness_start_time;
   0x000055555577a790 <+8000>:	mov    %rax,0x38be09(%rip)        # 0x555555b065a0 <timer_last_idleness_start_time>
   0x000055555577a797 <+8007>:	mov    %rdx,0x38be0a(%rip)        # 0x555555b065a8 <timer_last_idleness_start_time+8>

./src/lisp.h:
3726	  return calln (fn);
   0x000055555577a79e <+8014>:	call   0x555555820950 <Ffuncall>

./src/keyboard.c:
2829	  if (minibuf_level == 0
   0x000055555577a7a3 <+8019>:	cmpq   $0x0,0x39fe05(%rip)        # 0x555555b1a5b0 <minibuf_level>
   0x000055555577a7ab <+8027>:	je     0x55555577a204 <read_char+6580>
   0x000055555577a7b1 <+8033>:	jmp    0x555555778db4 <read_char+1380>

3308	    {
3309	      record_char (c);
   0x000055555577a7b6 <+8038>:	mov    %r14,%rdi
   0x000055555577a7b9 <+8041>:	call   0x555555773260 <record_char>

3310	      recorded = true;
   0x000055555577a7be <+8046>:	movb   $0x1,-0x486(%rbp)
   0x000055555577a7c5 <+8053>:	jmp    0x5555557789ec <read_char+412>

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577a7ca <+8058>:	sar    $0x2,%r14

./src/keyboard.c:
2376	      XSETINT (c, XFIXNUM (c) | (extra_keyboard_modifiers & ~0xff7f & ~CHAR_CTL));
   0x000055555577a7ce <+8062>:	and    $0xfffffffffbff0080,%rax
   0x000055555577a7d4 <+8068>:	mov    0x334d4d(%rip),%rdx        # 0x555555aaf528 <selected_frame>
   0x000055555577a7db <+8075>:	or     %r14,%rax

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577a7de <+8078>:	lea    0x2(,%rax,4),%r14

./src/keyboard.c:
2409	      struct frame *frame = XFRAME (selected_frame);
   0x000055555577a7e6 <+8086>:	lea    -0x5(%rdx),%rax
   0x000055555577a7ea <+8090>:	mov    $0x1,%ecx
   0x000055555577a7ef <+8095>:	jmp    0x555555779b10 <read_char+4800>
   0x000055555577a7f4 <+8100>:	test   %dl,%dl
   0x000055555577a7f6 <+8102>:	jne    0x55555577a830 <read_char+8160>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577a7f8 <+8104>:	lea    -0x3(%rax),%edx

1384	}
1385
1386	#define XSETINT(a, b) ((a) = make_fixnum (b))
1387	#define XSETFASTINT(a, b) ((a) = make_fixed_natnum (b))
1388	#define XSETCONS(a, b) ((a) = make_lisp_ptr (b, Lisp_Cons))
1389	#define XSETVECTOR(a, b) ((a) = make_lisp_ptr (b, Lisp_Vectorlike))
1390	#define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String))
1391	#define XSETSYMBOL(a, b) ((a) = make_lisp_symbol (b))
1392	#define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float))
1393
1394	/* Return a Lisp_Object value that does not correspond to any object.
1395	   This can make some Lisp objects on free lists recognizable in O(1).  */
1396
1397	INLINE Lisp_Object
1398	dead_object (void)
1399	{
1400	  return make_lisp_ptr (NULL, Lisp_String);
1401	}
1402
1403	/* Pseudovector types.  */
1404
1405	#define XSETPVECTYPE(v, code)						\
1406	  ((v)->header.size |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS))
1407	#define PVECHEADERSIZE(code, lispsize, restsize) \
1408	  (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS) \
1409	   | ((restsize) << PSEUDOVECTOR_SIZE_BITS) | (lispsize))
1410	#define XSETPVECTYPESIZE(v, code, lispsize, restsize)		\
1411	  ((v)->header.size = PVECHEADERSIZE (code, lispsize, restsize))
1412
1413	/* The cast to struct vectorlike_header * avoids aliasing issues.  */
1414	#define XSETPSEUDOVECTOR(a, b, code) \
1415	  XSETTYPED_PSEUDOVECTOR (a, b,					\
1416				  (XUNTAG (a, Lisp_Vectorlike,		\
1417					   struct vectorlike_header)	\
1418				   ->size),				\
1419				  code)
1420	#define XSETTYPED_PSEUDOVECTOR(a, b, size, code)			\
1421	  (XSETVECTOR (a, b),							\
1422	   eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))		\
1423		    == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS))))
1424
1425	#define XSETWINDOW_CONFIGURATION(a, b) \
1426	  XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION)
1427	#define XSETPROCESS(a, b) XSETPSEUDOVECTOR (a, b, PVEC_PROCESS)
1428	#define XSETWINDOW(a, b) XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)
1429	#define XSETTERMINAL(a, b) XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)
1430	#define XSETSUBR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_SUBR)
1431	#define XSETBUFFER(a, b) XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)
1432	#define XSETCHAR_TABLE(a, b) XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)
1433	#define XSETBOOL_VECTOR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR)
1434	#define XSETSUB_CHAR_TABLE(a, b) XSETPSEUDOVECTOR (a, b, PVEC_SUB_CHAR_TABLE)
1435	#define XSETTHREAD(a, b) XSETPSEUDOVECTOR (a, b, PVEC_THREAD)
1436	#define XSETMUTEX(a, b) XSETPSEUDOVECTOR (a, b, PVEC_MUTEX)
1437	#define XSETCONDVAR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_CONDVAR)
1438	#define XSETNATIVE_COMP_UNIT(a, b) XSETPSEUDOVECTOR (a, b, PVEC_NATIVE_COMP_UNIT)
1439
1440	/* Efficiently convert a pointer to a Lisp object and back.  The
1441	   pointer is represented as a fixnum, so the garbage collector
1442	   does not know about it.  The pointer should not have both Lisp_Int1
1443	   bits set, which makes this conversion inherently unportable.  */
1444
1445	INLINE void *
1446	XFIXNUMPTR (Lisp_Object a)
1447	{
1448	  return XUNTAG (a, Lisp_Int0, char);
1449	}
1450
1451	INLINE Lisp_Object
1452	make_pointer_integer_unsafe (void *p)
1453	{
1454	  Lisp_Object a = TAG_PTR_INITIALLY (Lisp_Int0, p);
1455	  return a;
1456	}
1457
1458	INLINE Lisp_Object
1459	make_pointer_integer (void *p)
1460	{
1461	  Lisp_Object a = make_pointer_integer_unsafe (p);
1462	  eassert (FIXNUMP (a) && XFIXNUMPTR (a) == p);
1463	  return a;
1464	}
1465
1466	/* See the macros in intervals.h.  */
1467
1468	typedef struct interval *INTERVAL;
1469
1470	struct Lisp_Cons
1471	{
1472	  GC_HEADER
1473	  union
1474	  {
1475	    struct
1476	    {
1477	      /* Car of this cons cell.  */
1478	      Lisp_Object car;
1479
1480	      union
1481	      {
1482		/* Cdr of this cons cell.  */
1483		Lisp_Object cdr;
1484
1485		/* Used to chain conses on a free list.  */
1486		struct Lisp_Cons *chain;
1487	      } u;
1488	    } s;
1489	    GCALIGNED_UNION_MEMBER
1490	  } u;
1491	};
1492	static_assert (GCALIGNED (struct Lisp_Cons));
1493
1494	INLINE bool
1495	(NILP) (Lisp_Object x)
1496	{
1497	  return lisp_h_NILP (x);
1498	}
1499
1500	INLINE bool
1501	(CONSP) (Lisp_Object x)
1502	{
1503	  return lisp_h_CONSP (x);
1504	}
1505
1506	INLINE void
1507	CHECK_CONS (Lisp_Object x)
1508	{
1509	  CHECK_TYPE (CONSP (x), Qconsp, x);
1510	}
1511
1512	INLINE struct Lisp_Cons *
1513	XCONS (Lisp_Object a)
1514	{
1515	  eassert (CONSP (a));
   0x000055555577a7fb <+8107>:	and    $0x7,%edx
   0x000055555577a7fe <+8110>:	jne    0x5555555b2844 <read_char-1859596>

1516	  struct Lisp_Cons *c = XUNTAG (a, Lisp_Cons, struct Lisp_Cons);
   0x000055555577a804 <+8116>:	mov    0xd(%rax),%rdx
   0x000055555577a808 <+8120>:	lea    -0x3(%rax),%rbx

740	  return lisp_h_XLI (o);
   0x000055555577a80c <+8124>:	lea    -0x3(%rdx),%ecx

./src/keyboard.c:
2796			while (CONSP (XCDR (last)))
   0x000055555577a80f <+8127>:	and    $0x7,%ecx
   0x000055555577a812 <+8130>:	jne    0x55555577bbd0 <read_char+13184>
   0x000055555577a818 <+8136>:	mov    %rdx,%rax

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577a81b <+8139>:	lea    -0x3(%rax),%edx

1384	}
1385
1386	#define XSETINT(a, b) ((a) = make_fixnum (b))
1387	#define XSETFASTINT(a, b) ((a) = make_fixed_natnum (b))
1388	#define XSETCONS(a, b) ((a) = make_lisp_ptr (b, Lisp_Cons))
1389	#define XSETVECTOR(a, b) ((a) = make_lisp_ptr (b, Lisp_Vectorlike))
1390	#define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String))
1391	#define XSETSYMBOL(a, b) ((a) = make_lisp_symbol (b))
1392	#define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float))
1393
1394	/* Return a Lisp_Object value that does not correspond to any object.
1395	   This can make some Lisp objects on free lists recognizable in O(1).  */
1396
1397	INLINE Lisp_Object
1398	dead_object (void)
1399	{
1400	  return make_lisp_ptr (NULL, Lisp_String);
1401	}
1402
1403	/* Pseudovector types.  */
1404
1405	#define XSETPVECTYPE(v, code)						\
1406	  ((v)->header.size |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS))
1407	#define PVECHEADERSIZE(code, lispsize, restsize) \
1408	  (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS) \
1409	   | ((restsize) << PSEUDOVECTOR_SIZE_BITS) | (lispsize))
1410	#define XSETPVECTYPESIZE(v, code, lispsize, restsize)		\
1411	  ((v)->header.size = PVECHEADERSIZE (code, lispsize, restsize))
1412
1413	/* The cast to struct vectorlike_header * avoids aliasing issues.  */
1414	#define XSETPSEUDOVECTOR(a, b, code) \
1415	  XSETTYPED_PSEUDOVECTOR (a, b,					\
1416				  (XUNTAG (a, Lisp_Vectorlike,		\
1417					   struct vectorlike_header)	\
1418				   ->size),				\
1419				  code)
1420	#define XSETTYPED_PSEUDOVECTOR(a, b, size, code)			\
1421	  (XSETVECTOR (a, b),							\
1422	   eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))		\
1423		    == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS))))
1424
1425	#define XSETWINDOW_CONFIGURATION(a, b) \
1426	  XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION)
1427	#define XSETPROCESS(a, b) XSETPSEUDOVECTOR (a, b, PVEC_PROCESS)
1428	#define XSETWINDOW(a, b) XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)
1429	#define XSETTERMINAL(a, b) XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)
1430	#define XSETSUBR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_SUBR)
1431	#define XSETBUFFER(a, b) XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)
1432	#define XSETCHAR_TABLE(a, b) XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)
1433	#define XSETBOOL_VECTOR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR)
1434	#define XSETSUB_CHAR_TABLE(a, b) XSETPSEUDOVECTOR (a, b, PVEC_SUB_CHAR_TABLE)
1435	#define XSETTHREAD(a, b) XSETPSEUDOVECTOR (a, b, PVEC_THREAD)
1436	#define XSETMUTEX(a, b) XSETPSEUDOVECTOR (a, b, PVEC_MUTEX)
1437	#define XSETCONDVAR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_CONDVAR)
1438	#define XSETNATIVE_COMP_UNIT(a, b) XSETPSEUDOVECTOR (a, b, PVEC_NATIVE_COMP_UNIT)
1439
1440	/* Efficiently convert a pointer to a Lisp object and back.  The
1441	   pointer is represented as a fixnum, so the garbage collector
1442	   does not know about it.  The pointer should not have both Lisp_Int1
1443	   bits set, which makes this conversion inherently unportable.  */
1444
1445	INLINE void *
1446	XFIXNUMPTR (Lisp_Object a)
1447	{
1448	  return XUNTAG (a, Lisp_Int0, char);
1449	}
1450
1451	INLINE Lisp_Object
1452	make_pointer_integer_unsafe (void *p)
1453	{
1454	  Lisp_Object a = TAG_PTR_INITIALLY (Lisp_Int0, p);
1455	  return a;
1456	}
1457
1458	INLINE Lisp_Object
1459	make_pointer_integer (void *p)
1460	{
1461	  Lisp_Object a = make_pointer_integer_unsafe (p);
1462	  eassert (FIXNUMP (a) && XFIXNUMPTR (a) == p);
1463	  return a;
1464	}
1465
1466	/* See the macros in intervals.h.  */
1467
1468	typedef struct interval *INTERVAL;
1469
1470	struct Lisp_Cons
1471	{
1472	  GC_HEADER
1473	  union
1474	  {
1475	    struct
1476	    {
1477	      /* Car of this cons cell.  */
1478	      Lisp_Object car;
1479
1480	      union
1481	      {
1482		/* Cdr of this cons cell.  */
1483		Lisp_Object cdr;
1484
1485		/* Used to chain conses on a free list.  */
1486		struct Lisp_Cons *chain;
1487	      } u;
1488	    } s;
1489	    GCALIGNED_UNION_MEMBER
1490	  } u;
1491	};
1492	static_assert (GCALIGNED (struct Lisp_Cons));
1493
1494	INLINE bool
1495	(NILP) (Lisp_Object x)
1496	{
1497	  return lisp_h_NILP (x);
1498	}
1499
1500	INLINE bool
1501	(CONSP) (Lisp_Object x)
1502	{
1503	  return lisp_h_CONSP (x);
1504	}
1505
1506	INLINE void
1507	CHECK_CONS (Lisp_Object x)
1508	{
1509	  CHECK_TYPE (CONSP (x), Qconsp, x);
1510	}
1511
1512	INLINE struct Lisp_Cons *
1513	XCONS (Lisp_Object a)
1514	{
1515	  eassert (CONSP (a));
   0x000055555577a81e <+8142>:	and    $0x7,%edx
   0x000055555577a821 <+8145>:	je     0x55555577a804 <read_char+8116>
   0x000055555577a823 <+8147>:	jmp    0x5555555b2844 <read_char-1859596>
   0x000055555577a828 <+8152>:	nopl   0x0(%rax,%rax,1)

1516	  struct Lisp_Cons *c = XUNTAG (a, Lisp_Cons, struct Lisp_Cons);
   0x000055555577a830 <+8160>:	lea    -0x3(%rax),%rbx

1517	  igc_check_fwd (c, false);
1518	  return c;
   0x000055555577a834 <+8164>:	mov    %rax,%r13

1545	}
1546
1547	INLINE Lisp_Object
1548	(XCDR) (Lisp_Object c)
1549	{
1550	  return lisp_h_XCDR (c);
   0x000055555577a837 <+8167>:	mov    0x10(%rbx),%rax

740	  return lisp_h_XLI (o);
   0x000055555577a83b <+8171>:	lea    -0x3(%rax),%edx

./src/keyboard.c:
2796			while (CONSP (XCDR (last)))
   0x000055555577a83e <+8174>:	and    $0x7,%edx
   0x000055555577a841 <+8177>:	je     0x55555577a830 <read_char+8160>

2797			  last = XCDR (last);
2798			if (!NILP (XCDR (last)))
   0x000055555577a843 <+8179>:	mov    %r13,%rdi
   0x000055555577a846 <+8182>:	call   0x5555557630d0 <XCDR>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577a84b <+8187>:	test   %rax,%rax
   0x000055555577a84e <+8190>:	jne    0x5555555b2835 <read_char-1859611>
   0x000055555577a854 <+8196>:	sub    $0x3,%r13d

./src/keyboard.c:
2801		    if (!CONSP (last))
   0x000055555577a858 <+8200>:	and    $0x7,%r13d
   0x000055555577a85c <+8204>:	jne    0x555555779274 <read_char+2596>

2803		    else
2804		      XSETCDR (last, list1 (c));
   0x000055555577a862 <+8210>:	mov    %r14,%rdi
   0x000055555577a865 <+8213>:	call   0x5555557ef5c0 <list1>

./src/lisp.h:
1565	  *xcdr_addr (c) = n;
   0x000055555577a86a <+8218>:	mov    %rax,0x10(%rbx)
   0x000055555577a86e <+8222>:	jmp    0x555555779281 <read_char+2609>

1184	  return a;
   0x000055555577a873 <+8227>:	mov    %r14,%rdi
   0x000055555577a876 <+8230>:	call   0x555555763090 <XCAR>
   0x000055555577a87b <+8235>:	mov    $0x38,%esi
   0x000055555577a880 <+8240>:	mov    %rax,%rdi
   0x000055555577a883 <+8243>:	call   0x555555764470 <EQ>

./src/keyboard.c:
2970		c = XCDR (c);
   0x000055555577a888 <+8248>:	mov    %r14,%rdi

2969	      if (CONSP (c) && EQ (XCAR (c), Qt))
   0x000055555577a88b <+8251>:	test   %al,%al
   0x000055555577a88d <+8253>:	jne    0x55555577b0d8 <read_char+10376>

./src/lisp.h:
1184	  return a;
   0x000055555577a893 <+8259>:	call   0x555555763090 <XCAR>
   0x000055555577a898 <+8264>:	mov    $0x10760,%esi
   0x000055555577a89d <+8269>:	mov    %rax,%rdi
   0x000055555577a8a0 <+8272>:	call   0x555555764470 <EQ>

./src/keyboard.c:
2973		  if (CONSP (c) && EQ (XCAR (c), Qno_record))
   0x000055555577a8a5 <+8277>:	test   %al,%al
   0x000055555577a8a7 <+8279>:	jne    0x55555577ba44 <read_char+12788>

2977		    }
2978		  reread = true;
   0x000055555577a8ad <+8285>:	movb   $0x1,-0x487(%rbp)

2979		}
2980
2981	      c_volatile = c;
   0x000055555577a8b4 <+8292>:	mov    %r14,-0x470(%rbp)

2982	    }
2983
2984	  /* Read something from current KBOARD's side queue, if possible.  */
2985
2986	  if (NILP (c))
   0x000055555577a8bb <+8299>:	jmp    0x555555778e33 <read_char+1507>

./src/lisp.h:
3986	  return wrap_specpdl_ref ((char *)specpdl_ptr - (char *)specpdl);
   0x000055555577a8c0 <+8304>:	mov    0x30d099(%rip),%rax        # 0x555555a87960 <current_thread>

3912	  return (specpdl_ref){.bytes = bytes};
   0x000055555577a8c7 <+8311>:	xor    %edi,%edi

1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577a8c9 <+8313>:	movabs $0x400000000d000000,%r13

3913	#else
3914	  return bytes;
3915	#endif
3916	}
3917
3918	/* Internal use only.  */
3919	INLINE ptrdiff_t
3920	unwrap_specpdl_ref (specpdl_ref ref)
3921	{
3922	#ifdef WRAP_SPECPDL_REF
3923	  return ref.bytes;
3924	#else
3925	  return ref;
3926	#endif
3927	}
3928
3929	INLINE specpdl_ref
3930	specpdl_count_to_ref (ptrdiff_t count)
3931	{
3932	  return wrap_specpdl_ref (count * sizeof (union specbinding));
3933	}
3934
3935	INLINE ptrdiff_t
3936	specpdl_ref_to_count (specpdl_ref ref)
3937	{
3938	  return unwrap_specpdl_ref (ref) / sizeof (union specbinding);
3939	}
3940
3941	/* Whether two `specpdl_ref' refer to the same entry.  */
3942	INLINE bool
3943	specpdl_ref_eq (specpdl_ref a, specpdl_ref b)
3944	{
3945	  return unwrap_specpdl_ref (a) == unwrap_specpdl_ref (b);
3946	}
3947
3948	/* Whether `a' refers to an earlier entry than `b'.  */
3949	INLINE bool
3950	specpdl_ref_lt (specpdl_ref a, specpdl_ref b)
3951	{
3952	  return unwrap_specpdl_ref (a) < unwrap_specpdl_ref (b);
3953	}
3954
3955	INLINE bool
3956	specpdl_ref_valid_p (specpdl_ref ref)
3957	{
3958	  return unwrap_specpdl_ref (ref) >= 0;
3959	}
3960
3961	INLINE specpdl_ref
3962	make_invalid_specpdl_ref (void)
3963	{
3964	  return wrap_specpdl_ref (-1);
3965	}
3966
3967	/* Return a reference that is `delta' steps more recent than `ref'.
3968	   `delta' may be negative or zero.  */
3969	INLINE specpdl_ref
3970	specpdl_ref_add (specpdl_ref ref, ptrdiff_t delta)
3971	{
3972	  return wrap_specpdl_ref (unwrap_specpdl_ref (ref)
3973				   + delta * sizeof (union specbinding));
3974	}
3975
3976	INLINE union specbinding *
3977	specpdl_ref_to_ptr (specpdl_ref ref)
3978	{
3979	  return (union specbinding *)((char *)specpdl + unwrap_specpdl_ref (ref));
3980	}
3981
3982	/* Return a reference to the most recent specpdl entry.  */
3983	INLINE specpdl_ref
3984	SPECPDL_INDEX (void)
3985	{
3986	  return wrap_specpdl_ref ((char *)specpdl_ptr - (char *)specpdl);
   0x000055555577a8d3 <+8323>:	mov    0x88(%rax),%r12
   0x000055555577a8da <+8330>:	sub    0x78(%rax),%r12

1184	  return a;
   0x000055555577a8de <+8334>:	call   0x55555567ebb0 <Fcurrent_window_configuration>
   0x000055555577a8e3 <+8339>:	mov    0x38ba5e(%rip),%rsi        # 0x555555b06348 <help_form_saved_window_configs>
   0x000055555577a8ea <+8346>:	mov    %rax,%rdi
   0x000055555577a8ed <+8349>:	call   0x5555557ef2b0 <Fcons>

./src/keyboard.c:
3368	      record_unwind_protect_void (read_char_help_form_unwind);
   0x000055555577a8f2 <+8354>:	lea    -0x16f19(%rip),%rdi        # 0x5555557639e0 <read_char_help_form_unwind>

3366		= Fcons (Fcurrent_window_configuration (Qnil),
   0x000055555577a8f9 <+8361>:	mov    %rax,0x38ba48(%rip)        # 0x555555b06348 <help_form_saved_window_configs>

3367			 help_form_saved_window_configs);
3368	      record_unwind_protect_void (read_char_help_form_unwind);
   0x000055555577a900 <+8368>:	call   0x555555820340 <record_unwind_protect_void>

./src/lisp.h:
3726	  return calln (fn);
   0x000055555577a905 <+8373>:	lea    -0x3f8(%rbp),%rsi
   0x000055555577a90c <+8380>:	mov    $0x1,%edi
   0x000055555577a911 <+8385>:	movq   $0xc278,-0x3f8(%rbp)
   0x000055555577a91c <+8396>:	call   0x555555820950 <Ffuncall>

./src/keyboard.c:
672	  current_kboard->immediate_echo = false;
   0x000055555577a921 <+8401>:	mov    0x38b938(%rip),%rax        # 0x555555b06260 <current_kboard>

673	  kset_echo_prompt (current_kboard, Qnil);
674	  kset_echo_string (current_kboard, Qnil);
675	  ok_to_echo_at_next_pause = NULL;
   0x000055555577a928 <+8408>:	movq   $0x0,0x38bcbd(%rip)        # 0x555555b065f0 <ok_to_echo_at_next_pause>

676	  echo_kboard = NULL;
   0x000055555577a933 <+8419>:	movq   $0x0,0x38b82a(%rip)        # 0x555555b06168 <echo_kboard>

672	  current_kboard->immediate_echo = false;
   0x000055555577a93e <+8430>:	andb   $0xfe,0xb9(%rax)

450	  kb->echo_prompt_ = val;
   0x000055555577a945 <+8437>:	movq   $0x0,0xc0(%rax)

445	  kb->echo_string_ = val;
   0x000055555577a950 <+8448>:	movq   $0x0,0xb0(%rax)

677	  echo_message_buffer = Qnil;
   0x000055555577a95b <+8459>:	movq   $0x0,0x38b7fa(%rip)        # 0x555555b06160 <echo_message_buffer>
   0x000055555577a966 <+8470>:	cs nopw 0x0(%rax,%rax,1)

./src/lisp.h:
1184	  return a;
   0x000055555577a970 <+8480>:	xor    %r8d,%r8d
   0x000055555577a973 <+8483>:	xor    %ecx,%ecx
   0x000055555577a975 <+8485>:	xor    %edx,%edx
   0x000055555577a977 <+8487>:	xor    %esi,%esi
   0x000055555577a979 <+8489>:	xor    %edi,%edi
   0x000055555577a97b <+8491>:	call   0x555555778850 <read_char>

./src/keyboard.c:
3375		  c_volatile = c;
   0x000055555577a980 <+8496>:	mov    %rax,-0x470(%rbp)

3374		  c = read_char (0, Qnil, Qnil, 0, NULL);
   0x000055555577a987 <+8503>:	mov    %rax,%r14

3376		  if (EVENT_HAS_PARAMETERS (c)
   0x000055555577a98a <+8506>:	mov    %rax,%rbx

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577a98d <+8509>:	mov    %eax,%r15d

747	}
748
749	INLINE void *
750	(XLP) (Lisp_Object o)
751	{
752	  return lisp_h_XLP (o);
753	}
754
755	/* Extract A's type.  */
756
757	INLINE enum Lisp_Type
758	(XTYPE) (Lisp_Object a)
759	{
760	#if USE_LSB_TAG
761	  return lisp_h_XTYPE (a);
762	#else
763	  EMACS_UINT i = XLI (a);
764	  return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
765	#endif
766	}
767
768	/* True if A has type tag TAG.
769	   Equivalent to XTYPE (a) == TAG, but often faster.  */
770
771	INLINE bool
772	(TAGGEDP) (Lisp_Object a, enum Lisp_Type tag)
773	{
774	  return lisp_h_TAGGEDP (a, tag);
   0x000055555577a990 <+8512>:	lea    -0x3(%rax),%eax

./src/keyboard.c:
3376		  if (EVENT_HAS_PARAMETERS (c)
   0x000055555577a993 <+8515>:	test   $0x7,%al
   0x000055555577a995 <+8517>:	je     0x55555577aa68 <read_char+8728>

./src/lisp.h:
774	  return lisp_h_TAGGEDP (a, tag);
   0x000055555577a99b <+8523>:	lea    -0x5(%r15),%eax

775	}
776
777	INLINE void
778	(CHECK_TYPE) (int ok, Lisp_Object predicate, Lisp_Object x)
779	{
780	  lisp_h_CHECK_TYPE (ok, predicate, x);
781	}
782
783	/* Extract A's pointer value, assuming A's Lisp type is TYPE and the
784	   extracted pointer's type is CTYPE *.  When !USE_LSB_TAG this simply
785	   extracts A's low-order bits, as (uintptr_t) LISP_WORD_TAG (type) is
786	   always zero then.  */
787	#define XUNTAG(a, type, ctype) \
788	  ((ctype *) ((uintptr_t) XLP (a) - (uintptr_t) LISP_WORD_TAG (type)))
789
790	/* A forwarding pointer to a value.  It uses a generic pointer to
791	   avoid alignment bugs that could occur if it used a pointer to a
792	   union of the possible values (struct Lisp_Objfwd, struct
793	   Lisp_Intfwd, etc.).  The pointer is packaged inside a struct to
794	   help static checking.  */
795	typedef const struct Lisp_Fwd *lispfwd;
796	^L
797	/* Interned state of a symbol.  */
798
799	enum symbol_interned
800	{
801	  SYMBOL_UNINTERNED,		      /* not interned anywhere */
802	  SYMBOL_INTERNED,		      /* interned but not in initial obarray */
803	  SYMBOL_INTERNED_IN_INITIAL_OBARRAY  /* interned in initial obarray */
804	};
805
806	enum symbol_redirect
807	{
808	  SYMBOL_PLAINVAL,   /* plain var, value is in the `value' field */
809	  SYMBOL_VARALIAS,   /* var alias, value is really in the `alias' symbol */
810	  SYMBOL_LOCALIZED,  /* localized var, value is in the `blv' object */
811	  SYMBOL_FORWARDED   /* forwarding var, value is in `forward' */
812	};
813
814	enum symbol_trapped_write
815	{
816	  SYMBOL_UNTRAPPED_WRITE,  /* normal case, just set the value */
817	  SYMBOL_NOWRITE,          /* constant, cannot set, e.g. nil, t, :keyword */
818	  SYMBOL_TRAPPED_WRITE     /* trap the write, call watcher functions */
819	};
820
821	struct Lisp_Symbol
822	{
823	  GC_HEADER
824	  union
825	  {
826	    struct
827	    {
828	      bool_bf gcmarkbit : 1;
829
830	      /* Indicates where the value can be found.  */
831	      ENUM_BF (symbol_redirect) redirect : 2;
832
833	      ENUM_BF (symbol_trapped_write) trapped_write : 2;
834
835	      /* Interned state of the symbol.  */
836	      ENUM_BF (symbol_interned) interned : 2;
837
838	      /* True means that this variable has been explicitly declared
839		 special (with `defvar' etc), and shouldn't be lexically bound.  */
840	      bool_bf declared_special : 1;
841
842	      /* The symbol's name, as a Lisp string.  */
843	      Lisp_Object name;
844
845	      /* Value of the symbol or Qunbound if unbound.  Which alternative of the
846		 union is used depends on the `redirect' field above.  */
847	      union {
848		Lisp_Object value;
849		struct Lisp_Symbol *alias;
850		struct Lisp_Buffer_Local_Value *blv;
851		lispfwd fwd;
852	      } val;
853
854	      /* Function value of the symbol or Qnil if not fboundp.  */
855	      Lisp_Object function;
856
857	      /* The symbol's property list.  */
858	      Lisp_Object plist;
859
860	      /* Next symbol in obarray bucket, if the symbol is interned.  */
861	      struct Lisp_Symbol *next;
862	    } s;
863	    GCALIGNED_UNION_MEMBER
864	  } u;
865	};
866	static_assert (GCALIGNED (struct Lisp_Symbol));
867
868	/* Declare a Lisp-callable function.  The MAXARGS parameter has the same
869	   meaning as in the DEFUN macro, and is used to construct a prototype.  */
870	/* We can use the same trick as in the DEFUN macro to generate the
871	   appropriate prototype.  */
872	#define EXFUN(fnname, maxargs) \
873	  extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs
874
875	/* Note that the weird token-substitution semantics of ANSI C makes
876	   this work for MANY and UNEVALLED.  */
877	#define DEFUN_ARGS_MANY		(ptrdiff_t, Lisp_Object *)
878	#define DEFUN_ARGS_UNEVALLED	(Lisp_Object)
879	#define DEFUN_ARGS_0	(void)
880	#define DEFUN_ARGS_1	(Lisp_Object)
881	#define DEFUN_ARGS_2	(Lisp_Object, Lisp_Object)
882	#define DEFUN_ARGS_3	(Lisp_Object, Lisp_Object, Lisp_Object)
883	#define DEFUN_ARGS_4	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
884	#define DEFUN_ARGS_5	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
885				 Lisp_Object)
886	#define DEFUN_ARGS_6	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
887				 Lisp_Object, Lisp_Object)
888	#define DEFUN_ARGS_7	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
889				 Lisp_Object, Lisp_Object, Lisp_Object)
890	#define DEFUN_ARGS_8	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
891				 Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
892
893	/* Lisp_Word_tag is big enough for a possibly-shifted tag, to be
894	   added to a pointer value for conversion to a Lisp_Word.  */
895	#if LISP_WORDS_ARE_POINTERS
896	typedef uintptr_t Lisp_Word_tag;
897	#else
898	typedef EMACS_UINT Lisp_Word_tag;
899	#endif
900
901	/* A integer value tagged with TAG, and otherwise all zero.  */
902	#define LISP_WORD_TAG(tag) \
903	  ((Lisp_Word_tag) (tag) << (USE_LSB_TAG ? 0 : VALBITS))
904
905	/* An initializer for a Lisp_Object that contains TAG along with P.
906	   P can be a pointer or an integer.  The result is usable in a static
907	   initializer if TAG and P are both integer constant expressions.  */
908	#define TAG_PTR_INITIALLY(tag, p) \
909	  LISP_INITIALLY ((Lisp_Word) ((uintptr_t) (p) + LISP_WORD_TAG (tag)))
910
911	/* LISPSYM_INITIALLY (Qfoo) is equivalent to Qfoo except it is
912	   designed for use as a (possibly static) initializer.  */
913	#define LISPSYM_INITIALLY(name) \
914	  TAG_PTR_INITIALLY (Lisp_Symbol, (intptr_t) ((i##name) * sizeof *lispsym))
915
916	/* Declare extern constants for Lisp symbols.  These can be helpful
917	   when using a debugger like GDB, on older platforms where the debug
918	   format does not represent C macros.  However, they are unbounded
919	   and would just be asking for trouble if checking pointer bounds.  */
920	#define DEFINE_LISP_SYMBOL(name) \
921	  DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) \
922	  DEFINE_GDB_SYMBOL_END (LISPSYM_INITIALLY (name))
923
924	/* The index of the C-defined Lisp symbol SYM.
925	   This can be used in a static initializer.  */
926	#define SYMBOL_INDEX(sym) i##sym
927
928	/* By default, define macros for Qt, etc., as this leads to a bit
929	   better performance in the core Emacs interpreter.  A plugin can
930	   define DEFINE_NON_NIL_Q_SYMBOL_MACROS to be false, to be portable to
931	   other Emacs instances that assign different values to Qt, etc.  */
932	#ifndef DEFINE_NON_NIL_Q_SYMBOL_MACROS
933	# define DEFINE_NON_NIL_Q_SYMBOL_MACROS true
934	#endif
935
936	/* True if N is a power of 2.  N should be positive.  */
937
938	#define POWER_OF_2(n) (((n) & ((n) - 1)) == 0)
939
940	/* Return X rounded to the next multiple of Y.  Y should be positive,
941	   and Y - 1 + X should not overflow.  Arguments should not have side
942	   effects, as they are evaluated more than once.  Tune for Y being a
943	   power of 2.  */
944
945	#define ROUNDUP(x, y) (POWER_OF_2 (y)					\
946	                       ? ((y) - 1 + (x)) & ~ ((y) - 1)			\
947	                       : ((y) - 1 + (x)) - ((y) - 1 + (x)) % (y))
948
949	#include <globals.h>
950
951	/* Header of vector-like objects.  This documents the layout constraints on
952	   vectors and pseudovectors (objects of PVEC_xxx subtype).  It also prevents
953	   compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR
954	   and PSEUDOVECTORP cast their pointers to struct vectorlike_header *,
955	   because when two such pointers potentially alias, a compiler won't
956	   incorrectly reorder loads and stores to their size fields.  See
957	   Bug#8546.   */
958	struct vectorlike_header
959	  {
960	    /* The `size' header word, W bits wide, has one of two forms
961	       discriminated by the second-highest bit (PSEUDOVECTOR_FLAG):
962
963	         1   1                    W-2
964	       +---+---+-------------------------------------+
965	       | M | 0 |                 SIZE                |  vector
966	       +---+---+-------------------------------------+
967
968	         1   1    W-32      6       12         12
969	       +---+---+--------+------+----------+----------+
970	       | M | 1 | unused | TYPE | RESTSIZE | LISPSIZE |  pseudovector
971	       +---+---+--------+------+----------+----------+
972
973	       M (ARRAY_MARK_FLAG) holds the GC mark bit.
974
975	       SIZE     is the length (number of slots) of a regular Lisp vector,
976	                and the object layout is struct Lisp_Vector.
977
978	       TYPE     is the pseudovector subtype (enum pvec_type).
979
980	       LISPSIZE is the number of Lisp_Object fields at the beginning of the
981	                object (after the header).  These are always traced by the GC.
982
983	       RESTSIZE is the number of fields (in word_size units) following.
984	                These are not automatically traced by the GC.
985	                For PVEC_BOOL and statically allocated PVEC_SUBR, RESTSIZE is 0.
986	                (The block size for PVEC_BOOL is computed from its own size
987	                field, to avoid being restricted by the 12-bit RESTSIZE field.)
988	    */
989	    GC_HEADER
990	    ptrdiff_t size;
991	  };
992
993	struct Lisp_Symbol_With_Pos
994	{
995	  struct vectorlike_header header;
996	  Lisp_Object sym;              /* A symbol */
997	  Lisp_Object pos;              /* A fixnum */
998	} GCALIGNED_STRUCT;
999
1000	/* In the size word of a vector, this bit means the vector has been marked.  */
1001
1002	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG)
1003	# define ARRAY_MARK_FLAG PTRDIFF_MIN
1004	DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG)
1005
1006	/* In the size word of a struct Lisp_Vector, this bit means it's really
1007	   some other vector-like object.  */
1008	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG)
1009	# define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2)
1010	DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
1011
1012	/* In a pseudovector, the size field actually contains a word with one
1013	   PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
1014	   with PVEC_TYPE_MASK to indicate the actual type.  */
1015	enum pvec_type
1016	{
1017	  PVEC_NORMAL_VECTOR,	/* Should be first, for sxhash_obj.  */
1018	  PVEC_FREE,
1019	  PVEC_BIGNUM,
1020	  PVEC_MARKER,
1021	  PVEC_OVERLAY,
1022	  PVEC_FINALIZER,
1023	  PVEC_SYMBOL_WITH_POS,
1024	  PVEC_MISC_PTR,
1025	  PVEC_USER_PTR,
1026	  PVEC_PROCESS,
1027	  PVEC_FRAME,
1028	  PVEC_WINDOW,
1029	  PVEC_BOOL_VECTOR,
1030	  PVEC_BUFFER,
1031	  PVEC_HASH_TABLE,
1032	#ifdef HAVE_MPS
1033	  PVEC_WEAK_HASH_TABLE,
1034	#endif
1035	  PVEC_OBARRAY,
1036	  PVEC_TERMINAL,
1037	  PVEC_WINDOW_CONFIGURATION,
1038	  PVEC_SUBR,
1039	  PVEC_OTHER,            /* Should never be visible to Elisp code.  */
1040	  PVEC_XWIDGET,
1041	  PVEC_XWIDGET_VIEW,
1042	  PVEC_THREAD,
1043	  PVEC_MUTEX,
1044	  PVEC_CONDVAR,
1045	  PVEC_MODULE_FUNCTION,
1046	  PVEC_MODULE_GLOBAL_REFERENCE,
1047	  PVEC_NATIVE_COMP_UNIT,
1048	  PVEC_TS_PARSER,
1049	  PVEC_TS_NODE,
1050	  PVEC_TS_COMPILED_QUERY,
1051	  PVEC_SQLITE,
1052
1053	  /* These should be last, for internal_equal and sxhash_obj.  */
1054	  PVEC_CLOSURE,
1055	  PVEC_CHAR_TABLE,
1056	  PVEC_SUB_CHAR_TABLE,
1057	  PVEC_RECORD,
1058	  PVEC_FONT,
1059	  PVEC_TAG_MAX = PVEC_FONT  /* Keep this equal to the highest member.  */
1060	};
1061
1062	enum More_Lisp_Bits
1063	  {
1064	    /* For convenience, we also store the number of elements in these bits.
1065	       Note that this size is not necessarily the memory-footprint size, but
1066	       only the number of Lisp_Object fields (that need to be traced by GC).
1067	       The distinction is used, e.g., by Lisp_Process, which places extra
1068	       non-Lisp_Object fields at the end of the structure.  */
1069	    PSEUDOVECTOR_SIZE_BITS = 12,
1070	    PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1,
1071
1072	    /* To calculate the memory footprint of the pseudovector, it's useful
1073	       to store the size of non-Lisp area in word_size units here.  */
1074	    PSEUDOVECTOR_REST_BITS = 12,
1075	    PSEUDOVECTOR_REST_MASK = (((1 << PSEUDOVECTOR_REST_BITS) - 1)
1076				      << PSEUDOVECTOR_SIZE_BITS),
1077
1078	    /* Used to extract pseudovector subtype information.  */
1079	    PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS,
1080	    PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS
1081	  };
1082	^L
1083	/* These functions extract various sorts of values from a Lisp_Object.
1084	   For example, if tem is a Lisp_Object whose type is Lisp_Cons,
1085	   XCONS (tem) is the struct Lisp_Cons * pointing to the memory for
1086	   that cons.  */
1087
1088	/* Largest and smallest representable fixnum values.  These are the C
1089	   values.  They are macros for use in #if and static initializers.  */
1090	#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
1091	#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
1092	^L
1093	INLINE bool
1094	PSEUDOVECTORP (Lisp_Object a, int code)
1095	{
1096	  return (lisp_h_VECTORLIKEP (a)
1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577a99f <+8527>:	test   $0x7,%al
   0x000055555577a9a1 <+8529>:	jne    0x55555577a9b6 <read_char+8550>

1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x000055555577a9a3 <+8531>:	movabs $0x400000003f000000,%rax
   0x000055555577a9ad <+8541>:	and    0x3(%rbx),%rax

1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577a9b1 <+8545>:	cmp    %r13,%rax
   0x000055555577a9b4 <+8548>:	je     0x55555577a970 <read_char+8480>

1183	  Lisp_Object a = TAG_PTR_INITIALLY (Lisp_Symbol, symoffset);
1184	  return a;
   0x000055555577a9b6 <+8550>:	xor    %esi,%esi
   0x000055555577a9b8 <+8552>:	mov    %r12,%rdi
   0x000055555577a9bb <+8555>:	call   0x5555558204b0 <unbind_to>

./src/keyboard.c:
3384	      redisplay ();
   0x000055555577a9c0 <+8560>:	call   0x55555564ed30 <redisplay>

3385	      if (BASE_EQ (c, make_fixnum (040)))
   0x000055555577a9c5 <+8565>:	cmp    $0x82,%rbx
   0x000055555577a9cc <+8572>:	jne    0x555555778b30 <read_char+736>

672	  current_kboard->immediate_echo = false;
   0x000055555577a9d2 <+8578>:	mov    0x38b887(%rip),%rax        # 0x555555b06260 <current_kboard>

673	  kset_echo_prompt (current_kboard, Qnil);
674	  kset_echo_string (current_kboard, Qnil);
675	  ok_to_echo_at_next_pause = NULL;
   0x000055555577a9d9 <+8585>:	movq   $0x0,0x38bc0c(%rip)        # 0x555555b065f0 <ok_to_echo_at_next_pause>

./src/lisp.h:
1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x000055555577a9e4 <+8596>:	movabs $0x400000003f000000,%r12

1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577a9ee <+8606>:	movabs $0x400000000d000000,%rbx

./src/keyboard.c:
676	  echo_kboard = NULL;
   0x000055555577a9f8 <+8616>:	movq   $0x0,0x38b765(%rip)        # 0x555555b06168 <echo_kboard>

672	  current_kboard->immediate_echo = false;
   0x000055555577aa03 <+8627>:	andb   $0xfe,0xb9(%rax)

450	  kb->echo_prompt_ = val;
   0x000055555577aa0a <+8634>:	movq   $0x0,0xc0(%rax)

445	  kb->echo_string_ = val;
   0x000055555577aa15 <+8645>:	movq   $0x0,0xb0(%rax)

677	  echo_message_buffer = Qnil;
   0x000055555577aa20 <+8656>:	movq   $0x0,0x38b735(%rip)        # 0x555555b06160 <echo_message_buffer>

./src/lisp.h:
1184	  return a;
   0x000055555577aa2b <+8667>:	xor    %r8d,%r8d
   0x000055555577aa2e <+8670>:	xor    %ecx,%ecx
   0x000055555577aa30 <+8672>:	xor    %edx,%edx
   0x000055555577aa32 <+8674>:	xor    %esi,%esi
   0x000055555577aa34 <+8676>:	xor    %edi,%edi
   0x000055555577aa36 <+8678>:	call   0x555555778850 <read_char>

./src/keyboard.c:
3389		    c_volatile = c = read_char (0, Qnil, Qnil, 0, NULL);
   0x000055555577aa3b <+8683>:	mov    %rax,-0x470(%rbp)

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577aa42 <+8690>:	mov    %rax,%r14

747	}
748
749	INLINE void *
750	(XLP) (Lisp_Object o)
751	{
752	  return lisp_h_XLP (o);
753	}
754
755	/* Extract A's type.  */
756
757	INLINE enum Lisp_Type
758	(XTYPE) (Lisp_Object a)
759	{
760	#if USE_LSB_TAG
761	  return lisp_h_XTYPE (a);
762	#else
763	  EMACS_UINT i = XLI (a);
764	  return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
765	#endif
766	}
767
768	/* True if A has type tag TAG.
769	   Equivalent to XTYPE (a) == TAG, but often faster.  */
770
771	INLINE bool
772	(TAGGEDP) (Lisp_Object a, enum Lisp_Type tag)
773	{
774	  return lisp_h_TAGGEDP (a, tag);
   0x000055555577aa45 <+8693>:	lea    -0x5(%rax),%eax

775	}
776
777	INLINE void
778	(CHECK_TYPE) (int ok, Lisp_Object predicate, Lisp_Object x)
779	{
780	  lisp_h_CHECK_TYPE (ok, predicate, x);
781	}
782
783	/* Extract A's pointer value, assuming A's Lisp type is TYPE and the
784	   extracted pointer's type is CTYPE *.  When !USE_LSB_TAG this simply
785	   extracts A's low-order bits, as (uintptr_t) LISP_WORD_TAG (type) is
786	   always zero then.  */
787	#define XUNTAG(a, type, ctype) \
788	  ((ctype *) ((uintptr_t) XLP (a) - (uintptr_t) LISP_WORD_TAG (type)))
789
790	/* A forwarding pointer to a value.  It uses a generic pointer to
791	   avoid alignment bugs that could occur if it used a pointer to a
792	   union of the possible values (struct Lisp_Objfwd, struct
793	   Lisp_Intfwd, etc.).  The pointer is packaged inside a struct to
794	   help static checking.  */
795	typedef const struct Lisp_Fwd *lispfwd;
796	^L
797	/* Interned state of a symbol.  */
798
799	enum symbol_interned
800	{
801	  SYMBOL_UNINTERNED,		      /* not interned anywhere */
802	  SYMBOL_INTERNED,		      /* interned but not in initial obarray */
803	  SYMBOL_INTERNED_IN_INITIAL_OBARRAY  /* interned in initial obarray */
804	};
805
806	enum symbol_redirect
807	{
808	  SYMBOL_PLAINVAL,   /* plain var, value is in the `value' field */
809	  SYMBOL_VARALIAS,   /* var alias, value is really in the `alias' symbol */
810	  SYMBOL_LOCALIZED,  /* localized var, value is in the `blv' object */
811	  SYMBOL_FORWARDED   /* forwarding var, value is in `forward' */
812	};
813
814	enum symbol_trapped_write
815	{
816	  SYMBOL_UNTRAPPED_WRITE,  /* normal case, just set the value */
817	  SYMBOL_NOWRITE,          /* constant, cannot set, e.g. nil, t, :keyword */
818	  SYMBOL_TRAPPED_WRITE     /* trap the write, call watcher functions */
819	};
820
821	struct Lisp_Symbol
822	{
823	  GC_HEADER
824	  union
825	  {
826	    struct
827	    {
828	      bool_bf gcmarkbit : 1;
829
830	      /* Indicates where the value can be found.  */
831	      ENUM_BF (symbol_redirect) redirect : 2;
832
833	      ENUM_BF (symbol_trapped_write) trapped_write : 2;
834
835	      /* Interned state of the symbol.  */
836	      ENUM_BF (symbol_interned) interned : 2;
837
838	      /* True means that this variable has been explicitly declared
839		 special (with `defvar' etc), and shouldn't be lexically bound.  */
840	      bool_bf declared_special : 1;
841
842	      /* The symbol's name, as a Lisp string.  */
843	      Lisp_Object name;
844
845	      /* Value of the symbol or Qunbound if unbound.  Which alternative of the
846		 union is used depends on the `redirect' field above.  */
847	      union {
848		Lisp_Object value;
849		struct Lisp_Symbol *alias;
850		struct Lisp_Buffer_Local_Value *blv;
851		lispfwd fwd;
852	      } val;
853
854	      /* Function value of the symbol or Qnil if not fboundp.  */
855	      Lisp_Object function;
856
857	      /* The symbol's property list.  */
858	      Lisp_Object plist;
859
860	      /* Next symbol in obarray bucket, if the symbol is interned.  */
861	      struct Lisp_Symbol *next;
862	    } s;
863	    GCALIGNED_UNION_MEMBER
864	  } u;
865	};
866	static_assert (GCALIGNED (struct Lisp_Symbol));
867
868	/* Declare a Lisp-callable function.  The MAXARGS parameter has the same
869	   meaning as in the DEFUN macro, and is used to construct a prototype.  */
870	/* We can use the same trick as in the DEFUN macro to generate the
871	   appropriate prototype.  */
872	#define EXFUN(fnname, maxargs) \
873	  extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs
874
875	/* Note that the weird token-substitution semantics of ANSI C makes
876	   this work for MANY and UNEVALLED.  */
877	#define DEFUN_ARGS_MANY		(ptrdiff_t, Lisp_Object *)
878	#define DEFUN_ARGS_UNEVALLED	(Lisp_Object)
879	#define DEFUN_ARGS_0	(void)
880	#define DEFUN_ARGS_1	(Lisp_Object)
881	#define DEFUN_ARGS_2	(Lisp_Object, Lisp_Object)
882	#define DEFUN_ARGS_3	(Lisp_Object, Lisp_Object, Lisp_Object)
883	#define DEFUN_ARGS_4	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
884	#define DEFUN_ARGS_5	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
885				 Lisp_Object)
886	#define DEFUN_ARGS_6	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
887				 Lisp_Object, Lisp_Object)
888	#define DEFUN_ARGS_7	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
889				 Lisp_Object, Lisp_Object, Lisp_Object)
890	#define DEFUN_ARGS_8	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
891				 Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
892
893	/* Lisp_Word_tag is big enough for a possibly-shifted tag, to be
894	   added to a pointer value for conversion to a Lisp_Word.  */
895	#if LISP_WORDS_ARE_POINTERS
896	typedef uintptr_t Lisp_Word_tag;
897	#else
898	typedef EMACS_UINT Lisp_Word_tag;
899	#endif
900
901	/* A integer value tagged with TAG, and otherwise all zero.  */
902	#define LISP_WORD_TAG(tag) \
903	  ((Lisp_Word_tag) (tag) << (USE_LSB_TAG ? 0 : VALBITS))
904
905	/* An initializer for a Lisp_Object that contains TAG along with P.
906	   P can be a pointer or an integer.  The result is usable in a static
907	   initializer if TAG and P are both integer constant expressions.  */
908	#define TAG_PTR_INITIALLY(tag, p) \
909	  LISP_INITIALLY ((Lisp_Word) ((uintptr_t) (p) + LISP_WORD_TAG (tag)))
910
911	/* LISPSYM_INITIALLY (Qfoo) is equivalent to Qfoo except it is
912	   designed for use as a (possibly static) initializer.  */
913	#define LISPSYM_INITIALLY(name) \
914	  TAG_PTR_INITIALLY (Lisp_Symbol, (intptr_t) ((i##name) * sizeof *lispsym))
915
916	/* Declare extern constants for Lisp symbols.  These can be helpful
917	   when using a debugger like GDB, on older platforms where the debug
918	   format does not represent C macros.  However, they are unbounded
919	   and would just be asking for trouble if checking pointer bounds.  */
920	#define DEFINE_LISP_SYMBOL(name) \
921	  DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) \
922	  DEFINE_GDB_SYMBOL_END (LISPSYM_INITIALLY (name))
923
924	/* The index of the C-defined Lisp symbol SYM.
925	   This can be used in a static initializer.  */
926	#define SYMBOL_INDEX(sym) i##sym
927
928	/* By default, define macros for Qt, etc., as this leads to a bit
929	   better performance in the core Emacs interpreter.  A plugin can
930	   define DEFINE_NON_NIL_Q_SYMBOL_MACROS to be false, to be portable to
931	   other Emacs instances that assign different values to Qt, etc.  */
932	#ifndef DEFINE_NON_NIL_Q_SYMBOL_MACROS
933	# define DEFINE_NON_NIL_Q_SYMBOL_MACROS true
934	#endif
935
936	/* True if N is a power of 2.  N should be positive.  */
937
938	#define POWER_OF_2(n) (((n) & ((n) - 1)) == 0)
939
940	/* Return X rounded to the next multiple of Y.  Y should be positive,
941	   and Y - 1 + X should not overflow.  Arguments should not have side
942	   effects, as they are evaluated more than once.  Tune for Y being a
943	   power of 2.  */
944
945	#define ROUNDUP(x, y) (POWER_OF_2 (y)					\
946	                       ? ((y) - 1 + (x)) & ~ ((y) - 1)			\
947	                       : ((y) - 1 + (x)) - ((y) - 1 + (x)) % (y))
948
949	#include <globals.h>
950
951	/* Header of vector-like objects.  This documents the layout constraints on
952	   vectors and pseudovectors (objects of PVEC_xxx subtype).  It also prevents
953	   compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR
954	   and PSEUDOVECTORP cast their pointers to struct vectorlike_header *,
955	   because when two such pointers potentially alias, a compiler won't
956	   incorrectly reorder loads and stores to their size fields.  See
957	   Bug#8546.   */
958	struct vectorlike_header
959	  {
960	    /* The `size' header word, W bits wide, has one of two forms
961	       discriminated by the second-highest bit (PSEUDOVECTOR_FLAG):
962
963	         1   1                    W-2
964	       +---+---+-------------------------------------+
965	       | M | 0 |                 SIZE                |  vector
966	       +---+---+-------------------------------------+
967
968	         1   1    W-32      6       12         12
969	       +---+---+--------+------+----------+----------+
970	       | M | 1 | unused | TYPE | RESTSIZE | LISPSIZE |  pseudovector
971	       +---+---+--------+------+----------+----------+
972
973	       M (ARRAY_MARK_FLAG) holds the GC mark bit.
974
975	       SIZE     is the length (number of slots) of a regular Lisp vector,
976	                and the object layout is struct Lisp_Vector.
977
978	       TYPE     is the pseudovector subtype (enum pvec_type).
979
980	       LISPSIZE is the number of Lisp_Object fields at the beginning of the
981	                object (after the header).  These are always traced by the GC.
982
983	       RESTSIZE is the number of fields (in word_size units) following.
984	                These are not automatically traced by the GC.
985	                For PVEC_BOOL and statically allocated PVEC_SUBR, RESTSIZE is 0.
986	                (The block size for PVEC_BOOL is computed from its own size
987	                field, to avoid being restricted by the 12-bit RESTSIZE field.)
988	    */
989	    GC_HEADER
990	    ptrdiff_t size;
991	  };
992
993	struct Lisp_Symbol_With_Pos
994	{
995	  struct vectorlike_header header;
996	  Lisp_Object sym;              /* A symbol */
997	  Lisp_Object pos;              /* A fixnum */
998	} GCALIGNED_STRUCT;
999
1000	/* In the size word of a vector, this bit means the vector has been marked.  */
1001
1002	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG)
1003	# define ARRAY_MARK_FLAG PTRDIFF_MIN
1004	DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG)
1005
1006	/* In the size word of a struct Lisp_Vector, this bit means it's really
1007	   some other vector-like object.  */
1008	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG)
1009	# define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2)
1010	DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
1011
1012	/* In a pseudovector, the size field actually contains a word with one
1013	   PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
1014	   with PVEC_TYPE_MASK to indicate the actual type.  */
1015	enum pvec_type
1016	{
1017	  PVEC_NORMAL_VECTOR,	/* Should be first, for sxhash_obj.  */
1018	  PVEC_FREE,
1019	  PVEC_BIGNUM,
1020	  PVEC_MARKER,
1021	  PVEC_OVERLAY,
1022	  PVEC_FINALIZER,
1023	  PVEC_SYMBOL_WITH_POS,
1024	  PVEC_MISC_PTR,
1025	  PVEC_USER_PTR,
1026	  PVEC_PROCESS,
1027	  PVEC_FRAME,
1028	  PVEC_WINDOW,
1029	  PVEC_BOOL_VECTOR,
1030	  PVEC_BUFFER,
1031	  PVEC_HASH_TABLE,
1032	#ifdef HAVE_MPS
1033	  PVEC_WEAK_HASH_TABLE,
1034	#endif
1035	  PVEC_OBARRAY,
1036	  PVEC_TERMINAL,
1037	  PVEC_WINDOW_CONFIGURATION,
1038	  PVEC_SUBR,
1039	  PVEC_OTHER,            /* Should never be visible to Elisp code.  */
1040	  PVEC_XWIDGET,
1041	  PVEC_XWIDGET_VIEW,
1042	  PVEC_THREAD,
1043	  PVEC_MUTEX,
1044	  PVEC_CONDVAR,
1045	  PVEC_MODULE_FUNCTION,
1046	  PVEC_MODULE_GLOBAL_REFERENCE,
1047	  PVEC_NATIVE_COMP_UNIT,
1048	  PVEC_TS_PARSER,
1049	  PVEC_TS_NODE,
1050	  PVEC_TS_COMPILED_QUERY,
1051	  PVEC_SQLITE,
1052
1053	  /* These should be last, for internal_equal and sxhash_obj.  */
1054	  PVEC_CLOSURE,
1055	  PVEC_CHAR_TABLE,
1056	  PVEC_SUB_CHAR_TABLE,
1057	  PVEC_RECORD,
1058	  PVEC_FONT,
1059	  PVEC_TAG_MAX = PVEC_FONT  /* Keep this equal to the highest member.  */
1060	};
1061
1062	enum More_Lisp_Bits
1063	  {
1064	    /* For convenience, we also store the number of elements in these bits.
1065	       Note that this size is not necessarily the memory-footprint size, but
1066	       only the number of Lisp_Object fields (that need to be traced by GC).
1067	       The distinction is used, e.g., by Lisp_Process, which places extra
1068	       non-Lisp_Object fields at the end of the structure.  */
1069	    PSEUDOVECTOR_SIZE_BITS = 12,
1070	    PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1,
1071
1072	    /* To calculate the memory footprint of the pseudovector, it's useful
1073	       to store the size of non-Lisp area in word_size units here.  */
1074	    PSEUDOVECTOR_REST_BITS = 12,
1075	    PSEUDOVECTOR_REST_MASK = (((1 << PSEUDOVECTOR_REST_BITS) - 1)
1076				      << PSEUDOVECTOR_SIZE_BITS),
1077
1078	    /* Used to extract pseudovector subtype information.  */
1079	    PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS,
1080	    PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS
1081	  };
1082	^L
1083	/* These functions extract various sorts of values from a Lisp_Object.
1084	   For example, if tem is a Lisp_Object whose type is Lisp_Cons,
1085	   XCONS (tem) is the struct Lisp_Cons * pointing to the memory for
1086	   that cons.  */
1087
1088	/* Largest and smallest representable fixnum values.  These are the C
1089	   values.  They are macros for use in #if and static initializers.  */
1090	#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
1091	#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
1092	^L
1093	INLINE bool
1094	PSEUDOVECTORP (Lisp_Object a, int code)
1095	{
1096	  return (lisp_h_VECTORLIKEP (a)
1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577aa48 <+8696>:	test   $0x7,%al
   0x000055555577aa4a <+8698>:	jne    0x555555778b30 <read_char+736>

1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x000055555577aa50 <+8704>:	mov    0x3(%r14),%rax
   0x000055555577aa54 <+8708>:	and    %r12,%rax

1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577aa57 <+8711>:	cmp    %rbx,%rax
   0x000055555577aa5a <+8714>:	jne    0x555555778b30 <read_char+736>
   0x000055555577aa60 <+8720>:	jmp    0x55555577aa2b <read_char+8667>
   0x000055555577aa62 <+8722>:	nopw   0x0(%rax,%rax,1)

1517	  igc_check_fwd (c, false);
1518	  return c;
   0x000055555577aa68 <+8728>:	mov    0x5(%r14),%rdi

./src/keyboard.c:
3377		      && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_click))
   0x000055555577aa6c <+8732>:	mov    $0x9338,%esi
   0x000055555577aa71 <+8737>:	call   0x555555838da0 <Fget>
   0x000055555577aa76 <+8742>:	mov    $0xfd50,%esi
   0x000055555577aa7b <+8747>:	mov    %rax,%rdi
   0x000055555577aa7e <+8750>:	call   0x555555764470 <EQ>
   0x000055555577aa83 <+8755>:	test   %al,%al
   0x000055555577aa85 <+8757>:	je     0x55555577a99b <read_char+8523>

3378		    XSETCAR (help_form_saved_window_configs, Qnil);
   0x000055555577aa8b <+8763>:	cmpb   $0x0,0x3a18ee(%rip)        # 0x555555b1c380 <suppress_checking>
   0x000055555577aa92 <+8770>:	mov    0x38b8af(%rip),%rax        # 0x555555b06348 <help_form_saved_window_configs>

./src/lisp.h:
1515	  eassert (CONSP (a));
   0x000055555577aa99 <+8777>:	jne    0x55555577aaa7 <read_char+8791>

740	  return lisp_h_XLI (o);
   0x000055555577aa9b <+8779>:	lea    -0x3(%rax),%edx

1384	}
1385
1386	#define XSETINT(a, b) ((a) = make_fixnum (b))
1387	#define XSETFASTINT(a, b) ((a) = make_fixed_natnum (b))
1388	#define XSETCONS(a, b) ((a) = make_lisp_ptr (b, Lisp_Cons))
1389	#define XSETVECTOR(a, b) ((a) = make_lisp_ptr (b, Lisp_Vectorlike))
1390	#define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String))
1391	#define XSETSYMBOL(a, b) ((a) = make_lisp_symbol (b))
1392	#define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float))
1393
1394	/* Return a Lisp_Object value that does not correspond to any object.
1395	   This can make some Lisp objects on free lists recognizable in O(1).  */
1396
1397	INLINE Lisp_Object
1398	dead_object (void)
1399	{
1400	  return make_lisp_ptr (NULL, Lisp_String);
1401	}
1402
1403	/* Pseudovector types.  */
1404
1405	#define XSETPVECTYPE(v, code)						\
1406	  ((v)->header.size |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS))
1407	#define PVECHEADERSIZE(code, lispsize, restsize) \
1408	  (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS) \
1409	   | ((restsize) << PSEUDOVECTOR_SIZE_BITS) | (lispsize))
1410	#define XSETPVECTYPESIZE(v, code, lispsize, restsize)		\
1411	  ((v)->header.size = PVECHEADERSIZE (code, lispsize, restsize))
1412
1413	/* The cast to struct vectorlike_header * avoids aliasing issues.  */
1414	#define XSETPSEUDOVECTOR(a, b, code) \
1415	  XSETTYPED_PSEUDOVECTOR (a, b,					\
1416				  (XUNTAG (a, Lisp_Vectorlike,		\
1417					   struct vectorlike_header)	\
1418				   ->size),				\
1419				  code)
1420	#define XSETTYPED_PSEUDOVECTOR(a, b, size, code)			\
1421	  (XSETVECTOR (a, b),							\
1422	   eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))		\
1423		    == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS))))
1424
1425	#define XSETWINDOW_CONFIGURATION(a, b) \
1426	  XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION)
1427	#define XSETPROCESS(a, b) XSETPSEUDOVECTOR (a, b, PVEC_PROCESS)
1428	#define XSETWINDOW(a, b) XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)
1429	#define XSETTERMINAL(a, b) XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)
1430	#define XSETSUBR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_SUBR)
1431	#define XSETBUFFER(a, b) XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)
1432	#define XSETCHAR_TABLE(a, b) XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)
1433	#define XSETBOOL_VECTOR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR)
1434	#define XSETSUB_CHAR_TABLE(a, b) XSETPSEUDOVECTOR (a, b, PVEC_SUB_CHAR_TABLE)
1435	#define XSETTHREAD(a, b) XSETPSEUDOVECTOR (a, b, PVEC_THREAD)
1436	#define XSETMUTEX(a, b) XSETPSEUDOVECTOR (a, b, PVEC_MUTEX)
1437	#define XSETCONDVAR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_CONDVAR)
1438	#define XSETNATIVE_COMP_UNIT(a, b) XSETPSEUDOVECTOR (a, b, PVEC_NATIVE_COMP_UNIT)
1439
1440	/* Efficiently convert a pointer to a Lisp object and back.  The
1441	   pointer is represented as a fixnum, so the garbage collector
1442	   does not know about it.  The pointer should not have both Lisp_Int1
1443	   bits set, which makes this conversion inherently unportable.  */
1444
1445	INLINE void *
1446	XFIXNUMPTR (Lisp_Object a)
1447	{
1448	  return XUNTAG (a, Lisp_Int0, char);
1449	}
1450
1451	INLINE Lisp_Object
1452	make_pointer_integer_unsafe (void *p)
1453	{
1454	  Lisp_Object a = TAG_PTR_INITIALLY (Lisp_Int0, p);
1455	  return a;
1456	}
1457
1458	INLINE Lisp_Object
1459	make_pointer_integer (void *p)
1460	{
1461	  Lisp_Object a = make_pointer_integer_unsafe (p);
1462	  eassert (FIXNUMP (a) && XFIXNUMPTR (a) == p);
1463	  return a;
1464	}
1465
1466	/* See the macros in intervals.h.  */
1467
1468	typedef struct interval *INTERVAL;
1469
1470	struct Lisp_Cons
1471	{
1472	  GC_HEADER
1473	  union
1474	  {
1475	    struct
1476	    {
1477	      /* Car of this cons cell.  */
1478	      Lisp_Object car;
1479
1480	      union
1481	      {
1482		/* Cdr of this cons cell.  */
1483		Lisp_Object cdr;
1484
1485		/* Used to chain conses on a free list.  */
1486		struct Lisp_Cons *chain;
1487	      } u;
1488	    } s;
1489	    GCALIGNED_UNION_MEMBER
1490	  } u;
1491	};
1492	static_assert (GCALIGNED (struct Lisp_Cons));
1493
1494	INLINE bool
1495	(NILP) (Lisp_Object x)
1496	{
1497	  return lisp_h_NILP (x);
1498	}
1499
1500	INLINE bool
1501	(CONSP) (Lisp_Object x)
1502	{
1503	  return lisp_h_CONSP (x);
1504	}
1505
1506	INLINE void
1507	CHECK_CONS (Lisp_Object x)
1508	{
1509	  CHECK_TYPE (CONSP (x), Qconsp, x);
1510	}
1511
1512	INLINE struct Lisp_Cons *
1513	XCONS (Lisp_Object a)
1514	{
1515	  eassert (CONSP (a));
   0x000055555577aa9e <+8782>:	and    $0x7,%edx
   0x000055555577aaa1 <+8785>:	jne    0x5555555b27bc <read_char-1859732>

1517	  igc_check_fwd (c, false);
1518	  return c;
   0x000055555577aaa7 <+8791>:	movq   $0x0,0x5(%rax)

1551	}
1552
1553	/* Use these to set the fields of a cons cell.
1554
1555	   Note that both arguments may refer to the same object, so 'n'
1556	   should not be read after 'c' is first modified.  */
1557	INLINE void
1558	XSETCAR (Lisp_Object c, Lisp_Object n)
1559	{
1560	  *xcar_addr (c) = n;
   0x000055555577aaaf <+8799>:	jmp    0x55555577a99b <read_char+8523>

./src/keyboard.c:
4514	  else if (had_pending_selection_requests)
   0x000055555577aab4 <+8804>:	test   %bl,%bl
   0x000055555577aab6 <+8806>:	jne    0x55555577a198 <read_char+6472>
   0x000055555577aabc <+8812>:	jmp    0x5555555b27b7 <read_char-1859737>
   0x000055555577aac1 <+8817>:	nopl   0x0(%rax)

4322		    Vlast_event_device = event->ie.device;
   0x000055555577aac8 <+8824>:	mov    %rbx,0x3a5fc1(%rip)        # 0x555555b20a90 <globals+1616>

4323
4324		  /* If we didn't decide to make a switch-frame event, go ahead
4325		     and build a real event from the queue entry.  */
4326		  if (NILP (obj))
   0x000055555577aacf <+8831>:	test   %r14,%r14
   0x000055555577aad2 <+8834>:	jne    0x555555779a17 <read_char+4551>

4327		    {
4328		      double pinch_dx, pinch_dy, pinch_angle;
4329
4330		      /* Pinch events are often sent in rapid succession, so
4331			 large amounts of such events have the potential to
4332			 queue up inside the keyboard buffer.  In that case,
4333			 find the last pinch event in succession on the same
4334			 frame with the same modifiers, and send that instead.  */
4335
4336		      if (event->ie.kind == PINCH_EVENT
   0x000055555577aad8 <+8840>:	movzwl (%r8),%eax
   0x000055555577aadc <+8844>:	cmp    $0x24,%ax
   0x000055555577aae0 <+8848>:	je     0x55555577b6a3 <read_char+11859>

4382
4383			      maybe_event = next_kbd_event (event);
4384			    }
4385			}
4386
4387		      if (event->kind == MULTIBYTE_CHAR_KEYSTROKE_EVENT
   0x000055555577aae6 <+8854>:	cmp    $0x2,%ax
   0x000055555577aaea <+8858>:	je     0x55555577bd4c <read_char+13564>

4426			}
4427
4428		      obj = make_lispy_event (&event->ie);
   0x000055555577aaf0 <+8864>:	mov    %r8,%rdi
   0x000055555577aaf3 <+8867>:	mov    %r8,-0x578(%rbp)
   0x000055555577aafa <+8874>:	call   0x55555576bb10 <make_lispy_event>

4429
4430	#ifdef HAVE_EXT_MENU_BAR
4431		      /* If this was a menu selection, then set the flag to inhibit
4432			 writing to last_nonmenu_event.  Don't do this if the event
4433			 we're returning is (menu-bar), though; that indicates the
4434			 beginning of the menu sequence, and we might as well leave
4435			 that as the `event with parameters' for this selection.  */
4436		      if (used_mouse_menu
4437			  && !EQ (event->ie.frame_or_window, event->ie.arg)
4438			  && (event->kind == MENU_BAR_EVENT
4439			      || event->kind == TAB_BAR_EVENT
4440			      || event->kind == TOOL_BAR_EVENT))
4441			*used_mouse_menu = true;
4442	#endif
4443	#ifdef HAVE_NS
4444		      /* Certain system events are non-key events.  */
4445		      if (used_mouse_menu
4446	                  && event->kind == NS_NONKEY_EVENT)
4447			*used_mouse_menu = true;
4448	#endif
4449
4450		      if (event->kind != MULTIBYTE_CHAR_KEYSTROKE_EVENT
   0x000055555577aaff <+8879>:	mov    -0x578(%rbp),%r8

4428		      obj = make_lispy_event (&event->ie);
   0x000055555577ab06 <+8886>:	mov    %rax,%r14

4429
4430	#ifdef HAVE_EXT_MENU_BAR
4431		      /* If this was a menu selection, then set the flag to inhibit
4432			 writing to last_nonmenu_event.  Don't do this if the event
4433			 we're returning is (menu-bar), though; that indicates the
4434			 beginning of the menu sequence, and we might as well leave
4435			 that as the `event with parameters' for this selection.  */
4436		      if (used_mouse_menu
4437			  && !EQ (event->ie.frame_or_window, event->ie.arg)
4438			  && (event->kind == MENU_BAR_EVENT
4439			      || event->kind == TAB_BAR_EVENT
4440			      || event->kind == TOOL_BAR_EVENT))
4441			*used_mouse_menu = true;
4442	#endif
4443	#ifdef HAVE_NS
4444		      /* Certain system events are non-key events.  */
4445		      if (used_mouse_menu
4446	                  && event->kind == NS_NONKEY_EVENT)
4447			*used_mouse_menu = true;
4448	#endif
4449
4450		      if (event->kind != MULTIBYTE_CHAR_KEYSTROKE_EVENT
   0x000055555577ab09 <+8889>:	cmpw   $0x2,(%r8)
   0x000055555577ab0e <+8894>:	je     0x55555577be28 <read_char+13784>

3963	  event->kind = NO_EVENT;
   0x000055555577ab14 <+8900>:	xor    %r9d,%r9d
   0x000055555577ab17 <+8903>:	mov    %r9w,(%r8)
   0x000055555577ab1b <+8907>:	jmp    0x55555577a649 <read_char+7673>

2336	  c = kbd_buffer_get_event (&kb, used_mouse_menu, end_time);
   0x000055555577ab20 <+8912>:	xor    %r14d,%r14d

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x000055555577ab23 <+8915>:	movzbl 0x3a1856(%rip),%eax        # 0x555555b1c380 <suppress_checking>
   0x000055555577ab2a <+8922>:	jmp    0x555555779acc <read_char+4732>

./src/keyboard.c:
3017	      for (kb = all_kboards; kb; kb = kb->next_kboard)
   0x000055555577ab2f <+8927>:	mov    0x38bb0a(%rip),%rax        # 0x555555b06640 <all_kboards>
   0x000055555577ab36 <+8934>:	test   %rax,%rax
   0x000055555577ab39 <+8937>:	jne    0x55555577ab4c <read_char+8956>
   0x000055555577ab3b <+8939>:	jmp    0x555555779457 <read_char+3079>
   0x000055555577ab40 <+8944>:	mov    (%rax),%rax
   0x000055555577ab43 <+8947>:	test   %rax,%rax
   0x000055555577ab46 <+8950>:	je     0x555555779457 <read_char+3079>

3018		if (kb->kbd_queue_has_data)
   0x000055555577ab4c <+8956>:	cmpb   $0x0,0xb8(%rax)
   0x000055555577ab53 <+8963>:	je     0x55555577ab40 <read_char+8944>

3019		  {
3020		    current_kboard = kb;
   0x000055555577ab55 <+8965>:	mov    %rax,0x38b704(%rip)        # 0x555555b06260 <current_kboard>

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577ab5c <+8972>:	mov    $0xfffffffffffffffa,%rax

./src/keyboard.c:
3021	            return make_fixnum (-2); /* wrong_kboard_jmpbuf */
   0x000055555577ab63 <+8979>:	jmp    0x555555778b5f <read_char+783>

3339	      && !end_time)
   0x000055555577ab68 <+8984>:	mov    -0x4a8(%rbp),%rax
   0x000055555577ab6f <+8991>:	or     0x38b6d2(%rip),%rax        # 0x555555b06248 <this_command_key_count>
   0x000055555577ab76 <+8998>:	jne    0x555555778b06 <read_char+694>
   0x000055555577ab7c <+9004>:	jmp    0x555555778a6c <read_char+540>

3321	      htem = Fcdr (XCDR (c));
   0x000055555577ab81 <+9009>:	mov    %r14,%rdi
   0x000055555577ab84 <+9012>:	call   0x5555557630d0 <XCDR>
   0x000055555577ab89 <+9017>:	mov    %rax,%rdi
   0x000055555577ab8c <+9020>:	call   0x555555802a20 <Fcdr>
   0x000055555577ab91 <+9025>:	mov    %rax,%rbx

3322	      help = Fcar (htem);
   0x000055555577ab94 <+9028>:	mov    %rax,%rdi
   0x000055555577ab97 <+9031>:	call   0x555555802980 <Fcar>

3323	      htem = Fcdr (htem);
   0x000055555577ab9c <+9036>:	mov    %rbx,%rdi

3322	      help = Fcar (htem);
   0x000055555577ab9f <+9039>:	mov    %rax,%r12

3323	      htem = Fcdr (htem);
   0x000055555577aba2 <+9042>:	call   0x555555802a20 <Fcdr>
   0x000055555577aba7 <+9047>:	mov    %rax,%rbx

3324	      window = Fcar (htem);
   0x000055555577abaa <+9050>:	mov    %rax,%rdi
   0x000055555577abad <+9053>:	call   0x555555802980 <Fcar>

3325	      htem = Fcdr (htem);
   0x000055555577abb2 <+9058>:	mov    %rbx,%rdi

3324	      window = Fcar (htem);
   0x000055555577abb5 <+9061>:	mov    %rax,%r13

3325	      htem = Fcdr (htem);
   0x000055555577abb8 <+9064>:	call   0x555555802a20 <Fcdr>
   0x000055555577abbd <+9069>:	mov    %rax,%rbx

3326	      object = Fcar (htem);
   0x000055555577abc0 <+9072>:	mov    %rax,%rdi
   0x000055555577abc3 <+9075>:	call   0x555555802980 <Fcar>

3327	      htem = Fcdr (htem);
   0x000055555577abc8 <+9080>:	mov    %rbx,%rdi

3326	      object = Fcar (htem);
   0x000055555577abcb <+9083>:	mov    %rax,%r14

3327	      htem = Fcdr (htem);
   0x000055555577abce <+9086>:	call   0x555555802a20 <Fcdr>

3328	      position = Fcar (htem);
   0x000055555577abd3 <+9091>:	mov    %rax,%rdi
   0x000055555577abd6 <+9094>:	call   0x555555802980 <Fcar>

3329
3330	      show_help_echo (help, window, object, position);
   0x000055555577abdb <+9099>:	mov    %r14,%rdx
   0x000055555577abde <+9102>:	mov    %r13,%rsi
   0x000055555577abe1 <+9105>:	mov    %r12,%rdi

3328	      position = Fcar (htem);
   0x000055555577abe4 <+9108>:	mov    %rax,%rcx

3329
3330	      show_help_echo (help, window, object, position);
   0x000055555577abe7 <+9111>:	call   0x55555576fe10 <show_help_echo>

3331
3332	      /* We stopped being idle for this event; undo that.  */
3333	      if (!end_time)
   0x000055555577abec <+9116>:	cmpq   $0x0,-0x4a8(%rbp)
   0x000055555577abf4 <+9124>:	jne    0x5555557788da <read_char+138>

./src/systime.h:
70	  return t.tv_nsec >= 0;
   0x000055555577abfa <+9130>:	cmpq   $0x0,0x38b9b6(%rip)        # 0x555555b065b8 <timer_idleness_start_time+8>
   0x000055555577ac02 <+9138>:	jns    0x5555557788da <read_char+138>

./src/keyboard.c:
4662	  timer_idleness_start_time = timer_last_idleness_start_time;
   0x000055555577ac08 <+9144>:	movdqa 0x38b990(%rip),%xmm0        # 0x555555b065a0 <timer_last_idleness_start_time>
   0x000055555577ac10 <+9152>:	movaps %xmm0,0x38b999(%rip)        # 0x555555b065b0 <timer_idleness_start_time>

3335	      goto retry;
   0x000055555577ac17 <+9159>:	jmp    0x5555557788da <read_char+138>

4311		      && !EQ (frame, selected_frame))
   0x000055555577ac1c <+9164>:	mov    0x334905(%rip),%rsi        # 0x555555aaf528 <selected_frame>
   0x000055555577ac23 <+9171>:	mov    %rbx,%rdi
   0x000055555577ac26 <+9174>:	mov    %r8,-0x560(%rbp)
   0x000055555577ac2d <+9181>:	call   0x555555764470 <EQ>
   0x000055555577ac32 <+9186>:	mov    -0x560(%rbp),%r8
   0x000055555577ac39 <+9193>:	test   %al,%al
   0x000055555577ac3b <+9195>:	jne    0x5555557799c1 <read_char+4465>

7164	    }
7165	}
7166
7167	/* Construct a switch frame event.  */
7168	static Lisp_Object
7169	make_lispy_switch_frame (Lisp_Object frame)
7170	{
7171	  return list2 (Qswitch_frame, frame);
   0x000055555577ac41 <+9201>:	mov    %rbx,%rsi
   0x000055555577ac44 <+9204>:	mov    $0x14858,%edi
   0x000055555577ac49 <+9209>:	mov    %r8,-0x5e0(%rbp)

./src/lisp.h:
1184	  return a;
   0x000055555577ac50 <+9216>:	call   0x5555557ef5d0 <list2>
   0x000055555577ac55 <+9221>:	mov    -0x5e0(%rbp),%r8
   0x000055555577ac5c <+9228>:	mov    %rax,%r14

./src/keyboard.c:
7171	  return list2 (Qswitch_frame, frame);
   0x000055555577ac5f <+9231>:	jmp    0x5555557799c1 <read_char+4465>

4306		  focus = FRAME_FOCUS_FRAME (XFRAME (frame));
   0x000055555577ac64 <+9236>:	cmpb   $0x0,0x3a1715(%rip)        # 0x555555b1c380 <suppress_checking>
   0x000055555577ac6b <+9243>:	je     0x5555555b28d6 <read_char-1859450>

./src/lisp.h:
1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577ac71 <+9249>:	lea    -0x5(%rdi),%rdx
   0x000055555577ac75 <+9253>:	jmp    0x55555577998e <read_char+4414>
   0x000055555577ac7a <+9258>:	mov    %r8,-0x558(%rbp)

./src/keyboard.c:
4302		    frame = XCAR (frame);
   0x000055555577ac81 <+9265>:	call   0x555555763090 <XCAR>
   0x000055555577ac86 <+9270>:	mov    -0x558(%rbp),%r8
   0x000055555577ac8d <+9277>:	mov    %rax,%rdi

4305
4306		  focus = FRAME_FOCUS_FRAME (XFRAME (frame));
   0x000055555577ac90 <+9280>:	cmpb   $0x0,0x3a16e9(%rip)        # 0x555555b1c380 <suppress_checking>
   0x000055555577ac97 <+9287>:	jne    0x55555577ac71 <read_char+9249>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577ac99 <+9289>:	lea    -0x5(%rdi),%eax

775	}
776
777	INLINE void
778	(CHECK_TYPE) (int ok, Lisp_Object predicate, Lisp_Object x)
779	{
780	  lisp_h_CHECK_TYPE (ok, predicate, x);
781	}
782
783	/* Extract A's pointer value, assuming A's Lisp type is TYPE and the
784	   extracted pointer's type is CTYPE *.  When !USE_LSB_TAG this simply
785	   extracts A's low-order bits, as (uintptr_t) LISP_WORD_TAG (type) is
786	   always zero then.  */
787	#define XUNTAG(a, type, ctype) \
788	  ((ctype *) ((uintptr_t) XLP (a) - (uintptr_t) LISP_WORD_TAG (type)))
789
790	/* A forwarding pointer to a value.  It uses a generic pointer to
791	   avoid alignment bugs that could occur if it used a pointer to a
792	   union of the possible values (struct Lisp_Objfwd, struct
793	   Lisp_Intfwd, etc.).  The pointer is packaged inside a struct to
794	   help static checking.  */
795	typedef const struct Lisp_Fwd *lispfwd;
796	^L
797	/* Interned state of a symbol.  */
798
799	enum symbol_interned
800	{
801	  SYMBOL_UNINTERNED,		      /* not interned anywhere */
802	  SYMBOL_INTERNED,		      /* interned but not in initial obarray */
803	  SYMBOL_INTERNED_IN_INITIAL_OBARRAY  /* interned in initial obarray */
804	};
805
806	enum symbol_redirect
807	{
808	  SYMBOL_PLAINVAL,   /* plain var, value is in the `value' field */
809	  SYMBOL_VARALIAS,   /* var alias, value is really in the `alias' symbol */
810	  SYMBOL_LOCALIZED,  /* localized var, value is in the `blv' object */
811	  SYMBOL_FORWARDED   /* forwarding var, value is in `forward' */
812	};
813
814	enum symbol_trapped_write
815	{
816	  SYMBOL_UNTRAPPED_WRITE,  /* normal case, just set the value */
817	  SYMBOL_NOWRITE,          /* constant, cannot set, e.g. nil, t, :keyword */
818	  SYMBOL_TRAPPED_WRITE     /* trap the write, call watcher functions */
819	};
820
821	struct Lisp_Symbol
822	{
823	  GC_HEADER
824	  union
825	  {
826	    struct
827	    {
828	      bool_bf gcmarkbit : 1;
829
830	      /* Indicates where the value can be found.  */
831	      ENUM_BF (symbol_redirect) redirect : 2;
832
833	      ENUM_BF (symbol_trapped_write) trapped_write : 2;
834
835	      /* Interned state of the symbol.  */
836	      ENUM_BF (symbol_interned) interned : 2;
837
838	      /* True means that this variable has been explicitly declared
839		 special (with `defvar' etc), and shouldn't be lexically bound.  */
840	      bool_bf declared_special : 1;
841
842	      /* The symbol's name, as a Lisp string.  */
843	      Lisp_Object name;
844
845	      /* Value of the symbol or Qunbound if unbound.  Which alternative of the
846		 union is used depends on the `redirect' field above.  */
847	      union {
848		Lisp_Object value;
849		struct Lisp_Symbol *alias;
850		struct Lisp_Buffer_Local_Value *blv;
851		lispfwd fwd;
852	      } val;
853
854	      /* Function value of the symbol or Qnil if not fboundp.  */
855	      Lisp_Object function;
856
857	      /* The symbol's property list.  */
858	      Lisp_Object plist;
859
860	      /* Next symbol in obarray bucket, if the symbol is interned.  */
861	      struct Lisp_Symbol *next;
862	    } s;
863	    GCALIGNED_UNION_MEMBER
864	  } u;
865	};
866	static_assert (GCALIGNED (struct Lisp_Symbol));
867
868	/* Declare a Lisp-callable function.  The MAXARGS parameter has the same
869	   meaning as in the DEFUN macro, and is used to construct a prototype.  */
870	/* We can use the same trick as in the DEFUN macro to generate the
871	   appropriate prototype.  */
872	#define EXFUN(fnname, maxargs) \
873	  extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs
874
875	/* Note that the weird token-substitution semantics of ANSI C makes
876	   this work for MANY and UNEVALLED.  */
877	#define DEFUN_ARGS_MANY		(ptrdiff_t, Lisp_Object *)
878	#define DEFUN_ARGS_UNEVALLED	(Lisp_Object)
879	#define DEFUN_ARGS_0	(void)
880	#define DEFUN_ARGS_1	(Lisp_Object)
881	#define DEFUN_ARGS_2	(Lisp_Object, Lisp_Object)
882	#define DEFUN_ARGS_3	(Lisp_Object, Lisp_Object, Lisp_Object)
883	#define DEFUN_ARGS_4	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
884	#define DEFUN_ARGS_5	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
885				 Lisp_Object)
886	#define DEFUN_ARGS_6	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
887				 Lisp_Object, Lisp_Object)
888	#define DEFUN_ARGS_7	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
889				 Lisp_Object, Lisp_Object, Lisp_Object)
890	#define DEFUN_ARGS_8	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
891				 Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
892
893	/* Lisp_Word_tag is big enough for a possibly-shifted tag, to be
894	   added to a pointer value for conversion to a Lisp_Word.  */
895	#if LISP_WORDS_ARE_POINTERS
896	typedef uintptr_t Lisp_Word_tag;
897	#else
898	typedef EMACS_UINT Lisp_Word_tag;
899	#endif
900
901	/* A integer value tagged with TAG, and otherwise all zero.  */
902	#define LISP_WORD_TAG(tag) \
903	  ((Lisp_Word_tag) (tag) << (USE_LSB_TAG ? 0 : VALBITS))
904
905	/* An initializer for a Lisp_Object that contains TAG along with P.
906	   P can be a pointer or an integer.  The result is usable in a static
907	   initializer if TAG and P are both integer constant expressions.  */
908	#define TAG_PTR_INITIALLY(tag, p) \
909	  LISP_INITIALLY ((Lisp_Word) ((uintptr_t) (p) + LISP_WORD_TAG (tag)))
910
911	/* LISPSYM_INITIALLY (Qfoo) is equivalent to Qfoo except it is
912	   designed for use as a (possibly static) initializer.  */
913	#define LISPSYM_INITIALLY(name) \
914	  TAG_PTR_INITIALLY (Lisp_Symbol, (intptr_t) ((i##name) * sizeof *lispsym))
915
916	/* Declare extern constants for Lisp symbols.  These can be helpful
917	   when using a debugger like GDB, on older platforms where the debug
918	   format does not represent C macros.  However, they are unbounded
919	   and would just be asking for trouble if checking pointer bounds.  */
920	#define DEFINE_LISP_SYMBOL(name) \
921	  DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) \
922	  DEFINE_GDB_SYMBOL_END (LISPSYM_INITIALLY (name))
923
924	/* The index of the C-defined Lisp symbol SYM.
925	   This can be used in a static initializer.  */
926	#define SYMBOL_INDEX(sym) i##sym
927
928	/* By default, define macros for Qt, etc., as this leads to a bit
929	   better performance in the core Emacs interpreter.  A plugin can
930	   define DEFINE_NON_NIL_Q_SYMBOL_MACROS to be false, to be portable to
931	   other Emacs instances that assign different values to Qt, etc.  */
932	#ifndef DEFINE_NON_NIL_Q_SYMBOL_MACROS
933	# define DEFINE_NON_NIL_Q_SYMBOL_MACROS true
934	#endif
935
936	/* True if N is a power of 2.  N should be positive.  */
937
938	#define POWER_OF_2(n) (((n) & ((n) - 1)) == 0)
939
940	/* Return X rounded to the next multiple of Y.  Y should be positive,
941	   and Y - 1 + X should not overflow.  Arguments should not have side
942	   effects, as they are evaluated more than once.  Tune for Y being a
943	   power of 2.  */
944
945	#define ROUNDUP(x, y) (POWER_OF_2 (y)					\
946	                       ? ((y) - 1 + (x)) & ~ ((y) - 1)			\
947	                       : ((y) - 1 + (x)) - ((y) - 1 + (x)) % (y))
948
949	#include <globals.h>
950
951	/* Header of vector-like objects.  This documents the layout constraints on
952	   vectors and pseudovectors (objects of PVEC_xxx subtype).  It also prevents
953	   compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR
954	   and PSEUDOVECTORP cast their pointers to struct vectorlike_header *,
955	   because when two such pointers potentially alias, a compiler won't
956	   incorrectly reorder loads and stores to their size fields.  See
957	   Bug#8546.   */
958	struct vectorlike_header
959	  {
960	    /* The `size' header word, W bits wide, has one of two forms
961	       discriminated by the second-highest bit (PSEUDOVECTOR_FLAG):
962
963	         1   1                    W-2
964	       +---+---+-------------------------------------+
965	       | M | 0 |                 SIZE                |  vector
966	       +---+---+-------------------------------------+
967
968	         1   1    W-32      6       12         12
969	       +---+---+--------+------+----------+----------+
970	       | M | 1 | unused | TYPE | RESTSIZE | LISPSIZE |  pseudovector
971	       +---+---+--------+------+----------+----------+
972
973	       M (ARRAY_MARK_FLAG) holds the GC mark bit.
974
975	       SIZE     is the length (number of slots) of a regular Lisp vector,
976	                and the object layout is struct Lisp_Vector.
977
978	       TYPE     is the pseudovector subtype (enum pvec_type).
979
980	       LISPSIZE is the number of Lisp_Object fields at the beginning of the
981	                object (after the header).  These are always traced by the GC.
982
983	       RESTSIZE is the number of fields (in word_size units) following.
984	                These are not automatically traced by the GC.
985	                For PVEC_BOOL and statically allocated PVEC_SUBR, RESTSIZE is 0.
986	                (The block size for PVEC_BOOL is computed from its own size
987	                field, to avoid being restricted by the 12-bit RESTSIZE field.)
988	    */
989	    GC_HEADER
990	    ptrdiff_t size;
991	  };
992
993	struct Lisp_Symbol_With_Pos
994	{
995	  struct vectorlike_header header;
996	  Lisp_Object sym;              /* A symbol */
997	  Lisp_Object pos;              /* A fixnum */
998	} GCALIGNED_STRUCT;
999
1000	/* In the size word of a vector, this bit means the vector has been marked.  */
1001
1002	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG)
1003	# define ARRAY_MARK_FLAG PTRDIFF_MIN
1004	DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG)
1005
1006	/* In the size word of a struct Lisp_Vector, this bit means it's really
1007	   some other vector-like object.  */
1008	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG)
1009	# define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2)
1010	DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
1011
1012	/* In a pseudovector, the size field actually contains a word with one
1013	   PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
1014	   with PVEC_TYPE_MASK to indicate the actual type.  */
1015	enum pvec_type
1016	{
1017	  PVEC_NORMAL_VECTOR,	/* Should be first, for sxhash_obj.  */
1018	  PVEC_FREE,
1019	  PVEC_BIGNUM,
1020	  PVEC_MARKER,
1021	  PVEC_OVERLAY,
1022	  PVEC_FINALIZER,
1023	  PVEC_SYMBOL_WITH_POS,
1024	  PVEC_MISC_PTR,
1025	  PVEC_USER_PTR,
1026	  PVEC_PROCESS,
1027	  PVEC_FRAME,
1028	  PVEC_WINDOW,
1029	  PVEC_BOOL_VECTOR,
1030	  PVEC_BUFFER,
1031	  PVEC_HASH_TABLE,
1032	#ifdef HAVE_MPS
1033	  PVEC_WEAK_HASH_TABLE,
1034	#endif
1035	  PVEC_OBARRAY,
1036	  PVEC_TERMINAL,
1037	  PVEC_WINDOW_CONFIGURATION,
1038	  PVEC_SUBR,
1039	  PVEC_OTHER,            /* Should never be visible to Elisp code.  */
1040	  PVEC_XWIDGET,
1041	  PVEC_XWIDGET_VIEW,
1042	  PVEC_THREAD,
1043	  PVEC_MUTEX,
1044	  PVEC_CONDVAR,
1045	  PVEC_MODULE_FUNCTION,
1046	  PVEC_MODULE_GLOBAL_REFERENCE,
1047	  PVEC_NATIVE_COMP_UNIT,
1048	  PVEC_TS_PARSER,
1049	  PVEC_TS_NODE,
1050	  PVEC_TS_COMPILED_QUERY,
1051	  PVEC_SQLITE,
1052
1053	  /* These should be last, for internal_equal and sxhash_obj.  */
1054	  PVEC_CLOSURE,
1055	  PVEC_CHAR_TABLE,
1056	  PVEC_SUB_CHAR_TABLE,
1057	  PVEC_RECORD,
1058	  PVEC_FONT,
1059	  PVEC_TAG_MAX = PVEC_FONT  /* Keep this equal to the highest member.  */
1060	};
1061
1062	enum More_Lisp_Bits
1063	  {
1064	    /* For convenience, we also store the number of elements in these bits.
1065	       Note that this size is not necessarily the memory-footprint size, but
1066	       only the number of Lisp_Object fields (that need to be traced by GC).
1067	       The distinction is used, e.g., by Lisp_Process, which places extra
1068	       non-Lisp_Object fields at the end of the structure.  */
1069	    PSEUDOVECTOR_SIZE_BITS = 12,
1070	    PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1,
1071
1072	    /* To calculate the memory footprint of the pseudovector, it's useful
1073	       to store the size of non-Lisp area in word_size units here.  */
1074	    PSEUDOVECTOR_REST_BITS = 12,
1075	    PSEUDOVECTOR_REST_MASK = (((1 << PSEUDOVECTOR_REST_BITS) - 1)
1076				      << PSEUDOVECTOR_SIZE_BITS),
1077
1078	    /* Used to extract pseudovector subtype information.  */
1079	    PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS,
1080	    PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS
1081	  };
1082	^L
1083	/* These functions extract various sorts of values from a Lisp_Object.
1084	   For example, if tem is a Lisp_Object whose type is Lisp_Cons,
1085	   XCONS (tem) is the struct Lisp_Cons * pointing to the memory for
1086	   that cons.  */
1087
1088	/* Largest and smallest representable fixnum values.  These are the C
1089	   values.  They are macros for use in #if and static initializers.  */
1090	#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
1091	#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
1092	^L
1093	INLINE bool
1094	PSEUDOVECTORP (Lisp_Object a, int code)
1095	{
1096	  return (lisp_h_VECTORLIKEP (a)
1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577ac9c <+9292>:	test   $0x7,%al
   0x000055555577ac9e <+9294>:	jne    0x5555555b28d6 <read_char-1859450>

1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x000055555577aca4 <+9300>:	movabs $0x400000003f000000,%rax

1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577acae <+9310>:	lea    -0x5(%rdi),%rdx

1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x000055555577acb2 <+9314>:	and    0x3(%rdi),%rax
   0x000055555577acb6 <+9318>:	jmp    0x55555577997b <read_char+4395>

1239	}
1240
1241	INLINE Lisp_Object
1242	make_ufixnum (EMACS_INT n)
1243	{
1244	  eassert (0 <= n && n <= INTMASK);
1245	  return lisp_h_make_fixnum_wrap (n);
1246	}
1247
1248	#else /* ! USE_LSB_TAG */
1249
1250	/* Although compiled only if ! USE_LSB_TAG, the following functions
1251	   also work when USE_LSB_TAG; this is to aid future maintenance when
1252	   the lisp_h_* macros are eventually removed.  */
1253
1254	/* Make a fixnum representing the value of the low order bits of N.  */
1255	INLINE Lisp_Object
1256	make_fixnum (EMACS_INT n)
1257	{
1258	  eassert (! FIXNUM_OVERFLOW_P (n));
1259	  EMACS_INT int0 = Lisp_Int0;
1260	  if (USE_LSB_TAG)
1261	    {
1262	      EMACS_UINT u = n;
1263	      n = u << INTTYPEBITS;
1264	      n += int0;
1265	    }
1266	  else
1267	    {
1268	      n &= INTMASK;
1269	      n += (int0 << VALBITS);
1270	    }
1271	  return XIL (n);
1272	}
1273
1274	/* Extract A's value as a signed integer.  Unlike XFIXNUM, this works
1275	   on any Lisp object, although the resulting integer is useful only
1276	   for things like hashing when A is not a fixnum.  */
1277	INLINE EMACS_INT
1278	XFIXNUM_RAW (Lisp_Object a)
1279	{
1280	  EMACS_INT i = XLI (a);
1281	  if (! USE_LSB_TAG)
1282	    {
1283	      EMACS_UINT u = i;
1284	      i = u << INTTYPEBITS;
1285	    }
1286	  return i >> INTTYPEBITS;
1287	}
1288
1289	INLINE Lisp_Object
1290	make_ufixnum (EMACS_INT n)
1291	{
1292	  eassert (0 <= n && n <= INTMASK);
1293	  EMACS_INT int0 = Lisp_Int0;
1294	  if (USE_LSB_TAG)
1295	    {
1296	      EMACS_UINT u = n;
1297	      n = u << INTTYPEBITS;
1298	      n += int0;
1299	    }
1300	  else
1301	    n += int0 << VALBITS;
1302	  return XIL (n);
1303	}
1304
1305	#endif /* ! USE_LSB_TAG */
1306
1307	INLINE bool
1308	(FIXNUMP) (Lisp_Object x)
1309	{
1310	  return lisp_h_FIXNUMP (x);
   0x000055555577acbb <+9323>:	lea    -0x2(%r14),%eax
   0x000055555577acbf <+9327>:	mov    -0x508(%rbp),%r15
   0x000055555577acc6 <+9334>:	and    $0x3,%eax

./src/keyboard.c:
2362	  if (noninteractive && FIXNUMP (c) && XFIXNUM (c) < 0)
   0x000055555577acc9 <+9337>:	cmpb   $0x0,0x34b3c6(%rip)        # 0x555555ac6096 <noninteractive>

./src/lisp.h:
1310	  return lisp_h_FIXNUMP (x);
   0x000055555577acd0 <+9344>:	mov    %eax,%edx

./src/keyboard.c:
2362	  if (noninteractive && FIXNUMP (c) && XFIXNUM (c) < 0)
   0x000055555577acd2 <+9346>:	jne    0x55555577b416 <read_char+11206>

2363	    Fkill_emacs (make_fixnum (1), Qnil);
2364
2365	  if (FIXNUMP (c))
   0x000055555577acd8 <+9352>:	movzbl 0x3a16a1(%rip),%eax        # 0x555555b1c380 <suppress_checking>
   0x000055555577acdf <+9359>:	test   %edx,%edx
   0x000055555577ace1 <+9361>:	jne    0x555555779acc <read_char+4732>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577ace7 <+9367>:	sar    $0x2,%r14

./src/keyboard.c:
2368	      if ((extra_keyboard_modifiers & CHAR_CTL)
   0x000055555577aceb <+9371>:	mov    0x3a673e(%rip),%rax        # 0x555555b21430 <globals+4080>
   0x000055555577acf2 <+9378>:	test   $0x4000000,%eax
   0x000055555577acf7 <+9383>:	jne    0x55555577b9c0 <read_char+12656>

2369		  || ((extra_keyboard_modifiers & 0177) < ' '
   0x000055555577acfd <+9389>:	test   $0x60,%al
   0x000055555577acff <+9391>:	jne    0x55555577ad09 <read_char+9401>

2370		      && (extra_keyboard_modifiers & 0177) != 0))
   0x000055555577ad01 <+9393>:	test   $0x7f,%al
   0x000055555577ad03 <+9395>:	jne    0x55555577b9c0 <read_char+12656>

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x000055555577ad09 <+9401>:	cmpb   $0x0,0x3a1670(%rip)        # 0x555555b1c380 <suppress_checking>
   0x000055555577ad10 <+9408>:	je     0x55555577ba10 <read_char+12736>

746	  return lisp_h_XIL (i);
   0x000055555577ad16 <+9414>:	and    $0xfffffffffbff0080,%rax

./src/keyboard.c:
2376	      XSETINT (c, XFIXNUM (c) | (extra_keyboard_modifiers & ~0xff7f & ~CHAR_CTL));
   0x000055555577ad1c <+9420>:	mov    0x334805(%rip),%rdx        # 0x555555aaf528 <selected_frame>
   0x000055555577ad23 <+9427>:	or     %r14,%rax

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577ad26 <+9430>:	lea    0x2(,%rax,4),%r14

./src/keyboard.c:
2409	      struct frame *frame = XFRAME (selected_frame);
   0x000055555577ad2e <+9438>:	jmp    0x55555577a7e6 <read_char+8086>

./src/lisp.h:
1381	  Lisp_Object a = TAG_PTR_INITIALLY (type, ptr);
   0x000055555577ad33 <+9443>:	lea    0x5(%rbx),%rax

1382	  eassert (TAGGEDP (a, type) && XUNTAG (a, type, char) == ptr);
   0x000055555577ad37 <+9447>:	cmpb   $0x0,0x3a1642(%rip)        # 0x555555b1c380 <suppress_checking>

1381	  Lisp_Object a = TAG_PTR_INITIALLY (type, ptr);
   0x000055555577ad3e <+9454>:	mov    %rax,%rdx

1382	  eassert (TAGGEDP (a, type) && XUNTAG (a, type, char) == ptr);
   0x000055555577ad41 <+9457>:	jne    0x55555577a08c <read_char+6204>

774	  return lisp_h_TAGGEDP (a, tag);
   0x000055555577ad47 <+9463>:	sub    $0x5,%eax

1382	  eassert (TAGGEDP (a, type) && XUNTAG (a, type, char) == ptr);
   0x000055555577ad4a <+9466>:	test   $0x7,%al
   0x000055555577ad4c <+9468>:	jne    0x5555555b27d9 <read_char-1859703>

1383	  return a;
   0x000055555577ad52 <+9474>:	movabs $0x400000003f000000,%rax
   0x000055555577ad5c <+9484>:	and    0x8(%rbx),%rax
   0x000055555577ad60 <+9488>:	movabs $0x400000000a000000,%rcx
   0x000055555577ad6a <+9498>:	cmp    %rcx,%rax
   0x000055555577ad6d <+9501>:	je     0x55555577a08c <read_char+6204>
   0x000055555577ad73 <+9507>:	jmp    0x5555555b27c1 <read_char-1859727>
   0x000055555577ad78 <+9512>:	nopl   0x0(%rax,%rax,1)

./src/keyboard.c:
3033	      if (NILP (c) && end_time
   0x000055555577ad80 <+9520>:	cmpq   $0x0,-0x4a8(%rbp)
   0x000055555577ad88 <+9528>:	je     0x55555577b4a0 <read_char+11344>

3034		  && timespec_cmp (*end_time, current_timespec ()) <= 0)
   0x000055555577ad8e <+9534>:	call   0x555555936cd0 <current_timespec>

../lib/timespec.h:
66	  return 2 * _GL_CMP (a.tv_sec, b.tv_sec) + _GL_CMP (a.tv_nsec, b.tv_nsec);
   0x000055555577ad93 <+9539>:	mov    -0x4a8(%rbp),%rbx

./src/keyboard.c:
3034		  && timespec_cmp (*end_time, current_timespec ()) <= 0)
   0x000055555577ad9a <+9546>:	mov    %rax,%rcx
   0x000055555577ad9d <+9549>:	mov    %rdx,%rax

../lib/timespec.h:
66	  return 2 * _GL_CMP (a.tv_sec, b.tv_sec) + _GL_CMP (a.tv_nsec, b.tv_nsec);
   0x000055555577ada0 <+9552>:	xor    %edx,%edx
   0x000055555577ada2 <+9554>:	cmp    (%rbx),%rcx
   0x000055555577ada5 <+9557>:	setg   %cl
   0x000055555577ada8 <+9560>:	setl   %dl
   0x000055555577adab <+9563>:	movzbl %cl,%ecx
   0x000055555577adae <+9566>:	sub    %ecx,%edx
   0x000055555577adb0 <+9568>:	cmp    %rax,0x8(%rbx)
   0x000055555577adb4 <+9572>:	setg   %al
   0x000055555577adb7 <+9575>:	setl   %cl
   0x000055555577adba <+9578>:	movzbl %al,%eax
   0x000055555577adbd <+9581>:	movzbl %cl,%ecx
   0x000055555577adc0 <+9584>:	sub    %ecx,%eax
   0x000055555577adc2 <+9586>:	lea    (%rax,%rdx,2),%eax

./src/keyboard.c:
3034		  && timespec_cmp (*end_time, current_timespec ()) <= 0)
   0x000055555577adc5 <+9589>:	test   %eax,%eax
   0x000055555577adc7 <+9591>:	jle    0x555555778b30 <read_char+736>

3048		}
3049
3050	      c_volatile = c;
   0x000055555577adcd <+9597>:	movq   $0x0,-0x470(%rbp)

3051	  }
3052
3053	 non_reread:
3054
3055	  if (!end_time)
   0x000055555577add8 <+9608>:	jmp    0x555555778e6e <read_char+1566>

4316		    Vlast_event_device = ((event->ie.kind == ASCII_KEYSTROKE_EVENT
   0x000055555577addd <+9613>:	mov    0x38b7b4(%rip),%rax        # 0x555555b06598 <virtual_core_pointer_name>
   0x000055555577ade4 <+9620>:	mov    %rax,0x3a5ca5(%rip)        # 0x555555b20a90 <globals+1616>
   0x000055555577adeb <+9627>:	jmp    0x55555577aacf <read_char+8831>

./src/lisp.h:
1184	  return a;
   0x000055555577adf0 <+9632>:	mov    %r14,%rdi
   0x000055555577adf3 <+9635>:	call   0x555555763090 <XCAR>

./src/keyboard.c:
3000		      && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qswitch_frame))
   0x000055555577adf8 <+9640>:	mov    $0x9338,%esi
   0x000055555577adfd <+9645>:	mov    %rax,%rdi
   0x000055555577ae00 <+9648>:	call   0x555555838da0 <Fget>
   0x000055555577ae05 <+9653>:	mov    $0x14858,%esi
   0x000055555577ae0a <+9658>:	mov    %rax,%rdi
   0x000055555577ae0d <+9661>:	call   0x555555764470 <EQ>
   0x000055555577ae12 <+9666>:	test   %al,%al
   0x000055555577ae14 <+9668>:	jne    0x55555577bfb8 <read_char+14184>

3002		  Vlast_event_frame = internal_last_event_frame;
   0x000055555577ae1a <+9674>:	mov    0x38b307(%rip),%rax        # 0x555555b06128 <internal_last_event_frame>
   0x000055555577ae21 <+9681>:	mov    %rax,0x3a5c70(%rip)        # 0x555555b20a98 <globals+1624>

3003		}
3004	    }
3005
3006	  /* If current_kboard's side queue is empty check the other kboards.
3007	     If one of them has data that we have not yet seen here,
3008	     switch to it and process the data waiting for it.
3009
3010	     Note: if the events queued up for another kboard
3011	     have already been seen here, and therefore are not a complete command,
3012	     the kbd_queue_has_data field is 0, so we skip that kboard here.
3013	     That's to avoid an infinite loop switching between kboards here.  */
3014	  if (NILP (c) && !single_kboard)
   0x000055555577ae28 <+9688>:	jmp    0x555555778e33 <read_char+1507>

2997		    current_kboard->kbd_queue_has_data = false;
   0x000055555577ae2d <+9693>:	movb   $0x0,0xb8(%rbx)
   0x000055555577ae34 <+9700>:	jmp    0x55555577941c <read_char+3020>

2409	      struct frame *frame = XFRAME (selected_frame);
   0x000055555577ae39 <+9705>:	mov    -0x508(%rbp),%r15
   0x000055555577ae40 <+9712>:	movzbl 0x3a1539(%rip),%eax        # 0x555555b1c380 <suppress_checking>

2327	    return c;
   0x000055555577ae47 <+9719>:	xor    %r14d,%r14d
   0x000055555577ae4a <+9722>:	jmp    0x555555779acc <read_char+4732>

3676		return 1;
3677	    }
3678	  else
3679	    {
3680	      KBOARD *kb;
3681	      for (kb = all_kboards; kb; kb = kb->next_kboard)
   0x000055555577ae4f <+9727>:	mov    0x38b7ea(%rip),%rdx        # 0x555555b06640 <all_kboards>
   0x000055555577ae56 <+9734>:	test   %rdx,%rdx
   0x000055555577ae59 <+9737>:	jne    0x55555577ae6c <read_char+9756>
   0x000055555577ae5b <+9739>:	jmp    0x555555779a33 <read_char+4579>
   0x000055555577ae60 <+9744>:	mov    (%rdx),%rdx
   0x000055555577ae63 <+9747>:	test   %rdx,%rdx
   0x000055555577ae66 <+9750>:	je     0x555555779a33 <read_char+4579>

3682		if (kb->kbd_queue_has_data)
   0x000055555577ae6c <+9756>:	movzbl 0xb8(%rdx),%eax
   0x000055555577ae73 <+9763>:	test   %al,%al
   0x000055555577ae75 <+9765>:	je     0x55555577ae60 <read_char+9744>
   0x000055555577ae77 <+9767>:	jmp    0x555555779a33 <read_char+4579>

4498		      && !EQ (frame, selected_frame))
   0x000055555577ae7c <+9772>:	mov    0x3346a5(%rip),%rsi        # 0x555555aaf528 <selected_frame>
   0x000055555577ae83 <+9779>:	mov    %rdx,%rdi
   0x000055555577ae86 <+9782>:	mov    %rdx,-0x598(%rbp)
   0x000055555577ae8d <+9789>:	call   0x555555764470 <EQ>
   0x000055555577ae92 <+9794>:	mov    -0x598(%rbp),%rdx
   0x000055555577ae99 <+9801>:	test   %al,%al
   0x000055555577ae9b <+9803>:	jne    0x55555577a0b1 <read_char+6241>

./src/lisp.h:
1184	  return a;
   0x000055555577aea1 <+9809>:	mov    %rdx,%rsi
   0x000055555577aea4 <+9812>:	mov    $0x14858,%edi
   0x000055555577aea9 <+9817>:	mov    %rdx,-0x670(%rbp)
   0x000055555577aeb0 <+9824>:	call   0x5555557ef5d0 <list2>

./src/keyboard.c:
4500		  internal_last_event_frame = frame;
   0x000055555577aeb5 <+9829>:	mov    -0x670(%rbp),%rdx

4501		}
4502
4503	      /* If we didn't decide to make a switch-frame event, go ahead and
4504		 return a mouse-motion event.  */
4505	      if (!NILP (x) && NILP (obj))
   0x000055555577aebc <+9836>:	cmpq   $0x0,-0x458(%rbp)
   0x000055555577aec4 <+9844>:	mov    %rax,%rcx

4500		  internal_last_event_frame = frame;
   0x000055555577aec7 <+9847>:	mov    %rdx,0x38b25a(%rip)        # 0x555555b06128 <internal_last_event_frame>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577aece <+9854>:	je     0x55555577a16d <read_char+6429>

./src/keyboard.c:
4505	      if (!NILP (x) && NILP (obj))
   0x000055555577aed4 <+9860>:	test   %rax,%rax
   0x000055555577aed7 <+9863>:	je     0x55555577c389 <read_char+15161>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577aedd <+9869>:	mov    0x30(%r14),%rax
   0x000055555577aee1 <+9873>:	lea    -0x4(%rax),%edx

./src/keyboard.c:
4511				      : virtual_core_pointer_name);
   0x000055555577aee4 <+9876>:	and    $0x7,%edx
   0x000055555577aee7 <+9879>:	je     0x55555577aef0 <read_char+9888>

4509		Vlast_event_device = (STRINGP (movement_frame->last_mouse_device)
   0x000055555577aee9 <+9881>:	mov    0x38b6a8(%rip),%rax        # 0x555555b06598 <virtual_core_pointer_name>
   0x000055555577aef0 <+9888>:	mov    %rax,0x3a5b99(%rip)        # 0x555555b20a90 <globals+1616>

3621	  if (kbd_fetch_ptr != kbd_store_ptr)
   0x000055555577aef7 <+9895>:	mov    0x34b21a(%rip),%r8        # 0x555555ac6118 <kbd_fetch_ptr>
   0x000055555577aefe <+9902>:	mov    %rcx,%r14
   0x000055555577af01 <+9905>:	mov    0x34b208(%rip),%rdx        # 0x555555ac6110 <kbd_store_ptr>
   0x000055555577af08 <+9912>:	jmp    0x555555779a25 <read_char+4565>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577af0d <+9917>:	sar    $0x2,%rbx

./src/keyboard.c:
3232	      && ' ' <= XFIXNUM (c) && XFIXNUM (c) < 256 && XFIXNUM (c) != 127)
   0x000055555577af11 <+9921>:	lea    -0x20(%rbx),%rax
   0x000055555577af15 <+9925>:	cmp    $0xdf,%rax
   0x000055555577af1b <+9931>:	ja     0x5555557789dd <read_char+397>
   0x000055555577af21 <+9937>:	cmp    $0x7f,%rbx
   0x000055555577af25 <+9941>:	je     0x5555557789dd <read_char+397>

./src/lisp.h:
3986	  return wrap_specpdl_ref ((char *)specpdl_ptr - (char *)specpdl);
   0x000055555577af2b <+9947>:	mov    0x30ca2e(%rip),%rax        # 0x555555a87960 <current_thread>

3912	  return (specpdl_ref){.bytes = bytes};
   0x000055555577af32 <+9954>:	mov    0x38b30f(%rip),%r12        # 0x555555b06248 <this_command_key_count>

./src/keyboard.c:
3241	      struct kboard *saved_ok_to_echo = ok_to_echo_at_next_pause;
   0x000055555577af39 <+9961>:	mov    0x38b6b0(%rip),%r15        # 0x555555b065f0 <ok_to_echo_at_next_pause>

./src/lisp.h:
3986	  return wrap_specpdl_ref ((char *)specpdl_ptr - (char *)specpdl);
   0x000055555577af40 <+9968>:	mov    0x88(%rax),%rdx
   0x000055555577af47 <+9975>:	sub    0x78(%rax),%rdx

./src/keyboard.c:
3240	      bool saved_immediate_echo = current_kboard->immediate_echo;
   0x000055555577af4b <+9979>:	mov    0x38b30e(%rip),%rax        # 0x555555b06260 <current_kboard>

./src/lisp.h:
3986	  return wrap_specpdl_ref ((char *)specpdl_ptr - (char *)specpdl);
   0x000055555577af52 <+9986>:	mov    %rdx,-0x5d0(%rbp)

./src/keyboard.c:
3240	      bool saved_immediate_echo = current_kboard->immediate_echo;
   0x000055555577af59 <+9993>:	movzbl 0xb9(%rax),%ebx

3242	      Lisp_Object saved_echo_string = KVAR (current_kboard, echo_string);
   0x000055555577af60 <+10000>:	mov    0xb0(%rax),%r13

3243	      Lisp_Object saved_echo_prompt = KVAR (current_kboard, echo_prompt);
   0x000055555577af67 <+10007>:	mov    0xc0(%rax),%rax

3240	      bool saved_immediate_echo = current_kboard->immediate_echo;
   0x000055555577af6e <+10014>:	and    $0x1,%ebx

3243	      Lisp_Object saved_echo_prompt = KVAR (current_kboard, echo_prompt);
   0x000055555577af71 <+10017>:	mov    %rax,-0x5c8(%rbp)

3244
3245	      /* Save the this_command_keys status.  */
3246	      key_count = this_command_key_count;
3247	      command_key_start = this_single_command_key_start;
   0x000055555577af78 <+10024>:	mov    0x38b691(%rip),%rax        # 0x555555b06610 <this_single_command_key_start>

3240	      bool saved_immediate_echo = current_kboard->immediate_echo;
   0x000055555577af7f <+10031>:	mov    %bl,-0x585(%rbp)

3244
3245	      /* Save the this_command_keys status.  */
3246	      key_count = this_command_key_count;
3247	      command_key_start = this_single_command_key_start;
   0x000055555577af85 <+10037>:	xor    %ebx,%ebx
   0x000055555577af87 <+10039>:	mov    %rax,-0x5b8(%rbp)

3248
3249	      if (key_count > 0)
   0x000055555577af8e <+10046>:	test   %r12,%r12
   0x000055555577af91 <+10049>:	jle    0x55555577afa2 <read_char+10066>

3250		keys = Fcopy_sequence (this_command_keys);
   0x000055555577af93 <+10051>:	mov    0x38b2b6(%rip),%rdi        # 0x555555b06250 <this_command_keys>
   0x000055555577af9a <+10058>:	call   0x55555582f1e0 <Fcopy_sequence>
   0x000055555577af9f <+10063>:	mov    %rax,%rbx

3251	      else
3252		keys = Qnil;
3253
3254	      /* Clear out this_command_keys.  */
3255	      this_command_key_count = 0;
   0x000055555577afa2 <+10066>:	cmpq   $0x0,0x3345e6(%rip)        # 0x555555aaf590 <echo_area_buffer>
   0x000055555577afaa <+10074>:	movq   $0x0,0x38b293(%rip)        # 0x555555b06248 <this_command_key_count>

3256	      this_single_command_key_start = 0;
   0x000055555577afb5 <+10085>:	movq   $0x0,0x38b650(%rip)        # 0x555555b06610 <this_single_command_key_start>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577afc0 <+10096>:	je     0x55555577afcc <read_char+10108>

1183	  Lisp_Object a = TAG_PTR_INITIALLY (Lisp_Symbol, symoffset);
1184	  return a;
   0x000055555577afc2 <+10098>:	mov    $0x8b90,%edi
   0x000055555577afc7 <+10103>:	call   0x55555576fb10 <safe_run_hooks>

./src/keyboard.c:
3261	      clear_message (1, 0);
   0x000055555577afcc <+10108>:	xor    %esi,%esi
   0x000055555577afce <+10110>:	mov    $0x1,%edi
   0x000055555577afd3 <+10115>:	call   0x55555561dd60 <clear_message>

3262	      echo_truncate (0);
   0x000055555577afd8 <+10120>:	xor    %edi,%edi
   0x000055555577afda <+10122>:	call   0x5555557643d0 <echo_truncate>

3263
3264	      /* If we are not reading a key sequence,
3265		 never use the echo area.  */
3266	      if (!KEYMAPP (map))
   0x000055555577afdf <+10127>:	mov    -0x4b0(%rbp),%rdi
   0x000055555577afe6 <+10134>:	xor    %edx,%edx
   0x000055555577afe8 <+10136>:	xor    %esi,%esi
   0x000055555577afea <+10138>:	call   0x55555578ab50 <get_keymap>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577afef <+10143>:	test   %rax,%rax
   0x000055555577aff2 <+10146>:	je     0x55555577cad0 <read_char+17024>

./src/keyboard.c:
3272	      tem = calln (Vinput_method_function, c);
   0x000055555577aff8 <+10152>:	mov    0x3a5a11(%rip),%rax        # 0x555555b20a10 <globals+1488>
   0x000055555577afff <+10159>:	lea    -0x3e0(%rbp),%rsi
   0x000055555577b006 <+10166>:	mov    $0x2,%edi
   0x000055555577b00b <+10171>:	mov    %r14,-0x3d8(%rbp)
   0x000055555577b012 <+10178>:	mov    %rax,-0x3e0(%rbp)
   0x000055555577b019 <+10185>:	call   0x555555820950 <Ffuncall>

3273
3274	      tem = unbind_to (count, tem);
   0x000055555577b01e <+10190>:	mov    -0x5d0(%rbp),%rdi
   0x000055555577b025 <+10197>:	mov    %rax,%rsi
   0x000055555577b028 <+10200>:	call   0x5555558204b0 <unbind_to>

3275
3276	      /* Restore the saved echoing state
3277		 and this_command_keys state.  */
3278	      this_command_key_count = key_count;
   0x000055555577b02d <+10205>:	mov    %r12,0x38b214(%rip)        # 0x555555b06248 <this_command_key_count>

3274	      tem = unbind_to (count, tem);
   0x000055555577b034 <+10212>:	mov    %rax,%rdx

3279	      this_single_command_key_start = command_key_start;
   0x000055555577b037 <+10215>:	mov    -0x5b8(%rbp),%rax
   0x000055555577b03e <+10222>:	mov    %rax,0x38b5cb(%rip)        # 0x555555b06610 <this_single_command_key_start>

3280	      if (key_count > 0)
   0x000055555577b045 <+10229>:	test   %r12,%r12
   0x000055555577b048 <+10232>:	jle    0x55555577b051 <read_char+10241>

3281		this_command_keys = keys;
   0x000055555577b04a <+10234>:	mov    %rbx,0x38b1ff(%rip)        # 0x555555b06250 <this_command_keys>

672	  current_kboard->immediate_echo = false;
   0x000055555577b051 <+10241>:	mov    0x38b208(%rip),%rax        # 0x555555b06260 <current_kboard>

450	  kb->echo_prompt_ = val;
   0x000055555577b058 <+10248>:	mov    -0x5c8(%rbp),%rbx

676	  echo_kboard = NULL;
   0x000055555577b05f <+10255>:	movq   $0x0,0x38b0fe(%rip)        # 0x555555b06168 <echo_kboard>

677	  echo_message_buffer = Qnil;
   0x000055555577b06a <+10266>:	movq   $0x0,0x38b0eb(%rip)        # 0x555555b06160 <echo_message_buffer>

672	  current_kboard->immediate_echo = false;
   0x000055555577b075 <+10277>:	andb   $0xfe,0xb9(%rax)

3282
3283	      cancel_echoing ();
3284	      ok_to_echo_at_next_pause = saved_ok_to_echo;
   0x000055555577b07c <+10284>:	cmpb   $0x0,-0x585(%rbp)
   0x000055555577b083 <+10291>:	mov    %r15,0x38b566(%rip)        # 0x555555b065f0 <ok_to_echo_at_next_pause>

445	  kb->echo_string_ = val;
   0x000055555577b08a <+10298>:	mov    %r13,0xb0(%rax)

446	}
447	static void
448	kset_echo_prompt (struct kboard *kb, Lisp_Object val)
449	{
450	  kb->echo_prompt_ = val;
   0x000055555577b091 <+10305>:	mov    %rbx,0xc0(%rax)

3285	      kset_echo_string (current_kboard, saved_echo_string);
3286	      kset_echo_prompt (current_kboard, saved_echo_prompt);
3287	      if (saved_immediate_echo)
   0x000055555577b098 <+10312>:	jne    0x55555577c8a9 <read_char+16473>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577b09e <+10318>:	lea    -0x3(%rdx),%eax

./src/keyboard.c:
3291	      if (! CONSP (tem))
   0x000055555577b0a1 <+10321>:	test   $0x7,%al
   0x000055555577b0a3 <+10323>:	je     0x55555577c869 <read_char+16409>

3292		{
3293		  /* Bring back the previous message, if any.  */
3294		  if (! NILP (previous_echo_area_message))
   0x000055555577b0a9 <+10329>:	mov    -0x480(%rbp),%rax
   0x000055555577b0b0 <+10336>:	test   %rax,%rax
   0x000055555577b0b3 <+10339>:	je     0x5555557788da <read_char+138>

3295		    message_with_string ("%s", previous_echo_area_message, 0);
   0x000055555577b0b9 <+10345>:	mov    -0x480(%rbp),%rsi
   0x000055555577b0c0 <+10352>:	xor    %edx,%edx
   0x000055555577b0c2 <+10354>:	lea    0x23a09b(%rip),%rdi        # 0x5555559b5164
   0x000055555577b0c9 <+10361>:	call   0x55555564eab0 <message_with_string>
   0x000055555577b0ce <+10366>:	jmp    0x5555557788da <read_char+138>
   0x000055555577b0d3 <+10371>:	nopl   0x0(%rax,%rax,1)

2970		c = XCDR (c);
   0x000055555577b0d8 <+10376>:	call   0x5555557630d0 <XCDR>
   0x000055555577b0dd <+10381>:	mov    %rax,%r14
   0x000055555577b0e0 <+10384>:	jmp    0x5555557793c4 <read_char+2932>

./src/lisp.h:
774	  return lisp_h_TAGGEDP (a, tag);
   0x000055555577b0e5 <+10389>:	lea    -0x5(%rax),%edx

775	}
776
777	INLINE void
778	(CHECK_TYPE) (int ok, Lisp_Object predicate, Lisp_Object x)
779	{
780	  lisp_h_CHECK_TYPE (ok, predicate, x);
781	}
782
783	/* Extract A's pointer value, assuming A's Lisp type is TYPE and the
784	   extracted pointer's type is CTYPE *.  When !USE_LSB_TAG this simply
785	   extracts A's low-order bits, as (uintptr_t) LISP_WORD_TAG (type) is
786	   always zero then.  */
787	#define XUNTAG(a, type, ctype) \
788	  ((ctype *) ((uintptr_t) XLP (a) - (uintptr_t) LISP_WORD_TAG (type)))
789
790	/* A forwarding pointer to a value.  It uses a generic pointer to
791	   avoid alignment bugs that could occur if it used a pointer to a
792	   union of the possible values (struct Lisp_Objfwd, struct
793	   Lisp_Intfwd, etc.).  The pointer is packaged inside a struct to
794	   help static checking.  */
795	typedef const struct Lisp_Fwd *lispfwd;
796	^L
797	/* Interned state of a symbol.  */
798
799	enum symbol_interned
800	{
801	  SYMBOL_UNINTERNED,		      /* not interned anywhere */
802	  SYMBOL_INTERNED,		      /* interned but not in initial obarray */
803	  SYMBOL_INTERNED_IN_INITIAL_OBARRAY  /* interned in initial obarray */
804	};
805
806	enum symbol_redirect
807	{
808	  SYMBOL_PLAINVAL,   /* plain var, value is in the `value' field */
809	  SYMBOL_VARALIAS,   /* var alias, value is really in the `alias' symbol */
810	  SYMBOL_LOCALIZED,  /* localized var, value is in the `blv' object */
811	  SYMBOL_FORWARDED   /* forwarding var, value is in `forward' */
812	};
813
814	enum symbol_trapped_write
815	{
816	  SYMBOL_UNTRAPPED_WRITE,  /* normal case, just set the value */
817	  SYMBOL_NOWRITE,          /* constant, cannot set, e.g. nil, t, :keyword */
818	  SYMBOL_TRAPPED_WRITE     /* trap the write, call watcher functions */
819	};
820
821	struct Lisp_Symbol
822	{
823	  GC_HEADER
824	  union
825	  {
826	    struct
827	    {
828	      bool_bf gcmarkbit : 1;
829
830	      /* Indicates where the value can be found.  */
831	      ENUM_BF (symbol_redirect) redirect : 2;
832
833	      ENUM_BF (symbol_trapped_write) trapped_write : 2;
834
835	      /* Interned state of the symbol.  */
836	      ENUM_BF (symbol_interned) interned : 2;
837
838	      /* True means that this variable has been explicitly declared
839		 special (with `defvar' etc), and shouldn't be lexically bound.  */
840	      bool_bf declared_special : 1;
841
842	      /* The symbol's name, as a Lisp string.  */
843	      Lisp_Object name;
844
845	      /* Value of the symbol or Qunbound if unbound.  Which alternative of the
846		 union is used depends on the `redirect' field above.  */
847	      union {
848		Lisp_Object value;
849		struct Lisp_Symbol *alias;
850		struct Lisp_Buffer_Local_Value *blv;
851		lispfwd fwd;
852	      } val;
853
854	      /* Function value of the symbol or Qnil if not fboundp.  */
855	      Lisp_Object function;
856
857	      /* The symbol's property list.  */
858	      Lisp_Object plist;
859
860	      /* Next symbol in obarray bucket, if the symbol is interned.  */
861	      struct Lisp_Symbol *next;
862	    } s;
863	    GCALIGNED_UNION_MEMBER
864	  } u;
865	};
866	static_assert (GCALIGNED (struct Lisp_Symbol));
867
868	/* Declare a Lisp-callable function.  The MAXARGS parameter has the same
869	   meaning as in the DEFUN macro, and is used to construct a prototype.  */
870	/* We can use the same trick as in the DEFUN macro to generate the
871	   appropriate prototype.  */
872	#define EXFUN(fnname, maxargs) \
873	  extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs
874
875	/* Note that the weird token-substitution semantics of ANSI C makes
876	   this work for MANY and UNEVALLED.  */
877	#define DEFUN_ARGS_MANY		(ptrdiff_t, Lisp_Object *)
878	#define DEFUN_ARGS_UNEVALLED	(Lisp_Object)
879	#define DEFUN_ARGS_0	(void)
880	#define DEFUN_ARGS_1	(Lisp_Object)
881	#define DEFUN_ARGS_2	(Lisp_Object, Lisp_Object)
882	#define DEFUN_ARGS_3	(Lisp_Object, Lisp_Object, Lisp_Object)
883	#define DEFUN_ARGS_4	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
884	#define DEFUN_ARGS_5	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
885				 Lisp_Object)
886	#define DEFUN_ARGS_6	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
887				 Lisp_Object, Lisp_Object)
888	#define DEFUN_ARGS_7	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
889				 Lisp_Object, Lisp_Object, Lisp_Object)
890	#define DEFUN_ARGS_8	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
891				 Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
892
893	/* Lisp_Word_tag is big enough for a possibly-shifted tag, to be
894	   added to a pointer value for conversion to a Lisp_Word.  */
895	#if LISP_WORDS_ARE_POINTERS
896	typedef uintptr_t Lisp_Word_tag;
897	#else
898	typedef EMACS_UINT Lisp_Word_tag;
899	#endif
900
901	/* A integer value tagged with TAG, and otherwise all zero.  */
902	#define LISP_WORD_TAG(tag) \
903	  ((Lisp_Word_tag) (tag) << (USE_LSB_TAG ? 0 : VALBITS))
904
905	/* An initializer for a Lisp_Object that contains TAG along with P.
906	   P can be a pointer or an integer.  The result is usable in a static
907	   initializer if TAG and P are both integer constant expressions.  */
908	#define TAG_PTR_INITIALLY(tag, p) \
909	  LISP_INITIALLY ((Lisp_Word) ((uintptr_t) (p) + LISP_WORD_TAG (tag)))
910
911	/* LISPSYM_INITIALLY (Qfoo) is equivalent to Qfoo except it is
912	   designed for use as a (possibly static) initializer.  */
913	#define LISPSYM_INITIALLY(name) \
914	  TAG_PTR_INITIALLY (Lisp_Symbol, (intptr_t) ((i##name) * sizeof *lispsym))
915
916	/* Declare extern constants for Lisp symbols.  These can be helpful
917	   when using a debugger like GDB, on older platforms where the debug
918	   format does not represent C macros.  However, they are unbounded
919	   and would just be asking for trouble if checking pointer bounds.  */
920	#define DEFINE_LISP_SYMBOL(name) \
921	  DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) \
922	  DEFINE_GDB_SYMBOL_END (LISPSYM_INITIALLY (name))
923
924	/* The index of the C-defined Lisp symbol SYM.
925	   This can be used in a static initializer.  */
926	#define SYMBOL_INDEX(sym) i##sym
927
928	/* By default, define macros for Qt, etc., as this leads to a bit
929	   better performance in the core Emacs interpreter.  A plugin can
930	   define DEFINE_NON_NIL_Q_SYMBOL_MACROS to be false, to be portable to
931	   other Emacs instances that assign different values to Qt, etc.  */
932	#ifndef DEFINE_NON_NIL_Q_SYMBOL_MACROS
933	# define DEFINE_NON_NIL_Q_SYMBOL_MACROS true
934	#endif
935
936	/* True if N is a power of 2.  N should be positive.  */
937
938	#define POWER_OF_2(n) (((n) & ((n) - 1)) == 0)
939
940	/* Return X rounded to the next multiple of Y.  Y should be positive,
941	   and Y - 1 + X should not overflow.  Arguments should not have side
942	   effects, as they are evaluated more than once.  Tune for Y being a
943	   power of 2.  */
944
945	#define ROUNDUP(x, y) (POWER_OF_2 (y)					\
946	                       ? ((y) - 1 + (x)) & ~ ((y) - 1)			\
947	                       : ((y) - 1 + (x)) - ((y) - 1 + (x)) % (y))
948
949	#include <globals.h>
950
951	/* Header of vector-like objects.  This documents the layout constraints on
952	   vectors and pseudovectors (objects of PVEC_xxx subtype).  It also prevents
953	   compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR
954	   and PSEUDOVECTORP cast their pointers to struct vectorlike_header *,
955	   because when two such pointers potentially alias, a compiler won't
956	   incorrectly reorder loads and stores to their size fields.  See
957	   Bug#8546.   */
958	struct vectorlike_header
959	  {
960	    /* The `size' header word, W bits wide, has one of two forms
961	       discriminated by the second-highest bit (PSEUDOVECTOR_FLAG):
962
963	         1   1                    W-2
964	       +---+---+-------------------------------------+
965	       | M | 0 |                 SIZE                |  vector
966	       +---+---+-------------------------------------+
967
968	         1   1    W-32      6       12         12
969	       +---+---+--------+------+----------+----------+
970	       | M | 1 | unused | TYPE | RESTSIZE | LISPSIZE |  pseudovector
971	       +---+---+--------+------+----------+----------+
972
973	       M (ARRAY_MARK_FLAG) holds the GC mark bit.
974
975	       SIZE     is the length (number of slots) of a regular Lisp vector,
976	                and the object layout is struct Lisp_Vector.
977
978	       TYPE     is the pseudovector subtype (enum pvec_type).
979
980	       LISPSIZE is the number of Lisp_Object fields at the beginning of the
981	                object (after the header).  These are always traced by the GC.
982
983	       RESTSIZE is the number of fields (in word_size units) following.
984	                These are not automatically traced by the GC.
985	                For PVEC_BOOL and statically allocated PVEC_SUBR, RESTSIZE is 0.
986	                (The block size for PVEC_BOOL is computed from its own size
987	                field, to avoid being restricted by the 12-bit RESTSIZE field.)
988	    */
989	    GC_HEADER
990	    ptrdiff_t size;
991	  };
992
993	struct Lisp_Symbol_With_Pos
994	{
995	  struct vectorlike_header header;
996	  Lisp_Object sym;              /* A symbol */
997	  Lisp_Object pos;              /* A fixnum */
998	} GCALIGNED_STRUCT;
999
1000	/* In the size word of a vector, this bit means the vector has been marked.  */
1001
1002	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG)
1003	# define ARRAY_MARK_FLAG PTRDIFF_MIN
1004	DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG)
1005
1006	/* In the size word of a struct Lisp_Vector, this bit means it's really
1007	   some other vector-like object.  */
1008	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG)
1009	# define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2)
1010	DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
1011
1012	/* In a pseudovector, the size field actually contains a word with one
1013	   PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
1014	   with PVEC_TYPE_MASK to indicate the actual type.  */
1015	enum pvec_type
1016	{
1017	  PVEC_NORMAL_VECTOR,	/* Should be first, for sxhash_obj.  */
1018	  PVEC_FREE,
1019	  PVEC_BIGNUM,
1020	  PVEC_MARKER,
1021	  PVEC_OVERLAY,
1022	  PVEC_FINALIZER,
1023	  PVEC_SYMBOL_WITH_POS,
1024	  PVEC_MISC_PTR,
1025	  PVEC_USER_PTR,
1026	  PVEC_PROCESS,
1027	  PVEC_FRAME,
1028	  PVEC_WINDOW,
1029	  PVEC_BOOL_VECTOR,
1030	  PVEC_BUFFER,
1031	  PVEC_HASH_TABLE,
1032	#ifdef HAVE_MPS
1033	  PVEC_WEAK_HASH_TABLE,
1034	#endif
1035	  PVEC_OBARRAY,
1036	  PVEC_TERMINAL,
1037	  PVEC_WINDOW_CONFIGURATION,
1038	  PVEC_SUBR,
1039	  PVEC_OTHER,            /* Should never be visible to Elisp code.  */
1040	  PVEC_XWIDGET,
1041	  PVEC_XWIDGET_VIEW,
1042	  PVEC_THREAD,
1043	  PVEC_MUTEX,
1044	  PVEC_CONDVAR,
1045	  PVEC_MODULE_FUNCTION,
1046	  PVEC_MODULE_GLOBAL_REFERENCE,
1047	  PVEC_NATIVE_COMP_UNIT,
1048	  PVEC_TS_PARSER,
1049	  PVEC_TS_NODE,
1050	  PVEC_TS_COMPILED_QUERY,
1051	  PVEC_SQLITE,
1052
1053	  /* These should be last, for internal_equal and sxhash_obj.  */
1054	  PVEC_CLOSURE,
1055	  PVEC_CHAR_TABLE,
1056	  PVEC_SUB_CHAR_TABLE,
1057	  PVEC_RECORD,
1058	  PVEC_FONT,
1059	  PVEC_TAG_MAX = PVEC_FONT  /* Keep this equal to the highest member.  */
1060	};
1061
1062	enum More_Lisp_Bits
1063	  {
1064	    /* For convenience, we also store the number of elements in these bits.
1065	       Note that this size is not necessarily the memory-footprint size, but
1066	       only the number of Lisp_Object fields (that need to be traced by GC).
1067	       The distinction is used, e.g., by Lisp_Process, which places extra
1068	       non-Lisp_Object fields at the end of the structure.  */
1069	    PSEUDOVECTOR_SIZE_BITS = 12,
1070	    PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1,
1071
1072	    /* To calculate the memory footprint of the pseudovector, it's useful
1073	       to store the size of non-Lisp area in word_size units here.  */
1074	    PSEUDOVECTOR_REST_BITS = 12,
1075	    PSEUDOVECTOR_REST_MASK = (((1 << PSEUDOVECTOR_REST_BITS) - 1)
1076				      << PSEUDOVECTOR_SIZE_BITS),
1077
1078	    /* Used to extract pseudovector subtype information.  */
1079	    PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS,
1080	    PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS
1081	  };
1082	^L
1083	/* These functions extract various sorts of values from a Lisp_Object.
1084	   For example, if tem is a Lisp_Object whose type is Lisp_Cons,
1085	   XCONS (tem) is the struct Lisp_Cons * pointing to the memory for
1086	   that cons.  */
1087
1088	/* Largest and smallest representable fixnum values.  These are the C
1089	   values.  They are macros for use in #if and static initializers.  */
1090	#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
1091	#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
1092	^L
1093	INLINE bool
1094	PSEUDOVECTORP (Lisp_Object a, int code)
1095	{
1096	  return (lisp_h_VECTORLIKEP (a)
1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577b0e8 <+10392>:	and    $0x7,%edx
   0x000055555577b0eb <+10395>:	jne    0x555555778c13 <read_char+963>

1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x000055555577b0f1 <+10401>:	movabs $0x400000003f000000,%rdx
   0x000055555577b0fb <+10411>:	and    0x3(%rax),%rdx
   0x000055555577b0ff <+10415>:	mov    %rdx,%rax

1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577b102 <+10418>:	movabs $0x4000000006000000,%rdx
   0x000055555577b10c <+10428>:	cmp    %rdx,%rax
   0x000055555577b10f <+10431>:	jne    0x555555778c13 <read_char+963>
   0x000055555577b115 <+10437>:	jmp    0x555555778c22 <read_char+978>
   0x000055555577b11a <+10442>:	cmp    $0xf,%r15d
   0x000055555577b11e <+10446>:	jne    0x55555577c485 <read_char+15413>

1233	}
1234
1235	INLINE EMACS_INT
1236	(XFIXNUM_RAW) (Lisp_Object a)
1237	{
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b124 <+10452>:	movdqa -0x390(%rbp),%xmm0
   0x000055555577b12c <+10460>:	movdqa -0x370(%rbp),%xmm1

./src/keyboard.c:
2451			  for (i = 0; i < n; i++)
   0x000055555577b134 <+10468>:	mov    $0x10,%esi

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b139 <+10473>:	shufps $0x88,-0x360(%rbp),%xmm1
   0x000055555577b141 <+10481>:	shufps $0x88,-0x380(%rbp),%xmm0
   0x000055555577b149 <+10489>:	movdqa %xmm0,%xmm2
   0x000055555577b14d <+10493>:	punpcklwd %xmm1,%xmm0
   0x000055555577b151 <+10497>:	cmpq   $0x10,-0x4e8(%rbp)
   0x000055555577b159 <+10505>:	punpckhwd %xmm1,%xmm2
   0x000055555577b15d <+10509>:	movdqa %xmm0,%xmm1
   0x000055555577b161 <+10513>:	punpckhwd %xmm2,%xmm1
   0x000055555577b165 <+10517>:	punpcklwd %xmm2,%xmm0
   0x000055555577b169 <+10521>:	movdqa -0x330(%rbp),%xmm2
   0x000055555577b171 <+10529>:	shufps $0x88,-0x320(%rbp),%xmm2
   0x000055555577b179 <+10537>:	punpcklwd %xmm1,%xmm0
   0x000055555577b17d <+10541>:	movdqa -0x350(%rbp),%xmm1
   0x000055555577b185 <+10549>:	shufps $0x88,-0x340(%rbp),%xmm1
   0x000055555577b18d <+10557>:	movdqa %xmm1,%xmm3
   0x000055555577b191 <+10561>:	punpcklwd %xmm2,%xmm1
   0x000055555577b195 <+10565>:	psraw  $0x2,%xmm0
   0x000055555577b19a <+10570>:	punpckhwd %xmm2,%xmm3
   0x000055555577b19e <+10574>:	movdqa %xmm1,%xmm2
   0x000055555577b1a2 <+10578>:	punpcklwd %xmm3,%xmm1
   0x000055555577b1a6 <+10582>:	punpckhwd %xmm3,%xmm2
   0x000055555577b1aa <+10586>:	punpcklwd %xmm2,%xmm1

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x000055555577b1ae <+10590>:	movdqa 0x24385a(%rip),%xmm2        # 0x5555559bea10

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b1b6 <+10598>:	psraw  $0x2,%xmm1

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x000055555577b1bb <+10603>:	pand   %xmm2,%xmm0
   0x000055555577b1bf <+10607>:	pand   %xmm1,%xmm2
   0x000055555577b1c3 <+10611>:	packuswb %xmm2,%xmm0
   0x000055555577b1c7 <+10615>:	movaps %xmm0,-0xa0(%rbp)

2451			  for (i = 0; i < n; i++)
   0x000055555577b1ce <+10622>:	je     0x55555577cb5d <read_char+17165>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b1d4 <+10628>:	movslq %esi,%rdi
   0x000055555577b1d7 <+10631>:	mov    -0x390(%rbp,%rdi,8),%rdx
   0x000055555577b1df <+10639>:	sar    $0x2,%rdx

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x000055555577b1e3 <+10643>:	mov    %dl,-0xa0(%rbp,%rdi,1)

2451			  for (i = 0; i < n; i++)
   0x000055555577b1ea <+10650>:	cmp    %esi,%r15d
   0x000055555577b1ed <+10653>:	jle    0x55555577b35c <read_char+11020>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b1f3 <+10659>:	mov    -0x388(%rbp),%rsi
   0x000055555577b1fa <+10666>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x000055555577b1fe <+10670>:	mov    %sil,-0x9f(%rbp)

2451			  for (i = 0; i < n; i++)
   0x000055555577b205 <+10677>:	cmp    $0x1,%r15d
   0x000055555577b209 <+10681>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b20f <+10687>:	mov    -0x380(%rbp),%rsi
   0x000055555577b216 <+10694>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x000055555577b21a <+10698>:	mov    %sil,-0x9e(%rbp)

2451			  for (i = 0; i < n; i++)
   0x000055555577b221 <+10705>:	cmp    $0x2,%r15d
   0x000055555577b225 <+10709>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b22b <+10715>:	mov    -0x378(%rbp),%rsi
   0x000055555577b232 <+10722>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x000055555577b236 <+10726>:	mov    %sil,-0x9d(%rbp)

2451			  for (i = 0; i < n; i++)
   0x000055555577b23d <+10733>:	cmp    $0x3,%r15d
   0x000055555577b241 <+10737>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b247 <+10743>:	mov    -0x370(%rbp),%rsi
   0x000055555577b24e <+10750>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x000055555577b252 <+10754>:	mov    %sil,-0x9c(%rbp)

2451			  for (i = 0; i < n; i++)
   0x000055555577b259 <+10761>:	cmp    $0x4,%r15d
   0x000055555577b25d <+10765>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b263 <+10771>:	mov    -0x368(%rbp),%rsi
   0x000055555577b26a <+10778>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x000055555577b26e <+10782>:	mov    %sil,-0x9b(%rbp)

2451			  for (i = 0; i < n; i++)
   0x000055555577b275 <+10789>:	cmp    $0x5,%r15d
   0x000055555577b279 <+10793>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b27f <+10799>:	mov    -0x360(%rbp),%rsi
   0x000055555577b286 <+10806>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x000055555577b28a <+10810>:	mov    %sil,-0x9a(%rbp)

2451			  for (i = 0; i < n; i++)
   0x000055555577b291 <+10817>:	cmp    $0x6,%r15d
   0x000055555577b295 <+10821>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b29b <+10827>:	mov    -0x358(%rbp),%rsi
   0x000055555577b2a2 <+10834>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x000055555577b2a6 <+10838>:	mov    %sil,-0x99(%rbp)

2451			  for (i = 0; i < n; i++)
   0x000055555577b2ad <+10845>:	cmp    $0x7,%r15d
   0x000055555577b2b1 <+10849>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b2b7 <+10855>:	mov    -0x350(%rbp),%rsi
   0x000055555577b2be <+10862>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x000055555577b2c2 <+10866>:	mov    %sil,-0x98(%rbp)

2451			  for (i = 0; i < n; i++)
   0x000055555577b2c9 <+10873>:	cmp    $0x8,%r15d
   0x000055555577b2cd <+10877>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b2d3 <+10883>:	mov    -0x348(%rbp),%rsi
   0x000055555577b2da <+10890>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x000055555577b2de <+10894>:	mov    %sil,-0x97(%rbp)

2451			  for (i = 0; i < n; i++)
   0x000055555577b2e5 <+10901>:	cmp    $0x9,%r15d
   0x000055555577b2e9 <+10905>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b2eb <+10907>:	mov    -0x340(%rbp),%rsi
   0x000055555577b2f2 <+10914>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x000055555577b2f6 <+10918>:	mov    %sil,-0x96(%rbp)

2451			  for (i = 0; i < n; i++)
   0x000055555577b2fd <+10925>:	cmp    $0xa,%r15d
   0x000055555577b301 <+10929>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b303 <+10931>:	mov    -0x338(%rbp),%rsi
   0x000055555577b30a <+10938>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x000055555577b30e <+10942>:	mov    %sil,-0x95(%rbp)

2451			  for (i = 0; i < n; i++)
   0x000055555577b315 <+10949>:	cmp    $0xb,%r15d
   0x000055555577b319 <+10953>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b31b <+10955>:	mov    -0x330(%rbp),%rsi
   0x000055555577b322 <+10962>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x000055555577b326 <+10966>:	mov    %sil,-0x94(%rbp)

2451			  for (i = 0; i < n; i++)
   0x000055555577b32d <+10973>:	cmp    $0xc,%r15d
   0x000055555577b331 <+10977>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b333 <+10979>:	mov    -0x328(%rbp),%rsi
   0x000055555577b33a <+10986>:	sar    $0x2,%rsi

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x000055555577b33e <+10990>:	mov    %sil,-0x93(%rbp)

2451			  for (i = 0; i < n; i++)
   0x000055555577b345 <+10997>:	cmp    $0xd,%r15d
   0x000055555577b349 <+11001>:	je     0x55555577b35c <read_char+11020>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b34b <+11003>:	mov    -0x320(%rbp),%rdx
   0x000055555577b352 <+11010>:	sar    $0x2,%rdx

./src/keyboard.c:
2452			    src[i] = XFIXNUM (events[i]);
   0x000055555577b356 <+11014>:	mov    %dl,-0x92(%rbp)

2453			  if (meta_key < 2) /* input-meta-mode is t or nil */
   0x000055555577b35c <+11020>:	cmp    $0x1,%ebx
   0x000055555577b35f <+11023>:	jle    0x55555577c035 <read_char+14309>

2456			  coding->destination = dest;
   0x000055555577b365 <+11029>:	mov    -0x4e8(%rbp),%r9
   0x000055555577b36c <+11036>:	sub    $0x8,%rsp
   0x000055555577b370 <+11040>:	mov    %r10,%rdi
   0x000055555577b373 <+11043>:	xor    %ecx,%ecx
   0x000055555577b375 <+11045>:	lea    -0x90(%rbp),%rax

2458			  decode_coding_c_string (coding, src, n, Qnil);
   0x000055555577b37c <+11052>:	xor    %edx,%edx
   0x000055555577b37e <+11054>:	xor    %esi,%esi

2457			  coding->dst_bytes = sizeof dest;
   0x000055555577b380 <+11056>:	movq   $0x50,0x1e0(%r10)

2458			  decode_coding_c_string (coding, src, n, Qnil);
   0x000055555577b38b <+11067>:	movq   %r9,%xmm0

2456			  coding->destination = dest;
   0x000055555577b390 <+11072>:	mov    %rax,0x1f0(%r10)

2458			  decode_coding_c_string (coding, src, n, Qnil);
   0x000055555577b397 <+11079>:	mov    %r9,%r8
   0x000055555577b39a <+11082>:	lea    -0xa0(%rbp),%rax
   0x000055555577b3a1 <+11089>:	punpcklqdq %xmm0,%xmm0
   0x000055555577b3a5 <+11093>:	mov    %rax,0x1c8(%r10)
   0x000055555577b3ac <+11100>:	movups %xmm0,0x1b0(%r10)

./src/lisp.h:
1184	  return a;
   0x000055555577b3b4 <+11108>:	push   $0x0
   0x000055555577b3b6 <+11110>:	mov    %r10,-0x590(%rbp)
   0x000055555577b3bd <+11117>:	call   0x5555556c4690 <decode_coding_object>

./src/keyboard.c:
2459			  eassert (coding->produced_char <= n);
   0x000055555577b3c2 <+11122>:	mov    -0x590(%rbp),%r10
   0x000055555577b3c9 <+11129>:	movzbl 0x3a0fb0(%rip),%esi        # 0x555555b1c380 <suppress_checking>

2458			  decode_coding_c_string (coding, src, n, Qnil);
   0x000055555577b3d0 <+11136>:	pop    %rdx
   0x000055555577b3d1 <+11137>:	pop    %rcx

2459			  eassert (coding->produced_char <= n);
   0x000055555577b3d2 <+11138>:	mov    0x188(%r10),%rdi
   0x000055555577b3d9 <+11145>:	test   %sil,%sil
   0x000055555577b3dc <+11148>:	jne    0x55555577b3eb <read_char+11163>
   0x000055555577b3de <+11150>:	cmp    %rdi,-0x4e8(%rbp)
   0x000055555577b3e5 <+11157>:	jl     0x5555555b2932 <read_char-1859358>

2460			  if (coding->produced_char == 0)
   0x000055555577b3eb <+11163>:	test   %rdi,%rdi
   0x000055555577b3ee <+11166>:	jne    0x55555577c8c1 <read_char+16497>

2461			    { /* The encoded sequence is incomplete.  */
2462			      if (n < MAX_ENCODED_BYTES) /* Avoid buffer overflow.  */
   0x000055555577b3f4 <+11172>:	addq   $0x1,-0x4e8(%rbp)
   0x000055555577b3fc <+11180>:	mov    -0x4e8(%rbp),%rax
   0x000055555577b403 <+11187>:	cmp    $0x11,%rax
   0x000055555577b407 <+11191>:	je     0x55555577c48c <read_char+15420>

2463				continue;		     /* Read on!  */
   0x000055555577b40d <+11197>:	add    $0x1,%r15
   0x000055555577b411 <+11201>:	jmp    0x555555779491 <read_char+3137>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577b416 <+11206>:	test   %eax,%eax
   0x000055555577b418 <+11208>:	jne    0x55555577ab23 <read_char+8915>

1233	}
1234
1235	INLINE EMACS_INT
1236	(XFIXNUM_RAW) (Lisp_Object a)
1237	{
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b41e <+11214>:	sar    $0x2,%r14
   0x000055555577b422 <+11218>:	jns    0x55555577aceb <read_char+9371>
   0x000055555577b428 <+11224>:	jmp    0x5555555b28ca <read_char-1859462>
   0x000055555577b42d <+11229>:	nopl   (%rax)

./src/keyboard.c:
2647		  && (XFIXNAT (c) & 0x80) && (XFIXNAT (c) <= 0xff))
   0x000055555577b430 <+11232>:	mov    %r14,%rdi
   0x000055555577b433 <+11235>:	call   0x555555763380 <XFIXNAT>
   0x000055555577b438 <+11240>:	test   %al,%al
   0x000055555577b43a <+11242>:	jns    0x5555557789a3 <read_char+339>
   0x000055555577b440 <+11248>:	cmp    $0xff,%rax
   0x000055555577b446 <+11254>:	jg     0x5555557789a3 <read_char+339>

./src/lisp.h:
1347	  eassert (0 <= n && n <= MOST_POSITIVE_FIXNUM);
   0x000055555577b44c <+11260>:	and    $0xfffffffff7ffff7f,%rax

./src/keyboard.c:
2648		XSETFASTINT (c, CHAR_META | (XFIXNAT (c) & ~0x80));
   0x000055555577b452 <+11266>:	or     $0x8000000,%rax

./src/lisp.h:
1347	  eassert (0 <= n && n <= MOST_POSITIVE_FIXNUM);
   0x000055555577b458 <+11272>:	cmpb   $0x0,0x3a0f21(%rip)        # 0x555555b1c380 <suppress_checking>
   0x000055555577b45f <+11279>:	jne    0x55555577b46e <read_char+11294>
   0x000055555577b461 <+11281>:	mov    %rax,%rbx
   0x000055555577b464 <+11284>:	shr    $0x3d,%rbx
   0x000055555577b468 <+11288>:	jne    0x5555555b285f <read_char-1859569>

746	  return lisp_h_XIL (i);
   0x000055555577b46e <+11294>:	lea    0x2(,%rax,4),%rbx

1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577b476 <+11302>:	mov    %rbx,%r14

1348	  EMACS_INT int0 = Lisp_Int0;
1349	  return USE_LSB_TAG ? make_fixnum (n) : XIL (n + (int0 << VALBITS));
   0x000055555577b479 <+11305>:	jmp    0x5555557789a6 <read_char+342>

1184	  return a;
   0x000055555577b47e <+11310>:	mov    $0xf148,%esi
   0x000055555577b483 <+11315>:	mov    %r14,%rdi
   0x000055555577b486 <+11318>:	call   0x555555764470 <EQ>

./src/keyboard.c:
2609		      || was_disabled))
   0x000055555577b48b <+11323>:	test   %bl,%bl
   0x000055555577b48d <+11325>:	jne    0x555555778be0 <read_char+912>
   0x000055555577b493 <+11331>:	test   %al,%al
   0x000055555577b495 <+11333>:	jne    0x555555778be0 <read_char+912>
   0x000055555577b49b <+11339>:	jmp    0x555555778bea <read_char+922>

3048		}
3049
3050	      c_volatile = c;
   0x000055555577b4a0 <+11344>:	movq   $0x0,-0x470(%rbp)

4641
4642	  /* Mark all idle-time timers as once again candidates for running.  */
4643	  call0 (Qinternal_timer_start_idle);
4644	}
4645
4646	/* Record that Emacs is no longer idle, so stop running idle-time timers.  */
4647
4648	static void
4649	timer_stop_idle (void)
4650	{
4651	  timer_idleness_start_time = invalid_timespec ();
   0x000055555577b4ab <+11355>:	movdqa 0x23fc4d(%rip),%xmm0        # 0x5555559bb100
   0x000055555577b4b3 <+11363>:	movaps %xmm0,0x38b0f6(%rip)        # 0x555555b065b0 <timer_idleness_start_time>

4652	}
   0x000055555577b4ba <+11370>:	jmp    0x555555778e6e <read_char+1566>

./src/lisp.h:
1310	  return lisp_h_FIXNUMP (x);
   0x000055555577b4bf <+11375>:	lea    -0x2(%r13),%eax

./src/keyboard.c:
3115	  if (FIXNUMP (c))
   0x000055555577b4c3 <+11379>:	test   $0x3,%al
   0x000055555577b4c5 <+11381>:	jne    0x55555577b506 <read_char+11446>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b4c7 <+11383>:	sar    $0x2,%r15
   0x000055555577b4cb <+11387>:	mov    %r15,-0x5c0(%rbp)

./src/keyboard.c:
3118	      if (XFIXNUM (c) == -1)
   0x000055555577b4d2 <+11394>:	cmp    $0xffffffffffffffff,%r15
   0x000055555577b4d6 <+11398>:	je     0x555555778b30 <read_char+736>

3119		goto exit;
3120
3121	      if ((STRINGP (KVAR (current_kboard, Vkeyboard_translate_table))
   0x000055555577b4dc <+11404>:	mov    0x38ad7d(%rip),%rax        # 0x555555b06260 <current_kboard>
   0x000055555577b4e3 <+11411>:	mov    0x20(%rax),%r15

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577b4e7 <+11415>:	mov    %rax,-0x5a0(%rbp)

747	}
748
749	INLINE void *
750	(XLP) (Lisp_Object o)
751	{
752	  return lisp_h_XLP (o);
753	}
754
755	/* Extract A's type.  */
756
757	INLINE enum Lisp_Type
758	(XTYPE) (Lisp_Object a)
759	{
760	#if USE_LSB_TAG
761	  return lisp_h_XTYPE (a);
762	#else
763	  EMACS_UINT i = XLI (a);
764	  return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
765	#endif
766	}
767
768	/* True if A has type tag TAG.
769	   Equivalent to XTYPE (a) == TAG, but often faster.  */
770
771	INLINE bool
772	(TAGGEDP) (Lisp_Object a, enum Lisp_Type tag)
773	{
774	  return lisp_h_TAGGEDP (a, tag);
   0x000055555577b4ee <+11422>:	lea    -0x4(%r15),%eax

./src/keyboard.c:
3121	      if ((STRINGP (KVAR (current_kboard, Vkeyboard_translate_table))
   0x000055555577b4f2 <+11426>:	test   $0x7,%al
   0x000055555577b4f4 <+11428>:	je     0x55555577c428 <read_char+15320>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577b4fa <+11434>:	lea    -0x5(%r15),%eax

1598	}
1599
1600	#ifdef HAVE_MPS
1601	/* When using MPS, Lisp_String data is actually a pointer to the
1602	   flexible "data" array in this struct. */
1603	struct Lisp_String_Data
1604	{
1605	  GC_HEADER
1606	  unsigned char data[FLEXIBLE_ARRAY_MEMBER];
1607	};
1608	#endif
1609
1610	/* In a string or vector, the sign bit of u.s.size is the gc mark bit.  */
1611
1612	struct Lisp_String
1613	{
1614	  GC_HEADER
1615	  union
1616	  {
1617	    struct
1618	    {
1619	      /* Number of characters in string; MSB is used as the mark bit.  */
1620	      ptrdiff_t size;
1621	      /* If nonnegative, number of bytes in the string (which is multibyte).
1622		 If negative, the string is unibyte:
1623		 -1 for data normally allocated
1624		 -2 for data in rodata (C string constants)
1625		 -3 for data that must be immovable (used for bytecode)  */
1626	      ptrdiff_t size_byte;
1627
1628	      INTERVAL intervals;	/* Text properties in this string.  */
1629	      unsigned char *data;
1630	    } s;
1631	    struct Lisp_String *next;
1632	    GCALIGNED_UNION_MEMBER
1633	  } u;
1634	};
1635	static_assert (GCALIGNED (struct Lisp_String));
1636
1637	INLINE bool
1638	STRINGP (Lisp_Object x)
1639	{
1640	  return TAGGEDP (x, Lisp_String);
1641	}
1642
1643	INLINE void
1644	CHECK_STRING (Lisp_Object x)
1645	{
1646	  CHECK_TYPE (STRINGP (x), Qstringp, x);
1647	}
1648
1649	INLINE struct Lisp_String *
1650	XSTRING (Lisp_Object a)
1651	{
1652	  eassert (STRINGP (a));
1653	  struct Lisp_String *s = XUNTAG (a, Lisp_String, struct Lisp_String);
1654	  igc_check_fwd (s, false);
1655	  return s;
1656	}
1657
1658	/* True if STR is a multibyte string.  */
1659	INLINE bool
1660	STRING_MULTIBYTE (Lisp_Object str)
1661	{
1662	  return 0 <= XSTRING (str)->u.s.size_byte;
1663	}
1664
1665	/* An upper bound on the number of bytes in a Lisp string, not
1666	   counting the terminating null.  This a tight enough bound to
1667	   prevent integer overflow errors that would otherwise occur during
1668	   string size calculations.  A string cannot contain more bytes than
1669	   a fixnum can represent, nor can it be so long that C pointer
1670	   arithmetic stops working on the string plus its terminating null.
1671	   Although the actual size limit (see STRING_BYTES_MAX in alloc.c)
1672	   may be a bit smaller than STRING_BYTES_BOUND, calculating it here
1673	   would expose alloc.c internal details that we'd rather keep
1674	   private.
1675
1676	   This is a macro for use in static initializers.  The cast to
1677	   ptrdiff_t ensures that the macro is signed.  */
1678	#define STRING_BYTES_BOUND  \
1679	  ((ptrdiff_t) min (MOST_POSITIVE_FIXNUM, min (SIZE_MAX, PTRDIFF_MAX) - 1))
1680
1681	/* Mark STR as a unibyte string.  */
1682	#define STRING_SET_UNIBYTE(STR)				\
1683	  do {							\
1684	    if (XSTRING (STR)->u.s.size == 0)			\
1685	      (STR) = empty_unibyte_string;			\
1686	    else						\
1687	      XSTRING (STR)->u.s.size_byte = -1;		\
1688	  } while (false)
1689
1690	/* Mark STR as a multibyte string.  Assure that STR contains only
1691	   ASCII characters in advance.  */
1692	INLINE void
1693	STRING_SET_MULTIBYTE (Lisp_Object str)
1694	{
1695	  /* The 0-length strings are unique&shared so we can't modify them.  */
1696	  eassert (XSTRING (str)->u.s.size > 0);
1697	  XSTRING (str)->u.s.size_byte = XSTRING (str)->u.s.size;
1698	}
1699
1700	/* Convenience functions for dealing with Lisp strings.  */
1701
1702	/* WARNING: Use the 'char *' pointers to string data with care in code
1703	   that could GC: GC can relocate string data, invalidating such
1704	   pointers.  It is best to use string character or byte index
1705	   instead, delaying the access through SDATA/SSDATA pointers to the
1706	   latest possible moment.  If you must use the 'char *' pointers
1707	   (e.g., for speed), be sure to adjust them after any call that could
1708	   potentially GC.  */
1709
1710	INLINE unsigned char *
1711	SDATA (Lisp_Object string)
1712	{
1713	  return XSTRING (string)->u.s.data;
1714	}
1715	INLINE char *
1716	SSDATA (Lisp_Object string)
1717	{
1718	  /* Avoid "differ in sign" warnings.  */
1719	  return (char *) SDATA (string);
1720	}
1721	INLINE unsigned char
1722	SREF (Lisp_Object string, ptrdiff_t index)
1723	{
1724	  return SDATA (string)[index];
1725	}
1726	INLINE void
1727	SSET (Lisp_Object string, ptrdiff_t index, unsigned char new)
1728	{
1729	  SDATA (string)[index] = new;
1730	}
1731	INLINE ptrdiff_t
1732	SCHARS (Lisp_Object string)
1733	{
1734	  ptrdiff_t nchars = XSTRING (string)->u.s.size;
1735	  eassume (0 <= nchars);
1736	  return nchars;
1737	}
1738
1739	#ifdef GC_CHECK_STRING_BYTES
1740	extern ptrdiff_t string_bytes (struct Lisp_String *);
1741	#endif
1742	INLINE ptrdiff_t
1743	STRING_BYTES (struct Lisp_String *s)
1744	{
1745	#if defined GC_CHECK_STRING_BYTES && !defined HAVE_MPS
1746	  ptrdiff_t nbytes = string_bytes (s);
1747	#else
1748	  ptrdiff_t nbytes = s->u.s.size_byte < 0 ? s->u.s.size : s->u.s.size_byte;
1749	#endif
1750	  eassume (0 <= nbytes);
1751	  return nbytes;
1752	}
1753
1754	INLINE ptrdiff_t
1755	SBYTES (Lisp_Object string)
1756	{
1757	  return STRING_BYTES (XSTRING (string));
1758	}
1759	INLINE void
1760	STRING_SET_CHARS (Lisp_Object string, ptrdiff_t newsize)
1761	{
1762	  /* This function cannot change the size of data allocated for the
1763	     string when it was created.  */
1764	  eassert (STRING_MULTIBYTE (string)
1765		   ? 0 <= newsize && newsize <= SBYTES (string)
1766		   : newsize == SCHARS (string));
1767	  XSTRING (string)->u.s.size = newsize;
1768	}
1769
1770	INLINE void
1771	CHECK_STRING_NULL_BYTES (Lisp_Object string)
1772	{
1773	  CHECK_TYPE (memchr (SSDATA (string), '\0', SBYTES (string)) == NULL,
1774		      Qfilenamep, string);
1775	}
1776
1777	/* True if STR is immovable (whose data won't move during GC).  */
1778	INLINE bool
1779	string_immovable_p (Lisp_Object str)
1780	{
1781	  return XSTRING (str)->u.s.size_byte == -3;
1782	}
1783
1784	/* A regular vector is just a header plus an array of Lisp_Objects.  */
1785
1786	struct Lisp_Vector
1787	  {
1788	    struct vectorlike_header header;
1789	    Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER];
1790	  } GCALIGNED_STRUCT;
1791
1792	INLINE bool
1793	(VECTORLIKEP) (Lisp_Object x)
1794	{
1795	  return lisp_h_VECTORLIKEP (x);
1796	}
1797
1798	INLINE struct Lisp_Vector *
1799	XVECTOR (Lisp_Object a)
1800	{
1801	  eassert (VECTORLIKEP (a));
1802	  struct Lisp_Vector *v = XUNTAG (a, Lisp_Vectorlike, struct Lisp_Vector);
1803	  igc_check_fwd (v, true);
1804	  return v;
1805	}
1806
1807	INLINE ptrdiff_t
1808	ASIZE (Lisp_Object array)
1809	{
1810	  ptrdiff_t size = XVECTOR (array)->header.size;
1811	  eassume (0 <= size);
1812	  return size;
1813	}
1814
1815	INLINE ptrdiff_t
1816	gc_asize (Lisp_Object array)
1817	{
1818	  /* Like ASIZE, but also can be used in the garbage collector.  */
1819	  return XVECTOR (array)->header.size & ~ARRAY_MARK_FLAG;
1820	}
1821
1822	INLINE ptrdiff_t
1823	PVSIZE (Lisp_Object pv)
1824	{
1825	  return ASIZE (pv) & PSEUDOVECTOR_SIZE_MASK;
1826	}
1827
1828	INLINE bool
1829	VECTORP (Lisp_Object x)
1830	{
1831	  return VECTORLIKEP (x) && ! (ASIZE (x) & PSEUDOVECTOR_FLAG);
   0x000055555577b4fe <+11438>:	test   $0x7,%al
   0x000055555577b500 <+11440>:	je     0x55555577c3c0 <read_char+15216>

740	  return lisp_h_XLI (o);
   0x000055555577b506 <+11446>:	sub    $0x3,%r13d

./src/keyboard.c:
3141	  if (EVENT_HAS_PARAMETERS (c)
   0x000055555577b50a <+11450>:	and    $0x7,%r13d
   0x000055555577b50e <+11454>:	jne    0x55555577b523 <read_char+11475>

3142	      && CONSP (XCDR (c))
   0x000055555577b510 <+11456>:	mov    %r14,%rdi
   0x000055555577b513 <+11459>:	call   0x5555557630d0 <XCDR>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577b518 <+11464>:	sub    $0x3,%eax

./src/keyboard.c:
3142	      && CONSP (XCDR (c))
   0x000055555577b51b <+11467>:	test   $0x7,%al
   0x000055555577b51d <+11469>:	je     0x55555577c516 <read_char+15558>

3175		}
3176	    }
3177
3178	  /* Store these characters into recent_keys, the dribble file if any,
3179	     and the keyboard macro being defined, if any.  */
3180	  record_char (c);
   0x000055555577b523 <+11475>:	mov    %r14,%rdi
   0x000055555577b526 <+11478>:	call   0x555555773260 <record_char>

3181	  recorded = true;
   0x000055555577b52b <+11483>:	movb   $0x1,-0x486(%rbp)

3182	  if (! NILP (also_record))
   0x000055555577b532 <+11490>:	mov    -0x478(%rbp),%rax
   0x000055555577b539 <+11497>:	test   %rax,%rax
   0x000055555577b53c <+11500>:	je     0x55555577b54a <read_char+11514>

3183	    record_char (also_record);
   0x000055555577b53e <+11502>:	mov    -0x478(%rbp),%rdi
   0x000055555577b545 <+11509>:	call   0x555555773260 <record_char>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577b54a <+11514>:	lea    -0x2(%rbx),%r12d
   0x000055555577b54e <+11518>:	mov    %ebx,%r13d

./src/keyboard.c:
3188	  if (FIXNUMP (c)
   0x000055555577b551 <+11521>:	and    $0x3,%r12d
   0x000055555577b555 <+11525>:	jne    0x55555577b57f <read_char+11567>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577b557 <+11527>:	cmpq   $0x0,0x3a54b1(%rip)        # 0x555555b20a10 <globals+1488>
   0x000055555577b55f <+11535>:	je     0x55555577b57f <read_char+11567>

1233	}
1234
1235	INLINE EMACS_INT
1236	(XFIXNUM_RAW) (Lisp_Object a)
1237	{
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b561 <+11537>:	mov    %rbx,%rax
   0x000055555577b564 <+11540>:	sar    $0x2,%rax

./src/keyboard.c:
3190	      && ' ' <= XFIXNUM (c) && XFIXNUM (c) < 256 && XFIXNUM (c) != 127)
   0x000055555577b568 <+11544>:	lea    -0x20(%rax),%rdx
   0x000055555577b56c <+11548>:	cmp    $0xdf,%rdx
   0x000055555577b573 <+11555>:	ja     0x55555577b57f <read_char+11567>
   0x000055555577b575 <+11557>:	cmp    $0x7f,%rax
   0x000055555577b579 <+11561>:	jne    0x55555577cab1 <read_char+16993>

./src/lisp.h:
774	  return lisp_h_TAGGEDP (a, tag);
   0x000055555577b57f <+11567>:	sub    $0x3,%r13d

./src/keyboard.c:
3198	  if (!CONSP (c)
   0x000055555577b583 <+11571>:	and    $0x7,%r13d
   0x000055555577b587 <+11575>:	je     0x55555577c1a5 <read_char+14677>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577b58d <+11581>:	cmpq   $0x0,0x333ffb(%rip)        # 0x555555aaf590 <echo_area_buffer>
   0x000055555577b595 <+11589>:	je     0x55555577c359 <read_char+15113>

1183	  Lisp_Object a = TAG_PTR_INITIALLY (Lisp_Symbol, symoffset);
1184	  return a;
   0x000055555577b59b <+11595>:	mov    $0x8b90,%edi
   0x000055555577b5a0 <+11600>:	call   0x55555576fb10 <safe_run_hooks>

./src/keyboard.c:
3208		  clear_message (1, 0);
   0x000055555577b5a5 <+11605>:	xor    %esi,%esi
   0x000055555577b5a7 <+11607>:	mov    $0x1,%edi
   0x000055555577b5ac <+11612>:	call   0x55555561dd60 <clear_message>

3209		  /* If we were showing the echo-area message on top of an
3210		     active minibuffer, resize the mini-window, since the
3211		     minibuffer may need more or less space than the echo area
3212		     we've just wiped.  */
3213		  if (minibuf_level
   0x000055555577b5b1 <+11617>:	cmpq   $0x0,0x39eff7(%rip)        # 0x555555b1a5b0 <minibuf_level>
   0x000055555577b5b9 <+11625>:	je     0x5555557789c0 <read_char+368>

3214		      && EQ (minibuf_window, echo_area_window)
   0x000055555577b5bf <+11631>:	mov    0x333fe2(%rip),%rsi        # 0x555555aaf5a8 <echo_area_window>
   0x000055555577b5c6 <+11638>:	mov    0x335893(%rip),%rdi        # 0x555555ab0e60 <minibuf_window>
   0x000055555577b5cd <+11645>:	call   0x555555764470 <EQ>
   0x000055555577b5d2 <+11650>:	test   %al,%al
   0x000055555577b5d4 <+11652>:	je     0x5555557789c0 <read_char+368>
   0x000055555577b5da <+11658>:	mov    0x3a560f(%rip),%rax        # 0x555555b20bf0 <globals+1968>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577b5e1 <+11665>:	lea    -0x2(%rax),%edx

2094	}
2095
2096	/* A char-table is a kind of vectorlike, with contents like a vector,
2097	   but with a few additional slots.  For some purposes, it makes sense
2098	   to handle a char-table as type 'struct Lisp_Vector'.  An element of
2099	   a char-table can be any Lisp object, but if it is a sub-char-table,
2100	   we treat it as a table that contains information of a specific
2101	   range of characters.  A sub-char-table is like a vector, but with
2102	   two integer fields between the header and Lisp data, which means
2103	   that it has to be marked with some precautions (see mark_char_table
2104	   in alloc.c).  A sub-char-table appears in an element of a char-table.  */
2105
2106	enum CHARTAB_SIZE_BITS
2107	  {
2108	    CHARTAB_SIZE_BITS_0 = 6,
2109	    CHARTAB_SIZE_BITS_1 = 4,
2110	    CHARTAB_SIZE_BITS_2 = 5,
2111	    CHARTAB_SIZE_BITS_3 = 7
2112	  };
2113
2114	extern const int chartab_size[4];
2115
2116	struct Lisp_Char_Table
2117	  {
2118	    /* HEADER.SIZE is the vector's size field, which also holds the
2119	       pseudovector type information.  It holds the size, too.
2120	       The size counts the defalt, parent, purpose, ascii,
2121	       contents, and extras slots.  */
2122	    struct vectorlike_header header;
2123
2124	    /* This holds the default value, which is used whenever the value
2125	       for a specific character is nil.  */
2126	    Lisp_Object defalt;
2127
2128	    /* This points to another char table, from which we inherit when the
2129	       value for a specific character is nil.  The `defalt' slot takes
2130	       precedence over this.  */
2131	    Lisp_Object parent;
2132
2133	    /* This is a symbol which says what kind of use this char-table is
2134	       meant for.  */
2135	    Lisp_Object purpose;
2136
2137	    /* The bottom sub char-table for characters in the range 0..127.  It
2138	       is nil if no ASCII character has a specific value.  */
2139	    Lisp_Object ascii;
2140
2141	    Lisp_Object contents[(1 << CHARTAB_SIZE_BITS_0)];
2142
2143	    /* These hold additional data.  It is a vector.  */
2144	    Lisp_Object extras[FLEXIBLE_ARRAY_MEMBER];
2145	  } GCALIGNED_STRUCT;
2146
2147	INLINE bool
2148	CHAR_TABLE_P (Lisp_Object a)
2149	{
2150	  return PSEUDOVECTORP (a, PVEC_CHAR_TABLE);
2151	}
2152
2153	INLINE struct Lisp_Char_Table *
2154	XCHAR_TABLE (Lisp_Object a)
2155	{
2156	  eassert (CHAR_TABLE_P (a));
2157	  struct Lisp_Char_Table *t = XUNTAG (a, Lisp_Vectorlike, struct Lisp_Char_Table);
2158	  igc_check_fwd (t, true);
2159	  return t;
2160	}
2161
2162	struct Lisp_Sub_Char_Table
2163	  {
2164	    /* HEADER.SIZE is the vector's size field, which also holds the
2165	       pseudovector type information.  It holds the size, too.  */
2166	    struct vectorlike_header header;
2167
2168	    /* Depth of this sub char-table.  It should be 1, 2, or 3.  A sub
2169	       char-table of depth 1 contains 16 elements, and each element
2170	       covers 4096 (128*32) characters.  A sub char-table of depth 2
2171	       contains 32 elements, and each element covers 128 characters.  A
2172	       sub char-table of depth 3 contains 128 elements, and each element
2173	       is for one character.  */
2174	    int depth;
2175
2176	    /* Minimum character covered by the sub char-table.  */
2177	    int min_char;
2178
2179	    /* Use set_sub_char_table_contents to set this.  */
2180	    Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER];
2181	  } GCALIGNED_STRUCT;
2182
2183	INLINE bool
2184	SUB_CHAR_TABLE_P (Lisp_Object a)
2185	{
2186	  return PSEUDOVECTORP (a, PVEC_SUB_CHAR_TABLE);
2187	}
2188
2189	INLINE struct Lisp_Sub_Char_Table *
2190	XSUB_CHAR_TABLE (Lisp_Object a)
2191	{
2192	  eassert (SUB_CHAR_TABLE_P (a));
2193	  return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Sub_Char_Table);
2194	}
2195
2196	INLINE Lisp_Object
2197	CHAR_TABLE_REF_ASCII (Lisp_Object ct, ptrdiff_t idx)
2198	{
2199	  for (struct Lisp_Char_Table *tbl = XCHAR_TABLE (ct); ;
2200	       tbl = XCHAR_TABLE (tbl->parent))
2201	    {
2202	      Lisp_Object val = (SUB_CHAR_TABLE_P (tbl->ascii)
2203				 ? XSUB_CHAR_TABLE (tbl->ascii)->contents[idx]
2204				 : tbl->ascii);
2205	      if (NILP (val))
2206		val = tbl->defalt;
2207	      if (!NILP (val) || NILP (tbl->parent))
2208		return val;
2209	    }
2210	}
2211
2212	/* Almost equivalent to Faref (CT, IDX) with optimization for ASCII
2213	   characters.  Does not check validity of CT.  */
2214	INLINE Lisp_Object
2215	CHAR_TABLE_REF (Lisp_Object ct, int idx)
2216	{
2217	  return (ASCII_CHAR_P (idx)
2218		  ? CHAR_TABLE_REF_ASCII (ct, idx)
2219		  : char_table_ref (ct, idx));
2220	}
2221
2222	/* Equivalent to Faset (CT, IDX, VAL) with optimization for ASCII and
2223	   8-bit European characters.  Does not check validity of CT.  */
2224	INLINE void
2225	CHAR_TABLE_SET (Lisp_Object ct, int idx, Lisp_Object val)
2226	{
2227	  if (ASCII_CHAR_P (idx) && SUB_CHAR_TABLE_P (XCHAR_TABLE (ct)->ascii))
2228	    set_sub_char_table_contents (XCHAR_TABLE (ct)->ascii, idx, val);
2229	  else
2230	    char_table_set (ct, idx, val);
2231	}
2232
2233	#include "comp.h"
2234
2235	/* This structure describes a built-in function.
2236	   It is generated by the DEFUN macro only.
2237	   defsubr makes it into a Lisp object.  */
2238
2239	struct Lisp_Subr
2240	  {
2241	    struct vectorlike_header header;
2242	    union {
2243	      Lisp_Object (*a0) (void);
2244	      Lisp_Object (*a1) (Lisp_Object);
2245	      Lisp_Object (*a2) (Lisp_Object, Lisp_Object);
2246	      Lisp_Object (*a3) (Lisp_Object, Lisp_Object, Lisp_Object);
2247	      Lisp_Object (*a4) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);
2248	      Lisp_Object (*a5) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);
2249	      Lisp_Object (*a6) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);
2250	      Lisp_Object (*a7) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);
2251	      Lisp_Object (*a8) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);
2252	      Lisp_Object (*aUNEVALLED) (Lisp_Object args);
2253	      Lisp_Object (*aMANY) (ptrdiff_t, Lisp_Object *);
2254	    } function;
2255	    short min_args, max_args;
2256	    const char *symbol_name;
2257	    union {
2258	      const char *string;
2259	      Lisp_Object native;
2260	    } intspec;
2261	    Lisp_Object command_modes;
2262	    /* Positive values: offset into etc/DOC.  Negative values: one's
2263	       complement of index into the native comp unit's vector of
2264	       documentation strings.  */
2265	    EMACS_INT doc;
2266	#ifdef HAVE_NATIVE_COMP
2267	    Lisp_Object native_comp_u;
2268	    char *native_c_name;
2269	    Lisp_Object lambda_list;
2270	    Lisp_Object type;
2271	#endif
2272	  } GCALIGNED_STRUCT;
2273	union Aligned_Lisp_Subr
2274	  {
2275	    struct Lisp_Subr s;
2276	    GCALIGNED_UNION_MEMBER
2277	  };
2278	static_assert (GCALIGNED (union Aligned_Lisp_Subr));
2279
2280	INLINE bool
2281	SUBRP (Lisp_Object a)
2282	{
2283	  return PSEUDOVECTORP (a, PVEC_SUBR);
2284	}
2285
2286	INLINE struct Lisp_Subr *
2287	XSUBR (Lisp_Object a)
2288	{
2289	  eassert (SUBRP (a));
2290	  return &XUNTAG (a, Lisp_Vectorlike, union Aligned_Lisp_Subr)->s;
2291	}
2292
2293	/* Return whether a value might be a valid docstring.
2294	   Used to distinguish the presence of non-docstring in the docstring slot,
2295	   as in the case of OClosures.  */
2296	INLINE bool
2297	VALID_DOCSTRING_P (Lisp_Object doc)
2298	{
2299	  return FIXNUMP (doc) || STRINGP (doc)
2300	         || (CONSP (doc) && STRINGP (XCAR (doc)) && FIXNUMP (XCDR (doc)));
2301	}
2302
2303	enum char_table_specials
2304	  {
2305	    /* This is the number of slots that every char table must have.  This
2306	       counts the ordinary slots and the top, defalt, parent, and purpose
2307	       slots.  */
2308	    CHAR_TABLE_STANDARD_SLOTS
2309	      = (PSEUDOVECSIZE (struct Lisp_Char_Table, contents) - 1
2310		 + (1 << CHARTAB_SIZE_BITS_0)),
2311
2312	    /* This is the index of the first Lisp_Object field in Lisp_Sub_Char_Table
2313	       when the latter is treated as an ordinary Lisp_Vector.  */
2314	    SUB_CHAR_TABLE_OFFSET
2315	      = PSEUDOVECSIZE (struct Lisp_Sub_Char_Table, contents) - 1
2316	  };
2317
2318	/* Sanity-check pseudovector layout.  */
2319	static_assert (offsetof (struct Lisp_Char_Table, defalt) == header_size);
2320	static_assert (offsetof (struct Lisp_Char_Table, extras)
2321		       == header_size + CHAR_TABLE_STANDARD_SLOTS * sizeof (Lisp_Object));
2322	static_assert (offsetof (struct Lisp_Sub_Char_Table, contents)
2323		       == header_size + SUB_CHAR_TABLE_OFFSET * sizeof (Lisp_Object));
2324
2325	/* Return the number of "extra" slots in the char table CT.  */
2326
2327	INLINE int
2328	CHAR_TABLE_EXTRA_SLOTS (struct Lisp_Char_Table *ct)
2329	{
2330	  return ((ct->header.size & PSEUDOVECTOR_SIZE_MASK)
2331		  - CHAR_TABLE_STANDARD_SLOTS);
2332	}
2333
2334
2335	/* Save and restore the instruction and environment pointers,
2336	   without affecting the signal mask.  */
2337
2338	#ifdef HAVE__SETJMP
2339	typedef jmp_buf sys_jmp_buf;
2340	# define sys_setjmp(j) _setjmp (j)
2341	# define sys_longjmp(j, v) _longjmp (j, v)
2342	#elif defined HAVE_SIGSETJMP
2343	typedef sigjmp_buf sys_jmp_buf;
2344	# define sys_setjmp(j) sigsetjmp (j, 0)
2345	# define sys_longjmp(j, v) siglongjmp (j, v)
2346	#else
2347	/* A platform that uses neither _longjmp nor siglongjmp; assume
2348	   longjmp does not affect the sigmask.  */
2349	typedef jmp_buf sys_jmp_buf;
2350	# define sys_setjmp(j) setjmp (j)
2351	# define sys_longjmp(j, v) longjmp (j, v)
2352	#endif
2353
2354	#include "thread.h"
2355
2356	/***********************************************************************
2357				       Symbols
2358	 ***********************************************************************/
2359
2360	/* Value is name of symbol.  */
2361
2362	INLINE Lisp_Object
2363	SYMBOL_VAL (struct Lisp_Symbol *sym)
2364	{
2365	  eassert (sym->u.s.redirect == SYMBOL_PLAINVAL);
2366	  return sym->u.s.val.value;
2367	}
2368
2369	INLINE struct Lisp_Symbol *
2370	SYMBOL_ALIAS (struct Lisp_Symbol *sym)
2371	{
2372	  eassume (sym->u.s.redirect == SYMBOL_VARALIAS && sym->u.s.val.alias);
2373	  return sym->u.s.val.alias;
2374	}
2375	INLINE struct Lisp_Buffer_Local_Value *
2376	SYMBOL_BLV (struct Lisp_Symbol *sym)
2377	{
2378	  eassume (sym->u.s.redirect == SYMBOL_LOCALIZED && sym->u.s.val.blv);
2379	  return sym->u.s.val.blv;
2380	}
2381	INLINE lispfwd
2382	SYMBOL_FWD (struct Lisp_Symbol *sym)
2383	{
2384	  eassume (sym->u.s.redirect == SYMBOL_FORWARDED && sym->u.s.val.fwd);
2385	  return sym->u.s.val.fwd;
2386	}
2387
2388	INLINE void
2389	SET_SYMBOL_VAL (struct Lisp_Symbol *sym, Lisp_Object v)
2390	{
2391	  eassert (sym->u.s.redirect == SYMBOL_PLAINVAL);
2392	  sym->u.s.val.value = v;
2393	}
2394
2395	INLINE void
2396	SET_SYMBOL_ALIAS (struct Lisp_Symbol *sym, struct Lisp_Symbol *v)
2397	{
2398	  eassume (sym->u.s.redirect == SYMBOL_VARALIAS && v);
2399	  sym->u.s.val.alias = v;
2400	}
2401	INLINE void
2402	SET_SYMBOL_BLV (struct Lisp_Symbol *sym, struct Lisp_Buffer_Local_Value *v)
2403	{
2404	  eassume (sym->u.s.redirect == SYMBOL_LOCALIZED && v);
2405	  sym->u.s.val.blv = v;
2406	}
2407	INLINE void
2408	SET_SYMBOL_FWD (struct Lisp_Symbol *sym, lispfwd fwd)
2409	{
2410	  eassume (sym->u.s.redirect == SYMBOL_FORWARDED && fwd);
2411	  sym->u.s.val.fwd = fwd;
2412	}
2413
2414	INLINE Lisp_Object
2415	SYMBOL_NAME (Lisp_Object sym)
2416	{
2417	  return XSYMBOL (sym)->u.s.name;
2418	}
2419
2420	/* Value is true if SYM is an interned symbol.  */
2421
2422	INLINE bool
2423	SYMBOL_INTERNED_P (Lisp_Object sym)
2424	{
2425	  return XSYMBOL (sym)->u.s.interned != SYMBOL_UNINTERNED;
2426	}
2427
2428	/* Value is true if SYM is interned in initial_obarray.  */
2429
2430	INLINE bool
2431	SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym)
2432	{
2433	  return XSYMBOL (sym)->u.s.interned == SYMBOL_INTERNED_IN_INITIAL_OBARRAY;
2434	}
2435
2436	/* Value is non-zero if symbol cannot be changed through a simple set,
2437	   i.e. it's a constant (e.g. nil, t, :keywords), or it has some
2438	   watching functions.  */
2439
2440	INLINE int
2441	(SYMBOL_TRAPPED_WRITE_P) (Lisp_Object sym)
2442	{
2443	  return lisp_h_SYMBOL_TRAPPED_WRITE_P (sym);
2444	}
2445
2446	/* Value is non-zero if symbol cannot be changed at all, i.e. it's a
2447	   constant (e.g. nil, t, :keywords).  Code that actually wants to
2448	   write to SYM, should also check whether there are any watching
2449	   functions.  */
2450
2451	INLINE int
2452	(SYMBOL_CONSTANT_P) (Lisp_Object sym)
2453	{
2454	  return lisp_h_SYMBOL_CONSTANT_P (sym);
2455	}
2456
2457	/* Placeholder for make-docfile to process.  The actual symbol
2458	   definition is done by lread.c's define_symbol.  */
2459	#define DEFSYM(sym, name) /* empty */
2460
2461
2462	struct Lisp_Obarray
2463	{
2464	  struct vectorlike_header header;
2465
2466	  /* Array of 2**size_bits values, each being either a (bare) symbol or
2467	     the fixnum 0.  The symbols for each bucket are chained via
2468	     their s.next field.  */
2469	  Lisp_Object *buckets;
2470
2471	  unsigned size_bits;  /* log2(size of buckets vector) */
2472	  unsigned count;      /* number of symbols in obarray */
2473	};
2474
2475	INLINE bool
2476	OBARRAYP (Lisp_Object a)
2477	{
2478	  return PSEUDOVECTORP (a, PVEC_OBARRAY);
2479	}
2480
2481	INLINE struct Lisp_Obarray *
2482	XOBARRAY (Lisp_Object a)
2483	{
2484	  eassert (OBARRAYP (a));
2485	  struct Lisp_Obarray *o = XUNTAG (a, Lisp_Vectorlike, struct Lisp_Obarray);
2486	# if defined HAVE_MPS && defined ENABLE_CHECKING
2487	  igc_check_fwd (o, true);
2488	# endif
2489	  return o;
2490	}
2491
2492	INLINE void
2493	CHECK_OBARRAY (Lisp_Object x)
2494	{
2495	  CHECK_TYPE (OBARRAYP (x), Qobarrayp, x);
2496	}
2497
2498	INLINE Lisp_Object
2499	make_lisp_obarray (struct Lisp_Obarray *o)
2500	{
2501	  eassert (PSEUDOVECTOR_TYPEP (&o->header, PVEC_OBARRAY));
2502	  return make_lisp_ptr (o, Lisp_Vectorlike);
2503	}
2504
2505	INLINE ptrdiff_t
2506	obarray_size (const struct Lisp_Obarray *o)
2507	{
2508	  return (ptrdiff_t)1 << o->size_bits;
2509	}
2510
2511	Lisp_Object check_obarray_slow (Lisp_Object);
2512
2513	/* Return an obarray object from OBARRAY or signal an error.  */
2514	INLINE Lisp_Object
2515	check_obarray (Lisp_Object obarray)
2516	{
2517	  return OBARRAYP (obarray) ? obarray : check_obarray_slow (obarray);
2518	}
2519
2520	/* Obarray iterator state.  Don't access these members directly.
2521	   The iterator functions must be called in the order followed by DOOBARRAY.  */
2522	typedef struct {
2523	  struct Lisp_Obarray *o;
2524	  ptrdiff_t idx;		/* Current bucket index.  */
2525	  struct Lisp_Symbol *symbol;	/* Current symbol, or NULL if at end
2526					   of current bucket.  */
2527	} obarray_iter_t;
2528
2529	INLINE obarray_iter_t
2530	make_obarray_iter (struct Lisp_Obarray *oa)
2531	{
2532	  return (obarray_iter_t){.o = oa, .idx = -1, .symbol = NULL};
2533	}
2534
2535	/* Whether IT has reached the end and there are no more symbols.
2536	   If true, IT is dead and cannot be used any more.  */
2537	INLINE bool
2538	obarray_iter_at_end (obarray_iter_t *it)
2539	{
2540	  if (it->symbol)
2541	    return false;
2542	  ptrdiff_t size = obarray_size (it->o);
2543	  while (++it->idx < size)
2544	    {
2545	      Lisp_Object obj = it->o->buckets[it->idx];
2546	      if (!BASE_EQ (obj, make_fixnum (0)))
2547		{
2548		  it->symbol = XBARE_SYMBOL (obj);
2549		  return false;
2550		}
2551	    }
2552	  return true;
2553	}
2554
2555	/* Advance IT to the next symbol if any.  */
2556	INLINE void
2557	obarray_iter_step (obarray_iter_t *it)
2558	{
2559	  it->symbol = it->symbol->u.s.next;
2560	}
2561
2562	/* The Lisp symbol at IT, if obarray_iter_at_end returned false.  */
2563	INLINE Lisp_Object
2564	obarray_iter_symbol (obarray_iter_t *it)
2565	{
2566	  return make_lisp_symbol (it->symbol);
2567	}
2568
2569	/* Iterate IT over the symbols of the obarray OA.
2570	   The body shouldn't add or remove symbols in OA, but disobeying that rule
2571	   only risks symbols to be iterated more than once or not at all,
2572	   not crashes or data corruption.  */
2573	#define DOOBARRAY(oa, it)					\
2574	  for (obarray_iter_t it = make_obarray_iter (oa);		\
2575	       !obarray_iter_at_end (&it); obarray_iter_step (&it))
2576
2577	^L
2578	/***********************************************************************
2579				     Hash Tables
2580	 ***********************************************************************/
2581
2582	/* The structure of a Lisp hash table.  */
2583
2584	struct Lisp_Weak_Hash_Table;
2585	struct Lisp_Hash_Table;
2586	struct hash_impl;
2587
2588	/* The type of a hash value stored in the table.
2589	   It's unsigned and a subtype of EMACS_UINT.  */
2590	typedef unsigned int hash_hash_t;
2591
2592	typedef enum hash_table_std_test_t {
2593	  Test_eql,
2594	  Test_eq,
2595	  Test_equal,
2596	} hash_table_std_test_t;
2597
2598	struct hash_table_test
2599	{
2600	  /* C function to compute hash code.  */
2601	  hash_hash_t (*hashfn) (Lisp_Object, struct Lisp_Hash_Table *);
2602
2603	  /* C function to compare two keys.  */
2604	  Lisp_Object (*cmpfn) (Lisp_Object, Lisp_Object, struct Lisp_Hash_Table *);
2605
2606	  /* User-supplied hash function, or nil.  */
2607	  Lisp_Object user_hash_function;
2608
2609	  /* User-supplied key comparison function, or nil.  */
2610	  Lisp_Object user_cmp_function;
2611
2612	  /* Function used to compare keys; always a bare symbol.  */
2613	  Lisp_Object name;
2614	};
2615
2616	typedef enum hash_table_weakness_t {
2617	  Weak_None,		 /* No weak references.  */
2618	  Weak_Key,		 /* Reference to key is weak.  */
2619	  Weak_Value,		 /* Reference to value is weak.  */
2620	  Weak_Key_Or_Value,	 /* References to key or value are weak:
2621				    element kept as long as strong reference to
2622				    either key or value remains.  */
2623	  Weak_Key_And_Value,	 /* References to key and value are weak:
2624				    element kept as long as strong references to
2625				    both key and value remain.  */
2626	} hash_table_weakness_t;
2627
2628	/* The type of a hash table index, both for table indices and index
2629	   (hash) indices.  It's signed and a subtype of ptrdiff_t.  */
2630	typedef int32_t hash_idx_t;
2631
2632	/* The reason for this unusual structure is an MPS peculiarity on 32-bit x86 systems. */
2633	struct Lisp_Weak_Hash_Table_Entry
2634	{
2635	  EMACS_UINT intptr; /* must be an MPS base pointer */
2636	  Lisp_Object fixnum; /* a fixnum indicating the tag, or just a fixnum */
2637	};
2638
2639	extern Lisp_Object weak_hash_table_entry (struct Lisp_Weak_Hash_Table_Entry entry);
2640	extern struct Lisp_Weak_Hash_Table_Entry make_weak_hash_table_entry (Lisp_Object);
2641
2642	struct Lisp_Weak_Hash_Table_Strong_Part
2643	{
2644	  GC_HEADER
2645	  Lisp_Object index_bits;
2646	  Lisp_Object next_free;
2647	  Lisp_Object table_size;
2648	  struct Lisp_Weak_Hash_Table_Weak_Part *weak;
2649	  const struct hash_table_test *test;
2650	  struct Lisp_Weak_Hash_Table_Entry *index; /* internal pointer to an all-fixnum array */
2651	  struct Lisp_Weak_Hash_Table_Entry *hash; /* internal pointer to an all-fixnum array */
2652	  struct Lisp_Weak_Hash_Table_Entry *next; /* internal pointer to an all-fixnum array */
2653	  struct Lisp_Weak_Hash_Table_Entry *key; /* either internal pointer or pointer to dependent object */
2654	  struct Lisp_Weak_Hash_Table_Entry *value; /* either internal pointer or pointer to dependent object */
2655	  hash_table_weakness_t weakness : 3;
2656	  hash_table_std_test_t frozen_test : 2;
2657
2658	  /* True if the table can be purecopied.  The table cannot be
2659	     changed afterwards.  */
2660	  bool_bf purecopy : 1;
2661
2662	  /* True if the table is mutable.  Ordinarily tables are mutable, but
2663	     pure tables are not, and while a table is being mutated it is
2664	     immutable for recursive attempts to mutate it.  */
2665	  bool_bf mutable : 1;
2666	  struct Lisp_Weak_Hash_Table_Entry entries[FLEXIBLE_ARRAY_MEMBER];
2667	};
2668
2669	struct Lisp_Weak_Hash_Table_Weak_Part
2670	{
2671	  GC_HEADER
2672	  struct Lisp_Weak_Hash_Table_Strong_Part *strong;
2673	  struct Lisp_Weak_Hash_Table_Entry entries[FLEXIBLE_ARRAY_MEMBER];
2674	};
2675
2676	struct Lisp_Weak_Hash_Table
2677	{
2678	  struct vectorlike_header header;
2679
2680	  struct Lisp_Weak_Hash_Table_Strong_Part *strong;
2681	  struct Lisp_Weak_Hash_Table_Weak_Part *weak;
2682	  Lisp_Object dump_replacement;
2683	};
2684
2685	struct Lisp_Hash_Table
2686	{
2687	  struct vectorlike_header header;
2688
2689	  /* Hash table internal structure:
2690
2691	     Lisp key         index                  table
2692	         |            vector
2693	         | hash fn                  hash    key   value  next
2694	         v             +--+       +------+-------+------+----+
2695	     hash value        |-1|       | C351 |  cow  | moo  | -1 |<-
2696	         |             +--+       +------+-------+------+----+  |
2697	          ------------>| -------->| 07A8 |  cat  | meow | -1 |  |
2698	            range      +--+       +------+-------+------+----+  |
2699	          reduction    |-1|     ->| 91D2 |  dog  | woof |   ----
2700	                       +--+    |  +------+-------+------+----+
2701	                       | ------   |  ?   |unbound|  ?   | -1 |<-
2702	                       +--+       +------+-------+------+----+  |
2703	                       | -------->| F6B0 | duck  |quack | -1 |  |
2704	                       +--+       +------+-------+------+----+  |
2705	                       |-1|     ->|  ?   |unbound|  ?   |   ----
2706	                       +--+    |  +------+-------+------+----+
2707	                       :  :    |  :      :       :     :    :
2708	                               |
2709	                           next_free
2710
2711	     The table is physically split into three vectors (hash, next,
2712	     key_and_value) which may or may not be beneficial.  */
2713
2714	  /* Bucket vector.  An entry of -1 indicates no item is present,
2715	     and a nonnegative entry is the index of the first item in
2716	     a collision chain.
2717	     This vector is 2**index_bits entries long.
2718	     If index_bits is 0 (and table_size is 0), then this is the
2719	     constant read-only vector {-1}, shared between all instances.
2720	     Otherwise it is heap-allocated.  */
2721	  hash_idx_t *index;
2722
2723	  /* Vector of hash codes.  Unused entries have undefined values.
2724	     This vector is table_size entries long.  */
2725	  hash_hash_t *hash;
2726
2727	  /* Vectors of keys and values.  If the key is HASH_UNUSED_ENTRY_KEY,
2728	     then this slot is unused.  This is gc_marked specially if the table
2729	     is weak.  */
2730	  Lisp_Object *key;
2731	  Lisp_Object *value;
2732
2733	  /* The comparison and hash functions.  */
2734	  const struct hash_table_test *test;
2735
2736	  /* Vector used to chain entries.  If entry I is free, next[I] is the
2737	     entry number of the next free item.  If entry I is non-free,
2738	     next[I] is the index of the next entry in the collision chain,
2739	     or -1 if there is no such entry.
2740	     This vector is table_size entries long.  */
2741	  hash_idx_t *next;
2742
2743	  /* Number of key/value entries in the table.  */
2744	  hash_idx_t count;
2745
2746	  /* Index of first free entry in free list, or -1 if none.  */
2747	  hash_idx_t next_free;
2748
2749	  hash_idx_t table_size;   /* Size of the next and hash vectors.  */
2750
2751	  unsigned char index_bits;	/* log2 (size of the index vector).  */
2752
2753	  /* Weakness of the table.  */
2754	  ENUM_BF (hash_table_weakness_t) weakness : 3;
2755
2756	  /* Hash table test (only used when frozen in dump)  */
2757	  ENUM_BF (hash_table_std_test_t) frozen_test : 2;
2758
2759	  /* True if the table is mutable.  Ordinarily tables are mutable, but
2760	     some tables are not: while a table is being mutated it is immutable
2761	     for recursive attempts to mutate it.  */
2762	  bool_bf mutable : 1;
2763
2764	  /* Next weak hash table if this is a weak hash table.  The head of
2765	     the list is in weak_hash_tables.  Used only during garbage
2766	     collection --- at other times, it is NULL.  */
2767	  struct Lisp_Hash_Table *next_weak;
2768	} GCALIGNED_STRUCT;
2769
2770	/* A specific Lisp_Object that is not a valid Lisp value.
2771	   We need to be careful not to leak this value into machinery
2772	   where it may be treated as one; we'd get a segfault if lucky.  */
2773	#define INVALID_LISP_VALUE make_lisp_ptr (NULL, Lisp_Float)
2774
2775	/* Key value that marks an unused hash table entry.  */
2776	#define HASH_UNUSED_ENTRY_KEY INVALID_LISP_VALUE
2777
2778	/* KEY is a key of an unused hash table entry.  */
2779	INLINE bool
2780	hash_unused_entry_key_p (Lisp_Object key)
2781	{
2782	  return BASE_EQ (key, HASH_UNUSED_ENTRY_KEY);
2783	}
2784
2785	INLINE bool
2786	HASH_TABLE_P (Lisp_Object a)
2787	{
2788	  return PSEUDOVECTORP (a, PVEC_HASH_TABLE);
2789	}
2790
2791	INLINE struct Lisp_Hash_Table *
2792	XHASH_TABLE (Lisp_Object a)
2793	{
2794	  eassert (HASH_TABLE_P (a));
2795	  struct Lisp_Hash_Table *h
2796	    = XUNTAG (a, Lisp_Vectorlike, struct Lisp_Hash_Table);
2797	  igc_check_fwd (h, true);
2798	  return h;
2799	}
2800
2801	#ifdef HAVE_MPS
2802	INLINE bool
2803	WEAK_HASH_TABLE_P (Lisp_Object a)
2804	{
2805	  return PSEUDOVECTORP (a, PVEC_WEAK_HASH_TABLE);
2806	}
2807
2808	INLINE struct Lisp_Weak_Hash_Table *
2809	XWEAK_HASH_TABLE (Lisp_Object a)
2810	{
2811	  eassert (WEAK_HASH_TABLE_P (a));
2812	  struct Lisp_Weak_Hash_Table *h
2813	    = XUNTAG (a, Lisp_Vectorlike, struct Lisp_Weak_Hash_Table);
2814	  igc_check_fwd (h, true);
2815	  return h;
2816	}
2817	#endif
2818
2819	INLINE Lisp_Object
2820	make_lisp_hash_table (struct Lisp_Hash_Table *h)
2821	{
2822	  eassert (PSEUDOVECTOR_TYPEP (&h->header, PVEC_HASH_TABLE));
2823	  return make_lisp_ptr (h, Lisp_Vectorlike);
2824	}
2825
2826	/* Value is the key part of entry IDX in hash table H.  */
2827	INLINE Lisp_Object
2828	HASH_KEY (const struct Lisp_Hash_Table *h, ptrdiff_t idx)
2829	{
2830	  eassert (idx >= 0 && idx < h->table_size);
2831	  return h->key[idx];
2832	}
2833
2834	/* Value is the value part of entry IDX in hash table H.  */
2835	INLINE Lisp_Object
2836	HASH_VALUE (const struct Lisp_Hash_Table *h, ptrdiff_t idx)
2837	{
2838	  eassert (idx >= 0 && idx < h->table_size);
2839	  return h->value[idx];
2840	}
2841
2842	/* Value is the hash code computed for entry IDX in hash table H.  */
2843	INLINE hash_hash_t
2844	HASH_HASH (const struct Lisp_Hash_Table *h, ptrdiff_t idx)
2845	{
2846	  eassert (idx >= 0 && idx < h->table_size);
2847	  return h->hash[idx];
2848	}
2849
2850	/* Value is the size of hash table H.  */
2851	INLINE ptrdiff_t
2852	HASH_TABLE_SIZE (const struct Lisp_Hash_Table *h)
2853	{
2854	  return h->table_size;
2855	}
2856
2857	/* Size of the index vector in hash table H.  */
2858	INLINE ptrdiff_t
2859	hash_table_index_size (const struct Lisp_Hash_Table *h)
2860	{
2861	  return (ptrdiff_t)1 << h->index_bits;
2862	}
2863
2864	/* Hash value for KEY in hash table H.  */
2865	INLINE hash_hash_t
2866	hash_from_key (struct Lisp_Hash_Table *h, Lisp_Object key)
2867	{
2868	  return h->test->hashfn (key, h);
2869	}
2870
2871	#ifdef HAVE_MPS
2872	INLINE Lisp_Object
2873	make_lisp_weak_hash_table (struct Lisp_Weak_Hash_Table *h)
2874	{
2875	  eassert (PSEUDOVECTOR_TYPEP (&h->header, PVEC_WEAK_HASH_TABLE));
2876	  return make_lisp_ptr (h, Lisp_Vectorlike);
2877	}
2878
2879	/* Value is the key part of entry IDX in hash table H.  */
2880	INLINE Lisp_Object
2881	WEAK_HASH_KEY (const struct Lisp_Weak_Hash_Table *h, ptrdiff_t idx)
2882	{
2883	  eassert (idx >= 0 && idx < XFIXNUM (h->strong->table_size));
2884	  return weak_hash_table_entry (h->strong->key[idx]);
2885	}
2886
2887	INLINE Lisp_Object
2888	WEAK_HASH_VALUE (const struct Lisp_Weak_Hash_Table *h, ptrdiff_t idx)
2889	{
2890	  return weak_hash_table_entry (h->strong->value[idx]);
2891	}
2892
2893	/* Value is the hash code computed for entry IDX in hash table H.  */
2894	INLINE Lisp_Object
2895	WEAK_HASH_HASH (const struct Lisp_Weak_Hash_Table *h, ptrdiff_t idx)
2896	{
2897	  eassert (idx >= 0 && idx < XFIXNUM (h->strong->table_size));
2898	  return weak_hash_table_entry (h->strong->hash[idx]);
2899	}
2900
2901	/* Value is the size of hash table H.  */
2902	INLINE ptrdiff_t
2903	WEAK_HASH_TABLE_SIZE (const struct Lisp_Weak_Hash_Table *h)
2904	{
2905	  return XFIXNUM (h->strong->table_size);
2906	}
2907
2908	INLINE ptrdiff_t
2909	weak_hash_table_index_size (const struct Lisp_Weak_Hash_Table *h)
2910	{
2911	  return (ptrdiff_t)1 << XFIXNUM (h->strong->index_bits);
2912	}
2913
2914	/* Hash value for KEY in hash table H.  */
2915	extern Lisp_Object weak_hash_from_key (struct Lisp_Weak_Hash_Table *h, Lisp_Object key);
2916	#endif
2917
2918	/* Iterate K and V as key and value of valid entries in hash table H.
2919	   The body may remove the current entry or alter its value slot, but not
2920	   mutate TABLE in any other way.  */
2921	# define DOHASH(h, k, v)						\
2922	  for (Lisp_Object *dohash_##k##_##v##_k = (h)->key,			\
2923			   *dohash_##k##_##v##_v = (h)->value,			\
2924	                   *dohash_##k##_##v##_end = dohash_##k##_##v##_k	\
2925	                                             + HASH_TABLE_SIZE (h),	\
2926		           *dohash_##k##_##v##_base = dohash_##k##_##v##_k,	\
2927	                   k, v;						\
2928	       dohash_##k##_##v##_k < dohash_##k##_##v##_end			\
2929		 && (k = dohash_##k##_##v##_k[0],				\
2930		     v = dohash_##k##_##v##_v[0], /*maybe unused*/ (void)v,	\
2931	           true);			                                \
2932	       eassert (dohash_##k##_##v##_base == (h)->key			\
2933			&& dohash_##k##_##v##_end				\
2934			   == dohash_##k##_##v##_base				\
2935			+ HASH_TABLE_SIZE (h)),					\
2936		 ++dohash_##k##_##v##_k, ++dohash_##k##_##v##_v)		\
2937	    if (hash_unused_entry_key_p (k))					\
2938	      ;									\
2939	    else
2940
2941	/* Iterate K and V as key and value of valid entries in weak hash table H.
2942	   The body may remove the current entry or alter its value slot, but not
2943	   mutate TABLE in any other way.  */
2944	# define DOHASH_WEAK(h, k, v)						\
2945	  for (struct Lisp_Weak_Hash_Table_Entry *dohash_##k##_##v##_k = (h)->strong->key, \
2946		 *dohash_##k##_##v##_v = (h)->strong->value,			\
2947		 *dohash_##k##_##v##_end = dohash_##k##_##v##_k			\
2948		 + WEAK_HASH_TABLE_SIZE (h),					\
2949		 *dohash_##k##_##v##_base = dohash_##k##_##v##_k;		\
2950	       dohash_##k##_##v##_k < dohash_##k##_##v##_end			\
2951		 && (k = weak_hash_table_entry (dohash_##k##_##v##_k[0]),	\
2952		     v = weak_hash_table_entry (dohash_##k##_##v##_v[0]),	\
2953	           true);			                                \
2954	       eassert (dohash_##k##_##v##_base == (h)->strong->key		\
2955			&& dohash_##k##_##v##_end				\
2956			   == dohash_##k##_##v##_base				\
2957			+ WEAK_HASH_TABLE_SIZE (h)),				\
2958		 ++dohash_##k##_##v##_k, ++dohash_##k##_##v##_v)		\
2959	    if (hash_unused_entry_key_p (k))					\
2960	      ;									\
2961	    else if (PSEUDOVECTORP (k, PVEC_FREE) || PSEUDOVECTORP (v, PVEC_FREE)) \
2962	      ;									\
2963	    else
2964
2965	/* Iterate I as index of valid entries in hash table H.
2966	   Unlike DOHASH, this construct copes with arbitrary table mutations
2967	   in the body.  The consequences of such mutations are limited to
2968	   whether and in what order entries are encountered by the loop
2969	   (which is usually bad enough), but not crashing or corrupting the
2970	   Lisp state.  */
2971	#define DOHASH_SAFE(h, i)					\
2972	  for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (h); i++)		\
2973	    if (hash_unused_entry_key_p (HASH_KEY (h, i)))		\
2974	      ;								\
2975	    else
2976
2977	/* Iterate I as index of valid entries in weak hash table H.
2978	   Unlike DOHASH, this construct copes with arbitrary table mutations
2979	   in the body.  The consequences of such mutations are limited to
2980	   whether and in what order entries are encountered by the loop
2981	   (which is usually bad enough), but not crashing or corrupting the
2982	   Lisp state.  */
2983	#define DOHASH_WEAK_SAFE(h, i)					\
2984	  for (ptrdiff_t i = 0; i < WEAK_HASH_TABLE_SIZE (h); i++)	\
2985	    if (hash_unused_entry_key_p (WEAK_HASH_KEY (h, i)))		\
2986	      ;								\
2987	    else
2988
2989	void hash_table_thaw (Lisp_Object hash_table);
2990	void hash_table_rehash (struct Lisp_Hash_Table *h);
2991
2992	/* Default size for hash tables if not specified.  */
2993
2994	enum DEFAULT_HASH_SIZE { DEFAULT_HASH_SIZE = 0 };
2995
2996	/* Combine two integers X and Y for hashing.  The result might exceed
2997	   INTMASK.  */
2998
2999	INLINE EMACS_UINT
3000	sxhash_combine (EMACS_UINT x, EMACS_UINT y)
3001	{
3002	  return (x << 4) + (x >> (EMACS_INT_WIDTH - 4)) + y;
3003	}
3004
3005	/* Hash X, returning a value in the range 0..INTMASK.  */
3006
3007	INLINE EMACS_UINT
3008	SXHASH_REDUCE (EMACS_UINT x)
3009	{
3010	  return (x ^ x >> (EMACS_INT_WIDTH - FIXNUM_BITS)) & INTMASK;
3011	}
3012
3013	/* Reduce an EMACS_UINT hash value to hash_hash_t.  */
3014	INLINE hash_hash_t
3015	reduce_emacs_uint_to_hash_hash (EMACS_UINT x)
3016	{
3017	  static_assert (sizeof x <= 2 * sizeof (hash_hash_t));
3018	  return (sizeof x == sizeof (hash_hash_t)
3019		  ? x
3020		  : x ^ (x >> (8 * (sizeof x - sizeof (hash_hash_t)))));
3021	}
3022
3023	/* Reduce HASH to a value BITS wide.  */
3024	INLINE ptrdiff_t
3025	knuth_hash (hash_hash_t hash, unsigned bits)
3026	{
3027	  /* Knuth multiplicative hashing, tailored for 32-bit indices
3028	     (avoiding a 64-bit multiply on typical platforms).  */
3029	  unsigned int h = hash;
3030	  unsigned int alpha = 2654435769;	/* 2**32/phi */
3031	  /* Multiply with unsigned int, ANDing in case UINT_WIDTH exceeds 32.  */
3032	  unsigned int product = (h * alpha) & 0xffffffffu;
3033	  /* Convert to a wider type, so that the shift works when BITS == 0.  */
3034	  unsigned long long int wide_product = product;
3035	  return wide_product >> (32 - bits);
3036	}
3037
3038
3039	struct Lisp_Marker
3040	{
3041	  struct vectorlike_header header;
3042
3043	  /* This is the buffer that the marker points into, or 0 if it points nowhere.
3044	     Note: a chain of markers can contain markers pointing into different
3045	     buffers (the chain is per buffer_text rather than per buffer, so it's
3046	     shared between indirect buffers).  */
3047	  /* This is used for (other than NULL-checking):
3048	     - Fmarker_buffer
3049	     - Fset_marker: check eq(oldbuf, newbuf) to avoid unchain+rechain.
3050	     - unchain_marker: to find the list from which to unchain.
3051	     - Fkill_buffer: to only unchain the markers of current indirect buffer.
3052	     */
3053	  struct buffer *buffer;
3054
3055	  /* This flag is temporarily used in the functions
3056	     decode/encode_coding_object to record that the marker position
3057	     must be adjusted after the conversion.  */
3058	  bool_bf need_adjustment : 1;
3059	  /* True means normal insertion at the marker's position
3060	     leaves the marker after the inserted text.  */
3061	  bool_bf insertion_type : 1;
3062
3063	  /* The remaining fields are meaningless in a marker that
3064	     does not point anywhere.  */
3065
3066	#ifndef HAVE_MPS
3067	  /* For markers that point somewhere,
3068	     this is used to chain of all the markers in a given buffer.
3069	     The chain does not preserve markers from garbage collection;
3070	     instead, markers are removed from the chain when freed by GC.  */
3071	  /* We could remove it and use an array in buffer_text instead.
3072	     That would also allow us to preserve it ordered.  */
3073	  struct Lisp_Marker *next;
3074	  /* This is the char position where the marker points.  */
3075	#endif
3076
3077	  ptrdiff_t charpos;
3078	  /* This is the byte position.
3079	     It's mostly used as a charpos<->bytepos cache (i.e. it's not directly
3080	     used to implement the functionality of markers, but rather to (ab)use
3081	     markers as a cache for char<->byte mappings).  */
3082	  ptrdiff_t bytepos;
3083
3084	# ifdef HAVE_MPS
3085	  /* If in a buffer's marker vector, this is the index where it is
3086	     stored. */
3087	  ptrdiff_t index;
3088	# endif
3089	} GCALIGNED_STRUCT;
3090
3091	struct Lisp_Overlay
3092	/* An overlay's real data content is:
3093	   - plist
3094	   - buffer
3095	   - itree node
3096	   - start buffer position (field of the itree node)
3097	   - end buffer position (field of the itree node)
3098	   - insertion types of both ends (fields of the itree node).  */
3099	  {
3100	    struct vectorlike_header header;
3101	    Lisp_Object plist;
3102	    struct buffer *buffer;        /* eassert (live buffer || NULL). */
3103	    struct itree_node *interval;
3104	  } GCALIGNED_STRUCT;
3105
3106	struct Lisp_Misc_Ptr
3107	  {
3108	    struct vectorlike_header header;
3109	    void *pointer;
3110	  } GCALIGNED_STRUCT;
3111
3112	extern Lisp_Object make_misc_ptr (void *);
3113
3114	/* A mint_ptr object OBJ represents a C-language pointer P efficiently.
3115	   Preferably (and typically), OBJ is a fixnum I such that
3116	   XFIXNUMPTR (I) == P, as this represents P within a single Lisp value
3117	   without requiring any auxiliary memory.  However, if P would be
3118	   damaged by being tagged as an integer and then untagged via
3119	   XFIXNUMPTR, then OBJ is a Lisp_Misc_Ptr with pointer component P.
3120
3121	   mint_ptr objects are efficiency hacks intended for C code.
3122	   Although xmint_ptr can be given any mint_ptr generated by non-buggy
3123	   C code, it should not be given a mint_ptr generated from Lisp code
3124	   as that would allow Lisp code to coin pointers from integers and
3125	   could lead to crashes.  To package a C pointer into a Lisp-visible
3126	   object you can put the pointer into a pseudovector instead; see
3127	   Lisp_User_Ptr for an example.  */
3128
3129	INLINE Lisp_Object
3130	make_mint_ptr (void *a)
3131	{
3132	  Lisp_Object val = TAG_PTR_INITIALLY (Lisp_Int0, a);
3133	  return FIXNUMP (val) && XFIXNUMPTR (val) == a ? val : make_misc_ptr (a);
3134	}
3135
3136	INLINE bool
3137	mint_ptrp (Lisp_Object x)
3138	{
3139	  return FIXNUMP (x) || PSEUDOVECTORP (x, PVEC_MISC_PTR);
3140	}
3141
3142	INLINE void *
3143	xmint_pointer (Lisp_Object a)
3144	{
3145	  eassert (mint_ptrp (a));
3146	  if (FIXNUMP (a))
3147	    return XFIXNUMPTR (a);
3148	  return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Misc_Ptr)->pointer;
3149	}
3150
3151	struct Lisp_Sqlite
3152	{
3153	  struct vectorlike_header header;
3154	  void *db;
3155	  void *stmt;
3156	  char *name;
3157	  void (*finalizer) (void *);
3158	  bool eof;
3159	  bool is_statement;
3160	} GCALIGNED_STRUCT;
3161
3162	struct Lisp_User_Ptr
3163	{
3164	  struct vectorlike_header header;
3165	  void (*finalizer) (void *);
3166	  void *p;
3167	} GCALIGNED_STRUCT;
3168
3169	/* A finalizer sentinel.  */
3170	struct Lisp_Finalizer
3171	  {
3172	    struct vectorlike_header header;
3173
3174	    /* Call FUNCTION when the finalizer becomes unreachable, even if
3175	       FUNCTION contains a reference to the finalizer; i.e., call
3176	       FUNCTION when it is reachable _only_ through finalizers.  */
3177	    Lisp_Object function;
3178
3179	    /* Circular list of all active weak references.  */
3180	    struct Lisp_Finalizer *prev;
3181	    struct Lisp_Finalizer *next;
3182	  } GCALIGNED_STRUCT;
3183
3184	extern struct Lisp_Finalizer finalizers;
3185	extern struct Lisp_Finalizer doomed_finalizers;
3186	void unchain_finalizer (struct Lisp_Finalizer *finalizer);
3187
3188	INLINE bool
3189	FINALIZERP (Lisp_Object x)
3190	{
3191	  return PSEUDOVECTORP (x, PVEC_FINALIZER);
3192	}
3193
3194	INLINE struct Lisp_Finalizer *
3195	XFINALIZER (Lisp_Object a)
3196	{
3197	  eassert (FINALIZERP (a));
3198	  return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Finalizer);
3199	}
3200
3201	INLINE bool
3202	MARKERP (Lisp_Object x)
3203	{
3204	  return PSEUDOVECTORP (x, PVEC_MARKER);
3205	}
3206
3207	INLINE struct Lisp_Marker *
3208	XMARKER (Lisp_Object a)
3209	{
3210	  eassert (MARKERP (a));
3211	  struct Lisp_Marker *m = XUNTAG (a, Lisp_Vectorlike, struct Lisp_Marker);
3212	  igc_check_fwd (m, true);
3213	  return m;
3214	}
3215
3216	INLINE bool
3217	OVERLAYP (Lisp_Object x)
3218	{
3219	  return PSEUDOVECTORP (x, PVEC_OVERLAY);
3220	}
3221
3222	INLINE struct Lisp_Overlay *
3223	XOVERLAY (Lisp_Object a)
3224	{
3225	  eassert (OVERLAYP (a));
3226	  struct Lisp_Overlay *o = XUNTAG (a, Lisp_Vectorlike, struct Lisp_Overlay);
3227	  igc_check_fwd (o, true);
3228	  return o;
3229	}
3230
3231	INLINE bool
3232	USER_PTRP (Lisp_Object x)
3233	{
3234	  return PSEUDOVECTORP (x, PVEC_USER_PTR);
3235	}
3236
3237	INLINE struct Lisp_User_Ptr *
3238	XUSER_PTR (Lisp_Object a)
3239	{
3240	  eassert (USER_PTRP (a));
3241	  return XUNTAG (a, Lisp_Vectorlike, struct Lisp_User_Ptr);
3242	}
3243
3244	INLINE bool
3245	SQLITEP (Lisp_Object x)
3246	{
3247	  return PSEUDOVECTORP (x, PVEC_SQLITE);
3248	}
3249
3250	INLINE bool
3251	SQLITE (Lisp_Object a)
3252	{
3253	  return PSEUDOVECTORP (a, PVEC_SQLITE);
3254	}
3255
3256	INLINE void
3257	CHECK_SQLITE (Lisp_Object x)
3258	{
3259	  CHECK_TYPE (SQLITE (x), Qsqlitep, x);
3260	}
3261
3262	INLINE struct Lisp_Sqlite *
3263	XSQLITE (Lisp_Object a)
3264	{
3265	  eassert (SQLITEP (a));
3266	  return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Sqlite);
3267	}
3268
3269	INLINE bool
3270	BIGNUMP (Lisp_Object x)
3271	{
3272	  return PSEUDOVECTORP (x, PVEC_BIGNUM);
3273	}
3274
3275	INLINE bool
3276	INTEGERP (Lisp_Object x)
3277	{
3278	  return FIXNUMP (x) || BIGNUMP (x);
   0x000055555577b5e4 <+11668>:	and    $0x3,%edx
   0x000055555577b5e7 <+11671>:	je     0x5555557789c0 <read_char+368>

774	  return lisp_h_TAGGEDP (a, tag);
   0x000055555577b5ed <+11677>:	lea    -0x5(%rax),%edx

775	}
776
777	INLINE void
778	(CHECK_TYPE) (int ok, Lisp_Object predicate, Lisp_Object x)
779	{
780	  lisp_h_CHECK_TYPE (ok, predicate, x);
781	}
782
783	/* Extract A's pointer value, assuming A's Lisp type is TYPE and the
784	   extracted pointer's type is CTYPE *.  When !USE_LSB_TAG this simply
785	   extracts A's low-order bits, as (uintptr_t) LISP_WORD_TAG (type) is
786	   always zero then.  */
787	#define XUNTAG(a, type, ctype) \
788	  ((ctype *) ((uintptr_t) XLP (a) - (uintptr_t) LISP_WORD_TAG (type)))
789
790	/* A forwarding pointer to a value.  It uses a generic pointer to
791	   avoid alignment bugs that could occur if it used a pointer to a
792	   union of the possible values (struct Lisp_Objfwd, struct
793	   Lisp_Intfwd, etc.).  The pointer is packaged inside a struct to
794	   help static checking.  */
795	typedef const struct Lisp_Fwd *lispfwd;
796	^L
797	/* Interned state of a symbol.  */
798
799	enum symbol_interned
800	{
801	  SYMBOL_UNINTERNED,		      /* not interned anywhere */
802	  SYMBOL_INTERNED,		      /* interned but not in initial obarray */
803	  SYMBOL_INTERNED_IN_INITIAL_OBARRAY  /* interned in initial obarray */
804	};
805
806	enum symbol_redirect
807	{
808	  SYMBOL_PLAINVAL,   /* plain var, value is in the `value' field */
809	  SYMBOL_VARALIAS,   /* var alias, value is really in the `alias' symbol */
810	  SYMBOL_LOCALIZED,  /* localized var, value is in the `blv' object */
811	  SYMBOL_FORWARDED   /* forwarding var, value is in `forward' */
812	};
813
814	enum symbol_trapped_write
815	{
816	  SYMBOL_UNTRAPPED_WRITE,  /* normal case, just set the value */
817	  SYMBOL_NOWRITE,          /* constant, cannot set, e.g. nil, t, :keyword */
818	  SYMBOL_TRAPPED_WRITE     /* trap the write, call watcher functions */
819	};
820
821	struct Lisp_Symbol
822	{
823	  GC_HEADER
824	  union
825	  {
826	    struct
827	    {
828	      bool_bf gcmarkbit : 1;
829
830	      /* Indicates where the value can be found.  */
831	      ENUM_BF (symbol_redirect) redirect : 2;
832
833	      ENUM_BF (symbol_trapped_write) trapped_write : 2;
834
835	      /* Interned state of the symbol.  */
836	      ENUM_BF (symbol_interned) interned : 2;
837
838	      /* True means that this variable has been explicitly declared
839		 special (with `defvar' etc), and shouldn't be lexically bound.  */
840	      bool_bf declared_special : 1;
841
842	      /* The symbol's name, as a Lisp string.  */
843	      Lisp_Object name;
844
845	      /* Value of the symbol or Qunbound if unbound.  Which alternative of the
846		 union is used depends on the `redirect' field above.  */
847	      union {
848		Lisp_Object value;
849		struct Lisp_Symbol *alias;
850		struct Lisp_Buffer_Local_Value *blv;
851		lispfwd fwd;
852	      } val;
853
854	      /* Function value of the symbol or Qnil if not fboundp.  */
855	      Lisp_Object function;
856
857	      /* The symbol's property list.  */
858	      Lisp_Object plist;
859
860	      /* Next symbol in obarray bucket, if the symbol is interned.  */
861	      struct Lisp_Symbol *next;
862	    } s;
863	    GCALIGNED_UNION_MEMBER
864	  } u;
865	};
866	static_assert (GCALIGNED (struct Lisp_Symbol));
867
868	/* Declare a Lisp-callable function.  The MAXARGS parameter has the same
869	   meaning as in the DEFUN macro, and is used to construct a prototype.  */
870	/* We can use the same trick as in the DEFUN macro to generate the
871	   appropriate prototype.  */
872	#define EXFUN(fnname, maxargs) \
873	  extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs
874
875	/* Note that the weird token-substitution semantics of ANSI C makes
876	   this work for MANY and UNEVALLED.  */
877	#define DEFUN_ARGS_MANY		(ptrdiff_t, Lisp_Object *)
878	#define DEFUN_ARGS_UNEVALLED	(Lisp_Object)
879	#define DEFUN_ARGS_0	(void)
880	#define DEFUN_ARGS_1	(Lisp_Object)
881	#define DEFUN_ARGS_2	(Lisp_Object, Lisp_Object)
882	#define DEFUN_ARGS_3	(Lisp_Object, Lisp_Object, Lisp_Object)
883	#define DEFUN_ARGS_4	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
884	#define DEFUN_ARGS_5	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
885				 Lisp_Object)
886	#define DEFUN_ARGS_6	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
887				 Lisp_Object, Lisp_Object)
888	#define DEFUN_ARGS_7	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
889				 Lisp_Object, Lisp_Object, Lisp_Object)
890	#define DEFUN_ARGS_8	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
891				 Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
892
893	/* Lisp_Word_tag is big enough for a possibly-shifted tag, to be
894	   added to a pointer value for conversion to a Lisp_Word.  */
895	#if LISP_WORDS_ARE_POINTERS
896	typedef uintptr_t Lisp_Word_tag;
897	#else
898	typedef EMACS_UINT Lisp_Word_tag;
899	#endif
900
901	/* A integer value tagged with TAG, and otherwise all zero.  */
902	#define LISP_WORD_TAG(tag) \
903	  ((Lisp_Word_tag) (tag) << (USE_LSB_TAG ? 0 : VALBITS))
904
905	/* An initializer for a Lisp_Object that contains TAG along with P.
906	   P can be a pointer or an integer.  The result is usable in a static
907	   initializer if TAG and P are both integer constant expressions.  */
908	#define TAG_PTR_INITIALLY(tag, p) \
909	  LISP_INITIALLY ((Lisp_Word) ((uintptr_t) (p) + LISP_WORD_TAG (tag)))
910
911	/* LISPSYM_INITIALLY (Qfoo) is equivalent to Qfoo except it is
912	   designed for use as a (possibly static) initializer.  */
913	#define LISPSYM_INITIALLY(name) \
914	  TAG_PTR_INITIALLY (Lisp_Symbol, (intptr_t) ((i##name) * sizeof *lispsym))
915
916	/* Declare extern constants for Lisp symbols.  These can be helpful
917	   when using a debugger like GDB, on older platforms where the debug
918	   format does not represent C macros.  However, they are unbounded
919	   and would just be asking for trouble if checking pointer bounds.  */
920	#define DEFINE_LISP_SYMBOL(name) \
921	  DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) \
922	  DEFINE_GDB_SYMBOL_END (LISPSYM_INITIALLY (name))
923
924	/* The index of the C-defined Lisp symbol SYM.
925	   This can be used in a static initializer.  */
926	#define SYMBOL_INDEX(sym) i##sym
927
928	/* By default, define macros for Qt, etc., as this leads to a bit
929	   better performance in the core Emacs interpreter.  A plugin can
930	   define DEFINE_NON_NIL_Q_SYMBOL_MACROS to be false, to be portable to
931	   other Emacs instances that assign different values to Qt, etc.  */
932	#ifndef DEFINE_NON_NIL_Q_SYMBOL_MACROS
933	# define DEFINE_NON_NIL_Q_SYMBOL_MACROS true
934	#endif
935
936	/* True if N is a power of 2.  N should be positive.  */
937
938	#define POWER_OF_2(n) (((n) & ((n) - 1)) == 0)
939
940	/* Return X rounded to the next multiple of Y.  Y should be positive,
941	   and Y - 1 + X should not overflow.  Arguments should not have side
942	   effects, as they are evaluated more than once.  Tune for Y being a
943	   power of 2.  */
944
945	#define ROUNDUP(x, y) (POWER_OF_2 (y)					\
946	                       ? ((y) - 1 + (x)) & ~ ((y) - 1)			\
947	                       : ((y) - 1 + (x)) - ((y) - 1 + (x)) % (y))
948
949	#include <globals.h>
950
951	/* Header of vector-like objects.  This documents the layout constraints on
952	   vectors and pseudovectors (objects of PVEC_xxx subtype).  It also prevents
953	   compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR
954	   and PSEUDOVECTORP cast their pointers to struct vectorlike_header *,
955	   because when two such pointers potentially alias, a compiler won't
956	   incorrectly reorder loads and stores to their size fields.  See
957	   Bug#8546.   */
958	struct vectorlike_header
959	  {
960	    /* The `size' header word, W bits wide, has one of two forms
961	       discriminated by the second-highest bit (PSEUDOVECTOR_FLAG):
962
963	         1   1                    W-2
964	       +---+---+-------------------------------------+
965	       | M | 0 |                 SIZE                |  vector
966	       +---+---+-------------------------------------+
967
968	         1   1    W-32      6       12         12
969	       +---+---+--------+------+----------+----------+
970	       | M | 1 | unused | TYPE | RESTSIZE | LISPSIZE |  pseudovector
971	       +---+---+--------+------+----------+----------+
972
973	       M (ARRAY_MARK_FLAG) holds the GC mark bit.
974
975	       SIZE     is the length (number of slots) of a regular Lisp vector,
976	                and the object layout is struct Lisp_Vector.
977
978	       TYPE     is the pseudovector subtype (enum pvec_type).
979
980	       LISPSIZE is the number of Lisp_Object fields at the beginning of the
981	                object (after the header).  These are always traced by the GC.
982
983	       RESTSIZE is the number of fields (in word_size units) following.
984	                These are not automatically traced by the GC.
985	                For PVEC_BOOL and statically allocated PVEC_SUBR, RESTSIZE is 0.
986	                (The block size for PVEC_BOOL is computed from its own size
987	                field, to avoid being restricted by the 12-bit RESTSIZE field.)
988	    */
989	    GC_HEADER
990	    ptrdiff_t size;
991	  };
992
993	struct Lisp_Symbol_With_Pos
994	{
995	  struct vectorlike_header header;
996	  Lisp_Object sym;              /* A symbol */
997	  Lisp_Object pos;              /* A fixnum */
998	} GCALIGNED_STRUCT;
999
1000	/* In the size word of a vector, this bit means the vector has been marked.  */
1001
1002	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG)
1003	# define ARRAY_MARK_FLAG PTRDIFF_MIN
1004	DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG)
1005
1006	/* In the size word of a struct Lisp_Vector, this bit means it's really
1007	   some other vector-like object.  */
1008	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG)
1009	# define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2)
1010	DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
1011
1012	/* In a pseudovector, the size field actually contains a word with one
1013	   PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
1014	   with PVEC_TYPE_MASK to indicate the actual type.  */
1015	enum pvec_type
1016	{
1017	  PVEC_NORMAL_VECTOR,	/* Should be first, for sxhash_obj.  */
1018	  PVEC_FREE,
1019	  PVEC_BIGNUM,
1020	  PVEC_MARKER,
1021	  PVEC_OVERLAY,
1022	  PVEC_FINALIZER,
1023	  PVEC_SYMBOL_WITH_POS,
1024	  PVEC_MISC_PTR,
1025	  PVEC_USER_PTR,
1026	  PVEC_PROCESS,
1027	  PVEC_FRAME,
1028	  PVEC_WINDOW,
1029	  PVEC_BOOL_VECTOR,
1030	  PVEC_BUFFER,
1031	  PVEC_HASH_TABLE,
1032	#ifdef HAVE_MPS
1033	  PVEC_WEAK_HASH_TABLE,
1034	#endif
1035	  PVEC_OBARRAY,
1036	  PVEC_TERMINAL,
1037	  PVEC_WINDOW_CONFIGURATION,
1038	  PVEC_SUBR,
1039	  PVEC_OTHER,            /* Should never be visible to Elisp code.  */
1040	  PVEC_XWIDGET,
1041	  PVEC_XWIDGET_VIEW,
1042	  PVEC_THREAD,
1043	  PVEC_MUTEX,
1044	  PVEC_CONDVAR,
1045	  PVEC_MODULE_FUNCTION,
1046	  PVEC_MODULE_GLOBAL_REFERENCE,
1047	  PVEC_NATIVE_COMP_UNIT,
1048	  PVEC_TS_PARSER,
1049	  PVEC_TS_NODE,
1050	  PVEC_TS_COMPILED_QUERY,
1051	  PVEC_SQLITE,
1052
1053	  /* These should be last, for internal_equal and sxhash_obj.  */
1054	  PVEC_CLOSURE,
1055	  PVEC_CHAR_TABLE,
1056	  PVEC_SUB_CHAR_TABLE,
1057	  PVEC_RECORD,
1058	  PVEC_FONT,
1059	  PVEC_TAG_MAX = PVEC_FONT  /* Keep this equal to the highest member.  */
1060	};
1061
1062	enum More_Lisp_Bits
1063	  {
1064	    /* For convenience, we also store the number of elements in these bits.
1065	       Note that this size is not necessarily the memory-footprint size, but
1066	       only the number of Lisp_Object fields (that need to be traced by GC).
1067	       The distinction is used, e.g., by Lisp_Process, which places extra
1068	       non-Lisp_Object fields at the end of the structure.  */
1069	    PSEUDOVECTOR_SIZE_BITS = 12,
1070	    PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1,
1071
1072	    /* To calculate the memory footprint of the pseudovector, it's useful
1073	       to store the size of non-Lisp area in word_size units here.  */
1074	    PSEUDOVECTOR_REST_BITS = 12,
1075	    PSEUDOVECTOR_REST_MASK = (((1 << PSEUDOVECTOR_REST_BITS) - 1)
1076				      << PSEUDOVECTOR_SIZE_BITS),
1077
1078	    /* Used to extract pseudovector subtype information.  */
1079	    PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS,
1080	    PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS
1081	  };
1082	^L
1083	/* These functions extract various sorts of values from a Lisp_Object.
1084	   For example, if tem is a Lisp_Object whose type is Lisp_Cons,
1085	   XCONS (tem) is the struct Lisp_Cons * pointing to the memory for
1086	   that cons.  */
1087
1088	/* Largest and smallest representable fixnum values.  These are the C
1089	   values.  They are macros for use in #if and static initializers.  */
1090	#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
1091	#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
1092	^L
1093	INLINE bool
1094	PSEUDOVECTORP (Lisp_Object a, int code)
1095	{
1096	  return (lisp_h_VECTORLIKEP (a)
1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577b5f0 <+11680>:	and    $0x7,%edx
   0x000055555577b5f3 <+11683>:	jne    0x55555577b616 <read_char+11718>

1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x000055555577b5f5 <+11685>:	movabs $0x400000003f000000,%rdx
   0x000055555577b5ff <+11695>:	and    0x3(%rax),%rdx

1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577b603 <+11699>:	movabs $0x4000000002000000,%rcx
   0x000055555577b60d <+11709>:	cmp    %rcx,%rdx
   0x000055555577b610 <+11712>:	je     0x5555557789c0 <read_char+368>

774	  return lisp_h_TAGGEDP (a, tag);
   0x000055555577b616 <+11718>:	sub    $0x7,%eax

3437	}
3438
3439	/* Most hosts nowadays use IEEE floating point, so they use IEC 60559
3440	   representations, have infinities and NaNs, and do not trap on
3441	   exceptions.  Define IEEE_FLOATING_POINT to 1 if this host is one of the
3442	   typical ones.  The C23 macro __STDC_IEC_60559_BFP__ (or its
3443	   obsolescent C11 counterpart __STDC_IEC_559__) is close to what is
3444	   wanted here, but is not quite right because Emacs does not require
3445	   all the features of C23 Annex F (and does not require C11 or later,
3446	   for that matter).  */
3447
3448	#define IEEE_FLOATING_POINT (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
3449				     && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128)
3450
3451	/* Meanings of slots in a Lisp_Closure:  */
3452
3453	enum Lisp_Closure
3454	  {
3455	    CLOSURE_ARGLIST = 0,
3456	    CLOSURE_CODE = 1,
3457	    CLOSURE_CONSTANTS = 2,
3458	    CLOSURE_STACK_DEPTH = 3,
3459	    CLOSURE_DOC_STRING = 4,
3460	    CLOSURE_INTERACTIVE = 5
3461	  };
3462
3463	/* Flag bits in a character.  These also get used in termhooks.h.
3464	   Emacs needs 22 bits for the character value itself, see MAX_CHAR,
3465	   so we shouldn't use any bits lower than 0x0400000.  */
3466	enum char_bits
3467	  {
3468	    CHAR_ALT = 0x0400000,
3469	    CHAR_SUPER = 0x0800000,
3470	    CHAR_HYPER = 0x1000000,
3471	    CHAR_SHIFT = 0x2000000,
3472	    CHAR_CTL = 0x4000000,
3473	    CHAR_META = 0x8000000,
3474
3475	    CHAR_MODIFIER_MASK =
3476	      CHAR_ALT | CHAR_SUPER | CHAR_HYPER | CHAR_SHIFT | CHAR_CTL | CHAR_META,
3477
3478	    /* Actually, the current Emacs uses 22 bits for the character value
3479	       itself.  */
3480	    CHARACTERBITS = 22
3481	  };
3482	^L
3483	/* Data type checking.  */
3484
3485	INLINE bool
3486	FIXNATP (Lisp_Object x)
3487	{
3488	  return FIXNUMP (x) && 0 <= XFIXNUM (x);
3489	}
3490
3491	/* Like XFIXNUM (A), but may be faster.  A must be nonnegative.  */
3492	INLINE EMACS_INT
3493	XFIXNAT (Lisp_Object a)
3494	{
3495	  eassert (FIXNUMP (a));
3496	  EMACS_INT int0 = Lisp_Int0;
3497	  EMACS_INT result = USE_LSB_TAG ? XFIXNUM (a) : XLI (a) - (int0 << VALBITS);
3498	  eassume (0 <= result);
3499	  return result;
3500	}
3501
3502	INLINE bool
3503	NUMBERP (Lisp_Object x)
3504	{
3505	  return INTEGERP (x) || FLOATP (x);
   0x000055555577b619 <+11721>:	test   $0x7,%al
   0x000055555577b61b <+11723>:	je     0x5555557789c0 <read_char+368>

./src/keyboard.c:
3218		    resize_mini_window (XWINDOW (minibuf_window), false);
   0x000055555577b621 <+11729>:	mov    0x335838(%rip),%rdi        # 0x555555ab0e60 <minibuf_window>
   0x000055555577b628 <+11736>:	call   0x555555763130 <XWINDOW>
   0x000055555577b62d <+11741>:	xor    %esi,%esi
   0x000055555577b62f <+11743>:	mov    %rax,%rdi
   0x000055555577b632 <+11746>:	call   0x555555642190 <resize_mini_window>
   0x000055555577b637 <+11751>:	jmp    0x5555557789c0 <read_char+368>
   0x000055555577b63c <+11756>:	nopl   0x0(%rax)

3046		  c = XCDR (c);
   0x000055555577b640 <+11760>:	mov    %r14,%rdi
   0x000055555577b643 <+11763>:	call   0x5555557630d0 <XCDR>

3047		  recorded = true;
   0x000055555577b648 <+11768>:	movb   $0x1,-0x486(%rbp)

3046		  c = XCDR (c);
   0x000055555577b64f <+11775>:	mov    %rax,%r14

3047		  recorded = true;
   0x000055555577b652 <+11778>:	jmp    0x55555577a6fa <read_char+7850>

2587		      c = XCDR (c);
   0x000055555577b657 <+11783>:	mov    %r14,%rdi
   0x000055555577b65a <+11786>:	call   0x5555557630d0 <XCDR>

2588		      recorded = true;
   0x000055555577b65f <+11791>:	movb   $0x1,-0x486(%rbp)

2589		    }
2590		  reread = true;
   0x000055555577b666 <+11798>:	movb   $0x1,-0x487(%rbp)

2587		      c = XCDR (c);
   0x000055555577b66d <+11805>:	mov    %rax,%r14

2588		      recorded = true;
   0x000055555577b670 <+11808>:	lea    -0x3(%rax),%eax

./src/lisp.h:
774	  return lisp_h_TAGGEDP (a, tag);
   0x000055555577b673 <+11811>:	and    $0x7,%eax

740	  return lisp_h_XLI (o);
   0x000055555577b676 <+11814>:	test   %eax,%eax
   0x000055555577b678 <+11816>:	jne    0x555555778bae <read_char+862>
   0x000055555577b67e <+11822>:	jmp    0x555555778fed <read_char+1949>

./src/keyboard.c:
2595	      if (CONSP (c)
   0x000055555577b683 <+11827>:	call   0x555555764a20 <start_polling>
   0x000055555577b688 <+11832>:	jmp    0x555555778e86 <read_char+1590>

2625		c = XCAR (c);
   0x000055555577b68d <+11837>:	mov    %r14,%rdi
   0x000055555577b690 <+11840>:	call   0x555555763090 <XCAR>
   0x000055555577b695 <+11845>:	mov    %rax,%r14

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577b698 <+11848>:	mov    %rax,%rbx

1239	}
1240
1241	INLINE Lisp_Object
1242	make_ufixnum (EMACS_INT n)
1243	{
1244	  eassert (0 <= n && n <= INTMASK);
1245	  return lisp_h_make_fixnum_wrap (n);
1246	}
1247
1248	#else /* ! USE_LSB_TAG */
1249
1250	/* Although compiled only if ! USE_LSB_TAG, the following functions
1251	   also work when USE_LSB_TAG; this is to aid future maintenance when
1252	   the lisp_h_* macros are eventually removed.  */
1253
1254	/* Make a fixnum representing the value of the low order bits of N.  */
1255	INLINE Lisp_Object
1256	make_fixnum (EMACS_INT n)
1257	{
1258	  eassert (! FIXNUM_OVERFLOW_P (n));
1259	  EMACS_INT int0 = Lisp_Int0;
1260	  if (USE_LSB_TAG)
1261	    {
1262	      EMACS_UINT u = n;
1263	      n = u << INTTYPEBITS;
1264	      n += int0;
1265	    }
1266	  else
1267	    {
1268	      n &= INTMASK;
1269	      n += (int0 << VALBITS);
1270	    }
1271	  return XIL (n);
1272	}
1273
1274	/* Extract A's value as a signed integer.  Unlike XFIXNUM, this works
1275	   on any Lisp object, although the resulting integer is useful only
1276	   for things like hashing when A is not a fixnum.  */
1277	INLINE EMACS_INT
1278	XFIXNUM_RAW (Lisp_Object a)
1279	{
1280	  EMACS_INT i = XLI (a);
1281	  if (! USE_LSB_TAG)
1282	    {
1283	      EMACS_UINT u = i;
1284	      i = u << INTTYPEBITS;
1285	    }
1286	  return i >> INTTYPEBITS;
1287	}
1288
1289	INLINE Lisp_Object
1290	make_ufixnum (EMACS_INT n)
1291	{
1292	  eassert (0 <= n && n <= INTMASK);
1293	  EMACS_INT int0 = Lisp_Int0;
1294	  if (USE_LSB_TAG)
1295	    {
1296	      EMACS_UINT u = n;
1297	      n = u << INTTYPEBITS;
1298	      n += int0;
1299	    }
1300	  else
1301	    n += int0 << VALBITS;
1302	  return XIL (n);
1303	}
1304
1305	#endif /* ! USE_LSB_TAG */
1306
1307	INLINE bool
1308	(FIXNUMP) (Lisp_Object x)
1309	{
1310	  return lisp_h_FIXNUMP (x);
   0x000055555577b69b <+11851>:	mov    %eax,%r12d
   0x000055555577b69e <+11854>:	jmp    0x555555778cbe <read_char+1134>

./src/keyboard.c:
4342			       = XFLOAT_DATA (XCAR (event->ie.arg))) != 0.0
   0x000055555577b6a3 <+11859>:	mov    0x30(%r8),%rbx
   0x000055555577b6a7 <+11863>:	mov    %r8,-0x5e8(%rbp)
   0x000055555577b6ae <+11870>:	mov    %rbx,%rdi
   0x000055555577b6b1 <+11873>:	call   0x555555763090 <XCAR>
   0x000055555577b6b6 <+11878>:	mov    %rax,%rdi

./src/lisp.h:
3436	  return XFLOAT (f)->u.data;
   0x000055555577b6b9 <+11881>:	call   0x555555762b70 <XFLOAT>

./src/keyboard.c:
4341			  && ((pinch_dx
   0x000055555577b6be <+11886>:	pxor   %xmm5,%xmm5
   0x000055555577b6c2 <+11890>:	mov    -0x5e8(%rbp),%r8

./src/lisp.h:
3436	  return XFLOAT (f)->u.data;
   0x000055555577b6c9 <+11897>:	movsd  0x10(%rax),%xmm6

./src/keyboard.c:
4341			  && ((pinch_dx
   0x000055555577b6ce <+11902>:	ucomisd %xmm5,%xmm6

./src/lisp.h:
3436	  return XFLOAT (f)->u.data;
   0x000055555577b6d2 <+11906>:	movsd  %xmm6,-0x540(%rbp)

./src/keyboard.c:
4341			  && ((pinch_dx
   0x000055555577b6da <+11914>:	jp     0x55555577b6e2 <read_char+11922>
   0x000055555577b6dc <+11916>:	je     0x55555577c496 <read_char+15430>

429	  return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1;
   0x000055555577b6e2 <+11922>:	mov    0x30(%r8),%rsi
   0x000055555577b6e6 <+11926>:	lea    0x38a9f3(%rip),%r14        # 0x555555b060e0 <kbd_buffer+262080>
   0x000055555577b6ed <+11933>:	lea    0x40(%r8),%rbx

4345			{
4346			  union buffered_input_event *maybe_event = next_kbd_event (event);
4347
4348			  pinch_dy = XFLOAT_DATA (XCAR (XCDR (event->ie.arg)));
   0x000055555577b6f1 <+11937>:	mov    %r8,-0x608(%rbp)

429	  return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1;
   0x000055555577b6f8 <+11944>:	cmp    %r14,%r8
   0x000055555577b6fb <+11947>:	lea    -0x3ffc0(%r14),%rax

4345			{
4346			  union buffered_input_event *maybe_event = next_kbd_event (event);
4347
4348			  pinch_dy = XFLOAT_DATA (XCAR (XCDR (event->ie.arg)));
   0x000055555577b702 <+11954>:	mov    %rsi,%rdi

429	  return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1;
   0x000055555577b705 <+11957>:	cmove  %rax,%rbx

4345			{
4346			  union buffered_input_event *maybe_event = next_kbd_event (event);
4347
4348			  pinch_dy = XFLOAT_DATA (XCAR (XCDR (event->ie.arg)));
   0x000055555577b709 <+11961>:	mov    %rsi,-0x600(%rbp)
   0x000055555577b710 <+11968>:	call   0x5555557630d0 <XCDR>
   0x000055555577b715 <+11973>:	mov    %rax,%rdi
   0x000055555577b718 <+11976>:	call   0x555555763090 <XCAR>
   0x000055555577b71d <+11981>:	mov    %rax,%rdi

./src/lisp.h:
3436	  return XFLOAT (f)->u.data;
   0x000055555577b720 <+11984>:	call   0x555555762b70 <XFLOAT>

./src/keyboard.c:
4349			  pinch_angle = XFLOAT_DATA (Fnth (make_fixnum (3), event->ie.arg));
   0x000055555577b725 <+11989>:	mov    -0x600(%rbp),%rsi
   0x000055555577b72c <+11996>:	mov    $0xe,%edi

./src/lisp.h:
3436	  return XFLOAT (f)->u.data;
   0x000055555577b731 <+12001>:	movsd  0x10(%rax),%xmm2
   0x000055555577b736 <+12006>:	movsd  %xmm2,-0x530(%rbp)

746	  return lisp_h_XIL (i);
   0x000055555577b73e <+12014>:	call   0x55555582c7d0 <Fnth>

./src/keyboard.c:
4349			  pinch_angle = XFLOAT_DATA (Fnth (make_fixnum (3), event->ie.arg));
   0x000055555577b743 <+12019>:	mov    %rax,%rdi

./src/lisp.h:
3436	  return XFLOAT (f)->u.data;
   0x000055555577b746 <+12022>:	call   0x555555762b70 <XFLOAT>

./src/keyboard.c:
4362				 && (XFLOAT_DATA (XCAR (maybe_event->ie.arg)) != 0.0
   0x000055555577b74b <+12027>:	cmp    0x34a9be(%rip),%rbx        # 0x555555ac6110 <kbd_store_ptr>
   0x000055555577b752 <+12034>:	mov    -0x608(%rbp),%r8

./src/lisp.h:
3436	  return XFLOAT (f)->u.data;
   0x000055555577b759 <+12041>:	movsd  0x10(%rax),%xmm3
   0x000055555577b75e <+12046>:	movsd  %xmm3,-0x538(%rbp)

./src/keyboard.c:
4362				 && (XFLOAT_DATA (XCAR (maybe_event->ie.arg)) != 0.0
   0x000055555577b766 <+12054>:	je     0x55555577bf0a <read_char+14010>
   0x000055555577b76c <+12060>:	mov    %r12,-0x568(%rbp)
   0x000055555577b773 <+12067>:	mov    %r8,%r12
   0x000055555577b776 <+12070>:	mov    %r15,-0x570(%rbp)
   0x000055555577b77d <+12077>:	jmp    0x55555577b796 <read_char+12102>

429	  return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1;
   0x000055555577b77f <+12079>:	lea    0x40(%rbx),%rax

4359					event->ie.frame_or_window)
4360				 /* Make sure that the event isn't the start
4361				    of a new pinch gesture sequence.  */
4362				 && (XFLOAT_DATA (XCAR (maybe_event->ie.arg)) != 0.0
   0x000055555577b783 <+12083>:	cmp    %rax,0x34a986(%rip)        # 0x555555ac6110 <kbd_store_ptr>
   0x000055555577b78a <+12090>:	je     0x55555577b9a5 <read_char+12629>

429	  return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1;
   0x000055555577b790 <+12096>:	mov    %rbx,%r12
   0x000055555577b793 <+12099>:	mov    %rax,%rbx

4350
4351			  while (maybe_event != kbd_store_ptr
4352				 && maybe_event->ie.kind == PINCH_EVENT
   0x000055555577b796 <+12102>:	cmpw   $0x24,(%rbx)
   0x000055555577b79a <+12106>:	jne    0x55555577bef9 <read_char+13993>

4353				 /* Make sure we never miss an event that has
4354				    different modifiers.  */
4355				 && maybe_event->ie.modifiers == event->ie.modifiers
   0x000055555577b7a0 <+12112>:	mov    0x8(%r12),%eax
   0x000055555577b7a5 <+12117>:	cmp    %eax,0x8(%rbx)
   0x000055555577b7a8 <+12120>:	jne    0x55555577bef9 <read_char+13993>

4356				 /* Make sure that the event is for the same
4357				    frame.  */
4358				 && EQ (maybe_event->ie.frame_or_window,
   0x000055555577b7ae <+12126>:	mov    0x28(%r12),%rsi
   0x000055555577b7b3 <+12131>:	mov    0x28(%rbx),%rdi
   0x000055555577b7b7 <+12135>:	call   0x555555764470 <EQ>
   0x000055555577b7bc <+12140>:	test   %al,%al
   0x000055555577b7be <+12142>:	je     0x55555577bef9 <read_char+13993>

4359					event->ie.frame_or_window)
4360				 /* Make sure that the event isn't the start
4361				    of a new pinch gesture sequence.  */
4362				 && (XFLOAT_DATA (XCAR (maybe_event->ie.arg)) != 0.0
   0x000055555577b7c4 <+12148>:	mov    0x30(%rbx),%rdi
   0x000055555577b7c8 <+12152>:	call   0x555555763090 <XCAR>

./src/lisp.h:
3427	  eassert (FLOATP (a));
   0x000055555577b7cd <+12157>:	movzbl 0x3a0bab(%rip),%r15d        # 0x555555b1c380 <suppress_checking>
   0x000055555577b7d5 <+12165>:	test   %r15b,%r15b
   0x000055555577b7d8 <+12168>:	jne    0x55555577b7e6 <read_char+12182>

740	  return lisp_h_XLI (o);
   0x000055555577b7da <+12170>:	lea    -0x7(%rax),%ecx

3286	}
3287	INLINE Lisp_Object
3288	make_uint (uintmax_t n)
3289	{
3290	  return FIXNUM_OVERFLOW_P (n) ? make_biguint (n) : make_fixnum (n);
3291	}
3292
3293	/* Return a Lisp integer equal to the value of the C integer EXPR.  */
3294	#define INT_TO_INTEGER(expr) \
3295	  (EXPR_SIGNED (expr) ? make_int (expr) : make_uint (expr))
3296
3297	^L
3298	/* struct Lisp_Buffer_Local_Value is used in a symbol value cell when
3299	   the symbol has buffer-local bindings.  (Exception:
3300	   some buffer-local variables are built-in, with their values stored
3301	   in the buffer structure itself.  They are handled differently,
3302	   using struct Lisp_Buffer_Objfwd.)
3303
3304	   The `valcell' slot holds the variable's current value (unless `fwd'
3305	   is set).  This value is the one that corresponds to the loaded binding.
3306	   To read or set the variable, you must first make sure the right binding
3307	   is loaded; then you can access the value in (or through) `valcell'.
3308
3309	   `where' is the buffer for which the loaded binding was found.
3310	   If it has changed, to make sure the right binding is loaded it is
3311	   necessary to find which binding goes with the current buffer, then
3312	   load it.  To load it, first unload the previous binding.
3313
3314	   `local_if_set' indicates that merely setting the variable creates a
3315	   local binding for the current buffer.  Otherwise the latter, setting
3316	   the variable does not do that; only make-local-variable does that.  */
3317
3318	struct Lisp_Buffer_Local_Value
3319	  {
3320	    GC_HEADER
3321	    /* True means that merely setting the variable creates a local
3322	       binding for the current buffer.  */
3323	    bool_bf local_if_set : 1;
3324	    /* True means that the binding now loaded was found.
3325	       Presumably equivalent to (defcell!=valcell).  */
3326	    bool_bf found : 1;
3327	    /* If non-NULL, a forwarding to the C var where it should also be set.  */
3328	    lispfwd fwd;	/* Should never be (Buffer|Kboard)_Objfwd.  */
3329	    /* The buffer for which the loaded binding was found.  */
3330	    Lisp_Object where;
3331	    /* A cons cell that holds the default value.  It has the form
3332	       (SYMBOL . DEFAULT-VALUE).  */
3333	    Lisp_Object defcell;
3334	    /* The cons cell from `where's parameter alist.
3335	       It always has the form (SYMBOL . VALUE)
3336	       Note that if `fwd' is non-NULL, VALUE may be out of date.
3337	       Also if the currently loaded binding is the default binding, then
3338	       this is `eq'ual to defcell.  */
3339	    Lisp_Object valcell;
3340	  };
3341
3342	enum Lisp_Fwd_Predicate
3343	{
3344	  FWDPRED_Qnil,
3345	  FWDPRED_Qintegerp,
3346	  FWDPRED_Qsymbolp,
3347	  FWDPRED_Qstringp,
3348	  FWDPRED_Qnumberp,
3349	  FWDPRED_Qfraction,
3350	  FWDPRED_Qvertical_scroll_bar,
3351	  FWDPRED_Qoverwrite_mode,
3352	};
3353
3354	/* A struct Lisp_Fwd is used to locate a variable.  See Lisp_Fwd_Type
3355	   for the various types of variables.
3356
3357	   Lisp_Fwd structs are created by macros like DEFVAR_INT, DEFVAR_BOOL etc.
3358	   and are always kept in static variables.  They are never allocated
3359	   dynamically. */
3360
3361	struct Lisp_Fwd
3362	{
3363	  enum Lisp_Fwd_Type type : 8;
3364	  union
3365	  {
3366	    intmax_t *intvar;
3367	    bool *boolvar;
3368	    Lisp_Object *objvar;
3369	    struct
3370	    {
3371	      uint16_t offset;
3372	      enum Lisp_Fwd_Predicate predicate : 8;
3373	    } buf;
3374	    int kbdoffset;
3375	  } u;
3376	};
3377
3378	INLINE enum Lisp_Fwd_Type
3379	XFWDTYPE (lispfwd a)
3380	{
3381	  return a->type;
3382	}
3383
3384	INLINE bool
3385	BUFFER_OBJFWDP (lispfwd a)
3386	{
3387	  return XFWDTYPE (a) == Lisp_Fwd_Buffer_Obj;
3388	}
3389
3390	INLINE int
3391	XBUFFER_OFFSET (lispfwd a)
3392	{
3393	  eassert (BUFFER_OBJFWDP (a));
3394	  return a->u.buf.offset;
3395	}
3396
3397	INLINE bool
3398	KBOARD_OBJFWDP (lispfwd a)
3399	{
3400	  return XFWDTYPE (a) == Lisp_Fwd_Kboard_Obj;
3401	}
3402
3403	^L
3404	/* Lisp floating point type.  */
3405	struct Lisp_Float
3406	{
3407	  GC_HEADER
3408	  int type;
3409	  union
3410	  {
3411	    double data;
3412	    struct Lisp_Float *chain;
3413	    GCALIGNED_UNION_MEMBER
3414	  } u;
3415	};
3416	static_assert (GCALIGNED (struct Lisp_Float));
3417
3418	INLINE bool
3419	(FLOATP) (Lisp_Object x)
3420	{
3421	  return lisp_h_FLOATP (x);
3422	}
3423
3424	INLINE struct Lisp_Float *
3425	XFLOAT (Lisp_Object a)
3426	{
3427	  eassert (FLOATP (a));
   0x000055555577b7dd <+12173>:	and    $0x7,%ecx
   0x000055555577b7e0 <+12176>:	jne    0x5555555b28fd <read_char-1859411>

3428	  struct Lisp_Float *f = XUNTAG (a, Lisp_Float, struct Lisp_Float);
3429	  igc_check_fwd (f, false);
3430	  return f;
   0x000055555577b7e6 <+12182>:	pxor   %xmm0,%xmm0
   0x000055555577b7ea <+12186>:	ucomisd 0x9(%rax),%xmm0
   0x000055555577b7ef <+12191>:	jp     0x55555577b826 <read_char+12246>
   0x000055555577b7f1 <+12193>:	jne    0x55555577b826 <read_char+12246>

./src/keyboard.c:
4363				     || XFLOAT_DATA (XCAR (XCDR (maybe_event->ie.arg))) != 0.0
   0x000055555577b7f3 <+12195>:	mov    0x30(%rbx),%rdi
   0x000055555577b7f7 <+12199>:	call   0x5555557630d0 <XCDR>
   0x000055555577b7fc <+12204>:	mov    %rax,%rdi
   0x000055555577b7ff <+12207>:	call   0x555555763090 <XCAR>

./src/lisp.h:
3427	  eassert (FLOATP (a));
   0x000055555577b804 <+12212>:	test   %r15b,%r15b
   0x000055555577b807 <+12215>:	jne    0x55555577b815 <read_char+12229>

740	  return lisp_h_XLI (o);
   0x000055555577b809 <+12217>:	lea    -0x7(%rax),%edx

3286	}
3287	INLINE Lisp_Object
3288	make_uint (uintmax_t n)
3289	{
3290	  return FIXNUM_OVERFLOW_P (n) ? make_biguint (n) : make_fixnum (n);
3291	}
3292
3293	/* Return a Lisp integer equal to the value of the C integer EXPR.  */
3294	#define INT_TO_INTEGER(expr) \
3295	  (EXPR_SIGNED (expr) ? make_int (expr) : make_uint (expr))
3296
3297	^L
3298	/* struct Lisp_Buffer_Local_Value is used in a symbol value cell when
3299	   the symbol has buffer-local bindings.  (Exception:
3300	   some buffer-local variables are built-in, with their values stored
3301	   in the buffer structure itself.  They are handled differently,
3302	   using struct Lisp_Buffer_Objfwd.)
3303
3304	   The `valcell' slot holds the variable's current value (unless `fwd'
3305	   is set).  This value is the one that corresponds to the loaded binding.
3306	   To read or set the variable, you must first make sure the right binding
3307	   is loaded; then you can access the value in (or through) `valcell'.
3308
3309	   `where' is the buffer for which the loaded binding was found.
3310	   If it has changed, to make sure the right binding is loaded it is
3311	   necessary to find which binding goes with the current buffer, then
3312	   load it.  To load it, first unload the previous binding.
3313
3314	   `local_if_set' indicates that merely setting the variable creates a
3315	   local binding for the current buffer.  Otherwise the latter, setting
3316	   the variable does not do that; only make-local-variable does that.  */
3317
3318	struct Lisp_Buffer_Local_Value
3319	  {
3320	    GC_HEADER
3321	    /* True means that merely setting the variable creates a local
3322	       binding for the current buffer.  */
3323	    bool_bf local_if_set : 1;
3324	    /* True means that the binding now loaded was found.
3325	       Presumably equivalent to (defcell!=valcell).  */
3326	    bool_bf found : 1;
3327	    /* If non-NULL, a forwarding to the C var where it should also be set.  */
3328	    lispfwd fwd;	/* Should never be (Buffer|Kboard)_Objfwd.  */
3329	    /* The buffer for which the loaded binding was found.  */
3330	    Lisp_Object where;
3331	    /* A cons cell that holds the default value.  It has the form
3332	       (SYMBOL . DEFAULT-VALUE).  */
3333	    Lisp_Object defcell;
3334	    /* The cons cell from `where's parameter alist.
3335	       It always has the form (SYMBOL . VALUE)
3336	       Note that if `fwd' is non-NULL, VALUE may be out of date.
3337	       Also if the currently loaded binding is the default binding, then
3338	       this is `eq'ual to defcell.  */
3339	    Lisp_Object valcell;
3340	  };
3341
3342	enum Lisp_Fwd_Predicate
3343	{
3344	  FWDPRED_Qnil,
3345	  FWDPRED_Qintegerp,
3346	  FWDPRED_Qsymbolp,
3347	  FWDPRED_Qstringp,
3348	  FWDPRED_Qnumberp,
3349	  FWDPRED_Qfraction,
3350	  FWDPRED_Qvertical_scroll_bar,
3351	  FWDPRED_Qoverwrite_mode,
3352	};
3353
3354	/* A struct Lisp_Fwd is used to locate a variable.  See Lisp_Fwd_Type
3355	   for the various types of variables.
3356
3357	   Lisp_Fwd structs are created by macros like DEFVAR_INT, DEFVAR_BOOL etc.
3358	   and are always kept in static variables.  They are never allocated
3359	   dynamically. */
3360
3361	struct Lisp_Fwd
3362	{
3363	  enum Lisp_Fwd_Type type : 8;
3364	  union
3365	  {
3366	    intmax_t *intvar;
3367	    bool *boolvar;
3368	    Lisp_Object *objvar;
3369	    struct
3370	    {
3371	      uint16_t offset;
3372	      enum Lisp_Fwd_Predicate predicate : 8;
3373	    } buf;
3374	    int kbdoffset;
3375	  } u;
3376	};
3377
3378	INLINE enum Lisp_Fwd_Type
3379	XFWDTYPE (lispfwd a)
3380	{
3381	  return a->type;
3382	}
3383
3384	INLINE bool
3385	BUFFER_OBJFWDP (lispfwd a)
3386	{
3387	  return XFWDTYPE (a) == Lisp_Fwd_Buffer_Obj;
3388	}
3389
3390	INLINE int
3391	XBUFFER_OFFSET (lispfwd a)
3392	{
3393	  eassert (BUFFER_OBJFWDP (a));
3394	  return a->u.buf.offset;
3395	}
3396
3397	INLINE bool
3398	KBOARD_OBJFWDP (lispfwd a)
3399	{
3400	  return XFWDTYPE (a) == Lisp_Fwd_Kboard_Obj;
3401	}
3402
3403	^L
3404	/* Lisp floating point type.  */
3405	struct Lisp_Float
3406	{
3407	  GC_HEADER
3408	  int type;
3409	  union
3410	  {
3411	    double data;
3412	    struct Lisp_Float *chain;
3413	    GCALIGNED_UNION_MEMBER
3414	  } u;
3415	};
3416	static_assert (GCALIGNED (struct Lisp_Float));
3417
3418	INLINE bool
3419	(FLOATP) (Lisp_Object x)
3420	{
3421	  return lisp_h_FLOATP (x);
3422	}
3423
3424	INLINE struct Lisp_Float *
3425	XFLOAT (Lisp_Object a)
3426	{
3427	  eassert (FLOATP (a));
   0x000055555577b80c <+12220>:	and    $0x7,%edx
   0x000055555577b80f <+12223>:	jne    0x5555555b291a <read_char-1859382>

3428	  struct Lisp_Float *f = XUNTAG (a, Lisp_Float, struct Lisp_Float);
3429	  igc_check_fwd (f, false);
3430	  return f;
   0x000055555577b815 <+12229>:	pxor   %xmm0,%xmm0
   0x000055555577b819 <+12233>:	ucomisd 0x9(%rax),%xmm0
   0x000055555577b81e <+12238>:	jp     0x55555577b826 <read_char+12246>
   0x000055555577b820 <+12240>:	je     0x55555577beca <read_char+13946>

./src/keyboard.c:
4369			      pinch_dx += XFLOAT_DATA (XCAR (maybe_event->ie.arg));
   0x000055555577b826 <+12246>:	mov    0x30(%rbx),%rdi
   0x000055555577b82a <+12250>:	call   0x555555763090 <XCAR>

./src/lisp.h:
3427	  eassert (FLOATP (a));
   0x000055555577b82f <+12255>:	movzbl 0x3a0b49(%rip),%r12d        # 0x555555b1c380 <suppress_checking>
   0x000055555577b837 <+12263>:	test   %r12b,%r12b
   0x000055555577b83a <+12266>:	jne    0x55555577b848 <read_char+12280>

740	  return lisp_h_XLI (o);
   0x000055555577b83c <+12268>:	lea    -0x7(%rax),%edx

3286	}
3287	INLINE Lisp_Object
3288	make_uint (uintmax_t n)
3289	{
3290	  return FIXNUM_OVERFLOW_P (n) ? make_biguint (n) : make_fixnum (n);
3291	}
3292
3293	/* Return a Lisp integer equal to the value of the C integer EXPR.  */
3294	#define INT_TO_INTEGER(expr) \
3295	  (EXPR_SIGNED (expr) ? make_int (expr) : make_uint (expr))
3296
3297	^L
3298	/* struct Lisp_Buffer_Local_Value is used in a symbol value cell when
3299	   the symbol has buffer-local bindings.  (Exception:
3300	   some buffer-local variables are built-in, with their values stored
3301	   in the buffer structure itself.  They are handled differently,
3302	   using struct Lisp_Buffer_Objfwd.)
3303
3304	   The `valcell' slot holds the variable's current value (unless `fwd'
3305	   is set).  This value is the one that corresponds to the loaded binding.
3306	   To read or set the variable, you must first make sure the right binding
3307	   is loaded; then you can access the value in (or through) `valcell'.
3308
3309	   `where' is the buffer for which the loaded binding was found.
3310	   If it has changed, to make sure the right binding is loaded it is
3311	   necessary to find which binding goes with the current buffer, then
3312	   load it.  To load it, first unload the previous binding.
3313
3314	   `local_if_set' indicates that merely setting the variable creates a
3315	   local binding for the current buffer.  Otherwise the latter, setting
3316	   the variable does not do that; only make-local-variable does that.  */
3317
3318	struct Lisp_Buffer_Local_Value
3319	  {
3320	    GC_HEADER
3321	    /* True means that merely setting the variable creates a local
3322	       binding for the current buffer.  */
3323	    bool_bf local_if_set : 1;
3324	    /* True means that the binding now loaded was found.
3325	       Presumably equivalent to (defcell!=valcell).  */
3326	    bool_bf found : 1;
3327	    /* If non-NULL, a forwarding to the C var where it should also be set.  */
3328	    lispfwd fwd;	/* Should never be (Buffer|Kboard)_Objfwd.  */
3329	    /* The buffer for which the loaded binding was found.  */
3330	    Lisp_Object where;
3331	    /* A cons cell that holds the default value.  It has the form
3332	       (SYMBOL . DEFAULT-VALUE).  */
3333	    Lisp_Object defcell;
3334	    /* The cons cell from `where's parameter alist.
3335	       It always has the form (SYMBOL . VALUE)
3336	       Note that if `fwd' is non-NULL, VALUE may be out of date.
3337	       Also if the currently loaded binding is the default binding, then
3338	       this is `eq'ual to defcell.  */
3339	    Lisp_Object valcell;
3340	  };
3341
3342	enum Lisp_Fwd_Predicate
3343	{
3344	  FWDPRED_Qnil,
3345	  FWDPRED_Qintegerp,
3346	  FWDPRED_Qsymbolp,
3347	  FWDPRED_Qstringp,
3348	  FWDPRED_Qnumberp,
3349	  FWDPRED_Qfraction,
3350	  FWDPRED_Qvertical_scroll_bar,
3351	  FWDPRED_Qoverwrite_mode,
3352	};
3353
3354	/* A struct Lisp_Fwd is used to locate a variable.  See Lisp_Fwd_Type
3355	   for the various types of variables.
3356
3357	   Lisp_Fwd structs are created by macros like DEFVAR_INT, DEFVAR_BOOL etc.
3358	   and are always kept in static variables.  They are never allocated
3359	   dynamically. */
3360
3361	struct Lisp_Fwd
3362	{
3363	  enum Lisp_Fwd_Type type : 8;
3364	  union
3365	  {
3366	    intmax_t *intvar;
3367	    bool *boolvar;
3368	    Lisp_Object *objvar;
3369	    struct
3370	    {
3371	      uint16_t offset;
3372	      enum Lisp_Fwd_Predicate predicate : 8;
3373	    } buf;
3374	    int kbdoffset;
3375	  } u;
3376	};
3377
3378	INLINE enum Lisp_Fwd_Type
3379	XFWDTYPE (lispfwd a)
3380	{
3381	  return a->type;
3382	}
3383
3384	INLINE bool
3385	BUFFER_OBJFWDP (lispfwd a)
3386	{
3387	  return XFWDTYPE (a) == Lisp_Fwd_Buffer_Obj;
3388	}
3389
3390	INLINE int
3391	XBUFFER_OFFSET (lispfwd a)
3392	{
3393	  eassert (BUFFER_OBJFWDP (a));
3394	  return a->u.buf.offset;
3395	}
3396
3397	INLINE bool
3398	KBOARD_OBJFWDP (lispfwd a)
3399	{
3400	  return XFWDTYPE (a) == Lisp_Fwd_Kboard_Obj;
3401	}
3402
3403	^L
3404	/* Lisp floating point type.  */
3405	struct Lisp_Float
3406	{
3407	  GC_HEADER
3408	  int type;
3409	  union
3410	  {
3411	    double data;
3412	    struct Lisp_Float *chain;
3413	    GCALIGNED_UNION_MEMBER
3414	  } u;
3415	};
3416	static_assert (GCALIGNED (struct Lisp_Float));
3417
3418	INLINE bool
3419	(FLOATP) (Lisp_Object x)
3420	{
3421	  return lisp_h_FLOATP (x);
3422	}
3423
3424	INLINE struct Lisp_Float *
3425	XFLOAT (Lisp_Object a)
3426	{
3427	  eassert (FLOATP (a));
   0x000055555577b83f <+12271>:	and    $0x7,%edx
   0x000055555577b842 <+12274>:	jne    0x5555555b27de <read_char-1859698>

3428	  struct Lisp_Float *f = XUNTAG (a, Lisp_Float, struct Lisp_Float);
3429	  igc_check_fwd (f, false);
3430	  return f;
   0x000055555577b848 <+12280>:	movsd  -0x540(%rbp),%xmm1
   0x000055555577b850 <+12288>:	addsd  0x9(%rax),%xmm1

./src/keyboard.c:
4370			      pinch_dy += XFLOAT_DATA (XCAR (XCDR (maybe_event->ie.arg)));
   0x000055555577b855 <+12293>:	mov    0x30(%rbx),%rdi

4369			      pinch_dx += XFLOAT_DATA (XCAR (maybe_event->ie.arg));
   0x000055555577b859 <+12297>:	movsd  %xmm1,-0x540(%rbp)

4370			      pinch_dy += XFLOAT_DATA (XCAR (XCDR (maybe_event->ie.arg)));
   0x000055555577b861 <+12305>:	call   0x5555557630d0 <XCDR>
   0x000055555577b866 <+12310>:	mov    %rax,%rdi
   0x000055555577b869 <+12313>:	call   0x555555763090 <XCAR>

./src/lisp.h:
3427	  eassert (FLOATP (a));
   0x000055555577b86e <+12318>:	test   %r12b,%r12b
   0x000055555577b871 <+12321>:	jne    0x55555577b87f <read_char+12335>

740	  return lisp_h_XLI (o);
   0x000055555577b873 <+12323>:	lea    -0x7(%rax),%edx

3286	}
3287	INLINE Lisp_Object
3288	make_uint (uintmax_t n)
3289	{
3290	  return FIXNUM_OVERFLOW_P (n) ? make_biguint (n) : make_fixnum (n);
3291	}
3292
3293	/* Return a Lisp integer equal to the value of the C integer EXPR.  */
3294	#define INT_TO_INTEGER(expr) \
3295	  (EXPR_SIGNED (expr) ? make_int (expr) : make_uint (expr))
3296
3297	^L
3298	/* struct Lisp_Buffer_Local_Value is used in a symbol value cell when
3299	   the symbol has buffer-local bindings.  (Exception:
3300	   some buffer-local variables are built-in, with their values stored
3301	   in the buffer structure itself.  They are handled differently,
3302	   using struct Lisp_Buffer_Objfwd.)
3303
3304	   The `valcell' slot holds the variable's current value (unless `fwd'
3305	   is set).  This value is the one that corresponds to the loaded binding.
3306	   To read or set the variable, you must first make sure the right binding
3307	   is loaded; then you can access the value in (or through) `valcell'.
3308
3309	   `where' is the buffer for which the loaded binding was found.
3310	   If it has changed, to make sure the right binding is loaded it is
3311	   necessary to find which binding goes with the current buffer, then
3312	   load it.  To load it, first unload the previous binding.
3313
3314	   `local_if_set' indicates that merely setting the variable creates a
3315	   local binding for the current buffer.  Otherwise the latter, setting
3316	   the variable does not do that; only make-local-variable does that.  */
3317
3318	struct Lisp_Buffer_Local_Value
3319	  {
3320	    GC_HEADER
3321	    /* True means that merely setting the variable creates a local
3322	       binding for the current buffer.  */
3323	    bool_bf local_if_set : 1;
3324	    /* True means that the binding now loaded was found.
3325	       Presumably equivalent to (defcell!=valcell).  */
3326	    bool_bf found : 1;
3327	    /* If non-NULL, a forwarding to the C var where it should also be set.  */
3328	    lispfwd fwd;	/* Should never be (Buffer|Kboard)_Objfwd.  */
3329	    /* The buffer for which the loaded binding was found.  */
3330	    Lisp_Object where;
3331	    /* A cons cell that holds the default value.  It has the form
3332	       (SYMBOL . DEFAULT-VALUE).  */
3333	    Lisp_Object defcell;
3334	    /* The cons cell from `where's parameter alist.
3335	       It always has the form (SYMBOL . VALUE)
3336	       Note that if `fwd' is non-NULL, VALUE may be out of date.
3337	       Also if the currently loaded binding is the default binding, then
3338	       this is `eq'ual to defcell.  */
3339	    Lisp_Object valcell;
3340	  };
3341
3342	enum Lisp_Fwd_Predicate
3343	{
3344	  FWDPRED_Qnil,
3345	  FWDPRED_Qintegerp,
3346	  FWDPRED_Qsymbolp,
3347	  FWDPRED_Qstringp,
3348	  FWDPRED_Qnumberp,
3349	  FWDPRED_Qfraction,
3350	  FWDPRED_Qvertical_scroll_bar,
3351	  FWDPRED_Qoverwrite_mode,
3352	};
3353
3354	/* A struct Lisp_Fwd is used to locate a variable.  See Lisp_Fwd_Type
3355	   for the various types of variables.
3356
3357	   Lisp_Fwd structs are created by macros like DEFVAR_INT, DEFVAR_BOOL etc.
3358	   and are always kept in static variables.  They are never allocated
3359	   dynamically. */
3360
3361	struct Lisp_Fwd
3362	{
3363	  enum Lisp_Fwd_Type type : 8;
3364	  union
3365	  {
3366	    intmax_t *intvar;
3367	    bool *boolvar;
3368	    Lisp_Object *objvar;
3369	    struct
3370	    {
3371	      uint16_t offset;
3372	      enum Lisp_Fwd_Predicate predicate : 8;
3373	    } buf;
3374	    int kbdoffset;
3375	  } u;
3376	};
3377
3378	INLINE enum Lisp_Fwd_Type
3379	XFWDTYPE (lispfwd a)
3380	{
3381	  return a->type;
3382	}
3383
3384	INLINE bool
3385	BUFFER_OBJFWDP (lispfwd a)
3386	{
3387	  return XFWDTYPE (a) == Lisp_Fwd_Buffer_Obj;
3388	}
3389
3390	INLINE int
3391	XBUFFER_OFFSET (lispfwd a)
3392	{
3393	  eassert (BUFFER_OBJFWDP (a));
3394	  return a->u.buf.offset;
3395	}
3396
3397	INLINE bool
3398	KBOARD_OBJFWDP (lispfwd a)
3399	{
3400	  return XFWDTYPE (a) == Lisp_Fwd_Kboard_Obj;
3401	}
3402
3403	^L
3404	/* Lisp floating point type.  */
3405	struct Lisp_Float
3406	{
3407	  GC_HEADER
3408	  int type;
3409	  union
3410	  {
3411	    double data;
3412	    struct Lisp_Float *chain;
3413	    GCALIGNED_UNION_MEMBER
3414	  } u;
3415	};
3416	static_assert (GCALIGNED (struct Lisp_Float));
3417
3418	INLINE bool
3419	(FLOATP) (Lisp_Object x)
3420	{
3421	  return lisp_h_FLOATP (x);
3422	}
3423
3424	INLINE struct Lisp_Float *
3425	XFLOAT (Lisp_Object a)
3426	{
3427	  eassert (FLOATP (a));
   0x000055555577b876 <+12326>:	and    $0x7,%edx
   0x000055555577b879 <+12329>:	jne    0x5555555b27f6 <read_char-1859674>

3428	  struct Lisp_Float *f = XUNTAG (a, Lisp_Float, struct Lisp_Float);
3429	  igc_check_fwd (f, false);
3430	  return f;
   0x000055555577b87f <+12335>:	movsd  -0x530(%rbp),%xmm4
   0x000055555577b887 <+12343>:	addsd  0x9(%rax),%xmm4

./src/keyboard.c:
4371			      pinch_angle += XFLOAT_DATA (Fnth (make_fixnum (3),
   0x000055555577b88c <+12348>:	mov    $0xe,%edi
   0x000055555577b891 <+12353>:	mov    0x30(%rbx),%rsi

4370			      pinch_dy += XFLOAT_DATA (XCAR (XCDR (maybe_event->ie.arg)));
   0x000055555577b895 <+12357>:	movsd  %xmm4,-0x530(%rbp)

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577b89d <+12365>:	call   0x55555582c7d0 <Fnth>

3286	}
3287	INLINE Lisp_Object
3288	make_uint (uintmax_t n)
3289	{
3290	  return FIXNUM_OVERFLOW_P (n) ? make_biguint (n) : make_fixnum (n);
3291	}
3292
3293	/* Return a Lisp integer equal to the value of the C integer EXPR.  */
3294	#define INT_TO_INTEGER(expr) \
3295	  (EXPR_SIGNED (expr) ? make_int (expr) : make_uint (expr))
3296
3297	^L
3298	/* struct Lisp_Buffer_Local_Value is used in a symbol value cell when
3299	   the symbol has buffer-local bindings.  (Exception:
3300	   some buffer-local variables are built-in, with their values stored
3301	   in the buffer structure itself.  They are handled differently,
3302	   using struct Lisp_Buffer_Objfwd.)
3303
3304	   The `valcell' slot holds the variable's current value (unless `fwd'
3305	   is set).  This value is the one that corresponds to the loaded binding.
3306	   To read or set the variable, you must first make sure the right binding
3307	   is loaded; then you can access the value in (or through) `valcell'.
3308
3309	   `where' is the buffer for which the loaded binding was found.
3310	   If it has changed, to make sure the right binding is loaded it is
3311	   necessary to find which binding goes with the current buffer, then
3312	   load it.  To load it, first unload the previous binding.
3313
3314	   `local_if_set' indicates that merely setting the variable creates a
3315	   local binding for the current buffer.  Otherwise the latter, setting
3316	   the variable does not do that; only make-local-variable does that.  */
3317
3318	struct Lisp_Buffer_Local_Value
3319	  {
3320	    GC_HEADER
3321	    /* True means that merely setting the variable creates a local
3322	       binding for the current buffer.  */
3323	    bool_bf local_if_set : 1;
3324	    /* True means that the binding now loaded was found.
3325	       Presumably equivalent to (defcell!=valcell).  */
3326	    bool_bf found : 1;
3327	    /* If non-NULL, a forwarding to the C var where it should also be set.  */
3328	    lispfwd fwd;	/* Should never be (Buffer|Kboard)_Objfwd.  */
3329	    /* The buffer for which the loaded binding was found.  */
3330	    Lisp_Object where;
3331	    /* A cons cell that holds the default value.  It has the form
3332	       (SYMBOL . DEFAULT-VALUE).  */
3333	    Lisp_Object defcell;
3334	    /* The cons cell from `where's parameter alist.
3335	       It always has the form (SYMBOL . VALUE)
3336	       Note that if `fwd' is non-NULL, VALUE may be out of date.
3337	       Also if the currently loaded binding is the default binding, then
3338	       this is `eq'ual to defcell.  */
3339	    Lisp_Object valcell;
3340	  };
3341
3342	enum Lisp_Fwd_Predicate
3343	{
3344	  FWDPRED_Qnil,
3345	  FWDPRED_Qintegerp,
3346	  FWDPRED_Qsymbolp,
3347	  FWDPRED_Qstringp,
3348	  FWDPRED_Qnumberp,
3349	  FWDPRED_Qfraction,
3350	  FWDPRED_Qvertical_scroll_bar,
3351	  FWDPRED_Qoverwrite_mode,
3352	};
3353
3354	/* A struct Lisp_Fwd is used to locate a variable.  See Lisp_Fwd_Type
3355	   for the various types of variables.
3356
3357	   Lisp_Fwd structs are created by macros like DEFVAR_INT, DEFVAR_BOOL etc.
3358	   and are always kept in static variables.  They are never allocated
3359	   dynamically. */
3360
3361	struct Lisp_Fwd
3362	{
3363	  enum Lisp_Fwd_Type type : 8;
3364	  union
3365	  {
3366	    intmax_t *intvar;
3367	    bool *boolvar;
3368	    Lisp_Object *objvar;
3369	    struct
3370	    {
3371	      uint16_t offset;
3372	      enum Lisp_Fwd_Predicate predicate : 8;
3373	    } buf;
3374	    int kbdoffset;
3375	  } u;
3376	};
3377
3378	INLINE enum Lisp_Fwd_Type
3379	XFWDTYPE (lispfwd a)
3380	{
3381	  return a->type;
3382	}
3383
3384	INLINE bool
3385	BUFFER_OBJFWDP (lispfwd a)
3386	{
3387	  return XFWDTYPE (a) == Lisp_Fwd_Buffer_Obj;
3388	}
3389
3390	INLINE int
3391	XBUFFER_OFFSET (lispfwd a)
3392	{
3393	  eassert (BUFFER_OBJFWDP (a));
3394	  return a->u.buf.offset;
3395	}
3396
3397	INLINE bool
3398	KBOARD_OBJFWDP (lispfwd a)
3399	{
3400	  return XFWDTYPE (a) == Lisp_Fwd_Kboard_Obj;
3401	}
3402
3403	^L
3404	/* Lisp floating point type.  */
3405	struct Lisp_Float
3406	{
3407	  GC_HEADER
3408	  int type;
3409	  union
3410	  {
3411	    double data;
3412	    struct Lisp_Float *chain;
3413	    GCALIGNED_UNION_MEMBER
3414	  } u;
3415	};
3416	static_assert (GCALIGNED (struct Lisp_Float));
3417
3418	INLINE bool
3419	(FLOATP) (Lisp_Object x)
3420	{
3421	  return lisp_h_FLOATP (x);
3422	}
3423
3424	INLINE struct Lisp_Float *
3425	XFLOAT (Lisp_Object a)
3426	{
3427	  eassert (FLOATP (a));
   0x000055555577b8a2 <+12370>:	cmpb   $0x0,0x3a0ad7(%rip)        # 0x555555b1c380 <suppress_checking>
   0x000055555577b8a9 <+12377>:	jne    0x55555577b8b7 <read_char+12391>

740	  return lisp_h_XLI (o);
   0x000055555577b8ab <+12379>:	lea    -0x7(%rax),%edx

3286	}
3287	INLINE Lisp_Object
3288	make_uint (uintmax_t n)
3289	{
3290	  return FIXNUM_OVERFLOW_P (n) ? make_biguint (n) : make_fixnum (n);
3291	}
3292
3293	/* Return a Lisp integer equal to the value of the C integer EXPR.  */
3294	#define INT_TO_INTEGER(expr) \
3295	  (EXPR_SIGNED (expr) ? make_int (expr) : make_uint (expr))
3296
3297	^L
3298	/* struct Lisp_Buffer_Local_Value is used in a symbol value cell when
3299	   the symbol has buffer-local bindings.  (Exception:
3300	   some buffer-local variables are built-in, with their values stored
3301	   in the buffer structure itself.  They are handled differently,
3302	   using struct Lisp_Buffer_Objfwd.)
3303
3304	   The `valcell' slot holds the variable's current value (unless `fwd'
3305	   is set).  This value is the one that corresponds to the loaded binding.
3306	   To read or set the variable, you must first make sure the right binding
3307	   is loaded; then you can access the value in (or through) `valcell'.
3308
3309	   `where' is the buffer for which the loaded binding was found.
3310	   If it has changed, to make sure the right binding is loaded it is
3311	   necessary to find which binding goes with the current buffer, then
3312	   load it.  To load it, first unload the previous binding.
3313
3314	   `local_if_set' indicates that merely setting the variable creates a
3315	   local binding for the current buffer.  Otherwise the latter, setting
3316	   the variable does not do that; only make-local-variable does that.  */
3317
3318	struct Lisp_Buffer_Local_Value
3319	  {
3320	    GC_HEADER
3321	    /* True means that merely setting the variable creates a local
3322	       binding for the current buffer.  */
3323	    bool_bf local_if_set : 1;
3324	    /* True means that the binding now loaded was found.
3325	       Presumably equivalent to (defcell!=valcell).  */
3326	    bool_bf found : 1;
3327	    /* If non-NULL, a forwarding to the C var where it should also be set.  */
3328	    lispfwd fwd;	/* Should never be (Buffer|Kboard)_Objfwd.  */
3329	    /* The buffer for which the loaded binding was found.  */
3330	    Lisp_Object where;
3331	    /* A cons cell that holds the default value.  It has the form
3332	       (SYMBOL . DEFAULT-VALUE).  */
3333	    Lisp_Object defcell;
3334	    /* The cons cell from `where's parameter alist.
3335	       It always has the form (SYMBOL . VALUE)
3336	       Note that if `fwd' is non-NULL, VALUE may be out of date.
3337	       Also if the currently loaded binding is the default binding, then
3338	       this is `eq'ual to defcell.  */
3339	    Lisp_Object valcell;
3340	  };
3341
3342	enum Lisp_Fwd_Predicate
3343	{
3344	  FWDPRED_Qnil,
3345	  FWDPRED_Qintegerp,
3346	  FWDPRED_Qsymbolp,
3347	  FWDPRED_Qstringp,
3348	  FWDPRED_Qnumberp,
3349	  FWDPRED_Qfraction,
3350	  FWDPRED_Qvertical_scroll_bar,
3351	  FWDPRED_Qoverwrite_mode,
3352	};
3353
3354	/* A struct Lisp_Fwd is used to locate a variable.  See Lisp_Fwd_Type
3355	   for the various types of variables.
3356
3357	   Lisp_Fwd structs are created by macros like DEFVAR_INT, DEFVAR_BOOL etc.
3358	   and are always kept in static variables.  They are never allocated
3359	   dynamically. */
3360
3361	struct Lisp_Fwd
3362	{
3363	  enum Lisp_Fwd_Type type : 8;
3364	  union
3365	  {
3366	    intmax_t *intvar;
3367	    bool *boolvar;
3368	    Lisp_Object *objvar;
3369	    struct
3370	    {
3371	      uint16_t offset;
3372	      enum Lisp_Fwd_Predicate predicate : 8;
3373	    } buf;
3374	    int kbdoffset;
3375	  } u;
3376	};
3377
3378	INLINE enum Lisp_Fwd_Type
3379	XFWDTYPE (lispfwd a)
3380	{
3381	  return a->type;
3382	}
3383
3384	INLINE bool
3385	BUFFER_OBJFWDP (lispfwd a)
3386	{
3387	  return XFWDTYPE (a) == Lisp_Fwd_Buffer_Obj;
3388	}
3389
3390	INLINE int
3391	XBUFFER_OFFSET (lispfwd a)
3392	{
3393	  eassert (BUFFER_OBJFWDP (a));
3394	  return a->u.buf.offset;
3395	}
3396
3397	INLINE bool
3398	KBOARD_OBJFWDP (lispfwd a)
3399	{
3400	  return XFWDTYPE (a) == Lisp_Fwd_Kboard_Obj;
3401	}
3402
3403	^L
3404	/* Lisp floating point type.  */
3405	struct Lisp_Float
3406	{
3407	  GC_HEADER
3408	  int type;
3409	  union
3410	  {
3411	    double data;
3412	    struct Lisp_Float *chain;
3413	    GCALIGNED_UNION_MEMBER
3414	  } u;
3415	};
3416	static_assert (GCALIGNED (struct Lisp_Float));
3417
3418	INLINE bool
3419	(FLOATP) (Lisp_Object x)
3420	{
3421	  return lisp_h_FLOATP (x);
3422	}
3423
3424	INLINE struct Lisp_Float *
3425	XFLOAT (Lisp_Object a)
3426	{
3427	  eassert (FLOATP (a));
   0x000055555577b8ae <+12382>:	and    $0x7,%edx
   0x000055555577b8b1 <+12385>:	jne    0x5555555b280e <read_char-1859650>

3428	  struct Lisp_Float *f = XUNTAG (a, Lisp_Float, struct Lisp_Float);
3429	  igc_check_fwd (f, false);
3430	  return f;
   0x000055555577b8b7 <+12391>:	movsd  -0x538(%rbp),%xmm5
   0x000055555577b8bf <+12399>:	addsd  0x9(%rax),%xmm5

./src/keyboard.c:
4374			      XSETCAR (maybe_event->ie.arg, make_float (pinch_dx));
   0x000055555577b8c4 <+12404>:	movsd  -0x540(%rbp),%xmm0

4371			      pinch_angle += XFLOAT_DATA (Fnth (make_fixnum (3),
   0x000055555577b8cc <+12412>:	movsd  %xmm5,-0x538(%rbp)

4372								maybe_event->ie.arg));
4373
4374			      XSETCAR (maybe_event->ie.arg, make_float (pinch_dx));
   0x000055555577b8d4 <+12420>:	call   0x5555557ef5b0 <make_float>

./src/lisp.h:
1515	  eassert (CONSP (a));
   0x000055555577b8d9 <+12425>:	cmpb   $0x0,0x3a0aa0(%rip)        # 0x555555b1c380 <suppress_checking>
   0x000055555577b8e0 <+12432>:	mov    0x30(%rbx),%rdx
   0x000055555577b8e4 <+12436>:	jne    0x55555577b8f2 <read_char+12450>

740	  return lisp_h_XLI (o);
   0x000055555577b8e6 <+12438>:	lea    -0x3(%rdx),%ecx

1384	}
1385
1386	#define XSETINT(a, b) ((a) = make_fixnum (b))
1387	#define XSETFASTINT(a, b) ((a) = make_fixed_natnum (b))
1388	#define XSETCONS(a, b) ((a) = make_lisp_ptr (b, Lisp_Cons))
1389	#define XSETVECTOR(a, b) ((a) = make_lisp_ptr (b, Lisp_Vectorlike))
1390	#define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String))
1391	#define XSETSYMBOL(a, b) ((a) = make_lisp_symbol (b))
1392	#define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float))
1393
1394	/* Return a Lisp_Object value that does not correspond to any object.
1395	   This can make some Lisp objects on free lists recognizable in O(1).  */
1396
1397	INLINE Lisp_Object
1398	dead_object (void)
1399	{
1400	  return make_lisp_ptr (NULL, Lisp_String);
1401	}
1402
1403	/* Pseudovector types.  */
1404
1405	#define XSETPVECTYPE(v, code)						\
1406	  ((v)->header.size |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS))
1407	#define PVECHEADERSIZE(code, lispsize, restsize) \
1408	  (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS) \
1409	   | ((restsize) << PSEUDOVECTOR_SIZE_BITS) | (lispsize))
1410	#define XSETPVECTYPESIZE(v, code, lispsize, restsize)		\
1411	  ((v)->header.size = PVECHEADERSIZE (code, lispsize, restsize))
1412
1413	/* The cast to struct vectorlike_header * avoids aliasing issues.  */
1414	#define XSETPSEUDOVECTOR(a, b, code) \
1415	  XSETTYPED_PSEUDOVECTOR (a, b,					\
1416				  (XUNTAG (a, Lisp_Vectorlike,		\
1417					   struct vectorlike_header)	\
1418				   ->size),				\
1419				  code)
1420	#define XSETTYPED_PSEUDOVECTOR(a, b, size, code)			\
1421	  (XSETVECTOR (a, b),							\
1422	   eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))		\
1423		    == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS))))
1424
1425	#define XSETWINDOW_CONFIGURATION(a, b) \
1426	  XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION)
1427	#define XSETPROCESS(a, b) XSETPSEUDOVECTOR (a, b, PVEC_PROCESS)
1428	#define XSETWINDOW(a, b) XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)
1429	#define XSETTERMINAL(a, b) XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)
1430	#define XSETSUBR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_SUBR)
1431	#define XSETBUFFER(a, b) XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)
1432	#define XSETCHAR_TABLE(a, b) XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)
1433	#define XSETBOOL_VECTOR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR)
1434	#define XSETSUB_CHAR_TABLE(a, b) XSETPSEUDOVECTOR (a, b, PVEC_SUB_CHAR_TABLE)
1435	#define XSETTHREAD(a, b) XSETPSEUDOVECTOR (a, b, PVEC_THREAD)
1436	#define XSETMUTEX(a, b) XSETPSEUDOVECTOR (a, b, PVEC_MUTEX)
1437	#define XSETCONDVAR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_CONDVAR)
1438	#define XSETNATIVE_COMP_UNIT(a, b) XSETPSEUDOVECTOR (a, b, PVEC_NATIVE_COMP_UNIT)
1439
1440	/* Efficiently convert a pointer to a Lisp object and back.  The
1441	   pointer is represented as a fixnum, so the garbage collector
1442	   does not know about it.  The pointer should not have both Lisp_Int1
1443	   bits set, which makes this conversion inherently unportable.  */
1444
1445	INLINE void *
1446	XFIXNUMPTR (Lisp_Object a)
1447	{
1448	  return XUNTAG (a, Lisp_Int0, char);
1449	}
1450
1451	INLINE Lisp_Object
1452	make_pointer_integer_unsafe (void *p)
1453	{
1454	  Lisp_Object a = TAG_PTR_INITIALLY (Lisp_Int0, p);
1455	  return a;
1456	}
1457
1458	INLINE Lisp_Object
1459	make_pointer_integer (void *p)
1460	{
1461	  Lisp_Object a = make_pointer_integer_unsafe (p);
1462	  eassert (FIXNUMP (a) && XFIXNUMPTR (a) == p);
1463	  return a;
1464	}
1465
1466	/* See the macros in intervals.h.  */
1467
1468	typedef struct interval *INTERVAL;
1469
1470	struct Lisp_Cons
1471	{
1472	  GC_HEADER
1473	  union
1474	  {
1475	    struct
1476	    {
1477	      /* Car of this cons cell.  */
1478	      Lisp_Object car;
1479
1480	      union
1481	      {
1482		/* Cdr of this cons cell.  */
1483		Lisp_Object cdr;
1484
1485		/* Used to chain conses on a free list.  */
1486		struct Lisp_Cons *chain;
1487	      } u;
1488	    } s;
1489	    GCALIGNED_UNION_MEMBER
1490	  } u;
1491	};
1492	static_assert (GCALIGNED (struct Lisp_Cons));
1493
1494	INLINE bool
1495	(NILP) (Lisp_Object x)
1496	{
1497	  return lisp_h_NILP (x);
1498	}
1499
1500	INLINE bool
1501	(CONSP) (Lisp_Object x)
1502	{
1503	  return lisp_h_CONSP (x);
1504	}
1505
1506	INLINE void
1507	CHECK_CONS (Lisp_Object x)
1508	{
1509	  CHECK_TYPE (CONSP (x), Qconsp, x);
1510	}
1511
1512	INLINE struct Lisp_Cons *
1513	XCONS (Lisp_Object a)
1514	{
1515	  eassert (CONSP (a));
   0x000055555577b8e9 <+12441>:	and    $0x7,%ecx
   0x000055555577b8ec <+12444>:	jne    0x5555555b2826 <read_char-1859626>

1517	  igc_check_fwd (c, false);
1518	  return c;
   0x000055555577b8f2 <+12450>:	mov    %rax,0x5(%rdx)

./src/keyboard.c:
4375			      XSETCAR (XCDR (maybe_event->ie.arg), make_float (pinch_dy));
   0x000055555577b8f6 <+12454>:	movsd  -0x530(%rbp),%xmm0
   0x000055555577b8fe <+12462>:	call   0x5555557ef5b0 <make_float>
   0x000055555577b903 <+12467>:	mov    0x30(%rbx),%rdi
   0x000055555577b907 <+12471>:	mov    %rax,%r12
   0x000055555577b90a <+12474>:	call   0x5555557630d0 <XCDR>

./src/lisp.h:
1515	  eassert (CONSP (a));
   0x000055555577b90f <+12479>:	cmpb   $0x0,0x3a0a6a(%rip)        # 0x555555b1c380 <suppress_checking>
   0x000055555577b916 <+12486>:	jne    0x55555577b924 <read_char+12500>

740	  return lisp_h_XLI (o);
   0x000055555577b918 <+12488>:	lea    -0x3(%rax),%edx

1384	}
1385
1386	#define XSETINT(a, b) ((a) = make_fixnum (b))
1387	#define XSETFASTINT(a, b) ((a) = make_fixed_natnum (b))
1388	#define XSETCONS(a, b) ((a) = make_lisp_ptr (b, Lisp_Cons))
1389	#define XSETVECTOR(a, b) ((a) = make_lisp_ptr (b, Lisp_Vectorlike))
1390	#define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String))
1391	#define XSETSYMBOL(a, b) ((a) = make_lisp_symbol (b))
1392	#define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float))
1393
1394	/* Return a Lisp_Object value that does not correspond to any object.
1395	   This can make some Lisp objects on free lists recognizable in O(1).  */
1396
1397	INLINE Lisp_Object
1398	dead_object (void)
1399	{
1400	  return make_lisp_ptr (NULL, Lisp_String);
1401	}
1402
1403	/* Pseudovector types.  */
1404
1405	#define XSETPVECTYPE(v, code)						\
1406	  ((v)->header.size |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS))
1407	#define PVECHEADERSIZE(code, lispsize, restsize) \
1408	  (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS) \
1409	   | ((restsize) << PSEUDOVECTOR_SIZE_BITS) | (lispsize))
1410	#define XSETPVECTYPESIZE(v, code, lispsize, restsize)		\
1411	  ((v)->header.size = PVECHEADERSIZE (code, lispsize, restsize))
1412
1413	/* The cast to struct vectorlike_header * avoids aliasing issues.  */
1414	#define XSETPSEUDOVECTOR(a, b, code) \
1415	  XSETTYPED_PSEUDOVECTOR (a, b,					\
1416				  (XUNTAG (a, Lisp_Vectorlike,		\
1417					   struct vectorlike_header)	\
1418				   ->size),				\
1419				  code)
1420	#define XSETTYPED_PSEUDOVECTOR(a, b, size, code)			\
1421	  (XSETVECTOR (a, b),							\
1422	   eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))		\
1423		    == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS))))
1424
1425	#define XSETWINDOW_CONFIGURATION(a, b) \
1426	  XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION)
1427	#define XSETPROCESS(a, b) XSETPSEUDOVECTOR (a, b, PVEC_PROCESS)
1428	#define XSETWINDOW(a, b) XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)
1429	#define XSETTERMINAL(a, b) XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)
1430	#define XSETSUBR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_SUBR)
1431	#define XSETBUFFER(a, b) XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)
1432	#define XSETCHAR_TABLE(a, b) XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)
1433	#define XSETBOOL_VECTOR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR)
1434	#define XSETSUB_CHAR_TABLE(a, b) XSETPSEUDOVECTOR (a, b, PVEC_SUB_CHAR_TABLE)
1435	#define XSETTHREAD(a, b) XSETPSEUDOVECTOR (a, b, PVEC_THREAD)
1436	#define XSETMUTEX(a, b) XSETPSEUDOVECTOR (a, b, PVEC_MUTEX)
1437	#define XSETCONDVAR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_CONDVAR)
1438	#define XSETNATIVE_COMP_UNIT(a, b) XSETPSEUDOVECTOR (a, b, PVEC_NATIVE_COMP_UNIT)
1439
1440	/* Efficiently convert a pointer to a Lisp object and back.  The
1441	   pointer is represented as a fixnum, so the garbage collector
1442	   does not know about it.  The pointer should not have both Lisp_Int1
1443	   bits set, which makes this conversion inherently unportable.  */
1444
1445	INLINE void *
1446	XFIXNUMPTR (Lisp_Object a)
1447	{
1448	  return XUNTAG (a, Lisp_Int0, char);
1449	}
1450
1451	INLINE Lisp_Object
1452	make_pointer_integer_unsafe (void *p)
1453	{
1454	  Lisp_Object a = TAG_PTR_INITIALLY (Lisp_Int0, p);
1455	  return a;
1456	}
1457
1458	INLINE Lisp_Object
1459	make_pointer_integer (void *p)
1460	{
1461	  Lisp_Object a = make_pointer_integer_unsafe (p);
1462	  eassert (FIXNUMP (a) && XFIXNUMPTR (a) == p);
1463	  return a;
1464	}
1465
1466	/* See the macros in intervals.h.  */
1467
1468	typedef struct interval *INTERVAL;
1469
1470	struct Lisp_Cons
1471	{
1472	  GC_HEADER
1473	  union
1474	  {
1475	    struct
1476	    {
1477	      /* Car of this cons cell.  */
1478	      Lisp_Object car;
1479
1480	      union
1481	      {
1482		/* Cdr of this cons cell.  */
1483		Lisp_Object cdr;
1484
1485		/* Used to chain conses on a free list.  */
1486		struct Lisp_Cons *chain;
1487	      } u;
1488	    } s;
1489	    GCALIGNED_UNION_MEMBER
1490	  } u;
1491	};
1492	static_assert (GCALIGNED (struct Lisp_Cons));
1493
1494	INLINE bool
1495	(NILP) (Lisp_Object x)
1496	{
1497	  return lisp_h_NILP (x);
1498	}
1499
1500	INLINE bool
1501	(CONSP) (Lisp_Object x)
1502	{
1503	  return lisp_h_CONSP (x);
1504	}
1505
1506	INLINE void
1507	CHECK_CONS (Lisp_Object x)
1508	{
1509	  CHECK_TYPE (CONSP (x), Qconsp, x);
1510	}
1511
1512	INLINE struct Lisp_Cons *
1513	XCONS (Lisp_Object a)
1514	{
1515	  eassert (CONSP (a));
   0x000055555577b91b <+12491>:	and    $0x7,%edx
   0x000055555577b91e <+12494>:	jne    0x5555555b282b <read_char-1859621>

1517	  igc_check_fwd (c, false);
1518	  return c;
   0x000055555577b924 <+12500>:	mov    %r12,0x5(%rax)

./src/keyboard.c:
4376			      XSETCAR (Fnthcdr (make_fixnum (3),
   0x000055555577b928 <+12504>:	movsd  0x2556f0(%rip),%xmm1        # 0x5555559d1020
   0x000055555577b930 <+12512>:	movsd  -0x538(%rbp),%xmm0
   0x000055555577b938 <+12520>:	call   0x55555559c350 <fmod <at> plt>
   0x000055555577b93d <+12525>:	call   0x5555557ef5b0 <make_float>
   0x000055555577b942 <+12530>:	mov    0x30(%rbx),%rsi
   0x000055555577b946 <+12534>:	mov    $0xe,%edi
   0x000055555577b94b <+12539>:	mov    %rax,%r12

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577b94e <+12542>:	call   0x55555582c520 <Fnthcdr>

1384	}
1385
1386	#define XSETINT(a, b) ((a) = make_fixnum (b))
1387	#define XSETFASTINT(a, b) ((a) = make_fixed_natnum (b))
1388	#define XSETCONS(a, b) ((a) = make_lisp_ptr (b, Lisp_Cons))
1389	#define XSETVECTOR(a, b) ((a) = make_lisp_ptr (b, Lisp_Vectorlike))
1390	#define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String))
1391	#define XSETSYMBOL(a, b) ((a) = make_lisp_symbol (b))
1392	#define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float))
1393
1394	/* Return a Lisp_Object value that does not correspond to any object.
1395	   This can make some Lisp objects on free lists recognizable in O(1).  */
1396
1397	INLINE Lisp_Object
1398	dead_object (void)
1399	{
1400	  return make_lisp_ptr (NULL, Lisp_String);
1401	}
1402
1403	/* Pseudovector types.  */
1404
1405	#define XSETPVECTYPE(v, code)						\
1406	  ((v)->header.size |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS))
1407	#define PVECHEADERSIZE(code, lispsize, restsize) \
1408	  (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS) \
1409	   | ((restsize) << PSEUDOVECTOR_SIZE_BITS) | (lispsize))
1410	#define XSETPVECTYPESIZE(v, code, lispsize, restsize)		\
1411	  ((v)->header.size = PVECHEADERSIZE (code, lispsize, restsize))
1412
1413	/* The cast to struct vectorlike_header * avoids aliasing issues.  */
1414	#define XSETPSEUDOVECTOR(a, b, code) \
1415	  XSETTYPED_PSEUDOVECTOR (a, b,					\
1416				  (XUNTAG (a, Lisp_Vectorlike,		\
1417					   struct vectorlike_header)	\
1418				   ->size),				\
1419				  code)
1420	#define XSETTYPED_PSEUDOVECTOR(a, b, size, code)			\
1421	  (XSETVECTOR (a, b),							\
1422	   eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))		\
1423		    == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS))))
1424
1425	#define XSETWINDOW_CONFIGURATION(a, b) \
1426	  XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION)
1427	#define XSETPROCESS(a, b) XSETPSEUDOVECTOR (a, b, PVEC_PROCESS)
1428	#define XSETWINDOW(a, b) XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)
1429	#define XSETTERMINAL(a, b) XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)
1430	#define XSETSUBR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_SUBR)
1431	#define XSETBUFFER(a, b) XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)
1432	#define XSETCHAR_TABLE(a, b) XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)
1433	#define XSETBOOL_VECTOR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR)
1434	#define XSETSUB_CHAR_TABLE(a, b) XSETPSEUDOVECTOR (a, b, PVEC_SUB_CHAR_TABLE)
1435	#define XSETTHREAD(a, b) XSETPSEUDOVECTOR (a, b, PVEC_THREAD)
1436	#define XSETMUTEX(a, b) XSETPSEUDOVECTOR (a, b, PVEC_MUTEX)
1437	#define XSETCONDVAR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_CONDVAR)
1438	#define XSETNATIVE_COMP_UNIT(a, b) XSETPSEUDOVECTOR (a, b, PVEC_NATIVE_COMP_UNIT)
1439
1440	/* Efficiently convert a pointer to a Lisp object and back.  The
1441	   pointer is represented as a fixnum, so the garbage collector
1442	   does not know about it.  The pointer should not have both Lisp_Int1
1443	   bits set, which makes this conversion inherently unportable.  */
1444
1445	INLINE void *
1446	XFIXNUMPTR (Lisp_Object a)
1447	{
1448	  return XUNTAG (a, Lisp_Int0, char);
1449	}
1450
1451	INLINE Lisp_Object
1452	make_pointer_integer_unsafe (void *p)
1453	{
1454	  Lisp_Object a = TAG_PTR_INITIALLY (Lisp_Int0, p);
1455	  return a;
1456	}
1457
1458	INLINE Lisp_Object
1459	make_pointer_integer (void *p)
1460	{
1461	  Lisp_Object a = make_pointer_integer_unsafe (p);
1462	  eassert (FIXNUMP (a) && XFIXNUMPTR (a) == p);
1463	  return a;
1464	}
1465
1466	/* See the macros in intervals.h.  */
1467
1468	typedef struct interval *INTERVAL;
1469
1470	struct Lisp_Cons
1471	{
1472	  GC_HEADER
1473	  union
1474	  {
1475	    struct
1476	    {
1477	      /* Car of this cons cell.  */
1478	      Lisp_Object car;
1479
1480	      union
1481	      {
1482		/* Cdr of this cons cell.  */
1483		Lisp_Object cdr;
1484
1485		/* Used to chain conses on a free list.  */
1486		struct Lisp_Cons *chain;
1487	      } u;
1488	    } s;
1489	    GCALIGNED_UNION_MEMBER
1490	  } u;
1491	};
1492	static_assert (GCALIGNED (struct Lisp_Cons));
1493
1494	INLINE bool
1495	(NILP) (Lisp_Object x)
1496	{
1497	  return lisp_h_NILP (x);
1498	}
1499
1500	INLINE bool
1501	(CONSP) (Lisp_Object x)
1502	{
1503	  return lisp_h_CONSP (x);
1504	}
1505
1506	INLINE void
1507	CHECK_CONS (Lisp_Object x)
1508	{
1509	  CHECK_TYPE (CONSP (x), Qconsp, x);
1510	}
1511
1512	INLINE struct Lisp_Cons *
1513	XCONS (Lisp_Object a)
1514	{
1515	  eassert (CONSP (a));
   0x000055555577b953 <+12547>:	cmpb   $0x0,0x3a0a26(%rip)        # 0x555555b1c380 <suppress_checking>
   0x000055555577b95a <+12554>:	jne    0x55555577b968 <read_char+12568>

740	  return lisp_h_XLI (o);
   0x000055555577b95c <+12556>:	lea    -0x3(%rax),%edx

1384	}
1385
1386	#define XSETINT(a, b) ((a) = make_fixnum (b))
1387	#define XSETFASTINT(a, b) ((a) = make_fixed_natnum (b))
1388	#define XSETCONS(a, b) ((a) = make_lisp_ptr (b, Lisp_Cons))
1389	#define XSETVECTOR(a, b) ((a) = make_lisp_ptr (b, Lisp_Vectorlike))
1390	#define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String))
1391	#define XSETSYMBOL(a, b) ((a) = make_lisp_symbol (b))
1392	#define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float))
1393
1394	/* Return a Lisp_Object value that does not correspond to any object.
1395	   This can make some Lisp objects on free lists recognizable in O(1).  */
1396
1397	INLINE Lisp_Object
1398	dead_object (void)
1399	{
1400	  return make_lisp_ptr (NULL, Lisp_String);
1401	}
1402
1403	/* Pseudovector types.  */
1404
1405	#define XSETPVECTYPE(v, code)						\
1406	  ((v)->header.size |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS))
1407	#define PVECHEADERSIZE(code, lispsize, restsize) \
1408	  (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS) \
1409	   | ((restsize) << PSEUDOVECTOR_SIZE_BITS) | (lispsize))
1410	#define XSETPVECTYPESIZE(v, code, lispsize, restsize)		\
1411	  ((v)->header.size = PVECHEADERSIZE (code, lispsize, restsize))
1412
1413	/* The cast to struct vectorlike_header * avoids aliasing issues.  */
1414	#define XSETPSEUDOVECTOR(a, b, code) \
1415	  XSETTYPED_PSEUDOVECTOR (a, b,					\
1416				  (XUNTAG (a, Lisp_Vectorlike,		\
1417					   struct vectorlike_header)	\
1418				   ->size),				\
1419				  code)
1420	#define XSETTYPED_PSEUDOVECTOR(a, b, size, code)			\
1421	  (XSETVECTOR (a, b),							\
1422	   eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))		\
1423		    == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS))))
1424
1425	#define XSETWINDOW_CONFIGURATION(a, b) \
1426	  XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION)
1427	#define XSETPROCESS(a, b) XSETPSEUDOVECTOR (a, b, PVEC_PROCESS)
1428	#define XSETWINDOW(a, b) XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)
1429	#define XSETTERMINAL(a, b) XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)
1430	#define XSETSUBR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_SUBR)
1431	#define XSETBUFFER(a, b) XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)
1432	#define XSETCHAR_TABLE(a, b) XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)
1433	#define XSETBOOL_VECTOR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR)
1434	#define XSETSUB_CHAR_TABLE(a, b) XSETPSEUDOVECTOR (a, b, PVEC_SUB_CHAR_TABLE)
1435	#define XSETTHREAD(a, b) XSETPSEUDOVECTOR (a, b, PVEC_THREAD)
1436	#define XSETMUTEX(a, b) XSETPSEUDOVECTOR (a, b, PVEC_MUTEX)
1437	#define XSETCONDVAR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_CONDVAR)
1438	#define XSETNATIVE_COMP_UNIT(a, b) XSETPSEUDOVECTOR (a, b, PVEC_NATIVE_COMP_UNIT)
1439
1440	/* Efficiently convert a pointer to a Lisp object and back.  The
1441	   pointer is represented as a fixnum, so the garbage collector
1442	   does not know about it.  The pointer should not have both Lisp_Int1
1443	   bits set, which makes this conversion inherently unportable.  */
1444
1445	INLINE void *
1446	XFIXNUMPTR (Lisp_Object a)
1447	{
1448	  return XUNTAG (a, Lisp_Int0, char);
1449	}
1450
1451	INLINE Lisp_Object
1452	make_pointer_integer_unsafe (void *p)
1453	{
1454	  Lisp_Object a = TAG_PTR_INITIALLY (Lisp_Int0, p);
1455	  return a;
1456	}
1457
1458	INLINE Lisp_Object
1459	make_pointer_integer (void *p)
1460	{
1461	  Lisp_Object a = make_pointer_integer_unsafe (p);
1462	  eassert (FIXNUMP (a) && XFIXNUMPTR (a) == p);
1463	  return a;
1464	}
1465
1466	/* See the macros in intervals.h.  */
1467
1468	typedef struct interval *INTERVAL;
1469
1470	struct Lisp_Cons
1471	{
1472	  GC_HEADER
1473	  union
1474	  {
1475	    struct
1476	    {
1477	      /* Car of this cons cell.  */
1478	      Lisp_Object car;
1479
1480	      union
1481	      {
1482		/* Cdr of this cons cell.  */
1483		Lisp_Object cdr;
1484
1485		/* Used to chain conses on a free list.  */
1486		struct Lisp_Cons *chain;
1487	      } u;
1488	    } s;
1489	    GCALIGNED_UNION_MEMBER
1490	  } u;
1491	};
1492	static_assert (GCALIGNED (struct Lisp_Cons));
1493
1494	INLINE bool
1495	(NILP) (Lisp_Object x)
1496	{
1497	  return lisp_h_NILP (x);
1498	}
1499
1500	INLINE bool
1501	(CONSP) (Lisp_Object x)
1502	{
1503	  return lisp_h_CONSP (x);
1504	}
1505
1506	INLINE void
1507	CHECK_CONS (Lisp_Object x)
1508	{
1509	  CHECK_TYPE (CONSP (x), Qconsp, x);
1510	}
1511
1512	INLINE struct Lisp_Cons *
1513	XCONS (Lisp_Object a)
1514	{
1515	  eassert (CONSP (a));
   0x000055555577b95f <+12559>:	and    $0x7,%edx
   0x000055555577b962 <+12562>:	jne    0x5555555b2830 <read_char-1859616>

1517	  igc_check_fwd (c, false);
1518	  return c;
   0x000055555577b968 <+12568>:	mov    %r12,0x5(%rax)

1184	  return a;
   0x000055555577b96c <+12572>:	mov    0x38(%rbx),%r12
   0x000055555577b970 <+12576>:	mov    $0x38,%esi
   0x000055555577b975 <+12581>:	mov    %r12,%rdi
   0x000055555577b978 <+12584>:	call   0x555555764470 <EQ>

./src/keyboard.c:
4380			      if (!EQ (maybe_event->ie.device, Qt))
   0x000055555577b97d <+12589>:	test   %al,%al
   0x000055555577b97f <+12591>:	jne    0x55555577b988 <read_char+12600>

4381				Vlast_event_device = maybe_event->ie.device;
   0x000055555577b981 <+12593>:	mov    %r12,0x3a5108(%rip)        # 0x555555b20a90 <globals+1616>

429	  return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1;
   0x000055555577b988 <+12600>:	cmp    %r14,%rbx
   0x000055555577b98b <+12603>:	jne    0x55555577b77f <read_char+12079>

4359					event->ie.frame_or_window)
4360				 /* Make sure that the event isn't the start
4361				    of a new pinch gesture sequence.  */
4362				 && (XFLOAT_DATA (XCAR (maybe_event->ie.arg)) != 0.0
   0x000055555577b991 <+12609>:	lea    0x34a788(%rip),%rax        # 0x555555ac6120 <kbd_buffer>
   0x000055555577b998 <+12616>:	cmp    %rax,0x34a771(%rip)        # 0x555555ac6110 <kbd_store_ptr>
   0x000055555577b99f <+12623>:	jne    0x55555577b790 <read_char+12096>
   0x000055555577b9a5 <+12629>:	mov    -0x568(%rbp),%r12
   0x000055555577b9ac <+12636>:	mov    -0x570(%rbp),%r15

4382
4383			      maybe_event = next_kbd_event (event);
4384			    }
4385			}
4386
4387		      if (event->kind == MULTIBYTE_CHAR_KEYSTROKE_EVENT
   0x000055555577b9b3 <+12643>:	mov    %rbx,%r8
   0x000055555577b9b6 <+12646>:	movzwl (%rbx),%eax
   0x000055555577b9b9 <+12649>:	jmp    0x55555577aae6 <read_char+8854>
   0x000055555577b9be <+12654>:	xchg   %ax,%ax

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577b9c0 <+12656>:	movslq %r14d,%rdx

./src/keyboard.c:
2371		XSETINT (c, make_ctrl_char (XFIXNUM (c)));
   0x000055555577b9c3 <+12659>:	mov    %r14d,%ecx

./src/lisp.h:
2093	  return 0 <= c && c < 0x80;
   0x000055555577b9c6 <+12662>:	cmp    $0x7f,%rdx
   0x000055555577b9ca <+12666>:	ja     0x55555577c026 <read_char+14294>

./src/keyboard.c:
2181	  if (c >= 0100 && c < 0140)
   0x000055555577b9d0 <+12672>:	sub    $0x40,%r14d
   0x000055555577b9d4 <+12676>:	cmp    $0x1f,%r14d
   0x000055555577b9d8 <+12680>:	ja     0x55555577c010 <read_char+14272>

2182	    {
2183	      int oc = c;
2184	      c &= ~0140;
2185	      /* Set the shift modifier for a control char
2186		 made from a shifted letter.  But only for letters!  */
2187	      if (oc >= 'A' && oc <= 'Z')
   0x000055555577b9de <+12686>:	mov    %ecx,%esi
   0x000055555577b9e0 <+12688>:	lea    -0x41(%rcx),%edi

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577b9e3 <+12691>:	and    $0x1f,%esi
   0x000055555577b9e6 <+12694>:	mov    %rsi,%rdx
   0x000055555577b9e9 <+12697>:	or     $0x2000000,%rdx
   0x000055555577b9f0 <+12704>:	cmp    $0x1a,%edi
   0x000055555577b9f3 <+12707>:	cmovae %rsi,%rdx
   0x000055555577b9f7 <+12711>:	cmpb   $0x0,0x3a0982(%rip)        # 0x555555b1c380 <suppress_checking>
   0x000055555577b9fe <+12718>:	lea    0x2(,%rdx,4),%r14

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x000055555577ba06 <+12726>:	jne    0x55555577a7ca <read_char+8058>

740	  return lisp_h_XLI (o);
   0x000055555577ba0c <+12732>:	sar    $0x2,%r14

1199	}
1200
1201	INLINE bool
1202	c_symbol_p (struct Lisp_Symbol *sym)
1203	{
1204	  char *bp = (char *) lispsym;
1205	  char *sp = (char *) sym;
1206	  if (PTRDIFF_MAX < INTPTR_MAX)
1207	    return bp <= sp && sp < bp + sizeof lispsym;
1208	  else
1209	    {
1210	      ptrdiff_t offset = sp - bp;
1211	      return 0 <= offset && offset < sizeof lispsym;
1212	    }
1213	}
1214
1215	INLINE void
1216	(CHECK_SYMBOL) (Lisp_Object x)
1217	{
1218	  lisp_h_CHECK_SYMBOL (x);
1219	}
1220
1221	/* True if the possibly-unsigned integer I doesn't fit in a fixnum.  */
1222
1223	#define FIXNUM_OVERFLOW_P(i) \
1224	  (! ((0 <= (i) || MOST_NEGATIVE_FIXNUM <= (i)) && (i) <= MOST_POSITIVE_FIXNUM))
1225
1226	#if USE_LSB_TAG
1227
1228	INLINE Lisp_Object
1229	(make_fixnum) (EMACS_INT n)
1230	{
1231	  eassert (!FIXNUM_OVERFLOW_P (n));
   0x000055555577ba10 <+12736>:	movabs $0x2000000000000000,%rdx

./src/keyboard.c:
2376	      XSETINT (c, XFIXNUM (c) | (extra_keyboard_modifiers & ~0xff7f & ~CHAR_CTL));
   0x000055555577ba1a <+12746>:	and    $0xfffffffffbff0080,%rax
   0x000055555577ba20 <+12752>:	or     %r14,%rax

./src/lisp.h:
1231	  eassert (!FIXNUM_OVERFLOW_P (n));
   0x000055555577ba23 <+12755>:	add    %rax,%rdx
   0x000055555577ba26 <+12758>:	shr    $0x3e,%rdx
   0x000055555577ba2a <+12762>:	jne    0x55555577d10e <read_char+18622>

746	  return lisp_h_XIL (i);
   0x000055555577ba30 <+12768>:	mov    0x333af1(%rip),%rdx        # 0x555555aaf528 <selected_frame>

1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577ba37 <+12775>:	lea    0x2(,%rax,4),%r14

./src/keyboard.c:
2409	      struct frame *frame = XFRAME (selected_frame);
   0x000055555577ba3f <+12783>:	jmp    0x555555779adb <read_char+4747>

2974		    {
2975		      c = XCDR (c);
   0x000055555577ba44 <+12788>:	mov    %r14,%rdi
   0x000055555577ba47 <+12791>:	call   0x5555557630d0 <XCDR>

2976		      recorded = true;
   0x000055555577ba4c <+12796>:	movb   $0x1,-0x486(%rbp)

2975		      c = XCDR (c);
   0x000055555577ba53 <+12803>:	mov    %rax,%r14

2976		      recorded = true;
   0x000055555577ba56 <+12806>:	jmp    0x5555557793bd <read_char+2925>

2668	      bool echo_current = EQ (echo_message_buffer, echo_area_buffer[0]);
   0x000055555577ba5b <+12811>:	mov    0x333b2e(%rip),%rsi        # 0x555555aaf590 <echo_area_buffer>
   0x000055555577ba62 <+12818>:	mov    0x38a6f7(%rip),%rdi        # 0x555555b06160 <echo_message_buffer>
   0x000055555577ba69 <+12825>:	call   0x555555764470 <EQ>

2669
2670		/* If there is pending input, process any events which are not
2671		   user-visible, such as X selection_request events.  */
2672	      if (input_pending
   0x000055555577ba6e <+12830>:	cmpb   $0x0,0x38a6ac(%rip)        # 0x555555b06121 <input_pending>

2668	      bool echo_current = EQ (echo_message_buffer, echo_area_buffer[0]);
   0x000055555577ba75 <+12837>:	mov    %eax,%r12d

2669
2670		/* If there is pending input, process any events which are not
2671		   user-visible, such as X selection_request events.  */
2672	      if (input_pending
   0x000055555577ba78 <+12840>:	jne    0x55555577ba85 <read_char+12853>

2673		  || detect_input_pending_run_timers (0))
   0x000055555577ba7a <+12842>:	xor    %edi,%edi
   0x000055555577ba7c <+12844>:	call   0x5555557786a0 <detect_input_pending_run_timers>
   0x000055555577ba81 <+12849>:	test   %al,%al
   0x000055555577ba83 <+12851>:	je     0x55555577ba8c <read_char+12860>

2674		swallow_events (false);		/* May clear input_pending.  */
   0x000055555577ba85 <+12853>:	xor    %edi,%edi
   0x000055555577ba87 <+12855>:	call   0x555555772f40 <swallow_events>

2675
2676	      /* Redisplay if no pending input.  */
2677	      while (!(input_pending && input_was_pending))
   0x000055555577ba8c <+12860>:	movzbl 0x38a68e(%rip),%eax        # 0x555555b06121 <input_pending>

7172	}
7173
7174	static Lisp_Object
7175	make_lispy_focus_in (Lisp_Object frame)
7176	{
7177	  return list2 (Qfocus_in, frame);
7178	}
7179
7180	static Lisp_Object
7181	make_lispy_focus_out (Lisp_Object frame)
7182	{
7183	  return list2 (Qfocus_out, frame);
7184	}
7185
7186	/* Manipulating modifiers.  */
7187
7188	/* Parse the name of SYMBOL, and return the set of modifiers it contains.
7189
7190	   If MODIFIER_END is non-zero, set *MODIFIER_END to the position in
7191	   SYMBOL's name of the end of the modifiers; the string from this
7192	   position is the unmodified symbol name.
7193
7194	   This doesn't use any caches.  */
7195
7196	static int
7197	parse_modifiers_uncached (Lisp_Object symbol, ptrdiff_t *modifier_end)
7198	{
7199	  Lisp_Object name;
7200	  ptrdiff_t i;
7201	  int modifiers;
7202
7203	  CHECK_SYMBOL (symbol);
7204
7205	  modifiers = 0;
7206	  name = SYMBOL_NAME (symbol);
7207
7208	  for (i = 0; i < SBYTES (name) - 1; )
7209	    {
7210	      ptrdiff_t this_mod_end = 0;
7211	      int this_mod = 0;
7212
7213	      /* See if the name continues with a modifier word.
7214		 Check that the word appears, but don't check what follows it.
7215		 Set this_mod and this_mod_end to record what we find.  */
7216
7217	      switch (SREF (name, i))
7218		{
7219	#define SINGLE_LETTER_MOD(BIT)				\
7220		  (this_mod_end = i + 1, this_mod = BIT)
7221
7222		case 'A':
7223		  SINGLE_LETTER_MOD (alt_modifier);
7224		  break;
7225
7226		case 'C':
7227		  SINGLE_LETTER_MOD (ctrl_modifier);
7228		  break;
7229
7230		case 'H':
7231		  SINGLE_LETTER_MOD (hyper_modifier);
7232		  break;
7233
7234		case 'M':
7235		  SINGLE_LETTER_MOD (meta_modifier);
7236		  break;
7237
7238		case 'S':
7239		  SINGLE_LETTER_MOD (shift_modifier);
7240		  break;
7241
7242		case 's':
7243		  SINGLE_LETTER_MOD (super_modifier);
7244		  break;
7245
7246	#undef SINGLE_LETTER_MOD
7247
7248	#define MULTI_LETTER_MOD(BIT, NAME, LEN)			\
7249		  if (i + LEN + 1 <= SBYTES (name)			\
7250		      && ! memcmp (SDATA (name) + i, NAME, LEN))	\
7251		    {							\
7252		      this_mod_end = i + LEN;				\
7253		      this_mod = BIT;					\
7254		    }
7255
7256		case 'd':
7257		  MULTI_LETTER_MOD (drag_modifier, "drag", 4);
7258		  MULTI_LETTER_MOD (down_modifier, "down", 4);
7259		  MULTI_LETTER_MOD (double_modifier, "double", 6);
7260		  break;
7261
7262		case 't':
7263		  MULTI_LETTER_MOD (triple_modifier, "triple", 6);
7264		  break;
7265
7266		case 'u':
7267		  MULTI_LETTER_MOD (up_modifier, "up", 2);
7268		  break;
7269	#undef MULTI_LETTER_MOD
7270
7271		}
7272
7273	      /* If we found no modifier, stop looking for them.  */
7274	      if (this_mod_end == 0)
7275		break;
7276
7277	      /* Check there is a dash after the modifier, so that it
7278		 really is a modifier.  */
7279	      if (this_mod_end >= SBYTES (name)
7280		  || SREF (name, this_mod_end) != '-')
7281		break;
7282
7283	      /* This modifier is real; look for another.  */
7284	      modifiers |= this_mod;
7285	      i = this_mod_end + 1;
7286	    }
7287
7288	  /* Should we include the `click' modifier?  */
7289	  if (! (modifiers & (down_modifier | drag_modifier
7290			      | double_modifier | triple_modifier))
7291	      && i + 7 == SBYTES (name)
7292	      && memcmp (SDATA (name) + i, "mouse-", 6) == 0
7293	      && ('0' <= SREF (name, i + 6) && SREF (name, i + 6) <= '9'))
7294	    modifiers |= click_modifier;
7295
7296	  if (! (modifiers & (double_modifier | triple_modifier))
7297	      && i + 6 < SBYTES (name)
7298	      && memcmp (SDATA (name) + i, "wheel-", 6) == 0)
7299	    modifiers |= click_modifier;
7300
7301	  if (modifier_end)
7302	    *modifier_end = i;
7303
7304	  return modifiers;
7305	}
7306
7307	/* Return a symbol whose name is the modifier prefixes for MODIFIERS
7308	   prepended to the string BASE[0..BASE_LEN-1].
7309	   This doesn't use any caches.  */
7310	static Lisp_Object
7311	apply_modifiers_uncached (int modifiers, char *base, int base_len, int base_len_byte)
7312	{
7313	  /* Since BASE could contain nulls, we can't use intern here; we have
7314	     to use Fintern, which expects a genuine Lisp_String, and keeps a
7315	     reference to it.  */
7316	  char new_mods[sizeof "A-C-H-M-S-s-up-down-drag-double-triple-"];
7317	  int mod_len;
7318
7319	  {
7320	    char *p = new_mods;
7321
7322	    /* Mouse events should not exhibit the `up' modifier once they
7323	       leave the event queue only accessible to C code; `up' will
7324	       always be turned into a click or drag event before being
7325	       presented to lisp code.  But since lisp events can be
7326	       synthesized bypassing the event queue and pushed into
7327	       `unread-command-events' or its companions, it's better to just
7328	       deal with unexpected modifier combinations. */
7329
7330	    if (modifiers & alt_modifier)   { *p++ = 'A'; *p++ = '-'; }
7331	    if (modifiers & ctrl_modifier)  { *p++ = 'C'; *p++ = '-'; }
7332	    if (modifiers & hyper_modifier) { *p++ = 'H'; *p++ = '-'; }
7333	    if (modifiers & meta_modifier)  { *p++ = 'M'; *p++ = '-'; }
7334	    if (modifiers & shift_modifier) { *p++ = 'S'; *p++ = '-'; }
7335	    if (modifiers & super_modifier) { *p++ = 's'; *p++ = '-'; }
7336	    if (modifiers & double_modifier) p = stpcpy (p, "double-");
7337	    if (modifiers & triple_modifier) p = stpcpy (p, "triple-");
7338	    if (modifiers & up_modifier) p = stpcpy (p, "up-");
7339	    if (modifiers & down_modifier) p = stpcpy (p, "down-");
7340	    if (modifiers & drag_modifier) p = stpcpy (p, "drag-");
7341	    /* The click modifier is denoted by the absence of other modifiers.  */
7342
7343	    *p = '\0';
7344
7345	    mod_len = p - new_mods;
7346	  }
7347
7348	  {
7349	    Lisp_Object new_name;
7350
7351	    new_name = make_uninit_multibyte_string (mod_len + base_len,
7352						     mod_len + base_len_byte);
7353	    memcpy (SDATA (new_name), new_mods, mod_len);
7354	    memcpy (SDATA (new_name) + mod_len, base, base_len_byte);
7355
7356	    return Fintern (new_name, Qnil);
7357	  }
7358	}
7359
7360
7361	static const char *const modifier_names[] =
7362	{
7363	  "up", "down", "drag", "click", "double", "triple", 0, 0,
7364	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7365	  0, 0, "alt", "super", "hyper", "shift", "control", "meta"
7366	};
7367	#define NUM_MOD_NAMES ARRAYELTS (modifier_names)
7368
7369	static Lisp_Object modifier_symbols;
7370
7371	/* Return the list of modifier symbols corresponding to the mask MODIFIERS.  */
7372	static Lisp_Object
7373	lispy_modifier_list (int modifiers)
7374	{
7375	  Lisp_Object modifier_list;
7376	  int i;
7377
7378	  modifier_list = Qnil;
7379	  for (i = 0; (1<<i) <= modifiers && i < NUM_MOD_NAMES; i++)
7380	    if (modifiers & (1<<i))
7381	      modifier_list = Fcons (AREF (modifier_symbols, i),
7382				     modifier_list);
7383
7384	  return modifier_list;
7385	}
7386
7387
7388	/* Parse the modifiers on SYMBOL, and return a list like (UNMODIFIED MASK),
7389	   where UNMODIFIED is the unmodified form of SYMBOL,
7390	   MASK is the set of modifiers present in SYMBOL's name.
7391	   This is similar to parse_modifiers_uncached, but uses the cache in
7392	   SYMBOL's Qevent_symbol_element_mask property, and maintains the
7393	   Qevent_symbol_elements property.  */
7394
7395	#define KEY_TO_CHAR(k) (XFIXNUM (k) & ((1 << CHARACTERBITS) - 1))
7396
7397	Lisp_Object
7398	parse_modifiers (Lisp_Object symbol)
7399	{
7400	  Lisp_Object elements;
7401
7402	  if (FIXNUMP (symbol))
7403	    return list2i (KEY_TO_CHAR (symbol), XFIXNUM (symbol) & CHAR_MODIFIER_MASK);
7404	  else if (!SYMBOLP (symbol))
7405	    return Qnil;
7406
7407	  elements = Fget (symbol, Qevent_symbol_element_mask);
7408	  if (CONSP (elements))
7409	    return elements;
7410	  else
7411	    {
7412	      ptrdiff_t end;
7413	      int modifiers = parse_modifiers_uncached (symbol, &end);
7414	      Lisp_Object unmodified;
7415	      Lisp_Object mask;
7416
7417	      unmodified = Fintern (make_string (SSDATA (SYMBOL_NAME (symbol)) + end,
7418						 SBYTES (SYMBOL_NAME (symbol)) - end),
7419				    Qnil);
7420
7421	      if (modifiers & ~INTMASK)
7422		emacs_abort ();
7423	      XSETFASTINT (mask, modifiers);
7424	      elements = list2 (unmodified, mask);
7425
7426	      /* Cache the parsing results on SYMBOL.  */
7427	      Fput (symbol, Qevent_symbol_element_mask,
7428		    elements);
7429	      Fput (symbol, Qevent_symbol_elements,
7430		    Fcons (unmodified, lispy_modifier_list (modifiers)));
7431
7432	      /* Since we know that SYMBOL is modifiers applied to unmodified,
7433		 it would be nice to put that in unmodified's cache.
7434		 But we can't, since we're not sure that parse_modifiers is
7435		 canonical.  */
7436
7437	      return elements;
7438	    }
7439	}
7440
7441	DEFUN ("internal-event-symbol-parse-modifiers", Fevent_symbol_parse_modifiers,
7442	       Sevent_symbol_parse_modifiers, 1, 1, 0,
7443	       doc: /* Parse the event symbol.  For internal use.  */)
7444	  (Lisp_Object symbol)
7445	{
7446	  /* Fill the cache if needed.  */
7447	  parse_modifiers (symbol);
7448	  /* Ignore the result (which is stored on Qevent_symbol_element_mask)
7449	     and use the Lispier representation stored on Qevent_symbol_elements
7450	     instead.  */
7451	  return Fget (symbol, Qevent_symbol_elements);
7452	}
7453
7454	/* Apply the modifiers MODIFIERS to the symbol BASE.
7455	   BASE must be unmodified.
7456
7457	   This is like apply_modifiers_uncached, but uses BASE's
7458	   Qmodifier_cache property, if present.
7459
7460	   apply_modifiers copies the value of BASE's Qevent_kind property to
7461	   the modified symbol.  */
7462	static Lisp_Object
7463	apply_modifiers (int modifiers, Lisp_Object base)
7464	{
7465	  Lisp_Object cache, idx, entry, new_symbol;
7466
7467	  /* Mask out upper bits.  We don't know where this value's been.  */
7468	  modifiers &= INTMASK;
7469
7470	  if (FIXNUMP (base))
7471	    return make_fixnum (XFIXNUM (base) | modifiers);
7472
7473	  /* The click modifier never figures into cache indices.  */
7474	  cache = Fget (base, Qmodifier_cache);
7475	  XSETFASTINT (idx, (modifiers & ~click_modifier));
7476	  entry = assq_no_quit (idx, cache);
7477
7478	  if (CONSP (entry))
7479	    new_symbol = XCDR (entry);
7480	  else
7481	    {
7482	      /* We have to create the symbol ourselves.  */
7483	      new_symbol = apply_modifiers_uncached (modifiers,
7484						     SSDATA (SYMBOL_NAME (base)),
7485						     SCHARS (SYMBOL_NAME (base)),
7486						     SBYTES (SYMBOL_NAME (base)));
7487
7488	      /* Add the new symbol to the base's cache.  */
7489	      entry = Fcons (idx, new_symbol);
7490	      Fput (base, Qmodifier_cache, Fcons (entry, cache));
7491
7492	      /* We have the parsing info now for free, so we could add it to
7493		 the caches:
7494	         XSETFASTINT (idx, modifiers);
7495	         Fput (new_symbol, Qevent_symbol_element_mask,
7496	               list2 (base, idx));
7497	         Fput (new_symbol, Qevent_symbol_elements,
7498	               Fcons (base, lispy_modifier_list (modifiers)));
7499		 Sadly, this is only correct if `base' is indeed a base event,
7500		 which is not necessarily the case.  -stef  */
7501	    }
7502
7503	  /* Make sure this symbol is of the same kind as BASE.
7504
7505	     You'd think we could just set this once and for all when we
7506	     intern the symbol above, but reorder_modifiers may call us when
7507	     BASE's property isn't set right; we can't assume that just
7508	     because it has a Qmodifier_cache property it must have its
7509	     Qevent_kind set right as well.  */
7510	  if (NILP (Fget (new_symbol, Qevent_kind)))
7511	    {
7512	      Lisp_Object kind;
7513
7514	      kind = Fget (base, Qevent_kind);
7515	      if (! NILP (kind))
7516		Fput (new_symbol, Qevent_kind, kind);
7517	    }
7518
7519	  return new_symbol;
7520	}
7521
7522
7523	/* Given a symbol whose name begins with modifiers ("C-", "M-", etc),
7524	   return a symbol with the modifiers placed in the canonical order.
7525	   Canonical order is alphabetical, except for down and drag, which
7526	   always come last.  The 'click' modifier is never written out.
7527
7528	   Fdefine_key calls this to make sure that (for example) C-M-foo
7529	   and M-C-foo end up being equivalent in the keymap.  */
7530
7531	Lisp_Object
7532	reorder_modifiers (Lisp_Object symbol)
7533	{
7534	  /* It's hopefully okay to write the code this way, since everything
7535	     will soon be in caches, and no consing will be done at all.  */
7536	  Lisp_Object parsed;
7537
7538	  parsed = parse_modifiers (symbol);
7539	  return apply_modifiers (XFIXNAT (XCAR (XCDR (parsed))),
7540				  XCAR (parsed));
7541	}
7542
7543
7544	/* For handling events, we often want to produce a symbol whose name
7545	   is a series of modifier key prefixes ("M-", "C-", etcetera) attached
7546	   to some base, like the name of a function key or mouse button.
7547	   modify_event_symbol produces symbols of this sort.
7548
7549	   NAME_TABLE should point to an array of strings, such that NAME_TABLE[i]
7550	   is the name of the i'th symbol.  TABLE_SIZE is the number of elements
7551	   in the table.
7552
7553	   Alternatively, NAME_ALIST_OR_STEM is either an alist mapping codes
7554	   into symbol names, or a string specifying a name stem used to
7555	   construct a symbol name or the form `STEM-N', where N is the decimal
7556	   representation of SYMBOL_NUM.  NAME_ALIST_OR_STEM is used if it is
7557	   non-nil; otherwise NAME_TABLE is used.
7558
7559	   SYMBOL_TABLE should be a pointer to a Lisp_Object whose value will
7560	   persist between calls to modify_event_symbol that it can use to
7561	   store a cache of the symbols it's generated for this NAME_TABLE
7562	   before.  The object stored there may be a vector or an alist.
7563
7564	   SYMBOL_NUM is the number of the base name we want from NAME_TABLE.
7565
7566	   MODIFIERS is a set of modifier bits (as given in struct input_events)
7567	   whose prefixes should be applied to the symbol name.
7568
7569	   SYMBOL_KIND is the value to be placed in the event_kind property of
7570	   the returned symbol.
7571
7572	   The symbols we create are supposed to have an
7573	   `event-symbol-elements' property, which lists the modifiers present
7574	   in the symbol's name.  */
7575
7576	static Lisp_Object
7577	modify_event_symbol (ptrdiff_t symbol_num, int modifiers, Lisp_Object symbol_kind,
7578			     Lisp_Object name_alist_or_stem, const char *const *name_table,
7579			     Lisp_Object *symbol_table, ptrdiff_t table_size)
7580	{
7581	  Lisp_Object value;
7582	  Lisp_Object symbol_int;
7583
7584	  /* Get rid of the "vendor-specific" bit here.  */
7585	  XSETINT (symbol_int, symbol_num & 0xffffff);
7586
7587	  /* Is this a request for a valid symbol?  */
7588	  if (symbol_num < 0 || symbol_num >= table_size)
7589	    return Qnil;
7590
7591	  if (CONSP (*symbol_table))
7592	    value = Fcdr (assq_no_quit (symbol_int, *symbol_table));
7593
7594	  /* If *symbol_table doesn't seem to be initialized properly, fix that.
7595	     *symbol_table should be a lisp vector TABLE_SIZE elements long,
7596	     where the Nth element is the symbol for NAME_TABLE[N], or nil if
7597	     we've never used that symbol before.  */
7598	  else
7599	    {
7600	      if (! VECTORP (*symbol_table)
7601		  || ASIZE (*symbol_table) != table_size)
7602		*symbol_table = make_nil_vector (table_size);
7603
7604	      value = AREF (*symbol_table, symbol_num);
7605	    }
7606
7607	  /* Have we already used this symbol before?  */
7608	  if (NILP (value))
7609	    {
7610	      /* No; let's create it.  */
7611	      if (CONSP (name_alist_or_stem))
7612		value = Fcdr_safe (Fassq (symbol_int, name_alist_or_stem));
7613	      else if (STRINGP (name_alist_or_stem))
7614		{
7615		  char *buf;
7616		  ptrdiff_t len = (SBYTES (name_alist_or_stem)
7617				   + sizeof "-" + INT_STRLEN_BOUND (EMACS_INT));
7618		  USE_SAFE_ALLOCA;
7619		  buf = SAFE_ALLOCA (len);
7620		  esprintf (buf, "%s-%"pI"d", SDATA (name_alist_or_stem),
7621			    XFIXNUM (symbol_int) + 1);
7622		  value = intern (buf);
7623		  SAFE_FREE ();
7624		}
7625	      else if (name_table != 0 && name_table[symbol_num])
7626		value = intern (name_table[symbol_num]);
7627
7628	#ifdef HAVE_WINDOW_SYSTEM
7629	      if (NILP (value))
7630		{
7631		  char *name = get_keysym_name (symbol_num);
7632		  if (name)
7633		    value = intern (name);
7634		}
7635	#endif
7636
7637	      if (NILP (value))
7638		{
7639		  char buf[sizeof "key-" + INT_STRLEN_BOUND (EMACS_INT)];
7640		  sprintf (buf, "key-%"pD"d", symbol_num);
7641		  value = intern (buf);
7642		}
7643
7644	      if (CONSP (*symbol_table))
7645	        *symbol_table = Fcons (Fcons (symbol_int, value), *symbol_table);
7646	      else
7647		ASET (*symbol_table, symbol_num, value);
7648
7649	      /* Fill in the cache entries for this symbol; this also
7650		 builds the Qevent_symbol_elements property, which the user
7651		 cares about.  */
7652	      apply_modifiers (modifiers & click_modifier, value);
7653	      Fput (value, Qevent_kind, symbol_kind);
7654	    }
7655
7656	  /* Apply modifiers to that symbol.  */
7657	  return apply_modifiers (modifiers, value);
7658	}
7659	^L
7660	/* Convert a list that represents an event type,
7661	   such as (ctrl meta backspace), into the usual representation of that
7662	   event type as a number or a symbol.  */
7663
7664	DEFUN ("event-convert-list", Fevent_convert_list, Sevent_convert_list, 1, 1, 0,
7665	       doc: /* Convert the event description list EVENT-DESC to an event type.
7666	EVENT-DESC should contain one base event type (a character or symbol)
7667	and zero or more modifier names (control, meta, hyper, super, shift, alt,
7668	drag, down, double or triple).  The base must be last.
7669
7670	The return value is an event type (a character or symbol) which has
7671	essentially the same base event type and all the specified modifiers.
7672	(Some compatibility base types, like symbols that represent a
7673	character, are not returned verbatim.)  */)
7674	  (Lisp_Object event_desc)
7675	{
7676	  Lisp_Object base = Qnil;
7677	  int modifiers = 0;
7678
7679	  FOR_EACH_TAIL_SAFE (event_desc)
7680	    {
7681	      Lisp_Object elt = XCAR (event_desc);
7682	      int this = 0;
7683
7684	      /* Given a symbol, see if it is a modifier name.  */
7685	      if (SYMBOLP (elt) && CONSP (XCDR (event_desc)))
7686		this = parse_solitary_modifier (elt);
7687
7688	      if (this != 0)
7689		modifiers |= this;
7690	      else if (!NILP (base))
7691		error ("Two bases given in one event");
7692	      else
7693		base = elt;
7694	    }
7695
7696	  /* Let the symbol A refer to the character A.  */
7697	  if (SYMBOLP (base) && SCHARS (SYMBOL_NAME (base)) == 1)
7698	    XSETINT (base, SREF (SYMBOL_NAME (base), 0));
7699
7700	  if (FIXNUMP (base))
7701	    {
7702	      /* Turn (shift a) into A.  */
7703	      if ((modifiers & shift_modifier) != 0
7704		  && (XFIXNUM (base) >= 'a' && XFIXNUM (base) <= 'z'))
7705		{
7706		  XSETINT (base, XFIXNUM (base) - ('a' - 'A'));
7707		  modifiers &= ~shift_modifier;
7708		}
7709
7710	      /* Turn (control a) into C-a.  */
7711	      if (modifiers & ctrl_modifier)
7712		return make_fixnum ((modifiers & ~ctrl_modifier)
7713				    | make_ctrl_char (XFIXNUM (base)));
7714	      else
7715		return make_fixnum (modifiers | XFIXNUM (base));
7716	    }
7717	  else if (SYMBOLP (base))
7718	    return apply_modifiers (modifiers, base);
7719	  else
7720	    error ("Invalid base event");
7721	}
7722
7723	DEFUN ("internal-handle-focus-in", Finternal_handle_focus_in,
7724	       Sinternal_handle_focus_in, 1, 1, 0,
7725	       doc: /* Internally handle focus-in events.
7726	This function potentially generates an artificial switch-frame event.  */)
7727	     (Lisp_Object event)
7728	{
7729	  Lisp_Object frame;
7730	  if (!EQ (CAR_SAFE (event), Qfocus_in) ||
7731	      !CONSP (XCDR (event)) ||
7732	      !FRAMEP ((frame = XCAR (XCDR (event)))))
7733	    error ("Invalid focus-in event");
7734
7735	  /* Conceptually, the concept of window manager focus on a particular
7736	     frame and the Emacs selected frame shouldn't be related, but for
7737	     a long time, we automatically switched the selected frame in
7738	     response to focus events, so let's keep doing that.  */
7739	  bool switching = (!EQ (frame, internal_last_event_frame)
7740	                    && !EQ (frame, selected_frame));
7741	  internal_last_event_frame = frame;
7742	  if (switching || !NILP (unread_switch_frame))
7743	    unread_switch_frame = make_lispy_switch_frame (frame);
7744
7745	  return Qnil;
7746	}
7747
7748	/* Try to recognize SYMBOL as a modifier name.
7749	   Return the modifier flag bit, or 0 if not recognized.  */
7750
7751	int
7752	parse_solitary_modifier (Lisp_Object symbol)
7753	{
7754	  Lisp_Object name;
7755
7756	  if (!SYMBOLP (symbol))
7757	    return 0;
7758
7759	  name = SYMBOL_NAME (symbol);
7760
7761	  switch (SREF (name, 0))
7762	    {
7763	#define SINGLE_LETTER_MOD(BIT)				\
7764	      if (SBYTES (name) == 1)				\
7765		return BIT;
7766
7767	#define MULTI_LETTER_MOD(BIT, NAME, LEN)		\
7768	      if (LEN == SBYTES (name)				\
7769		  && ! memcmp (SDATA (name), NAME, LEN))	\
7770		return BIT;
7771
7772	    case 'A':
7773	      SINGLE_LETTER_MOD (alt_modifier);
7774	      break;
7775
7776	    case 'a':
7777	      MULTI_LETTER_MOD (alt_modifier, "alt", 3);
7778	      break;
7779
7780	    case 'C':
7781	      SINGLE_LETTER_MOD (ctrl_modifier);
7782	      break;
7783
7784	    case 'c':
7785	      MULTI_LETTER_MOD (ctrl_modifier, "ctrl", 4);
7786	      MULTI_LETTER_MOD (ctrl_modifier, "control", 7);
7787	      MULTI_LETTER_MOD (click_modifier, "click", 5);
7788	      break;
7789
7790	    case 'H':
7791	      SINGLE_LETTER_MOD (hyper_modifier);
7792	      break;
7793
7794	    case 'h':
7795	      MULTI_LETTER_MOD (hyper_modifier, "hyper", 5);
7796	      break;
7797
7798	    case 'M':
7799	      SINGLE_LETTER_MOD (meta_modifier);
7800	      break;
7801
7802	    case 'm':
7803	      MULTI_LETTER_MOD (meta_modifier, "meta", 4);
7804	      break;
7805
7806	    case 'S':
7807	      SINGLE_LETTER_MOD (shift_modifier);
7808	      break;
7809
7810	    case 's':
7811	      MULTI_LETTER_MOD (shift_modifier, "shift", 5);
7812	      MULTI_LETTER_MOD (super_modifier, "super", 5);
7813	      SINGLE_LETTER_MOD (super_modifier);
7814	      break;
7815
7816	    case 'd':
7817	      MULTI_LETTER_MOD (drag_modifier, "drag", 4);
7818	      MULTI_LETTER_MOD (down_modifier, "down", 4);
7819	      MULTI_LETTER_MOD (double_modifier, "double", 6);
7820	      break;
7821
7822	    case 't':
7823	      MULTI_LETTER_MOD (triple_modifier, "triple", 6);
7824	      break;
7825
7826	    case 'u':
7827	      MULTI_LETTER_MOD (up_modifier, "up", 2);
7828	      break;
7829
7830	#undef SINGLE_LETTER_MOD
7831	#undef MULTI_LETTER_MOD
7832	    }
7833
7834	  return 0;
7835	}
7836
7837	/* Return true if EVENT is a list whose elements are all integers or symbols.
7838	   Such a list is not valid as an event,
7839	   but it can be a Lucid-style event type list.  */
7840
7841	bool
7842	lucid_event_type_list_p (Lisp_Object object)
7843	{
7844	  if (! CONSP (object))
7845	    return false;
7846
7847	  if (EQ (XCAR (object), Qhelp_echo)
7848	      || EQ (XCAR (object), Qvertical_line)
7849	      || EQ (XCAR (object), Qmode_line)
7850	      || EQ (XCAR (object), Qtab_line)
7851	      || EQ (XCAR (object), Qheader_line))
7852	    return false;
7853
7854	  Lisp_Object tail = object;
7855	  FOR_EACH_TAIL_SAFE (object)
7856	    {
7857	      Lisp_Object elt = XCAR (object);
7858	      if (! (FIXNUMP (elt) || SYMBOLP (elt)))
7859		return false;
7860	      tail = XCDR (object);
7861	    }
7862
7863	  return NILP (tail);
7864	}
7865	^L
7866	/* Return true if terminal input chars are available.
7867	   Also, store the return value into INPUT_PENDING.
7868
7869	   Serves the purpose of ioctl (0, FIONREAD, ...)
7870	   but works even if FIONREAD does not exist.
7871	   (In fact, this may actually read some input.)
7872
7873	   If READABLE_EVENTS_DO_TIMERS_NOW is set in FLAGS, actually run
7874	   timer events that are ripe.
7875	   If READABLE_EVENTS_FILTER_EVENTS is set in FLAGS, ignore internal
7876	   events (FOCUS_IN_EVENT).
7877	   If READABLE_EVENTS_IGNORE_SQUEEZABLES is set in FLAGS, ignore mouse
7878	   movements and toolkit scroll bar thumb drags.
7879
7880	   On X, this also returns if the selection event chain is full, since
7881	   that's also "keyboard input".  */
7882
7883	static bool
7884	get_input_pending (int flags)
7885	{
7886	  /* First of all, have we already counted some input?  */
7887	  input_pending = (!NILP (Vquit_flag) || readable_events (flags));
   0x000055555577ba93 <+12867>:	lea    0x3a49a6(%rip),%rbx        # 0x555555b20440 <globals>

2677	      while (!(input_pending && input_was_pending))
   0x000055555577ba9a <+12874>:	test   %al,%al
   0x000055555577ba9c <+12876>:	jne    0x55555577bae8 <read_char+12952>
   0x000055555577ba9e <+12878>:	xchg   %ax,%ax

2678		{
2679		  input_was_pending = input_pending;
   0x000055555577baa0 <+12880>:	cmpb   $0x0,0x333ae4(%rip)        # 0x555555aaf58b <help_echo_showing_p>
   0x000055555577baa7 <+12887>:	mov    %al,0x38a673(%rip)        # 0x555555b06120 <input_was_pending>

2680		  if (help_echo_showing_p && !BASE_EQ (selected_window, minibuf_window))
   0x000055555577baad <+12893>:	je     0x55555577bb20 <read_char+13008>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577baaf <+12895>:	mov    0x3353aa(%rip),%rax        # 0x555555ab0e60 <minibuf_window>
   0x000055555577bab6 <+12902>:	cmp    %rax,0x3353b3(%rip)        # 0x555555ab0e70 <selected_window>
   0x000055555577babd <+12909>:	je     0x55555577bb20 <read_char+13008>

./src/keyboard.c:
2681		    redisplay_preserve_echo_area (5);
   0x000055555577babf <+12911>:	mov    $0x5,%edi
   0x000055555577bac4 <+12916>:	call   0x55555564ed40 <redisplay_preserve_echo_area>

2684
2685		  if (!input_pending)
   0x000055555577bac9 <+12921>:	cmpb   $0x0,0x38a651(%rip)        # 0x555555b06121 <input_pending>
   0x000055555577bad0 <+12928>:	je     0x55555577baf6 <read_char+12966>

4525
4526	  return (obj);
4527	}
4528	^L
4529	/* Process any non-user-visible events (currently X selection events),
4530	   without reading any user-visible events.  */
4531
4532	static void
4533	process_special_events (void)
4534	{
4535	  union buffered_input_event *event;
4536	#if defined HAVE_X11 || defined HAVE_PGTK || defined HAVE_HAIKU
4537	#ifndef HAVE_HAIKU
4538	  struct selection_input_event copy;
4539	#else
4540	  struct input_event copy;
4541	#endif
4542	  int moved_events;
4543	#endif
4544
4545	  for (event = kbd_fetch_ptr;  event != kbd_store_ptr;
4546	       event = next_kbd_event (event))
4547	    {
4548	      /* If we find a stored X selection request, handle it now.  */
4549	      if (event->kind == SELECTION_REQUEST_EVENT
4550		  || event->kind == SELECTION_CLEAR_EVENT)
4551		{
4552	#if defined HAVE_X11 || defined HAVE_PGTK
4553
4554		  /* Remove the event from the fifo buffer before processing;
4555		     otherwise swallow_events called recursively could see it
4556		     and process it again.  To do this, we move the events
4557		     between kbd_fetch_ptr and EVENT one slot to the right,
4558		     cyclically.  */
4559
4560		  copy = event->sie;
4561
4562		  if (event < kbd_fetch_ptr)
4563		    {
4564		      memmove (kbd_buffer + 1, kbd_buffer,
4565			       (event - kbd_buffer) * sizeof *kbd_buffer);
4566		      kbd_buffer[0] = kbd_buffer[KBD_BUFFER_SIZE - 1];
4567		      moved_events = kbd_buffer + KBD_BUFFER_SIZE - 1 - kbd_fetch_ptr;
4568		    }
4569		  else
4570		    moved_events = event - kbd_fetch_ptr;
4571
4572		  memmove (kbd_fetch_ptr + 1, kbd_fetch_ptr,
4573			   moved_events * sizeof *kbd_fetch_ptr);
4574		  kbd_fetch_ptr = next_kbd_event (kbd_fetch_ptr);
4575		  input_pending = readable_events (0);
4576
4577	#ifdef HAVE_X11
4578		  x_handle_selection_event (&copy);
4579	#else
4580		  pgtk_handle_selection_event (&copy);
4581	#endif
4582	#elif defined HAVE_HAIKU
4583		  if (event->ie.kind != SELECTION_CLEAR_EVENT)
4584		    emacs_abort ();
4585
4586		  copy = event->ie;
4587
4588		  if (event < kbd_fetch_ptr)
4589		    {
4590		      memmove (kbd_buffer + 1, kbd_buffer,
4591			       (event - kbd_buffer) * sizeof *kbd_buffer);
4592		      kbd_buffer[0] = kbd_buffer[KBD_BUFFER_SIZE - 1];
4593		      moved_events = kbd_buffer + KBD_BUFFER_SIZE - 1 - kbd_fetch_ptr;
4594		    }
4595		  else
4596		    moved_events = event - kbd_fetch_ptr;
4597
4598		  memmove (kbd_fetch_ptr + 1, kbd_fetch_ptr,
4599			   moved_events * sizeof *kbd_fetch_ptr);
4600		  kbd_fetch_ptr = next_kbd_event (kbd_fetch_ptr);
4601		  input_pending = readable_events (0);
4602		  haiku_handle_selection_clear (&copy);
4603	#else
4604		  /* We're getting selection request events, but we don't have
4605	             a window system.  */
4606		  emacs_abort ();
4607	#endif
4608		}
4609	    }
4610	}
4611
4612	/* Process any events that are not user-visible, run timer events that
4613	   are ripe, and return, without reading any user-visible events.  */
4614
4615	void
4616	swallow_events (bool do_display)
4617	{
4618	  unsigned old_timers_run;
4619
4620	  process_special_events ();
   0x000055555577bad2 <+12930>:	call   0x555555763ca0 <process_special_events>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577bad7 <+12935>:	cmpq   $0x0,0x988(%rbx)
   0x000055555577badf <+12943>:	je     0x55555577bb27 <read_char+13015>

./src/keyboard.c:
7894	      input_pending = (!NILP (Vquit_flag) || readable_events (flags));
   0x000055555577bae1 <+12945>:	movb   $0x1,0x38a639(%rip)        # 0x555555b06121 <input_pending>

2677	      while (!(input_pending && input_was_pending))
   0x000055555577bae8 <+12952>:	cmpb   $0x0,0x38a631(%rip)        # 0x555555b06120 <input_was_pending>
   0x000055555577baef <+12959>:	mov    $0x1,%eax
   0x000055555577baf4 <+12964>:	je     0x55555577baa0 <read_char+12880>

2686		    /* Normal case: no input arrived during redisplay.  */
2687		    break;
2688
2689		  /* Input arrived and preempted redisplay.
2690		     Process any events which are not user-visible.  */
2691		  swallow_events (false);
2692		  /* If that cleared input_pending, try again to redisplay.  */
2693		}
2694
2695	      /* Prevent the redisplay we just did
2696		 from messing up echoing of the input after the prompt.  */
2697	      if (commandflag == 0 && echo_current)
   0x000055555577baf6 <+12966>:	mov    -0x4dc(%rbp),%edi
   0x000055555577bafc <+12972>:	test   %edi,%edi
   0x000055555577bafe <+12974>:	jne    0x555555778ce2 <read_char+1170>
   0x000055555577bb04 <+12980>:	test   %r12b,%r12b
   0x000055555577bb07 <+12983>:	je     0x555555778ce2 <read_char+1170>

2698		echo_message_buffer = echo_area_buffer[0];
   0x000055555577bb0d <+12989>:	mov    0x333a7c(%rip),%rax        # 0x555555aaf590 <echo_area_buffer>
   0x000055555577bb14 <+12996>:	mov    %rax,0x38a645(%rip)        # 0x555555b06160 <echo_message_buffer>
   0x000055555577bb1b <+13003>:	jmp    0x555555778ce2 <read_char+1170>

2683		    redisplay ();
   0x000055555577bb20 <+13008>:	call   0x55555564ed30 <redisplay>
   0x000055555577bb25 <+13013>:	jmp    0x55555577bac9 <read_char+12921>

7172	}
7173
7174	static Lisp_Object
7175	make_lispy_focus_in (Lisp_Object frame)
7176	{
7177	  return list2 (Qfocus_in, frame);
7178	}
7179
7180	static Lisp_Object
7181	make_lispy_focus_out (Lisp_Object frame)
7182	{
7183	  return list2 (Qfocus_out, frame);
7184	}
7185
7186	/* Manipulating modifiers.  */
7187
7188	/* Parse the name of SYMBOL, and return the set of modifiers it contains.
7189
7190	   If MODIFIER_END is non-zero, set *MODIFIER_END to the position in
7191	   SYMBOL's name of the end of the modifiers; the string from this
7192	   position is the unmodified symbol name.
7193
7194	   This doesn't use any caches.  */
7195
7196	static int
7197	parse_modifiers_uncached (Lisp_Object symbol, ptrdiff_t *modifier_end)
7198	{
7199	  Lisp_Object name;
7200	  ptrdiff_t i;
7201	  int modifiers;
7202
7203	  CHECK_SYMBOL (symbol);
7204
7205	  modifiers = 0;
7206	  name = SYMBOL_NAME (symbol);
7207
7208	  for (i = 0; i < SBYTES (name) - 1; )
7209	    {
7210	      ptrdiff_t this_mod_end = 0;
7211	      int this_mod = 0;
7212
7213	      /* See if the name continues with a modifier word.
7214		 Check that the word appears, but don't check what follows it.
7215		 Set this_mod and this_mod_end to record what we find.  */
7216
7217	      switch (SREF (name, i))
7218		{
7219	#define SINGLE_LETTER_MOD(BIT)				\
7220		  (this_mod_end = i + 1, this_mod = BIT)
7221
7222		case 'A':
7223		  SINGLE_LETTER_MOD (alt_modifier);
7224		  break;
7225
7226		case 'C':
7227		  SINGLE_LETTER_MOD (ctrl_modifier);
7228		  break;
7229
7230		case 'H':
7231		  SINGLE_LETTER_MOD (hyper_modifier);
7232		  break;
7233
7234		case 'M':
7235		  SINGLE_LETTER_MOD (meta_modifier);
7236		  break;
7237
7238		case 'S':
7239		  SINGLE_LETTER_MOD (shift_modifier);
7240		  break;
7241
7242		case 's':
7243		  SINGLE_LETTER_MOD (super_modifier);
7244		  break;
7245
7246	#undef SINGLE_LETTER_MOD
7247
7248	#define MULTI_LETTER_MOD(BIT, NAME, LEN)			\
7249		  if (i + LEN + 1 <= SBYTES (name)			\
7250		      && ! memcmp (SDATA (name) + i, NAME, LEN))	\
7251		    {							\
7252		      this_mod_end = i + LEN;				\
7253		      this_mod = BIT;					\
7254		    }
7255
7256		case 'd':
7257		  MULTI_LETTER_MOD (drag_modifier, "drag", 4);
7258		  MULTI_LETTER_MOD (down_modifier, "down", 4);
7259		  MULTI_LETTER_MOD (double_modifier, "double", 6);
7260		  break;
7261
7262		case 't':
7263		  MULTI_LETTER_MOD (triple_modifier, "triple", 6);
7264		  break;
7265
7266		case 'u':
7267		  MULTI_LETTER_MOD (up_modifier, "up", 2);
7268		  break;
7269	#undef MULTI_LETTER_MOD
7270
7271		}
7272
7273	      /* If we found no modifier, stop looking for them.  */
7274	      if (this_mod_end == 0)
7275		break;
7276
7277	      /* Check there is a dash after the modifier, so that it
7278		 really is a modifier.  */
7279	      if (this_mod_end >= SBYTES (name)
7280		  || SREF (name, this_mod_end) != '-')
7281		break;
7282
7283	      /* This modifier is real; look for another.  */
7284	      modifiers |= this_mod;
7285	      i = this_mod_end + 1;
7286	    }
7287
7288	  /* Should we include the `click' modifier?  */
7289	  if (! (modifiers & (down_modifier | drag_modifier
7290			      | double_modifier | triple_modifier))
7291	      && i + 7 == SBYTES (name)
7292	      && memcmp (SDATA (name) + i, "mouse-", 6) == 0
7293	      && ('0' <= SREF (name, i + 6) && SREF (name, i + 6) <= '9'))
7294	    modifiers |= click_modifier;
7295
7296	  if (! (modifiers & (double_modifier | triple_modifier))
7297	      && i + 6 < SBYTES (name)
7298	      && memcmp (SDATA (name) + i, "wheel-", 6) == 0)
7299	    modifiers |= click_modifier;
7300
7301	  if (modifier_end)
7302	    *modifier_end = i;
7303
7304	  return modifiers;
7305	}
7306
7307	/* Return a symbol whose name is the modifier prefixes for MODIFIERS
7308	   prepended to the string BASE[0..BASE_LEN-1].
7309	   This doesn't use any caches.  */
7310	static Lisp_Object
7311	apply_modifiers_uncached (int modifiers, char *base, int base_len, int base_len_byte)
7312	{
7313	  /* Since BASE could contain nulls, we can't use intern here; we have
7314	     to use Fintern, which expects a genuine Lisp_String, and keeps a
7315	     reference to it.  */
7316	  char new_mods[sizeof "A-C-H-M-S-s-up-down-drag-double-triple-"];
7317	  int mod_len;
7318
7319	  {
7320	    char *p = new_mods;
7321
7322	    /* Mouse events should not exhibit the `up' modifier once they
7323	       leave the event queue only accessible to C code; `up' will
7324	       always be turned into a click or drag event before being
7325	       presented to lisp code.  But since lisp events can be
7326	       synthesized bypassing the event queue and pushed into
7327	       `unread-command-events' or its companions, it's better to just
7328	       deal with unexpected modifier combinations. */
7329
7330	    if (modifiers & alt_modifier)   { *p++ = 'A'; *p++ = '-'; }
7331	    if (modifiers & ctrl_modifier)  { *p++ = 'C'; *p++ = '-'; }
7332	    if (modifiers & hyper_modifier) { *p++ = 'H'; *p++ = '-'; }
7333	    if (modifiers & meta_modifier)  { *p++ = 'M'; *p++ = '-'; }
7334	    if (modifiers & shift_modifier) { *p++ = 'S'; *p++ = '-'; }
7335	    if (modifiers & super_modifier) { *p++ = 's'; *p++ = '-'; }
7336	    if (modifiers & double_modifier) p = stpcpy (p, "double-");
7337	    if (modifiers & triple_modifier) p = stpcpy (p, "triple-");
7338	    if (modifiers & up_modifier) p = stpcpy (p, "up-");
7339	    if (modifiers & down_modifier) p = stpcpy (p, "down-");
7340	    if (modifiers & drag_modifier) p = stpcpy (p, "drag-");
7341	    /* The click modifier is denoted by the absence of other modifiers.  */
7342
7343	    *p = '\0';
7344
7345	    mod_len = p - new_mods;
7346	  }
7347
7348	  {
7349	    Lisp_Object new_name;
7350
7351	    new_name = make_uninit_multibyte_string (mod_len + base_len,
7352						     mod_len + base_len_byte);
7353	    memcpy (SDATA (new_name), new_mods, mod_len);
7354	    memcpy (SDATA (new_name) + mod_len, base, base_len_byte);
7355
7356	    return Fintern (new_name, Qnil);
7357	  }
7358	}
7359
7360
7361	static const char *const modifier_names[] =
7362	{
7363	  "up", "down", "drag", "click", "double", "triple", 0, 0,
7364	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7365	  0, 0, "alt", "super", "hyper", "shift", "control", "meta"
7366	};
7367	#define NUM_MOD_NAMES ARRAYELTS (modifier_names)
7368
7369	static Lisp_Object modifier_symbols;
7370
7371	/* Return the list of modifier symbols corresponding to the mask MODIFIERS.  */
7372	static Lisp_Object
7373	lispy_modifier_list (int modifiers)
7374	{
7375	  Lisp_Object modifier_list;
7376	  int i;
7377
7378	  modifier_list = Qnil;
7379	  for (i = 0; (1<<i) <= modifiers && i < NUM_MOD_NAMES; i++)
7380	    if (modifiers & (1<<i))
7381	      modifier_list = Fcons (AREF (modifier_symbols, i),
7382				     modifier_list);
7383
7384	  return modifier_list;
7385	}
7386
7387
7388	/* Parse the modifiers on SYMBOL, and return a list like (UNMODIFIED MASK),
7389	   where UNMODIFIED is the unmodified form of SYMBOL,
7390	   MASK is the set of modifiers present in SYMBOL's name.
7391	   This is similar to parse_modifiers_uncached, but uses the cache in
7392	   SYMBOL's Qevent_symbol_element_mask property, and maintains the
7393	   Qevent_symbol_elements property.  */
7394
7395	#define KEY_TO_CHAR(k) (XFIXNUM (k) & ((1 << CHARACTERBITS) - 1))
7396
7397	Lisp_Object
7398	parse_modifiers (Lisp_Object symbol)
7399	{
7400	  Lisp_Object elements;
7401
7402	  if (FIXNUMP (symbol))
7403	    return list2i (KEY_TO_CHAR (symbol), XFIXNUM (symbol) & CHAR_MODIFIER_MASK);
7404	  else if (!SYMBOLP (symbol))
7405	    return Qnil;
7406
7407	  elements = Fget (symbol, Qevent_symbol_element_mask);
7408	  if (CONSP (elements))
7409	    return elements;
7410	  else
7411	    {
7412	      ptrdiff_t end;
7413	      int modifiers = parse_modifiers_uncached (symbol, &end);
7414	      Lisp_Object unmodified;
7415	      Lisp_Object mask;
7416
7417	      unmodified = Fintern (make_string (SSDATA (SYMBOL_NAME (symbol)) + end,
7418						 SBYTES (SYMBOL_NAME (symbol)) - end),
7419				    Qnil);
7420
7421	      if (modifiers & ~INTMASK)
7422		emacs_abort ();
7423	      XSETFASTINT (mask, modifiers);
7424	      elements = list2 (unmodified, mask);
7425
7426	      /* Cache the parsing results on SYMBOL.  */
7427	      Fput (symbol, Qevent_symbol_element_mask,
7428		    elements);
7429	      Fput (symbol, Qevent_symbol_elements,
7430		    Fcons (unmodified, lispy_modifier_list (modifiers)));
7431
7432	      /* Since we know that SYMBOL is modifiers applied to unmodified,
7433		 it would be nice to put that in unmodified's cache.
7434		 But we can't, since we're not sure that parse_modifiers is
7435		 canonical.  */
7436
7437	      return elements;
7438	    }
7439	}
7440
7441	DEFUN ("internal-event-symbol-parse-modifiers", Fevent_symbol_parse_modifiers,
7442	       Sevent_symbol_parse_modifiers, 1, 1, 0,
7443	       doc: /* Parse the event symbol.  For internal use.  */)
7444	  (Lisp_Object symbol)
7445	{
7446	  /* Fill the cache if needed.  */
7447	  parse_modifiers (symbol);
7448	  /* Ignore the result (which is stored on Qevent_symbol_element_mask)
7449	     and use the Lispier representation stored on Qevent_symbol_elements
7450	     instead.  */
7451	  return Fget (symbol, Qevent_symbol_elements);
7452	}
7453
7454	/* Apply the modifiers MODIFIERS to the symbol BASE.
7455	   BASE must be unmodified.
7456
7457	   This is like apply_modifiers_uncached, but uses BASE's
7458	   Qmodifier_cache property, if present.
7459
7460	   apply_modifiers copies the value of BASE's Qevent_kind property to
7461	   the modified symbol.  */
7462	static Lisp_Object
7463	apply_modifiers (int modifiers, Lisp_Object base)
7464	{
7465	  Lisp_Object cache, idx, entry, new_symbol;
7466
7467	  /* Mask out upper bits.  We don't know where this value's been.  */
7468	  modifiers &= INTMASK;
7469
7470	  if (FIXNUMP (base))
7471	    return make_fixnum (XFIXNUM (base) | modifiers);
7472
7473	  /* The click modifier never figures into cache indices.  */
7474	  cache = Fget (base, Qmodifier_cache);
7475	  XSETFASTINT (idx, (modifiers & ~click_modifier));
7476	  entry = assq_no_quit (idx, cache);
7477
7478	  if (CONSP (entry))
7479	    new_symbol = XCDR (entry);
7480	  else
7481	    {
7482	      /* We have to create the symbol ourselves.  */
7483	      new_symbol = apply_modifiers_uncached (modifiers,
7484						     SSDATA (SYMBOL_NAME (base)),
7485						     SCHARS (SYMBOL_NAME (base)),
7486						     SBYTES (SYMBOL_NAME (base)));
7487
7488	      /* Add the new symbol to the base's cache.  */
7489	      entry = Fcons (idx, new_symbol);
7490	      Fput (base, Qmodifier_cache, Fcons (entry, cache));
7491
7492	      /* We have the parsing info now for free, so we could add it to
7493		 the caches:
7494	         XSETFASTINT (idx, modifiers);
7495	         Fput (new_symbol, Qevent_symbol_element_mask,
7496	               list2 (base, idx));
7497	         Fput (new_symbol, Qevent_symbol_elements,
7498	               Fcons (base, lispy_modifier_list (modifiers)));
7499		 Sadly, this is only correct if `base' is indeed a base event,
7500		 which is not necessarily the case.  -stef  */
7501	    }
7502
7503	  /* Make sure this symbol is of the same kind as BASE.
7504
7505	     You'd think we could just set this once and for all when we
7506	     intern the symbol above, but reorder_modifiers may call us when
7507	     BASE's property isn't set right; we can't assume that just
7508	     because it has a Qmodifier_cache property it must have its
7509	     Qevent_kind set right as well.  */
7510	  if (NILP (Fget (new_symbol, Qevent_kind)))
7511	    {
7512	      Lisp_Object kind;
7513
7514	      kind = Fget (base, Qevent_kind);
7515	      if (! NILP (kind))
7516		Fput (new_symbol, Qevent_kind, kind);
7517	    }
7518
7519	  return new_symbol;
7520	}
7521
7522
7523	/* Given a symbol whose name begins with modifiers ("C-", "M-", etc),
7524	   return a symbol with the modifiers placed in the canonical order.
7525	   Canonical order is alphabetical, except for down and drag, which
7526	   always come last.  The 'click' modifier is never written out.
7527
7528	   Fdefine_key calls this to make sure that (for example) C-M-foo
7529	   and M-C-foo end up being equivalent in the keymap.  */
7530
7531	Lisp_Object
7532	reorder_modifiers (Lisp_Object symbol)
7533	{
7534	  /* It's hopefully okay to write the code this way, since everything
7535	     will soon be in caches, and no consing will be done at all.  */
7536	  Lisp_Object parsed;
7537
7538	  parsed = parse_modifiers (symbol);
7539	  return apply_modifiers (XFIXNAT (XCAR (XCDR (parsed))),
7540				  XCAR (parsed));
7541	}
7542
7543
7544	/* For handling events, we often want to produce a symbol whose name
7545	   is a series of modifier key prefixes ("M-", "C-", etcetera) attached
7546	   to some base, like the name of a function key or mouse button.
7547	   modify_event_symbol produces symbols of this sort.
7548
7549	   NAME_TABLE should point to an array of strings, such that NAME_TABLE[i]
7550	   is the name of the i'th symbol.  TABLE_SIZE is the number of elements
7551	   in the table.
7552
7553	   Alternatively, NAME_ALIST_OR_STEM is either an alist mapping codes
7554	   into symbol names, or a string specifying a name stem used to
7555	   construct a symbol name or the form `STEM-N', where N is the decimal
7556	   representation of SYMBOL_NUM.  NAME_ALIST_OR_STEM is used if it is
7557	   non-nil; otherwise NAME_TABLE is used.
7558
7559	   SYMBOL_TABLE should be a pointer to a Lisp_Object whose value will
7560	   persist between calls to modify_event_symbol that it can use to
7561	   store a cache of the symbols it's generated for this NAME_TABLE
7562	   before.  The object stored there may be a vector or an alist.
7563
7564	   SYMBOL_NUM is the number of the base name we want from NAME_TABLE.
7565
7566	   MODIFIERS is a set of modifier bits (as given in struct input_events)
7567	   whose prefixes should be applied to the symbol name.
7568
7569	   SYMBOL_KIND is the value to be placed in the event_kind property of
7570	   the returned symbol.
7571
7572	   The symbols we create are supposed to have an
7573	   `event-symbol-elements' property, which lists the modifiers present
7574	   in the symbol's name.  */
7575
7576	static Lisp_Object
7577	modify_event_symbol (ptrdiff_t symbol_num, int modifiers, Lisp_Object symbol_kind,
7578			     Lisp_Object name_alist_or_stem, const char *const *name_table,
7579			     Lisp_Object *symbol_table, ptrdiff_t table_size)
7580	{
7581	  Lisp_Object value;
7582	  Lisp_Object symbol_int;
7583
7584	  /* Get rid of the "vendor-specific" bit here.  */
7585	  XSETINT (symbol_int, symbol_num & 0xffffff);
7586
7587	  /* Is this a request for a valid symbol?  */
7588	  if (symbol_num < 0 || symbol_num >= table_size)
7589	    return Qnil;
7590
7591	  if (CONSP (*symbol_table))
7592	    value = Fcdr (assq_no_quit (symbol_int, *symbol_table));
7593
7594	  /* If *symbol_table doesn't seem to be initialized properly, fix that.
7595	     *symbol_table should be a lisp vector TABLE_SIZE elements long,
7596	     where the Nth element is the symbol for NAME_TABLE[N], or nil if
7597	     we've never used that symbol before.  */
7598	  else
7599	    {
7600	      if (! VECTORP (*symbol_table)
7601		  || ASIZE (*symbol_table) != table_size)
7602		*symbol_table = make_nil_vector (table_size);
7603
7604	      value = AREF (*symbol_table, symbol_num);
7605	    }
7606
7607	  /* Have we already used this symbol before?  */
7608	  if (NILP (value))
7609	    {
7610	      /* No; let's create it.  */
7611	      if (CONSP (name_alist_or_stem))
7612		value = Fcdr_safe (Fassq (symbol_int, name_alist_or_stem));
7613	      else if (STRINGP (name_alist_or_stem))
7614		{
7615		  char *buf;
7616		  ptrdiff_t len = (SBYTES (name_alist_or_stem)
7617				   + sizeof "-" + INT_STRLEN_BOUND (EMACS_INT));
7618		  USE_SAFE_ALLOCA;
7619		  buf = SAFE_ALLOCA (len);
7620		  esprintf (buf, "%s-%"pI"d", SDATA (name_alist_or_stem),
7621			    XFIXNUM (symbol_int) + 1);
7622		  value = intern (buf);
7623		  SAFE_FREE ();
7624		}
7625	      else if (name_table != 0 && name_table[symbol_num])
7626		value = intern (name_table[symbol_num]);
7627
7628	#ifdef HAVE_WINDOW_SYSTEM
7629	      if (NILP (value))
7630		{
7631		  char *name = get_keysym_name (symbol_num);
7632		  if (name)
7633		    value = intern (name);
7634		}
7635	#endif
7636
7637	      if (NILP (value))
7638		{
7639		  char buf[sizeof "key-" + INT_STRLEN_BOUND (EMACS_INT)];
7640		  sprintf (buf, "key-%"pD"d", symbol_num);
7641		  value = intern (buf);
7642		}
7643
7644	      if (CONSP (*symbol_table))
7645	        *symbol_table = Fcons (Fcons (symbol_int, value), *symbol_table);
7646	      else
7647		ASET (*symbol_table, symbol_num, value);
7648
7649	      /* Fill in the cache entries for this symbol; this also
7650		 builds the Qevent_symbol_elements property, which the user
7651		 cares about.  */
7652	      apply_modifiers (modifiers & click_modifier, value);
7653	      Fput (value, Qevent_kind, symbol_kind);
7654	    }
7655
7656	  /* Apply modifiers to that symbol.  */
7657	  return apply_modifiers (modifiers, value);
7658	}
7659	^L
7660	/* Convert a list that represents an event type,
7661	   such as (ctrl meta backspace), into the usual representation of that
7662	   event type as a number or a symbol.  */
7663
7664	DEFUN ("event-convert-list", Fevent_convert_list, Sevent_convert_list, 1, 1, 0,
7665	       doc: /* Convert the event description list EVENT-DESC to an event type.
7666	EVENT-DESC should contain one base event type (a character or symbol)
7667	and zero or more modifier names (control, meta, hyper, super, shift, alt,
7668	drag, down, double or triple).  The base must be last.
7669
7670	The return value is an event type (a character or symbol) which has
7671	essentially the same base event type and all the specified modifiers.
7672	(Some compatibility base types, like symbols that represent a
7673	character, are not returned verbatim.)  */)
7674	  (Lisp_Object event_desc)
7675	{
7676	  Lisp_Object base = Qnil;
7677	  int modifiers = 0;
7678
7679	  FOR_EACH_TAIL_SAFE (event_desc)
7680	    {
7681	      Lisp_Object elt = XCAR (event_desc);
7682	      int this = 0;
7683
7684	      /* Given a symbol, see if it is a modifier name.  */
7685	      if (SYMBOLP (elt) && CONSP (XCDR (event_desc)))
7686		this = parse_solitary_modifier (elt);
7687
7688	      if (this != 0)
7689		modifiers |= this;
7690	      else if (!NILP (base))
7691		error ("Two bases given in one event");
7692	      else
7693		base = elt;
7694	    }
7695
7696	  /* Let the symbol A refer to the character A.  */
7697	  if (SYMBOLP (base) && SCHARS (SYMBOL_NAME (base)) == 1)
7698	    XSETINT (base, SREF (SYMBOL_NAME (base), 0));
7699
7700	  if (FIXNUMP (base))
7701	    {
7702	      /* Turn (shift a) into A.  */
7703	      if ((modifiers & shift_modifier) != 0
7704		  && (XFIXNUM (base) >= 'a' && XFIXNUM (base) <= 'z'))
7705		{
7706		  XSETINT (base, XFIXNUM (base) - ('a' - 'A'));
7707		  modifiers &= ~shift_modifier;
7708		}
7709
7710	      /* Turn (control a) into C-a.  */
7711	      if (modifiers & ctrl_modifier)
7712		return make_fixnum ((modifiers & ~ctrl_modifier)
7713				    | make_ctrl_char (XFIXNUM (base)));
7714	      else
7715		return make_fixnum (modifiers | XFIXNUM (base));
7716	    }
7717	  else if (SYMBOLP (base))
7718	    return apply_modifiers (modifiers, base);
7719	  else
7720	    error ("Invalid base event");
7721	}
7722
7723	DEFUN ("internal-handle-focus-in", Finternal_handle_focus_in,
7724	       Sinternal_handle_focus_in, 1, 1, 0,
7725	       doc: /* Internally handle focus-in events.
7726	This function potentially generates an artificial switch-frame event.  */)
7727	     (Lisp_Object event)
7728	{
7729	  Lisp_Object frame;
7730	  if (!EQ (CAR_SAFE (event), Qfocus_in) ||
7731	      !CONSP (XCDR (event)) ||
7732	      !FRAMEP ((frame = XCAR (XCDR (event)))))
7733	    error ("Invalid focus-in event");
7734
7735	  /* Conceptually, the concept of window manager focus on a particular
7736	     frame and the Emacs selected frame shouldn't be related, but for
7737	     a long time, we automatically switched the selected frame in
7738	     response to focus events, so let's keep doing that.  */
7739	  bool switching = (!EQ (frame, internal_last_event_frame)
7740	                    && !EQ (frame, selected_frame));
7741	  internal_last_event_frame = frame;
7742	  if (switching || !NILP (unread_switch_frame))
7743	    unread_switch_frame = make_lispy_switch_frame (frame);
7744
7745	  return Qnil;
7746	}
7747
7748	/* Try to recognize SYMBOL as a modifier name.
7749	   Return the modifier flag bit, or 0 if not recognized.  */
7750
7751	int
7752	parse_solitary_modifier (Lisp_Object symbol)
7753	{
7754	  Lisp_Object name;
7755
7756	  if (!SYMBOLP (symbol))
7757	    return 0;
7758
7759	  name = SYMBOL_NAME (symbol);
7760
7761	  switch (SREF (name, 0))
7762	    {
7763	#define SINGLE_LETTER_MOD(BIT)				\
7764	      if (SBYTES (name) == 1)				\
7765		return BIT;
7766
7767	#define MULTI_LETTER_MOD(BIT, NAME, LEN)		\
7768	      if (LEN == SBYTES (name)				\
7769		  && ! memcmp (SDATA (name), NAME, LEN))	\
7770		return BIT;
7771
7772	    case 'A':
7773	      SINGLE_LETTER_MOD (alt_modifier);
7774	      break;
7775
7776	    case 'a':
7777	      MULTI_LETTER_MOD (alt_modifier, "alt", 3);
7778	      break;
7779
7780	    case 'C':
7781	      SINGLE_LETTER_MOD (ctrl_modifier);
7782	      break;
7783
7784	    case 'c':
7785	      MULTI_LETTER_MOD (ctrl_modifier, "ctrl", 4);
7786	      MULTI_LETTER_MOD (ctrl_modifier, "control", 7);
7787	      MULTI_LETTER_MOD (click_modifier, "click", 5);
7788	      break;
7789
7790	    case 'H':
7791	      SINGLE_LETTER_MOD (hyper_modifier);
7792	      break;
7793
7794	    case 'h':
7795	      MULTI_LETTER_MOD (hyper_modifier, "hyper", 5);
7796	      break;
7797
7798	    case 'M':
7799	      SINGLE_LETTER_MOD (meta_modifier);
7800	      break;
7801
7802	    case 'm':
7803	      MULTI_LETTER_MOD (meta_modifier, "meta", 4);
7804	      break;
7805
7806	    case 'S':
7807	      SINGLE_LETTER_MOD (shift_modifier);
7808	      break;
7809
7810	    case 's':
7811	      MULTI_LETTER_MOD (shift_modifier, "shift", 5);
7812	      MULTI_LETTER_MOD (super_modifier, "super", 5);
7813	      SINGLE_LETTER_MOD (super_modifier);
7814	      break;
7815
7816	    case 'd':
7817	      MULTI_LETTER_MOD (drag_modifier, "drag", 4);
7818	      MULTI_LETTER_MOD (down_modifier, "down", 4);
7819	      MULTI_LETTER_MOD (double_modifier, "double", 6);
7820	      break;
7821
7822	    case 't':
7823	      MULTI_LETTER_MOD (triple_modifier, "triple", 6);
7824	      break;
7825
7826	    case 'u':
7827	      MULTI_LETTER_MOD (up_modifier, "up", 2);
7828	      break;
7829
7830	#undef SINGLE_LETTER_MOD
7831	#undef MULTI_LETTER_MOD
7832	    }
7833
7834	  return 0;
7835	}
7836
7837	/* Return true if EVENT is a list whose elements are all integers or symbols.
7838	   Such a list is not valid as an event,
7839	   but it can be a Lucid-style event type list.  */
7840
7841	bool
7842	lucid_event_type_list_p (Lisp_Object object)
7843	{
7844	  if (! CONSP (object))
7845	    return false;
7846
7847	  if (EQ (XCAR (object), Qhelp_echo)
7848	      || EQ (XCAR (object), Qvertical_line)
7849	      || EQ (XCAR (object), Qmode_line)
7850	      || EQ (XCAR (object), Qtab_line)
7851	      || EQ (XCAR (object), Qheader_line))
7852	    return false;
7853
7854	  Lisp_Object tail = object;
7855	  FOR_EACH_TAIL_SAFE (object)
7856	    {
7857	      Lisp_Object elt = XCAR (object);
7858	      if (! (FIXNUMP (elt) || SYMBOLP (elt)))
7859		return false;
7860	      tail = XCDR (object);
7861	    }
7862
7863	  return NILP (tail);
7864	}
7865	^L
7866	/* Return true if terminal input chars are available.
7867	   Also, store the return value into INPUT_PENDING.
7868
7869	   Serves the purpose of ioctl (0, FIONREAD, ...)
7870	   but works even if FIONREAD does not exist.
7871	   (In fact, this may actually read some input.)
7872
7873	   If READABLE_EVENTS_DO_TIMERS_NOW is set in FLAGS, actually run
7874	   timer events that are ripe.
7875	   If READABLE_EVENTS_FILTER_EVENTS is set in FLAGS, ignore internal
7876	   events (FOCUS_IN_EVENT).
7877	   If READABLE_EVENTS_IGNORE_SQUEEZABLES is set in FLAGS, ignore mouse
7878	   movements and toolkit scroll bar thumb drags.
7879
7880	   On X, this also returns if the selection event chain is full, since
7881	   that's also "keyboard input".  */
7882
7883	static bool
7884	get_input_pending (int flags)
7885	{
7886	  /* First of all, have we already counted some input?  */
7887	  input_pending = (!NILP (Vquit_flag) || readable_events (flags));
   0x000055555577bb27 <+13015>:	mov    $0x1,%edi
   0x000055555577bb2c <+13020>:	call   0x555555772b20 <readable_events>
   0x000055555577bb31 <+13025>:	test   %al,%al
   0x000055555577bb33 <+13027>:	jne    0x55555577bae1 <read_char+12945>

7888
7889	  /* If input is being read as it arrives, and we have none, there is none.  */
7890	  if (!input_pending && (!interrupt_input || interrupts_deferred))
   0x000055555577bb35 <+13029>:	cmpb   $0x0,0x34a5be(%rip)        # 0x555555ac60fa <interrupt_input>

7887	  input_pending = (!NILP (Vquit_flag) || readable_events (flags));
   0x000055555577bb3c <+13036>:	movb   $0x0,0x38a5de(%rip)        # 0x555555b06121 <input_pending>

7888
7889	  /* If input is being read as it arrives, and we have none, there is none.  */
7890	  if (!input_pending && (!interrupt_input || interrupts_deferred))
   0x000055555577bb43 <+13043>:	je     0x55555577bb54 <read_char+13060>
   0x000055555577bb45 <+13045>:	movzbl 0x34a5ad(%rip),%eax        # 0x555555ac60f9 <interrupts_deferred>
   0x000055555577bb4c <+13052>:	test   %al,%al
   0x000055555577bb4e <+13054>:	je     0x55555577baa0 <read_char+12880>

7891	    {
7892	      /* Try to read some input and see how much we get.  */
7893	      gobble_input ();
   0x000055555577bb54 <+13060>:	call   0x555555771b00 <gobble_input>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577bb59 <+13065>:	cmpq   $0x0,0x988(%rbx)
   0x000055555577bb61 <+13073>:	jne    0x55555577bae1 <read_char+12945>

./src/keyboard.c:
7894	      input_pending = (!NILP (Vquit_flag) || readable_events (flags));
   0x000055555577bb67 <+13079>:	mov    $0x1,%edi
   0x000055555577bb6c <+13084>:	call   0x555555772b20 <readable_events>
   0x000055555577bb71 <+13089>:	mov    %al,0x38a5aa(%rip)        # 0x555555b06121 <input_pending>

4625	  if (!input_pending && timers_run != old_timers_run && do_display)
   0x000055555577bb77 <+13095>:	jmp    0x55555577ba9a <read_char+12874>

2561		c = XCAR (c);
   0x000055555577bb7c <+13100>:	mov    %r14,%rdi
   0x000055555577bb7f <+13103>:	call   0x555555763090 <XCAR>

2562
2563	      reread = true;
   0x000055555577bb84 <+13108>:	movb   $0x1,-0x487(%rbp)

2561		c = XCAR (c);
   0x000055555577bb8b <+13115>:	mov    %rax,%r14
   0x000055555577bb8e <+13118>:	mov    %rax,%r12

./src/lisp.h:
774	  return lisp_h_TAGGEDP (a, tag);
   0x000055555577bb91 <+13121>:	lea    -0x3(%rax),%eax
   0x000055555577bb94 <+13124>:	and    $0x7,%eax

./src/keyboard.c:
2564	      goto reread_first;
   0x000055555577bb97 <+13127>:	jmp    0x555555778a30 <read_char+480>

3060	    {
3061	      if (commandflag >= 0
   0x000055555577bb9c <+13132>:	mov    -0x4dc(%rbp),%eax
   0x000055555577bba2 <+13138>:	test   %eax,%eax
   0x000055555577bba4 <+13140>:	js     0x555555779457 <read_char+3079>

3062		  && !input_pending && !detect_input_pending_run_timers (0))
   0x000055555577bbaa <+13146>:	cmpb   $0x0,0x38a570(%rip)        # 0x555555b06121 <input_pending>
   0x000055555577bbb1 <+13153>:	jne    0x555555779457 <read_char+3079>
   0x000055555577bbb7 <+13159>:	xor    %edi,%edi
   0x000055555577bbb9 <+13161>:	call   0x5555557786a0 <detect_input_pending_run_timers>
   0x000055555577bbbe <+13166>:	test   %al,%al
   0x000055555577bbc0 <+13168>:	jne    0x555555779457 <read_char+3079>

3063		redisplay ();
   0x000055555577bbc6 <+13174>:	call   0x55555564ed30 <redisplay>
   0x000055555577bbcb <+13179>:	jmp    0x555555779457 <read_char+3079>

2796			while (CONSP (XCDR (last)))
   0x000055555577bbd0 <+13184>:	mov    %rax,%r13
   0x000055555577bbd3 <+13187>:	jmp    0x55555577a843 <read_char+8179>

2732		  || ok_to_echo_at_next_pause == NULL))
   0x000055555577bbd8 <+13192>:	cmpq   $0x0,0x38aa10(%rip)        # 0x555555b065f0 <ok_to_echo_at_next_pause>
   0x000055555577bbe0 <+13200>:	je     0x555555778d04 <read_char+1204>

2733	    cancel_echoing ();
2734	  else
2735	    echo_dash ();
   0x000055555577bbe6 <+13206>:	call   0x555555767b70 <echo_dash>
   0x000055555577bbeb <+13211>:	jmp    0x555555778d42 <read_char+1266>

4506		obj = make_lispy_movement (f, bar_window, part, x, y, t);
   0x000055555577bbf0 <+13216>:	mov    -0x448(%rbp),%rcx
   0x000055555577bbf7 <+13223>:	mov    -0x458(%rbp),%rax
   0x000055555577bbfe <+13230>:	mov    -0x450(%rbp),%rdx

7152			    list5 (bar_window,
7153				   Qvertical_scroll_bar,
7154				   Fcons (x, y),
7155				   make_fixnum (t),
7156				   part_sym));
7157	    }
7158	  /* Or is it an ordinary mouse movement?  */
7159	  else
7160	    {
7161	      Lisp_Object position;
7162	      position = make_lispy_position (frame, x, y, t);
   0x000055555577bc05 <+13237>:	mov    %rax,%rsi
   0x000055555577bc08 <+13240>:	mov    %rbx,%rdi
   0x000055555577bc0b <+13243>:	call   0x5555557693e0 <make_lispy_position>

7163	      return list2 (Qmouse_movement, position);
   0x000055555577bc10 <+13248>:	mov    $0xfe68,%edi

7162	      position = make_lispy_position (frame, x, y, t);
   0x000055555577bc15 <+13253>:	mov    %rax,%rsi

./src/lisp.h:
1184	  return a;
   0x000055555577bc18 <+13256>:	call   0x5555557ef5d0 <list2>
   0x000055555577bc1d <+13261>:	mov    %rax,%rcx

./src/keyboard.c:
7163	      return list2 (Qmouse_movement, position);
   0x000055555577bc20 <+13264>:	jmp    0x55555577a16d <read_char+6429>

./src/lisp.h:
1184	  return a;
   0x000055555577bc25 <+13269>:	mov    -0x4c0(%rbp),%rdi
   0x000055555577bc2c <+13276>:	call   0x555555763090 <XCAR>
   0x000055555577bc31 <+13281>:	mov    $0xf148,%esi
   0x000055555577bc36 <+13286>:	mov    %rax,%rdi
   0x000055555577bc39 <+13289>:	call   0x555555764470 <EQ>

./src/keyboard.c:
2887	      && !EQ (XCAR (prev_event), Qmenu_bar)
   0x000055555577bc3e <+13294>:	test   %al,%al
   0x000055555577bc40 <+13296>:	jne    0x55555577a4d4 <read_char+7300>

./src/lisp.h:
1184	  return a;
   0x000055555577bc46 <+13302>:	mov    -0x4c0(%rbp),%rdi
   0x000055555577bc4d <+13309>:	call   0x555555763090 <XCAR>
   0x000055555577bc52 <+13314>:	mov    $0x14b30,%esi
   0x000055555577bc57 <+13319>:	mov    %rax,%rdi
   0x000055555577bc5a <+13322>:	call   0x555555764470 <EQ>

./src/keyboard.c:
2888	      && !EQ (XCAR (prev_event), Qtab_bar)
   0x000055555577bc5f <+13327>:	test   %al,%al
   0x000055555577bc61 <+13329>:	jne    0x55555577a4d4 <read_char+7300>

./src/lisp.h:
1184	  return a;
   0x000055555577bc67 <+13335>:	mov    -0x4c0(%rbp),%rdi
   0x000055555577bc6e <+13342>:	call   0x555555763090 <XCAR>
   0x000055555577bc73 <+13347>:	mov    $0x15230,%esi
   0x000055555577bc78 <+13352>:	mov    %rax,%rdi
   0x000055555577bc7b <+13355>:	call   0x555555764470 <EQ>

./src/keyboard.c:
2889	      && !EQ (XCAR (prev_event), Qtool_bar)
   0x000055555577bc80 <+13360>:	test   %al,%al
   0x000055555577bc82 <+13362>:	jne    0x55555577a4d4 <read_char+7300>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577bc88 <+13368>:	mov    0x3a53ea(%rip),%eax        # 0x555555b21078 <globals+3128>
   0x000055555577bc8e <+13374>:	sub    $0x3,%eax

./src/keyboard.c:
2891	      && !CONSP (Vunread_command_events))
   0x000055555577bc91 <+13377>:	test   $0x7,%al
   0x000055555577bc93 <+13379>:	je     0x55555577a4d4 <read_char+7300>

2892	    {
2893	      c = read_char_x_menu_prompt (map, prev_event, used_mouse_menu);
   0x000055555577bc99 <+13385>:	mov    -0x4d0(%rbp),%rdx
   0x000055555577bca0 <+13392>:	mov    -0x4c0(%rbp),%rsi
   0x000055555577bca7 <+13399>:	mov    -0x4b0(%rbp),%rdi
   0x000055555577bcae <+13406>:	call   0x555555773bf0 <read_char_x_menu_prompt>

2894
2895	      /* Now that we have read an event, Emacs is not idle.  */
2896	      if (!end_time)
   0x000055555577bcb3 <+13411>:	cmpq   $0x0,-0x4a8(%rbp)

2893	      c = read_char_x_menu_prompt (map, prev_event, used_mouse_menu);
   0x000055555577bcbb <+13419>:	mov    %rax,%r14

2894
2895	      /* Now that we have read an event, Emacs is not idle.  */
2896	      if (!end_time)
   0x000055555577bcbe <+13422>:	jne    0x555555778b30 <read_char+736>

4641
4642	  /* Mark all idle-time timers as once again candidates for running.  */
4643	  call0 (Qinternal_timer_start_idle);
4644	}
4645
4646	/* Record that Emacs is no longer idle, so stop running idle-time timers.  */
4647
4648	static void
4649	timer_stop_idle (void)
4650	{
4651	  timer_idleness_start_time = invalid_timespec ();
   0x000055555577bcc4 <+13428>:	movdqa 0x23f434(%rip),%xmm0        # 0x5555559bb100
   0x000055555577bccc <+13436>:	movaps %xmm0,0x38a8dd(%rip)        # 0x555555b065b0 <timer_idleness_start_time>

4652	}
   0x000055555577bcd3 <+13443>:	jmp    0x555555778b30 <read_char+736>
   0x000055555577bcd8 <+13448>:	nopl   0x0(%rax,%rax,1)

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577bce0 <+13456>:	lea    -0x5(%rax),%esi

775	}
776
777	INLINE void
778	(CHECK_TYPE) (int ok, Lisp_Object predicate, Lisp_Object x)
779	{
780	  lisp_h_CHECK_TYPE (ok, predicate, x);
781	}
782
783	/* Extract A's pointer value, assuming A's Lisp type is TYPE and the
784	   extracted pointer's type is CTYPE *.  When !USE_LSB_TAG this simply
785	   extracts A's low-order bits, as (uintptr_t) LISP_WORD_TAG (type) is
786	   always zero then.  */
787	#define XUNTAG(a, type, ctype) \
788	  ((ctype *) ((uintptr_t) XLP (a) - (uintptr_t) LISP_WORD_TAG (type)))
789
790	/* A forwarding pointer to a value.  It uses a generic pointer to
791	   avoid alignment bugs that could occur if it used a pointer to a
792	   union of the possible values (struct Lisp_Objfwd, struct
793	   Lisp_Intfwd, etc.).  The pointer is packaged inside a struct to
794	   help static checking.  */
795	typedef const struct Lisp_Fwd *lispfwd;
796	^L
797	/* Interned state of a symbol.  */
798
799	enum symbol_interned
800	{
801	  SYMBOL_UNINTERNED,		      /* not interned anywhere */
802	  SYMBOL_INTERNED,		      /* interned but not in initial obarray */
803	  SYMBOL_INTERNED_IN_INITIAL_OBARRAY  /* interned in initial obarray */
804	};
805
806	enum symbol_redirect
807	{
808	  SYMBOL_PLAINVAL,   /* plain var, value is in the `value' field */
809	  SYMBOL_VARALIAS,   /* var alias, value is really in the `alias' symbol */
810	  SYMBOL_LOCALIZED,  /* localized var, value is in the `blv' object */
811	  SYMBOL_FORWARDED   /* forwarding var, value is in `forward' */
812	};
813
814	enum symbol_trapped_write
815	{
816	  SYMBOL_UNTRAPPED_WRITE,  /* normal case, just set the value */
817	  SYMBOL_NOWRITE,          /* constant, cannot set, e.g. nil, t, :keyword */
818	  SYMBOL_TRAPPED_WRITE     /* trap the write, call watcher functions */
819	};
820
821	struct Lisp_Symbol
822	{
823	  GC_HEADER
824	  union
825	  {
826	    struct
827	    {
828	      bool_bf gcmarkbit : 1;
829
830	      /* Indicates where the value can be found.  */
831	      ENUM_BF (symbol_redirect) redirect : 2;
832
833	      ENUM_BF (symbol_trapped_write) trapped_write : 2;
834
835	      /* Interned state of the symbol.  */
836	      ENUM_BF (symbol_interned) interned : 2;
837
838	      /* True means that this variable has been explicitly declared
839		 special (with `defvar' etc), and shouldn't be lexically bound.  */
840	      bool_bf declared_special : 1;
841
842	      /* The symbol's name, as a Lisp string.  */
843	      Lisp_Object name;
844
845	      /* Value of the symbol or Qunbound if unbound.  Which alternative of the
846		 union is used depends on the `redirect' field above.  */
847	      union {
848		Lisp_Object value;
849		struct Lisp_Symbol *alias;
850		struct Lisp_Buffer_Local_Value *blv;
851		lispfwd fwd;
852	      } val;
853
854	      /* Function value of the symbol or Qnil if not fboundp.  */
855	      Lisp_Object function;
856
857	      /* The symbol's property list.  */
858	      Lisp_Object plist;
859
860	      /* Next symbol in obarray bucket, if the symbol is interned.  */
861	      struct Lisp_Symbol *next;
862	    } s;
863	    GCALIGNED_UNION_MEMBER
864	  } u;
865	};
866	static_assert (GCALIGNED (struct Lisp_Symbol));
867
868	/* Declare a Lisp-callable function.  The MAXARGS parameter has the same
869	   meaning as in the DEFUN macro, and is used to construct a prototype.  */
870	/* We can use the same trick as in the DEFUN macro to generate the
871	   appropriate prototype.  */
872	#define EXFUN(fnname, maxargs) \
873	  extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs
874
875	/* Note that the weird token-substitution semantics of ANSI C makes
876	   this work for MANY and UNEVALLED.  */
877	#define DEFUN_ARGS_MANY		(ptrdiff_t, Lisp_Object *)
878	#define DEFUN_ARGS_UNEVALLED	(Lisp_Object)
879	#define DEFUN_ARGS_0	(void)
880	#define DEFUN_ARGS_1	(Lisp_Object)
881	#define DEFUN_ARGS_2	(Lisp_Object, Lisp_Object)
882	#define DEFUN_ARGS_3	(Lisp_Object, Lisp_Object, Lisp_Object)
883	#define DEFUN_ARGS_4	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
884	#define DEFUN_ARGS_5	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
885				 Lisp_Object)
886	#define DEFUN_ARGS_6	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
887				 Lisp_Object, Lisp_Object)
888	#define DEFUN_ARGS_7	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
889				 Lisp_Object, Lisp_Object, Lisp_Object)
890	#define DEFUN_ARGS_8	(Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
891				 Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
892
893	/* Lisp_Word_tag is big enough for a possibly-shifted tag, to be
894	   added to a pointer value for conversion to a Lisp_Word.  */
895	#if LISP_WORDS_ARE_POINTERS
896	typedef uintptr_t Lisp_Word_tag;
897	#else
898	typedef EMACS_UINT Lisp_Word_tag;
899	#endif
900
901	/* A integer value tagged with TAG, and otherwise all zero.  */
902	#define LISP_WORD_TAG(tag) \
903	  ((Lisp_Word_tag) (tag) << (USE_LSB_TAG ? 0 : VALBITS))
904
905	/* An initializer for a Lisp_Object that contains TAG along with P.
906	   P can be a pointer or an integer.  The result is usable in a static
907	   initializer if TAG and P are both integer constant expressions.  */
908	#define TAG_PTR_INITIALLY(tag, p) \
909	  LISP_INITIALLY ((Lisp_Word) ((uintptr_t) (p) + LISP_WORD_TAG (tag)))
910
911	/* LISPSYM_INITIALLY (Qfoo) is equivalent to Qfoo except it is
912	   designed for use as a (possibly static) initializer.  */
913	#define LISPSYM_INITIALLY(name) \
914	  TAG_PTR_INITIALLY (Lisp_Symbol, (intptr_t) ((i##name) * sizeof *lispsym))
915
916	/* Declare extern constants for Lisp symbols.  These can be helpful
917	   when using a debugger like GDB, on older platforms where the debug
918	   format does not represent C macros.  However, they are unbounded
919	   and would just be asking for trouble if checking pointer bounds.  */
920	#define DEFINE_LISP_SYMBOL(name) \
921	  DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) \
922	  DEFINE_GDB_SYMBOL_END (LISPSYM_INITIALLY (name))
923
924	/* The index of the C-defined Lisp symbol SYM.
925	   This can be used in a static initializer.  */
926	#define SYMBOL_INDEX(sym) i##sym
927
928	/* By default, define macros for Qt, etc., as this leads to a bit
929	   better performance in the core Emacs interpreter.  A plugin can
930	   define DEFINE_NON_NIL_Q_SYMBOL_MACROS to be false, to be portable to
931	   other Emacs instances that assign different values to Qt, etc.  */
932	#ifndef DEFINE_NON_NIL_Q_SYMBOL_MACROS
933	# define DEFINE_NON_NIL_Q_SYMBOL_MACROS true
934	#endif
935
936	/* True if N is a power of 2.  N should be positive.  */
937
938	#define POWER_OF_2(n) (((n) & ((n) - 1)) == 0)
939
940	/* Return X rounded to the next multiple of Y.  Y should be positive,
941	   and Y - 1 + X should not overflow.  Arguments should not have side
942	   effects, as they are evaluated more than once.  Tune for Y being a
943	   power of 2.  */
944
945	#define ROUNDUP(x, y) (POWER_OF_2 (y)					\
946	                       ? ((y) - 1 + (x)) & ~ ((y) - 1)			\
947	                       : ((y) - 1 + (x)) - ((y) - 1 + (x)) % (y))
948
949	#include <globals.h>
950
951	/* Header of vector-like objects.  This documents the layout constraints on
952	   vectors and pseudovectors (objects of PVEC_xxx subtype).  It also prevents
953	   compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR
954	   and PSEUDOVECTORP cast their pointers to struct vectorlike_header *,
955	   because when two such pointers potentially alias, a compiler won't
956	   incorrectly reorder loads and stores to their size fields.  See
957	   Bug#8546.   */
958	struct vectorlike_header
959	  {
960	    /* The `size' header word, W bits wide, has one of two forms
961	       discriminated by the second-highest bit (PSEUDOVECTOR_FLAG):
962
963	         1   1                    W-2
964	       +---+---+-------------------------------------+
965	       | M | 0 |                 SIZE                |  vector
966	       +---+---+-------------------------------------+
967
968	         1   1    W-32      6       12         12
969	       +---+---+--------+------+----------+----------+
970	       | M | 1 | unused | TYPE | RESTSIZE | LISPSIZE |  pseudovector
971	       +---+---+--------+------+----------+----------+
972
973	       M (ARRAY_MARK_FLAG) holds the GC mark bit.
974
975	       SIZE     is the length (number of slots) of a regular Lisp vector,
976	                and the object layout is struct Lisp_Vector.
977
978	       TYPE     is the pseudovector subtype (enum pvec_type).
979
980	       LISPSIZE is the number of Lisp_Object fields at the beginning of the
981	                object (after the header).  These are always traced by the GC.
982
983	       RESTSIZE is the number of fields (in word_size units) following.
984	                These are not automatically traced by the GC.
985	                For PVEC_BOOL and statically allocated PVEC_SUBR, RESTSIZE is 0.
986	                (The block size for PVEC_BOOL is computed from its own size
987	                field, to avoid being restricted by the 12-bit RESTSIZE field.)
988	    */
989	    GC_HEADER
990	    ptrdiff_t size;
991	  };
992
993	struct Lisp_Symbol_With_Pos
994	{
995	  struct vectorlike_header header;
996	  Lisp_Object sym;              /* A symbol */
997	  Lisp_Object pos;              /* A fixnum */
998	} GCALIGNED_STRUCT;
999
1000	/* In the size word of a vector, this bit means the vector has been marked.  */
1001
1002	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG)
1003	# define ARRAY_MARK_FLAG PTRDIFF_MIN
1004	DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG)
1005
1006	/* In the size word of a struct Lisp_Vector, this bit means it's really
1007	   some other vector-like object.  */
1008	DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG)
1009	# define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2)
1010	DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
1011
1012	/* In a pseudovector, the size field actually contains a word with one
1013	   PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
1014	   with PVEC_TYPE_MASK to indicate the actual type.  */
1015	enum pvec_type
1016	{
1017	  PVEC_NORMAL_VECTOR,	/* Should be first, for sxhash_obj.  */
1018	  PVEC_FREE,
1019	  PVEC_BIGNUM,
1020	  PVEC_MARKER,
1021	  PVEC_OVERLAY,
1022	  PVEC_FINALIZER,
1023	  PVEC_SYMBOL_WITH_POS,
1024	  PVEC_MISC_PTR,
1025	  PVEC_USER_PTR,
1026	  PVEC_PROCESS,
1027	  PVEC_FRAME,
1028	  PVEC_WINDOW,
1029	  PVEC_BOOL_VECTOR,
1030	  PVEC_BUFFER,
1031	  PVEC_HASH_TABLE,
1032	#ifdef HAVE_MPS
1033	  PVEC_WEAK_HASH_TABLE,
1034	#endif
1035	  PVEC_OBARRAY,
1036	  PVEC_TERMINAL,
1037	  PVEC_WINDOW_CONFIGURATION,
1038	  PVEC_SUBR,
1039	  PVEC_OTHER,            /* Should never be visible to Elisp code.  */
1040	  PVEC_XWIDGET,
1041	  PVEC_XWIDGET_VIEW,
1042	  PVEC_THREAD,
1043	  PVEC_MUTEX,
1044	  PVEC_CONDVAR,
1045	  PVEC_MODULE_FUNCTION,
1046	  PVEC_MODULE_GLOBAL_REFERENCE,
1047	  PVEC_NATIVE_COMP_UNIT,
1048	  PVEC_TS_PARSER,
1049	  PVEC_TS_NODE,
1050	  PVEC_TS_COMPILED_QUERY,
1051	  PVEC_SQLITE,
1052
1053	  /* These should be last, for internal_equal and sxhash_obj.  */
1054	  PVEC_CLOSURE,
1055	  PVEC_CHAR_TABLE,
1056	  PVEC_SUB_CHAR_TABLE,
1057	  PVEC_RECORD,
1058	  PVEC_FONT,
1059	  PVEC_TAG_MAX = PVEC_FONT  /* Keep this equal to the highest member.  */
1060	};
1061
1062	enum More_Lisp_Bits
1063	  {
1064	    /* For convenience, we also store the number of elements in these bits.
1065	       Note that this size is not necessarily the memory-footprint size, but
1066	       only the number of Lisp_Object fields (that need to be traced by GC).
1067	       The distinction is used, e.g., by Lisp_Process, which places extra
1068	       non-Lisp_Object fields at the end of the structure.  */
1069	    PSEUDOVECTOR_SIZE_BITS = 12,
1070	    PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1,
1071
1072	    /* To calculate the memory footprint of the pseudovector, it's useful
1073	       to store the size of non-Lisp area in word_size units here.  */
1074	    PSEUDOVECTOR_REST_BITS = 12,
1075	    PSEUDOVECTOR_REST_MASK = (((1 << PSEUDOVECTOR_REST_BITS) - 1)
1076				      << PSEUDOVECTOR_SIZE_BITS),
1077
1078	    /* Used to extract pseudovector subtype information.  */
1079	    PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS,
1080	    PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS
1081	  };
1082	^L
1083	/* These functions extract various sorts of values from a Lisp_Object.
1084	   For example, if tem is a Lisp_Object whose type is Lisp_Cons,
1085	   XCONS (tem) is the struct Lisp_Cons * pointing to the memory for
1086	   that cons.  */
1087
1088	/* Largest and smallest representable fixnum values.  These are the C
1089	   values.  They are macros for use in #if and static initializers.  */
1090	#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
1091	#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
1092	^L
1093	INLINE bool
1094	PSEUDOVECTORP (Lisp_Object a, int code)
1095	{
1096	  return (lisp_h_VECTORLIKEP (a)
1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577bce3 <+13459>:	and    $0x7,%esi
   0x000055555577bce6 <+13462>:	jne    0x555555779b3d <read_char+4845>

1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x000055555577bcec <+13468>:	movabs $0x400000003f000000,%rsi
   0x000055555577bcf6 <+13478>:	and    0x3(%rax),%rsi

1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577bcfa <+13482>:	movabs $0x4000000006000000,%r8
   0x000055555577bd04 <+13492>:	cmp    %r8,%rsi
   0x000055555577bd07 <+13495>:	jne    0x555555779b3d <read_char+4845>

1099		      == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS))));
1100	}
1101
1102	INLINE bool
1103	(BARE_SYMBOL_P) (Lisp_Object x)
1104	{
1105	  return lisp_h_BARE_SYMBOL_P (x);
1106	}
1107
1108	INLINE bool
1109	(SYMBOL_WITH_POS_P) (Lisp_Object x)
1110	{
1111	  return lisp_h_SYMBOL_WITH_POS_P (x);
1112	}
1113
1114	INLINE bool
1115	SYMBOLP (Lisp_Object x)
1116	{
1117	  return (BARE_SYMBOL_P (x)
1118		  || (symbols_with_pos_enabled && SYMBOL_WITH_POS_P (x)));
1119	}
1120
1121	INLINE struct Lisp_Symbol_With_Pos *
1122	XSYMBOL_WITH_POS (Lisp_Object a)
1123	{
1124	  eassert (SYMBOL_WITH_POS_P (a));
1125
1126	  struct Lisp_Symbol_With_Pos *s
1127	    = XUNTAG (a, Lisp_Vectorlike, struct Lisp_Symbol_With_Pos);
1128	  igc_check_fwd (s, false);
1129	  return s;
1130	}
1131
1132	INLINE Lisp_Object
1133	XSYMBOL_WITH_POS_SYM (Lisp_Object a)
1134	{
1135	  Lisp_Object sym = XSYMBOL_WITH_POS (a)->sym;
   0x000055555577bd0d <+13501>:	mov    0xb(%rax),%rax

1136	  eassume (BARE_SYMBOL_P (sym));
   0x000055555577bd11 <+13505>:	mov    %eax,%esi
   0x000055555577bd13 <+13507>:	and    $0x7,%esi
   0x000055555577bd16 <+13510>:	test   %cl,%cl
   0x000055555577bd18 <+13512>:	jne    0x555555779b3d <read_char+4845>
   0x000055555577bd1e <+13518>:	test   %esi,%esi
   0x000055555577bd20 <+13520>:	je     0x555555779b3d <read_char+4845>
   0x000055555577bd26 <+13526>:	jmp    0x5555555b285a <read_char-1859574>
   0x000055555577bd2b <+13531>:	nopl   0x0(%rax,%rax,1)
   0x000055555577bd30 <+13536>:	mov    %r8,-0x5d8(%rbp)

./src/keyboard.c:
4304		    frame = WINDOW_FRAME (XWINDOW (frame));
   0x000055555577bd37 <+13543>:	call   0x555555763130 <XWINDOW>
   0x000055555577bd3c <+13548>:	mov    -0x5d8(%rbp),%r8
   0x000055555577bd43 <+13555>:	mov    0x10(%rax),%rdi
   0x000055555577bd47 <+13559>:	jmp    0x55555577ac90 <read_char+9280>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577bd4c <+13564>:	mov    0x30(%r8),%rsi
   0x000055555577bd50 <+13568>:	lea    -0x4(%rsi),%edx
   0x000055555577bd53 <+13571>:	mov    %esi,%eax

./src/keyboard.c:
4389			  && STRINGP (event->ie.arg))
   0x000055555577bd55 <+13573>:	and    $0x7,%edx
   0x000055555577bd58 <+13576>:	je     0x55555577c23e <read_char+14830>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577bd5e <+13582>:	sub    $0x3,%eax

./src/keyboard.c:
4414			  && CONSP (event->ie.arg))
   0x000055555577bd61 <+13585>:	test   $0x7,%al
   0x000055555577bd63 <+13587>:	jne    0x55555577aaf0 <read_char+8864>

4415			{
4416			  eassert (FIXNUMP (XCAR (event->ie.arg)));
   0x000055555577bd69 <+13593>:	cmpb   $0x0,0x3a0610(%rip)        # 0x555555b1c380 <suppress_checking>
   0x000055555577bd70 <+13600>:	je     0x55555577c2be <read_char+14958>

4419				   < SCHARS (XCDR (event->ie.arg)));
4420
4421			  event->ie.code = XFIXNUM (Faref (XCDR (event->ie.arg),
   0x000055555577bd76 <+13606>:	mov    0x30(%r8),%r14
   0x000055555577bd7a <+13610>:	mov    %r8,-0x648(%rbp)
   0x000055555577bd81 <+13617>:	mov    %r14,%rdi
   0x000055555577bd84 <+13620>:	call   0x555555763090 <XCAR>
   0x000055555577bd89 <+13625>:	mov    %r14,%rdi
   0x000055555577bd8c <+13628>:	mov    %rax,%rbx
   0x000055555577bd8f <+13631>:	call   0x5555557630d0 <XCDR>
   0x000055555577bd94 <+13636>:	mov    %rbx,%rsi
   0x000055555577bd97 <+13639>:	mov    %rax,%rdi
   0x000055555577bd9a <+13642>:	call   0x5555558046f0 <Faref>

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x000055555577bd9f <+13647>:	cmpb   $0x0,0x3a05da(%rip)        # 0x555555b1c380 <suppress_checking>
   0x000055555577bda6 <+13654>:	mov    -0x648(%rbp),%r8
   0x000055555577bdad <+13661>:	jne    0x55555577c208 <read_char+14776>

740	  return lisp_h_XLI (o);
   0x000055555577bdb3 <+13667>:	lea    -0x2(%rax),%edx

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x000055555577bdb6 <+13670>:	and    $0x3,%edx
   0x000055555577bdb9 <+13673>:	jne    0x5555555b283a <read_char-1859606>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577bdbf <+13679>:	sar    $0x2,%rax

./src/keyboard.c:
4425				   make_fixnum (XFIXNUM (XCAR (event->ie.arg)) + 1));
   0x000055555577bdc3 <+13683>:	mov    0x30(%r8),%rbx
   0x000055555577bdc7 <+13687>:	mov    %r8,-0x650(%rbp)

4421			  event->ie.code = XFIXNUM (Faref (XCDR (event->ie.arg),
   0x000055555577bdce <+13694>:	mov    %eax,0x4(%r8)

4422							   XCAR (event->ie.arg)));
4423
4424			  XSETCAR (event->ie.arg,
   0x000055555577bdd2 <+13698>:	mov    %rbx,%rdi
   0x000055555577bdd5 <+13701>:	call   0x555555763090 <XCAR>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577bdda <+13706>:	mov    -0x650(%rbp),%r8

1239	}
1240
1241	INLINE Lisp_Object
1242	make_ufixnum (EMACS_INT n)
1243	{
1244	  eassert (0 <= n && n <= INTMASK);
1245	  return lisp_h_make_fixnum_wrap (n);
1246	}
1247
1248	#else /* ! USE_LSB_TAG */
1249
1250	/* Although compiled only if ! USE_LSB_TAG, the following functions
1251	   also work when USE_LSB_TAG; this is to aid future maintenance when
1252	   the lisp_h_* macros are eventually removed.  */
1253
1254	/* Make a fixnum representing the value of the low order bits of N.  */
1255	INLINE Lisp_Object
1256	make_fixnum (EMACS_INT n)
1257	{
1258	  eassert (! FIXNUM_OVERFLOW_P (n));
1259	  EMACS_INT int0 = Lisp_Int0;
1260	  if (USE_LSB_TAG)
1261	    {
1262	      EMACS_UINT u = n;
1263	      n = u << INTTYPEBITS;
1264	      n += int0;
1265	    }
1266	  else
1267	    {
1268	      n &= INTMASK;
1269	      n += (int0 << VALBITS);
1270	    }
1271	  return XIL (n);
1272	}
1273
1274	/* Extract A's value as a signed integer.  Unlike XFIXNUM, this works
1275	   on any Lisp object, although the resulting integer is useful only
1276	   for things like hashing when A is not a fixnum.  */
1277	INLINE EMACS_INT
1278	XFIXNUM_RAW (Lisp_Object a)
1279	{
1280	  EMACS_INT i = XLI (a);
1281	  if (! USE_LSB_TAG)
1282	    {
1283	      EMACS_UINT u = i;
1284	      i = u << INTTYPEBITS;
1285	    }
1286	  return i >> INTTYPEBITS;
1287	}
1288
1289	INLINE Lisp_Object
1290	make_ufixnum (EMACS_INT n)
1291	{
1292	  eassert (0 <= n && n <= INTMASK);
1293	  EMACS_INT int0 = Lisp_Int0;
1294	  if (USE_LSB_TAG)
1295	    {
1296	      EMACS_UINT u = n;
1297	      n = u << INTTYPEBITS;
1298	      n += int0;
1299	    }
1300	  else
1301	    n += int0 << VALBITS;
1302	  return XIL (n);
1303	}
1304
1305	#endif /* ! USE_LSB_TAG */
1306
1307	INLINE bool
1308	(FIXNUMP) (Lisp_Object x)
1309	{
1310	  return lisp_h_FIXNUMP (x);
   0x000055555577bde1 <+13713>:	lea    -0x2(%rax),%edx

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x000055555577bde4 <+13716>:	and    $0x3,%edx
   0x000055555577bde7 <+13719>:	jne    0x55555577d11d <read_char+18637>

740	  return lisp_h_XLI (o);
   0x000055555577bded <+13725>:	movabs $0x1fffffffffffffff,%rcx

1233	}
1234
1235	INLINE EMACS_INT
1236	(XFIXNUM_RAW) (Lisp_Object a)
1237	{
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577bdf7 <+13735>:	sar    $0x2,%rax

./src/keyboard.c:
4424			  XSETCAR (event->ie.arg,
   0x000055555577bdfb <+13739>:	lea    0x1(%rax),%rdx

./src/lisp.h:
1231	  eassert (!FIXNUM_OVERFLOW_P (n));
   0x000055555577bdff <+13743>:	cmp    %rcx,%rax
   0x000055555577be02 <+13746>:	je     0x5555555b28ee <read_char-1859426>

746	  return lisp_h_XIL (i);
   0x000055555577be08 <+13752>:	lea    -0x3(%rbx),%ecx

1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577be0b <+13755>:	lea    0x2(,%rdx,4),%rdx
   0x000055555577be13 <+13763>:	mov    %rbx,%rax

740	  return lisp_h_XLI (o);
   0x000055555577be16 <+13766>:	and    $0x7,%ecx
   0x000055555577be19 <+13769>:	jne    0x55555577d118 <read_char+18632>

1517	  igc_check_fwd (c, false);
1518	  return c;
   0x000055555577be1f <+13775>:	mov    %rdx,0x5(%rax)

1551	}
1552
1553	/* Use these to set the fields of a cons cell.
1554
1555	   Note that both arguments may refer to the same object, so 'n'
1556	   should not be read after 'c' is first modified.  */
1557	INLINE void
1558	XSETCAR (Lisp_Object c, Lisp_Object n)
1559	{
1560	  *xcar_addr (c) = n;
   0x000055555577be23 <+13779>:	jmp    0x55555577aaf0 <read_char+8864>

740	  return lisp_h_XLI (o);
   0x000055555577be28 <+13784>:	mov    0x30(%r8),%rdi
   0x000055555577be2c <+13788>:	lea    -0x3(%rdi),%eax

./src/keyboard.c:
4451			  || !CONSP (event->ie.arg)
   0x000055555577be2f <+13791>:	test   $0x7,%al
   0x000055555577be31 <+13793>:	jne    0x55555577ab14 <read_char+8900>
   0x000055555577be37 <+13799>:	mov    %r8,-0x660(%rbp)

4452			  || (XFIXNUM (XCAR (event->ie.arg))
   0x000055555577be3e <+13806>:	call   0x555555763090 <XCAR>

./src/lisp.h:
1316	  eassert (FIXNUMP (a));
   0x000055555577be43 <+13811>:	cmpb   $0x0,0x3a0536(%rip)        # 0x555555b1c380 <suppress_checking>
   0x000055555577be4a <+13818>:	mov    -0x660(%rbp),%r8
   0x000055555577be51 <+13825>:	jne    0x55555577be5f <read_char+13839>

740	  return lisp_h_XLI (o);
   0x000055555577be53 <+13827>:	lea    -0x2(%rax),%edx

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x000055555577be56 <+13830>:	and    $0x3,%edx
   0x000055555577be59 <+13833>:	jne    0x5555555b28c5 <read_char-1859467>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577be5f <+13839>:	mov    0x30(%r8),%rdi
   0x000055555577be63 <+13843>:	sar    $0x2,%rax

./src/keyboard.c:
4453			      >= SCHARS (XCDR (event->ie.arg))))
   0x000055555577be67 <+13847>:	mov    %r8,-0x668(%rbp)

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577be6e <+13854>:	mov    %rax,%rbx

./src/keyboard.c:
4453			      >= SCHARS (XCDR (event->ie.arg))))
   0x000055555577be71 <+13857>:	call   0x5555557630d0 <XCDR>
   0x000055555577be76 <+13862>:	mov    %rax,%rdi
   0x000055555577be79 <+13865>:	call   0x555555763300 <SCHARS>

4452			  || (XFIXNUM (XCAR (event->ie.arg))
   0x000055555577be7e <+13870>:	mov    -0x668(%rbp),%r8
   0x000055555577be85 <+13877>:	cmp    %rax,%rbx
   0x000055555577be88 <+13880>:	jge    0x55555577ab14 <read_char+8900>
   0x000055555577be8e <+13886>:	jmp    0x555555779a17 <read_char+4551>

./src/lisp.h:
3285	  return FIXNUM_OVERFLOW_P (n) ? make_bigint (n) : make_fixnum (n);
   0x000055555577be93 <+13891>:	call   0x555555795700 <make_bigint>
   0x000055555577be98 <+13896>:	mov    %rax,%rsi
   0x000055555577be9b <+13899>:	jmp    0x555555778983 <read_char+307>

3506	}
3507
3508	INLINE bool
3509	RANGED_FIXNUMP (intmax_t lo, Lisp_Object x, intmax_t hi)
3510	{
3511	  return FIXNUMP (x) && lo <= XFIXNUM (x) && XFIXNUM (x) <= hi;
3512	}
3513
3514	#define TYPE_RANGED_FIXNUMP(type, x) \
3515	  (FIXNUMP (x)			      \
3516	   && (TYPE_SIGNED (type) ? TYPE_MINIMUM (type) <= XFIXNUM (x) : 0 <= XFIXNUM (x)) \
3517	   && XFIXNUM (x) <= TYPE_MAXIMUM (type))
3518
3519	INLINE bool
3520	AUTOLOADP (Lisp_Object x)
3521	{
3522	  return CONSP (x) && EQ (Qautoload, XCAR (x));
3523	}
3524
3525
3526	/* Test for specific pseudovector types.  */
3527
3528	INLINE bool
3529	WINDOW_CONFIGURATIONP (Lisp_Object a)
3530	{
3531	  return PSEUDOVECTORP (a, PVEC_WINDOW_CONFIGURATION);
3532	}
3533
3534	INLINE bool
3535	CLOSUREP (Lisp_Object a)
3536	{
3537	  return PSEUDOVECTORP (a, PVEC_CLOSURE);
3538	}
3539
3540	INLINE bool
3541	FRAMEP (Lisp_Object a)
3542	{
3543	  return PSEUDOVECTORP (a, PVEC_FRAME);
3544	}
3545
3546	INLINE bool
3547	RECORDP (Lisp_Object a)
3548	{
3549	  return PSEUDOVECTORP (a, PVEC_RECORD);
3550	}
3551
3552	INLINE void
3553	CHECK_RECORD (Lisp_Object x)
3554	{
3555	  CHECK_TYPE (RECORDP (x), Qrecordp, x);
3556	}
3557
3558	/* Test for image (image . spec)  */
3559	INLINE bool
3560	IMAGEP (Lisp_Object x)
3561	{
3562	  return CONSP (x) && EQ (XCAR (x), Qimage);
3563	}
3564
3565	/* Array types.  */
3566	INLINE bool
3567	ARRAYP (Lisp_Object x)
3568	{
3569	  return VECTORP (x) || STRINGP (x) || CHAR_TABLE_P (x) || BOOL_VECTOR_P (x);
3570	}
3571	^L
3572	INLINE void
3573	CHECK_LIST (Lisp_Object x)
3574	{
3575	  CHECK_TYPE (CONSP (x) || NILP (x), Qlistp, x);
3576	}
3577
3578	INLINE void
3579	CHECK_LIST_END (Lisp_Object x, Lisp_Object y)
3580	{
3581	  CHECK_TYPE (NILP (x), Qlistp, y);
3582	}
3583
3584	INLINE void
3585	(CHECK_FIXNUM) (Lisp_Object x)
3586	{
3587	  lisp_h_CHECK_FIXNUM (x);
3588	}
3589
3590	INLINE void
3591	CHECK_STRING_CAR (Lisp_Object x)
3592	{
3593	  CHECK_TYPE (STRINGP (XCAR (x)), Qstringp, XCAR (x));
3594	}
3595	/* This is a bit special because we always need size afterwards.  */
3596	INLINE ptrdiff_t
3597	CHECK_VECTOR_OR_STRING (Lisp_Object x)
3598	{
3599	  if (VECTORP (x))
3600	    return ASIZE (x);
3601	  if (STRINGP (x))
3602	    return SCHARS (x);
3603	  wrong_type_argument (Qarrayp, x);
3604	}
3605	INLINE void
3606	CHECK_ARRAY (Lisp_Object x, Lisp_Object predicate)
3607	{
3608	  CHECK_TYPE (ARRAYP (x), predicate, x);
3609	}
3610	INLINE void
3611	CHECK_FIXNAT (Lisp_Object x)
3612	{
3613	  CHECK_TYPE (FIXNATP (x), Qwholenump, x);
3614	}
3615
3616	INLINE double
3617	XFLOATINT (Lisp_Object n)
3618	{
3619	  return (FIXNUMP (n) ? XFIXNUM (n)
3620		  : FLOATP (n) ? XFLOAT_DATA (n)
3621		  : bignum_to_double (n));
3622	}
3623
3624	INLINE void
3625	CHECK_NUMBER (Lisp_Object x)
3626	{
3627	  CHECK_TYPE (NUMBERP (x), Qnumberp, x);
3628	}
3629
3630	INLINE void
3631	CHECK_INTEGER (Lisp_Object x)
3632	{
3633	  CHECK_TYPE (INTEGERP (x), Qintegerp, x);
3634	}
3635
3636	INLINE void
3637	CHECK_SUBR (Lisp_Object x)
3638	{
3639	  CHECK_TYPE (SUBRP (x), Qsubrp, x);
3640	}
3641	^L
3642
3643	/* If we're not dumping using the legacy dumper and we might be using
3644	   the portable dumper, try to bunch all the subr structures together
3645	   for more efficient dump loading.  */
3646	#ifdef DARWIN_OS
3647	# define SUBR_SECTION_ATTRIBUTE ATTRIBUTE_SECTION ("__DATA,subrs")
3648	#else
3649	# define SUBR_SECTION_ATTRIBUTE ATTRIBUTE_SECTION (".subrs")
3650	#endif
3651
3652	/* Define a built-in function for calling from Lisp.
3653	 `lname' should be the name to give the function in Lisp,
3654	    as a null-terminated C string.
3655	 `fnname' should be the name of the function in C.
3656	    By convention, it starts with F.
3657	 `sname' should be the name for the C constant structure
3658	    that records information on this function for internal use.
3659	    By convention, it should be the same as `fnname' but with S instead of F.
3660	    It's too bad that C macros can't compute this from `fnname'.
3661	 `minargs' should be a number, the minimum number of arguments allowed.
3662	 `maxargs' should be a number, the maximum number of arguments allowed,
3663	    or else MANY or UNEVALLED.
3664	    MANY means there are &rest arguments.  Here we pass a vector
3665	        of evaluated arguments in the form of an integer
3666	        number-of-arguments followed by the address of a vector of
3667	        Lisp_Objects which contains the argument values.  (We also use
3668	        this convention when calling a subr with more than 8 parameters.)
3669	    UNEVALLED means pass the list of unevaluated arguments
3670	 `intspec' says how interactive arguments are to be fetched.
3671	    If the string starts with a `(', `intspec' is evaluated and the resulting
3672	    list is the list of arguments.
3673	    If it's a string that doesn't start with `(', the value should follow
3674	    the one of the doc string for `interactive'.
3675	    A null string means call interactively with no arguments.
3676	 `doc' is documentation for the user.  */
3677
3678	/* This version of DEFUN declares a function prototype with the right
3679	   arguments, so we can catch errors with maxargs at compile-time.  */
3680	#ifdef HAVE_MPS
3681	#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc)	\
3682	  SUBR_SECTION_ATTRIBUTE						\
3683	  static union Aligned_Lisp_Subr sname =				\
3684	    { {	{ GC_HEADER_INIT						\
3685		  (PSEUDOVECTOR_FLAG | PVEC_SUBR << PSEUDOVECTOR_AREA_BITS) },	\
3686	        { .a ## maxargs = fnname },					\
3687		minargs, maxargs, lname, {intspec}, lisp_h_Qnil}};		\
3688	   Lisp_Object fnname
3689	#else
3690	#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc)	\
3691	  SUBR_SECTION_ATTRIBUTE						\
3692	  static union Aligned_Lisp_Subr sname =				\
3693	    { {	{ GC_HEADER_INIT PVEC_SUBR << PSEUDOVECTOR_AREA_BITS },		\
3694	        { .a ## maxargs = fnname },					\
3695		minargs, maxargs, lname, {intspec}, lisp_h_Qnil}};		\
3696	   Lisp_Object fnname
3697	#endif
3698
3699	/* defsubr (Sname);
3700	   is how we define the symbol for function `name' at start-up time.  */
3701	extern void defsubr (union Aligned_Lisp_Subr *);
3702
3703	enum maxargs
3704	  {
3705	    MANY = -2,
3706	    UNEVALLED = -1
3707	  };
3708
3709	/* Call a function F that accepts many args, passing it ARRAY's elements.  */
3710	#define CALLMANY(f, array) (f) (ARRAYELTS (array), array)
3711
3712	/* Call a function F that accepts many args, passing it the remaining args,
3713	   E.g., 'return CALLN (Fformat, fmt, text);' is less error-prone than
3714	   '{ Lisp_Object a[2]; a[0] = fmt; a[1] = text; return Fformat (2, a); }'.
3715	   CALLN requires at least one function argument (as C99 prohibits
3716	   empty initializers), and is overkill for simple usages like
3717	   'Finsert (1, &text);'.  */
3718	#define CALLN(f, ...) CALLMANY (f, ((Lisp_Object []) {__VA_ARGS__}))
3719	#define calln(...) CALLN (Ffuncall, __VA_ARGS__)
3720
3721	/* Define 'call0' as a function rather than a CPP macro because we
3722	   sometimes want to pass it as a first class function.  */
3723	INLINE Lisp_Object
3724	call0 (Lisp_Object fn)
3725	{
3726	  return calln (fn);
   0x000055555577bea0 <+13904>:	lea    -0x400(%rbp),%rsi
   0x000055555577bea7 <+13911>:	mov    $0x1,%edi
   0x000055555577beac <+13916>:	movq   $0xd270,-0x400(%rbp)
   0x000055555577beb7 <+13927>:	call   0x555555820950 <Ffuncall>

./src/keyboard.c:
2833		  || !NILP (call0 (Qinternal_echo_keystrokes_prefix)))
   0x000055555577bebc <+13932>:	test   %rax,%rax
   0x000055555577bebf <+13935>:	jne    0x55555577a226 <read_char+6614>
   0x000055555577bec5 <+13941>:	jmp    0x555555778db4 <read_char+1380>

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577beca <+13946>:	mov    0x30(%rbx),%rsi
   0x000055555577bece <+13950>:	mov    $0xe,%edi
   0x000055555577bed3 <+13955>:	call   0x55555582c7d0 <Fnth>
   0x000055555577bed8 <+13960>:	mov    %rax,%rdi

3431	}
3432
3433	INLINE double
3434	XFLOAT_DATA (Lisp_Object f)
3435	{
3436	  return XFLOAT (f)->u.data;
   0x000055555577bedb <+13963>:	call   0x555555762b70 <XFLOAT>

./src/keyboard.c:
4364				     || XFLOAT_DATA (Fnth (make_fixnum (3),
   0x000055555577bee0 <+13968>:	pxor   %xmm0,%xmm0

./src/lisp.h:
3436	  return XFLOAT (f)->u.data;
   0x000055555577bee4 <+13972>:	movsd  0x10(%rax),%xmm1

./src/keyboard.c:
4364				     || XFLOAT_DATA (Fnth (make_fixnum (3),
   0x000055555577bee9 <+13977>:	ucomisd %xmm0,%xmm1
   0x000055555577beed <+13981>:	jp     0x55555577b826 <read_char+12246>
   0x000055555577bef3 <+13987>:	jne    0x55555577b826 <read_char+12246>

4382
4383			      maybe_event = next_kbd_event (event);
4384			    }
4385			}
4386
4387		      if (event->kind == MULTIBYTE_CHAR_KEYSTROKE_EVENT
   0x000055555577bef9 <+13993>:	mov    %r12,%r8
   0x000055555577befc <+13996>:	mov    -0x570(%rbp),%r15
   0x000055555577bf03 <+14003>:	mov    -0x568(%rbp),%r12
   0x000055555577bf0a <+14010>:	movzwl (%r8),%eax
   0x000055555577bf0e <+14014>:	jmp    0x55555577aae6 <read_char+8854>

2582		c = XCDR (c);
   0x000055555577bf13 <+14019>:	call   0x5555557630d0 <XCDR>
   0x000055555577bf18 <+14024>:	mov    %rax,%r14

./src/lisp.h:
774	  return lisp_h_TAGGEDP (a, tag);
   0x000055555577bf1b <+14027>:	lea    -0x3(%rax),%eax
   0x000055555577bf1e <+14030>:	and    $0x7,%eax
   0x000055555577bf21 <+14033>:	jmp    0x55555577b676 <read_char+11814>

./src/keyboard.c:
3043		c = XCDR (c);
   0x000055555577bf26 <+14038>:	call   0x5555557630d0 <XCDR>
   0x000055555577bf2b <+14043>:	mov    %rax,%r14
   0x000055555577bf2e <+14046>:	jmp    0x55555577a6fa <read_char+7850>

2743	  if (KEYMAPP (map) && INTERACTIVE
   0x000055555577bf33 <+14051>:	cmpb   $0x0,0x34a15c(%rip)        # 0x555555ac6096 <noninteractive>
   0x000055555577bf3a <+14058>:	jne    0x555555778d68 <read_char+1304>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577bf40 <+14064>:	mov    -0x4c0(%rbp),%rax

./src/keyboard.c:
2744	      && !NILP (prev_event) && ! EVENT_HAS_PARAMETERS (prev_event)
   0x000055555577bf47 <+14071>:	test   %rax,%rax
   0x000055555577bf4a <+14074>:	je     0x555555778d68 <read_char+1304>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577bf50 <+14080>:	sub    $0x3,%eax

./src/keyboard.c:
2744	      && !NILP (prev_event) && ! EVENT_HAS_PARAMETERS (prev_event)
   0x000055555577bf53 <+14083>:	test   $0x7,%al
   0x000055555577bf55 <+14085>:	je     0x555555778d68 <read_char+1304>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577bf5b <+14091>:	mov    0x3a5117(%rip),%eax        # 0x555555b21078 <globals+3128>
   0x000055555577bf61 <+14097>:	sub    $0x3,%eax

./src/keyboard.c:
2746	      && !CONSP (Vunread_command_events)
   0x000055555577bf64 <+14100>:	test   $0x7,%al
   0x000055555577bf66 <+14102>:	je     0x555555778d68 <read_char+1304>

2747	      && !detect_input_pending_run_timers (0))
   0x000055555577bf6c <+14108>:	xor    %edi,%edi
   0x000055555577bf6e <+14110>:	call   0x5555557786a0 <detect_input_pending_run_timers>
   0x000055555577bf73 <+14115>:	test   %al,%al
   0x000055555577bf75 <+14117>:	jne    0x555555778d68 <read_char+1304>

2748	    {
2749	      c = read_char_minibuf_menu_prompt (commandflag, map);
   0x000055555577bf7b <+14123>:	mov    -0x4b0(%rbp),%rsi
   0x000055555577bf82 <+14130>:	mov    -0x4dc(%rbp),%edi
   0x000055555577bf88 <+14136>:	call   0x555555781f20 <read_char_minibuf_menu_prompt>
   0x000055555577bf8d <+14141>:	mov    %rax,%r14

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577bf90 <+14144>:	lea    -0x2(%rax),%eax

./src/keyboard.c:
2751	      if (FIXNUMP (c) && XFIXNUM (c) == -2)
   0x000055555577bf93 <+14147>:	test   $0x3,%al
   0x000055555577bf95 <+14149>:	jne    0x55555577cb88 <read_char+17208>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577bf9b <+14155>:	mov    %r14,%rax
   0x000055555577bf9e <+14158>:	sar    $0x2,%rax

./src/keyboard.c:
2751	      if (FIXNUMP (c) && XFIXNUM (c) == -2)
   0x000055555577bfa2 <+14162>:	cmp    $0xfffffffffffffffe,%rax
   0x000055555577bfa6 <+14166>:	jne    0x555555778b30 <read_char+736>
   0x000055555577bfac <+14172>:	jmp    0x555555778b5c <read_char+780>
   0x000055555577bfb1 <+14177>:	nopl   0x0(%rax)

3001		    internal_last_event_frame = XCAR (XCDR (c));
   0x000055555577bfb8 <+14184>:	mov    %r14,%rdi
   0x000055555577bfbb <+14187>:	call   0x5555557630d0 <XCDR>
   0x000055555577bfc0 <+14192>:	mov    %rax,%rdi
   0x000055555577bfc3 <+14195>:	call   0x555555763090 <XCAR>
   0x000055555577bfc8 <+14200>:	mov    %rax,0x38a159(%rip)        # 0x555555b06128 <internal_last_event_frame>

3002		  Vlast_event_frame = internal_last_event_frame;
   0x000055555577bfcf <+14207>:	mov    %rax,0x3a4ac2(%rip)        # 0x555555b20a98 <globals+1624>

3003		}
3004	    }
3005
3006	  /* If current_kboard's side queue is empty check the other kboards.
3007	     If one of them has data that we have not yet seen here,
3008	     switch to it and process the data waiting for it.
3009
3010	     Note: if the events queued up for another kboard
3011	     have already been seen here, and therefore are not a complete command,
3012	     the kbd_queue_has_data field is 0, so we skip that kboard here.
3013	     That's to avoid an infinite loop switching between kboards here.  */
3014	  if (NILP (c) && !single_kboard)
   0x000055555577bfd6 <+14214>:	jmp    0x555555778e33 <read_char+1507>
   0x000055555577bfdb <+14219>:	mov    -0x508(%rbp),%r15
   0x000055555577bfe2 <+14226>:	jmp    0x55555577a71b <read_char+7883>

2912		last_non_minibuf_size = Z - BEG;
   0x000055555577bfe7 <+14231>:	mov    0x30b972(%rip),%rax        # 0x555555a87960 <current_thread>
   0x000055555577bfee <+14238>:	mov    0x98(%rax),%rax
   0x000055555577bff5 <+14245>:	mov    0x2f8(%rax),%rax
   0x000055555577bffc <+14252>:	mov    0x10(%rax),%rax
   0x000055555577c000 <+14256>:	sub    $0x1,%rax
   0x000055555577c004 <+14260>:	mov    %rax,0x38a5dd(%rip)        # 0x555555b065e8 <last_non_minibuf_size>
   0x000055555577c00b <+14267>:	jmp    0x5555557792e2 <read_char+2706>

2192	  else if (c >= 'a' && c <= 'z')
   0x000055555577c010 <+14272>:	lea    -0x61(%rcx),%esi
   0x000055555577c013 <+14275>:	cmp    $0x19,%esi
   0x000055555577c016 <+14278>:	ja     0x55555577c18e <read_char+14654>

2193	    c &= ~0140;
   0x000055555577c01c <+14284>:	mov    %ecx,%edx
   0x000055555577c01e <+14286>:	and    $0x1f,%edx
   0x000055555577c021 <+14289>:	jmp    0x55555577b9f7 <read_char+12711>

2175	    return c |= ctrl_modifier;
   0x000055555577c026 <+14294>:	or     $0x4000000,%r14d

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577c02d <+14301>:	movslq %r14d,%rdx

./src/keyboard.c:
2175	    return c |= ctrl_modifier;
   0x000055555577c030 <+14304>:	jmp    0x55555577b9f7 <read_char+12711>
   0x000055555577c035 <+14309>:	cmp    $0xf,%eax
   0x000055555577c038 <+14312>:	jne    0x55555577cae4 <read_char+17044>

2455			      src[i] &= ~0x80;
   0x000055555577c03e <+14318>:	movdqa 0x254f9a(%rip),%xmm0        # 0x5555559d0fe0
   0x000055555577c046 <+14326>:	pand   -0xa0(%rbp),%xmm0
   0x000055555577c04e <+14334>:	cmpq   $0x10,-0x4e8(%rbp)
   0x000055555577c056 <+14342>:	movaps %xmm0,-0xa0(%rbp)

2454			    for (i = 0; i < n; i++)
   0x000055555577c05d <+14349>:	je     0x55555577b365 <read_char+11029>

2455			      src[i] &= ~0x80;
   0x000055555577c063 <+14355>:	mov    $0x10,%ecx

2454			    for (i = 0; i < n; i++)
   0x000055555577c068 <+14360>:	mov    $0x10,%edx
   0x000055555577c06d <+14365>:	sub    %ecx,%eax
   0x000055555577c06f <+14367>:	lea    0x1(%rax),%esi
   0x000055555577c072 <+14370>:	cmp    $0x6,%eax
   0x000055555577c075 <+14373>:	jbe    0x55555577c0a5 <read_char+14421>

2455			      src[i] &= ~0x80;
   0x000055555577c077 <+14375>:	movq   0x254f61(%rip),%xmm1        # 0x5555559d0fe0
   0x000055555577c07f <+14383>:	mov    %ecx,%eax
   0x000055555577c081 <+14385>:	lea    -0xa0(%rbp,%rax,1),%rax
   0x000055555577c089 <+14393>:	movq   (%rax),%xmm0
   0x000055555577c08d <+14397>:	pand   %xmm1,%xmm0
   0x000055555577c091 <+14401>:	movq   %xmm0,(%rax)

2454			    for (i = 0; i < n; i++)
   0x000055555577c095 <+14405>:	mov    %esi,%eax
   0x000055555577c097 <+14407>:	and    $0xfffffff8,%eax
   0x000055555577c09a <+14410>:	add    %eax,%edx
   0x000055555577c09c <+14412>:	and    $0x7,%esi
   0x000055555577c09f <+14415>:	je     0x55555577b365 <read_char+11029>

2455			      src[i] &= ~0x80;
   0x000055555577c0a5 <+14421>:	movslq %edx,%rax

2454			    for (i = 0; i < n; i++)
   0x000055555577c0a8 <+14424>:	lea    0x1(%rdx),%esi

2455			      src[i] &= ~0x80;
   0x000055555577c0ab <+14427>:	andb   $0x7f,-0xa0(%rbp,%rax,1)

2454			    for (i = 0; i < n; i++)
   0x000055555577c0b3 <+14435>:	cmp    %edx,%r15d
   0x000055555577c0b6 <+14438>:	jle    0x55555577b365 <read_char+11029>

2455			      src[i] &= ~0x80;
   0x000055555577c0bc <+14444>:	movslq %esi,%rax
   0x000055555577c0bf <+14447>:	andb   $0x7f,-0xa0(%rbp,%rax,1)

2454			    for (i = 0; i < n; i++)
   0x000055555577c0c7 <+14455>:	lea    0x2(%rdx),%eax
   0x000055555577c0ca <+14458>:	cmp    %esi,%r15d
   0x000055555577c0cd <+14461>:	jle    0x55555577b365 <read_char+11029>

2455			      src[i] &= ~0x80;
   0x000055555577c0d3 <+14467>:	movslq %eax,%rsi
   0x000055555577c0d6 <+14470>:	andb   $0x7f,-0xa0(%rbp,%rsi,1)

2454			    for (i = 0; i < n; i++)
   0x000055555577c0de <+14478>:	lea    0x3(%rdx),%esi
   0x000055555577c0e1 <+14481>:	cmp    %eax,%r15d
   0x000055555577c0e4 <+14484>:	jle    0x55555577b365 <read_char+11029>

2455			      src[i] &= ~0x80;
   0x000055555577c0ea <+14490>:	movslq %esi,%rax
   0x000055555577c0ed <+14493>:	andb   $0x7f,-0xa0(%rbp,%rax,1)

2454			    for (i = 0; i < n; i++)
   0x000055555577c0f5 <+14501>:	lea    0x4(%rdx),%eax
   0x000055555577c0f8 <+14504>:	cmp    %esi,%r15d
   0x000055555577c0fb <+14507>:	jle    0x55555577b365 <read_char+11029>

2455			      src[i] &= ~0x80;
   0x000055555577c101 <+14513>:	movslq %eax,%rsi
   0x000055555577c104 <+14516>:	andb   $0x7f,-0xa0(%rbp,%rsi,1)

2454			    for (i = 0; i < n; i++)
   0x000055555577c10c <+14524>:	lea    0x5(%rdx),%esi
   0x000055555577c10f <+14527>:	cmp    %eax,%r15d
   0x000055555577c112 <+14530>:	jle    0x55555577b365 <read_char+11029>

2455			      src[i] &= ~0x80;
   0x000055555577c118 <+14536>:	movslq %esi,%rax
   0x000055555577c11b <+14539>:	andb   $0x7f,-0xa0(%rbp,%rax,1)

2454			    for (i = 0; i < n; i++)
   0x000055555577c123 <+14547>:	lea    0x6(%rdx),%eax
   0x000055555577c126 <+14550>:	cmp    %esi,%r15d
   0x000055555577c129 <+14553>:	jle    0x55555577b365 <read_char+11029>

2455			      src[i] &= ~0x80;
   0x000055555577c12f <+14559>:	cltq
   0x000055555577c131 <+14561>:	andb   $0x7f,-0xa0(%rbp,%rax,1)

2454			    for (i = 0; i < n; i++)
   0x000055555577c139 <+14569>:	jmp    0x55555577b365 <read_char+11029>

3087
3088	      if (CONSP (c) && !NILP (Fmemq (XCAR (c), Vwhile_no_input_ignore_events))
   0x000055555577c13e <+14574>:	mov    %r14,%rdi
   0x000055555577c141 <+14577>:	call   0x555555763090 <XCAR>
   0x000055555577c146 <+14582>:	mov    0x3a4f8b(%rip),%rsi        # 0x555555b210d8 <globals+3224>
   0x000055555577c14d <+14589>:	mov    %rax,%rdi
   0x000055555577c150 <+14592>:	call   0x55555582b900 <Fmemq>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577c155 <+14597>:	test   %rax,%rax
   0x000055555577c158 <+14600>:	je     0x555555778f8c <read_char+1852>

./src/keyboard.c:
3089		  && !end_time)
   0x000055555577c15e <+14606>:	cmpq   $0x0,-0x4a8(%rbp)
   0x000055555577c166 <+14614>:	jne    0x555555778f8c <read_char+1852>

./src/systime.h:
70	  return t.tv_nsec >= 0;
   0x000055555577c16c <+14620>:	cmpq   $0x0,0x38a444(%rip)        # 0x555555b065b8 <timer_idleness_start_time+8>
   0x000055555577c174 <+14628>:	jns    0x555555778f8c <read_char+1852>

./src/keyboard.c:
4662	  timer_idleness_start_time = timer_last_idleness_start_time;
   0x000055555577c17a <+14634>:	movdqa 0x38a41e(%rip),%xmm7        # 0x555555b065a0 <timer_last_idleness_start_time>
   0x000055555577c182 <+14642>:	movaps %xmm7,0x38a427(%rip)        # 0x555555b065b0 <timer_idleness_start_time>
   0x000055555577c189 <+14649>:	jmp    0x555555778f8c <read_char+1852>

2197	  else if (c >= ' ')
   0x000055555577c18e <+14654>:	mov    %ecx,%esi
   0x000055555577c190 <+14656>:	or     $0x4000000,%esi
   0x000055555577c196 <+14662>:	and    $0x60,%ecx

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577c199 <+14665>:	movslq %esi,%rsi
   0x000055555577c19c <+14668>:	cmovne %rsi,%rdx
   0x000055555577c1a0 <+14672>:	jmp    0x55555577b9f7 <read_char+12711>

./src/keyboard.c:
3199	      || (!(EQ (Qhelp_echo, XCAR (c)))
   0x000055555577c1a5 <+14677>:	mov    %r14,%rdi
   0x000055555577c1a8 <+14680>:	call   0x555555763090 <XCAR>
   0x000055555577c1ad <+14685>:	mov    $0xc208,%edi
   0x000055555577c1b2 <+14690>:	mov    %rax,%rsi

./src/lisp.h:
1184	  return a;
   0x000055555577c1b5 <+14693>:	call   0x555555764470 <EQ>

./src/keyboard.c:
3199	      || (!(EQ (Qhelp_echo, XCAR (c)))
   0x000055555577c1ba <+14698>:	test   %al,%al
   0x000055555577c1bc <+14700>:	jne    0x5555557789c0 <read_char+368>

3200		  && !(EQ (Qswitch_frame, XCAR (c)))
   0x000055555577c1c2 <+14706>:	mov    %r14,%rdi
   0x000055555577c1c5 <+14709>:	call   0x555555763090 <XCAR>
   0x000055555577c1ca <+14714>:	mov    $0x14858,%edi
   0x000055555577c1cf <+14719>:	mov    %rax,%rsi

./src/lisp.h:
1184	  return a;
   0x000055555577c1d2 <+14722>:	call   0x555555764470 <EQ>

./src/keyboard.c:
3200		  && !(EQ (Qswitch_frame, XCAR (c)))
   0x000055555577c1d7 <+14727>:	test   %al,%al
   0x000055555577c1d9 <+14729>:	jne    0x5555557789c0 <read_char+368>

3201		  /* Don't wipe echo area for select window events: These might
3202		     get delayed via `mouse-autoselect-window' (Bug#11304).  */
3203		  && !(EQ (Qselect_window, XCAR (c)))))
   0x000055555577c1df <+14735>:	mov    %r14,%rdi
   0x000055555577c1e2 <+14738>:	call   0x555555763090 <XCAR>
   0x000055555577c1e7 <+14743>:	mov    $0x13470,%edi
   0x000055555577c1ec <+14748>:	mov    %rax,%rsi

./src/lisp.h:
1184	  return a;
   0x000055555577c1ef <+14751>:	call   0x555555764470 <EQ>

./src/keyboard.c:
3203		  && !(EQ (Qselect_window, XCAR (c)))))
   0x000055555577c1f4 <+14756>:	test   %al,%al
   0x000055555577c1f6 <+14758>:	jne    0x5555557789c0 <read_char+368>
   0x000055555577c1fc <+14764>:	jmp    0x55555577b58d <read_char+11581>
   0x000055555577c201 <+14769>:	nopl   0x0(%rax)

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577c208 <+14776>:	sar    $0x2,%rax

./src/keyboard.c:
4425				   make_fixnum (XFIXNUM (XCAR (event->ie.arg)) + 1));
   0x000055555577c20c <+14780>:	mov    0x30(%r8),%rbx
   0x000055555577c210 <+14784>:	mov    %r8,-0x658(%rbp)

4421			  event->ie.code = XFIXNUM (Faref (XCDR (event->ie.arg),
   0x000055555577c217 <+14791>:	mov    %eax,0x4(%r8)

4422							   XCAR (event->ie.arg)));
4423
4424			  XSETCAR (event->ie.arg,
   0x000055555577c21b <+14795>:	mov    %rbx,%rdi
   0x000055555577c21e <+14798>:	call   0x555555763090 <XCAR>

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577c223 <+14803>:	mov    -0x658(%rbp),%r8

1233	}
1234
1235	INLINE EMACS_INT
1236	(XFIXNUM_RAW) (Lisp_Object a)
1237	{
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577c22a <+14810>:	sar    $0x2,%rax

1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577c22e <+14814>:	lea    0x6(,%rax,4),%rdx
   0x000055555577c236 <+14822>:	mov    %rbx,%rax

1384	}
1385
1386	#define XSETINT(a, b) ((a) = make_fixnum (b))
1387	#define XSETFASTINT(a, b) ((a) = make_fixed_natnum (b))
1388	#define XSETCONS(a, b) ((a) = make_lisp_ptr (b, Lisp_Cons))
1389	#define XSETVECTOR(a, b) ((a) = make_lisp_ptr (b, Lisp_Vectorlike))
1390	#define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String))
1391	#define XSETSYMBOL(a, b) ((a) = make_lisp_symbol (b))
1392	#define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float))
1393
1394	/* Return a Lisp_Object value that does not correspond to any object.
1395	   This can make some Lisp objects on free lists recognizable in O(1).  */
1396
1397	INLINE Lisp_Object
1398	dead_object (void)
1399	{
1400	  return make_lisp_ptr (NULL, Lisp_String);
1401	}
1402
1403	/* Pseudovector types.  */
1404
1405	#define XSETPVECTYPE(v, code)						\
1406	  ((v)->header.size |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS))
1407	#define PVECHEADERSIZE(code, lispsize, restsize) \
1408	  (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS) \
1409	   | ((restsize) << PSEUDOVECTOR_SIZE_BITS) | (lispsize))
1410	#define XSETPVECTYPESIZE(v, code, lispsize, restsize)		\
1411	  ((v)->header.size = PVECHEADERSIZE (code, lispsize, restsize))
1412
1413	/* The cast to struct vectorlike_header * avoids aliasing issues.  */
1414	#define XSETPSEUDOVECTOR(a, b, code) \
1415	  XSETTYPED_PSEUDOVECTOR (a, b,					\
1416				  (XUNTAG (a, Lisp_Vectorlike,		\
1417					   struct vectorlike_header)	\
1418				   ->size),				\
1419				  code)
1420	#define XSETTYPED_PSEUDOVECTOR(a, b, size, code)			\
1421	  (XSETVECTOR (a, b),							\
1422	   eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))		\
1423		    == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS))))
1424
1425	#define XSETWINDOW_CONFIGURATION(a, b) \
1426	  XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION)
1427	#define XSETPROCESS(a, b) XSETPSEUDOVECTOR (a, b, PVEC_PROCESS)
1428	#define XSETWINDOW(a, b) XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)
1429	#define XSETTERMINAL(a, b) XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)
1430	#define XSETSUBR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_SUBR)
1431	#define XSETBUFFER(a, b) XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)
1432	#define XSETCHAR_TABLE(a, b) XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)
1433	#define XSETBOOL_VECTOR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR)
1434	#define XSETSUB_CHAR_TABLE(a, b) XSETPSEUDOVECTOR (a, b, PVEC_SUB_CHAR_TABLE)
1435	#define XSETTHREAD(a, b) XSETPSEUDOVECTOR (a, b, PVEC_THREAD)
1436	#define XSETMUTEX(a, b) XSETPSEUDOVECTOR (a, b, PVEC_MUTEX)
1437	#define XSETCONDVAR(a, b) XSETPSEUDOVECTOR (a, b, PVEC_CONDVAR)
1438	#define XSETNATIVE_COMP_UNIT(a, b) XSETPSEUDOVECTOR (a, b, PVEC_NATIVE_COMP_UNIT)
1439
1440	/* Efficiently convert a pointer to a Lisp object and back.  The
1441	   pointer is represented as a fixnum, so the garbage collector
1442	   does not know about it.  The pointer should not have both Lisp_Int1
1443	   bits set, which makes this conversion inherently unportable.  */
1444
1445	INLINE void *
1446	XFIXNUMPTR (Lisp_Object a)
1447	{
1448	  return XUNTAG (a, Lisp_Int0, char);
1449	}
1450
1451	INLINE Lisp_Object
1452	make_pointer_integer_unsafe (void *p)
1453	{
1454	  Lisp_Object a = TAG_PTR_INITIALLY (Lisp_Int0, p);
1455	  return a;
1456	}
1457
1458	INLINE Lisp_Object
1459	make_pointer_integer (void *p)
1460	{
1461	  Lisp_Object a = make_pointer_integer_unsafe (p);
1462	  eassert (FIXNUMP (a) && XFIXNUMPTR (a) == p);
1463	  return a;
1464	}
1465
1466	/* See the macros in intervals.h.  */
1467
1468	typedef struct interval *INTERVAL;
1469
1470	struct Lisp_Cons
1471	{
1472	  GC_HEADER
1473	  union
1474	  {
1475	    struct
1476	    {
1477	      /* Car of this cons cell.  */
1478	      Lisp_Object car;
1479
1480	      union
1481	      {
1482		/* Cdr of this cons cell.  */
1483		Lisp_Object cdr;
1484
1485		/* Used to chain conses on a free list.  */
1486		struct Lisp_Cons *chain;
1487	      } u;
1488	    } s;
1489	    GCALIGNED_UNION_MEMBER
1490	  } u;
1491	};
1492	static_assert (GCALIGNED (struct Lisp_Cons));
1493
1494	INLINE bool
1495	(NILP) (Lisp_Object x)
1496	{
1497	  return lisp_h_NILP (x);
1498	}
1499
1500	INLINE bool
1501	(CONSP) (Lisp_Object x)
1502	{
1503	  return lisp_h_CONSP (x);
1504	}
1505
1506	INLINE void
1507	CHECK_CONS (Lisp_Object x)
1508	{
1509	  CHECK_TYPE (CONSP (x), Qconsp, x);
1510	}
1511
1512	INLINE struct Lisp_Cons *
1513	XCONS (Lisp_Object a)
1514	{
1515	  eassert (CONSP (a));
   0x000055555577c239 <+14825>:	jmp    0x55555577be1f <read_char+13775>

./src/keyboard.c:
4391			  str = internal_condition_case_1 (kbd_buffer_get_event_1,
   0x000055555577c23e <+14830>:	lea    -0x19875(%rip),%rcx        # 0x5555557629d0 <kbd_buffer_get_event_2>
   0x000055555577c245 <+14837>:	mov    $0x38,%edx
   0x000055555577c24a <+14842>:	lea    -0x179e1(%rip),%rdi        # 0x555555764870 <kbd_buffer_get_event_1>
   0x000055555577c251 <+14849>:	mov    %r8,-0x610(%rbp)

./src/lisp.h:
1184	  return a;
   0x000055555577c258 <+14856>:	call   0x55555581e9c0 <internal_condition_case_1>

./src/keyboard.c:
4397			  if (NILP (str))
   0x000055555577c25d <+14861>:	mov    -0x610(%rbp),%r8
   0x000055555577c264 <+14868>:	test   %rax,%rax

4391			  str = internal_condition_case_1 (kbd_buffer_get_event_1,
   0x000055555577c267 <+14871>:	mov    %rax,%rbx

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577c26a <+14874>:	je     0x55555577caa8 <read_char+16984>

./src/keyboard.c:
4400			  if (!SCHARS (str))
   0x000055555577c270 <+14880>:	mov    %rbx,%rdi
   0x000055555577c273 <+14883>:	mov    %r8,-0x618(%rbp)
   0x000055555577c27a <+14890>:	call   0x555555763300 <SCHARS>
   0x000055555577c27f <+14895>:	mov    -0x618(%rbp),%r8
   0x000055555577c286 <+14902>:	test   %rax,%rax
   0x000055555577c289 <+14905>:	jne    0x55555577ca76 <read_char+16934>

429	  return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1;
   0x000055555577c28f <+14911>:	lea    0x389e4a(%rip),%rdx        # 0x555555b060e0 <kbd_buffer+262080>
   0x000055555577c296 <+14918>:	lea    0x40(%r8),%rax
   0x000055555577c29a <+14922>:	cmp    %rdx,%r8
   0x000055555577c29d <+14925>:	lea    -0x3ffc0(%rdx),%r8

3399
3400	/* Record a key that came from a mouse menu.
3401	   Record it for echoing, for this-command-keys, and so on.  */
3402
3403	static void
3404	record_menu_key (Lisp_Object c)
3405	{
3406	  /* Wipe the echo area.  */
3407	  clear_message (1, 0);
3408
3409	  record_char (c);
3410
3411	  /* Once we reread a character, echoing can happen
3412	     the next time we pause to read a new one.  */
3413	  ok_to_echo_at_next_pause = NULL;
3414
3415	  /* Record this character as part of the current key.  */
3416	  add_command_key (c);
3417	  echo_update ();
3418
3419	  /* Re-reading in the middle of a command.  */
3420	  last_input_event = c;
3421	  num_input_events++;
3422	}
3423
3424	/* Return true if should recognize C as "the help character".  */
3425
3426	static bool
3427	help_char_p (Lisp_Object c)
3428	{
3429	  if (EQ (c, Vhelp_char))
3430	    return true;
3431	  Lisp_Object tail = Vhelp_event_list;
3432	  FOR_EACH_TAIL_SAFE (tail)
3433	    if (EQ (c, XCAR (tail)))
3434	      return true;
3435	  return false;
3436	}
3437
3438	/* Record the input event C in various ways.  */
3439
3440	static void
3441	record_char (Lisp_Object c)
3442	{
3443	  /* subr.el/read-passwd binds inhibit_record_char to avoid recording
3444	     passwords.  */
3445	  if (!record_all_keys && inhibit_record_char)
3446	    return;
3447
3448	  int recorded = 0;
3449
3450	  if (CONSP (c) && (EQ (XCAR (c), Qhelp_echo) || EQ (XCAR (c), Qmouse_movement)))
3451	    {
3452	      /* To avoid filling recent_keys with help-echo and mouse-movement
3453		 events, we filter out repeated help-echo events, only store the
3454		 first and last in a series of mouse-movement events, and don't
3455		 store repeated help-echo events which are only separated by
3456		 mouse-movement events.  */
3457
3458	      Lisp_Object ev1, ev2, ev3;
3459	      int ix1, ix2, ix3;
3460
3461	      if ((ix1 = recent_keys_index - 1) < 0)
3462		ix1 = lossage_limit - 1;
3463	      ev1 = AREF (recent_keys, ix1);
3464
3465	      if ((ix2 = ix1 - 1) < 0)
3466		ix2 = lossage_limit - 1;
3467	      ev2 = AREF (recent_keys, ix2);
3468
3469	      if ((ix3 = ix2 - 1) < 0)
3470		ix3 = lossage_limit - 1;
3471	      ev3 = AREF (recent_keys, ix3);
3472
3473	      if (EQ (XCAR (c), Qhelp_echo))
3474		{
3475		  /* Don't record `help-echo' in recent_keys unless it shows some help
3476		     message, and a different help than the previously recorded
3477		     event.  */
3478		  Lisp_Object help, last_help;
3479
3480		  help = Fcar_safe (Fcdr_safe (XCDR (c)));
3481		  if (!STRINGP (help))
3482		    recorded = 1;
3483		  else if (CONSP (ev1) && EQ (XCAR (ev1), Qhelp_echo)
3484			   && (last_help = Fcar_safe (Fcdr_safe (XCDR (ev1))), EQ (last_help, help)))
3485		    recorded = 1;
3486		  else if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
3487			   && CONSP (ev2) && EQ (XCAR (ev2), Qhelp_echo)
3488			   && (last_help = Fcar_safe (Fcdr_safe (XCDR (ev2))), EQ (last_help, help)))
3489		    recorded = -1;
3490		  else if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
3491			   && CONSP (ev2) && EQ (XCAR (ev2), Qmouse_movement)
3492			   && CONSP (ev3) && EQ (XCAR (ev3), Qhelp_echo)
3493			   && (last_help = Fcar_safe (Fcdr_safe (XCDR (ev3))), EQ (last_help, help)))
3494		    recorded = -2;
3495		}
3496	      else if (EQ (XCAR (c), Qmouse_movement))
3497		{
3498		  /* Only record one pair of `mouse-movement' on a window in recent_keys.
3499		     So additional mouse movement events replace the last element.  */
3500		  Lisp_Object last_window, window;
3501
3502		  window = Fcar_safe (Fcar_safe (XCDR (c)));
3503		  if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
3504		      && (last_window = Fcar_safe (Fcar_safe (XCDR (ev1))), EQ (last_window, window))
3505		      && CONSP (ev2) && EQ (XCAR (ev2), Qmouse_movement)
3506		      && (last_window = Fcar_safe (Fcar_safe (XCDR (ev2))), EQ (last_window, window)))
3507		    {
3508		      ASET (recent_keys, ix1, c);
3509		      recorded = 1;
3510		    }
3511		}
3512	    }
3513	  else if (NILP (Vexecuting_kbd_macro))
3514	    store_kbd_macro_char (c);
3515
3516	  /* recent_keys should not include events from keyboard macros.  */
3517	  if (NILP (Vexecuting_kbd_macro))
3518	    {
3519	      if (!recorded)
3520		{
3521		  total_keys += total_keys < lossage_limit;
3522		  ASET (recent_keys, recent_keys_index,
3523	                /* Copy the event, in case it gets modified by side-effect
3524	                   by some remapping function (bug#30955).  */
3525	                CONSP (c) ? Fcopy_sequence (c) : c);
3526		  if (++recent_keys_index >= lossage_limit)
3527		    recent_keys_index = 0;
3528		}
3529	      else if (recorded < 0)
3530		{
3531		  /* We need to remove one or two events from recent_keys.
3532		     To do this, we simply put nil at those events and move the
3533		     recent_keys_index backwards over those events.  Usually,
3534		     users will never see those nil events, as they will be
3535		     overwritten by the command keys entered to see recent_keys
3536		     (e.g. C-h l).  */
3537
3538		  while (recorded++ < 0 && total_keys > 0)
3539		    {
3540		      if (total_keys < lossage_limit)
3541			total_keys--;
3542		      if (--recent_keys_index < 0)
3543			recent_keys_index = lossage_limit - 1;
3544		      ASET (recent_keys, recent_keys_index, Qnil);
3545		    }
3546		}
3547
3548	      num_nonmacro_input_events++;
3549	    }
3550
3551	  /* Write c to the dribble file.  If c is a lispy event, write
3552	     the event's symbol to the dribble file, in <brackets>.  Bleaugh.
3553	     If you, dear reader, have a better idea, you've got the source.  :-) */
3554	  if (dribble && NILP (Vexecuting_kbd_macro))
3555	    {
3556	      block_input ();
3557	      if (FIXNUMP (c))
3558		{
3559		  if (XUFIXNUM (c) < 0x100)
3560		    putc (XUFIXNUM (c), dribble);
3561		  else
3562		    fprintf (dribble, " 0x%"pI"x", XUFIXNUM (c));
3563		}
3564	      else
3565		{
3566		  Lisp_Object dribblee;
3567
3568		  /* If it's a structured event, take the event header.  */
3569		  dribblee = EVENT_HEAD (c);
3570
3571		  if (SYMBOLP (dribblee))
3572		    {
3573		      putc ('<', dribble);
3574		      fwrite (SDATA (SYMBOL_NAME (dribblee)), sizeof (char),
3575			      SBYTES (SYMBOL_NAME (dribblee)), dribble);
3576		      putc ('>', dribble);
3577		    }
3578		}
3579
3580	      fflush (dribble);
3581	      unblock_input ();
3582	    }
3583	}
3584
3585	/* Copy out or in the info on where C-g should throw to.
3586	   This is used when running Lisp code from within get_char,
3587	   in case get_char is called recursively.
3588	   See read_process_output.  */
3589
3590	static void
3591	save_getcjmp (sys_jmp_buf temp)
3592	{
3593	  memcpy (temp, getcjmp, sizeof getcjmp);
3594	}
3595
3596	static void
3597	restore_getcjmp (void *temp)
3598	{
3599	  memcpy (getcjmp, temp, sizeof getcjmp);
3600	}
3601	^L
3602	/* Low level keyboard/mouse input.
3603	   kbd_buffer_store_event places events in kbd_buffer, and
3604	   kbd_buffer_get_event retrieves them.  */
3605
3606	/* Return true if there are any events in the queue that read-char
3607	   would return.  If this returns false, a read-char would block.  */
3608	static bool
3609	readable_events (int flags)
3610	{
3611	  if (flags & READABLE_EVENTS_DO_TIMERS_NOW)
3612	    timer_check ();
3613
3614	  /* READABLE_EVENTS_FILTER_EVENTS is meant to be used only by
3615	     input-pending-p and similar callers, which aren't interested in
3616	     some input events.  If this flag is set, and
3617	     input-pending-p-filter-events is non-nil, ignore events in
3618	     while-no-input-ignore-events.  If the flag is set and
3619	     input-pending-p-filter-events is nil, ignore only
3620	     FOCUS_IN/OUT_EVENT events.  */
3621	  if (kbd_fetch_ptr != kbd_store_ptr)
   0x000055555577c2a4 <+14932>:	mov    0x349e65(%rip),%rdx        # 0x555555ac6110 <kbd_store_ptr>

429	  return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1;
   0x000055555577c2ab <+14939>:	cmovne %rax,%r8

3399
3400	/* Record a key that came from a mouse menu.
3401	   Record it for echoing, for this-command-keys, and so on.  */
3402
3403	static void
3404	record_menu_key (Lisp_Object c)
3405	{
3406	  /* Wipe the echo area.  */
3407	  clear_message (1, 0);
3408
3409	  record_char (c);
3410
3411	  /* Once we reread a character, echoing can happen
3412	     the next time we pause to read a new one.  */
3413	  ok_to_echo_at_next_pause = NULL;
3414
3415	  /* Record this character as part of the current key.  */
3416	  add_command_key (c);
3417	  echo_update ();
3418
3419	  /* Re-reading in the middle of a command.  */
3420	  last_input_event = c;
3421	  num_input_events++;
3422	}
3423
3424	/* Return true if should recognize C as "the help character".  */
3425
3426	static bool
3427	help_char_p (Lisp_Object c)
3428	{
3429	  if (EQ (c, Vhelp_char))
3430	    return true;
3431	  Lisp_Object tail = Vhelp_event_list;
3432	  FOR_EACH_TAIL_SAFE (tail)
3433	    if (EQ (c, XCAR (tail)))
3434	      return true;
3435	  return false;
3436	}
3437
3438	/* Record the input event C in various ways.  */
3439
3440	static void
3441	record_char (Lisp_Object c)
3442	{
3443	  /* subr.el/read-passwd binds inhibit_record_char to avoid recording
3444	     passwords.  */
3445	  if (!record_all_keys && inhibit_record_char)
3446	    return;
3447
3448	  int recorded = 0;
3449
3450	  if (CONSP (c) && (EQ (XCAR (c), Qhelp_echo) || EQ (XCAR (c), Qmouse_movement)))
3451	    {
3452	      /* To avoid filling recent_keys with help-echo and mouse-movement
3453		 events, we filter out repeated help-echo events, only store the
3454		 first and last in a series of mouse-movement events, and don't
3455		 store repeated help-echo events which are only separated by
3456		 mouse-movement events.  */
3457
3458	      Lisp_Object ev1, ev2, ev3;
3459	      int ix1, ix2, ix3;
3460
3461	      if ((ix1 = recent_keys_index - 1) < 0)
3462		ix1 = lossage_limit - 1;
3463	      ev1 = AREF (recent_keys, ix1);
3464
3465	      if ((ix2 = ix1 - 1) < 0)
3466		ix2 = lossage_limit - 1;
3467	      ev2 = AREF (recent_keys, ix2);
3468
3469	      if ((ix3 = ix2 - 1) < 0)
3470		ix3 = lossage_limit - 1;
3471	      ev3 = AREF (recent_keys, ix3);
3472
3473	      if (EQ (XCAR (c), Qhelp_echo))
3474		{
3475		  /* Don't record `help-echo' in recent_keys unless it shows some help
3476		     message, and a different help than the previously recorded
3477		     event.  */
3478		  Lisp_Object help, last_help;
3479
3480		  help = Fcar_safe (Fcdr_safe (XCDR (c)));
3481		  if (!STRINGP (help))
3482		    recorded = 1;
3483		  else if (CONSP (ev1) && EQ (XCAR (ev1), Qhelp_echo)
3484			   && (last_help = Fcar_safe (Fcdr_safe (XCDR (ev1))), EQ (last_help, help)))
3485		    recorded = 1;
3486		  else if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
3487			   && CONSP (ev2) && EQ (XCAR (ev2), Qhelp_echo)
3488			   && (last_help = Fcar_safe (Fcdr_safe (XCDR (ev2))), EQ (last_help, help)))
3489		    recorded = -1;
3490		  else if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
3491			   && CONSP (ev2) && EQ (XCAR (ev2), Qmouse_movement)
3492			   && CONSP (ev3) && EQ (XCAR (ev3), Qhelp_echo)
3493			   && (last_help = Fcar_safe (Fcdr_safe (XCDR (ev3))), EQ (last_help, help)))
3494		    recorded = -2;
3495		}
3496	      else if (EQ (XCAR (c), Qmouse_movement))
3497		{
3498		  /* Only record one pair of `mouse-movement' on a window in recent_keys.
3499		     So additional mouse movement events replace the last element.  */
3500		  Lisp_Object last_window, window;
3501
3502		  window = Fcar_safe (Fcar_safe (XCDR (c)));
3503		  if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
3504		      && (last_window = Fcar_safe (Fcar_safe (XCDR (ev1))), EQ (last_window, window))
3505		      && CONSP (ev2) && EQ (XCAR (ev2), Qmouse_movement)
3506		      && (last_window = Fcar_safe (Fcar_safe (XCDR (ev2))), EQ (last_window, window)))
3507		    {
3508		      ASET (recent_keys, ix1, c);
3509		      recorded = 1;
3510		    }
3511		}
3512	    }
3513	  else if (NILP (Vexecuting_kbd_macro))
3514	    store_kbd_macro_char (c);
3515
3516	  /* recent_keys should not include events from keyboard macros.  */
3517	  if (NILP (Vexecuting_kbd_macro))
3518	    {
3519	      if (!recorded)
3520		{
3521		  total_keys += total_keys < lossage_limit;
3522		  ASET (recent_keys, recent_keys_index,
3523	                /* Copy the event, in case it gets modified by side-effect
3524	                   by some remapping function (bug#30955).  */
3525	                CONSP (c) ? Fcopy_sequence (c) : c);
3526		  if (++recent_keys_index >= lossage_limit)
3527		    recent_keys_index = 0;
3528		}
3529	      else if (recorded < 0)
3530		{
3531		  /* We need to remove one or two events from recent_keys.
3532		     To do this, we simply put nil at those events and move the
3533		     recent_keys_index backwards over those events.  Usually,
3534		     users will never see those nil events, as they will be
3535		     overwritten by the command keys entered to see recent_keys
3536		     (e.g. C-h l).  */
3537
3538		  while (recorded++ < 0 && total_keys > 0)
3539		    {
3540		      if (total_keys < lossage_limit)
3541			total_keys--;
3542		      if (--recent_keys_index < 0)
3543			recent_keys_index = lossage_limit - 1;
3544		      ASET (recent_keys, recent_keys_index, Qnil);
3545		    }
3546		}
3547
3548	      num_nonmacro_input_events++;
3549	    }
3550
3551	  /* Write c to the dribble file.  If c is a lispy event, write
3552	     the event's symbol to the dribble file, in <brackets>.  Bleaugh.
3553	     If you, dear reader, have a better idea, you've got the source.  :-) */
3554	  if (dribble && NILP (Vexecuting_kbd_macro))
3555	    {
3556	      block_input ();
3557	      if (FIXNUMP (c))
3558		{
3559		  if (XUFIXNUM (c) < 0x100)
3560		    putc (XUFIXNUM (c), dribble);
3561		  else
3562		    fprintf (dribble, " 0x%"pI"x", XUFIXNUM (c));
3563		}
3564	      else
3565		{
3566		  Lisp_Object dribblee;
3567
3568		  /* If it's a structured event, take the event header.  */
3569		  dribblee = EVENT_HEAD (c);
3570
3571		  if (SYMBOLP (dribblee))
3572		    {
3573		      putc ('<', dribble);
3574		      fwrite (SDATA (SYMBOL_NAME (dribblee)), sizeof (char),
3575			      SBYTES (SYMBOL_NAME (dribblee)), dribble);
3576		      putc ('>', dribble);
3577		    }
3578		}
3579
3580	      fflush (dribble);
3581	      unblock_input ();
3582	    }
3583	}
3584
3585	/* Copy out or in the info on where C-g should throw to.
3586	   This is used when running Lisp code from within get_char,
3587	   in case get_char is called recursively.
3588	   See read_process_output.  */
3589
3590	static void
3591	save_getcjmp (sys_jmp_buf temp)
3592	{
3593	  memcpy (temp, getcjmp, sizeof getcjmp);
3594	}
3595
3596	static void
3597	restore_getcjmp (void *temp)
3598	{
3599	  memcpy (getcjmp, temp, sizeof getcjmp);
3600	}
3601	^L
3602	/* Low level keyboard/mouse input.
3603	   kbd_buffer_store_event places events in kbd_buffer, and
3604	   kbd_buffer_get_event retrieves them.  */
3605
3606	/* Return true if there are any events in the queue that read-char
3607	   would return.  If this returns false, a read-char would block.  */
3608	static bool
3609	readable_events (int flags)
3610	{
3611	  if (flags & READABLE_EVENTS_DO_TIMERS_NOW)
3612	    timer_check ();
3613
3614	  /* READABLE_EVENTS_FILTER_EVENTS is meant to be used only by
3615	     input-pending-p and similar callers, which aren't interested in
3616	     some input events.  If this flag is set, and
3617	     input-pending-p-filter-events is non-nil, ignore events in
3618	     while-no-input-ignore-events.  If the flag is set and
3619	     input-pending-p-filter-events is nil, ignore only
3620	     FOCUS_IN/OUT_EVENT events.  */
3621	  if (kbd_fetch_ptr != kbd_store_ptr)
   0x000055555577c2af <+14943>:	xor    %r14d,%r14d

4401			    {
4402			      kbd_fetch_ptr = next_kbd_event (event);
   0x000055555577c2b2 <+14946>:	mov    %r8,0x349e5f(%rip)        # 0x555555ac6118 <kbd_fetch_ptr>

4403			      obj = Qnil;
4404			      break;
   0x000055555577c2b9 <+14953>:	jmp    0x555555779a25 <read_char+4565>

4415			{
4416			  eassert (FIXNUMP (XCAR (event->ie.arg)));
   0x000055555577c2be <+14958>:	mov    0x30(%r8),%rbx
   0x000055555577c2c2 <+14962>:	mov    %r8,-0x628(%rbp)
   0x000055555577c2c9 <+14969>:	mov    %rbx,%rdi
   0x000055555577c2cc <+14972>:	call   0x555555763090 <XCAR>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577c2d1 <+14977>:	sub    $0x2,%eax

./src/keyboard.c:
4416			  eassert (FIXNUMP (XCAR (event->ie.arg)));
   0x000055555577c2d4 <+14980>:	test   $0x3,%al
   0x000055555577c2d6 <+14982>:	jne    0x5555555b297f <read_char-1859281>
   0x000055555577c2dc <+14988>:	mov    -0x628(%rbp),%r8

4417			  eassert (STRINGP (XCDR (event->ie.arg)));
   0x000055555577c2e3 <+14995>:	mov    %rbx,%rdi
   0x000055555577c2e6 <+14998>:	mov    %r8,-0x630(%rbp)
   0x000055555577c2ed <+15005>:	call   0x5555557630d0 <XCDR>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577c2f2 <+15010>:	sub    $0x4,%eax

./src/keyboard.c:
4417			  eassert (STRINGP (XCDR (event->ie.arg)));
   0x000055555577c2f5 <+15013>:	test   $0x7,%al
   0x000055555577c2f7 <+15015>:	jne    0x5555555b2967 <read_char-1859305>
   0x000055555577c2fd <+15021>:	mov    -0x630(%rbp),%r8

4418			  eassert (XFIXNUM (XCAR (event->ie.arg))
   0x000055555577c304 <+15028>:	mov    %rbx,%rdi
   0x000055555577c307 <+15031>:	mov    %r8,-0x638(%rbp)
   0x000055555577c30e <+15038>:	call   0x555555763090 <XCAR>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577c313 <+15043>:	lea    -0x2(%rax),%edx

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x000055555577c316 <+15046>:	and    $0x3,%edx
   0x000055555577c319 <+15049>:	jne    0x5555555b2962 <read_char-1859310>
   0x000055555577c31f <+15055>:	mov    -0x638(%rbp),%r8

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577c326 <+15062>:	sar    $0x2,%rax

./src/keyboard.c:
4418			  eassert (XFIXNUM (XCAR (event->ie.arg))
   0x000055555577c32a <+15066>:	mov    %rbx,%rdi

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577c32d <+15069>:	mov    %rax,%r14
   0x000055555577c330 <+15072>:	mov    %r8,-0x640(%rbp)
   0x000055555577c337 <+15079>:	call   0x5555557630d0 <XCDR>
   0x000055555577c33c <+15084>:	mov    %rax,%rdi
   0x000055555577c33f <+15087>:	call   0x555555763300 <SCHARS>
   0x000055555577c344 <+15092>:	cmp    %rax,%r14
   0x000055555577c347 <+15095>:	jge    0x5555555b294a <read_char-1859334>
   0x000055555577c34d <+15101>:	mov    -0x640(%rbp),%r8
   0x000055555577c354 <+15108>:	jmp    0x55555577bd76 <read_char+13606>

./src/keyboard.c:
3220	      else if (FUNCTIONP (Vclear_message_function))
   0x000055555577c359 <+15113>:	mov    0x3a4210(%rip),%rdi        # 0x555555b20570 <globals+304>
   0x000055555577c360 <+15120>:	call   0x55555581f590 <FUNCTIONP>
   0x000055555577c365 <+15125>:	test   %al,%al
   0x000055555577c367 <+15127>:	je     0x5555557789c0 <read_char+368>

3221	        clear_message (1, 0);
   0x000055555577c36d <+15133>:	xor    %esi,%esi
   0x000055555577c36f <+15135>:	mov    $0x1,%edi
   0x000055555577c374 <+15140>:	call   0x55555561dd60 <clear_message>
   0x000055555577c379 <+15145>:	jmp    0x5555557789c0 <read_char+368>

2915	      while (buffer_size > 64)
   0x000055555577c37e <+15150>:	mov    $0x4,%r12d
   0x000055555577c384 <+15156>:	jmp    0x555555779318 <read_char+2760>

4506		obj = make_lispy_movement (f, bar_window, part, x, y, t);
   0x000055555577c389 <+15161>:	mov    -0x468(%rbp),%rbx
   0x000055555577c390 <+15168>:	mov    -0x448(%rbp),%rcx
   0x000055555577c397 <+15175>:	mov    -0x484(%rbp),%esi
   0x000055555577c39d <+15181>:	mov    -0x460(%rbp),%r9
   0x000055555577c3a4 <+15188>:	mov    -0x458(%rbp),%rax
   0x000055555577c3ab <+15195>:	mov    -0x450(%rbp),%rdx

4663	}
4664
4665	/* List of elisp functions to call, delayed because they were generated in
4666	   a context where Elisp could not be safely run (e.g. redisplay, signal,
4667	   ...).  Each element has the form (FUN . ARGS).  */
4668	Lisp_Object pending_funcalls;
4669
4670	/* Return the value of TIMER if it is a valid timer, an invalid struct
4671	   timespec otherwise.  */
4672	static struct timespec
4673	decode_timer (Lisp_Object timer)
4674	{
4675	  Lisp_Object *vec;
4676
4677	  if (! (VECTORP (timer) && ASIZE (timer) == 10))
4678	    return invalid_timespec ();
4679	  vec = XVECTOR (timer)->contents;
4680	  if (! NILP (vec[0]))
4681	    return invalid_timespec ();
4682	  if (! FIXNUMP (vec[2]))
4683	    return invalid_timespec ();
4684	  return list4_to_timespec (vec[1], vec[2], vec[3], vec[8]);
4685	}
4686
4687
4688	/* Check whether a timer has fired.  To prevent larger problems we simply
4689	   disregard elements that are not proper timers.  Do not make a circular
4690	   timer list for the time being.
4691
4692	   Returns the time to wait until the next timer fires.  If a
4693	   timer is triggering now, return zero.
4694	   If no timer is active, return -1.
4695
4696	   If a timer is ripe, we run it, with quitting turned off.
4697	   In that case we return 0 to indicate that a new timer_check_2 call
4698	   should be done.  */
4699
4700	static struct timespec
4701	timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers)
4702	{
4703	  /* First run the code that was delayed.  */
4704	  while (CONSP (pending_funcalls))
4705	    {
4706	      Lisp_Object funcall = XCAR (pending_funcalls);
4707	      pending_funcalls = XCDR (pending_funcalls);
4708	      safe_calln (Qapply, XCAR (funcall), XCDR (funcall));
4709	    }
4710
4711	  if (! (CONSP (timers) || CONSP (idle_timers)))
4712	    return invalid_timespec ();
4713
4714	#ifdef HAVE_MPS
4715	  igc_on_idle ();
4716	#endif
4717
4718	  struct timespec
4719	    now = current_timespec (),
4720	    idleness_now = (timespec_valid_p (timer_idleness_start_time)
4721			    ? timespec_sub (now, timer_idleness_start_time)
4722			    : make_timespec (0, 0));
4723
4724	  do
4725	    {
4726	      Lisp_Object chosen_timer, timer = Qnil, idle_timer = Qnil;
4727	      struct timespec difference;
4728	      struct timespec timer_difference = invalid_timespec ();
4729	      struct timespec idle_timer_difference = invalid_timespec ();
4730	      bool ripe, timer_ripe = 0, idle_timer_ripe = 0;
4731
4732	      /* Set TIMER and TIMER_DIFFERENCE
4733		 based on the next ordinary timer.
4734		 TIMER_DIFFERENCE is the distance in time from NOW to when
4735		 this timer becomes ripe.
4736	         Skip past invalid timers and timers already handled.  */
4737	      if (CONSP (timers))
4738		{
4739		  timer = XCAR (timers);
4740		  struct timespec timer_time = decode_timer (timer);
4741		  if (! timespec_valid_p (timer_time))
4742		    {
4743		      timers = XCDR (timers);
4744		      continue;
4745		    }
4746
4747		  timer_ripe = timespec_cmp (timer_time, now) <= 0;
4748		  timer_difference = (timer_ripe
4749				      ? timespec_sub (now, timer_time)
4750				      : timespec_sub (timer_time, now));
4751		}
4752
4753	      /* Likewise for IDLE_TIMER and IDLE_TIMER_DIFFERENCE
4754		 based on the next idle timer.  */
4755	      if (CONSP (idle_timers))
4756		{
4757		  idle_timer = XCAR (idle_timers);
4758		  struct timespec idle_timer_time = decode_timer (idle_timer);
4759		  if (! timespec_valid_p (idle_timer_time))
4760		    {
4761		      idle_timers = XCDR (idle_timers);
4762		      continue;
4763		    }
4764
4765		  idle_timer_ripe = timespec_cmp (idle_timer_time, idleness_now) <= 0;
4766		  idle_timer_difference
4767		    = (idle_timer_ripe
4768		       ? timespec_sub (idleness_now, idle_timer_time)
4769		       : timespec_sub (idle_timer_time, idleness_now));
4770		}
4771
4772	      /* Decide which timer is the next timer,
4773		 and set CHOSEN_TIMER, DIFFERENCE, and RIPE accordingly.
4774		 Also step down the list where we found that timer.  */
4775
4776	      if (timespec_valid_p (timer_difference)
4777		  && (! timespec_valid_p (idle_timer_difference)
4778		      || idle_timer_ripe < timer_ripe
4779		      || (idle_timer_ripe == timer_ripe
4780			  && ((timer_ripe
4781			       ? timespec_cmp (idle_timer_difference,
4782					       timer_difference)
4783			       : timespec_cmp (timer_difference,
4784					       idle_timer_difference))
4785			      < 0))))
4786		{
4787		  chosen_timer = timer;
4788		  timers = XCDR (timers);
4789		  difference = timer_difference;
4790		  ripe = timer_ripe;
4791		}
4792	      else
4793		{
4794		  chosen_timer = idle_timer;
4795		  idle_timers = XCDR (idle_timers);
4796		  difference = idle_timer_difference;
4797		  ripe = idle_timer_ripe;
4798		}
4799
4800	      /* If timer is ripe, run it if it hasn't been run.  */
4801	      if (ripe)
4802		{
4803		  /* If we got here, presumably `decode_timer` has checked
4804	             that this timer has not yet been triggered.  */
4805		  eassert (NILP (AREF (chosen_timer, 0)));
4806		  /* In a production build, where assertions compile to
4807		     nothing, we still want to play it safe here.  */
4808		  if (NILP (AREF (chosen_timer, 0)))
4809		    {
4810		      specpdl_ref count = SPECPDL_INDEX ();
4811		      Lisp_Object old_deactivate_mark = Vdeactivate_mark;
4812
4813		      /* Mark the timer as triggered to prevent problems if the lisp
4814			 code fails to reschedule it right.  */
4815		      ASET (chosen_timer, 0, Qt);
4816
4817		      specbind (Qinhibit_quit, Qt);
4818
4819		      calln (Qtimer_event_handler, chosen_timer);
4820		      Vdeactivate_mark = old_deactivate_mark;
4821		      timers_run++;
4822		      unbind_to (count, Qnil);
4823
4824		      /* Since we have handled the event,
4825			 we don't need to tell the caller to wake up and do it.  */
4826		      /* But the caller must still wait for the next timer, so
4827			 return 0 to indicate that.  */
4828		    }
4829
4830		  return make_timespec (0, 0);
4831		}
4832	      else
4833		/* When we encounter a timer that is still waiting,
4834		   return the amount of time to wait before it is ripe.  */
4835		{
4836		  return difference;
4837		}
4838	    }
4839	  while (CONSP (timers) || CONSP (idle_timers));
4840
4841	  /* No timers are pending in the future.  */
4842	  return invalid_timespec ();
4843	}
4844
4845
4846	/* Check whether a timer has fired.  To prevent larger problems we simply
4847	   disregard elements that are not proper timers.  Do not make a circular
4848	   timer list for the time being.
4849
4850	   Returns the time to wait until the next timer fires.
4851	   If no timer is active, return an invalid value.
4852
4853	   As long as any timer is ripe, we run it.  */
4854
4855	struct timespec
4856	timer_check (void)
4857	{
4858	  struct timespec nexttime;
4859	  Lisp_Object timers, idle_timers;
4860
4861	  Lisp_Object tem = Vinhibit_quit;
4862	  Vinhibit_quit = Qt;
4863	  block_input ();
4864	  turn_on_atimers (false);
4865
4866	  /* We use copies of the timers' lists to allow a timer to add itself
4867	     again, without locking up Emacs if the newly added timer is
4868	     already ripe when added.  */
4869
4870	  /* Always consider the ordinary timers.  */
4871	  timers = Fcopy_sequence (Vtimer_list);
4872	  /* Consider the idle timers only if Emacs is idle.  */
4873	  if (timespec_valid_p (timer_idleness_start_time))
4874	    idle_timers = Fcopy_sequence (Vtimer_idle_list);
4875	  else
4876	    idle_timers = Qnil;
4877
4878	  turn_on_atimers (true);
4879	  unblock_input ();
4880	  Vinhibit_quit = tem;
4881
4882	  do
4883	    {
4884	      nexttime = timer_check_2 (timers, idle_timers);
4885	    }
4886	  while (nexttime.tv_sec == 0 && nexttime.tv_nsec == 0);
4887
4888	  return nexttime;
4889	}
4890
4891	DEFUN ("current-idle-time", Fcurrent_idle_time, Scurrent_idle_time, 0, 0, 0,
4892	       doc: /* Return the current length of Emacs idleness, or nil.
4893	The value when Emacs is idle is a Lisp timestamp in the style of
4894	`current-time'.
4895
4896	The value when Emacs is not idle is nil.
4897
4898	If the value is a list of four integers (HIGH LOW USEC PSEC), then PSEC
4899	is a multiple of the system clock resolution.  */)
4900	  (void)
4901	{
4902	  if (timespec_valid_p (timer_idleness_start_time))
4903	    return make_lisp_time (timespec_sub (current_timespec (),
4904						 timer_idleness_start_time));
4905
4906	  return Qnil;
4907	}
4908	^L
4909	/* Caches for modify_event_symbol.  */
4910	static Lisp_Object accent_key_syms;
4911	static Lisp_Object func_key_syms;
4912	static Lisp_Object mouse_syms;
4913	static Lisp_Object wheel_syms;
4914	static Lisp_Object drag_n_drop_syms;
4915	static Lisp_Object pinch_syms;
4916
4917	/* This is a list of keysym codes for special "accent" characters.
4918	   It parallels lispy_accent_keys.  */
4919
4920	static const int lispy_accent_codes[] =
4921	{
4922	#ifdef XK_dead_circumflex
4923	  XK_dead_circumflex,
4924	#else
4925	  0,
4926	#endif
4927	#ifdef XK_dead_grave
4928	  XK_dead_grave,
4929	#else
4930	  0,
4931	#endif
4932	#ifdef XK_dead_tilde
4933	  XK_dead_tilde,
4934	#else
4935	  0,
4936	#endif
4937	#ifdef XK_dead_diaeresis
4938	  XK_dead_diaeresis,
4939	#else
4940	  0,
4941	#endif
4942	#ifdef XK_dead_macron
4943	  XK_dead_macron,
4944	#else
4945	  0,
4946	#endif
4947	#ifdef XK_dead_degree
4948	  XK_dead_degree,
4949	#else
4950	  0,
4951	#endif
4952	#ifdef XK_dead_acute
4953	  XK_dead_acute,
4954	#else
4955	  0,
4956	#endif
4957	#ifdef XK_dead_cedilla
4958	  XK_dead_cedilla,
4959	#else
4960	  0,
4961	#endif
4962	#ifdef XK_dead_breve
4963	  XK_dead_breve,
4964	#else
4965	  0,
4966	#endif
4967	#ifdef XK_dead_ogonek
4968	  XK_dead_ogonek,
4969	#else
4970	  0,
4971	#endif
4972	#ifdef XK_dead_caron
4973	  XK_dead_caron,
4974	#else
4975	  0,
4976	#endif
4977	#ifdef XK_dead_doubleacute
4978	  XK_dead_doubleacute,
4979	#else
4980	  0,
4981	#endif
4982	#ifdef XK_dead_abovedot
4983	  XK_dead_abovedot,
4984	#else
4985	  0,
4986	#endif
4987	#ifdef XK_dead_abovering
4988	  XK_dead_abovering,
4989	#else
4990	  0,
4991	#endif
4992	#ifdef XK_dead_iota
4993	  XK_dead_iota,
4994	#else
4995	  0,
4996	#endif
4997	#ifdef XK_dead_belowdot
4998	  XK_dead_belowdot,
4999	#else
5000	  0,
5001	#endif
5002	#ifdef XK_dead_voiced_sound
5003	  XK_dead_voiced_sound,
5004	#else
5005	  0,
5006	#endif
5007	#ifdef XK_dead_semivoiced_sound
5008	  XK_dead_semivoiced_sound,
5009	#else
5010	  0,
5011	#endif
5012	#ifdef XK_dead_hook
5013	  XK_dead_hook,
5014	#else
5015	  0,
5016	#endif
5017	#ifdef XK_dead_horn
5018	  XK_dead_horn,
5019	#else
5020	  0,
5021	#endif
5022	};
5023
5024	/* This is a list of Lisp names for special "accent" characters.
5025	   It parallels lispy_accent_codes.  */
5026
5027	static const char *const lispy_accent_keys[] =
5028	{
5029	  "dead-circumflex",
5030	  "dead-grave",
5031	  "dead-tilde",
5032	  "dead-diaeresis",
5033	  "dead-macron",
5034	  "dead-degree",
5035	  "dead-acute",
5036	  "dead-cedilla",
5037	  "dead-breve",
5038	  "dead-ogonek",
5039	  "dead-caron",
5040	  "dead-doubleacute",
5041	  "dead-abovedot",
5042	  "dead-abovering",
5043	  "dead-iota",
5044	  "dead-belowdot",
5045	  "dead-voiced-sound",
5046	  "dead-semivoiced-sound",
5047	  "dead-hook",
5048	  "dead-horn",
5049	};
5050
5051	#ifdef HAVE_ANDROID
5052	#define FUNCTION_KEY_OFFSET 0
5053
5054	/* Mind that Android designates 23 KEYCODE_DPAD_CENTER, but it is
5055	   merely abstruse terminology for the ``select'' key frequently
5056	   located in certain physical keyboards.  */
5057
5058	static const char *const lispy_function_keys[] =
5059	  {
5060	    /* All elements in this array default to 0, except for the few
5061	       function keys that Emacs recognizes.  */
5062	    [111] = "escape",
5063	    [112] = "delete",
5064	    [116] = "scroll",
5065	    [120] = "sysrq",
5066	    [121] = "break",
5067	    [122] = "home",
5068	    [123] = "end",
5069	    [124] = "insert",
5070	    [126] = "media-play",
5071	    [127] = "media-pause",
5072	    [130] = "media-record",
5073	    [131] = "f1",
5074	    [132] = "f2",
5075	    [133] = "f3",
5076	    [134] = "f4",
5077	    [135] = "f5",
5078	    [136] = "f6",
5079	    [137] = "f7",
5080	    [138] = "f8",
5081	    [139] = "f9",
5082	    [140] = "f10",
5083	    [141] = "f11",
5084	    [142] = "f12",
5085	    [143] = "kp-numlock",
5086	    [160] = "kp-ret",
5087	    [164] = "volume-mute",
5088	    [165] = "info",
5089	    [19]  = "up",
5090	    [20]  = "down",
5091	    [211] = "zenkaku-hankaku",
5092	    [213] = "muhenkan",
5093	    [214] = "henkan",
5094	    [215] = "hiragana-katakana",
5095	    [218] = "kana",
5096	    [21]  = "left",
5097	    [223] = "sleep",
5098	    [22]  = "right",
5099	    [23]  = "select",
5100	    [24]  = "volume-up",
5101	    [259] = "help",
5102	    [25]  = "volume-down",
5103	    [268] = "kp-up-left",
5104	    [269] = "kp-down-left",
5105	    [26]  = "power",
5106	    [270] = "kp-up-right",
5107	    [271] = "kp-down-right",
5108	    [272] = "media-skip-forward",
5109	    [273] = "media-skip-backward",
5110	    [277] = "cut",
5111	    [278] = "copy",
5112	    [279] = "paste",
5113	    [285] = "browser-refresh",
5114	    [28]  = "clear",
5115	    [300] = "XF86Forward",
5116	    [4]	  = "XF86Back",
5117	    [61]  = "tab",
5118	    [66]  = "return",
5119	    [67]  = "backspace",
5120	    [82]  = "menu",
5121	    [84]  = "find",
5122	    [85]  = "media-play-pause",
5123	    [86]  = "media-stop",
5124	    [87]  = "media-next",
5125	    [88]  = "media-previous",
5126	    [89]  = "media-rewind",
5127	    [92]  = "prior",
5128	    [93]  = "next",
5129	    [95]  = "mode-change",
5130	  };
5131
5132	#elif defined HAVE_NTGUI
5133	#define FUNCTION_KEY_OFFSET 0x0
5134
5135	const char *const lispy_function_keys[] =
5136	  {
5137	    0,                /* 0                      */
5138
5139	    0,                /* VK_LBUTTON        0x01 */
5140	    0,                /* VK_RBUTTON        0x02 */
5141	    "cancel",         /* VK_CANCEL         0x03 */
5142	    0,                /* VK_MBUTTON        0x04 */
5143
5144	    0, 0, 0,          /*    0x05 .. 0x07        */
5145
5146	    "backspace",      /* VK_BACK           0x08 */
5147	    "tab",            /* VK_TAB            0x09 */
5148
5149	    0, 0,             /*    0x0A .. 0x0B        */
5150
5151	    "clear",          /* VK_CLEAR          0x0C */
5152	    "return",         /* VK_RETURN         0x0D */
5153
5154	    0, 0,             /*    0x0E .. 0x0F        */
5155
5156	    0,                /* VK_SHIFT          0x10 */
5157	    0,                /* VK_CONTROL        0x11 */
5158	    0,                /* VK_MENU           0x12 */
5159	    "pause",          /* VK_PAUSE          0x13 */
5160	    "capslock",       /* VK_CAPITAL        0x14 */
5161	    "kana",           /* VK_KANA/VK_HANGUL 0x15 */
5162	    0,                /*    0x16                */
5163	    "junja",          /* VK_JUNJA          0x17 */
5164	    "final",          /* VK_FINAL          0x18 */
5165	    "kanji",          /* VK_KANJI/VK_HANJA 0x19 */
5166	    0,                /*    0x1A                */
5167	    "escape",         /* VK_ESCAPE         0x1B */
5168	    "convert",        /* VK_CONVERT        0x1C */
5169	    "non-convert",    /* VK_NONCONVERT     0x1D */
5170	    "accept",         /* VK_ACCEPT         0x1E */
5171	    "mode-change",    /* VK_MODECHANGE     0x1F */
5172	    0,                /* VK_SPACE          0x20 */
5173	    "prior",          /* VK_PRIOR          0x21 */
5174	    "next",           /* VK_NEXT           0x22 */
5175	    "end",            /* VK_END            0x23 */
5176	    "home",           /* VK_HOME           0x24 */
5177	    "left",           /* VK_LEFT           0x25 */
5178	    "up",             /* VK_UP             0x26 */
5179	    "right",          /* VK_RIGHT          0x27 */
5180	    "down",           /* VK_DOWN           0x28 */
5181	    "select",         /* VK_SELECT         0x29 */
5182	    "print",          /* VK_PRINT          0x2A */
5183	    "execute",        /* VK_EXECUTE        0x2B */
5184	    "snapshot",       /* VK_SNAPSHOT       0x2C */
5185	    "insert",         /* VK_INSERT         0x2D */
5186	    "delete",         /* VK_DELETE         0x2E */
5187	    "help",           /* VK_HELP           0x2F */
5188
5189	    /* VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) */
5190
5191	    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5192
5193	    0, 0, 0, 0, 0, 0, 0, /* 0x3A .. 0x40       */
5194
5195	    /* VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */
5196
5197	    0, 0, 0, 0, 0, 0, 0, 0, 0,
5198	    0, 0, 0, 0, 0, 0, 0, 0, 0,
5199	    0, 0, 0, 0, 0, 0, 0, 0,
5200
5201	    "lwindow",       /* VK_LWIN           0x5B */
5202	    "rwindow",       /* VK_RWIN           0x5C */
5203	    "apps",          /* VK_APPS           0x5D */
5204	    0,               /*    0x5E                */
5205	    "sleep",
5206	    "kp-0",          /* VK_NUMPAD0        0x60 */
5207	    "kp-1",          /* VK_NUMPAD1        0x61 */
5208	    "kp-2",          /* VK_NUMPAD2        0x62 */
5209	    "kp-3",          /* VK_NUMPAD3        0x63 */
5210	    "kp-4",          /* VK_NUMPAD4        0x64 */
5211	    "kp-5",          /* VK_NUMPAD5        0x65 */
5212	    "kp-6",          /* VK_NUMPAD6        0x66 */
5213	    "kp-7",          /* VK_NUMPAD7        0x67 */
5214	    "kp-8",          /* VK_NUMPAD8        0x68 */
5215	    "kp-9",          /* VK_NUMPAD9        0x69 */
5216	    "kp-multiply",   /* VK_MULTIPLY       0x6A */
5217	    "kp-add",        /* VK_ADD            0x6B */
5218	    "kp-separator",  /* VK_SEPARATOR      0x6C */
5219	    "kp-subtract",   /* VK_SUBTRACT       0x6D */
5220	    "kp-decimal",    /* VK_DECIMAL        0x6E */
5221	    "kp-divide",     /* VK_DIVIDE         0x6F */
5222	    "f1",            /* VK_F1             0x70 */
5223	    "f2",            /* VK_F2             0x71 */
5224	    "f3",            /* VK_F3             0x72 */
5225	    "f4",            /* VK_F4             0x73 */
5226	    "f5",            /* VK_F5             0x74 */
5227	    "f6",            /* VK_F6             0x75 */
5228	    "f7",            /* VK_F7             0x76 */
5229	    "f8",            /* VK_F8             0x77 */
5230	    "f9",            /* VK_F9             0x78 */
5231	    "f10",           /* VK_F10            0x79 */
5232	    "f11",           /* VK_F11            0x7A */
5233	    "f12",           /* VK_F12            0x7B */
5234	    "f13",           /* VK_F13            0x7C */
5235	    "f14",           /* VK_F14            0x7D */
5236	    "f15",           /* VK_F15            0x7E */
5237	    "f16",           /* VK_F16            0x7F */
5238	    "f17",           /* VK_F17            0x80 */
5239	    "f18",           /* VK_F18            0x81 */
5240	    "f19",           /* VK_F19            0x82 */
5241	    "f20",           /* VK_F20            0x83 */
5242	    "f21",           /* VK_F21            0x84 */
5243	    "f22",           /* VK_F22            0x85 */
5244	    "f23",           /* VK_F23            0x86 */
5245	    "f24",           /* VK_F24            0x87 */
5246
5247	    0, 0, 0, 0,      /*    0x88 .. 0x8B        */
5248	    0, 0, 0, 0,      /*    0x8C .. 0x8F        */
5249
5250	    "kp-numlock",    /* VK_NUMLOCK        0x90 */
5251	    "scroll",        /* VK_SCROLL         0x91 */
5252	    /* Not sure where the following block comes from.
5253	       Windows headers have NEC and Fujitsu specific keys in
5254	       this block, but nothing generic.  */
5255	    "kp-space",	     /* VK_NUMPAD_CLEAR   0x92 */
5256	    "kp-enter",	     /* VK_NUMPAD_ENTER   0x93 */
5257	    "kp-prior",	     /* VK_NUMPAD_PRIOR   0x94 */
5258	    "kp-next",	     /* VK_NUMPAD_NEXT    0x95 */
5259	    "kp-end",	     /* VK_NUMPAD_END     0x96 */
5260	    "kp-home",	     /* VK_NUMPAD_HOME    0x97 */
5261	    "kp-left",	     /* VK_NUMPAD_LEFT    0x98 */
5262	    "kp-up",	     /* VK_NUMPAD_UP      0x99 */
5263	    "kp-right",	     /* VK_NUMPAD_RIGHT   0x9A */
5264	    "kp-down",	     /* VK_NUMPAD_DOWN    0x9B */
5265	    "kp-insert",     /* VK_NUMPAD_INSERT  0x9C */
5266	    "kp-delete",     /* VK_NUMPAD_DELETE  0x9D */
5267
5268	    0, 0,	     /*    0x9E .. 0x9F        */
5269
5270	    /*
5271	     * VK_L* & VK_R* - left and right Alt, Ctrl and Shift virtual keys.
5272	     * Used only as parameters to GetAsyncKeyState and GetKeyState.
5273	     * No other API or message will distinguish left and right keys this way.
5274	     * 0xA0 .. 0xA5
5275	     */
5276	    0, 0, 0, 0, 0, 0,
5277
5278	    /* Multimedia keys. These are handled as WM_APPCOMMAND, which allows us
5279	       to enable them selectively, and gives access to a few more functions.
5280	       See lispy_multimedia_keys below.  */
5281	    0, 0, 0, 0, 0, 0, 0, /* 0xA6 .. 0xAC        Browser */
5282	    0, 0, 0,             /* 0xAD .. 0xAF         Volume */
5283	    0, 0, 0, 0,          /* 0xB0 .. 0xB3          Media */
5284	    0, 0, 0, 0,          /* 0xB4 .. 0xB7           Apps */
5285
5286	    /* 0xB8 .. 0xC0 "OEM" keys - all seem to be punctuation.  */
5287	    0, 0, 0, 0, 0, 0, 0, 0, 0,
5288
5289	    /* 0xC1 - 0xDA unallocated, 0xDB-0xDF more OEM keys */
5290	    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5291	    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5292
5293	    0,               /* 0xE0                   */
5294	    "ax",            /* VK_OEM_AX         0xE1 */
5295	    0,               /* VK_OEM_102        0xE2 */
5296	    "ico-help",      /* VK_ICO_HELP       0xE3 */
5297	    "ico-00",        /* VK_ICO_00         0xE4 */
5298	    0,               /* VK_PROCESSKEY     0xE5 - used by IME */
5299	    "ico-clear",     /* VK_ICO_CLEAR      0xE6 */
5300	    0,               /* VK_PACKET         0xE7  - used to pass Unicode chars */
5301	    0,               /*                   0xE8 */
5302	    "reset",         /* VK_OEM_RESET      0xE9 */
5303	    "jump",          /* VK_OEM_JUMP       0xEA */
5304	    "oem-pa1",       /* VK_OEM_PA1        0xEB */
5305	    "oem-pa2",       /* VK_OEM_PA2        0xEC */
5306	    "oem-pa3",       /* VK_OEM_PA3        0xED */
5307	    "wsctrl",        /* VK_OEM_WSCTRL     0xEE */
5308	    "cusel",         /* VK_OEM_CUSEL      0xEF */
5309	    "oem-attn",      /* VK_OEM_ATTN       0xF0 */
5310	    "finish",        /* VK_OEM_FINISH     0xF1 */
5311	    "copy",          /* VK_OEM_COPY       0xF2 */
5312	    "auto",          /* VK_OEM_AUTO       0xF3 */
5313	    "enlw",          /* VK_OEM_ENLW       0xF4 */
5314	    "backtab",       /* VK_OEM_BACKTAB    0xF5 */
5315	    "attn",          /* VK_ATTN           0xF6 */
5316	    "crsel",         /* VK_CRSEL          0xF7 */
5317	    "exsel",         /* VK_EXSEL          0xF8 */
5318	    "ereof",         /* VK_EREOF          0xF9 */
5319	    "play",          /* VK_PLAY           0xFA */
5320	    "zoom",          /* VK_ZOOM           0xFB */
5321	    "noname",        /* VK_NONAME         0xFC */
5322	    "pa1",           /* VK_PA1            0xFD */
5323	    "oem_clear",     /* VK_OEM_CLEAR      0xFE */
5324	    0 /* 0xFF */
5325	  };
5326
5327	/* Some of these duplicate the "Media keys" on newer keyboards,
5328	   but they are delivered to the application in a different way.  */
5329	static const char *const lispy_multimedia_keys[] =
5330	  {
5331	    0,
5332	    "browser-back",
5333	    "browser-forward",
5334	    "browser-refresh",
5335	    "browser-stop",
5336	    "browser-search",
5337	    "browser-favorites",
5338	    "browser-home",
5339	    "volume-mute",
5340	    "volume-down",
5341	    "volume-up",
5342	    "media-next",
5343	    "media-previous",
5344	    "media-stop",
5345	    "media-play-pause",
5346	    "mail",
5347	    "media-select",
5348	    "app-1",
5349	    "app-2",
5350	    "bass-down",
5351	    "bass-boost",
5352	    "bass-up",
5353	    "treble-down",
5354	    "treble-up",
5355	    "mic-volume-mute",
5356	    "mic-volume-down",
5357	    "mic-volume-up",
5358	    "help",
5359	    "find",
5360	    "new",
5361	    "open",
5362	    "close",
5363	    "save",
5364	    "print",
5365	    "undo",
5366	    "redo",
5367	    "copy",
5368	    "cut",
5369	    "paste",
5370	    "mail-reply",
5371	    "mail-forward",
5372	    "mail-send",
5373	    "spell-check",
5374	    "toggle-dictate-command",
5375	    "mic-toggle",
5376	    "correction-list",
5377	    "media-play",
5378	    "media-pause",
5379	    "media-record",
5380	    "media-fast-forward",
5381	    "media-rewind",
5382	    "media-channel-up",
5383	    "media-channel-down"
5384	  };
5385
5386	#else /* not HAVE_NTGUI */
5387
5388	/* This should be dealt with in XTread_socket now, and that doesn't
5389	   depend on the client system having the Kana syms defined.  See also
5390	   the XK_kana_A case below.  */
5391	#if 0
5392	#ifdef XK_kana_A
5393	static const char *const lispy_kana_keys[] =
5394	  {
5395	    /* X Keysym value */
5396	    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	/* 0x400 .. 0x40f */
5397	    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	/* 0x410 .. 0x41f */
5398	    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	/* 0x420 .. 0x42f */
5399	    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	/* 0x430 .. 0x43f */
5400	    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	/* 0x440 .. 0x44f */
5401	    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	/* 0x450 .. 0x45f */
5402	    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	/* 0x460 .. 0x46f */
5403	    0,0,0,0,0,0,0,0,0,0,0,0,0,0,"overline",0,
5404	    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	/* 0x480 .. 0x48f */
5405	    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	/* 0x490 .. 0x49f */
5406	    0, "kana-fullstop", "kana-openingbracket", "kana-closingbracket",
5407	    "kana-comma", "kana-conjunctive", "kana-WO", "kana-a",
5408	    "kana-i", "kana-u", "kana-e", "kana-o",
5409	    "kana-ya", "kana-yu", "kana-yo", "kana-tsu",
5410	    "prolongedsound", "kana-A", "kana-I", "kana-U",
5411	    "kana-E", "kana-O", "kana-KA", "kana-KI",
5412	    "kana-KU", "kana-KE", "kana-KO", "kana-SA",
5413	    "kana-SHI", "kana-SU", "kana-SE", "kana-SO",
5414	    "kana-TA", "kana-CHI", "kana-TSU", "kana-TE",
5415	    "kana-TO", "kana-NA", "kana-NI", "kana-NU",
5416	    "kana-NE", "kana-NO", "kana-HA", "kana-HI",
5417	    "kana-FU", "kana-HE", "kana-HO", "kana-MA",
5418	    "kana-MI", "kana-MU", "kana-ME", "kana-MO",
5419	    "kana-YA", "kana-YU", "kana-YO", "kana-RA",
5420	    "kana-RI", "kana-RU", "kana-RE", "kana-RO",
5421	    "kana-WA", "kana-N", "voicedsound", "semivoicedsound",
5422	    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	/* 0x4e0 .. 0x4ef */
5423	    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	/* 0x4f0 .. 0x4ff */
5424	  };
5425	#endif /* XK_kana_A */
5426	#endif /* 0 */
5427
5428	#define FUNCTION_KEY_OFFSET 0xff00
5429
5430	/* You'll notice that this table is arranged to be conveniently
5431	   indexed by X Windows keysym values.  */
5432	#if defined HAVE_NS || !defined HAVE_WINDOW_SYSTEM
5433	/* FIXME: Why are we using X11 keysym values for NS?  */
5434	static
5435	#endif
5436	const char *const lispy_function_keys[] =
5437	  {
5438	    /* X Keysym value */
5439
5440	    0, 0, 0, 0, 0, 0, 0, 0,			      /* 0xff00...0f */
5441	    "backspace", "tab", "linefeed", "clear",
5442	    0, "return", 0, 0,
5443	    0, 0, 0, "pause",				      /* 0xff10...1f */
5444	    0, 0, 0, 0, 0, 0, 0, "escape",
5445	    0, 0, 0, 0,
5446	    0, "kanji", "muhenkan", "henkan",		      /* 0xff20...2f */
5447	    "romaji", "hiragana", "katakana", "hiragana-katakana",
5448	    "zenkaku", "hankaku", "zenkaku-hankaku", "touroku",
5449	    "massyo", "kana-lock", "kana-shift", "eisu-shift",
5450	    "eisu-toggle",				      /* 0xff30...3f */
5451	       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5452	    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   /* 0xff40...4f */
5453
5454	    "home", "left", "up", "right", /* 0xff50 */	/* IsCursorKey */
5455	    "down", "prior", "next", "end",
5456	    "begin", 0, 0, 0, 0, 0, 0, 0,
5457	    "select",			/* 0xff60 */	/* IsMiscFunctionKey */
5458	    "print",
5459	    "execute",
5460	    "insert",
5461	    0,		/* 0xff64 */
5462	    "undo",
5463	    "redo",
5464	    "menu",
5465	    "find",
5466	    "cancel",
5467	    "help",
5468	    "break",			/* 0xff6b */
5469
5470	    0, 0, 0, 0,
5471	    0, 0, 0, 0, "backtab", 0, 0, 0,		/* 0xff70...  */
5472	    0, 0, 0, 0, 0, 0, 0, "kp-numlock",		/* 0xff78...  */
5473	    "kp-space",			/* 0xff80 */	/* IsKeypadKey */
5474	    0, 0, 0, 0, 0, 0, 0, 0,
5475	    "kp-tab",			/* 0xff89 */
5476	    0, 0, 0,
5477	    "kp-enter",			/* 0xff8d */
5478	    0, 0, 0,
5479	    "kp-f1",			/* 0xff91 */
5480	    "kp-f2",
5481	    "kp-f3",
5482	    "kp-f4",
5483	    "kp-home",			/* 0xff95 */
5484	    "kp-left",
5485	    "kp-up",
5486	    "kp-right",
5487	    "kp-down",
5488	    "kp-prior",			/* kp-page-up */
5489	    "kp-next",			/* kp-page-down */
5490	    "kp-end",
5491	    "kp-begin",
5492	    "kp-insert",
5493	    "kp-delete",
5494	    0,				/* 0xffa0 */
5495	    0, 0, 0, 0, 0, 0, 0, 0, 0,
5496	    "kp-multiply",		/* 0xffaa */
5497	    "kp-add",
5498	    "kp-separator",
5499	    "kp-subtract",
5500	    "kp-decimal",
5501	    "kp-divide",		/* 0xffaf */
5502	    "kp-0",			/* 0xffb0 */
5503	    "kp-1",	"kp-2",	"kp-3",	"kp-4",	"kp-5",	"kp-6",	"kp-7",	"kp-8",	"kp-9",
5504	    0,		/* 0xffba */
5505	    0, 0,
5506	    "kp-equal",			/* 0xffbd */
5507	    "f1",			/* 0xffbe */	/* IsFunctionKey */
5508	    "f2",
5509	    "f3", "f4", "f5", "f6", "f7", "f8",	"f9", "f10", /* 0xffc0 */
5510	    "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18",
5511	    "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26", /* 0xffd0 */
5512	    "f27", "f28", "f29", "f30", "f31", "f32", "f33", "f34",
5513	    "f35", 0, 0, 0, 0, 0, 0, 0,	/* 0xffe0 */
5514	    0, 0, 0, 0, 0, 0, 0, 0,
5515	    0, 0, 0, 0, 0, 0, 0, 0,     /* 0xfff0 */
5516	    0, 0, 0, 0, 0, 0, 0, "delete"
5517	  };
5518
5519	/* ISO 9995 Function and Modifier Keys; the first byte is 0xFE.  */
5520	#define ISO_FUNCTION_KEY_OFFSET 0xfe00
5521
5522	static const char *const iso_lispy_function_keys[] =
5523	  {
5524	    0, 0, 0, 0, 0, 0, 0, 0,	/* 0xfe00 */
5525	    0, 0, 0, 0, 0, 0, 0, 0,	/* 0xfe08 */
5526	    0, 0, 0, 0, 0, 0, 0, 0,	/* 0xfe10 */
5527	    0, 0, 0, 0, 0, 0, 0, 0,	/* 0xfe18 */
5528	    "iso-lefttab",		/* 0xfe20 */
5529	    "iso-move-line-up", "iso-move-line-down",
5530	    "iso-partial-line-up", "iso-partial-line-down",
5531	    "iso-partial-space-left", "iso-partial-space-right",
5532	    "iso-set-margin-left", "iso-set-margin-right", /* 0xffe27, 28 */
5533	    "iso-release-margin-left", "iso-release-margin-right",
5534	    "iso-release-both-margins",
5535	    "iso-fast-cursor-left", "iso-fast-cursor-right",
5536	    "iso-fast-cursor-up", "iso-fast-cursor-down",
5537	    "iso-continuous-underline", "iso-discontinuous-underline", /* 0xfe30, 31 */
5538	    "iso-emphasize", "iso-center-object", "iso-enter", /* ... 0xfe34 */
5539	  };
5540
5541	#endif /* not HAVE_NTGUI */
5542
5543	static Lisp_Object Vlispy_mouse_stem;
5544
5545	static const char *const lispy_wheel_names[] =
5546	{
5547	  "wheel-up", "wheel-down", "wheel-left", "wheel-right"
5548	};
5549
5550	/* drag-n-drop events are generated when a set of selected files are
5551	   dragged from another application and dropped onto an Emacs window.  */
5552	static const char *const lispy_drag_n_drop_names[] =
5553	{
5554	  "drag-n-drop"
5555	};
5556
5557	/* An array of symbol indexes of scroll bar parts, indexed by an enum
5558	   scroll_bar_part value.  Note that Qnil corresponds to
5559	   scroll_bar_nowhere and should not appear in Lisp events.  */
5560	static short const scroll_bar_parts[] = {
5561	  SYMBOL_INDEX (Qnil), SYMBOL_INDEX (Qabove_handle), SYMBOL_INDEX (Qhandle),
5562	  SYMBOL_INDEX (Qbelow_handle), SYMBOL_INDEX (Qup), SYMBOL_INDEX (Qdown),
5563	  SYMBOL_INDEX (Qtop), SYMBOL_INDEX (Qbottom), SYMBOL_INDEX (Qend_scroll),
5564	  SYMBOL_INDEX (Qratio), SYMBOL_INDEX (Qbefore_handle),
5565	  SYMBOL_INDEX (Qhorizontal_handle), SYMBOL_INDEX (Qafter_handle),
5566	  SYMBOL_INDEX (Qleft), SYMBOL_INDEX (Qright), SYMBOL_INDEX (Qleftmost),
5567	  SYMBOL_INDEX (Qrightmost), SYMBOL_INDEX (Qend_scroll), SYMBOL_INDEX (Qratio)
5568	};
5569
5570	#ifdef HAVE_WINDOW_SYSTEM
5571	/* An array of symbol indexes of internal border parts, indexed by an enum
5572	   internal_border_part value.  Note that Qnil corresponds to
5573	   internal_border_part_none and should not appear in Lisp events.  */
5574	static short const internal_border_parts[] = {
5575	  SYMBOL_INDEX (Qnil), SYMBOL_INDEX (Qleft_edge),
5576	  SYMBOL_INDEX (Qtop_left_corner), SYMBOL_INDEX (Qtop_edge),
5577	  SYMBOL_INDEX (Qtop_right_corner), SYMBOL_INDEX (Qright_edge),
5578	  SYMBOL_INDEX (Qbottom_right_corner), SYMBOL_INDEX (Qbottom_edge),
5579	  SYMBOL_INDEX (Qbottom_left_corner)
5580	};
5581	#endif
5582
5583	/* A vector, indexed by button number, giving the down-going location
5584	   of currently depressed buttons, both scroll bar and non-scroll bar.
5585
5586	   The elements have the form
5587	     (BUTTON-NUMBER MODIFIER-MASK . REST)
5588	   where REST is the cdr of a position as it would be reported in the event.
5589
5590	   The make_lispy_event function stores positions here to tell the
5591	   difference between click and drag events, and to store the starting
5592	   location to be included in drag events.  */
5593
5594	static Lisp_Object button_down_location;
5595
5596	/* A cons recording the original frame-relative x and y coordinates of
5597	   the down mouse event.  */
5598	static Lisp_Object frame_relative_event_pos;
5599
5600	/* The line-number display width, in columns, at the time of most
5601	   recent down mouse event.  */
5602	static int down_mouse_line_number_width;
5603
5604	/* Information about the most recent up-going button event:  Which
5605	   button, what location, and what time.  */
5606
5607	static int last_mouse_button;
5608	static int last_mouse_x;
5609	static int last_mouse_y;
5610	static Time button_down_time;
5611
5612	/* The number of clicks in this multiple-click.  */
5613
5614	static int double_click_count;
5615
5616	/* X and Y are frame-relative coordinates for a click or wheel event.
5617	   Return a Lisp-style event list.  */
5618
5619	static Lisp_Object
5620	make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
5621			     Time t)
5622	{
5623	  enum window_part part;
5624	  Lisp_Object posn = Qnil;
5625	  Lisp_Object extra_info = Qnil;
5626	  int mx = XFIXNUM (x), my = XFIXNUM (y);
5627	  /* Coordinate pixel positions to return.  */
5628	  int xret = 0, yret = 0;
5629	  /* The window or frame under frame pixel coordinates (x,y)  */
5630	  Lisp_Object window_or_frame = (f != NULL
5631					 ? window_from_coordinates (f, mx, my, &part,
5632								    false, true, true)
5633					 : Qnil);
5634	#ifdef HAVE_WINDOW_SYSTEM
5635	  bool tool_bar_p = false;
5636	  bool menu_bar_p = false;
5637
5638	  /* Report mouse events on the tab bar and (on GUI frames) on the
5639	     tool bar.  */
5640	  if (f && ((WINDOWP (f->tab_bar_window)
5641		     && EQ (window_or_frame, f->tab_bar_window))
5642	#ifndef HAVE_EXT_TOOL_BAR
5643		    || (WINDOWP (f->tool_bar_window)
5644			&& EQ (window_or_frame, f->tool_bar_window))
5645	#endif
5646		    ))
5647	    {
5648	      /* While 'track-mouse' is neither nil nor t, do not report this
5649		 event as something that happened on the tool or tab bar since
5650		 that would break mouse drag operations that originate from an
5651		 ordinary window beneath that bar and expect the window to
5652		 auto-scroll as soon as the mouse cursor appears above or
5653		 beneath it (Bug#50993).  We do allow reports for t, because
5654		 applications may have set 'track-mouse' to t and still expect a
5655		 click on the tool or tab bar to get through (Bug#51794).
5656
5657		 FIXME: This is a preliminary fix for the bugs cited above and
5658		 awaits a solution that includes a convention for all special
5659		 values of 'track-mouse' and their documentation in the Elisp
5660		 manual.  */
5661	      if (NILP (track_mouse) || EQ (track_mouse, Qt))
5662		posn = EQ (window_or_frame, f->tab_bar_window) ? Qtab_bar : Qtool_bar;
5663	      /* Kludge alert: for mouse events on the tab bar and tool bar,
5664		 keyboard.c wants the frame, not the special-purpose window
5665		 we use to display those, and it wants frame-relative
5666		 coordinates.  FIXME!  */
5667	      window_or_frame = Qnil;
5668	    }
5669
5670	  if (f && FRAME_TERMINAL (f)->toolkit_position_hook)
5671	    {
5672	      FRAME_TERMINAL (f)->toolkit_position_hook (f, mx, my, &menu_bar_p,
5673							 &tool_bar_p);
5674
5675	      if (NILP (track_mouse) || EQ (track_mouse, Qt))
5676		{
5677		  if (menu_bar_p)
5678		    posn = Qmenu_bar;
5679		  else if (tool_bar_p)
5680		    posn = Qtool_bar;
5681		}
5682	    }
5683	#endif
5684	  if (f
5685	      && !FRAME_WINDOW_P (f)
5686	      && FRAME_TAB_BAR_LINES (f) > 0
5687	      && my >= FRAME_MENU_BAR_LINES (f)
5688	      && my < FRAME_MENU_BAR_LINES (f) + FRAME_TAB_BAR_LINES (f))
5689	    {
5690	      posn = Qtab_bar;
5691	      window_or_frame = Qnil;	/* see above */
5692	    }
5693
5694	  if (WINDOWP (window_or_frame))
5695	    {
5696	      /* It's a click in window WINDOW at frame coordinates (X,Y)  */
5697	      struct window *w = XWINDOW (window_or_frame);
5698	      Lisp_Object string_info = Qnil;
5699	      ptrdiff_t textpos = 0;
5700	      int col = -1, row = -1;
5701	      int dx  = -1, dy  = -1;
5702	      int width = -1, height = -1;
5703	      Lisp_Object object = Qnil;
5704
5705	      /* Pixel coordinates relative to the window corner.  */
5706	      int wx = mx - WINDOW_LEFT_EDGE_X (w);
5707	      int wy = my - WINDOW_TOP_EDGE_Y (w);
5708
5709	      /* For text area clicks, return X, Y relative to the corner of
5710		 this text area.  Note that dX, dY etc are set below, by
5711		 buffer_posn_from_coords.  */
5712	      if (part == ON_TEXT)
5713		{
5714		  xret = mx - window_box_left (w, TEXT_AREA);
5715		  yret = wy - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w);
5716		}
5717	      /* For mode line and header line clicks, return X, Y relative to
5718		 the left window edge.  Use mode_line_string to look for a
5719		 string on the click position.  */
5720	      else if (part == ON_MODE_LINE || part == ON_TAB_LINE
5721		       || part == ON_HEADER_LINE)
5722		{
5723		  Lisp_Object string;
5724		  ptrdiff_t charpos;
5725
5726		  posn = (part == ON_MODE_LINE ? Qmode_line
5727			  : (part == ON_TAB_LINE ? Qtab_line
5728			     : Qheader_line));
5729
5730		  /* Note that mode_line_string takes COL, ROW as pixels and
5731		     converts them to characters.  */
5732		  col = wx;
5733		  row = wy;
5734		  string = mode_line_string (w, part, &col, &row, &charpos,
5735					     &object, &dx, &dy, &width, &height);
5736		  if (STRINGP (string))
5737		    string_info = Fcons (string, make_fixnum (charpos));
5738		  textpos = -1;
5739
5740		  xret = wx;
5741		  yret = wy;
5742		}
5743	      /* For fringes and margins, Y is relative to the area's (and the
5744		 window's) top edge, while X is meaningless.  */
5745	      else if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
5746		{
5747		  Lisp_Object string;
5748		  ptrdiff_t charpos;
5749
5750		  posn = (part == ON_LEFT_MARGIN) ? Qleft_margin : Qright_margin;
5751		  col = wx;
5752		  row = wy;
5753		  string = marginal_area_string (w, part, &col, &row, &charpos,
5754						 &object, &dx, &dy, &width, &height);
5755		  if (STRINGP (string))
5756		    string_info = Fcons (string, make_fixnum (charpos));
5757		  xret = wx;
5758		  yret = wy - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w);
5759		}
5760	      else if (part == ON_LEFT_FRINGE)
5761		{
5762		  posn = Qleft_fringe;
5763		  col = 0;
5764		  xret = wx;
5765		  dx = wx
5766		    - (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5767		       ? 0 : window_box_width (w, LEFT_MARGIN_AREA));
5768		  dy = yret = wy - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w);
5769		}
5770	      else if (part == ON_RIGHT_FRINGE)
5771		{
5772		  posn = Qright_fringe;
5773		  col = 0;
5774		  xret = wx;
5775		  dx = wx
5776		    - window_box_width (w, LEFT_MARGIN_AREA)
5777		    - window_box_width (w, TEXT_AREA)
5778		    - (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5779		       ? window_box_width (w, RIGHT_MARGIN_AREA)
5780		       : 0);
5781		  dy = yret = wy - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w);
5782		}
5783	      else if (part == ON_VERTICAL_BORDER)
5784		{
5785		  posn = Qvertical_line;
5786		  width = 1;
5787		  dx = 0;
5788		  xret = wx;
5789		  dy = yret = wy;
5790		}
5791	      else if (part == ON_VERTICAL_SCROLL_BAR)
5792		{
5793		  posn = Qvertical_scroll_bar;
5794		  width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
5795		  dx = xret = wx;
5796		  dy = yret = wy;
5797		}
5798	      else if (part == ON_HORIZONTAL_SCROLL_BAR)
5799		{
5800		  posn = Qhorizontal_scroll_bar;
5801		  width = WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
5802		  dx = xret = wx;
5803		  dy = yret = wy;
5804		}
5805	      else if (part == ON_RIGHT_DIVIDER)
5806		{
5807		  posn = Qright_divider;
5808		  width = WINDOW_RIGHT_DIVIDER_WIDTH (w);
5809		  dx = xret = wx;
5810		  dy = yret = wy;
5811		}
5812	      else if (part == ON_BOTTOM_DIVIDER)
5813		{
5814		  posn = Qbottom_divider;
5815		  width = WINDOW_BOTTOM_DIVIDER_WIDTH (w);
5816		  dx = xret = wx;
5817		  dy = yret = wy;
5818		}
5819
5820	      /* For clicks in the text area, fringes, margins, or vertical
5821		 scroll bar, call buffer_posn_from_coords to extract TEXTPOS,
5822		 the buffer position nearest to the click.  */
5823	      if (!textpos)
5824		{
5825		  Lisp_Object string2, object2 = Qnil;
5826		  struct display_pos p;
5827		  int dx2, dy2;
5828		  int width2, height2;
5829		  /* The pixel X coordinate passed to buffer_posn_from_coords
5830		     is the X coordinate relative to the text area for clicks
5831		     in text-area, right-margin/fringe and right-side vertical
5832		     scroll bar, zero otherwise.  */
5833		  int x2
5834		    = (part == ON_TEXT) ? xret
5835		    : (part == ON_RIGHT_FRINGE || part == ON_RIGHT_MARGIN
5836		       || (part == ON_VERTICAL_SCROLL_BAR
5837			   && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
5838		    ? (mx - window_box_left (w, TEXT_AREA))
5839		    : 0;
5840		  int y2 = wy;
5841
5842		  string2 = buffer_posn_from_coords (w, &x2, &y2, &p,
5843						     &object2, &dx2, &dy2,
5844						     &width2, &height2);
5845		  textpos = CHARPOS (p.pos);
5846		  if (col < 0) col = x2;
5847		  if (row < 0) row = y2;
5848		  if (dx < 0) dx = dx2;
5849		  if (dy < 0) dy = dy2;
5850		  if (width < 0) width = width2;
5851		  if (height < 0) height = height2;
5852
5853		  if (NILP (posn))
5854		    {
5855		      posn = make_fixnum (textpos);
5856		      if (STRINGP (string2))
5857			string_info = Fcons (string2,
5858					     make_fixnum (CHARPOS (p.string_pos)));
5859		    }
5860		  if (NILP (object))
5861		    object = object2;
5862		}
5863
5864	#ifdef HAVE_WINDOW_SYSTEM
5865	      if (IMAGEP (object))
5866		{
5867		  Lisp_Object image_map, hotspot;
5868		  if ((image_map = plist_get (XCDR (object), QCmap),
5869		       !NILP (image_map))
5870		      && (hotspot = find_hot_spot (image_map, dx, dy),
5871			  CONSP (hotspot))
5872		      && (hotspot = XCDR (hotspot), CONSP (hotspot)))
5873		    posn = XCAR (hotspot);
5874		}
5875	#endif
5876
5877	      /* Object info.  */
5878	      extra_info
5879		= list3 (object,
5880			 Fcons (make_fixnum (dx), make_fixnum (dy)),
5881			 Fcons (make_fixnum (width), make_fixnum (height)));
5882
5883	      /* String info.  */
5884	      extra_info = Fcons (string_info,
5885				  Fcons (textpos < 0 ? Qnil : make_fixnum (textpos),
5886					 Fcons (Fcons (make_fixnum (col),
5887						       make_fixnum (row)),
5888						extra_info)));
5889	    }
5890	  else if (f)
5891	    {
5892	      /* Return mouse pixel coordinates here.  */
5893	      XSETFRAME (window_or_frame, f);
5894	      xret = mx;
5895	      yret = my;
5896
5897	#ifdef HAVE_WINDOW_SYSTEM
5898	      if (FRAME_WINDOW_P (f)
5899		  && FRAME_LIVE_P (f)
5900		  && NILP (posn)
5901		  && FRAME_INTERNAL_BORDER_WIDTH (f) > 0
5902		  && !NILP (get_frame_param (f, Qdrag_internal_border)))
5903		{
5904		  enum internal_border_part part
5905		    = frame_internal_border_part (f, xret, yret);
5906
5907		  posn = builtin_lisp_symbol (internal_border_parts[part]);
5908		}
5909	#endif
5910	    }
5911	  else
5912	    {
5913	      if (EQ (track_mouse, Qdrag_source))
5914		{
5915		  xret = mx;
5916		  yret = my;
5917		}
5918
5919	      window_or_frame = Qnil;
5920	    }
5921
5922	  return Fcons (window_or_frame,
5923			Fcons (posn,
5924			       Fcons (Fcons (make_fixnum (xret),
5925					     make_fixnum (yret)),
5926				      Fcons (INT_TO_INTEGER (t),
5927					     extra_info))));
5928	}
5929
5930	/* Return non-zero if F is a GUI frame that uses some toolkit-managed
5931	   menu bar.  This really means that Emacs draws and manages the menu
5932	   bar as part of its normal display, and therefore can compute its
5933	   geometry.  */
5934	static bool
5935	toolkit_menubar_in_use (struct frame *f)
5936	{
5937	#ifdef HAVE_EXT_MENU_BAR
5938	  return !(!FRAME_WINDOW_P (f));
5939	#else
5940	  return false;
5941	#endif
5942	}
5943
5944	/* Build the part of Lisp event which represents scroll bar state from
5945	   EV.  TYPE is one of Qvertical_scroll_bar or Qhorizontal_scroll_bar.  */
5946
5947	static Lisp_Object
5948	make_scroll_bar_position (struct input_event *ev, Lisp_Object type)
5949	{
5950	  return list5 (ev->frame_or_window, type, Fcons (ev->x, ev->y),
5951			INT_TO_INTEGER (ev->timestamp),
5952			builtin_lisp_symbol (scroll_bar_parts[ev->part]));
5953	}
5954
5955	#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
5956
5957	/* Return whether or not the coordinates X and Y are inside the
5958	   box of the menu-bar window of frame F.  */
5959
5960	static bool
5961	coords_in_menu_bar_window (struct frame *f, int x, int y)
5962	{
5963	  struct window *window;
5964
5965	  if (!WINDOWP (f->menu_bar_window))
5966	    return false;
5967
5968	  window = XWINDOW (f->menu_bar_window);
5969
5970	  return (y >= WINDOW_TOP_EDGE_Y (window)
5971		  && x >= WINDOW_LEFT_EDGE_X (window)
5972		  && y <= WINDOW_BOTTOM_EDGE_Y (window)
5973		  && x <= WINDOW_RIGHT_EDGE_X (window));
5974	}
5975
5976	#endif
5977
5978	#ifdef HAVE_WINDOW_SYSTEM
5979
5980	/* Return whether or not the coordinates X and Y are inside the
5981	   tab-bar window of the given frame F.  */
5982
5983	static bool
5984	coords_in_tab_bar_window (struct frame *f, int x, int y)
5985	{
5986	  struct window *window;
5987
5988	  if (!WINDOWP (f->tab_bar_window))
5989	    return false;
5990
5991	  window = XWINDOW (f->tab_bar_window);
5992
5993	  return (y >= WINDOW_TOP_EDGE_Y (window)
5994		  && x >= WINDOW_LEFT_EDGE_X (window)
5995		  && y <= WINDOW_BOTTOM_EDGE_Y (window)
5996		  && x <= WINDOW_RIGHT_EDGE_X (window));
5997	}
5998
5999	#endif /* HAVE_WINDOW_SYSTEM */
6000
6001	static void
6002	save_line_number_display_width (struct input_event *event)
6003	{
6004	  struct window *w;
6005	  int pixel_width;
6006
6007	  if (WINDOWP (event->frame_or_window))
6008	    w = XWINDOW (event->frame_or_window);
6009	  else if (FRAMEP (event->frame_or_window))
6010	    w = XWINDOW (XFRAME (event->frame_or_window)->selected_window);
6011	  else
6012	    w = XWINDOW (selected_window);
6013	  line_number_display_width (w, &down_mouse_line_number_width, &pixel_width);
6014	}
6015
6016	/* Return non-zero if the change of position from START_POS to END_POS
6017	   is likely to be the effect of horizontal scrolling due to a change
6018	   in line-number width produced by redisplay between two mouse
6019	   events, like mouse-down followed by mouse-up, at those positions.
6020	   This is used to decide whether to converts mouse-down followed by
6021	   mouse-up event into a mouse-drag event.  */
6022	static bool
6023	line_number_mode_hscroll (Lisp_Object start_pos, Lisp_Object end_pos)
6024	{
6025	  if (!EQ (Fcar (start_pos), Fcar (end_pos)) /* different window */
6026	      || list_length (start_pos) < 7	     /* no COL/ROW info */
6027	      || list_length (end_pos) < 7)
6028	    return false;
6029
6030	  Lisp_Object start_col_row = Fnth (make_fixnum (6), start_pos);
6031	  Lisp_Object end_col_row = Fnth (make_fixnum (6), end_pos);
6032	  Lisp_Object window = Fcar (end_pos);
6033	  int col_width, pixel_width;
6034	  Lisp_Object start_col, end_col;
6035	  struct window *w;
6036	  if (!WINDOW_VALID_P (window))
6037	    {
6038	      if (WINDOW_LIVE_P (window))
6039		window = XFRAME (window)->selected_window;
6040	      else
6041		window = selected_window;
6042	    }
6043	  w = XWINDOW (window);
6044	  line_number_display_width (w, &col_width, &pixel_width);
6045	  start_col = Fcar (start_col_row);
6046	  end_col = Fcar (end_col_row);
6047	  return EQ (start_col, end_col)
6048		 && down_mouse_line_number_width >= 0
6049		 && col_width != down_mouse_line_number_width;
6050	}
6051
6052	/* Given a struct input_event, build the lisp event which represents
6053	   it.  If EVENT is 0, build a mouse movement event from the mouse
6054	   movement buffer, which should have a movement event in it.
6055
6056	   Note that events must be passed to this function in the order they
6057	   are received; this function stores the location of button presses
6058	   in order to build drag events when the button is released.  */
6059
6060	static Lisp_Object
6061	make_lispy_event (struct input_event *event)
6062	{
6063	  int i;
6064
6065	  switch (event->kind)
6066	    {
6067	#ifdef HAVE_WINDOW_SYSTEM
6068	    case DELETE_WINDOW_EVENT:
6069	      /* Make an event (delete-frame (FRAME)).  */
6070	      return list2 (Qdelete_frame, list1 (event->frame_or_window));
6071
6072	    case ICONIFY_EVENT:
6073	      /* Make an event (iconify-frame (FRAME)).  */
6074	      return list2 (Qiconify_frame, list1 (event->frame_or_window));
6075
6076	    case DEICONIFY_EVENT:
6077	      /* Make an event (make-frame-visible (FRAME)).  */
6078	      return list2 (Qmake_frame_visible, list1 (event->frame_or_window));
6079
6080	    case MOVE_FRAME_EVENT:
6081	      /* Make an event (move-frame (FRAME)).  */
6082	      return list2 (Qmove_frame, list1 (event->frame_or_window));
6083	#endif
6084
6085	    /* Just discard these, by returning nil.
6086	       With MULTI_KBOARD, these events are used as placeholders
6087	       when we need to randomly delete events from the queue.
6088	       (They shouldn't otherwise be found in the buffer,
6089	       but on some machines it appears they do show up
6090	       even without MULTI_KBOARD.)  */
6091	    /* On Windows NT/9X, NO_EVENT is used to delete extraneous
6092	       mouse events during a popup-menu call.  */
6093	    case NO_EVENT:
6094	      return Qnil;
6095
6096	    case HELP_EVENT:
6097	      {
6098		Lisp_Object frame = event->frame_or_window;
6099		Lisp_Object object = event->arg;
6100		Lisp_Object position
6101	          = make_fixnum (Time_to_position (event->timestamp));
6102		Lisp_Object window = event->x;
6103		Lisp_Object help = event->y;
6104		clear_event (event);
6105
6106		if (!WINDOWP (window))
6107		  window = Qnil;
6108		return Fcons (Qhelp_echo,
6109			      list5 (frame, help, window, object, position));
6110	      }
6111
6112	    case FOCUS_IN_EVENT:
6113	        return make_lispy_focus_in (event->frame_or_window);
6114
6115	    case FOCUS_OUT_EVENT:
6116	        return make_lispy_focus_out (event->frame_or_window);
6117
6118	    /* A simple keystroke.  */
6119	    case ASCII_KEYSTROKE_EVENT:
6120	    case MULTIBYTE_CHAR_KEYSTROKE_EVENT:
6121	      {
6122		Lisp_Object lispy_c;
6123		EMACS_INT c = event->code;
6124		if (event->kind == ASCII_KEYSTROKE_EVENT)
6125		  {
6126		    c &= 0377;
6127		    eassert (c == event->code);
6128	          }
6129
6130	        /* Caps-lock shouldn't affect interpretation of key chords:
6131	           Control+s should produce C-s whether caps-lock is on or
6132	           not.  And Control+Shift+s should produce C-S-s whether
6133	           caps-lock is on or not.  */
6134	        if (event->modifiers & ~shift_modifier)
6135		  {
6136	            /* This is a key chord: some non-shift modifier is
6137	               depressed.  */
6138
6139	            if (uppercasep (c) &&
6140	                !(event->modifiers & shift_modifier))
6141		      {
6142	                /* Got a capital letter without a shift.  The caps
6143	                   lock is on.   Un-capitalize the letter.  */
6144	                c = downcase (c);
6145		      }
6146	            else if (lowercasep (c) &&
6147	                     (event->modifiers & shift_modifier))
6148		      {
6149	                /* Got a lower-case letter even though shift is
6150	                   depressed.  The caps lock is on.  Capitalize the
6151	                   letter.  */
6152	                c = upcase (c);
6153		      }
6154		  }
6155
6156		if (event->kind == ASCII_KEYSTROKE_EVENT)
6157		  {
6158		    /* Turn ASCII characters into control characters
6159		       when proper.  */
6160		    if (event->modifiers & ctrl_modifier)
6161		      {
6162			c = make_ctrl_char (c);
6163			event->modifiers &= ~ctrl_modifier;
6164		      }
6165		  }
6166
6167		/* Add in the other modifier bits.  The shift key was taken care
6168		   of by the X code.  */
6169		c |= (event->modifiers
6170		      & (meta_modifier | alt_modifier
6171			 | hyper_modifier | super_modifier | ctrl_modifier));
6172		/* Distinguish Shift-SPC from SPC.  */
6173		if ((event->code) == 040
6174		    && event->modifiers & shift_modifier)
6175		  c |= shift_modifier;
6176		button_down_time = 0;
6177		XSETFASTINT (lispy_c, c);
6178		return lispy_c;
6179	      }
6180
6181	#ifdef HAVE_NS
6182	    case NS_TEXT_EVENT:
6183	      return list1 (intern (event->code == KEY_NS_PUT_WORKING_TEXT
6184	                            ? "ns-put-working-text"
6185	                            : "ns-unput-working-text"));
6186
6187	      /* NS_NONKEY_EVENTs are just like NON_ASCII_KEYSTROKE_EVENTs,
6188		 except that they are non-key events (last-nonmenu-event is nil).  */
6189	    case NS_NONKEY_EVENT:
6190	#endif
6191
6192	      /* A function key.  The symbol may need to have modifier prefixes
6193		 tacked onto it.  */
6194	    case NON_ASCII_KEYSTROKE_EVENT:
6195	      button_down_time = 0;
6196
6197	      for (i = 0; i < ARRAYELTS (lispy_accent_codes); i++)
6198		if (event->code == lispy_accent_codes[i])
6199		  return modify_event_symbol (i,
6200					      event->modifiers,
6201					      Qfunction_key, Qnil,
6202					      lispy_accent_keys, &accent_key_syms,
6203	                                      ARRAYELTS (lispy_accent_keys));
6204
6205	#if 0
6206	#ifdef XK_kana_A
6207	      if (event->code >= 0x400 && event->code < 0x500)
6208		return modify_event_symbol (event->code - 0x400,
6209					    event->modifiers & ~shift_modifier,
6210					    Qfunction_key, Qnil,
6211					    lispy_kana_keys, &func_key_syms,
6212	                                    ARRAYELTS (lispy_kana_keys));
6213	#endif /* XK_kana_A */
6214	#endif /* 0 */
6215
6216	#ifdef ISO_FUNCTION_KEY_OFFSET
6217	      if (event->code < FUNCTION_KEY_OFFSET
6218		  && event->code >= ISO_FUNCTION_KEY_OFFSET)
6219		return modify_event_symbol (event->code - ISO_FUNCTION_KEY_OFFSET,
6220					    event->modifiers,
6221					    Qfunction_key, Qnil,
6222					    iso_lispy_function_keys, &func_key_syms,
6223	                                    ARRAYELTS (iso_lispy_function_keys));
6224	#endif
6225
6226	      if ((FUNCTION_KEY_OFFSET <= event->code
6227		   && (event->code
6228		       < FUNCTION_KEY_OFFSET + ARRAYELTS (lispy_function_keys)))
6229		  && lispy_function_keys[event->code - FUNCTION_KEY_OFFSET])
6230		return modify_event_symbol (event->code - FUNCTION_KEY_OFFSET,
6231					    event->modifiers,
6232					    Qfunction_key, Qnil,
6233					    lispy_function_keys, &func_key_syms,
6234					    ARRAYELTS (lispy_function_keys));
6235
6236	      /* Handle system-specific or unknown keysyms.
6237		 We need to use an alist rather than a vector as the cache
6238		 since we can't make a vector long enough.  */
6239	      if (NILP (KVAR (current_kboard, system_key_syms)))
6240		kset_system_key_syms (current_kboard, Fcons (Qnil, Qnil));
6241	      return modify_event_symbol (event->code,
6242					  event->modifiers,
6243					  Qfunction_key,
6244					  KVAR (current_kboard, Vsystem_key_alist),
6245					  0, &KVAR (current_kboard, system_key_syms),
6246					  PTRDIFF_MAX);
6247
6248	#ifdef HAVE_NTGUI
6249	    case END_SESSION_EVENT:
6250	      /* Make an event (end-session).  */
6251	      return list1 (Qend_session);
6252
6253	    case LANGUAGE_CHANGE_EVENT:
6254	      /* Make an event (language-change FRAME CODEPAGE LANGUAGE-ID).  */
6255	      return list4 (Qlanguage_change,
6256			    event->frame_or_window,
6257			    make_fixnum (event->code),
6258			    make_fixnum (event->modifiers));
6259
6260	    case MULTIMEDIA_KEY_EVENT:
6261	      if (event->code < ARRAYELTS (lispy_multimedia_keys)
6262	          && event->code > 0 && lispy_multimedia_keys[event->code])
6263	        {
6264	          return modify_event_symbol (event->code, event->modifiers,
6265	                                      Qfunction_key, Qnil,
6266	                                      lispy_multimedia_keys, &func_key_syms,
6267	                                      ARRAYELTS (lispy_multimedia_keys));
6268	        }
6269	      return Qnil;
6270	#endif
6271
6272	      /* A mouse click.  Figure out where it is, decide whether it's
6273	         a press, click or drag, and build the appropriate structure.  */
6274	    case MOUSE_CLICK_EVENT:
6275	#ifndef USE_TOOLKIT_SCROLL_BARS
6276	    case SCROLL_BAR_CLICK_EVENT:
6277	    case HORIZONTAL_SCROLL_BAR_CLICK_EVENT:
6278	#endif
6279	      {
6280		int button = event->code;
6281		bool is_double;
6282		Lisp_Object position;
6283		Lisp_Object *start_pos_ptr;
6284		Lisp_Object start_pos;
6285
6286		position = Qnil;
6287
6288		/* Build the position as appropriate for this mouse click.  */
6289		if (event->kind == MOUSE_CLICK_EVENT)
6290		  {
6291		    struct frame *f = XFRAME (event->frame_or_window);
6292		    int row, column;
6293
6294		    /* Ignore mouse events that were made on frame that
6295		       have been deleted.  */
6296		    if (! FRAME_LIVE_P (f))
6297		      return Qnil;
6298
6299		    /* EVENT->x and EVENT->y are frame-relative pixel
6300		       coordinates at this place.  Under old redisplay, COLUMN
6301		       and ROW are set to frame relative glyph coordinates
6302		       which are then used to determine whether this click is
6303		       in a menu (non-toolkit version).  */
6304		    if (!toolkit_menubar_in_use (f)
6305	#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
6306			/* Don't process events for menu bars if they are not
6307			   in the menu bar window.  */
6308			&& (!FRAME_WINDOW_P (f)
6309			    || coords_in_menu_bar_window (f, XFIXNUM (event->x),
6310							  XFIXNUM (event->y)))
6311	#endif
6312			)
6313		      {
6314	#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
6315			if (FRAME_WINDOW_P (f))
6316			  {
6317			    struct window *menu_w = XWINDOW (f->menu_bar_window);
6318			    int x, y, dummy;
6319
6320			    x = FRAME_TO_WINDOW_PIXEL_X (menu_w, XFIXNUM (event->x));
6321			    y = FRAME_TO_WINDOW_PIXEL_Y (menu_w, XFIXNUM (event->y));
6322
6323			    x_y_to_hpos_vpos (XWINDOW (f->menu_bar_window), x, y, &column, &row,
6324					      NULL, NULL, &dummy);
6325			  }
6326			else
6327	#endif
6328			  pixel_to_glyph_coords (f, XFIXNUM (event->x), XFIXNUM (event->y),
6329						 &column, &row, NULL, 1);
6330
6331			/* In the non-toolkit version, clicks on the menu bar
6332			   are ordinary button events in the event buffer.
6333			   Distinguish them, and invoke the menu.
6334
6335			   (In the toolkit version, the toolkit handles the
6336			   menu bar and Emacs doesn't know about it until
6337			   after the user makes a selection.)  */
6338			if (row >= 0 && row < FRAME_MENU_BAR_LINES (f)
6339			    && (event->modifiers & down_modifier))
6340			  {
6341			    Lisp_Object items, item;
6342
6343			    /* Find the menu bar item under `column'.  */
6344			    item = Qnil;
6345			    items = FRAME_MENU_BAR_ITEMS (f);
6346			    for (i = 0; i < ASIZE (items); i += 4)
6347			      {
6348				Lisp_Object pos, string;
6349				string = AREF (items, i + 1);
6350				pos = AREF (items, i + 3);
6351				if (NILP (string))
6352				  break;
6353				if (column >= XFIXNUM (pos)
6354				    && column < XFIXNUM (pos) + SCHARS (string))
6355				  {
6356				    item = AREF (items, i);
6357				    break;
6358				  }
6359			      }
6360
6361			    /* Don't generate a menu bar event if ITEM is
6362			       nil.  */
6363			    if (NILP (item))
6364			      return Qnil;
6365
6366			    /* ELisp manual 2.4b says (x y) are window
6367			       relative but code says they are
6368			       frame-relative.  */
6369			    position = list4 (event->frame_or_window,
6370					      Qmenu_bar,
6371					      Fcons (event->x, event->y),
6372					      INT_TO_INTEGER (event->timestamp));
6373
6374			    return list2 (item, position);
6375			  }
6376		      }
6377
6378		    position = make_lispy_position (f, event->x, event->y,
6379						    event->timestamp);
6380
6381		    /* For tab-bar clicks, add the propertized string with
6382		       button information as OBJECT member of POSITION.  */
6383		    if (CONSP (event->arg) && EQ (XCAR (event->arg), Qtab_bar))
6384		      position = nconc2 (position, Fcons (XCDR (event->arg), Qnil));
6385		  }
6386	#ifndef USE_TOOLKIT_SCROLL_BARS
6387		else
6388		  /* It's a scrollbar click.  */
6389		  position = make_scroll_bar_position (event, Qvertical_scroll_bar);
6390	#endif /* not USE_TOOLKIT_SCROLL_BARS */
6391
6392		if (button >= ASIZE (button_down_location))
6393		  {
6394		    ptrdiff_t incr = button - ASIZE (button_down_location) + 1;
6395		    button_down_location = larger_vector (button_down_location,
6396							  incr, -1);
6397		    mouse_syms = larger_vector (mouse_syms, incr, -1);
6398		  }
6399
6400		start_pos_ptr = aref_addr (button_down_location, button);
6401		start_pos = *start_pos_ptr;
6402		*start_pos_ptr = Qnil;
6403
6404		{
6405		  /* On window-system frames, use the value of
6406		     double-click-fuzz as is.  On other frames, interpret it
6407		     as a multiple of 1/8 characters.  */
6408		  struct frame *f;
6409		  intmax_t fuzz;
6410
6411		  if (WINDOWP (event->frame_or_window))
6412		    f = XFRAME (XWINDOW (event->frame_or_window)->frame);
6413		  else if (FRAMEP (event->frame_or_window))
6414		    f = XFRAME (event->frame_or_window);
6415		  else
6416		    emacs_abort ();
6417
6418		  if (FRAME_WINDOW_P (f))
6419		    fuzz = double_click_fuzz;
6420		  else
6421		    fuzz = double_click_fuzz / 8;
6422
6423		  is_double = (button == last_mouse_button
6424			       && (eabs (XFIXNUM (event->x) - last_mouse_x) <= fuzz)
6425			       && (eabs (XFIXNUM (event->y) - last_mouse_y) <= fuzz)
6426			       && button_down_time != 0
6427			       && (EQ (Vdouble_click_time, Qt)
6428				   || (FIXNATP (Vdouble_click_time)
6429				       && (event->timestamp - button_down_time
6430					   < XFIXNAT (Vdouble_click_time)))));
6431		}
6432
6433		last_mouse_button = button;
6434		last_mouse_x = XFIXNUM (event->x);
6435		last_mouse_y = XFIXNUM (event->y);
6436
6437		/* If this is a button press, squirrel away the location, so
6438	           we can decide later whether it was a click or a drag.  */
6439		if (event->modifiers & down_modifier)
6440		  {
6441		    if (is_double)
6442		      {
6443			double_click_count++;
6444			event->modifiers |= ((double_click_count > 2)
6445					     ? triple_modifier
6446					     : double_modifier);
6447		      }
6448		    else
6449		      double_click_count = 1;
6450		    button_down_time = event->timestamp;
6451		    *start_pos_ptr = Fcopy_alist (position);
6452		    frame_relative_event_pos = Fcons (event->x, event->y);
6453		    ignore_mouse_drag_p = false;
6454		    /* Squirrel away the line-number width, if any.  */
6455		    save_line_number_display_width (event);
6456		  }
6457
6458		/* Now we're releasing a button - check the coordinates to
6459	           see if this was a click or a drag.  */
6460		else if (event->modifiers & up_modifier)
6461		  {
6462		    /* If we did not see a down before this up, ignore the up.
6463		       Probably this happened because the down event chose a
6464		       menu item.  It would be an annoyance to treat the
6465		       release of the button that chose the menu item as a
6466		       separate event.  */
6467
6468		    if (!CONSP (start_pos))
6469		      return Qnil;
6470
6471		    unsigned click_or_drag_modifier = click_modifier;
6472
6473		    if (ignore_mouse_drag_p)
6474		      ignore_mouse_drag_p = false;
6475		    else
6476		      {
6477			intmax_t xdiff = double_click_fuzz, ydiff = double_click_fuzz;
6478
6479			xdiff = XFIXNUM (event->x)
6480			  - XFIXNUM (XCAR (frame_relative_event_pos));
6481			ydiff = XFIXNUM (event->y)
6482			  - XFIXNUM (XCDR (frame_relative_event_pos));
6483
6484			if (! (0 < double_click_fuzz
6485			       && - double_click_fuzz < xdiff
6486			       && xdiff < double_click_fuzz
6487			       && - double_click_fuzz < ydiff
6488			       && ydiff < double_click_fuzz
6489			       /* Maybe the mouse has moved a lot, caused scrolling, and
6490				  eventually ended up at the same screen position (but
6491				  not buffer position) in which case it is a drag, not
6492				  a click.  */
6493			       /* FIXME: OTOH if the buffer position has changed
6494				  because of a timer or process filter rather than
6495				  because of mouse movement, it should be considered as
6496				  a click.  But mouse-drag-region completely ignores
6497				  this case and it hasn't caused any real problem, so
6498				  it's probably OK to ignore it as well.  */
6499			       && (EQ (Fcar (Fcdr (start_pos)),
6500				       Fcar (Fcdr (position))) /* Same buffer pos */
6501				   /* Redisplay hscrolled text between down- and
6502	                              up-events due to display-line-numbers-mode.  */
6503				   || line_number_mode_hscroll (start_pos, position)
6504				   || !EQ (Fcar (start_pos),
6505					   Fcar (position))))) /* Different window */
6506
6507			  {
6508			    /* Mouse has moved enough.  */
6509			    button_down_time = 0;
6510			    click_or_drag_modifier = drag_modifier;
6511			    /* Reset the value for future clicks.  */
6512			    down_mouse_line_number_width = -1;
6513			  }
6514			else if (((!EQ (Fcar (start_pos), Fcar (position)))
6515				  || (!EQ (Fcar (Fcdr (start_pos)),
6516					   Fcar (Fcdr (position)))))
6517				 /* Was the down event in a window body? */
6518				 && FIXNUMP (Fcar (Fcdr (start_pos)))
6519				 && WINDOW_LIVE_P (Fcar (start_pos))
6520				 && !NILP (Ffboundp (Qwindow_edges)))
6521			  /* If the window (etc.) at the mouse position has
6522			     changed between the down event and the up event,
6523			     we assume there's been a redisplay between the
6524			     two events, and we pretend the mouse is still in
6525			     the old window to prevent a spurious drag event
6526			     being generated.  */
6527			  {
6528			    Lisp_Object edges
6529			      = calln (Qwindow_edges, Fcar (start_pos), Qt, Qnil, Qt);
6530			    int new_x = XFIXNUM (Fcar (frame_relative_event_pos));
6531			    int new_y = XFIXNUM (Fcdr (frame_relative_event_pos));
6532
6533			    /* If the up-event is outside the down-event's
6534			       window, use coordinates that are within it.  */
6535			    if (new_x < XFIXNUM (Fcar (edges)))
6536			      new_x = XFIXNUM (Fcar (edges));
6537			    else if (new_x >= XFIXNUM (Fcar (Fcdr (Fcdr (edges)))))
6538			      new_x = XFIXNUM (Fcar (Fcdr (Fcdr (edges)))) - 1;
6539			    if (new_y < XFIXNUM (Fcar (Fcdr (edges))))
6540			      new_y = XFIXNUM (Fcar (Fcdr (edges)));
6541			    else if (new_y
6542				     >= XFIXNUM (Fcar (Fcdr (Fcdr (Fcdr (edges))))))
6543			      new_y = XFIXNUM (Fcar (Fcdr (Fcdr (Fcdr (edges))))) - 1;
6544
6545			    position = make_lispy_position
6546			      (XFRAME (event->frame_or_window),
6547			       make_fixnum (new_x), make_fixnum (new_y),
6548			       event->timestamp);
6549			  }
6550		      }
6551
6552		    /* Don't check is_double; treat this as multiple if the
6553		       down-event was multiple.  */
6554		    event->modifiers
6555		      = ((event->modifiers & ~up_modifier)
6556			 | click_or_drag_modifier
6557			 | (double_click_count < 2 ? 0
6558			    : double_click_count == 2 ? double_modifier
6559			    : triple_modifier));
6560		  }
6561		else
6562		  /* Every mouse event should either have the down_modifier or
6563	             the up_modifier set.  */
6564		  emacs_abort ();
6565
6566		{
6567		  /* Get the symbol we should use for the mouse click.  */
6568		  Lisp_Object head;
6569
6570		  head = modify_event_symbol (button,
6571					      event->modifiers,
6572					      Qmouse_click, Vlispy_mouse_stem,
6573					      NULL,
6574					      &mouse_syms,
6575					      ASIZE (mouse_syms));
6576		  if (event->modifiers & drag_modifier)
6577		    return list3 (head, start_pos, position);
6578		  else if (event->modifiers & (double_modifier | triple_modifier))
6579		    return list3 (head, position, make_fixnum (double_click_count));
6580		  else
6581		    return list2 (head, position);
6582		}
6583	      }
6584
6585	    case WHEEL_EVENT:
6586	    case HORIZ_WHEEL_EVENT:
6587	      {
6588		Lisp_Object position;
6589		Lisp_Object head;
6590
6591		/* Build the position as appropriate for this mouse click.  */
6592		struct frame *f = XFRAME (event->frame_or_window);
6593
6594		/* Ignore wheel events that were made on frame that have been
6595		   deleted.  */
6596		if (! FRAME_LIVE_P (f))
6597		  return Qnil;
6598
6599		position = make_lispy_position (f, event->x, event->y,
6600						event->timestamp);
6601
6602		/* Set double or triple modifiers to indicate the wheel speed.  */
6603		{
6604		  /* On window-system frames, use the value of
6605		     double-click-fuzz as is.  On other frames, interpret it
6606		     as a multiple of 1/8 characters.  */
6607		  struct frame *fr;
6608		  intmax_t fuzz;
6609		  int symbol_num;
6610		  bool is_double;
6611
6612		  if (WINDOWP (event->frame_or_window))
6613		    fr = XFRAME (XWINDOW (event->frame_or_window)->frame);
6614		  else if (FRAMEP (event->frame_or_window))
6615		    fr = XFRAME (event->frame_or_window);
6616		  else
6617		    emacs_abort ();
6618
6619		  fuzz = FRAME_WINDOW_P (fr)
6620		    ? double_click_fuzz : double_click_fuzz / 8;
6621
6622		  if (event->modifiers & up_modifier)
6623		    {
6624		      /* Emit a wheel-up event.  */
6625		      event->modifiers &= ~up_modifier;
6626		      symbol_num = 0;
6627		    }
6628		  else if (event->modifiers & down_modifier)
6629		    {
6630		      /* Emit a wheel-down event.  */
6631		      event->modifiers &= ~down_modifier;
6632		      symbol_num = 1;
6633		    }
6634		  else
6635		    /* Every wheel event should either have the down_modifier or
6636		       the up_modifier set.  */
6637		    emacs_abort ();
6638
6639	          if (event->kind == HORIZ_WHEEL_EVENT)
6640	            symbol_num += 2;
6641
6642		  is_double = (last_mouse_button == - (1 + symbol_num)
6643			       && (eabs (XFIXNUM (event->x) - last_mouse_x) <= fuzz)
6644			       && (eabs (XFIXNUM (event->y) - last_mouse_y) <= fuzz)
6645			       && button_down_time != 0
6646			       && (EQ (Vdouble_click_time, Qt)
6647				   || (FIXNATP (Vdouble_click_time)
6648				       && (event->timestamp - button_down_time
6649					   < XFIXNAT (Vdouble_click_time)))));
6650		  if (is_double)
6651		    {
6652		      double_click_count++;
6653		      event->modifiers |= ((double_click_count > 2)
6654					   ? triple_modifier
6655					   : double_modifier);
6656		    }
6657		  else
6658		    {
6659		      double_click_count = 1;
6660		      event->modifiers |= click_modifier;
6661		    }
6662
6663		  button_down_time = event->timestamp;
6664		  /* Use a negative value to distinguish wheel from mouse button.  */
6665		  last_mouse_button = - (1 + symbol_num);
6666		  last_mouse_x = XFIXNUM (event->x);
6667		  last_mouse_y = XFIXNUM (event->y);
6668
6669		  /* Get the symbol we should use for the wheel event.  */
6670		  head = modify_event_symbol (symbol_num,
6671					      event->modifiers,
6672					      Qmouse_click,
6673					      Qnil,
6674					      lispy_wheel_names,
6675					      &wheel_syms,
6676					      ASIZE (wheel_syms));
6677		}
6678
6679		if (CONSP (event->arg))
6680		  return list5 (head, position, make_fixnum (double_click_count),
6681				XCAR (event->arg),
6682				/* FIXME: When a mouse-click on a tab-bar is
6683	                           converted into a wheel-event we get here something
6684	                           of an unexpected shape...  */
6685				(CONSP (XCDR (event->arg))
6686				 && CONSP (XCDR (XCDR (event->arg))))
6687				? Fcons (XCAR (XCDR (event->arg)),
6688				         XCAR (XCDR (XCDR (event->arg))))
6689				/* ... not knowing what this "unexpected shape" means,
6690				   we just use nil.  */
6691				: Qnil);
6692	        else if (NUMBERP (event->arg))
6693	          return list4 (head, position, make_fixnum (double_click_count),
6694	                        event->arg);
6695		else if (event->modifiers & (double_modifier | triple_modifier))
6696		  return list3 (head, position, make_fixnum (double_click_count));
6697		else
6698		  return list2 (head, position);
6699	      }
6700
6701	    case TOUCH_END_EVENT:
6702	      {
6703		Lisp_Object position;
6704
6705		/* Build the position as appropriate for this mouse click.  */
6706		struct frame *f = XFRAME (event->frame_or_window);
6707
6708		if (! FRAME_LIVE_P (f))
6709		  return Qnil;
6710
6711		position = make_lispy_position (f, event->x, event->y,
6712						event->timestamp);
6713
6714		return list2 (Qtouch_end, position);
6715	      }
6716
6717	    case TOUCHSCREEN_BEGIN_EVENT:
6718	      {
6719		Lisp_Object x, y, id, position;
6720		struct frame *f;
6721	#ifdef HAVE_WINDOW_SYSTEM
6722		int tab_bar_item;
6723		bool close;
6724	#endif /* HAVE_WINDOW_SYSTEM */
6725
6726		f = XFRAME (event->frame_or_window);
6727
6728		if (!FRAME_LIVE_P (f))
6729		  return Qnil;
6730
6731		id = event->arg;
6732		x = event->x;
6733		y = event->y;
6734
6735	#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
6736		if (coords_in_menu_bar_window (f, XFIXNUM (x), XFIXNUM (y)))
6737		  {
6738		    /* If the tap began in the menu bar window, then save the
6739		       id.  */
6740		    menu_bar_touch_id = id;
6741		    return Qnil;
6742		  }
6743	#endif /* defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR */
6744
6745		position = make_lispy_position (f, x, y, event->timestamp);
6746
6747	#ifdef HAVE_WINDOW_SYSTEM
6748
6749		/* Now check if POSITION lies on the tab bar.  If so, look up
6750		   the corresponding tab bar item's propertized string as the
6751		   OBJECT.  */
6752
6753		if (coords_in_tab_bar_window (f, XFIXNUM (event->x),
6754					      XFIXNUM (event->y))
6755		    /* `get_tab_bar_item_kbd' returns 0 if the item was
6756		       previously highlighted, 1 otherwise, and -1 if there is
6757		       no tab bar item.  */
6758		    && get_tab_bar_item_kbd (f, XFIXNUM (event->x),
6759					     XFIXNUM (event->y), &tab_bar_item,
6760					     &close) >= 0)
6761		  {
6762		    /* First, obtain the propertized string.  */
6763		    x = Fcopy_sequence (AREF (f->tab_bar_items,
6764					      (tab_bar_item
6765					       + TAB_BAR_ITEM_CAPTION)));
6766
6767		    /* Next, add the key binding.  */
6768		    AUTO_LIST2 (y, Qmenu_item, list3 (AREF (f->tab_bar_items,
6769							    (tab_bar_item
6770							     + TAB_BAR_ITEM_KEY)),
6771						      AREF (f->tab_bar_items,
6772							    (tab_bar_item
6773							     + TAB_BAR_ITEM_BINDING)),
6774						      close ? Qt : Qnil));
6775
6776		    /* And add the new properties to the propertized string.  */
6777		    Fadd_text_properties (make_fixnum (0),
6778					  make_fixnum (SCHARS (x)),
6779					  y, x);
6780
6781		    /* Set the position to 0.  */
6782		    x = Fcons (x, make_fixnum (0));
6783
6784		    /* Finally, add the OBJECT.  */
6785		    position = nconc2 (position, Fcons (x, Qnil));
6786		  }
6787
6788	#endif /* HAVE_WINDOW_SYSTEM */
6789
6790		return list2 (Qtouchscreen_begin,
6791			      Fcons (id, position));
6792	      }
6793
6794	    case TOUCHSCREEN_END_EVENT:
6795	      {
6796		Lisp_Object x, y, id, position;
6797		struct frame *f = XFRAME (event->frame_or_window);
6798	#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
6799		int column, row, dummy;
6800	#endif /* defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR */
6801	#ifdef HAVE_WINDOW_SYSTEM
6802		int tab_bar_item;
6803		bool close;
6804	#endif /* HAVE_WINDOW_SYSTEM */
6805
6806		if (!FRAME_LIVE_P (f))
6807		  return Qnil;
6808
6809		id = event->arg;
6810		x = event->x;
6811		y = event->y;
6812
6813	#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
6814		if (EQ (menu_bar_touch_id, id))
6815		  {
6816		    /* This touch should activate the menu bar.  Generate the
6817		       menu bar event.  */
6818		    menu_bar_touch_id = Qnil;
6819
6820		    if (!NILP (f->menu_bar_window))
6821		      {
6822			x_y_to_hpos_vpos (XWINDOW (f->menu_bar_window), XFIXNUM (x),
6823					  XFIXNUM (y), &column, &row, NULL, NULL,
6824					  &dummy);
6825
6826			if (row >= 0 && row < FRAME_MENU_BAR_LINES (f))
6827			  {
6828			    Lisp_Object items, item;
6829
6830			    /* Find the menu bar item under `column'.  */
6831			    item = Qnil;
6832			    items = FRAME_MENU_BAR_ITEMS (f);
6833			    for (i = 0; i < ASIZE (items); i += 4)
6834			      {
6835				Lisp_Object pos, string;
6836				string = AREF (items, i + 1);
6837				pos = AREF (items, i + 3);
6838				if (NILP (string))
6839				  break;
6840				if (column >= XFIXNUM (pos)
6841				    && column < XFIXNUM (pos) + SCHARS (string))
6842				  {
6843				    item = AREF (items, i);
6844				    break;
6845				  }
6846			      }
6847
6848			    /* Don't generate a menu bar event if ITEM is
6849			       nil.  */
6850			    if (NILP (item))
6851			      return Qnil;
6852
6853			    /* ELisp manual 2.4b says (x y) are window
6854			       relative but code says they are
6855			       frame-relative.  */
6856			    position = list4 (event->frame_or_window,
6857					      Qmenu_bar,
6858					      Fcons (event->x, event->y),
6859					      INT_TO_INTEGER (event->timestamp));
6860
6861			    return list2 (item, position);
6862			  }
6863		      }
6864
6865		    return Qnil;
6866		  }
6867	#endif /* defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR */
6868
6869		position = make_lispy_position (f, x, y, event->timestamp);
6870
6871	#ifdef HAVE_WINDOW_SYSTEM
6872
6873		/* Now check if POSITION lies on the tab bar.  If so, look up
6874		   the corresponding tab bar item's propertized string as the
6875		   OBJECT.  */
6876
6877		if (coords_in_tab_bar_window (f, XFIXNUM (event->x),
6878					      XFIXNUM (event->y))
6879		    /* `get_tab_bar_item_kbd' returns 0 if the item was
6880		       previously highlighted, 1 otherwise, and -1 if there is
6881		       no tab bar item.  */
6882		    && get_tab_bar_item_kbd (f, XFIXNUM (event->x),
6883					     XFIXNUM (event->y), &tab_bar_item,
6884					     &close) >= 0)
6885		  {
6886		    /* First, obtain the propertized string.  */
6887		    x = Fcopy_sequence (AREF (f->tab_bar_items,
6888					      (tab_bar_item
6889					       + TAB_BAR_ITEM_CAPTION)));
6890
6891		    /* Next, add the key binding.  */
6892		    AUTO_LIST2 (y, Qmenu_item, list3 (AREF (f->tab_bar_items,
6893							    (tab_bar_item
6894							     + TAB_BAR_ITEM_KEY)),
6895						      AREF (f->tab_bar_items,
6896							    (tab_bar_item
6897							     + TAB_BAR_ITEM_BINDING)),
6898						      close ? Qt : Qnil));
6899
6900		    /* And add the new properties to the propertized string.  */
6901		    Fadd_text_properties (make_fixnum (0),
6902					  make_fixnum (SCHARS (x)),
6903					  y, x);
6904
6905		    /* Set the position to 0.  */
6906		    x = Fcons (x, make_fixnum (0));
6907
6908		    /* Finally, add the OBJECT.  */
6909		    position = nconc2 (position, Fcons (x, Qnil));
6910		  }
6911
6912	#endif /* HAVE_WINDOW_SYSTEM */
6913
6914		position = make_lispy_position (f, x, y, event->timestamp);
6915
6916		return list3 (Qtouchscreen_end, Fcons (id, position),
6917			      event->modifiers ? Qt : Qnil);
6918	      }
6919
6920	    case PINCH_EVENT:
6921	      {
6922		Lisp_Object x, y, position;
6923		struct frame *f = XFRAME (event->frame_or_window);
6924
6925		x = event->x;
6926		y = event->y;
6927
6928		position = make_lispy_position (f, x, y, event->timestamp);
6929
6930		return Fcons (modify_event_symbol (0, event->modifiers, Qpinch,
6931						   Qnil, (const char *[]) {"pinch"},
6932						   &pinch_syms, 1),
6933			      Fcons (position, event->arg));
6934	      }
6935
6936	    case TOUCHSCREEN_UPDATE_EVENT:
6937	      {
6938		Lisp_Object x, y, id, position, tem, it, evt;
6939		struct frame *f = XFRAME (event->frame_or_window);
6940		evt = Qnil;
6941
6942		if (!FRAME_LIVE_P (f))
6943		  return Qnil;
6944
6945		for (tem = event->arg; CONSP (tem); tem = XCDR (tem))
6946		  {
6947		    it = XCAR (tem);
6948
6949		    x = XCAR (it);
6950		    y = XCAR (XCDR (it));
6951		    id = XCAR (XCDR (XCDR (it)));
6952
6953		    /* Don't report touches to the menu bar.  */
6954		    if (EQ (id, menu_bar_touch_id))
6955		      continue;
6956
6957		    position = make_lispy_position (f, x, y, event->timestamp);
6958		    evt = Fcons (Fcons (id, position), evt);
6959		  }
6960
6961		if (NILP (evt))
6962		  /* Don't return an event if the touchpoint list is
6963		     empty.  */
6964		  return Qnil;
6965
6966		return list2 (Qtouchscreen_update, evt);
6967	      }
6968
6969	#ifdef USE_TOOLKIT_SCROLL_BARS
6970
6971	      /* We don't have down and up events if using toolkit scroll bars,
6972		 so make this always a click event.  Store in the `part' of
6973		 the Lisp event a symbol which maps to the following actions:
6974
6975		 `above_handle'		page up
6976		 `below_handle'		page down
6977		 `up'			line up
6978		 `down'			line down
6979		 `top'			top of buffer
6980		 `bottom'		bottom of buffer
6981		 `handle'		thumb has been dragged.
6982		 `end-scroll'		end of interaction with scroll bar
6983
6984		 The incoming input_event contains in its `part' member an
6985		 index of type `enum scroll_bar_part' which we can use as an
6986		 index in scroll_bar_parts to get the appropriate symbol.  */
6987
6988	    case SCROLL_BAR_CLICK_EVENT:
6989	      {
6990		Lisp_Object position, head;
6991
6992		position = make_scroll_bar_position (event, Qvertical_scroll_bar);
6993
6994		/* Always treat scroll bar events as clicks.  */
6995		event->modifiers |= click_modifier;
6996		event->modifiers &= ~up_modifier;
6997
6998		if (event->code >= ASIZE (mouse_syms))
6999	          mouse_syms = larger_vector (mouse_syms,
7000					      event->code - ASIZE (mouse_syms) + 1,
7001					      -1);
7002
7003		/* Get the symbol we should use for the mouse click.  */
7004		head = modify_event_symbol (event->code,
7005					    event->modifiers,
7006					    Qmouse_click,
7007					    Vlispy_mouse_stem,
7008					    NULL, &mouse_syms,
7009					    ASIZE (mouse_syms));
7010		return list2 (head, position);
7011	      }
7012
7013	    case HORIZONTAL_SCROLL_BAR_CLICK_EVENT:
7014	      {
7015		Lisp_Object position, head;
7016
7017		position = make_scroll_bar_position (event, Qhorizontal_scroll_bar);
7018
7019		/* Always treat scroll bar events as clicks.  */
7020		event->modifiers |= click_modifier;
7021		event->modifiers &= ~up_modifier;
7022
7023		if (event->code >= ASIZE (mouse_syms))
7024	          mouse_syms = larger_vector (mouse_syms,
7025					      event->code - ASIZE (mouse_syms) + 1,
7026					      -1);
7027
7028		/* Get the symbol we should use for the mouse click.  */
7029		head = modify_event_symbol (event->code,
7030					    event->modifiers,
7031					    Qmouse_click,
7032					    Vlispy_mouse_stem,
7033					    NULL, &mouse_syms,
7034					    ASIZE (mouse_syms));
7035		return list2 (head, position);
7036	      }
7037
7038	#endif /* USE_TOOLKIT_SCROLL_BARS */
7039
7040	    case DRAG_N_DROP_EVENT:
7041	      {
7042		struct frame *f;
7043		Lisp_Object head, position;
7044		Lisp_Object files;
7045
7046		f = XFRAME (event->frame_or_window);
7047		files = event->arg;
7048
7049		/* Ignore mouse events that were made on frames that
7050		   have been deleted.  */
7051		if (! FRAME_LIVE_P (f))
7052		  return Qnil;
7053
7054		position = make_lispy_position (f, event->x, event->y,
7055						event->timestamp);
7056
7057		head = modify_event_symbol (0, event->modifiers,
7058					    Qdrag_n_drop, Qnil,
7059					    lispy_drag_n_drop_names,
7060					    &drag_n_drop_syms, 1);
7061		return list3 (head, position, files);
7062	      }
7063
7064	#ifdef HAVE_EXT_MENU_BAR
7065	    case MENU_BAR_EVENT:
7066	      if (EQ (event->arg, event->frame_or_window))
7067		/* This is the prefix key.  We translate this to
7068		   `(menu_bar)' because the code in keyboard.c for menu
7069		   events, which we use, relies on this.  */
7070		return list1 (Qmenu_bar);
7071	      return event->arg;
7072	#endif
7073
7074	    case SELECT_WINDOW_EVENT:
7075	      /* Make an event (select-window (WINDOW)).  */
7076	      return list2 (Qselect_window, list1 (event->frame_or_window));
7077
7078	    case TAB_BAR_EVENT:
7079	    case TOOL_BAR_EVENT:
7080	      {
7081		Lisp_Object res = event->arg;
7082		Lisp_Object location
7083		  = event->kind == TAB_BAR_EVENT ? Qtab_bar : Qtool_bar;
7084		if (SYMBOLP (res)) res = apply_modifiers (event->modifiers, res);
7085		return list2 (res, list2 (event->frame_or_window, location));
7086	      }
7087
7088	    case USER_SIGNAL_EVENT:
7089	      /* A user signal.  */
7090	      {
7091		char *name = find_user_signal_name (event->code);
7092		if (!name)
7093		  emacs_abort ();
7094		return intern (name);
7095	      }
7096
7097	    case SAVE_SESSION_EVENT:
7098	      return list2 (Qsave_session, event->arg);
7099
7100	#ifdef HAVE_DBUS
7101	    case DBUS_EVENT:
7102	      return Fcons (Qdbus_event, event->arg);
7103	#endif /* HAVE_DBUS */
7104
7105	#ifdef THREADS_ENABLED
7106	    case THREAD_EVENT:
7107	      return Fcons (Qthread_event, event->arg);
7108	#endif /* THREADS_ENABLED */
7109
7110	#ifdef HAVE_XWIDGETS
7111	    case XWIDGET_EVENT:
7112	      return Fcons (Qxwidget_event, event->arg);
7113
7114	    case XWIDGET_DISPLAY_EVENT:
7115	      return Fcons (Qxwidget_display_event, event->arg);
7116	#endif
7117
7118	#ifdef USE_FILE_NOTIFY
7119	    case FILE_NOTIFY_EVENT:
7120	#ifdef HAVE_W32NOTIFY
7121	      /* Make an event (file-notify (DESCRIPTOR ACTION FILE) CALLBACK).  */
7122	      return list3 (Qfile_notify, event->arg, event->frame_or_window);
7123	#else
7124	      return Fcons (Qfile_notify, event->arg);
7125	#endif
7126	#endif /* USE_FILE_NOTIFY */
7127
7128	    case CONFIG_CHANGED_EVENT:
7129		return list3 (Qconfig_changed_event,
7130			      event->arg, event->frame_or_window);
7131
7132	    case PREEDIT_TEXT_EVENT:
7133	      return list2 (Qpreedit_text, event->arg);
7134
7135	      /* The 'kind' field of the event is something we don't recognize.  */
7136	    default:
7137	      emacs_abort ();
7138	    }
7139	}
7140
7141	static Lisp_Object
7142	make_lispy_movement (struct frame *frame, Lisp_Object bar_window, enum scroll_bar_part part,
7143			     Lisp_Object x, Lisp_Object y, Time t)
7144	{
7145	  /* Is it a scroll bar movement?  */
7146	  if (frame && ! NILP (bar_window))
   0x000055555577c3b2 <+15202>:	test   %rbx,%rbx
   0x000055555577c3b5 <+15205>:	jne    0x55555577a0da <read_char+6282>
   0x000055555577c3bb <+15211>:	jmp    0x55555577bc05 <read_char+13237>

./src/lisp.h:
1831	  return VECTORLIKEP (x) && ! (ASIZE (x) & PSEUDOVECTOR_FLAG);
   0x000055555577c3c0 <+15216>:	mov    %r15,%rdi
   0x000055555577c3c3 <+15219>:	call   0x555555763340 <ASIZE>
   0x000055555577c3c8 <+15224>:	bt     $0x3e,%rax
   0x000055555577c3cd <+15229>:	jb     0x55555577c44e <read_char+15358>

./src/keyboard.c:
3125		      && XFIXNAT (c) < ASIZE (KVAR (current_kboard,
   0x000055555577c3cf <+15231>:	mov    %r14,%rdi
   0x000055555577c3d2 <+15234>:	call   0x555555763380 <XFIXNAT>
   0x000055555577c3d7 <+15239>:	mov    -0x5a0(%rbp),%rdi
   0x000055555577c3de <+15246>:	mov    %rax,-0x5b0(%rbp)
   0x000055555577c3e5 <+15253>:	mov    0x20(%rdi),%rdi
   0x000055555577c3e9 <+15257>:	call   0x555555763340 <ASIZE>
   0x000055555577c3ee <+15262>:	cmp    %rax,-0x5b0(%rbp)
   0x000055555577c3f5 <+15269>:	jge    0x55555577c44e <read_char+15358>

3126						    Vkeyboard_translate_table)))
3127		  || (CHAR_TABLE_P (KVAR (current_kboard, Vkeyboard_translate_table))
3128		      && CHARACTERP (c)))
3129		{
3130		  Lisp_Object d;
3131		  d = Faref (KVAR (current_kboard, Vkeyboard_translate_table), c);
   0x000055555577c3f7 <+15271>:	mov    -0x5a0(%rbp),%rax
   0x000055555577c3fe <+15278>:	mov    %r14,%rsi
   0x000055555577c401 <+15281>:	mov    0x20(%rax),%rdi
   0x000055555577c405 <+15285>:	call   0x5555558046f0 <Faref>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577c40a <+15290>:	test   %rax,%rax
   0x000055555577c40d <+15293>:	je     0x55555577b506 <read_char+11446>

./src/keyboard.c:
3134		    c_volatile = c = d;
   0x000055555577c413 <+15299>:	mov    %rax,-0x470(%rbp)
   0x000055555577c41a <+15306>:	mov    %rax,%r14

./src/lisp.h:
774	  return lisp_h_TAGGEDP (a, tag);
   0x000055555577c41d <+15309>:	mov    %eax,%r13d
   0x000055555577c420 <+15312>:	mov    %rax,%rbx
   0x000055555577c423 <+15315>:	jmp    0x55555577b506 <read_char+11446>

./src/keyboard.c:
3122		   && XFIXNAT (c) < SCHARS (KVAR (current_kboard,
   0x000055555577c428 <+15320>:	mov    %r14,%rdi
   0x000055555577c42b <+15323>:	call   0x555555763380 <XFIXNAT>
   0x000055555577c430 <+15328>:	mov    %r15,%rdi
   0x000055555577c433 <+15331>:	mov    %rax,-0x5a8(%rbp)
   0x000055555577c43a <+15338>:	call   0x555555763300 <SCHARS>
   0x000055555577c43f <+15343>:	cmp    %rax,-0x5a8(%rbp)
   0x000055555577c446 <+15350>:	jge    0x55555577b4fa <read_char+11434>
   0x000055555577c44c <+15356>:	jmp    0x55555577c3f7 <read_char+15271>

./src/lisp.h:
1098		       & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
   0x000055555577c44e <+15358>:	movabs $0x400000003f000000,%rax
   0x000055555577c458 <+15368>:	and    0x3(%r15),%rax

1097		  && ((XUNTAG (a, Lisp_Vectorlike, struct vectorlike_header)->size
   0x000055555577c45c <+15372>:	movabs $0x4000000022000000,%rdx
   0x000055555577c466 <+15382>:	cmp    %rdx,%rax
   0x000055555577c469 <+15385>:	jne    0x55555577b506 <read_char+11446>

./src/character.h:
161	  return 0 <= c && c <= MAX_CHAR;
   0x000055555577c46f <+15391>:	cmpq   $0x3fffff,-0x5c0(%rbp)
   0x000055555577c47a <+15402>:	jbe    0x55555577c3f7 <read_char+15271>
   0x000055555577c480 <+15408>:	jmp    0x55555577b506 <read_char+11446>

./src/keyboard.c:
2451			  for (i = 0; i < n; i++)
   0x000055555577c485 <+15413>:	xor    %esi,%esi
   0x000055555577c487 <+15415>:	jmp    0x55555577b1d4 <read_char+10628>

2423		  events[n++] = nextevt;
   0x000055555577c48c <+15420>:	mov    $0x10,%ebx
   0x000055555577c491 <+15425>:	jmp    0x55555577a699 <read_char+7753>

4343			      || XFLOAT_DATA (XCAR (XCDR (event->ie.arg))) != 0.0
   0x000055555577c496 <+15430>:	mov    %rbx,%rdi
   0x000055555577c499 <+15433>:	mov    %r8,-0x5f0(%rbp)
   0x000055555577c4a0 <+15440>:	call   0x5555557630d0 <XCDR>
   0x000055555577c4a5 <+15445>:	mov    %rax,%rdi
   0x000055555577c4a8 <+15448>:	call   0x555555763090 <XCAR>
   0x000055555577c4ad <+15453>:	mov    %rax,%rdi

./src/lisp.h:
3436	  return XFLOAT (f)->u.data;
   0x000055555577c4b0 <+15456>:	call   0x555555762b70 <XFLOAT>

./src/keyboard.c:
4343			      || XFLOAT_DATA (XCAR (XCDR (event->ie.arg))) != 0.0
   0x000055555577c4b5 <+15461>:	pxor   %xmm6,%xmm6
   0x000055555577c4b9 <+15465>:	mov    -0x5f0(%rbp),%r8

./src/lisp.h:
3436	  return XFLOAT (f)->u.data;
   0x000055555577c4c0 <+15472>:	movsd  0x10(%rax),%xmm0

./src/keyboard.c:
4343			      || XFLOAT_DATA (XCAR (XCDR (event->ie.arg))) != 0.0
   0x000055555577c4c5 <+15477>:	ucomisd %xmm6,%xmm0
   0x000055555577c4c9 <+15481>:	jp     0x55555577b6e2 <read_char+11922>
   0x000055555577c4cf <+15487>:	jne    0x55555577b6e2 <read_char+11922>

4344			      || XFLOAT_DATA (Fnth (make_fixnum (3), event->ie.arg)) != 0.0))
   0x000055555577c4d5 <+15493>:	mov    %rbx,%rsi
   0x000055555577c4d8 <+15496>:	mov    $0xe,%edi
   0x000055555577c4dd <+15501>:	mov    %r8,-0x5f8(%rbp)

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577c4e4 <+15508>:	call   0x55555582c7d0 <Fnth>
   0x000055555577c4e9 <+15513>:	mov    %rax,%rdi

3431	}
3432
3433	INLINE double
3434	XFLOAT_DATA (Lisp_Object f)
3435	{
3436	  return XFLOAT (f)->u.data;
   0x000055555577c4ec <+15516>:	call   0x555555762b70 <XFLOAT>

./src/keyboard.c:
4344			      || XFLOAT_DATA (Fnth (make_fixnum (3), event->ie.arg)) != 0.0))
   0x000055555577c4f1 <+15521>:	pxor   %xmm1,%xmm1
   0x000055555577c4f5 <+15525>:	mov    -0x5f8(%rbp),%r8

./src/lisp.h:
3436	  return XFLOAT (f)->u.data;
   0x000055555577c4fc <+15532>:	movsd  0x10(%rax),%xmm0

./src/keyboard.c:
4344			      || XFLOAT_DATA (Fnth (make_fixnum (3), event->ie.arg)) != 0.0))
   0x000055555577c501 <+15537>:	ucomisd %xmm1,%xmm0
   0x000055555577c505 <+15541>:	jp     0x55555577b6e2 <read_char+11922>
   0x000055555577c50b <+15547>:	je     0x55555577bf0a <read_char+14010>
   0x000055555577c511 <+15553>:	jmp    0x55555577b6e2 <read_char+11922>

438	  return XCAR (XCDR (event));
   0x000055555577c516 <+15558>:	mov    %r14,%rdi
   0x000055555577c519 <+15561>:	call   0x5555557630d0 <XCDR>
   0x000055555577c51e <+15566>:	mov    %rax,%rdi
   0x000055555577c521 <+15569>:	call   0x555555763090 <XCAR>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577c526 <+15574>:	sub    $0x3,%eax

./src/keyboard.c:
3143	      && CONSP (xevent_start (c))
   0x000055555577c529 <+15577>:	test   $0x7,%al
   0x000055555577c52b <+15579>:	jne    0x55555577b523 <read_char+11475>

438	  return XCAR (XCDR (event));
   0x000055555577c531 <+15585>:	mov    %r14,%rdi
   0x000055555577c534 <+15588>:	call   0x5555557630d0 <XCDR>
   0x000055555577c539 <+15593>:	mov    %rax,%rdi
   0x000055555577c53c <+15596>:	call   0x555555763090 <XCAR>
   0x000055555577c541 <+15601>:	mov    %rax,%rdi

3144	      && CONSP (XCDR (xevent_start (c))))
   0x000055555577c544 <+15604>:	call   0x5555557630d0 <XCDR>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577c549 <+15609>:	sub    $0x3,%eax

./src/keyboard.c:
3144	      && CONSP (XCDR (xevent_start (c))))
   0x000055555577c54c <+15612>:	test   $0x7,%al
   0x000055555577c54e <+15614>:	jne    0x55555577b523 <read_char+11475>

438	  return XCAR (XCDR (event));
   0x000055555577c554 <+15620>:	mov    %r14,%rdi
   0x000055555577c557 <+15623>:	call   0x5555557630d0 <XCDR>
   0x000055555577c55c <+15628>:	mov    %rax,%rdi
   0x000055555577c55f <+15631>:	call   0x555555763090 <XCAR>
   0x000055555577c564 <+15636>:	mov    %rax,%rdi

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577c567 <+15639>:	lea    -0x3(%rax),%eax

1593	}
1594	INLINE Lisp_Object
1595	CDR_SAFE (Lisp_Object c)
1596	{
1597	  return CONSP (c) ? XCDR (c) : Qnil;
   0x000055555577c56a <+15642>:	test   $0x7,%al
   0x000055555577c56c <+15644>:	je     0x55555577cb9d <read_char+17229>

1184	  return a;
   0x000055555577c572 <+15650>:	mov    $0xf148,%esi
   0x000055555577c577 <+15655>:	mov    %r12,%rdi
   0x000055555577c57a <+15658>:	mov    %r12,%r13

./src/keyboard.c:
3151	      if (EQ (posn, Qmenu_bar) || EQ (posn, Qtab_bar) || EQ (posn, Qtool_bar))
   0x000055555577c57d <+15661>:	call   0x555555764470 <EQ>
   0x000055555577c582 <+15666>:	test   %al,%al
   0x000055555577c584 <+15668>:	jne    0x55555577c59b <read_char+15691>

./src/lisp.h:
1184	  return a;
   0x000055555577c586 <+15670>:	mov    $0x14b30,%esi
   0x000055555577c58b <+15675>:	mov    %r12,%rdi
   0x000055555577c58e <+15678>:	call   0x555555764470 <EQ>

./src/keyboard.c:
3151	      if (EQ (posn, Qmenu_bar) || EQ (posn, Qtab_bar) || EQ (posn, Qtool_bar))
   0x000055555577c593 <+15683>:	test   %al,%al
   0x000055555577c595 <+15685>:	je     0x55555577d060 <read_char+18448>

3152		{
3153		  /* Change menu-bar to (menu-bar) as the event "position".  */
3154		  POSN_SET_POSN (xevent_start (c), list1 (posn));
   0x000055555577c59b <+15691>:	mov    %r13,%rdi
   0x000055555577c59e <+15694>:	call   0x5555557ef5c0 <list1>

438	  return XCAR (XCDR (event));
   0x000055555577c5a3 <+15699>:	mov    %r14,%rdi

3152		{
3153		  /* Change menu-bar to (menu-bar) as the event "position".  */
3154		  POSN_SET_POSN (xevent_start (c), list1 (posn));
   0x000055555577c5a6 <+15702>:	mov    %rax,%rbx

438	  return XCAR (XCDR (event));
   0x000055555577c5a9 <+15705>:	call   0x5555557630d0 <XCDR>
   0x000055555577c5ae <+15710>:	mov    %rax,%rdi
   0x000055555577c5b1 <+15713>:	call   0x555555763090 <XCAR>
   0x000055555577c5b6 <+15718>:	mov    %rax,%rdi

3152		{
3153		  /* Change menu-bar to (menu-bar) as the event "position".  */
3154		  POSN_SET_POSN (xevent_start (c), list1 (posn));
   0x000055555577c5b9 <+15721>:	call   0x5555557630d0 <XCDR>
   0x000055555577c5be <+15726>:	mov    %rbx,%rsi
   0x000055555577c5c1 <+15729>:	mov    %rax,%rdi
   0x000055555577c5c4 <+15732>:	call   0x5555557630b0 <XSETCAR>

3155
3156		  /* Should a command call `sit-for', or another command that
3157		     provides a timespec to Fread_event and co., the original
3158		     event will not subsequently be entered into
3159		     this_command_keys unless Qt be specified below.
3160
3161		     The same is the case in a number of other scenarios where
3162		     reread is true, but if so, event recording is to be
3163		     suppressed anyway.  */
3164
3165		  if (end_time)
   0x000055555577c5c9 <+15737>:	cmpq   $0x0,-0x4a8(%rbp)
   0x000055555577c5d1 <+15745>:	je     0x55555577d07a <read_char+18474>

./src/lisp.h:
1184	  return a;
   0x000055555577c5d7 <+15751>:	mov    %r14,%rsi
   0x000055555577c5da <+15754>:	mov    $0x38,%edi
   0x000055555577c5df <+15759>:	call   0x5555557ef2b0 <Fcons>
   0x000055555577c5e4 <+15764>:	mov    0x3a4a8d(%rip),%rsi        # 0x555555b21078 <globals+3128>
   0x000055555577c5eb <+15771>:	mov    %rax,%rdi
   0x000055555577c5ee <+15774>:	call   0x5555557ef2b0 <Fcons>
   0x000055555577c5f3 <+15779>:	mov    %rax,0x3a4a7e(%rip)        # 0x555555b21078 <globals+3128>

./src/keyboard.c:
3173		  c = posn;
   0x000055555577c5fa <+15786>:	mov    %r12,-0x470(%rbp)
   0x000055555577c601 <+15793>:	mov    %r12,%r14

3174		  c_volatile = c;
   0x000055555577c604 <+15796>:	mov    %r12,%rbx
   0x000055555577c607 <+15799>:	jmp    0x55555577b523 <read_char+11475>

2928		  EMACS_INT timeout = XFIXNAT (Vauto_save_timeout);
   0x000055555577c60c <+15804>:	call   0x555555763380 <XFIXNAT>

2929
2930		  timeout = min (timeout, MOST_POSITIVE_FIXNUM / delay_level * 4);
   0x000055555577c611 <+15809>:	movslq %r12d,%rcx

2932		  specpdl_ref count1 = SPECPDL_INDEX ();
2933		  save_getcjmp (save_jump);
2934		  record_unwind_protect_ptr (restore_getcjmp, save_jump);
   0x000055555577c614 <+15812>:	lea    -0x198db(%rip),%rdi        # 0x555555762d40 <restore_getcjmp>

2928		  EMACS_INT timeout = XFIXNAT (Vauto_save_timeout);
   0x000055555577c61b <+15819>:	mov    %rax,%rsi

2931		  timeout = delay_level * timeout / 4;
   0x000055555577c61e <+15822>:	movabs $0x1fffffffffffffff,%rax

2930		  timeout = min (timeout, MOST_POSITIVE_FIXNUM / delay_level * 4);
   0x000055555577c628 <+15832>:	cqto
   0x000055555577c62a <+15834>:	idiv   %rcx

./src/lisp.h:
3986	  return wrap_specpdl_ref ((char *)specpdl_ptr - (char *)specpdl);
   0x000055555577c62d <+15837>:	mov    0x30b32c(%rip),%rdx        # 0x555555a87960 <current_thread>

/usr/include/x86_64-linux-gnu/bits/string_fortified.h:
29	  return __builtin___memcpy_chk (__dest, __src, __len,
   0x000055555577c634 <+15844>:	movdqu 0xd8(%rdx),%xmm6

./src/lisp.h:
3986	  return wrap_specpdl_ref ((char *)specpdl_ptr - (char *)specpdl);
   0x000055555577c63c <+15852>:	mov    0x88(%rdx),%r13

/usr/include/x86_64-linux-gnu/bits/string_fortified.h:
29	  return __builtin___memcpy_chk (__dest, __src, __len,
   0x000055555577c643 <+15859>:	movdqu 0xe8(%rdx),%xmm2
   0x000055555577c64b <+15867>:	movdqu 0xf8(%rdx),%xmm3
   0x000055555577c653 <+15875>:	movdqu 0x108(%rdx),%xmm7
   0x000055555577c65b <+15883>:	movdqu 0x128(%rdx),%xmm1
   0x000055555577c663 <+15891>:	movdqu 0x168(%rdx),%xmm4
   0x000055555577c66b <+15899>:	movdqu 0x178(%rdx),%xmm5

./src/keyboard.c:
2930		  timeout = min (timeout, MOST_POSITIVE_FIXNUM / delay_level * 4);
   0x000055555577c673 <+15907>:	shl    $0x2,%rax
   0x000055555577c677 <+15911>:	cmp    %rsi,%rax
   0x000055555577c67a <+15914>:	cmovg  %rsi,%rax

/usr/include/x86_64-linux-gnu/bits/string_fortified.h:
29	  return __builtin___memcpy_chk (__dest, __src, __len,
   0x000055555577c67e <+15918>:	lea    -0x240(%rbp),%rsi

./src/keyboard.c:
2931		  timeout = delay_level * timeout / 4;
   0x000055555577c685 <+15925>:	imul   %rcx,%rax
   0x000055555577c689 <+15929>:	test   %rax,%rax
   0x000055555577c68c <+15932>:	lea    0x3(%rax),%r12
   0x000055555577c690 <+15936>:	cmovns %rax,%r12

./src/lisp.h:
3986	  return wrap_specpdl_ref ((char *)specpdl_ptr - (char *)specpdl);
   0x000055555577c694 <+15940>:	sub    0x78(%rdx),%r13

/usr/include/x86_64-linux-gnu/bits/string_fortified.h:
29	  return __builtin___memcpy_chk (__dest, __src, __len,
   0x000055555577c698 <+15944>:	movaps %xmm6,-0x240(%rbp)
   0x000055555577c69f <+15951>:	movdqu 0x118(%rdx),%xmm6
   0x000055555577c6a7 <+15959>:	mov    0x198(%rdx),%rax
   0x000055555577c6ae <+15966>:	movaps %xmm2,-0x230(%rbp)
   0x000055555577c6b5 <+15973>:	movdqu 0x138(%rdx),%xmm2
   0x000055555577c6bd <+15981>:	movaps %xmm3,-0x220(%rbp)
   0x000055555577c6c4 <+15988>:	movdqu 0x148(%rdx),%xmm3

./src/keyboard.c:
2931		  timeout = delay_level * timeout / 4;
   0x000055555577c6cc <+15996>:	sar    $0x2,%r12

/usr/include/x86_64-linux-gnu/bits/string_fortified.h:
29	  return __builtin___memcpy_chk (__dest, __src, __len,
   0x000055555577c6d0 <+16000>:	movaps %xmm7,-0x210(%rbp)
   0x000055555577c6d7 <+16007>:	movdqu 0x158(%rdx),%xmm7
   0x000055555577c6df <+16015>:	movaps %xmm6,-0x200(%rbp)
   0x000055555577c6e6 <+16022>:	movdqu 0x188(%rdx),%xmm6
   0x000055555577c6ee <+16030>:	mov    %rax,-0x180(%rbp)

./src/keyboard.c:
2934		  record_unwind_protect_ptr (restore_getcjmp, save_jump);
   0x000055555577c6f5 <+16037>:	movaps %xmm1,-0x1f0(%rbp)
   0x000055555577c6fc <+16044>:	movaps %xmm2,-0x1e0(%rbp)
   0x000055555577c703 <+16051>:	movaps %xmm3,-0x1d0(%rbp)
   0x000055555577c70a <+16058>:	movaps %xmm7,-0x1c0(%rbp)
   0x000055555577c711 <+16065>:	movaps %xmm4,-0x1b0(%rbp)
   0x000055555577c718 <+16072>:	movaps %xmm5,-0x1a0(%rbp)
   0x000055555577c71f <+16079>:	movaps %xmm6,-0x190(%rbp)
   0x000055555577c726 <+16086>:	call   0x5555558201a0 <record_unwind_protect_ptr>

/usr/include/x86_64-linux-gnu/bits/string_fortified.h:
29	  return __builtin___memcpy_chk (__dest, __src, __len,
   0x000055555577c72b <+16091>:	mov    0x30b22e(%rip),%rdx        # 0x555555a87960 <current_thread>
   0x000055555577c732 <+16098>:	movdqa -0x310(%rbp),%xmm1

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577c73a <+16106>:	lea    0x2(,%r12,4),%rdi

/usr/include/x86_64-linux-gnu/bits/string_fortified.h:
29	  return __builtin___memcpy_chk (__dest, __src, __len,
   0x000055555577c742 <+16114>:	movdqa -0x300(%rbp),%xmm2

./src/keyboard.c:
2936		  tem0 = sit_for (make_fixnum (timeout), 1, 1);
   0x000055555577c74a <+16122>:	mov    $0x1,%esi

/usr/include/x86_64-linux-gnu/bits/string_fortified.h:
29	  return __builtin___memcpy_chk (__dest, __src, __len,
   0x000055555577c74f <+16127>:	movups %xmm1,0xd8(%rdx)
   0x000055555577c756 <+16134>:	movdqa -0x2f0(%rbp),%xmm3
   0x000055555577c75e <+16142>:	lea    0xd8(%rdx),%rax
   0x000055555577c765 <+16149>:	movups %xmm2,0xe8(%rdx)
   0x000055555577c76c <+16156>:	movdqa -0x2e0(%rbp),%xmm7
   0x000055555577c774 <+16164>:	movups %xmm3,0xf8(%rdx)
   0x000055555577c77b <+16171>:	movdqa -0x2d0(%rbp),%xmm4
   0x000055555577c783 <+16179>:	movups %xmm7,0x108(%rdx)
   0x000055555577c78a <+16186>:	movdqa -0x2c0(%rbp),%xmm5
   0x000055555577c792 <+16194>:	movups %xmm4,0x118(%rdx)
   0x000055555577c799 <+16201>:	movdqa -0x2b0(%rbp),%xmm6
   0x000055555577c7a1 <+16209>:	movups %xmm5,0x128(%rdx)
   0x000055555577c7a8 <+16216>:	movdqa -0x2a0(%rbp),%xmm1
   0x000055555577c7b0 <+16224>:	movups %xmm6,0x138(%rdx)
   0x000055555577c7b7 <+16231>:	movdqa -0x290(%rbp),%xmm2
   0x000055555577c7bf <+16239>:	movups %xmm1,0x148(%rdx)
   0x000055555577c7c6 <+16246>:	movdqa -0x280(%rbp),%xmm3
   0x000055555577c7ce <+16254>:	movups %xmm2,0x158(%rdx)
   0x000055555577c7d5 <+16261>:	movdqa -0x270(%rbp),%xmm7
   0x000055555577c7dd <+16269>:	movups %xmm3,0x168(%rdx)
   0x000055555577c7e4 <+16276>:	movdqa -0x260(%rbp),%xmm4
   0x000055555577c7ec <+16284>:	movups %xmm7,0x178(%rdx)
   0x000055555577c7f3 <+16291>:	movups %xmm4,0x188(%rdx)
   0x000055555577c7fa <+16298>:	mov    -0x250(%rbp),%rdx
   0x000055555577c801 <+16305>:	mov    %rdx,0xc0(%rax)

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577c808 <+16312>:	mov    $0x1,%edx
   0x000055555577c80d <+16317>:	call   0x5555555e5750 <sit_for>

./src/keyboard.c:
2937		  unbind_to (count1, Qnil);
   0x000055555577c812 <+16322>:	xor    %esi,%esi
   0x000055555577c814 <+16324>:	mov    %r13,%rdi

2936		  tem0 = sit_for (make_fixnum (timeout), 1, 1);
   0x000055555577c817 <+16327>:	mov    %rax,%r12

./src/lisp.h:
1184	  return a;
   0x000055555577c81a <+16330>:	call   0x5555558204b0 <unbind_to>
   0x000055555577c81f <+16335>:	mov    $0x38,%esi

./src/keyboard.c:
2939		  if (EQ (tem0, Qt)
   0x000055555577c824 <+16340>:	mov    %r12,%rdi
   0x000055555577c827 <+16343>:	call   0x555555764470 <EQ>
   0x000055555577c82c <+16348>:	test   %al,%al
   0x000055555577c82e <+16350>:	je     0x55555577934a <read_char+2810>

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577c834 <+16356>:	mov    0x3a483e(%rip),%eax        # 0x555555b21078 <globals+3128>
   0x000055555577c83a <+16362>:	sub    $0x3,%eax

./src/keyboard.c:
2940		      && ! CONSP (Vunread_command_events))
   0x000055555577c83d <+16365>:	test   $0x7,%al
   0x000055555577c83f <+16367>:	je     0x55555577934a <read_char+2810>

./src/lisp.h:
1184	  return a;
   0x000055555577c845 <+16373>:	cmpb   $0x0,0x3a4d40(%rip)        # 0x555555b2158c <globals+4428>
   0x000055555577c84c <+16380>:	mov    $0x38,%eax
   0x000055555577c851 <+16385>:	cmovne %rax,%rbx
   0x000055555577c855 <+16389>:	xor    %esi,%esi
   0x000055555577c857 <+16391>:	mov    %rbx,%rdi
   0x000055555577c85a <+16394>:	call   0x5555557bf870 <Fdo_auto_save>

./src/keyboard.c:
2943		      redisplay ();
   0x000055555577c85f <+16399>:	call   0x55555564ed30 <redisplay>
   0x000055555577c864 <+16404>:	jmp    0x55555577934a <read_char+2810>

3296		  goto retry;
3297		}
3298	      /* It returned one event or more.  */
3299	      c = XCAR (tem);
   0x000055555577c869 <+16409>:	mov    %rdx,%rdi
   0x000055555577c86c <+16412>:	mov    %rdx,-0x690(%rbp)
   0x000055555577c873 <+16419>:	call   0x555555763090 <XCAR>

3302		= nconc2 (XCDR (tem), Vunread_post_input_method_events);
   0x000055555577c878 <+16424>:	mov    -0x690(%rbp),%rdi

3300	      c_volatile = c;
   0x000055555577c87f <+16431>:	mov    %rax,-0x470(%rbp)

3299	      c = XCAR (tem);
   0x000055555577c886 <+16438>:	mov    %rax,%r14

3301	      Vunread_post_input_method_events
   0x000055555577c889 <+16441>:	call   0x5555557630d0 <XCDR>
   0x000055555577c88e <+16446>:	mov    0x3a47f3(%rip),%rsi        # 0x555555b21088 <globals+3144>
   0x000055555577c895 <+16453>:	mov    %rax,%rdi
   0x000055555577c898 <+16456>:	call   0x555555839ba0 <nconc2>
   0x000055555577c89d <+16461>:	mov    %rax,0x3a47e4(%rip)        # 0x555555b21088 <globals+3144>

3302		= nconc2 (XCDR (tem), Vunread_post_input_method_events);
   0x000055555577c8a4 <+16468>:	jmp    0x5555557789dd <read_char+397>
   0x000055555577c8a9 <+16473>:	mov    %rdx,-0x688(%rbp)

3288		echo_now ();
   0x000055555577c8b0 <+16480>:	call   0x555555767ae0 <echo_now>
   0x000055555577c8b5 <+16485>:	mov    -0x688(%rbp),%rdx
   0x000055555577c8bc <+16492>:	jmp    0x55555577b09e <read_char+10318>

2467			      const unsigned char *p = coding->destination;
   0x000055555577c8c1 <+16497>:	mov    0x1f0(%r10),%rcx
   0x000055555577c8c8 <+16504>:	mov    %ebx,%r12d

2468			      eassert (coding->carryover_bytes == 0);
   0x000055555577c8cb <+16507>:	test   %sil,%sil
   0x000055555577c8ce <+16510>:	jne    0x55555577c8de <read_char+16526>
   0x000055555577c8d0 <+16512>:	cmpl   $0x0,0x248(%r10)
   0x000055555577c8d8 <+16520>:	jne    0x5555555b276a <read_char.cold>

2469			      n = 0;
2470			      while (n < coding->produced_char)
   0x000055555577c8de <+16526>:	mov    $0x1,%ebx
   0x000055555577c8e3 <+16531>:	test   %rdi,%rdi
   0x000055555577c8e6 <+16534>:	jg     0x55555577c983 <read_char+16691>
   0x000055555577c8ec <+16540>:	jmp    0x55555577cb96 <read_char+17222>
   0x000055555577c8f1 <+16545>:	nopl   0x0(%rax)

./src/character.h:
380	  eassume (0xC0 <= c);
   0x000055555577c8f8 <+16552>:	test   %sil,%sil
   0x000055555577c8fb <+16555>:	jne    0x55555577c908 <read_char+16568>
   0x000055555577c8fd <+16557>:	cmp    $0xbf,%eax
   0x000055555577c902 <+16562>:	jle    0x5555555b2782 <read_char-1859790>

381
382	  int d = (c << 6) + p[1] - ((0xC0 << 6) + 0x80);
   0x000055555577c908 <+16568>:	movzbl 0x1(%rcx),%edx
   0x000055555577c90c <+16572>:	mov    %eax,%r9d
   0x000055555577c90f <+16575>:	shl    $0x6,%r9d
   0x000055555577c913 <+16579>:	add    %edx,%r9d
   0x000055555577c916 <+16582>:	lea    -0x3080(%r9),%edx

383	  if (! (c & 0x20))
   0x000055555577c91d <+16589>:	test   $0x20,%r8b
   0x000055555577c921 <+16593>:	je     0x55555577c9f5 <read_char+16805>

387	    }
388
389	  d = (d << 6) + p[2] - ((0x20 << 12) + 0x80);
   0x000055555577c927 <+16599>:	movzbl 0x2(%rcx),%eax
   0x000055555577c92b <+16603>:	shl    $0x6,%edx
   0x000055555577c92e <+16606>:	add    %eax,%edx
   0x000055555577c930 <+16608>:	lea    -0x20080(%rdx),%eax

390	  if (! (c & 0x10))
   0x000055555577c936 <+16614>:	test   $0x10,%r8b
   0x000055555577c93a <+16618>:	jne    0x55555577c9b4 <read_char+16740>

391	    {
392	      *length = 3;
393	      eassume (MAX_2_BYTE_CHAR < d && d <= MAX_3_BYTE_CHAR);
   0x000055555577c93c <+16620>:	sub    $0x20880,%edx
   0x000055555577c942 <+16626>:	test   %sil,%sil
   0x000055555577c945 <+16629>:	jne    0x55555577c953 <read_char+16643>
   0x000055555577c947 <+16631>:	cmp    $0xf7ff,%edx
   0x000055555577c94d <+16637>:	ja     0x5555555b2864 <read_char-1859564>

408	  return d;
409	}
410
411	/* Return the character code of character whose multibyte form is at P.  */
412
413	INLINE int
414	STRING_CHAR (unsigned char const *p)
415	{
416	  int len;
417	  return string_char_and_length (p, &len);
418	}
419
420
421	/* Like STRING_CHAR (*PP), but advance *PP to the end of multibyte form.  */
422
423	INLINE int
424	string_char_advance (unsigned char const **pp)
425	{
426	  unsigned char const *p = *pp;
427	  int len, c = string_char_and_length (p, &len);
428	  *pp = p + len;
   0x000055555577c953 <+16643>:	add    $0x3,%rcx

./src/keyboard.c:
2473				  if (meta_key == 3)
   0x000055555577c957 <+16647>:	cmp    $0x3,%r12d
   0x000055555577c95b <+16651>:	je     0x55555577c9f0 <read_char+16800>

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577c961 <+16657>:	cltq

1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577c963 <+16659>:	lea    0x2(,%rax,4),%rax
   0x000055555577c96b <+16667>:	mov    %rax,-0x398(%rbp,%rbx,8)

./src/keyboard.c:
2470			      while (n < coding->produced_char)
   0x000055555577c973 <+16675>:	lea    0x1(%rbx),%rax
   0x000055555577c977 <+16679>:	cmp    %rdi,%rbx
   0x000055555577c97a <+16682>:	je     0x55555577a699 <read_char+7753>
   0x000055555577c980 <+16688>:	mov    %rax,%rbx

./src/character.h:
374	  int c = p[0];
   0x000055555577c983 <+16691>:	movzbl (%rcx),%eax
   0x000055555577c986 <+16694>:	mov    %eax,%r8d

375	  if (! (c & 0x80))
   0x000055555577c989 <+16697>:	test   %al,%al
   0x000055555577c98b <+16699>:	js     0x55555577c8f8 <read_char+16552>

408	  return d;
409	}
410
411	/* Return the character code of character whose multibyte form is at P.  */
412
413	INLINE int
414	STRING_CHAR (unsigned char const *p)
415	{
416	  int len;
417	  return string_char_and_length (p, &len);
418	}
419
420
421	/* Like STRING_CHAR (*PP), but advance *PP to the end of multibyte form.  */
422
423	INLINE int
424	string_char_advance (unsigned char const **pp)
425	{
426	  unsigned char const *p = *pp;
427	  int len, c = string_char_and_length (p, &len);
428	  *pp = p + len;
   0x000055555577c991 <+16705>:	add    $0x1,%rcx

./src/keyboard.c:
2473				  if (meta_key == 3)
   0x000055555577c995 <+16709>:	cmp    $0x3,%r12d
   0x000055555577c999 <+16713>:	jne    0x55555577c961 <read_char+16657>

./src/character.h:
378	      return c;
   0x000055555577c99b <+16715>:	mov    %eax,%edx

./src/keyboard.c:
2476					= (c < 0x100 && (c & 0x80)
   0x000055555577c99d <+16717>:	mov    %edx,%r8d
   0x000055555577c9a0 <+16720>:	mov    %edx,%eax
   0x000055555577c9a2 <+16722>:	shl    $0x14,%r8d
   0x000055555577c9a6 <+16726>:	and    $0x8000000,%r8d

2479				      c = (c & ~0x80) | modifier;
   0x000055555577c9ad <+16733>:	and    $0x7f,%al
   0x000055555577c9af <+16735>:	or     %r8d,%eax
   0x000055555577c9b2 <+16738>:	jmp    0x55555577c961 <read_char+16657>

./src/character.h:
397	  d = (d << 6) + p[3] - ((0x10 << 18) + 0x80);
   0x000055555577c9b4 <+16740>:	shl    $0x6,%eax
   0x000055555577c9b7 <+16743>:	mov    %eax,%edx
   0x000055555577c9b9 <+16745>:	movzbl 0x3(%rcx),%eax
   0x000055555577c9bd <+16749>:	add    %eax,%edx

398	  if (! (c & 0x08))
   0x000055555577c9bf <+16751>:	and    $0x8,%r8d

397	  d = (d << 6) + p[3] - ((0x10 << 18) + 0x80);
   0x000055555577c9c3 <+16755>:	lea    -0x400080(%rdx),%eax

398	  if (! (c & 0x08))
   0x000055555577c9c9 <+16761>:	jne    0x55555577ca13 <read_char+16835>

399	    {
400	      *length = 4;
401	      eassume (MAX_3_BYTE_CHAR < d && d <= MAX_4_BYTE_CHAR);
   0x000055555577c9cb <+16763>:	sub    $0x410080,%edx
   0x000055555577c9d1 <+16769>:	test   %sil,%sil
   0x000055555577c9d4 <+16772>:	jne    0x55555577c9e2 <read_char+16786>
   0x000055555577c9d6 <+16774>:	cmp    $0x1effff,%edx
   0x000055555577c9dc <+16780>:	ja     0x5555555b2881 <read_char-1859535>

408	  return d;
409	}
410
411	/* Return the character code of character whose multibyte form is at P.  */
412
413	INLINE int
414	STRING_CHAR (unsigned char const *p)
415	{
416	  int len;
417	  return string_char_and_length (p, &len);
418	}
419
420
421	/* Like STRING_CHAR (*PP), but advance *PP to the end of multibyte form.  */
422
423	INLINE int
424	string_char_advance (unsigned char const **pp)
425	{
426	  unsigned char const *p = *pp;
427	  int len, c = string_char_and_length (p, &len);
428	  *pp = p + len;
   0x000055555577c9e2 <+16786>:	add    $0x4,%rcx

./src/keyboard.c:
2473				  if (meta_key == 3)
   0x000055555577c9e6 <+16790>:	cmp    $0x3,%r12d
   0x000055555577c9ea <+16794>:	jne    0x55555577c961 <read_char+16657>

2477					   ? meta_modifier
2478					   : 0);
   0x000055555577c9f0 <+16800>:	xor    %r8d,%r8d
   0x000055555577c9f3 <+16803>:	jmp    0x55555577c9ad <read_char+16733>

./src/character.h:
386	      return d + (c < 0xC2 ? 0x3FFF80 : 0);
   0x000055555577c9f5 <+16805>:	add    $0x2,%rcx
   0x000055555577c9f9 <+16809>:	cmp    $0xc1,%eax
   0x000055555577c9fe <+16814>:	jg     0x55555577ca4b <read_char+16891>
   0x000055555577ca00 <+16816>:	lea    0x3fcf00(%r9),%eax

./src/keyboard.c:
2473				  if (meta_key == 3)
   0x000055555577ca07 <+16823>:	cmp    $0x3,%r12d
   0x000055555577ca0b <+16827>:	jne    0x55555577c961 <read_char+16657>
   0x000055555577ca11 <+16833>:	jmp    0x55555577c9f0 <read_char+16800>

./src/character.h:
405	  d = (d << 6) + p[4] - ((0x08 << 24) + 0x80);
   0x000055555577ca13 <+16835>:	shl    $0x6,%eax
   0x000055555577ca16 <+16838>:	mov    %eax,%edx
   0x000055555577ca18 <+16840>:	movzbl 0x4(%rcx),%eax
   0x000055555577ca1c <+16844>:	add    %eax,%edx
   0x000055555577ca1e <+16846>:	lea    -0x8000080(%rdx),%eax

406	  *length = 5;
407	  eassume (MAX_4_BYTE_CHAR < d && d <= MAX_5_BYTE_CHAR);
   0x000055555577ca24 <+16852>:	sub    $0x8200080,%edx
   0x000055555577ca2a <+16858>:	test   %sil,%sil
   0x000055555577ca2d <+16861>:	jne    0x55555577ca3b <read_char+16875>
   0x000055555577ca2f <+16863>:	cmp    $0x1fff7f,%edx
   0x000055555577ca35 <+16869>:	ja     0x5555555b2869 <read_char-1859559>

408	  return d;
409	}
410
411	/* Return the character code of character whose multibyte form is at P.  */
412
413	INLINE int
414	STRING_CHAR (unsigned char const *p)
415	{
416	  int len;
417	  return string_char_and_length (p, &len);
418	}
419
420
421	/* Like STRING_CHAR (*PP), but advance *PP to the end of multibyte form.  */
422
423	INLINE int
424	string_char_advance (unsigned char const **pp)
425	{
426	  unsigned char const *p = *pp;
427	  int len, c = string_char_and_length (p, &len);
428	  *pp = p + len;
   0x000055555577ca3b <+16875>:	add    $0x5,%rcx

./src/keyboard.c:
2473				  if (meta_key == 3)
   0x000055555577ca3f <+16879>:	cmp    $0x3,%r12d
   0x000055555577ca43 <+16883>:	jne    0x55555577c961 <read_char+16657>
   0x000055555577ca49 <+16889>:	jmp    0x55555577c9f0 <read_char+16800>
   0x000055555577ca4b <+16891>:	mov    %edx,%eax
   0x000055555577ca4d <+16893>:	cmp    $0x3,%r12d
   0x000055555577ca51 <+16897>:	jne    0x55555577c961 <read_char+16657>

2474				    {
2475				      int modifier
   0x000055555577ca57 <+16903>:	cmp    $0xff,%edx
   0x000055555577ca5d <+16909>:	jle    0x55555577c99d <read_char+16717>
   0x000055555577ca63 <+16915>:	jmp    0x55555577c9f0 <read_char+16800>
   0x000055555577ca65 <+16917>:	nopl   (%rax)

2843		  /* Or not echoing before and echoing allowed.  */
2844		  || (!echo_kboard && ok_to_echo_at_next_pause)))
   0x000055555577ca68 <+16920>:	test   %rax,%rax
   0x000055555577ca6b <+16923>:	jne    0x55555577a284 <read_char+6708>
   0x000055555577ca71 <+16929>:	jmp    0x555555778db4 <read_char+1380>

4405			    }
4406
4407			  /* car is the index of the next character in the
4408			     string that will be sent and cdr is the string
4409			     itself.  */
4410			  event->ie.arg = Fcons (make_fixnum (0), str);
   0x000055555577ca76 <+16934>:	mov    %rbx,%rsi
   0x000055555577ca79 <+16937>:	mov    $0x2,%edi
   0x000055555577ca7e <+16942>:	mov    %r8,-0x620(%rbp)

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577ca85 <+16949>:	call   0x5555557ef2b0 <Fcons>
   0x000055555577ca8a <+16954>:	mov    -0x620(%rbp),%r8

./src/keyboard.c:
4413		      if (event->kind == MULTIBYTE_CHAR_KEYSTROKE_EVENT
   0x000055555577ca91 <+16961>:	cmpw   $0x2,(%r8)

4410			  event->ie.arg = Fcons (make_fixnum (0), str);
   0x000055555577ca96 <+16966>:	mov    %rax,0x30(%r8)

4411			}
4412
4413		      if (event->kind == MULTIBYTE_CHAR_KEYSTROKE_EVENT
   0x000055555577ca9a <+16970>:	je     0x55555577bd5e <read_char+13582>
   0x000055555577caa0 <+16976>:	jmp    0x55555577aaf0 <read_char+8864>
   0x000055555577caa5 <+16981>:	nopl   (%rax)

4398			    str = event->ie.arg;
   0x000055555577caa8 <+16984>:	mov    0x30(%r8),%rbx
   0x000055555577caac <+16988>:	jmp    0x55555577c270 <read_char+14880>

3192	      previous_echo_area_message = Fcurrent_message ();
   0x000055555577cab1 <+16993>:	call   0x55555580c410 <Fcurrent_message>
   0x000055555577cab6 <+16998>:	mov    %rax,-0x480(%rbp)

3193	      Vinput_method_previous_message = previous_echo_area_message;
   0x000055555577cabd <+17005>:	mov    -0x480(%rbp),%rax
   0x000055555577cac4 <+17012>:	mov    %rax,0x3a3f4d(%rip)        # 0x555555b20a18 <globals+1496>
   0x000055555577cacb <+17019>:	jmp    0x55555577b57f <read_char+11567>

./src/lisp.h:
1184	  return a;
   0x000055555577cad0 <+17024>:	mov    $0x38,%esi
   0x000055555577cad5 <+17029>:	mov    $0xcd68,%edi
   0x000055555577cada <+17034>:	call   0x55555581fc90 <specbind>
   0x000055555577cadf <+17039>:	jmp    0x55555577aff8 <read_char+10152>

./src/keyboard.c:
2454			    for (i = 0; i < n; i++)
   0x000055555577cae4 <+17044>:	xor    %edx,%edx
   0x000055555577cae6 <+17046>:	jmp    0x55555577c06d <read_char+14365>

2433			  if (meta_key != 2)
   0x000055555577caeb <+17051>:	mov    %ebx,%r12d
   0x000055555577caee <+17054>:	mov    %esi,%ebx
   0x000055555577caf0 <+17056>:	cmp    $0x2,%r12d
   0x000055555577caf4 <+17060>:	je     0x55555577a699 <read_char+7753>
   0x000055555577cafa <+17066>:	cmpb   $0x0,0x39f87f(%rip)        # 0x555555b1c380 <suppress_checking>
   0x000055555577cb01 <+17073>:	jne    0x55555577cbbd <read_char+17261>
   0x000055555577cb07 <+17079>:	lea    -0x388(%rbp,%r15,8),%rsi

2436				{
2437				  int c = XFIXNUM (events[i]);
   0x000055555577cb0f <+17087>:	mov    (%rdx),%rax
   0x000055555577cb12 <+17090>:	mov    %rdx,%rcx

./src/lisp.h:
740	  return lisp_h_XLI (o);
   0x000055555577cb15 <+17093>:	lea    -0x2(%rax),%edi

1311	}
1312
1313	INLINE EMACS_INT
1314	XFIXNUM (Lisp_Object a)
1315	{
1316	  eassert (FIXNUMP (a));
   0x000055555577cb18 <+17096>:	and    $0x3,%edi
   0x000055555577cb1b <+17099>:	jne    0x5555555b2915 <read_char-1859387>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577cb21 <+17105>:	sar    $0x2,%rax

./src/keyboard.c:
2438				  int modifier =
   0x000055555577cb25 <+17109>:	cmp    $0xff,%eax
   0x000055555577cb2a <+17114>:	jg     0x55555577cb6b <read_char+17179>
   0x000055555577cb2c <+17116>:	cmp    $0x3,%r12d
   0x000055555577cb30 <+17120>:	jne    0x55555577cb6b <read_char+17179>

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577cb32 <+17122>:	mov    %eax,%ecx

./src/keyboard.c:
2442				  events[i] = make_fixnum ((c & ~0x80) | modifier);
   0x000055555577cb34 <+17124>:	and    $0x7f,%al

2435			      for (i = 0; i < n; i++)
   0x000055555577cb36 <+17126>:	add    $0x8,%rdx

2439				    (meta_key == 3 && c < 0x100 && (c & 0x80))
   0x000055555577cb3a <+17130>:	shl    $0x14,%ecx
   0x000055555577cb3d <+17133>:	and    $0x8000000,%ecx

2442				  events[i] = make_fixnum ((c & ~0x80) | modifier);
   0x000055555577cb43 <+17139>:	or     %ecx,%eax

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577cb45 <+17141>:	cltq
   0x000055555577cb47 <+17143>:	lea    0x2(,%rax,4),%rax
   0x000055555577cb4f <+17151>:	mov    %rax,-0x8(%rdx)

./src/keyboard.c:
2435			      for (i = 0; i < n; i++)
   0x000055555577cb53 <+17155>:	cmp    %rsi,%rdx
   0x000055555577cb56 <+17158>:	jne    0x55555577cb0f <read_char+17087>
   0x000055555577cb58 <+17160>:	jmp    0x55555577a699 <read_char+7753>

2453			  if (meta_key < 2) /* input-meta-mode is t or nil */
   0x000055555577cb5d <+17165>:	cmp    $0x1,%ebx
   0x000055555577cb60 <+17168>:	jg     0x55555577b365 <read_char+11029>
   0x000055555577cb66 <+17174>:	jmp    0x55555577c03e <read_char+14318>

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577cb6b <+17179>:	and    $0x7f,%al

./src/keyboard.c:
2435			      for (i = 0; i < n; i++)
   0x000055555577cb6d <+17181>:	add    $0x8,%rdx

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577cb71 <+17185>:	cltq
   0x000055555577cb73 <+17187>:	lea    0x2(,%rax,4),%rax
   0x000055555577cb7b <+17195>:	mov    %rax,(%rcx)

./src/keyboard.c:
2435			      for (i = 0; i < n; i++)
   0x000055555577cb7e <+17198>:	cmp    %rsi,%rdx
   0x000055555577cb81 <+17201>:	jne    0x55555577cb0f <read_char+17087>
   0x000055555577cb83 <+17203>:	jmp    0x55555577a699 <read_char+7753>

2752	        return c;               /* wrong_kboard_jmpbuf */
2753
2754	      if (! NILP (c))
   0x000055555577cb88 <+17208>:	test   %r14,%r14
   0x000055555577cb8b <+17211>:	je     0x555555778d68 <read_char+1304>
   0x000055555577cb91 <+17217>:	jmp    0x555555778b30 <read_char+736>

2470			      while (n < coding->produced_char)
   0x000055555577cb96 <+17222>:	xor    %ebx,%ebx
   0x000055555577cb98 <+17224>:	jmp    0x55555577a699 <read_char+7753>

./src/lisp.h:
1597	  return CONSP (c) ? XCDR (c) : Qnil;
   0x000055555577cb9d <+17229>:	call   0x5555557630d0 <XCDR>
   0x000055555577cba2 <+17234>:	mov    %rax,%rdi

740	  return lisp_h_XLI (o);
   0x000055555577cba5 <+17237>:	lea    -0x3(%rax),%eax

1566	}
1567
1568	/* Take the car or cdr of something whose type is not known.  */
1569	INLINE Lisp_Object
1570	CAR (Lisp_Object c)
1571	{
1572	  if (CONSP (c))
1573	    return XCAR (c);
1574	  if (!NILP (c))
1575	    wrong_type_argument (Qlistp, c);
1576	  return Qnil;
1577	}
1578	INLINE Lisp_Object
1579	CDR (Lisp_Object c)
1580	{
1581	  if (CONSP (c))
1582	    return XCDR (c);
1583	  if (!NILP (c))
1584	    wrong_type_argument (Qlistp, c);
1585	  return Qnil;
1586	}
1587
1588	/* Take the car or cdr of something whose type is not known.  */
1589	INLINE Lisp_Object
1590	CAR_SAFE (Lisp_Object c)
1591	{
1592	  return CONSP (c) ? XCAR (c) : Qnil;
   0x000055555577cba8 <+17240>:	test   $0x7,%al
   0x000055555577cbaa <+17242>:	jne    0x55555577c572 <read_char+15650>
   0x000055555577cbb0 <+17248>:	call   0x555555763090 <XCAR>
   0x000055555577cbb5 <+17253>:	mov    %rax,%r12
   0x000055555577cbb8 <+17256>:	jmp    0x55555577c572 <read_char+15650>

1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577cbbd <+17261>:	mov    -0x390(%rbp),%rcx
   0x000055555577cbc4 <+17268>:	sar    $0x2,%rcx

./src/keyboard.c:
2438				  int modifier =
   0x000055555577cbc8 <+17272>:	cmp    $0x3,%r12d
   0x000055555577cbcc <+17276>:	sete   %al

2440				    ? meta_modifier
2441				    : 0;
   0x000055555577cbcf <+17279>:	cmp    $0xff,%ecx
   0x000055555577cbd5 <+17285>:	jg     0x55555577d102 <read_char+18610>
   0x000055555577cbdb <+17291>:	test   %al,%al
   0x000055555577cbdd <+17293>:	je     0x55555577d102 <read_char+18610>

2439				    (meta_key == 3 && c < 0x100 && (c & 0x80))
   0x000055555577cbe3 <+17299>:	mov    %ecx,%esi
   0x000055555577cbe5 <+17301>:	shl    $0x14,%esi
   0x000055555577cbe8 <+17304>:	and    $0x8000000,%esi

2442				  events[i] = make_fixnum ((c & ~0x80) | modifier);
   0x000055555577cbee <+17310>:	and    $0x7f,%cl
   0x000055555577cbf1 <+17313>:	mov    %r15d,%edx

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577cbf4 <+17316>:	or     %esi,%ecx

1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577cbf6 <+17318>:	movslq %ecx,%rcx
   0x000055555577cbf9 <+17321>:	lea    0x2(,%rcx,4),%rcx
   0x000055555577cc01 <+17329>:	mov    %rcx,-0x390(%rbp)

./src/keyboard.c:
2435			      for (i = 0; i < n; i++)
   0x000055555577cc08 <+17336>:	test   %r15d,%r15d
   0x000055555577cc0b <+17339>:	je     0x55555577a699 <read_char+7753>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577cc11 <+17345>:	mov    -0x388(%rbp),%rcx
   0x000055555577cc18 <+17352>:	sar    $0x2,%rcx

./src/keyboard.c:
2438				  int modifier =
   0x000055555577cc1c <+17356>:	cmp    $0xff,%ecx
   0x000055555577cc22 <+17362>:	jg     0x55555577d0fb <read_char+18603>
   0x000055555577cc28 <+17368>:	test   %al,%al
   0x000055555577cc2a <+17370>:	je     0x55555577d0fb <read_char+18603>

2439				    (meta_key == 3 && c < 0x100 && (c & 0x80))
   0x000055555577cc30 <+17376>:	mov    %ecx,%esi
   0x000055555577cc32 <+17378>:	shl    $0x14,%esi
   0x000055555577cc35 <+17381>:	and    $0x8000000,%esi

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577cc3b <+17387>:	and    $0x7f,%cl

./src/keyboard.c:
2442				  events[i] = make_fixnum ((c & ~0x80) | modifier);
   0x000055555577cc3e <+17390>:	or     %esi,%ecx

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577cc40 <+17392>:	movslq %ecx,%rcx
   0x000055555577cc43 <+17395>:	lea    0x2(,%rcx,4),%rcx
   0x000055555577cc4b <+17403>:	mov    %rcx,-0x388(%rbp)

./src/keyboard.c:
2435			      for (i = 0; i < n; i++)
   0x000055555577cc52 <+17410>:	cmp    $0x1,%edx
   0x000055555577cc55 <+17413>:	je     0x55555577a699 <read_char+7753>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577cc5b <+17419>:	mov    -0x380(%rbp),%rcx
   0x000055555577cc62 <+17426>:	sar    $0x2,%rcx

./src/keyboard.c:
2438				  int modifier =
   0x000055555577cc66 <+17430>:	cmp    $0xff,%ecx
   0x000055555577cc6c <+17436>:	jg     0x55555577d0f4 <read_char+18596>
   0x000055555577cc72 <+17442>:	test   %al,%al
   0x000055555577cc74 <+17444>:	je     0x55555577d0f4 <read_char+18596>

2439				    (meta_key == 3 && c < 0x100 && (c & 0x80))
   0x000055555577cc7a <+17450>:	mov    %ecx,%esi
   0x000055555577cc7c <+17452>:	shl    $0x14,%esi
   0x000055555577cc7f <+17455>:	and    $0x8000000,%esi

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577cc85 <+17461>:	and    $0x7f,%cl

./src/keyboard.c:
2442				  events[i] = make_fixnum ((c & ~0x80) | modifier);
   0x000055555577cc88 <+17464>:	or     %esi,%ecx

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577cc8a <+17466>:	movslq %ecx,%rcx
   0x000055555577cc8d <+17469>:	lea    0x2(,%rcx,4),%rcx
   0x000055555577cc95 <+17477>:	mov    %rcx,-0x380(%rbp)

./src/keyboard.c:
2435			      for (i = 0; i < n; i++)
   0x000055555577cc9c <+17484>:	cmp    $0x2,%edx
   0x000055555577cc9f <+17487>:	je     0x55555577a699 <read_char+7753>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577cca5 <+17493>:	mov    -0x378(%rbp),%rcx
   0x000055555577ccac <+17500>:	sar    $0x2,%rcx

./src/keyboard.c:
2438				  int modifier =
   0x000055555577ccb0 <+17504>:	cmp    $0xff,%ecx
   0x000055555577ccb6 <+17510>:	jg     0x55555577d0ed <read_char+18589>
   0x000055555577ccbc <+17516>:	test   %al,%al
   0x000055555577ccbe <+17518>:	je     0x55555577d0ed <read_char+18589>

2439				    (meta_key == 3 && c < 0x100 && (c & 0x80))
   0x000055555577ccc4 <+17524>:	mov    %ecx,%esi
   0x000055555577ccc6 <+17526>:	shl    $0x14,%esi
   0x000055555577ccc9 <+17529>:	and    $0x8000000,%esi

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577cccf <+17535>:	and    $0x7f,%cl

./src/keyboard.c:
2442				  events[i] = make_fixnum ((c & ~0x80) | modifier);
   0x000055555577ccd2 <+17538>:	or     %esi,%ecx

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577ccd4 <+17540>:	movslq %ecx,%rcx
   0x000055555577ccd7 <+17543>:	lea    0x2(,%rcx,4),%rcx
   0x000055555577ccdf <+17551>:	mov    %rcx,-0x378(%rbp)

./src/keyboard.c:
2435			      for (i = 0; i < n; i++)
   0x000055555577cce6 <+17558>:	cmp    $0x3,%edx
   0x000055555577cce9 <+17561>:	je     0x55555577a699 <read_char+7753>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577ccef <+17567>:	mov    -0x370(%rbp),%rcx
   0x000055555577ccf6 <+17574>:	sar    $0x2,%rcx

./src/keyboard.c:
2438				  int modifier =
   0x000055555577ccfa <+17578>:	cmp    $0xff,%ecx
   0x000055555577cd00 <+17584>:	jg     0x55555577d0e6 <read_char+18582>
   0x000055555577cd06 <+17590>:	test   %al,%al
   0x000055555577cd08 <+17592>:	je     0x55555577d0e6 <read_char+18582>

2439				    (meta_key == 3 && c < 0x100 && (c & 0x80))
   0x000055555577cd0e <+17598>:	mov    %ecx,%esi
   0x000055555577cd10 <+17600>:	shl    $0x14,%esi
   0x000055555577cd13 <+17603>:	and    $0x8000000,%esi

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577cd19 <+17609>:	and    $0x7f,%cl

./src/keyboard.c:
2442				  events[i] = make_fixnum ((c & ~0x80) | modifier);
   0x000055555577cd1c <+17612>:	or     %esi,%ecx

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577cd1e <+17614>:	movslq %ecx,%rcx
   0x000055555577cd21 <+17617>:	lea    0x2(,%rcx,4),%rcx
   0x000055555577cd29 <+17625>:	mov    %rcx,-0x370(%rbp)

./src/keyboard.c:
2435			      for (i = 0; i < n; i++)
   0x000055555577cd30 <+17632>:	cmp    $0x4,%edx
   0x000055555577cd33 <+17635>:	je     0x55555577a699 <read_char+7753>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577cd39 <+17641>:	mov    -0x368(%rbp),%rcx
   0x000055555577cd40 <+17648>:	sar    $0x2,%rcx

./src/keyboard.c:
2438				  int modifier =
   0x000055555577cd44 <+17652>:	cmp    $0xff,%ecx
   0x000055555577cd4a <+17658>:	jg     0x55555577d0df <read_char+18575>
   0x000055555577cd50 <+17664>:	test   %al,%al
   0x000055555577cd52 <+17666>:	je     0x55555577d0df <read_char+18575>

2439				    (meta_key == 3 && c < 0x100 && (c & 0x80))
   0x000055555577cd58 <+17672>:	mov    %ecx,%esi
   0x000055555577cd5a <+17674>:	shl    $0x14,%esi
   0x000055555577cd5d <+17677>:	and    $0x8000000,%esi

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577cd63 <+17683>:	and    $0x7f,%cl

./src/keyboard.c:
2442				  events[i] = make_fixnum ((c & ~0x80) | modifier);
   0x000055555577cd66 <+17686>:	or     %esi,%ecx

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577cd68 <+17688>:	movslq %ecx,%rcx
   0x000055555577cd6b <+17691>:	lea    0x2(,%rcx,4),%rcx
   0x000055555577cd73 <+17699>:	mov    %rcx,-0x368(%rbp)

./src/keyboard.c:
2435			      for (i = 0; i < n; i++)
   0x000055555577cd7a <+17706>:	cmp    $0x5,%edx
   0x000055555577cd7d <+17709>:	je     0x55555577a699 <read_char+7753>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577cd83 <+17715>:	mov    -0x360(%rbp),%rcx
   0x000055555577cd8a <+17722>:	sar    $0x2,%rcx

./src/keyboard.c:
2438				  int modifier =
   0x000055555577cd8e <+17726>:	cmp    $0xff,%ecx
   0x000055555577cd94 <+17732>:	jg     0x55555577d0d8 <read_char+18568>
   0x000055555577cd9a <+17738>:	test   %al,%al
   0x000055555577cd9c <+17740>:	je     0x55555577d0d8 <read_char+18568>

2439				    (meta_key == 3 && c < 0x100 && (c & 0x80))
   0x000055555577cda2 <+17746>:	mov    %ecx,%esi
   0x000055555577cda4 <+17748>:	shl    $0x14,%esi
   0x000055555577cda7 <+17751>:	and    $0x8000000,%esi

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577cdad <+17757>:	and    $0x7f,%cl

./src/keyboard.c:
2442				  events[i] = make_fixnum ((c & ~0x80) | modifier);
   0x000055555577cdb0 <+17760>:	or     %esi,%ecx

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577cdb2 <+17762>:	movslq %ecx,%rcx
   0x000055555577cdb5 <+17765>:	lea    0x2(,%rcx,4),%rcx
   0x000055555577cdbd <+17773>:	mov    %rcx,-0x360(%rbp)

./src/keyboard.c:
2435			      for (i = 0; i < n; i++)
   0x000055555577cdc4 <+17780>:	cmp    $0x6,%edx
   0x000055555577cdc7 <+17783>:	je     0x55555577a699 <read_char+7753>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577cdcd <+17789>:	mov    -0x358(%rbp),%rcx
   0x000055555577cdd4 <+17796>:	sar    $0x2,%rcx

./src/keyboard.c:
2438				  int modifier =
   0x000055555577cdd8 <+17800>:	cmp    $0xff,%ecx
   0x000055555577cdde <+17806>:	jg     0x55555577d0d1 <read_char+18561>
   0x000055555577cde4 <+17812>:	test   %al,%al
   0x000055555577cde6 <+17814>:	je     0x55555577d0d1 <read_char+18561>

2439				    (meta_key == 3 && c < 0x100 && (c & 0x80))
   0x000055555577cdec <+17820>:	mov    %ecx,%esi
   0x000055555577cdee <+17822>:	shl    $0x14,%esi
   0x000055555577cdf1 <+17825>:	and    $0x8000000,%esi

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577cdf7 <+17831>:	and    $0x7f,%cl

./src/keyboard.c:
2442				  events[i] = make_fixnum ((c & ~0x80) | modifier);
   0x000055555577cdfa <+17834>:	or     %esi,%ecx

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577cdfc <+17836>:	movslq %ecx,%rcx
   0x000055555577cdff <+17839>:	lea    0x2(,%rcx,4),%rcx
   0x000055555577ce07 <+17847>:	mov    %rcx,-0x358(%rbp)

./src/keyboard.c:
2435			      for (i = 0; i < n; i++)
   0x000055555577ce0e <+17854>:	cmp    $0x7,%edx
   0x000055555577ce11 <+17857>:	je     0x55555577a699 <read_char+7753>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577ce17 <+17863>:	mov    -0x350(%rbp),%rcx
   0x000055555577ce1e <+17870>:	sar    $0x2,%rcx

./src/keyboard.c:
2438				  int modifier =
   0x000055555577ce22 <+17874>:	cmp    $0xff,%ecx
   0x000055555577ce28 <+17880>:	jg     0x55555577d0ca <read_char+18554>
   0x000055555577ce2e <+17886>:	test   %al,%al
   0x000055555577ce30 <+17888>:	je     0x55555577d0ca <read_char+18554>

2439				    (meta_key == 3 && c < 0x100 && (c & 0x80))
   0x000055555577ce36 <+17894>:	mov    %ecx,%esi
   0x000055555577ce38 <+17896>:	shl    $0x14,%esi
   0x000055555577ce3b <+17899>:	and    $0x8000000,%esi

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577ce41 <+17905>:	and    $0x7f,%cl

./src/keyboard.c:
2442				  events[i] = make_fixnum ((c & ~0x80) | modifier);
   0x000055555577ce44 <+17908>:	or     %esi,%ecx

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577ce46 <+17910>:	movslq %ecx,%rcx
   0x000055555577ce49 <+17913>:	lea    0x2(,%rcx,4),%rcx
   0x000055555577ce51 <+17921>:	mov    %rcx,-0x350(%rbp)

./src/keyboard.c:
2435			      for (i = 0; i < n; i++)
   0x000055555577ce58 <+17928>:	cmp    $0x8,%edx
   0x000055555577ce5b <+17931>:	je     0x55555577a699 <read_char+7753>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577ce61 <+17937>:	mov    -0x348(%rbp),%rcx
   0x000055555577ce68 <+17944>:	sar    $0x2,%rcx

./src/keyboard.c:
2438				  int modifier =
   0x000055555577ce6c <+17948>:	cmp    $0xff,%ecx
   0x000055555577ce72 <+17954>:	jg     0x55555577d0c3 <read_char+18547>
   0x000055555577ce78 <+17960>:	test   %al,%al
   0x000055555577ce7a <+17962>:	je     0x55555577d0c3 <read_char+18547>

2439				    (meta_key == 3 && c < 0x100 && (c & 0x80))
   0x000055555577ce80 <+17968>:	mov    %ecx,%esi
   0x000055555577ce82 <+17970>:	shl    $0x14,%esi
   0x000055555577ce85 <+17973>:	and    $0x8000000,%esi

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577ce8b <+17979>:	and    $0x7f,%cl

./src/keyboard.c:
2442				  events[i] = make_fixnum ((c & ~0x80) | modifier);
   0x000055555577ce8e <+17982>:	or     %esi,%ecx

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577ce90 <+17984>:	movslq %ecx,%rcx
   0x000055555577ce93 <+17987>:	lea    0x2(,%rcx,4),%rcx
   0x000055555577ce9b <+17995>:	mov    %rcx,-0x348(%rbp)

./src/keyboard.c:
2435			      for (i = 0; i < n; i++)
   0x000055555577cea2 <+18002>:	cmp    $0x9,%edx
   0x000055555577cea5 <+18005>:	je     0x55555577a699 <read_char+7753>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577ceab <+18011>:	mov    -0x340(%rbp),%rcx
   0x000055555577ceb2 <+18018>:	sar    $0x2,%rcx

./src/keyboard.c:
2438				  int modifier =
   0x000055555577ceb6 <+18022>:	cmp    $0xff,%ecx
   0x000055555577cebc <+18028>:	jg     0x55555577d0bc <read_char+18540>
   0x000055555577cec2 <+18034>:	test   %al,%al
   0x000055555577cec4 <+18036>:	je     0x55555577d0bc <read_char+18540>

2439				    (meta_key == 3 && c < 0x100 && (c & 0x80))
   0x000055555577ceca <+18042>:	mov    %ecx,%esi
   0x000055555577cecc <+18044>:	shl    $0x14,%esi
   0x000055555577cecf <+18047>:	and    $0x8000000,%esi

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577ced5 <+18053>:	and    $0x7f,%cl

./src/keyboard.c:
2442				  events[i] = make_fixnum ((c & ~0x80) | modifier);
   0x000055555577ced8 <+18056>:	or     %esi,%ecx

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577ceda <+18058>:	movslq %ecx,%rcx
   0x000055555577cedd <+18061>:	lea    0x2(,%rcx,4),%rcx
   0x000055555577cee5 <+18069>:	mov    %rcx,-0x340(%rbp)

./src/keyboard.c:
2435			      for (i = 0; i < n; i++)
   0x000055555577ceec <+18076>:	cmp    $0xa,%edx
   0x000055555577ceef <+18079>:	je     0x55555577a699 <read_char+7753>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577cef5 <+18085>:	mov    -0x338(%rbp),%rcx
   0x000055555577cefc <+18092>:	sar    $0x2,%rcx

./src/keyboard.c:
2438				  int modifier =
   0x000055555577cf00 <+18096>:	cmp    $0xff,%ecx
   0x000055555577cf06 <+18102>:	jg     0x55555577d0b5 <read_char+18533>
   0x000055555577cf0c <+18108>:	test   %al,%al
   0x000055555577cf0e <+18110>:	je     0x55555577d0b5 <read_char+18533>

2439				    (meta_key == 3 && c < 0x100 && (c & 0x80))
   0x000055555577cf14 <+18116>:	mov    %ecx,%esi
   0x000055555577cf16 <+18118>:	shl    $0x14,%esi
   0x000055555577cf19 <+18121>:	and    $0x8000000,%esi

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577cf1f <+18127>:	and    $0x7f,%cl

./src/keyboard.c:
2442				  events[i] = make_fixnum ((c & ~0x80) | modifier);
   0x000055555577cf22 <+18130>:	or     %esi,%ecx

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577cf24 <+18132>:	movslq %ecx,%rcx
   0x000055555577cf27 <+18135>:	lea    0x2(,%rcx,4),%rcx
   0x000055555577cf2f <+18143>:	mov    %rcx,-0x338(%rbp)

./src/keyboard.c:
2435			      for (i = 0; i < n; i++)
   0x000055555577cf36 <+18150>:	cmp    $0xb,%edx
   0x000055555577cf39 <+18153>:	je     0x55555577a699 <read_char+7753>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577cf3f <+18159>:	mov    -0x330(%rbp),%rcx
   0x000055555577cf46 <+18166>:	sar    $0x2,%rcx

./src/keyboard.c:
2438				  int modifier =
   0x000055555577cf4a <+18170>:	cmp    $0xff,%ecx
   0x000055555577cf50 <+18176>:	jg     0x55555577d0ae <read_char+18526>
   0x000055555577cf56 <+18182>:	test   %al,%al
   0x000055555577cf58 <+18184>:	je     0x55555577d0ae <read_char+18526>

2439				    (meta_key == 3 && c < 0x100 && (c & 0x80))
   0x000055555577cf5e <+18190>:	mov    %ecx,%esi
   0x000055555577cf60 <+18192>:	shl    $0x14,%esi
   0x000055555577cf63 <+18195>:	and    $0x8000000,%esi

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577cf69 <+18201>:	and    $0x7f,%cl

./src/keyboard.c:
2442				  events[i] = make_fixnum ((c & ~0x80) | modifier);
   0x000055555577cf6c <+18204>:	or     %esi,%ecx

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577cf6e <+18206>:	movslq %ecx,%rcx
   0x000055555577cf71 <+18209>:	lea    0x2(,%rcx,4),%rcx
   0x000055555577cf79 <+18217>:	mov    %rcx,-0x330(%rbp)

./src/keyboard.c:
2435			      for (i = 0; i < n; i++)
   0x000055555577cf80 <+18224>:	cmp    $0xc,%edx
   0x000055555577cf83 <+18227>:	je     0x55555577a699 <read_char+7753>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577cf89 <+18233>:	mov    -0x328(%rbp),%rcx
   0x000055555577cf90 <+18240>:	sar    $0x2,%rcx

./src/keyboard.c:
2438				  int modifier =
   0x000055555577cf94 <+18244>:	cmp    $0xff,%ecx
   0x000055555577cf9a <+18250>:	jg     0x55555577d0a7 <read_char+18519>
   0x000055555577cfa0 <+18256>:	test   %al,%al
   0x000055555577cfa2 <+18258>:	je     0x55555577d0a7 <read_char+18519>

2439				    (meta_key == 3 && c < 0x100 && (c & 0x80))
   0x000055555577cfa8 <+18264>:	mov    %ecx,%esi
   0x000055555577cfaa <+18266>:	shl    $0x14,%esi
   0x000055555577cfad <+18269>:	and    $0x8000000,%esi

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577cfb3 <+18275>:	and    $0x7f,%cl

./src/keyboard.c:
2442				  events[i] = make_fixnum ((c & ~0x80) | modifier);
   0x000055555577cfb6 <+18278>:	or     %esi,%ecx

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577cfb8 <+18280>:	movslq %ecx,%rcx
   0x000055555577cfbb <+18283>:	lea    0x2(,%rcx,4),%rcx
   0x000055555577cfc3 <+18291>:	mov    %rcx,-0x328(%rbp)

./src/keyboard.c:
2435			      for (i = 0; i < n; i++)
   0x000055555577cfca <+18298>:	cmp    $0xd,%edx
   0x000055555577cfcd <+18301>:	jle    0x55555577a699 <read_char+7753>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577cfd3 <+18307>:	mov    -0x320(%rbp),%rcx
   0x000055555577cfda <+18314>:	sar    $0x2,%rcx

./src/keyboard.c:
2438				  int modifier =
   0x000055555577cfde <+18318>:	cmp    $0xff,%ecx
   0x000055555577cfe4 <+18324>:	jg     0x55555577d0a0 <read_char+18512>
   0x000055555577cfea <+18330>:	test   %al,%al
   0x000055555577cfec <+18332>:	je     0x55555577d0a0 <read_char+18512>

2439				    (meta_key == 3 && c < 0x100 && (c & 0x80))
   0x000055555577cff2 <+18338>:	mov    %ecx,%esi
   0x000055555577cff4 <+18340>:	shl    $0x14,%esi
   0x000055555577cff7 <+18343>:	and    $0x8000000,%esi

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577cffd <+18349>:	and    $0x7f,%cl

./src/keyboard.c:
2442				  events[i] = make_fixnum ((c & ~0x80) | modifier);
   0x000055555577d000 <+18352>:	or     %esi,%ecx

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577d002 <+18354>:	movslq %ecx,%rcx
   0x000055555577d005 <+18357>:	lea    0x2(,%rcx,4),%rcx
   0x000055555577d00d <+18365>:	mov    %rcx,-0x320(%rbp)

./src/keyboard.c:
2435			      for (i = 0; i < n; i++)
   0x000055555577d014 <+18372>:	cmp    $0xf,%edx
   0x000055555577d017 <+18375>:	jne    0x55555577a699 <read_char+7753>

./src/lisp.h:
1238	  return lisp_h_XFIXNUM_RAW (a);
   0x000055555577d01d <+18381>:	mov    -0x318(%rbp),%rdx
   0x000055555577d024 <+18388>:	sar    $0x2,%rdx

./src/keyboard.c:
2438				  int modifier =
   0x000055555577d028 <+18392>:	cmp    $0xff,%edx
   0x000055555577d02e <+18398>:	jg     0x55555577d09c <read_char+18508>
   0x000055555577d030 <+18400>:	test   %al,%al
   0x000055555577d032 <+18402>:	je     0x55555577d09c <read_char+18508>

2439				    (meta_key == 3 && c < 0x100 && (c & 0x80))
   0x000055555577d034 <+18404>:	mov    %edx,%ecx
   0x000055555577d036 <+18406>:	shl    $0x14,%ecx
   0x000055555577d039 <+18409>:	and    $0x8000000,%ecx

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x000055555577d03f <+18415>:	mov    %edx,%eax
   0x000055555577d041 <+18417>:	and    $0x7f,%al

./src/keyboard.c:
2442				  events[i] = make_fixnum ((c & ~0x80) | modifier);
   0x000055555577d043 <+18419>:	or     %ecx,%eax

./src/lisp.h:
1232	  return lisp_h_make_fixnum_wrap (n);
   0x000055555577d045 <+18421>:	cltq
   0x000055555577d047 <+18423>:	lea    0x2(,%rax,4),%rax
   0x000055555577d04f <+18431>:	mov    %rax,-0x318(%rbp)

./src/keyboard.c:
2435			      for (i = 0; i < n; i++)
   0x000055555577d056 <+18438>:	jmp    0x55555577a699 <read_char+7753>

3398	}
   0x000055555577d05b <+18443>:	call   0x555555599ff0 <__stack_chk_fail <at> plt>

./src/lisp.h:
1184	  return a;
   0x000055555577d060 <+18448>:	mov    $0x15230,%esi
   0x000055555577d065 <+18453>:	mov    %r12,%rdi
   0x000055555577d068 <+18456>:	call   0x555555764470 <EQ>

./src/keyboard.c:
3151	      if (EQ (posn, Qmenu_bar) || EQ (posn, Qtab_bar) || EQ (posn, Qtool_bar))
   0x000055555577d06d <+18461>:	test   %al,%al
   0x000055555577d06f <+18463>:	jne    0x55555577c59b <read_char+15691>
   0x000055555577d075 <+18469>:	jmp    0x55555577b523 <read_char+11475>

3166		    Vunread_command_events = Fcons (Fcons (Qt, c),
3167						    Vunread_command_events);
3168		  else
3169		    {
3170		      also_record = c;
   0x000055555577d07a <+18474>:	mov    0x3a3ff7(%rip),%rsi        # 0x555555b21078 <globals+3128>
   0x000055555577d081 <+18481>:	mov    %r14,%rdi
   0x000055555577d084 <+18484>:	mov    %r14,-0x478(%rbp)

3171		      Vunread_command_events = Fcons (c, Vunread_command_events);
   0x000055555577d08b <+18491>:	call   0x5555557ef2b0 <Fcons>
   0x000055555577d090 <+18496>:	mov    %rax,0x3a3fe1(%rip)        # 0x555555b21078 <globals+3128>
   0x000055555577d097 <+18503>:	jmp    0x55555577c5fa <read_char+15786>

2441				    : 0;
   0x000055555577d09c <+18508>:	xor    %ecx,%ecx
   0x000055555577d09e <+18510>:	jmp    0x55555577d03f <read_char+18415>
   0x000055555577d0a0 <+18512>:	xor    %esi,%esi
   0x000055555577d0a2 <+18514>:	jmp    0x55555577cffd <read_char+18349>
   0x000055555577d0a7 <+18519>:	xor    %esi,%esi
   0x000055555577d0a9 <+18521>:	jmp    0x55555577cfb3 <read_char+18275>
   0x000055555577d0ae <+18526>:	xor    %esi,%esi
   0x000055555577d0b0 <+18528>:	jmp    0x55555577cf69 <read_char+18201>
   0x000055555577d0b5 <+18533>:	xor    %esi,%esi
   0x000055555577d0b7 <+18535>:	jmp    0x55555577cf1f <read_char+18127>
   0x000055555577d0bc <+18540>:	xor    %esi,%esi
   0x000055555577d0be <+18542>:	jmp    0x55555577ced5 <read_char+18053>
   0x000055555577d0c3 <+18547>:	xor    %esi,%esi
   0x000055555577d0c5 <+18549>:	jmp    0x55555577ce8b <read_char+17979>
   0x000055555577d0ca <+18554>:	xor    %esi,%esi
   0x000055555577d0cc <+18556>:	jmp    0x55555577ce41 <read_char+17905>
   0x000055555577d0d1 <+18561>:	xor    %esi,%esi
   0x000055555577d0d3 <+18563>:	jmp    0x55555577cdf7 <read_char+17831>
   0x000055555577d0d8 <+18568>:	xor    %esi,%esi
   0x000055555577d0da <+18570>:	jmp    0x55555577cdad <read_char+17757>
   0x000055555577d0df <+18575>:	xor    %esi,%esi
   0x000055555577d0e1 <+18577>:	jmp    0x55555577cd63 <read_char+17683>
   0x000055555577d0e6 <+18582>:	xor    %esi,%esi
   0x000055555577d0e8 <+18584>:	jmp    0x55555577cd19 <read_char+17609>
   0x000055555577d0ed <+18589>:	xor    %esi,%esi
   0x000055555577d0ef <+18591>:	jmp    0x55555577cccf <read_char+17535>
   0x000055555577d0f4 <+18596>:	xor    %esi,%esi
   0x000055555577d0f6 <+18598>:	jmp    0x55555577cc85 <read_char+17461>
   0x000055555577d0fb <+18603>:	xor    %esi,%esi
   0x000055555577d0fd <+18605>:	jmp    0x55555577cc3b <read_char+17387>
   0x000055555577d102 <+18610>:	xor    %esi,%esi
   0x000055555577d104 <+18612>:	jmp    0x55555577cbee <read_char+17310>
   0x000055555577d109 <+18617>:	jmp    0x5555555b28d6 <read_char-1859450>
   0x000055555577d10e <+18622>:	jmp    0x5555555b28bb <read_char-1859477>
   0x000055555577d113 <+18627>:	jmp    0x5555555b28c0 <read_char-1859472>
   0x000055555577d118 <+18632>:	jmp    0x5555555b28f3 <read_char-1859421>
   0x000055555577d11d <+18637>:	jmp    0x5555555b28f8 <read_char-1859416>
Address range 0x5555555b276a to 0x5555555b2997:
./src/keyboard.c:
2468			      eassert (coding->carryover_bytes == 0);
   0x00005555555b276a <-1859814>:	mov    $0x9a4,%edx
   0x00005555555b276f <-1859809>:	lea    0x41d221(%rip),%rsi        # 0x5555559cf997
   0x00005555555b2776 <-1859802>:	lea    0x41d459(%rip),%rdi        # 0x5555559cfbd6
   0x00005555555b277d <-1859795>:	call   0x5555555b8f19 <die>

./src/character.h:
380	  eassume (0xC0 <= c);
   0x00005555555b2782 <-1859790>:	mov    $0x17c,%edx
   0x00005555555b2787 <-1859785>:	lea    0x405027(%rip),%rsi        # 0x5555559b77b5
   0x00005555555b278e <-1859778>:	lea    0x4050e0(%rip),%rdi        # 0x5555559b7875
   0x00005555555b2795 <-1859771>:	call   0x5555555b8f19 <die>
   0x00005555555b279a <-1859766>:	call   0x5555555b1595 <make_fixnum>

./src/keyboard.c:
2409	      struct frame *frame = XFRAME (selected_frame);
   0x00005555555b279f <-1859761>:	mov    $0x969,%edx
   0x00005555555b27a4 <-1859756>:	lea    0x41d1ec(%rip),%rsi        # 0x5555559cf997
   0x00005555555b27ab <-1859749>:	lea    0x402c41(%rip),%rdi        # 0x5555559b53f3
   0x00005555555b27b2 <-1859742>:	call   0x5555555b8f19 <die>

4496
4497		  if (!EQ (frame, internal_last_event_frame)
4498		      && !EQ (frame, selected_frame))
4499		    obj = make_lispy_switch_frame (frame);
4500		  internal_last_event_frame = frame;
4501		}
4502
4503	      /* If we didn't decide to make a switch-frame event, go ahead and
4504		 return a mouse-motion event.  */
4505	      if (!NILP (x) && NILP (obj))
4506		obj = make_lispy_movement (f, bar_window, part, x, y, t);
4507
4508	      if (!NILP (obj))
4509		Vlast_event_device = (STRINGP (movement_frame->last_mouse_device)
4510				      ? movement_frame->last_mouse_device
4511				      : virtual_core_pointer_name);
4512	    }
4513	#ifdef HAVE_X_WINDOWS
4514	  else if (had_pending_selection_requests)
4515	    obj = Qnil;
4516	#endif
4517	  else
4518	    /* We were promised by the above while loop that there was
4519	       something for us to read!  */
4520	    emacs_abort ();
   0x00005555555b27b7 <-1859737>:	call   0x5555555b39b8 <emacs_abort>
   0x00005555555b27bc <-1859732>:	call   0x5555555b155e <XCONS>

4495		    XSETFRAME (frame, f);
   0x00005555555b27c1 <-1859727>:	mov    $0x118f,%edx
   0x00005555555b27c6 <-1859722>:	lea    0x41d1ca(%rip),%rsi        # 0x5555559cf997
   0x00005555555b27cd <-1859715>:	lea    0x403454(%rip),%rdi        # 0x5555559b5c28
   0x00005555555b27d4 <-1859708>:	call   0x5555555b8f19 <die>
   0x00005555555b27d9 <-1859703>:	call   0x5555555b163c <make_lisp_ptr>

./src/lisp.h:
3427	  eassert (FLOATP (a));
   0x00005555555b27de <-1859698>:	mov    $0xd63,%edx
   0x00005555555b27e3 <-1859693>:	lea    0x402836(%rip),%rsi        # 0x5555559b5020
   0x00005555555b27ea <-1859686>:	lea    0x403a31(%rip),%rdi        # 0x5555559b6222
   0x00005555555b27f1 <-1859679>:	call   0x5555555b8f19 <die>
   0x00005555555b27f6 <-1859674>:	mov    $0xd63,%edx
   0x00005555555b27fb <-1859669>:	lea    0x40281e(%rip),%rsi        # 0x5555559b5020
   0x00005555555b2802 <-1859662>:	lea    0x403a19(%rip),%rdi        # 0x5555559b6222
   0x00005555555b2809 <-1859655>:	call   0x5555555b8f19 <die>
   0x00005555555b280e <-1859650>:	mov    $0xd63,%edx
   0x00005555555b2813 <-1859645>:	lea    0x402806(%rip),%rsi        # 0x5555559b5020
   0x00005555555b281a <-1859638>:	lea    0x403a01(%rip),%rdi        # 0x5555559b6222
   0x00005555555b2821 <-1859631>:	call   0x5555555b8f19 <die>
   0x00005555555b2826 <-1859626>:	call   0x5555555b155e <XCONS>
   0x00005555555b282b <-1859621>:	call   0x5555555b155e <XCONS>
   0x00005555555b2830 <-1859616>:	call   0x5555555b155e <XCONS>

./src/keyboard.c:
2799			  emacs_abort ();
   0x00005555555b2835 <-1859611>:	call   0x5555555b39b8 <emacs_abort>
   0x00005555555b283a <-1859606>:	call   0x5555555b16f6 <XFIXNUM>
   0x00005555555b283f <-1859601>:	call   0x5555555b16f6 <XFIXNUM>
   0x00005555555b2844 <-1859596>:	call   0x5555555b155e <XCONS>

2992		  c = XCAR (KVAR (current_kboard, kbd_queue));
2993		  c_volatile = c;
2994		  kset_kbd_queue (current_kboard,
2995				  XCDR (KVAR (current_kboard, kbd_queue)));
2996		  if (NILP (KVAR (current_kboard, kbd_queue)))
2997		    current_kboard->kbd_queue_has_data = false;
2998		  input_pending = readable_events (0);
2999		  if (EVENT_HAS_PARAMETERS (c)
3000		      && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qswitch_frame))
3001		    internal_last_event_frame = XCAR (XCDR (c));
3002		  Vlast_event_frame = internal_last_event_frame;
3003		}
3004	    }
3005
3006	  /* If current_kboard's side queue is empty check the other kboards.
3007	     If one of them has data that we have not yet seen here,
3008	     switch to it and process the data waiting for it.
3009
3010	     Note: if the events queued up for another kboard
3011	     have already been seen here, and therefore are not a complete command,
3012	     the kbd_queue_has_data field is 0, so we skip that kboard here.
3013	     That's to avoid an infinite loop switching between kboards here.  */
3014	  if (NILP (c) && !single_kboard)
3015	    {
3016	      KBOARD *kb;
3017	      for (kb = all_kboards; kb; kb = kb->next_kboard)
3018		if (kb->kbd_queue_has_data)
3019		  {
3020		    current_kboard = kb;
3021	            return make_fixnum (-2); /* wrong_kboard_jmpbuf */
3022		  }
3023	    }
3024
3025	 wrong_kboard:
3026
3027	  STOP_POLLING;
3028
3029	  if (NILP (c))
3030	    {
3031	      c = read_decoded_event_from_main_queue (end_time, local_getcjmp,
3032	                                              prev_event, used_mouse_menu);
3033	      if (NILP (c) && end_time
3034		  && timespec_cmp (*end_time, current_timespec ()) <= 0)
3035	        {
3036	          goto exit;
3037	        }
3038
3039	      if (BASE_EQ (c, make_fixnum (-2)))
3040		return c;
3041
3042	      if (CONSP (c) && EQ (XCAR (c), Qt))
3043		c = XCDR (c);
3044	      else if (CONSP (c) && EQ (XCAR (c), Qno_record))
3045		{
3046		  c = XCDR (c);
3047		  recorded = true;
3048		}
3049
3050	      c_volatile = c;
3051	  }
3052
3053	 non_reread:
3054
3055	  if (!end_time)
3056	    timer_stop_idle ();
3057	  RESUME_POLLING;
3058
3059	  if (NILP (c))
3060	    {
3061	      if (commandflag >= 0
3062		  && !input_pending && !detect_input_pending_run_timers (0))
3063		redisplay ();
3064
3065	      goto wrong_kboard;
3066	    }
3067
3068	  /* Buffer switch events are only for internal wakeups
3069	     so don't show them to the user.
3070	     Also, don't record a key if we already did.  */
3071	  if (BUFFERP (c))
3072	    goto exit;
3073
3074	  /* Process special events within read_char
3075	     and loop around to read another event.  */
3076	  save = Vquit_flag;
3077	  Vquit_flag = Qnil;
3078	  tem = access_keymap (get_keymap (Vspecial_event_map, 0, 1), c, 0, 0, 1);
3079	  Vquit_flag = save;
3080
3081	  if (!NILP (tem))
3082	    {
3083	      struct buffer *prev_buffer = current_buffer;
3084	      last_input_event = c;
3085
3086	      calln (Qcommand_execute, tem, Qnil, Fvector (1, &last_input_event), Qt);
3087
3088	      if (CONSP (c) && !NILP (Fmemq (XCAR (c), Vwhile_no_input_ignore_events))
3089		  && !end_time)
3090		/* We stopped being idle for this event; undo that.  This
3091		   prevents automatic window selection (under
3092		   mouse-autoselect-window) from acting as a real input event, for
3093		   example banishing the mouse under mouse-avoidance-mode.  */
3094		timer_resume_idle ();
3095
3096	#ifdef HAVE_NS
3097	      if (CONSP (c)
3098	          && (EQ (XCAR (c), Qns_unput_working_text)))
3099	        input_was_pending = input_pending;
3100	#endif
3101
3102	      if (current_buffer != prev_buffer)
3103		{
3104		  /* The command may have changed the keymaps.  Pretend there
3105		     is input in another keyboard and return.  This will
3106		     recalculate keymaps.  */
3107		  c = make_fixnum (-2);
3108		  goto exit;
3109		}
3110	      else
3111		goto retry;
3112	    }
3113
3114	  /* Handle things that only apply to characters.  */
3115	  if (FIXNUMP (c))
3116	    {
3117	      /* If kbd_buffer_get_event gave us an EOF, return that.  */
3118	      if (XFIXNUM (c) == -1)
3119		goto exit;
3120
3121	      if ((STRINGP (KVAR (current_kboard, Vkeyboard_translate_table))
3122		   && XFIXNAT (c) < SCHARS (KVAR (current_kboard,
3123						  Vkeyboard_translate_table)))
3124		  || (VECTORP (KVAR (current_kboard, Vkeyboard_translate_table))
3125		      && XFIXNAT (c) < ASIZE (KVAR (current_kboard,
3126						    Vkeyboard_translate_table)))
3127		  || (CHAR_TABLE_P (KVAR (current_kboard, Vkeyboard_translate_table))
3128		      && CHARACTERP (c)))
3129		{
3130		  Lisp_Object d;
3131		  d = Faref (KVAR (current_kboard, Vkeyboard_translate_table), c);
3132		  /* nil in keyboard-translate-table means no translation.  */
3133		  if (!NILP (d))
3134		    c_volatile = c = d;
3135		}
3136	    }
3137
3138	  /* If this event is a mouse click in the menu bar,
3139	     return just menu-bar for now.  Modify the mouse click event
3140	     so we won't do this twice, then queue it up.  */
3141	  if (EVENT_HAS_PARAMETERS (c)
3142	      && CONSP (XCDR (c))
3143	      && CONSP (xevent_start (c))
3144	      && CONSP (XCDR (xevent_start (c))))
3145	    {
3146	      Lisp_Object posn;
3147
3148	      posn = POSN_POSN (xevent_start (c));
3149	      /* Handle menu-bar events:
3150		 insert the dummy prefix event `menu-bar'.  */
3151	      if (EQ (posn, Qmenu_bar) || EQ (posn, Qtab_bar) || EQ (posn, Qtool_bar))
3152		{
3153		  /* Change menu-bar to (menu-bar) as the event "position".  */
3154		  POSN_SET_POSN (xevent_start (c), list1 (posn));
3155
3156		  /* Should a command call `sit-for', or another command that
3157		     provides a timespec to Fread_event and co., the original
3158		     event will not subsequently be entered into
3159		     this_command_keys unless Qt be specified below.
3160
3161		     The same is the case in a number of other scenarios where
3162		     reread is true, but if so, event recording is to be
3163		     suppressed anyway.  */
3164
3165		  if (end_time)
3166		    Vunread_command_events = Fcons (Fcons (Qt, c),
3167						    Vunread_command_events);
3168		  else
3169		    {
3170		      also_record = c;
3171		      Vunread_command_events = Fcons (c, Vunread_command_events);
3172		    }
3173		  c = posn;
3174		  c_volatile = c;
3175		}
3176	    }
3177
3178	  /* Store these characters into recent_keys, the dribble file if any,
3179	     and the keyboard macro being defined, if any.  */
3180	  record_char (c);
3181	  recorded = true;
3182	  if (! NILP (also_record))
3183	    record_char (also_record);
3184
3185	  /* Wipe the echo area.
3186	     But first, if we are about to use an input method,
3187	     save the echo area contents for it to refer to.  */
3188	  if (FIXNUMP (c)
3189	      && ! NILP (Vinput_method_function)
3190	      && ' ' <= XFIXNUM (c) && XFIXNUM (c) < 256 && XFIXNUM (c) != 127)
3191	    {
3192	      previous_echo_area_message = Fcurrent_message ();
3193	      Vinput_method_previous_message = previous_echo_area_message;
3194	    }
3195
3196	  /* Now wipe the echo area, except for help events which do their
3197	     own stuff with the echo area.  */
3198	  if (!CONSP (c)
3199	      || (!(EQ (Qhelp_echo, XCAR (c)))
3200		  && !(EQ (Qswitch_frame, XCAR (c)))
3201		  /* Don't wipe echo area for select window events: These might
3202		     get delayed via `mouse-autoselect-window' (Bug#11304).  */
3203		  && !(EQ (Qselect_window, XCAR (c)))))
3204	    {
3205	      if (!NILP (echo_area_buffer[0]))
3206		{
3207		  safe_run_hooks (Qecho_area_clear_hook);
3208		  clear_message (1, 0);
3209		  /* If we were showing the echo-area message on top of an
3210		     active minibuffer, resize the mini-window, since the
3211		     minibuffer may need more or less space than the echo area
3212		     we've just wiped.  */
3213		  if (minibuf_level
3214		      && EQ (minibuf_window, echo_area_window)
3215		      /* The case where minibuffer-message-timeout is a number
3216			 was already handled near the beginning of command_loop_1.  */
3217		      && !NUMBERP (Vminibuffer_message_timeout))
3218		    resize_mini_window (XWINDOW (minibuf_window), false);
3219		}
3220	      else if (FUNCTIONP (Vclear_message_function))
3221	        clear_message (1, 0);
3222	    }
3223
3224	 reread_for_input_method:
3225	 from_macro:
3226	  /* Pass this to the input method, if appropriate.  */
3227	  if (FIXNUMP (c)
3228	      && ! NILP (Vinput_method_function)
3229	      /* Don't run the input method within a key sequence,
3230		 after the first event of the key sequence.  */
3231	      && NILP (prev_event)
3232	      && ' ' <= XFIXNUM (c) && XFIXNUM (c) < 256 && XFIXNUM (c) != 127)
3233	    {
3234	      Lisp_Object keys;
3235	      ptrdiff_t key_count;
3236	      ptrdiff_t command_key_start;
3237	      specpdl_ref count = SPECPDL_INDEX ();
3238
3239	      /* Save the echo status.  */
3240	      bool saved_immediate_echo = current_kboard->immediate_echo;
3241	      struct kboard *saved_ok_to_echo = ok_to_echo_at_next_pause;
3242	      Lisp_Object saved_echo_string = KVAR (current_kboard, echo_string);
3243	      Lisp_Object saved_echo_prompt = KVAR (current_kboard, echo_prompt);
3244
3245	      /* Save the this_command_keys status.  */
3246	      key_count = this_command_key_count;
3247	      command_key_start = this_single_command_key_start;
3248
3249	      if (key_count > 0)
3250		keys = Fcopy_sequence (this_command_keys);
3251	      else
3252		keys = Qnil;
3253
3254	      /* Clear out this_command_keys.  */
3255	      this_command_key_count = 0;
3256	      this_single_command_key_start = 0;
3257
3258	      /* Now wipe the echo area.  */
3259	      if (!NILP (echo_area_buffer[0]))
3260		safe_run_hooks (Qecho_area_clear_hook);
3261	      clear_message (1, 0);
3262	      echo_truncate (0);
3263
3264	      /* If we are not reading a key sequence,
3265		 never use the echo area.  */
3266	      if (!KEYMAPP (map))
3267		{
3268		  specbind (Qinput_method_use_echo_area, Qt);
3269		}
3270
3271	      /* Call the input method.  */
3272	      tem = calln (Vinput_method_function, c);
3273
3274	      tem = unbind_to (count, tem);
3275
3276	      /* Restore the saved echoing state
3277		 and this_command_keys state.  */
3278	      this_command_key_count = key_count;
3279	      this_single_command_key_start = command_key_start;
3280	      if (key_count > 0)
3281		this_command_keys = keys;
3282
3283	      cancel_echoing ();
3284	      ok_to_echo_at_next_pause = saved_ok_to_echo;
3285	      kset_echo_string (current_kboard, saved_echo_string);
3286	      kset_echo_prompt (current_kboard, saved_echo_prompt);
3287	      if (saved_immediate_echo)
3288		echo_now ();
3289
3290	      /* The input method can return no events.  */
3291	      if (! CONSP (tem))
3292		{
3293		  /* Bring back the previous message, if any.  */
3294		  if (! NILP (previous_echo_area_message))
3295		    message_with_string ("%s", previous_echo_area_message, 0);
3296		  goto retry;
3297		}
3298	      /* It returned one event or more.  */
3299	      c = XCAR (tem);
3300	      c_volatile = c;
3301	      Vunread_post_input_method_events
3302		= nconc2 (XCDR (tem), Vunread_post_input_method_events);
3303	    }
3304	  /* When we consume events from the various unread-*-events lists, we
3305	     bypass the code that records input, so record these events now if
3306	     they were not recorded already.  */
3307	  if (!recorded)
3308	    {
3309	      record_char (c);
3310	      recorded = true;
3311	    }
3312
3313	 reread_first:
3314
3315	  /* Display help if not echoing.  */
3316	  if (CONSP (c) && EQ (XCAR (c), Qhelp_echo))
3317	    {
3318	      /* (help-echo FRAME HELP WINDOW OBJECT POS).  */
3319	      Lisp_Object help, object, position, window, htem;
3320
3321	      htem = Fcdr (XCDR (c));
3322	      help = Fcar (htem);
3323	      htem = Fcdr (htem);
3324	      window = Fcar (htem);
3325	      htem = Fcdr (htem);
3326	      object = Fcar (htem);
3327	      htem = Fcdr (htem);
3328	      position = Fcar (htem);
3329
3330	      show_help_echo (help, window, object, position);
3331
3332	      /* We stopped being idle for this event; undo that.  */
3333	      if (!end_time)
3334		timer_resume_idle ();
3335	      goto retry;
3336	    }
3337
3338	  if ((! reread || this_command_key_count == 0)
3339	      && !end_time)
3340	    {
3341
3342	      /* Don't echo mouse motion events.  */
3343	      if (! (EVENT_HAS_PARAMETERS (c)
3344		     && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement)))
3345		/* Once we reread a character, echoing can happen
3346		   the next time we pause to read a new one.  */
3347		ok_to_echo_at_next_pause = current_kboard;
3348
3349	      /* Record this character as part of the current key.  */
3350	      add_command_key (c);
3351	      if (! NILP (also_record))
3352		add_command_key (also_record);
3353
3354	      echo_update ();
3355	    }
3356
3357	  last_input_event = c;
3358	  num_input_events++;
3359
3360	  /* Process the help character specially if enabled.  */
3361	  if (!NILP (Vhelp_form) && help_char_p (c))
3362	    {
3363	      specpdl_ref count = SPECPDL_INDEX ();
3364
3365	      help_form_saved_window_configs
3366		= Fcons (Fcurrent_window_configuration (Qnil),
3367			 help_form_saved_window_configs);
3368	      record_unwind_protect_void (read_char_help_form_unwind);
3369	      call0 (Qhelp_form_show);
3370
3371	      cancel_echoing ();
3372	      do
3373		{
3374		  c = read_char (0, Qnil, Qnil, 0, NULL);
3375		  c_volatile = c;
3376		  if (EVENT_HAS_PARAMETERS (c)
3377		      && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_click))
3378		    XSETCAR (help_form_saved_window_configs, Qnil);
3379		}
3380	      while (BUFFERP (c));
3381	      /* Remove the help from the frame.  */
3382	      unbind_to (count, Qnil);
3383
3384	      redisplay ();
3385	      if (BASE_EQ (c, make_fixnum (040)))
3386		{
3387		  cancel_echoing ();
3388		  do
3389		    c_volatile = c = read_char (0, Qnil, Qnil, 0, NULL);
3390		  while (BUFFERP (c));
3391		}
3392	    }
3393
3394	 exit:
3395	  RESUME_POLLING;
3396	  input_was_pending = input_pending;
3397	  return c;
3398	}
3399
3400	/* Record a key that came from a mouse menu.
3401	   Record it for echoing, for this-command-keys, and so on.  */
3402
3403	static void
3404	record_menu_key (Lisp_Object c)
3405	{
3406	  /* Wipe the echo area.  */
3407	  clear_message (1, 0);
3408
3409	  record_char (c);
3410
3411	  /* Once we reread a character, echoing can happen
3412	     the next time we pause to read a new one.  */
3413	  ok_to_echo_at_next_pause = NULL;
3414
3415	  /* Record this character as part of the current key.  */
3416	  add_command_key (c);
3417	  echo_update ();
3418
3419	  /* Re-reading in the middle of a command.  */
3420	  last_input_event = c;
3421	  num_input_events++;
3422	}
3423
3424	/* Return true if should recognize C as "the help character".  */
3425
3426	static bool
3427	help_char_p (Lisp_Object c)
3428	{
3429	  if (EQ (c, Vhelp_char))
3430	    return true;
3431	  Lisp_Object tail = Vhelp_event_list;
3432	  FOR_EACH_TAIL_SAFE (tail)
3433	    if (EQ (c, XCAR (tail)))
3434	      return true;
3435	  return false;
3436	}
3437
3438	/* Record the input event C in various ways.  */
3439
3440	static void
3441	record_char (Lisp_Object c)
3442	{
3443	  /* subr.el/read-passwd binds inhibit_record_char to avoid recording
3444	     passwords.  */
3445	  if (!record_all_keys && inhibit_record_char)
3446	    return;
3447
3448	  int recorded = 0;
3449
3450	  if (CONSP (c) && (EQ (XCAR (c), Qhelp_echo) || EQ (XCAR (c), Qmouse_movement)))
3451	    {
3452	      /* To avoid filling recent_keys with help-echo and mouse-movement
3453		 events, we filter out repeated help-echo events, only store the
3454		 first and last in a series of mouse-movement events, and don't
3455		 store repeated help-echo events which are only separated by
3456		 mouse-movement events.  */
3457
3458	      Lisp_Object ev1, ev2, ev3;
3459	      int ix1, ix2, ix3;
3460
3461	      if ((ix1 = recent_keys_index - 1) < 0)
3462		ix1 = lossage_limit - 1;
3463	      ev1 = AREF (recent_keys, ix1);
3464
3465	      if ((ix2 = ix1 - 1) < 0)
3466		ix2 = lossage_limit - 1;
3467	      ev2 = AREF (recent_keys, ix2);
3468
3469	      if ((ix3 = ix2 - 1) < 0)
3470		ix3 = lossage_limit - 1;
3471	      ev3 = AREF (recent_keys, ix3);
3472
3473	      if (EQ (XCAR (c), Qhelp_echo))
3474		{
3475		  /* Don't record `help-echo' in recent_keys unless it shows some help
3476		     message, and a different help than the previously recorded
3477		     event.  */
3478		  Lisp_Object help, last_help;
3479
3480		  help = Fcar_safe (Fcdr_safe (XCDR (c)));
3481		  if (!STRINGP (help))
3482		    recorded = 1;
3483		  else if (CONSP (ev1) && EQ (XCAR (ev1), Qhelp_echo)
3484			   && (last_help = Fcar_safe (Fcdr_safe (XCDR (ev1))), EQ (last_help, help)))
3485		    recorded = 1;
3486		  else if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
3487			   && CONSP (ev2) && EQ (XCAR (ev2), Qhelp_echo)
3488			   && (last_help = Fcar_safe (Fcdr_safe (XCDR (ev2))), EQ (last_help, help)))
3489		    recorded = -1;
3490		  else if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
3491			   && CONSP (ev2) && EQ (XCAR (ev2), Qmouse_movement)
3492			   && CONSP (ev3) && EQ (XCAR (ev3), Qhelp_echo)
3493			   && (last_help = Fcar_safe (Fcdr_safe (XCDR (ev3))), EQ (last_help, help)))
3494		    recorded = -2;
3495		}
3496	      else if (EQ (XCAR (c), Qmouse_movement))
3497		{
3498		  /* Only record one pair of `mouse-movement' on a window in recent_keys.
3499		     So additional mouse movement events replace the last element.  */
3500		  Lisp_Object last_window, window;
3501
3502		  window = Fcar_safe (Fcar_safe (XCDR (c)));
3503		  if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
3504		      && (last_window = Fcar_safe (Fcar_safe (XCDR (ev1))), EQ (last_window, window))
3505		      && CONSP (ev2) && EQ (XCAR (ev2), Qmouse_movement)
3506		      && (last_window = Fcar_safe (Fcar_safe (XCDR (ev2))), EQ (last_window, window)))
3507		    {
3508		      ASET (recent_keys, ix1, c);
3509		      recorded = 1;
3510		    }
3511		}
3512	    }
3513	  else if (NILP (Vexecuting_kbd_macro))
3514	    store_kbd_macro_char (c);
3515
3516	  /* recent_keys should not include events from keyboard macros.  */
3517	  if (NILP (Vexecuting_kbd_macro))
3518	    {
3519	      if (!recorded)
3520		{
3521		  total_keys += total_keys < lossage_limit;
3522		  ASET (recent_keys, recent_keys_index,
3523	                /* Copy the event, in case it gets modified by side-effect
3524	                   by some remapping function (bug#30955).  */
3525	                CONSP (c) ? Fcopy_sequence (c) : c);
3526		  if (++recent_keys_index >= lossage_limit)
3527		    recent_keys_index = 0;
3528		}
3529	      else if (recorded < 0)
3530		{
3531		  /* We need to remove one or two events from recent_keys.
3532		     To do this, we simply put nil at those events and move the
3533		     recent_keys_index backwards over those events.  Usually,
3534		     users will never see those nil events, as they will be
3535		     overwritten by the command keys entered to see recent_keys
3536		     (e.g. C-h l).  */
3537
3538		  while (recorded++ < 0 && total_keys > 0)
3539		    {
3540		      if (total_keys < lossage_limit)
3541			total_keys--;
3542		      if (--recent_keys_index < 0)
3543			recent_keys_index = lossage_limit - 1;
3544		      ASET (recent_keys, recent_keys_index, Qnil);
3545		    }
3546		}
3547
3548	      num_nonmacro_input_events++;
3549	    }
3550
3551	  /* Write c to the dribble file.  If c is a lispy event, write
3552	     the event's symbol to the dribble file, in <brackets>.  Bleaugh.
3553	     If you, dear reader, have a better idea, you've got the source.  :-) */
3554	  if (dribble && NILP (Vexecuting_kbd_macro))
3555	    {
3556	      block_input ();
3557	      if (FIXNUMP (c))
3558		{
3559		  if (XUFIXNUM (c) < 0x100)
3560		    putc (XUFIXNUM (c), dribble);
3561		  else
3562		    fprintf (dribble, " 0x%"pI"x", XUFIXNUM (c));
3563		}
3564	      else
3565		{
3566		  Lisp_Object dribblee;
3567
3568		  /* If it's a structured event, take the event header.  */
3569		  dribblee = EVENT_HEAD (c);
3570
3571		  if (SYMBOLP (dribblee))
3572		    {
3573		      putc ('<', dribble);
3574		      fwrite (SDATA (SYMBOL_NAME (dribblee)), sizeof (char),
3575			      SBYTES (SYMBOL_NAME (dribblee)), dribble);
3576		      putc ('>', dribble);
3577		    }
3578		}
3579
3580	      fflush (dribble);
3581	      unblock_input ();
3582	    }
3583	}
3584
3585	/* Copy out or in the info on where C-g should throw to.
3586	   This is used when running Lisp code from within get_char,
3587	   in case get_char is called recursively.
3588	   See read_process_output.  */
3589
3590	static void
3591	save_getcjmp (sys_jmp_buf temp)
3592	{
3593	  memcpy (temp, getcjmp, sizeof getcjmp);
3594	}
3595
3596	static void
3597	restore_getcjmp (void *temp)
3598	{
3599	  memcpy (getcjmp, temp, sizeof getcjmp);
3600	}
3601	^L
3602	/* Low level keyboard/mouse input.
3603	   kbd_buffer_store_event places events in kbd_buffer, and
3604	   kbd_buffer_get_event retrieves them.  */
3605
3606	/* Return true if there are any events in the queue that read-char
3607	   would return.  If this returns false, a read-char would block.  */
3608	static bool
3609	readable_events (int flags)
3610	{
3611	  if (flags & READABLE_EVENTS_DO_TIMERS_NOW)
3612	    timer_check ();
3613
3614	  /* READABLE_EVENTS_FILTER_EVENTS is meant to be used only by
3615	     input-pending-p and similar callers, which aren't interested in
3616	     some input events.  If this flag is set, and
3617	     input-pending-p-filter-events is non-nil, ignore events in
3618	     while-no-input-ignore-events.  If the flag is set and
3619	     input-pending-p-filter-events is nil, ignore only
3620	     FOCUS_IN/OUT_EVENT events.  */
3621	  if (kbd_fetch_ptr != kbd_store_ptr)
3622	    {
3623	      /* See https://lists.gnu.org/r/emacs-devel/2005-05/msg00297.html
3624		 for why we treat toolkit scroll-bar events specially here.  */
3625	      if (flags & (READABLE_EVENTS_FILTER_EVENTS
3626	#ifdef USE_TOOLKIT_SCROLL_BARS
3627			   | READABLE_EVENTS_IGNORE_SQUEEZABLES
3628	#endif
3629			   ))
3630	        {
3631	          union buffered_input_event *event = kbd_fetch_ptr;
3632
3633		  do
3634		    {
3635		      if (!(
3636	#ifdef USE_TOOLKIT_SCROLL_BARS
3637			    (flags & READABLE_EVENTS_FILTER_EVENTS) &&
3638	#endif
3639			    ((!input_pending_p_filter_events
3640			      && (event->kind == FOCUS_IN_EVENT
3641				  || event->kind == FOCUS_OUT_EVENT))
3642			     || (input_pending_p_filter_events
3643				 && is_ignored_event (event))))
3644	#ifdef USE_TOOLKIT_SCROLL_BARS
3645			  && !((flags & READABLE_EVENTS_IGNORE_SQUEEZABLES)
3646			       && (event->kind == SCROLL_BAR_CLICK_EVENT
3647				   || event->kind == HORIZONTAL_SCROLL_BAR_CLICK_EVENT)
3648			       && event->ie.part == scroll_bar_handle
3649			       && event->ie.modifiers == 0)
3650	#endif
3651			 )
3652			return 1;
3653		      event = next_kbd_event (event);
3654		    }
3655		  while (event != kbd_store_ptr);
3656	        }
3657	      else
3658		return 1;
3659	    }
3660
3661	#ifdef HAVE_X_WINDOWS
3662	  if (x_detect_pending_selection_requests ())
3663	    return 1;
3664	#endif
3665
3666	#ifdef HAVE_TEXT_CONVERSION
3667	  if (detect_conversion_events ())
3668	    return 1;
3669	#endif
3670
3671	  if (!(flags & READABLE_EVENTS_IGNORE_SQUEEZABLES) && some_mouse_moved ())
3672	    return 1;
3673	  if (single_kboard)
3674	    {
3675	      if (current_kboard->kbd_queue_has_data)
3676		return 1;
3677	    }
3678	  else
3679	    {
3680	      KBOARD *kb;
3681	      for (kb = all_kboards; kb; kb = kb->next_kboard)
3682		if (kb->kbd_queue_has_data)
3683		  return 1;
3684	    }
3685	  return 0;
3686	}
3687
3688	/* Set this for debugging, to have a way to get out */
3689	extern int stop_character;
3690	int stop_character EXTERNALLY_VISIBLE;
3691
3692	static KBOARD *
3693	event_to_kboard (struct input_event *event)
3694	{
3695	  /* Not applicable for these special events.  */
3696	  if (event->kind == SELECTION_REQUEST_EVENT
3697	      || event->kind == SELECTION_CLEAR_EVENT)
3698	    return NULL;
3699	  else
3700	    {
3701	      Lisp_Object obj = event->frame_or_window;
3702	      /* There are some events that set this field to nil or string.  */
3703	      if (WINDOWP (obj))
3704		obj = WINDOW_FRAME (XWINDOW (obj));
3705	      /* Also ignore dead frames here.  */
3706	      return ((FRAMEP (obj) && FRAME_LIVE_P (XFRAME (obj)))
3707		      ? FRAME_KBOARD (XFRAME (obj)) : NULL);
3708	    }
3709	}
3710
3711	#ifdef subprocesses
3712	/* Return the number of slots occupied in kbd_buffer.  */
3713
3714	static int
3715	kbd_buffer_nr_stored (void)
3716	{
3717	  int n = kbd_store_ptr - kbd_fetch_ptr;
3718	  return n + (n < 0 ? KBD_BUFFER_SIZE : 0);
3719	}
3720	#endif	/* Store an event obtained at interrupt level into kbd_buffer, fifo */
3721
3722	void
3723	kbd_buffer_store_event (register struct input_event *event)
3724	{
3725	  kbd_buffer_store_event_hold (event, 0);
3726	}
3727
3728	/* Store EVENT obtained at interrupt level into kbd_buffer, fifo.
3729
3730	   If HOLD_QUIT is 0, just stuff EVENT into the fifo.
3731	   Else, if HOLD_QUIT.kind != NO_EVENT, discard EVENT.
3732	   Else, if EVENT is a quit event, store the quit event
3733	   in HOLD_QUIT, and return (thus ignoring further events).
3734
3735	   This is used to postpone the processing of the quit event until all
3736	   subsequent input events have been parsed (and discarded).  */
3737
3738	void
3739	kbd_buffer_store_buffered_event (union buffered_input_event *event,
3740					 struct input_event *hold_quit)
3741	{
3742	  if (event->kind == NO_EVENT)
3743	    emacs_abort ();
3744
3745	  if (hold_quit && hold_quit->kind != NO_EVENT)
3746	    return;
3747
3748	  if (event->kind == ASCII_KEYSTROKE_EVENT)
3749	    {
3750	      int c = event->ie.code & 0377;
3751
3752	      if (event->ie.modifiers & ctrl_modifier)
3753		c = make_ctrl_char (c);
3754
3755	      c |= (event->ie.modifiers
3756		    & (meta_modifier | alt_modifier
3757		       | hyper_modifier | super_modifier));
3758
3759	      if (c == quit_char)
3760		{
3761		  KBOARD *kb = FRAME_KBOARD (XFRAME (event->ie.frame_or_window));
3762
3763		  if (single_kboard && kb != current_kboard)
3764		    {
3765		      kset_kbd_queue
3766			(kb, list2 (make_lispy_switch_frame (event->ie.frame_or_window),
3767				    make_fixnum (c)));
3768		      kb->kbd_queue_has_data = true;
3769
3770		      for (union buffered_input_event *sp = kbd_fetch_ptr;
3771			   sp != kbd_store_ptr; sp = next_kbd_event (sp))
3772			{
3773			  if (event_to_kboard (&sp->ie) == kb)
3774			    {
3775			      sp->ie.kind = NO_EVENT;
3776			      sp->ie.frame_or_window = Qnil;
3777			      sp->ie.arg = Qnil;
3778			    }
3779			}
3780		      return;
3781		    }
3782
3783		  if (hold_quit)
3784		    {
3785		      *hold_quit = event->ie;
3786		      return;
3787		    }
3788
3789		  /* If this results in a quit_char being returned to Emacs as
3790		     input, set Vlast_event_frame properly.  If this doesn't
3791		     get returned to Emacs as an event, the next event read
3792		     will set Vlast_event_frame again, so this is safe to do.  */
3793		  {
3794		    Lisp_Object focus;
3795
3796		    focus = FRAME_FOCUS_FRAME (XFRAME (event->ie.frame_or_window));
3797		    if (NILP (focus))
3798		      focus = event->ie.frame_or_window;
3799		    internal_last_event_frame = focus;
3800		    Vlast_event_frame = focus;
3801		  }
3802
3803		  handle_interrupt (0);
3804		  return;
3805		}
3806
3807	      if (c && c == stop_character)
3808		{
3809		  sys_suspend ();
3810		  return;
3811		}
3812	    }
3813
3814	  /* Don't let the very last slot in the buffer become full,
3815	     since that would make the two pointers equal,
3816	     and that is indistinguishable from an empty buffer.
3817	     Discard the event if it would fill the last slot.  */
3818	  union buffered_input_event *next_slot = next_kbd_event (kbd_store_ptr);
3819	  if (kbd_fetch_ptr != next_slot)
3820	    {
3821	      *kbd_store_ptr = *event;
3822	      kbd_store_ptr = next_slot;
3823	#ifdef subprocesses
3824	      if (kbd_buffer_nr_stored () > KBD_BUFFER_SIZE / 2
3825		  && ! kbd_on_hold_p ())
3826	        {
3827	          /* Don't read keyboard input until we have processed kbd_buffer.
3828	             This happens when pasting text longer than KBD_BUFFER_SIZE/2.  */
3829	          hold_keyboard_input ();
3830	          unrequest_sigio ();
3831	          stop_polling ();
3832	        }
3833	#endif	/* subprocesses */
3834	    }
3835
3836	  /* If we're inside while-no-input, and this event qualifies
3837	     as input, set quit-flag to cause an interrupt.  */
3838	  if (!NILP (Vthrow_on_input)
3839	      && !is_ignored_event (event))
3840	    Vquit_flag = Vthrow_on_input;
3841	}
3842
3843	/* Limit help event positions to this range, to avoid overflow problems.  */
3844	#define INPUT_EVENT_POS_MAX \
3845	  ((ptrdiff_t) min (PTRDIFF_MAX, min (TYPE_MAXIMUM (Time) / 2, \
3846					      MOST_POSITIVE_FIXNUM)))
3847	#define INPUT_EVENT_POS_MIN (PTRDIFF_MIN < -INPUT_EVENT_POS_MAX \
3848				     ? -1 - INPUT_EVENT_POS_MAX : PTRDIFF_MIN)
3849
3850	/* Return a Time that encodes position POS.  POS must be in range.  */
3851
3852	static Time
3853	position_to_Time (ptrdiff_t pos)
3854	{
3855	  eassert (INPUT_EVENT_POS_MIN <= pos && pos <= INPUT_EVENT_POS_MAX);
3856	  return pos;
3857	}
3858
3859	/* Return the position that ENCODED_POS encodes.
3860	   Avoid signed integer overflow.  */
3861
3862	static ptrdiff_t
3863	Time_to_position (Time encoded_pos)
3864	{
3865	  if (encoded_pos <= INPUT_EVENT_POS_MAX)
3866	    return encoded_pos;
3867	  Time encoded_pos_min = position_to_Time (INPUT_EVENT_POS_MIN);
3868	  eassert (encoded_pos_min <= encoded_pos);
3869	  ptrdiff_t notpos = -1 - encoded_pos;
3870	  return -1 - notpos;
3871	}
3872
3873	/* Generate a HELP_EVENT input_event and store it in the keyboard
3874	   buffer.
3875
3876	   HELP is the help form.
3877
3878	   FRAME and WINDOW are the frame and window where the help is
3879	   generated.  OBJECT is the Lisp object where the help was found (a
3880	   buffer, a string, an overlay, or nil if neither from a string nor
3881	   from a buffer).  POS is the position within OBJECT where the help
3882	   was found.  */
3883
3884	void
3885	gen_help_event (Lisp_Object help, Lisp_Object frame, Lisp_Object window,
3886			Lisp_Object object, ptrdiff_t pos)
3887	{
3888	  struct input_event event;
3889	  EVENT_INIT (event);
3890
3891	  event.kind = HELP_EVENT;
3892	  event.frame_or_window = frame;
3893	  event.arg = object;
3894	  event.x = WINDOWP (window) ? window : frame;
3895	  event.y = help;
3896	  event.timestamp = position_to_Time (pos);
3897	  kbd_buffer_store_event (&event);
3898	}
3899
3900
3901	/* Store HELP_EVENTs for HELP on FRAME in the input queue.  */
3902
3903	void
3904	kbd_buffer_store_help_event (Lisp_Object frame, Lisp_Object help)
3905	{
3906	  struct input_event event;
3907	  EVENT_INIT (event);
3908
3909	  event.kind = HELP_EVENT;
3910	  event.frame_or_window = frame;
3911	  event.arg = Qnil;
3912	  event.x = Qnil;
3913	  event.y = help;
3914	  event.timestamp = 0;
3915	  kbd_buffer_store_event (&event);
3916	}
3917
3918	^L
3919	/* Discard any mouse events in the event buffer by setting them to
3920	   NO_EVENT.  */
3921	void
3922	discard_mouse_events (void)
3923	{
3924	  for (union buffered_input_event *sp = kbd_fetch_ptr;
3925	       sp != kbd_store_ptr; sp = next_kbd_event (sp))
3926	    {
3927	      if (sp->kind == MOUSE_CLICK_EVENT
3928		  || sp->kind == WHEEL_EVENT
3929	          || sp->kind == HORIZ_WHEEL_EVENT
3930		  || sp->kind == SCROLL_BAR_CLICK_EVENT
3931		  || sp->kind == HORIZONTAL_SCROLL_BAR_CLICK_EVENT)
3932		{
3933		  sp->kind = NO_EVENT;
3934		}
3935	    }
3936	}
3937
3938
3939	/* Return true if there are any real events waiting in the event
3940	   buffer, not counting `NO_EVENT's.
3941
3942	   Discard NO_EVENT events at the front of the input queue, possibly
3943	   leaving the input queue empty if there are no real input events.  */
3944
3945	bool
3946	kbd_buffer_events_waiting (void)
3947	{
3948	  for (union buffered_input_event *sp = kbd_fetch_ptr;
3949	       ; sp = next_kbd_event (sp))
3950	    if (sp == kbd_store_ptr || sp->kind != NO_EVENT)
3951	      {
3952		kbd_fetch_ptr = sp;
3953		return sp != kbd_store_ptr && sp->kind != NO_EVENT;
3954	      }
3955	}
3956
3957	^L
3958	/* Clear input event EVENT.  */
3959
3960	static void
3961	clear_event (struct input_event *event)
3962	{
3963	  event->kind = NO_EVENT;
3964	}
3965
3966	static Lisp_Object
3967	kbd_buffer_get_event_1 (Lisp_Object arg)
3968	{
3969	  Lisp_Object coding_system = Fget_text_property (make_fixnum (0),
3970							  Qcoding, arg);
3971
3972	  if (EQ (coding_system, Qt))
3973	    return arg;
3974
3975	  return code_convert_string (arg, (!NILP (coding_system)
3976					    ? coding_system
3977					    : Vlocale_coding_system),
3978				      Qnil, 0, false, 0);
3979	}
3980
3981	static Lisp_Object
3982	kbd_buffer_get_event_2 (Lisp_Object val)
3983	{
3984	  return Qnil;
3985	}
3986
3987	/* Read one event from the event buffer, waiting if necessary.
3988	   The value is a Lisp object representing the event.
3989	   The value is nil for an event that should be ignored,
3990	   or that was handled here.
3991	   We always read and discard one event.  */
3992
3993	static Lisp_Object
3994	kbd_buffer_get_event (KBOARD **kbp,
3995	                      bool *used_mouse_menu,
3996	                      struct timespec *end_time)
3997	{
3998	  Lisp_Object obj, str;
3999	#ifdef HAVE_X_WINDOWS
4000	  bool had_pending_selection_requests;
4001
4002	  had_pending_selection_requests = false;
4003	#endif
4004	#ifdef HAVE_TEXT_CONVERSION
4005	  bool had_pending_conversion_events;
4006
4007	  had_pending_conversion_events = false;
4008	#endif
4009
4010	#ifdef subprocesses
4011	  if (kbd_on_hold_p () && kbd_buffer_nr_stored () < KBD_BUFFER_SIZE / 4)
4012	    {
4013	      /* Start reading input again because we have processed enough to
4014	         be able to accept new events again.  */
4015	      unhold_keyboard_input ();
4016	      request_sigio ();
4017	      start_polling ();
4018	    }
4019	#endif	/* subprocesses */
4020
4021	#if !defined HAVE_DBUS && !defined USE_FILE_NOTIFY && !defined THREADS_ENABLED
4022	  if (noninteractive
4023	      /* In case we are running as a daemon, only do this before
4024		 detaching from the terminal.  */
4025	      || (IS_DAEMON && DAEMON_RUNNING))
4026	    {
4027	      int c = getchar ();
4028	      XSETINT (obj, c);
4029	      *kbp = current_kboard;
4030	      return obj;
4031	    }
4032	#endif	/* !defined HAVE_DBUS && !defined USE_FILE_NOTIFY && !defined THREADS_ENABLED  */
4033
4034	  *kbp = current_kboard;
4035
4036	  /* Wait until there is input available.  */
4037	  for (;;)
4038	    {
4039	      /* Break loop if there's an unread command event.  Needed in
4040		 moused window autoselection which uses a timer to insert such
4041		 events.  */
4042	      if (CONSP (Vunread_command_events))
4043		break;
4044
4045	#ifdef HAVE_TEXT_CONVERSION
4046	      /* That text conversion events take priority over keyboard
4047		 events, since input methods frequently send them immediately
4048		 after edits, with the assumption that this order of events
4049		 will be observed.  */
4050
4051	      if (detect_conversion_events ())
4052		{
4053		  had_pending_conversion_events = true;
4054		  break;
4055		}
4056	#endif /* HAVE_TEXT_CONVERSION */
4057
4058	      if (kbd_fetch_ptr != kbd_store_ptr)
4059		break;
4060	      if (some_mouse_moved ())
4061		break;
4062
4063	      /* If the quit flag is set, then read_char will return
4064		 quit_char, so that counts as "available input."  */
4065	      if (!NILP (Vquit_flag))
4066		quit_throw_to_read_char (0);
   0x00005555555b2849 <-1859591>:	xor    %edi,%edi
   0x00005555555b284b <-1859589>:	call   0x5555555b1946 <quit_throw_to_read_char>

2991		    emacs_abort ();
   0x00005555555b2850 <-1859584>:	call   0x5555555b39b8 <emacs_abort>

4067
4068	      /* One way or another, wait until input is available; then, if
4069		 interrupt handlers have not read it, read it now.  */
4070
4071	#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
4072	      gobble_input ();
4073	#endif
4074
4075	      if (kbd_fetch_ptr != kbd_store_ptr)
4076		break;
4077	      if (some_mouse_moved ())
4078		break;
4079	#ifdef HAVE_X_WINDOWS
4080	      if (x_detect_pending_selection_requests ())
4081		{
4082		  had_pending_selection_requests = true;
4083		  break;
4084		}
4085	#endif
4086	      if (end_time)
4087		{
4088		  struct timespec now = current_timespec ();
4089		  if (timespec_cmp (*end_time, now) <= 0)
4090		    return Qnil;	/* Finished waiting.  */
4091		  else
4092		    {
4093		      struct timespec duration = timespec_sub (*end_time, now);
4094		      wait_reading_process_output (min (duration.tv_sec,
4095							WAIT_READING_MAX),
4096						   duration.tv_nsec,
4097						   -1, 1, Qnil, NULL, 0);
4098		    }
4099		}
4100	      else
4101		{
4102		  bool do_display = true;
4103
4104		  if (FRAME_TERMCAP_P (SELECTED_FRAME ()))
   0x00005555555b2855 <-1859579>:	call   0x5555555b39b8 <emacs_abort>
   0x00005555555b285a <-1859574>:	call   0x5555555b172e <XSYMBOL_WITH_POS_SYM>
   0x00005555555b285f <-1859569>:	call   0x5555555b15ba <make_fixed_natnum>
   0x00005555555b2864 <-1859564>:	call   0x5555555b1807 <string_char_and_length>

./src/character.h:
407	  eassume (MAX_4_BYTE_CHAR < d && d <= MAX_5_BYTE_CHAR);
   0x00005555555b2869 <-1859559>:	mov    $0x197,%edx
   0x00005555555b286e <-1859554>:	lea    0x404f40(%rip),%rsi        # 0x5555559b77b5
   0x00005555555b2875 <-1859547>:	lea    0x4067bc(%rip),%rdi        # 0x5555559b9038
   0x00005555555b287c <-1859540>:	call   0x5555555b8f19 <die>

401	      eassume (MAX_3_BYTE_CHAR < d && d <= MAX_4_BYTE_CHAR);
   0x00005555555b2881 <-1859535>:	mov    $0x191,%edx
   0x00005555555b2886 <-1859530>:	lea    0x404f28(%rip),%rsi        # 0x5555559b77b5
   0x00005555555b288d <-1859523>:	lea    0x406774(%rip),%rdi        # 0x5555559b9008
   0x00005555555b2894 <-1859516>:	call   0x5555555b8f19 <die>

./src/keyboard.c:
2793		      emacs_abort ();
   0x00005555555b2899 <-1859511>:	call   0x5555555b39b8 <emacs_abort>

2787		KBOARD *kb = FRAME_KBOARD (XFRAME (selected_frame));
   0x00005555555b289e <-1859506>:	mov    $0xae3,%edx
   0x00005555555b28a3 <-1859501>:	lea    0x41d0ed(%rip),%rsi        # 0x5555559cf997
   0x00005555555b28aa <-1859494>:	lea    0x402b42(%rip),%rdi        # 0x5555559b53f3
   0x00005555555b28b1 <-1859487>:	call   0x5555555b8f19 <die>
   0x00005555555b28b6 <-1859482>:	call   0x5555555b155e <XCONS>
   0x00005555555b28bb <-1859477>:	call   0x5555555b1595 <make_fixnum>

2347		    emacs_abort ();
   0x00005555555b28c0 <-1859472>:	call   0x5555555b39b8 <emacs_abort>
   0x00005555555b28c5 <-1859467>:	call   0x5555555b16f6 <XFIXNUM>

./src/lisp.h:
746	  return lisp_h_XIL (i);
   0x00005555555b28ca <-1859462>:	xor    %esi,%esi
   0x00005555555b28cc <-1859460>:	mov    $0x6,%edi
   0x00005555555b28d1 <-1859455>:	call   0x5555555b11f3 <Fkill_emacs>

./src/keyboard.c:
4306		  focus = FRAME_FOCUS_FRAME (XFRAME (frame));
   0x00005555555b28d6 <-1859450>:	mov    $0x10d2,%edx
   0x00005555555b28db <-1859445>:	lea    0x41d0b5(%rip),%rsi        # 0x5555559cf997
   0x00005555555b28e2 <-1859438>:	lea    0x402950(%rip),%rdi        # 0x5555559b5239
   0x00005555555b28e9 <-1859431>:	call   0x5555555b8f19 <die>
   0x00005555555b28ee <-1859426>:	call   0x5555555b1595 <make_fixnum>
   0x00005555555b28f3 <-1859421>:	call   0x5555555b155e <XCONS>
   0x00005555555b28f8 <-1859416>:	call   0x5555555b16f6 <XFIXNUM>

./src/lisp.h:
3427	  eassert (FLOATP (a));
   0x00005555555b28fd <-1859411>:	mov    $0xd63,%edx
   0x00005555555b2902 <-1859406>:	lea    0x402717(%rip),%rsi        # 0x5555559b5020
   0x00005555555b2909 <-1859399>:	lea    0x403912(%rip),%rdi        # 0x5555559b6222
   0x00005555555b2910 <-1859392>:	call   0x5555555b8f19 <die>
   0x00005555555b2915 <-1859387>:	call   0x5555555b16f6 <XFIXNUM>
   0x00005555555b291a <-1859382>:	mov    $0xd63,%edx
   0x00005555555b291f <-1859377>:	lea    0x4026fa(%rip),%rsi        # 0x5555559b5020
   0x00005555555b2926 <-1859370>:	lea    0x4038f5(%rip),%rdi        # 0x5555559b6222
   0x00005555555b292d <-1859363>:	call   0x5555555b8f19 <die>

./src/keyboard.c:
2459			  eassert (coding->produced_char <= n);
   0x00005555555b2932 <-1859358>:	mov    $0x99b,%edx
   0x00005555555b2937 <-1859353>:	lea    0x41d059(%rip),%rsi        # 0x5555559cf997
   0x00005555555b293e <-1859346>:	lea    0x41d276(%rip),%rdi        # 0x5555559cfbbb
   0x00005555555b2945 <-1859339>:	call   0x5555555b8f19 <die>

4418			  eassert (XFIXNUM (XCAR (event->ie.arg))
   0x00005555555b294a <-1859334>:	mov    $0x1142,%edx
   0x00005555555b294f <-1859329>:	lea    0x41d041(%rip),%rsi        # 0x5555559cf997
   0x00005555555b2956 <-1859322>:	lea    0x41cb93(%rip),%rdi        # 0x5555559cf4f0
   0x00005555555b295d <-1859315>:	call   0x5555555b8f19 <die>
   0x00005555555b2962 <-1859310>:	call   0x5555555b16f6 <XFIXNUM>

4417			  eassert (STRINGP (XCDR (event->ie.arg)));
   0x00005555555b2967 <-1859305>:	mov    $0x1141,%edx
   0x00005555555b296c <-1859300>:	lea    0x41d024(%rip),%rsi        # 0x5555559cf997
   0x00005555555b2973 <-1859293>:	lea    0x41cb56(%rip),%rdi        # 0x5555559cf4d0
   0x00005555555b297a <-1859286>:	call   0x5555555b8f19 <die>

4416			  eassert (FIXNUMP (XCAR (event->ie.arg)));
   0x00005555555b297f <-1859281>:	mov    $0x1140,%edx
   0x00005555555b2984 <-1859276>:	lea    0x41d00c(%rip),%rsi        # 0x5555559cf997
   0x00005555555b298b <-1859269>:	lea    0x41cb1e(%rip),%rdi        # 0x5555559cf4b0
   0x00005555555b2992 <-1859262>:	call   0x5555555b8f19 <die>
End of assembler dump.
No symbol "prepare_menu_bars" in current context.
Dump of assembler code from 0x5555555a4270 to 0x5555555a4470:
./src/xdisp.c:
13895		  struct frame *tf = XFRAME (other_frame);
   0x00005555555a4270 <gui_consider_frame_title-680800>:	cmp    $0x413a75,%eax
   0x00005555555a4275 <gui_consider_frame_title-680795>:	call   0x5555555b8f19 <die>
   0x00005555555a427a <gui_consider_frame_title-680790>:	call   0x5555555a0ca9 <XCONS>

13877	  struct frame *f = XFRAME (frame);
   0x00005555555a427f <gui_consider_frame_title-680785>:	mov    $0x3635,%edx
   0x00005555555a4284 <gui_consider_frame_title-680780>:	lea    0x413425(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a428b <gui_consider_frame_title-680773>:	lea    0x410fa7(%rip),%rdi        # 0x5555559b5239
   0x00005555555a4292 <gui_consider_frame_title-680766>:	call   0x5555555b8f19 <die>

17471
17472		  if (is_tty_frame (f))
17473		    {
17474		      /* Ignore all invisble tty frames, children or root.  */
17475		      if (!FRAME_VISIBLE_P (root_frame (f)))
17476			continue;
17477
17478		      /* Remember tty root frames which we've seen.  */
17479		      if (!FRAME_PARENT_FRAME (f)
17480			  && NILP (memq_no_quit (frame, tty_root_frames)))
17481			tty_root_frames = Fcons (frame, tty_root_frames);
17482		    }
17483
17484		retry_frame:
17485		  if (FRAME_WINDOW_P (f)
17486		      || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f) || f == sf)
17487		    {
17488		      /* Only GC scrollbars when we redisplay the whole frame.  */
17489		      bool gcscrollbars = f->redisplay || !REDISPLAY_SOME_P ();
17490		      bool f_redisplay_flag = f->redisplay;
17491
17492		      /* The X error handler may have deleted that frame before
17493			 we went back to retry_frame.  Or this could be a TTY
17494			 frame that is not completely made, in which case we
17495			 cannot safely redisplay its windows.  This must come
17496			 before any accesses to f->terminal.  */
17497		      if (!FRAME_LIVE_P (f)
17498			  || (FRAME_TERMCAP_P (f) && !f->after_make_frame))
17499			continue;
17500
17501		      /* Mark all the scroll bars to be removed; we'll redeem
17502			 the ones we want when we redisplay their windows.  */
17503		      if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
17504			FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
17505
17506		      if (FRAME_REDISPLAY_P (f))
17507			{
17508			  /* Don't allow freeing images and faces for this
17509			     frame as long as the frame's update wasn't
17510			     completed.  This prevents crashes when some Lisp
17511			     that runs from the various hooks or font-lock
17512			     decides to clear the frame's image cache and face
17513			     cache, when the images and faces in those caches
17514			     are referenced by the desired matrix.  */
17515			  f->inhibit_clear_image_cache = true;
17516			  redisplay_windows (FRAME_ROOT_WINDOW (f));
17517			}
17518		      /* Remember that the invisible frames need to be redisplayed next
17519			 time they're visible.  */
17520		      else if (!REDISPLAY_SOME_P ())
17521			f->redisplay = true;
17522
17523		      /* The X error handler may have deleted that frame.  */
17524		      if (!FRAME_LIVE_P (f))
17525			continue;
17526
17527		      /* Any scroll bars which redisplay_windows should have
17528			 nuked should now go away.  */
17529		      if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook)
17530			FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
17531
17532		      if (FRAME_REDISPLAY_P (f))
17533			{
17534			  /* If fonts changed on visible frame, display again.  */
17535			  if (f->fonts_changed)
17536			    {
17537			      adjust_frame_glyphs (f);
17538			      /* Disable all redisplay optimizations for this
17539				 frame.  For the reasons, see the comment near
17540				 the previous call to adjust_frame_glyphs above.  */
17541			      SET_FRAME_GARBAGED (f);
17542			      f->fonts_changed = false;
17543			      goto retry_frame;
17544			    }
17545
17546			  /* See if we have to hscroll.  */
17547			  if (!f->already_hscrolled_p)
17548			    {
17549			      f->already_hscrolled_p = true;
17550	                      if (hscroll_retries <= MAX_HSCROLL_RETRIES
17551	                          && hscroll_windows (f->root_window))
17552	                        {
17553	                          hscroll_retries++;
17554	                          goto retry_frame;
17555	                        }
17556			    }
17557
17558			  /* If the frame's redisplay flag was not set before
17559			     we went about redisplaying its windows, but it is
17560			     set now, that means we employed some redisplay
17561			     optimizations inside redisplay_windows, and
17562			     bypassed producing some screen lines.  But if
17563			     f->redisplay is now set, it might mean the old
17564			     faces are no longer valid (e.g., if redisplaying
17565			     some window called some Lisp which defined a new
17566			     face or redefined an existing face), so trying to
17567			     use them in update_frame will segfault.
17568			     Therefore, we must redisplay this frame.  */
17569			  if (!f_redisplay_flag && f->redisplay)
17570	                    goto retry_frame;
17571	                  /* In some case (e.g., window resize), we notice
17572	                     only during window updating that the window
17573	                     content changed unpredictably (e.g., a GTK
17574	                     scrollbar moved, or some Lisp hook that winds up
17575	                     calling adjust_frame_glyphs) and that our
17576	                     previous estimation of the frame content was
17577	                     garbage.  We have to start over.  These cases
17578	                     should be rare, so going all the way back to the
17579	                     top of redisplay should be good enough.  */
17580	                  if (FRAME_GARBAGED_P (f)
17581			      && garbaged_frame_retries++ < MAX_GARBAGED_FRAME_RETRIES)
17582	                    goto retry;
17583
17584	#ifdef HAVE_WINDOW_SYSTEM
17585	                  if (FRAME_WINDOW_P (f)
17586	                      && FRAME_RIF (f)->clear_under_internal_border)
17587	                    FRAME_RIF (f)->clear_under_internal_border (f);
17588	#endif
17589			  /* Prevent various kinds of signals during display
17590			     update.  stdio is not robust about handling
17591			     signals, which can cause an apparent I/O error.  */
17592			  if (interrupt_input)
17593			    unrequest_sigio ();
17594			  STOP_POLLING;
17595
17596			  update_frame (f, false);
17597			  /* On some platforms (at least MS-Windows), the
17598			     scroll_run_hook called from scrolling_window
17599			     called from update_frame could set the frame's
17600			     garbaged flag, in which case we need to redisplay
17601			     the frame.  Don't do that on TTY frames, since we
17602			     need to keep the garbaged flag in that case when
17603			     the frame has been resized.  */
17604	                  if (FRAME_GARBAGED_P (f))
17605			    {
17606			      fset_redisplay (f);
17607			      f->garbaged = false;
17608			      goto retry_frame;
17609			    }
17610			  f->cursor_type_changed = false;
17611			  f->updated_p = true;
17612			  f->inhibit_clear_image_cache = false;
17613			}
17614		    }
17615		}
17616
17617	      if (CONSP (tty_root_frames))
17618		combine_updates (tty_root_frames);
17619
17620	      eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
   0x00005555555a4297 <redisplay_internal.cold+0>:	mov    $0x44d4,%edx
   0x00005555555a429c <redisplay_internal-682692>:	lea    0x41340d(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a42a3 <redisplay_internal-682685>:	lea    0x415fc6(%rip),%rdi        # 0x5555559ba270
   0x00005555555a42aa <redisplay_internal-682678>:	call   0x5555555b8f19 <die>
   0x00005555555a42af <redisplay_internal-682673>:	mov    $0x44d4,%edx
   0x00005555555a42b4 <redisplay_internal-682668>:	lea    0x4133f5(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a42bb <redisplay_internal-682661>:	lea    0x411131(%rip),%rdi        # 0x5555559b53f3
   0x00005555555a42c2 <redisplay_internal-682654>:	call   0x5555555b8f19 <die>

17427		      eassert (this_line_y == it.current_y);
   0x00005555555a42c7 <redisplay_internal-682649>:	mov    $0x4413,%edx
   0x00005555555a42cc <redisplay_internal-682644>:	lea    0x4133dd(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a42d3 <redisplay_internal-682637>:	lea    0x413a65(%rip),%rdi        # 0x5555559b7d3f
   0x00005555555a42da <redisplay_internal-682630>:	call   0x5555555b8f19 <die>

17426		      eassert (this_line_vpos == it.vpos);
   0x00005555555a42df <redisplay_internal-682625>:	mov    $0x4412,%edx
   0x00005555555a42e4 <redisplay_internal-682620>:	lea    0x4133c5(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a42eb <redisplay_internal-682613>:	lea    0x413a33(%rip),%rdi        # 0x5555559b7d25
   0x00005555555a42f2 <redisplay_internal-682606>:	call   0x5555555b8f19 <die>

17621
17622	      /* Do the mark_window_display_accurate after all windows have
17623		 been redisplayed because this call resets flags in buffers
17624		 which are needed for proper redisplay.  */
17625	      FOR_EACH_FRAME (tail, frame)
17626		{
17627		  struct frame *f = XFRAME (frame);
   0x00005555555a42f7 <redisplay_internal-682601>:	mov    $0x44db,%edx
   0x00005555555a42fc <redisplay_internal-682596>:	lea    0x4133ad(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a4303 <redisplay_internal-682589>:	lea    0x410f2f(%rip),%rdi        # 0x5555559b5239
   0x00005555555a430a <redisplay_internal-682582>:	call   0x5555555b8f19 <die>
   0x00005555555a430f <redisplay_internal-682577>:	call   0x5555555a0e01 <XSYMBOL_WITH_POS_SYM>

17715
17716	      if (mini_frame != sf)
17717		{
17718		  XWINDOW (mini_window)->must_be_updated_p = true;
17719		  update_frame (mini_frame, false);
17720		  if (is_tty_frame (mini_frame))
17721		    combine_updates_for_frame (mini_frame, false);
17722		  mini_frame->cursor_type_changed = false;
17723	          if (hscroll_retries <= MAX_HSCROLL_RETRIES
17724	              && hscroll_windows (mini_window))
17725	            {
17726	              hscroll_retries++;
17727	              goto retry;
17728	            }
17729		}
17730	    }
17731
17732	  if (!consider_all_windows_p)
17733	    {
17734	      /* This has already been done above if
17735		 consider_all_windows_p is set.  */
17736	      if (XBUFFER (w->contents)->text->redisplay
17737		  && buffer_window_count (XBUFFER (w->contents)) > 1)
17738		/* This can happen if b->text->redisplay was set during
17739		   jit-lock.  */
17740		propagate_buffer_redisplay ();
17741	      mark_window_display_accurate_1 (w, true);
17742
17743	      /* Say overlay arrows are up to date.  */
17744	      update_overlay_arrows (1);
17745
17746	      if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
17747		FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
17748	    }
17749
17750	  update_mode_lines = 0;
17751	  windows_or_buffers_changed = 0;
17752
17753	  /* Start SIGIO interrupts coming again.  Having them off during the
17754	     code above makes it less likely one will discard output, but not
17755	     impossible, since there might be stuff in the system buffer here.
17756	     But it is much hairier to try to do anything about that.  */
17757	  if (interrupt_input)
17758	    request_sigio ();
17759	  RESUME_POLLING;
17760
17761	  /* If a frame has become visible which was not before, redisplay
17762	     again, so that we display it.  Expose events for such a frame
17763	     (which it gets when becoming visible) don't call the parts of
17764	     redisplay constructing glyphs, so simply exposing a frame won't
17765	     display anything in this case.  So, we have to display these
17766	     frames here explicitly.  */
17767	  int new_count = 0;
17768
17769	  FOR_EACH_FRAME (tail, frame)
17770	    {
17771	      if (FRAME_REDISPLAY_P (XFRAME (frame)))
   0x00005555555a4314 <redisplay_internal-682572>:	mov    $0x456b,%edx
   0x00005555555a4319 <redisplay_internal-682567>:	lea    0x413390(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a4320 <redisplay_internal-682560>:	lea    0x410f12(%rip),%rdi        # 0x5555559b5239
   0x00005555555a4327 <redisplay_internal-682553>:	call   0x5555555b8f19 <die>

17214	      && FRAME_REDISPLAY_P (XFRAME (w->frame))
   0x00005555555a432c <redisplay_internal-682548>:	mov    $0x433e,%edx
   0x00005555555a4331 <redisplay_internal-682543>:	lea    0x413378(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a4338 <redisplay_internal-682536>:	lea    0x410ccf(%rip),%rdi        # 0x5555559b500e
   0x00005555555a433f <redisplay_internal-682529>:	call   0x5555555b8f19 <die>
   0x00005555555a4344 <redisplay_internal-682524>:	call   0x5555555a0ca9 <XCONS>
   0x00005555555a4349 <redisplay_internal-682519>:	call   0x5555555a0bff <make_fixnum>
   0x00005555555a434e <redisplay_internal-682514>:	call   0x5555555a0b7d <buffer_window_count>

17024	    XFRAME (frame)->already_hscrolled_p = false;
   0x00005555555a4353 <redisplay_internal-682509>:	mov    $0x4280,%edx
   0x00005555555a4358 <redisplay_internal-682504>:	lea    0x413351(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a435f <redisplay_internal-682497>:	lea    0x410ed3(%rip),%rdi        # 0x5555559b5239
   0x00005555555a4366 <redisplay_internal-682490>:	call   0x5555555b8f19 <die>
   0x00005555555a436b <redisplay_internal-682485>:	call   0x5555555a0bbe <XBUFFER>

17215	      && !XFRAME (w->frame)->cursor_type_changed
17216	      && !XFRAME (w->frame)->face_change
17217	      /* Make sure recorded data applies to current buffer, etc.  */
17218	      && this_line_buffer == current_buffer
17219	      && match_p
17220	      && !w->force_start
17221	      && !w->optional_new_start
17222	      /* Point must be on the line that we have info recorded about.  */
17223	      && PT >= CHARPOS (tlbufpos)
17224	      && PT <= Z - CHARPOS (tlendpos)
17225	      /* FIXME: The following condition is only needed when
17226		 significant parts of the buffer are hidden (e.g., under
17227		 hs-minor-mode), but there doesn't seem to be a simple way of
17228		 detecting that, so we always disable the one-line redisplay
17229		 optimizations whenever display-line-numbers-mode is turned on
17230		 in the buffer.  */
17231	      && (NILP (Vdisplay_line_numbers)
17232		  || EQ (Vdisplay_line_numbers, Qvisual))
17233	      /* All text outside that line, including its final newline,
17234		 must be unchanged.  */
17235	      && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
17236						CHARPOS (tlendpos))
17237	      /* If this is a window on a tty root frame displaying a child frame,
17238		 the current matrix of W may contain glyphs of that child frame.
17239		 Don't try shortcuts that might use the current matrix in this case.  */
17240	      && !is_tty_root_frame_with_visible_child (XFRAME (w->frame)))
   0x00005555555a4370 <redisplay_internal-682480>:	mov    $0x4358,%edx
   0x00005555555a4375 <redisplay_internal-682475>:	lea    0x413334(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a437c <redisplay_internal-682468>:	lea    0x410c8b(%rip),%rdi        # 0x5555559b500e
   0x00005555555a4383 <redisplay_internal-682461>:	call   0x5555555b8f19 <die>
   0x00005555555a4388 <redisplay_internal-682456>:	call   0x5555555a0be3 <FRAME_PARENT_FRAME>

17628	          if (f->updated_p)
17629	            {
17630		      f->redisplay = false;
17631		      f->garbaged = false;
17632	              mark_window_display_accurate (f->root_window, true);
17633	              if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
17634	                FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
17635	            }
17636		}
17637	    }
17638	  else if (FRAME_REDISPLAY_P (sf))
17639	    {
17640	      sf->inhibit_clear_image_cache = true;
17641	      displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
17642	      /* Use list_of_error, not Qerror, so that
17643		 we catch only errors and don't run the debugger.  */
17644	      internal_condition_case_1 (redisplay_window_1, selected_window,
17645					 list_of_error,
17646					 redisplay_window_error);
17647	      if (update_miniwindow_p)
17648		{
17649		  Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
17650
17651		  displayed_buffer = XBUFFER (XWINDOW (mini_window)->contents);
17652		  internal_condition_case_1 (redisplay_window_1, mini_window,
17653					     list_of_error,
17654					     redisplay_window_error);
17655		}
17656
17657	      /* Compare desired and current matrices, perform output.  */
17658
17659	    update:
17660	      /* If fonts changed, display again.  Likewise if redisplay_window_1
17661		 above caused some change (e.g., a change in faces) that requires
17662		 considering the entire frame again.  */
17663	      if (sf->fonts_changed || sf->redisplay)
17664		{
17665		  if (sf->redisplay)
17666		    {
17667		      /* Set this to force a more thorough redisplay.
17668			 Otherwise, we might immediately loop back to the
17669			 above "else-if" clause (since all the conditions that
17670			 led here might still be true), and we will then
17671			 infloop, because the selected-frame's redisplay flag
17672			 is not (and cannot be) reset.  */
17673		      windows_or_buffers_changed = 50;
17674		    }
17675		  goto retry;
17676		}
17677
17678	      /* Prevent freeing of realized faces, since desired matrices are
17679		 pending that reference the faces we computed and cached.  */
17680	      inhibit_free_realized_faces = true;
17681
17682	      /* Prevent various kinds of signals during display update.
17683		 stdio is not robust about handling signals,
17684		 which can cause an apparent I/O error.  */
17685	      if (interrupt_input)
17686		unrequest_sigio ();
17687	      STOP_POLLING;
17688
17689	      if (FRAME_REDISPLAY_P (sf))
17690		{
17691	          if (hscroll_retries <= MAX_HSCROLL_RETRIES
17692	              && hscroll_windows (selected_window))
17693	            {
17694	              hscroll_retries++;
17695	              goto retry;
17696	            }
17697
17698		  XWINDOW (selected_window)->must_be_updated_p = true;
17699		  update_frame (sf, false);
17700
17701		  if (is_tty_frame (sf))
17702		    combine_updates_for_frame (sf, false);
17703
17704		  sf->cursor_type_changed = false;
17705		  sf->inhibit_clear_image_cache = false;
17706		}
17707
17708	      /* We may have called echo_area_display at the top of this
17709		 function.  If the echo area is on another frame, that may
17710		 have put text on a frame other than the selected one, so the
17711		 above call to update_frame would not have caught it.  Catch
17712		 it here.  */
17713	      Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
17714	      struct frame *mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
   0x00005555555a438d <redisplay_internal-682451>:	mov    $0x4532,%edx
   0x00005555555a4392 <redisplay_internal-682446>:	lea    0x413317(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a4399 <redisplay_internal-682439>:	lea    0x415f10(%rip),%rdi        # 0x5555559ba2b0
   0x00005555555a43a0 <redisplay_internal-682432>:	call   0x5555555b8f19 <die>

14036		  struct frame *f = XFRAME (frame);
   0x00005555555a43a5 <redisplay_internal-682427>:	mov    $0x36d4,%edx
   0x00005555555a43aa <redisplay_internal-682422>:	lea    0x4132ff(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a43b1 <redisplay_internal-682415>:	lea    0x410e81(%rip),%rdi        # 0x5555559b5239
   0x00005555555a43b8 <redisplay_internal-682408>:	call   0x5555555b8f19 <die>

17464
17465	      propagate_buffer_redisplay ();
17466
17467	      Lisp_Object tty_root_frames = Qnil;
17468	      FOR_EACH_FRAME (tail, frame)
17469		{
17470		  struct frame *f = XFRAME (frame);
   0x00005555555a43bd <redisplay_internal-682403>:	mov    $0x443e,%edx
   0x00005555555a43c2 <redisplay_internal-682398>:	lea    0x4132e7(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a43c9 <redisplay_internal-682391>:	lea    0x410e69(%rip),%rdi        # 0x5555559b5239
   0x00005555555a43d0 <redisplay_internal-682384>:	call   0x5555555b8f19 <die>

17463		XFRAME (frame)->updated_p = false;
   0x00005555555a43d5 <redisplay_internal-682379>:	mov    $0x4437,%edx
   0x00005555555a43da <redisplay_internal-682374>:	lea    0x4132cf(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a43e1 <redisplay_internal-682367>:	lea    0x410e51(%rip),%rdi        # 0x5555559b5239
   0x00005555555a43e8 <redisplay_internal-682360>:	call   0x5555555b8f19 <die>

17068	      struct frame *f = XFRAME (frame);
   0x00005555555a43ed <redisplay_internal-682355>:	mov    $0x42ac,%edx
   0x00005555555a43f2 <redisplay_internal-682350>:	lea    0x4132b7(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a43f9 <redisplay_internal-682343>:	lea    0x410e39(%rip),%rdi        # 0x5555559b5239
   0x00005555555a4400 <redisplay_internal-682336>:	call   0x5555555b8f19 <die>

16996	  fr = XFRAME (w->frame);
   0x00005555555a4405 <redisplay_internal-682331>:	mov    $0x4264,%edx
   0x00005555555a440a <redisplay_internal-682326>:	lea    0x41329f(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a4411 <redisplay_internal-682319>:	lea    0x410bf6(%rip),%rdi        # 0x5555559b500e
   0x00005555555a4418 <redisplay_internal-682312>:	call   0x5555555b8f19 <die>

14077		  struct frame *f = XFRAME (frame);
   0x00005555555a441d <redisplay_internal-682307>:	mov    $0x36fd,%edx
   0x00005555555a4422 <redisplay_internal-682302>:	lea    0x413287(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a4429 <redisplay_internal-682295>:	lea    0x410e09(%rip),%rdi        # 0x5555559b5239
   0x00005555555a4430 <redisplay_internal-682288>:	call   0x5555555b8f19 <die>

17772		new_count++;
17773	    }
17774
17775	    if (new_count != number_of_visible_frames)
17776	      windows_or_buffers_changed = 52;
17777
17778	  /* Change frame size now if a change is pending.  */
17779	  do_pending_window_change (true);
17780
17781	  /* If we just did a pending size change, or have additional
17782	     visible frames, or selected_window changed, redisplay again.  */
17783	  if (windows_or_buffers_changed
17784	      || (WINDOWP (selected_window)
17785		  && (w = XWINDOW (selected_window)) != sw))
17786	    goto retry;
17787
17788	  /* Clear the face and image caches.
17789
17790	     We used to do this only if consider_all_windows_p.  But the cache
17791	     needs to be cleared if a timer creates images in the current
17792	     buffer (e.g. the test case in Bug#6230).  */
17793
17794	  if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
17795	    {
17796	      clear_face_cache (false);
17797	      clear_face_cache_count = 0;
17798	    }
17799
17800	#ifdef HAVE_WINDOW_SYSTEM
17801	  if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
17802	    {
17803	      clear_image_caches (Qnil);
17804	      clear_image_cache_count = 0;
17805	    }
17806	#endif /* HAVE_WINDOW_SYSTEM */
17807
17808	 end_of_redisplay:
17809	#ifdef HAVE_NS
17810	  ns_set_doc_edited ();
17811	#endif
17812	  if (interrupt_input && interrupts_deferred)
17813	    request_sigio ();
17814
17815	  /* We're done with this redisplay cycle, so reset the tick count in
17816	     preparation for the next redisplay cycle.  */
17817	  if (max_redisplay_ticks > 0)
17818	    update_redisplay_ticks (0, NULL);
17819
17820	  unbind_to (count, Qnil);
17821	  RESUME_POLLING;
17822	}
17823
17824	static void
17825	unwind_redisplay_preserve_echo_area (void)
17826	{
17827	  unblock_buffer_flips ();
17828	}
17829
17830	/* Redisplay, but leave alone any recent echo area message unless
17831	   another message has been requested in its place.
17832
17833	   This is useful in situations where you need to redisplay but no
17834	   user action has occurred, making it inappropriate for the message
17835	   area to be cleared.  See tracking_off and
17836	   wait_reading_process_output for examples of these situations.
17837
17838	   FROM_WHERE is an integer saying from where this function was
17839	   called.  This is useful for debugging.  */
17840
17841	void
17842	redisplay_preserve_echo_area (int from_where)
17843	{
17844	  redisplay_trace ("redisplay_preserve_echo_area (%d)\n", from_where);
17845
17846	  block_input ();
17847	  specpdl_ref count = SPECPDL_INDEX ();
17848	  record_unwind_protect_void (unwind_redisplay_preserve_echo_area);
17849	  block_buffer_flips ();
17850	  unblock_input ();
17851
17852	  if (!NILP (echo_area_buffer[1]))
17853	    {
17854	      /* We have a previously displayed message, but no current
17855		 message.  Redisplay the previous message.  */
17856	      display_last_displayed_message_p = true;
17857	      redisplay_internal ();
17858	      display_last_displayed_message_p = false;
17859	    }
17860	  else
17861	    redisplay_internal ();
17862
17863	  flush_frame (SELECTED_FRAME ());
17864	  unbind_to (count, Qnil);
17865	}
17866
17867
17868	/* Function registered with record_unwind_protect in redisplay_internal.  */
17869
17870	static void
17871	unwind_redisplay (void)
17872	{
17873	  redisplaying_p = false;
17874	  unblock_buffer_flips ();
17875	}
17876
17877	/* Function registered with record_unwind_protect before calling
17878	   start_display outside of redisplay_internal.  */
17879	void
17880	unwind_display_working_on_window (void)
17881	{
17882	  display_working_on_window_p = false;
17883	}
17884
17885	/* Mark the display of leaf window W as accurate or inaccurate.
17886	   If ACCURATE_P, mark display of W as accurate.
17887	   If !ACCURATE_P, arrange for W to be redisplayed the next
17888	   time redisplay_internal is called.  */
17889
17890	static void
17891	mark_window_display_accurate_1 (struct window *w, bool accurate_p)
17892	{
17893	  struct buffer *b = XBUFFER (w->contents);
17894	#ifdef HAVE_TEXT_CONVERSION
17895	  ptrdiff_t prev_point, prev_mark;
17896	#endif /* HAVE_TEXT_CONVERSION */
17897
17898	  w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
17899	  w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
17900	  w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
17901
17902	  if (accurate_p)
17903	    {
17904	      b->clip_changed = false;
17905	      b->prevent_redisplay_optimizations_p = false;
17906	      eassert (buffer_window_count (b) > 0);
17907	      /* Resetting b->text->redisplay is problematic!
17908		 In order to make it safer to do it here, redisplay_internal must
17909		 have copied all b->text->redisplay to their respective windows.  */
17910	      b->text->redisplay = false;
17911
17912	      BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
17913	      BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
17914	      BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
17915	      BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
17916
17917	      w->current_matrix->buffer = b;
17918	      w->current_matrix->begv = BUF_BEGV (b);
17919	      w->current_matrix->zv = BUF_ZV (b);
17920	      w->current_matrix->header_line_p = window_wants_header_line (w);
17921	      w->current_matrix->tab_line_p = window_wants_tab_line (w);
17922
17923	      w->last_cursor_vpos = w->cursor.vpos;
17924	      w->last_cursor_off_p = w->cursor_off_p;
17925
17926	#ifdef HAVE_TEXT_CONVERSION
17927	      prev_point = w->last_point;
17928	      prev_mark = w->last_mark;
17929	#endif /* HAVE_TEXT_CONVERSION */
17930
17931	      if (w == XWINDOW (selected_window))
17932		w->last_point = BUF_PT (b);
17933	      else
17934		w->last_point = marker_position (w->pointm);
17935
17936	      /* w->last_mark is recorded for text conversion purposes.
17937	         Input methods aren't interested in the value of the mark
17938	         if it is inactive, so set it to -1 if it's not.  */
17939
17940	      if (XMARKER (BVAR (b, mark))->buffer == b
17941		  && !NILP (BVAR (b, mark_active)))
17942		w->last_mark = marker_position (BVAR (b, mark));
17943	      else
17944		w->last_mark = -1;
17945
17946	#ifdef HAVE_TEXT_CONVERSION
17947	      /* See the description of this field in struct window.  */
17948	      w->ephemeral_last_point = w->last_point;
17949
17950	      /* Point motion is only propagated to the input method for use
17951		 in text conversion during a redisplay.  While this can lead
17952		 to inconsistencies when point has moved but the change has
17953		 not yet been displayed, it leads to better results most of
17954		 the time, as point often changes within calls to
17955		 `save-excursion', and the only way to detect such calls is to
17956		 observe that the next redisplay never ends with those changes
17957		 applied.
17958
17959	         Changes to buffer text are immediately propagated to the
17960	         input method, and the position of point is also updated
17961	         during such a change, so the consequences are not that
17962	         severe.  */
17963
17964	      if ((prev_point != w->last_point
17965		   || prev_mark != w->last_mark)
17966		  && FRAME_WINDOW_P (WINDOW_XFRAME (w))
17967		  && !FRAME_TOOLTIP_P (WINDOW_XFRAME (w))
17968		  && w == XWINDOW (WINDOW_XFRAME (w)->selected_window))
17969		report_point_change (WINDOW_XFRAME (w), w, b);
17970	#endif /* HAVE_TEXT_CONVERSION */
17971
17972	      struct glyph_row *row;
17973	      /* These conditions should be consistent with CHECK_WINDOW_END.  */
17974	      if (w->window_end_vpos < w->current_matrix->nrows
17975		  && ((row = MATRIX_ROW (w->current_matrix, w->window_end_vpos),
17976		       !row->enabled_p
17977		       || MATRIX_ROW_DISPLAYS_TEXT_P (row)
17978		       || MATRIX_ROW_VPOS (row, w->current_matrix) == 0)))
17979		w->window_end_valid = true;
17980	      w->update_mode_line = false;
17981	      w->preserve_vscroll_p = false;
17982	    }
17983
17984	  w->redisplay = !accurate_p;
17985	}
17986
17987
17988	/* Mark the display of windows in the window tree rooted at WINDOW as
17989	   accurate or inaccurate.  If ACCURATE_P, mark display of
17990	   windows as accurate.  If !ACCURATE_P, arrange for windows to
17991	   be redisplayed the next time redisplay_internal is called.  */
17992
17993	void
17994	mark_window_display_accurate (Lisp_Object window, bool accurate_p)
17995	{
17996	  struct window *w;
17997
17998	  for (; !NILP (window); window = w->next)
17999	    {
18000	      w = XWINDOW (window);
18001	      if (WINDOWP (w->contents))
18002		mark_window_display_accurate (w->contents, accurate_p);
18003	      else
18004		mark_window_display_accurate_1 (w, accurate_p);
18005	    }
18006
18007	  if (accurate_p)
18008	    update_overlay_arrows (1);
18009	  else
18010	    /* Force a thorough redisplay the next time by setting
18011	       last_arrow_position and last_arrow_string to t, which is
18012	       unequal to any useful value of Voverlay_arrow_...  */
18013	    update_overlay_arrows (-1);
18014	}
18015
18016
18017	/* Return value in display table DP (Lisp_Char_Table *) for character
18018	   C.  Since a display table doesn't have any parent, we don't have to
18019	   follow parent.  Do not call this function directly but use the
18020	   macro DISP_CHAR_VECTOR.  */
18021
18022	Lisp_Object
18023	disp_char_vector (struct Lisp_Char_Table *dp, int c)
18024	{
18025	  Lisp_Object val;
18026
18027	  if (ASCII_CHAR_P (c))
18028	    {
18029	      val = dp->ascii;
18030	      if (SUB_CHAR_TABLE_P (val))
18031		val = XSUB_CHAR_TABLE (val)->contents[c];
18032	    }
18033	  else
18034	    {
18035	      Lisp_Object table;
18036
18037	      XSETCHAR_TABLE (table, dp);
18038	      val = char_table_ref (table, c);
18039	    }
18040	  if (NILP (val))
18041	    val = dp->defalt;
18042	  return val;
18043	}
18044
18045	static int buffer_flip_blocked_depth;
18046
18047	static void
18048	block_buffer_flips (void)
   0x00005555555a4435 <redisplay_internal-682283>:	mov    $0x4682,%edx
   0x00005555555a443a <redisplay_internal-682278>:	lea    0x41326f(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a4441 <redisplay_internal-682271>:	lea    0x415de8(%rip),%rdi        # 0x5555559ba230
   0x00005555555a4448 <redisplay_internal-682264>:	call   0x5555555b8f19 <die>

18049	{
18050	  eassert (buffer_flip_blocked_depth >= 0);
   0x00005555555a444d <redisplay_internal-682259>:	call   0x5555555a0b99 <XWINDOW>

16988	  if ((FRAME_INITIAL_P (SELECTED_FRAME ())
   0x00005555555a4452 <redisplay_internal-682254>:	call   0x5555555b39b8 <emacs_abort>
   0x00005555555a4457 <echo_area_display.cold+0>:	call   0x5555555a0e01 <XSYMBOL_WITH_POS_SYM>

./src/lisp.h:
1136	  eassume (BARE_SYMBOL_P (sym));
   0x00005555555a445c <echo_area_display-694084>:	call   0x5555555a0b99 <XWINDOW>

./src/xdisp.c:
13511	  f = XFRAME (WINDOW_FRAME (w));
   0x00005555555a4461 <echo_area_display-694079>:	mov    $0x34c7,%edx
   0x00005555555a4466 <echo_area_display-694074>:	lea    0x413243(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a446d <echo_area_display-694067>:	lea    0x410daf(%rip),%rdi        # 0x5555559b5223
End of assembler dump.
Dump of assembler code from 0x5555555a0ada to 0x5555555a0cda:
./src/xdisp.c:
7195	  eassert (it->sp < IT_STACK_SIZE);
   0x00005555555a0ada <push_it-366134>:	cmp    $0x416c41,%eax
   0x00005555555a0adf <push_it-366129>:	call   0x5555555b8f19 <die>

7203	  p->face_id = it->face_id;
7204	  p->string = it->string;
7205	  p->method = it->method;
7206	  p->from_overlay = it->from_overlay;
7207	  switch (p->method)
7208	    {
7209	    case GET_FROM_IMAGE:
7210	      p->u.image.object = it->object;
7211	      p->u.image.image_id = it->image_id;
7212	      p->u.image.slice = it->slice;
7213	      break;
7214	    case GET_FROM_STRETCH:
7215	      p->u.stretch.object = it->object;
7216	      break;
7217	    case GET_FROM_XWIDGET:
7218	      p->u.xwidget.object = it->object;
7219	      break;
7220	    case GET_FROM_BUFFER:
7221	    case GET_FROM_DISPLAY_VECTOR:
7222	    case GET_FROM_STRING:
7223	    case GET_FROM_C_STRING:
7224	      break;
7225	    default:
7226	      emacs_abort ();
   0x00005555555a0ae4 <push_it-366124>:	call   0x5555555b39b8 <emacs_abort>

7202	  eassert (it->face_id >= 0);
   0x00005555555a0ae9 <push_it-366119>:	mov    $0x1c22,%edx
   0x00005555555a0aee <push_it-366114>:	lea    0x416bbb(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a0af5 <push_it-366107>:	lea    0x416c3b(%rip),%rdi        # 0x5555559b7737
   0x00005555555a0afc <push_it-366100>:	call   0x5555555b8f19 <die>

3638		|| WINDOW_LEFT_FRINGE_WIDTH (w) == 0) ? 1 : 0);
   0x00005555555a0b01 <get_narrowed_width.cold+0>:	mov    $0xe36,%edx
   0x00005555555a0b06 <get_narrowed_width-367098>:	lea    0x416ba3(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a0b0d <get_narrowed_width-367091>:	lea    0x41470f(%rip),%rdi        # 0x5555559b5223
   0x00005555555a0b14 <get_narrowed_width-367084>:	call   0x5555555b8f19 <die>

3637	    - ((WINDOW_RIGHT_FRINGE_WIDTH (w) == 0
   0x00005555555a0b19 <get_narrowed_width-367079>:	mov    $0xe35,%edx
   0x00005555555a0b1e <get_narrowed_width-367074>:	lea    0x416b8b(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a0b25 <get_narrowed_width-367067>:	lea    0x4146f7(%rip),%rdi        # 0x5555559b5223
   0x00005555555a0b2c <get_narrowed_width-367060>:	call   0x5555555b8f19 <die>

3632	  int fact = FRAME_WINDOW_P (XFRAME (w->frame)) ? 3 : 2;
   0x00005555555a0b31 <get_narrowed_width-367055>:	mov    $0xe30,%edx
   0x00005555555a0b36 <get_narrowed_width-367050>:	lea    0x416b73(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a0b3d <get_narrowed_width-367043>:	lea    0x4144ca(%rip),%rdi        # 0x5555559b500e
   0x00005555555a0b44 <get_narrowed_width-367036>:	call   0x5555555b8f19 <die>

3639	  return fact * max (1, width);
3640	}
3641
3642	static int
3643	get_narrowed_len (struct window *w)
3644	{
3645	  int height = window_body_height (w, WINDOW_BODY_IN_CANONICAL_CHARS);
3646	  return get_narrowed_width (w) * max (1, height);
3647	}
3648
3649	static ptrdiff_t
3650	get_medium_narrowing_begv (struct window *w, ptrdiff_t pos)
3651	{
3652	  ptrdiff_t len = get_narrowed_len (w);
3653	  return max ((pos / len - 1) * len, BEGV);
3654	}
3655
3656	static ptrdiff_t
3657	get_medium_narrowing_zv (struct window *w, ptrdiff_t pos)
3658	{
3659	  ptrdiff_t len = get_narrowed_len (w);
3660	  return min ((pos / len + 1) * len, ZV);
3661	}
3662
3663	/* Find the position of the last BOL before POS, unless it is too far
3664	   away.  The buffer portion in which the search occurs is gradually
3665	   enlarged: [POS-500..POS], [POS-5500..POS-500],
3666	   [POS-55500..POS-5500], and finally [POS-555500..POS-55500].  Return
3667	   BEGV-1 if no BOL was found in [POS-555500..POS].  */
3668	static ptrdiff_t
3669	get_nearby_bol_pos (ptrdiff_t pos)
3670	{
3671	  ptrdiff_t start, pos_bytepos, cur, next, found, bol = BEGV - 1, init_pos = pos;
3672	  int dist;
3673	  for (dist = 500; dist <= 500000; dist *= 10)
3674	    {
3675	      pos_bytepos = pos == BEGV ? BEGV_BYTE : CHAR_TO_BYTE (pos);
3676	      start = max (pos - dist, BEGV);
3677	      for (cur = start; cur < pos; cur = next)
3678		{
3679		  next = find_newline1 (cur, CHAR_TO_BYTE (cur),
3680					pos, pos_bytepos,
3681					1, &found, NULL, false);
3682		  if (found)
3683		    bol = next;
3684		  else
3685		    break;
3686		}
3687	      if (bol >= BEGV || start == BEGV)
3688		break;
3689	      else
3690		pos = max (pos - dist, BEGV);
3691	    }
3692	  eassert (bol <= init_pos);
   0x00005555555a0b49 <get_nearby_bol_pos.cold+0>:	mov    $0xe6c,%edx
   0x00005555555a0b4e <get_nearby_bol_pos-367826>:	lea    0x416b5b(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a0b55 <get_nearby_bol_pos-367819>:	lea    0x416bec(%rip),%rdi        # 0x5555559b7748
   0x00005555555a0b5c <get_nearby_bol_pos-367812>:	call   0x5555555b8f19 <die>

./src/lisp.h:
1379	make_lisp_ptr (void *ptr, enum Lisp_Type type)
   0x00005555555a0b61 <make_lisp_ptr+0>:	push   %rbp

1380	{
1381	  Lisp_Object a = TAG_PTR_INITIALLY (type, ptr);
1382	  eassert (TAGGEDP (a, type) && XUNTAG (a, type, char) == ptr);
   0x00005555555a0b62 <make_lisp_ptr+1>:	mov    $0x566,%edx
   0x00005555555a0b67 <make_lisp_ptr+6>:	lea    0x4144b2(%rip),%rsi        # 0x5555559b5020
   0x00005555555a0b6e <make_lisp_ptr+13>:	lea    0x414b43(%rip),%rdi        # 0x5555559b56b8

1379	make_lisp_ptr (void *ptr, enum Lisp_Type type)
   0x00005555555a0b75 <make_lisp_ptr+20>:	mov    %rsp,%rbp

1380	{
1381	  Lisp_Object a = TAG_PTR_INITIALLY (type, ptr);
1382	  eassert (TAGGEDP (a, type) && XUNTAG (a, type, char) == ptr);
   0x00005555555a0b78 <make_lisp_ptr+23>:	call   0x5555555b8f19 <die>

./src/buffer.h:
1483	buffer_window_count (struct buffer *b)
   0x00005555555a0b7d <buffer_window_count+0>:	push   %rbp

1484	{
1485	  if (b->base_buffer)
1486	    b = b->base_buffer;
1487	  eassert (b->window_count >= 0);
   0x00005555555a0b7e <buffer_window_count+1>:	mov    $0x5cf,%edx
   0x00005555555a0b83 <buffer_window_count+6>:	lea    0x41453d(%rip),%rsi        # 0x5555559b50c7
   0x00005555555a0b8a <buffer_window_count+13>:	lea    0x416bc7(%rip),%rdi        # 0x5555559b7758

1483	buffer_window_count (struct buffer *b)
   0x00005555555a0b91 <buffer_window_count+20>:	mov    %rsp,%rbp

1484	{
1485	  if (b->base_buffer)
1486	    b = b->base_buffer;
1487	  eassert (b->window_count >= 0);
   0x00005555555a0b94 <buffer_window_count+23>:	call   0x5555555b8f19 <die>

./src/window.h:
490	XWINDOW (Lisp_Object a)
   0x00005555555a0b99 <XWINDOW+0>:	push   %rbp

492	  eassert (WINDOWP (a));
   0x00005555555a0b9a <XWINDOW+1>:	mov    $0x1ec,%edx
   0x00005555555a0b9f <XWINDOW+6>:	lea    0x4144a6(%rip),%rsi        # 0x5555559b504c
   0x00005555555a0ba6 <XWINDOW+13>:	lea    0x4144a8(%rip),%rdi        # 0x5555559b5055

490	XWINDOW (Lisp_Object a)
   0x00005555555a0bad <XWINDOW+20>:	mov    %rsp,%rbp

492	  eassert (WINDOWP (a));
   0x00005555555a0bb0 <XWINDOW+23>:	call   0x5555555b8f19 <die>

491	{
   0x00005555555a0bb5 <XWINDOW.cold+0>:	push   %rbp
   0x00005555555a0bb6 <XWINDOW-368666>:	mov    %rsp,%rbp
   0x00005555555a0bb9 <XWINDOW-368663>:	call   0x5555555a0b99 <XWINDOW>

./src/buffer.h:
827	XBUFFER (Lisp_Object a)
   0x00005555555a0bbe <XBUFFER+0>:	push   %rbp

829	  eassert (BUFFERP (a));
   0x00005555555a0bbf <XBUFFER+1>:	mov    $0x33d,%edx
   0x00005555555a0bc4 <XBUFFER+6>:	lea    0x4144fc(%rip),%rsi        # 0x5555559b50c7
   0x00005555555a0bcb <XBUFFER+13>:	lea    0x4144fe(%rip),%rdi        # 0x5555559b50d0

827	XBUFFER (Lisp_Object a)
   0x00005555555a0bd2 <XBUFFER+20>:	mov    %rsp,%rbp

829	  eassert (BUFFERP (a));
   0x00005555555a0bd5 <XBUFFER+23>:	call   0x5555555b8f19 <die>

828	{
   0x00005555555a0bda <XBUFFER.cold+0>:	push   %rbp
   0x00005555555a0bdb <XBUFFER-368709>:	mov    %rsp,%rbp
   0x00005555555a0bde <XBUFFER-368706>:	call   0x5555555a0bbe <XBUFFER>

./src/frame.h:
1234	FRAME_PARENT_FRAME (struct frame *f)
   0x00005555555a0be3 <FRAME_PARENT_FRAME+0>:	push   %rbp

1235	{
1236	  return NILP (f->parent_frame) ? NULL : XFRAME (f->parent_frame);
   0x00005555555a0be4 <FRAME_PARENT_FRAME+1>:	mov    $0x4d4,%edx
   0x00005555555a0be9 <FRAME_PARENT_FRAME+6>:	lea    0x414471(%rip),%rsi        # 0x5555559b5061
   0x00005555555a0bf0 <FRAME_PARENT_FRAME+13>:	lea    0x414472(%rip),%rdi        # 0x5555559b5069

1234	FRAME_PARENT_FRAME (struct frame *f)
   0x00005555555a0bf7 <FRAME_PARENT_FRAME+20>:	mov    %rsp,%rbp

1235	{
1236	  return NILP (f->parent_frame) ? NULL : XFRAME (f->parent_frame);
   0x00005555555a0bfa <FRAME_PARENT_FRAME+23>:	call   0x5555555b8f19 <die>

./src/lisp.h:
1229	(make_fixnum) (EMACS_INT n)
   0x00005555555a0bff <make_fixnum+0>:	push   %rbp

1230	{
1231	  eassert (!FIXNUM_OVERFLOW_P (n));
   0x00005555555a0c00 <make_fixnum+1>:	mov    $0x4cf,%edx
   0x00005555555a0c05 <make_fixnum+6>:	lea    0x414414(%rip),%rsi        # 0x5555559b5020
   0x00005555555a0c0c <make_fixnum+13>:	lea    0x4155ad(%rip),%rdi        # 0x5555559b61c0

1229	(make_fixnum) (EMACS_INT n)
   0x00005555555a0c13 <make_fixnum+20>:	mov    %rsp,%rbp

1230	{
1231	  eassert (!FIXNUM_OVERFLOW_P (n));
   0x00005555555a0c16 <make_fixnum+23>:	call   0x5555555b8f19 <die>

./src/xdisp.c:
24616	{
   0x00005555555a0c1b <get_it_property.cold+0>:	push   %rbp
   0x00005555555a0c1c <get_it_property-368724>:	mov    %rsp,%rbp
   0x00005555555a0c1f <get_it_property-368721>:	call   0x5555555a0bff <make_fixnum>

24617	  Lisp_Object position, object = it->object;
24618
24619	  if (STRINGP (object))
24620	    position = make_fixnum (IT_STRING_CHARPOS (*it));
24621	  else if (BUFFERP (object))
24622	    {
24623	      position = make_fixnum (IT_CHARPOS (*it));
24624	      object = it->window;
24625	    }
24626	  else
24627	    return Qnil;
24628
24629	  return Fget_char_property (position, prop, object);
24630	}
24631
24632	/* Return the line-prefix/wrap-prefix property, checking both the
24633	   current IT->OBJECT and the underlying buffer text.  */
24634
24635	static Lisp_Object
24636	get_line_prefix_it_property (struct it *it, Lisp_Object prop)
24637	{
24638	  Lisp_Object prefix = get_it_property (it, prop);
24639
24640	  /* If we are looking at a display or overlay string, check also the
24641	     underlying buffer text.  */
24642	  if (NILP (prefix) && it->sp > 0 && STRINGP (it->object))
24643	    return Fget_char_property (make_fixnum (IT_CHARPOS (*it)), prop,
24644				       it->w->contents);
24645	  return prefix;
24646	}
24647
24648	/* See if there's a line- or wrap-prefix, and if so, push it on IT.  */
24649
24650	static void
24651	handle_line_prefix (struct it *it)
24652	{
24653	  Lisp_Object prefix;
24654	  bool wrap_prop = false;
24655
24656	  if (it->continuation_lines_width > 0)
24657	    {
24658	      prefix = get_line_prefix_it_property (it, Qwrap_prefix);
24659	      if (NILP (prefix))
24660		prefix = Vwrap_prefix;
24661	      wrap_prop = true;
24662	    }
24663	  else
24664	    {
24665	      prefix = get_line_prefix_it_property (it, Qline_prefix);
24666	      if (NILP (prefix))
24667		prefix = Vline_prefix;
24668	    }
24669	  if (! NILP (prefix) && push_prefix_prop (it, prefix))
24670	    {
24671	      /* If the prefix is wider than the window, and we try to wrap
24672		 it, it would acquire its own wrap prefix, and so on till the
24673		 iterator stack overflows.  So, don't wrap the prefix.  */
24674	      it->line_wrap = TRUNCATE;
24675	      it->avoid_cursor_p = true;
24676	      /* Interpreting :align-to relative to the beginning of the logical
24677	         line effectively renders this feature unusable, so we make an
24678	         exception for this use of :align-to.  */
24679	      if (wrap_prop && CONSP (prefix) && EQ (XCAR (prefix), Qspace))
24680		it->align_visually_p = true;
24681	    }
24682	}
24683
24684	^L
24685
24686	/* Remove N glyphs at the start of a reversed IT->glyph_row.  Called
24687	   only for R2L lines from display_line and display_string, when they
24688	   decide that too many glyphs were produced by PRODUCE_GLYPHS, and
24689	   the line/string needs to be continued on the next glyph row.  */
24690	static void
24691	unproduce_glyphs (struct it *it, int n)
24692	{
24693	  struct glyph *glyph, *end;
24694
24695	  eassert (it->glyph_row);
24696	  eassert (it->glyph_row->reversed_p);
24697	  eassert (it->area == TEXT_AREA);
24698	  eassert (n <= it->glyph_row->used[TEXT_AREA]);
24699
24700	  if (n > it->glyph_row->used[TEXT_AREA])
24701	    n = it->glyph_row->used[TEXT_AREA];
24702	  glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
24703	  end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
24704	  for ( ; glyph < end; glyph++)
24705	    glyph[-n] = *glyph;
24706	}
24707
24708	/* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
24709	   and ROW->maxpos.  */
24710	static void
24711	find_row_edges (struct it *it, struct glyph_row *row,
24712			ptrdiff_t min_pos, ptrdiff_t min_bpos,
24713			ptrdiff_t max_pos, ptrdiff_t max_bpos)
24714	{
24715	  /* FIXME: Revisit this when glyph ``spilling'' in continuation
24716	     lines' rows is implemented for bidi-reordered rows.  */
24717
24718	  /* ROW->minpos is the value of min_pos, the minimal buffer position
24719	     we have in ROW, or ROW->start.pos if that is smaller.  */
24720	  if (min_pos <= ZV && min_pos < row->start.pos.charpos)
24721	    SET_TEXT_POS (row->minpos, min_pos, min_bpos);
24722	  else
24723	    /* We didn't find buffer positions smaller than ROW->start, or
24724	       didn't find _any_ valid buffer positions in any of the glyphs,
24725	       so we must trust the iterator's computed positions.  */
24726	      row->minpos = row->start.pos;
24727	  if (max_pos <= 0)
24728	    {
24729	      max_pos = CHARPOS (it->current.pos);
24730	      max_bpos = BYTEPOS (it->current.pos);
24731	    }
24732
24733	  /* Here are the various use-cases for ending the row, and the
24734	     corresponding values for ROW->maxpos:
24735
24736	     Line ends in a newline from buffer       eol_pos + 1
24737	     Line is continued from buffer            max_pos + 1
24738	     Line is truncated on right               it->current.pos
24739	     Line ends in a newline from string       max_pos + 1(*)
24740	      (*) + 1 only when line ends in a forward scan
24741	     Line is continued from string            max_pos
24742	     Line is continued from display vector    max_pos
24743	     Line is entirely from a string           min_pos == max_pos
24744	     Line is entirely from a display vector   min_pos == max_pos
24745	     Line that ends at ZV                     ZV
24746
24747	     If you discover other use-cases, please add them here as
24748	     appropriate.  */
24749	  if (row->ends_at_zv_p)
24750	    row->maxpos = it->current.pos;
24751	  else if (row->used[TEXT_AREA])
24752	    {
24753	      bool seen_this_string = false;
24754	      struct glyph_row *r1 = row - 1;
24755
24756	      /* Did we see the same display string on the previous row?  */
24757	      if (STRINGP (it->object)
24758		  /* this is not the first row */
24759		  && row > it->w->desired_matrix->rows
24760		  /* previous row is not the header line or tab-line */
24761		  && !r1->mode_line_p
24762		  /* previous row also ends in a newline from a string */
24763		  && r1->ends_in_newline_from_string_p)
24764		{
24765		  struct glyph *start, *end;
24766
24767		  /* Search for the last glyph of the previous row that came
24768		     from buffer or string.  Depending on whether the row is
24769		     L2R or R2L, we need to process it front to back or the
24770		     other way round.  */
24771		  if (!r1->reversed_p)
24772		    {
24773		      start = r1->glyphs[TEXT_AREA];
24774		      end = start + r1->used[TEXT_AREA];
24775		      /* Glyphs inserted by redisplay have nil as their object.  */
24776		      while (end > start
24777			     && NILP ((end - 1)->object)
24778			     && (end - 1)->charpos <= 0)
24779			--end;
24780		      if (end > start)
24781			{
24782			  if (EQ ((end - 1)->object, it->object))
24783			    seen_this_string = true;
24784			}
24785		      else
24786			/* If all the glyphs of the previous row were inserted
24787			   by redisplay, it means the previous row was
24788			   produced from a single newline, which is only
24789			   possible if that newline came from the same string
24790			   as the one which produced this ROW.  */
24791			seen_this_string = true;
24792		    }
24793		  else
24794		    {
24795		      end = r1->glyphs[TEXT_AREA] - 1;
24796		      start = end + r1->used[TEXT_AREA];
24797		      while (end < start
24798			     && NILP ((end + 1)->object)
24799			     && (end + 1)->charpos <= 0)
24800			++end;
24801		      if (end < start)
24802			{
24803			  if (EQ ((end + 1)->object, it->object))
24804			    seen_this_string = true;
24805			}
24806		      else
24807			seen_this_string = true;
24808		    }
24809		}
24810	      /* Take note of each display string that covers a newline only
24811		 once, the first time we see it.  This is for when a display
24812		 string includes more than one newline in it.  */
24813	      if (row->ends_in_newline_from_string_p && !seen_this_string)
24814		{
24815		  /* If we were scanning the buffer forward when we displayed
24816		     the string, we want to account for at least one buffer
24817		     position that belongs to this row (position covered by
24818		     the display string), so that cursor positioning will
24819		     consider this row as a candidate when point is at the end
24820		     of the visual line represented by this row.  This is not
24821		     required when scanning back, because max_pos will already
24822		     have a much larger value.  */
24823		  if (CHARPOS (row->end.pos) > max_pos)
24824		    inc_both (&max_pos, &max_bpos);
24825		  SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
24826		}
24827	      else if (CHARPOS (it->eol_pos) > 0)
24828		SET_TEXT_POS (row->maxpos,
24829			      CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
24830	      else if (row->continued_p)
24831		{
24832		  /* If max_pos is different from IT's current position, it
24833		     means IT->method does not belong to the display element
24834		     at max_pos.  However, it also means that the display
24835		     element at max_pos was displayed in its entirety on this
24836		     line, which is equivalent to saying that the next line
24837		     starts at the next buffer position.  */
24838		  if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
24839		    SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
24840		  else
24841		    {
24842		      inc_both (&max_pos, &max_bpos);
24843		      SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
24844		    }
24845		}
24846	      else if (row->truncated_on_right_p)
24847		/* display_line already called reseat_at_next_visible_line_start,
24848		   which puts the iterator at the beginning of the next line, in
24849		   the logical order. */
24850		row->maxpos = it->current.pos;
24851	      else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
24852		/* A line that is entirely from a string/image/stretch...  */
24853		row->maxpos = row->minpos;
24854	      else
24855		emacs_abort ();
24856	    }
24857	  else
24858	    row->maxpos = it->current.pos;
24859	}
24860
24861	/* Like display_count_lines, but capable of counting outside of the
24862	   current narrowed region.  */
24863	static ptrdiff_t
24864	display_count_lines_logically (ptrdiff_t start_byte, ptrdiff_t limit_byte,
24865				       ptrdiff_t count, ptrdiff_t *byte_pos_ptr)
24866	{
24867	  if (!display_line_numbers_widen || (BEGV == BEG && ZV == Z))
24868	    return display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
24869
24870	  ptrdiff_t val;
24871	  specpdl_ref pdl_count = SPECPDL_INDEX ();
24872	  record_unwind_protect (save_restriction_restore, save_restriction_save ());
24873	  labeled_restrictions_remove_in_current_buffer ();
24874	  Fwiden ();
24875	  val = display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
24876	  unbind_to (pdl_count, Qnil);
24877	  return val;
24878	}
24879
24880	/* Count the number of screen lines in window IT->w between character
24881	   position IT_CHARPOS(*IT) and the line showing that window's point.  */
24882	static ptrdiff_t
24883	display_count_lines_visually (struct it *it)
24884	{
24885	  struct it tem_it;
24886	  ptrdiff_t to;
24887	  struct text_pos from;
24888
24889	  /* If we already calculated a relative line number, use that.  This
24890	     trick relies on the fact that visual lines (a.k.a. "glyph rows")
24891	     are laid out sequentially, one by one, for each sequence of calls
24892	     to display_line or other similar function that follows a call to
24893	     init_iterator.  */
24894	  if (it->lnum_bytepos > 0)
24895	    return it->lnum + 1;
24896	  else
24897	    {
24898	      specpdl_ref count = SPECPDL_INDEX ();
24899
24900	      if (IT_CHARPOS (*it) <= PT)
24901		{
24902		  from = it->current.pos;
24903		  to = PT;
24904		}
24905	      else
24906		{
24907		  SET_TEXT_POS (from, PT, PT_BYTE);
24908		  to = IT_CHARPOS (*it);
24909		}
24910	      /* Need to disable visual mode temporarily, since otherwise the
24911		 call to move_it_to below and inside start_display will cause
24912		 infinite recursion.  */
24913	      specbind (Qdisplay_line_numbers, Qrelative);
24914	      start_display (&tem_it, it->w, from);
24915	      /* Some redisplay optimizations could invoke us very far from
24916		 PT, which will make the caller painfully slow.  There should
24917		 be no need to go too far beyond the window's bottom, as any
24918		 such optimization will fail to show point anyway.  */
24919	      move_it_to (&tem_it, to, -1,
24920			  tem_it.last_visible_y
24921			  + (SCROLL_LIMIT + 10) * FRAME_LINE_HEIGHT (tem_it.f),
24922			  -1, MOVE_TO_POS | MOVE_TO_Y);
24923	      unbind_to (count, Qnil);
24924	      return IT_CHARPOS (*it) <= PT ? -tem_it.vpos : tem_it.vpos;
24925	    }
24926	}
24927
24928	/* Produce the line-number glyphs for the current glyph_row.  If
24929	   IT->glyph_row is non-NULL, populate the row with the produced
24930	   glyphs.  */
24931	static void
24932	maybe_produce_line_number (struct it *it)
24933	{
24934	  ptrdiff_t last_line = it->lnum;
24935	  ptrdiff_t start_from, bytepos;
24936	  ptrdiff_t this_line;
24937	  bool first_time = false;
24938	  ptrdiff_t beg_byte;
24939	  ptrdiff_t z_byte;
24940	  bool line_numbers_wide;
24941	  void *itdata = bidi_shelve_cache ();
24942
24943	  if (display_line_numbers_offset
24944	      && !display_line_numbers_widen
24945	      && !EQ (Vdisplay_line_numbers, Qvisual)
24946	      && !EQ (Vdisplay_line_numbers, Qrelative))
24947	    line_numbers_wide = true;
24948	  else
24949	    line_numbers_wide = display_line_numbers_widen;
24950
24951	  beg_byte = line_numbers_wide ? BEG_BYTE : BEGV_BYTE;
24952	  z_byte = line_numbers_wide ? Z_BYTE : ZV_BYTE;
24953
24954	  if (EQ (Vdisplay_line_numbers, Qvisual))
24955	    this_line = display_count_lines_visually (it);
24956	  else
24957	    {
24958	      if (!last_line)
24959		{
24960		  /* If possible, reuse data cached by line-number-mode.  */
24961		  /* NOTE: We use `base_line_number` without checking
24962		     BASE_LINE_NUMBER_VALID_P because we assume that `redisplay_window`
24963		     has already flushed this cache for us when needed.
24964		     NOTE2: Checking BASE_LINE_NUMBER_VALID_P here would be
24965		     overly pessimistic because it might say that the cache
24966		     was invalid before entering `redisplay_window` yet the
24967		     value has just been refreshed.  */
24968		  if (it->w->base_line_number > 0
24969		      && it->w->base_line_pos > 0
24970		      && it->w->base_line_pos <= IT_CHARPOS (*it)
24971		      /* line-number-mode always displays narrowed line
24972			 numbers, so we cannot use its data if the user wants
24973			 line numbers that disregard narrowing, or if the
24974			 buffer's narrowing has just changed.  */
24975		      && !(line_numbers_wide
24976			   && (BEG_BYTE != BEGV_BYTE || Z_BYTE != ZV_BYTE))
24977		      && !current_buffer->clip_changed)
24978		    {
24979		      start_from = CHAR_TO_BYTE (it->w->base_line_pos);
24980		      last_line = it->w->base_line_number - 1;
24981		    }
24982		  else
24983		    start_from = beg_byte;
24984		  if (!it->lnum_bytepos)
24985		    first_time = true;
24986		}
24987	      else
24988		start_from = it->lnum_bytepos;
24989
24990	      /* Paranoia: what if someone changes the narrowing since the
24991		 last time display_line was called?  Shouldn't really happen,
24992		 but who knows what some crazy Lisp invoked by :eval could do?  */
24993	      if (!(beg_byte <= start_from && start_from <= z_byte))
24994		{
24995		  last_line = 0;
24996		  start_from = beg_byte;
24997		}
24998
24999	      this_line =
25000		last_line + display_count_lines_logically (start_from,
25001							   IT_BYTEPOS (*it),
25002							   IT_CHARPOS (*it), &bytepos);
25003	      eassert (this_line > 0 || (this_line == 0 && start_from == beg_byte));
25004	      eassert (bytepos == IT_BYTEPOS (*it));
25005	    }
25006
25007	  /* Record the line number information.  */
25008	  if (this_line != last_line || !it->lnum_bytepos)
25009	    {
25010	      it->lnum = this_line;
25011	      it->lnum_bytepos = IT_BYTEPOS (*it);
25012	    }
25013
25014	  /* Produce the glyphs for the line number.  */
25015	  struct it tem_it;
25016	  char lnum_buf[INT_STRLEN_BOUND (ptrdiff_t) + 1];
25017	  bool beyond_zv = IT_BYTEPOS (*it) >= ZV_BYTE;
25018	  ptrdiff_t lnum_offset = -1; /* to produce 1-based line numbers */
25019	  int lnum_face_id = merge_faces (it->w, Qline_number, 0, DEFAULT_FACE_ID);
25020	  int current_lnum_face_id
25021	    = merge_faces (it->w, Qline_number_current_line, 0, DEFAULT_FACE_ID);
25022	  /* From here onwards, we must prevent freeing realized faces, because
25023	     we are using the above 2 face IDs for the glyphs we produce.  */
25024	  bool save_free_realized_faces = inhibit_free_realized_faces;
25025	  inhibit_free_realized_faces = true;
25026	  /* Compute point's line number if needed.  */
25027	  if ((EQ (Vdisplay_line_numbers, Qrelative)
25028	       || EQ (Vdisplay_line_numbers, Qvisual)
25029	       || lnum_face_id != current_lnum_face_id)
25030	      && !it->pt_lnum)
25031	    {
25032	      ptrdiff_t ignored;
25033	      if (PT_BYTE > it->lnum_bytepos && !EQ (Vdisplay_line_numbers, Qvisual))
25034		it->pt_lnum =
25035		  this_line + display_count_lines_logically (it->lnum_bytepos, PT_BYTE,
25036							     PT, &ignored);
25037	      else
25038		it->pt_lnum = display_count_lines_logically (beg_byte, PT_BYTE, PT,
25039							     &ignored);
25040	    }
25041	  /* Compute the required width if needed.  */
25042	  if (!it->lnum_width)
25043	    {
25044	      if (FIXNATP (Vdisplay_line_numbers_width))
25045		it->lnum_width = XFIXNAT (Vdisplay_line_numbers_width);
25046
25047	      /* Max line number to be displayed cannot be more than the one
25048		 corresponding to the last row of the desired matrix.  */
25049	      ptrdiff_t max_lnum;
25050
25051	      if (NILP (Vdisplay_line_numbers_current_absolute)
25052		  && (EQ (Vdisplay_line_numbers, Qrelative)
25053		      || EQ (Vdisplay_line_numbers, Qvisual)))
25054		/* We subtract one more because the current line is always
25055		   zero in this mode.  */
25056		max_lnum = it->w->desired_matrix->nrows - 2;
25057	      else if (EQ (Vdisplay_line_numbers, Qvisual))
25058		max_lnum = it->pt_lnum + it->w->desired_matrix->nrows - 1;
25059	      else
25060		max_lnum = this_line + it->w->desired_matrix->nrows - 1 - it->vpos;
25061	      max_lnum = max (1, max_lnum);
25062	      it->lnum_width = max (it->lnum_width, log10 (max_lnum) + 1);
25063	      eassert (it->lnum_width > 0);
25064	    }
25065	  if (EQ (Vdisplay_line_numbers, Qrelative))
25066	    lnum_offset = it->pt_lnum;
25067	  else if (EQ (Vdisplay_line_numbers, Qvisual))
25068	    lnum_offset = 0;
25069	  else if (display_line_numbers_offset)
25070	    lnum_offset -= display_line_numbers_offset;
25071
25072	  /* Under 'relative', display the absolute line number for the
25073	     current line, unless the user requests otherwise.  */
25074	  ptrdiff_t lnum_to_display = eabs (this_line - lnum_offset);
25075	  if ((EQ (Vdisplay_line_numbers, Qrelative)
25076	       || EQ (Vdisplay_line_numbers, Qvisual))
25077	      && lnum_to_display == 0
25078	      && !NILP (Vdisplay_line_numbers_current_absolute))
25079	    lnum_to_display = it->pt_lnum + 1;
25080	  /* In L2R rows we need to append the blank separator, in R2L
25081	     rows we need to prepend it.  But this function is usually
25082	     called when no display elements were produced from the
25083	     following line, so the paragraph direction might be unknown.
25084	     Therefore we cheat and add 2 blanks, one on either side.  */
25085	  pint2str (lnum_buf, it->lnum_width + 1, lnum_to_display);
25086	  strcat (lnum_buf, " ");
25087
25088	  /* Setup for producing the glyphs.  */
25089	  init_iterator (&tem_it, it->w, -1, -1, &scratch_glyph_row,
25090			 /* FIXME: Use specialized face.  */
25091			 DEFAULT_FACE_ID);
25092	  scratch_glyph_row.reversed_p = false;
25093	  scratch_glyph_row.used[TEXT_AREA] = 0;
25094	  SET_TEXT_POS (tem_it.position, 0, 0);
25095	  tem_it.avoid_cursor_p = true;
25096	  tem_it.bidi_p = true;
25097	  tem_it.bidi_it.type = WEAK_EN;
25098	  /* According to UAX#9, EN goes up 2 levels in L2R paragraph and
25099	     1 level in R2L paragraphs.  Emulate that, assuming we are in
25100	     an L2R paragraph.  */
25101	  tem_it.bidi_it.resolved_level = 2;
25102
25103	  /* We must leave space for 2 glyphs for continuation and truncation,
25104	     and at least one glyph for buffer text.  */
25105	  int width_limit =
25106	    tem_it.last_visible_x - tem_it.first_visible_x
25107	    - 3 * FRAME_COLUMN_WIDTH (it->f);
25108
25109	  tem_it.face_id = lnum_face_id;
25110	  /* Avoid displaying any face other than line-number on
25111	     empty lines beyond EOB.  */
25112	  if (lnum_face_id != current_lnum_face_id
25113	      && (EQ (Vdisplay_line_numbers, Qvisual)
25114		  ? this_line == 0
25115		  : this_line == it->pt_lnum)
25116	      && it->what != IT_EOB)
25117	    tem_it.face_id = current_lnum_face_id;
25118	  else if (!beyond_zv)
25119	    {
25120	      if (display_line_numbers_major_tick > 0
25121		  && (lnum_to_display % display_line_numbers_major_tick == 0))
25122		tem_it.face_id = merge_faces (it->w, Qline_number_major_tick,
25123					      0, DEFAULT_FACE_ID);
25124	      else if (display_line_numbers_minor_tick > 0
25125		       && (lnum_to_display % display_line_numbers_minor_tick == 0))
25126		tem_it.face_id = merge_faces (it->w, Qline_number_minor_tick,
25127					      0, DEFAULT_FACE_ID);
25128	    }
25129
25130	  /* Produce glyphs for the line number in a scratch glyph_row.  */
25131	  for (const char *p = lnum_buf; *p; p++)
25132	    {
25133	      /* For continuation lines and lines after ZV, instead of a line
25134		 number, produce a blank prefix of the same width.  */
25135	      if (beyond_zv
25136		  /* Don't display the same line number more than once.  */
25137		  || (!EQ (Vdisplay_line_numbers, Qvisual)
25138		      && (it->continuation_lines_width > 0
25139			  || (this_line == last_line && !first_time))))
25140		tem_it.c = tem_it.char_to_display = ' ';
25141	      else
25142		tem_it.c = tem_it.char_to_display = *p;
25143	      tem_it.len = 1;
25144	      /* Make sure these glyphs will have a "position" of -1.  */
25145	      SET_TEXT_POS (tem_it.position, -1, -1);
25146	      PRODUCE_GLYPHS (&tem_it);
25147
25148	      /* Stop producing glyphs, and refrain from producing the line
25149		 number, if we don't have enough space on this line.  */
25150	      if (tem_it.current_x >= width_limit)
25151		{
25152		  it->lnum_width = 0;
25153		  it->lnum_pixel_width = 0;
25154		  bidi_unshelve_cache (itdata, false);
25155		  inhibit_free_realized_faces = save_free_realized_faces;
25156		  return;
25157		}
25158	    }
25159
25160	  inhibit_free_realized_faces = save_free_realized_faces;
25161
25162	  /* Record the width in pixels we need for the line number display.  */
25163	  it->lnum_pixel_width = tem_it.current_x;
25164	  /* Copy the produced glyphs into IT's glyph_row.  */
25165	  struct glyph *g = scratch_glyph_row.glyphs[TEXT_AREA];
25166	  struct glyph *e = g + scratch_glyph_row.used[TEXT_AREA];
25167	  struct glyph *p = it->glyph_row ? it->glyph_row->glyphs[TEXT_AREA] : NULL;
25168	  short *u = it->glyph_row ? &it->glyph_row->used[TEXT_AREA] : NULL;
25169
25170	  eassert (it->glyph_row == NULL || it->glyph_row->used[TEXT_AREA] == 0);
25171
25172	  for ( ; g < e; g++)
25173	    {
25174	      it->current_x += g->pixel_width;
25175	      /* The following is important when this function is called
25176		 from move_it_in_display_line_to: HPOS is incremented only
25177		 when we are in the visible portion of the glyph row.  */
25178	      if (it->current_x > it->first_visible_x)
25179		it->hpos++;
25180	      if (p)
25181		{
25182		  *p++ = *g;
25183		  (*u)++;
25184		}
25185	    }
25186
25187	  /* Update IT's metrics due to glyphs produced for line numbers.
25188	     Don't do that for rows beyond ZV, to avoid displaying a cursor of
25189	     different dimensions there.  */
25190	  if (!beyond_zv)
25191	    {
25192	      if (it->glyph_row)
25193		{
25194		  struct glyph_row *row = it->glyph_row;
25195
25196		  it->max_ascent = max (row->ascent, tem_it.max_ascent);
25197		  it->max_descent = max (row->height - row->ascent, tem_it.max_descent);
25198		  it->max_phys_ascent = max (row->phys_ascent, tem_it.max_phys_ascent);
25199		  it->max_phys_descent = max (row->phys_height - row->phys_ascent,
25200					      tem_it.max_phys_descent);
25201		}
25202	      else
25203		{
25204		  it->max_ascent = max (it->max_ascent, tem_it.max_ascent);
25205		  it->max_descent = max (it->max_descent, tem_it.max_descent);
25206		  it->max_phys_ascent = max (it->max_phys_ascent,
25207					     tem_it.max_phys_ascent);
25208		  it->max_phys_descent = max (it->max_phys_descent,
25209					      tem_it.max_phys_descent);
25210		}
25211	    }
25212
25213	  it->line_number_produced_p = true;
25214
25215	  bidi_unshelve_cache (itdata, false);
25216	}
25217
25218	/* Return true if this glyph row needs a line number to be produced
25219	   for it.  */
25220	static bool
25221	should_produce_line_number (struct it *it)
25222	{
25223	  if (NILP (Vdisplay_line_numbers))
25224	    return false;
25225
25226	  /* Don't display line numbers in minibuffer windows.  */
25227	  if (MINI_WINDOW_P (it->w))
25228	    return false;
25229
25230	#ifdef HAVE_WINDOW_SYSTEM
25231	  /* Don't display line number in tooltip frames.  */
25232	  if (FRAME_TOOLTIP_P (XFRAME (WINDOW_FRAME (it->w))))
   0x00005555555a0c24 <should_produce_line_number.cold+0>:	mov    $0x6290,%edx
   0x00005555555a0c29 <should_produce_line_number-368903>:	lea    0x416a80(%rip),%rsi        # 0x5555559b76b0
   0x00005555555a0c30 <should_produce_line_number-368896>:	lea    0x416b36(%rip),%rdi        # 0x5555559b776d
   0x00005555555a0c37 <should_produce_line_number-368889>:	call   0x5555555b8f19 <die>
   0x00005555555a0c3c <should_produce_line_number-368884>:	call   0x5555555a0bff <make_fixnum>

./src/lisp.h:
1314	XFIXNUM (Lisp_Object a)
   0x00005555555a0c41 <XFIXNUM+0>:	push   %rbp

1315	{
1316	  eassert (FIXNUMP (a));
   0x00005555555a0c42 <XFIXNUM+1>:	mov    $0x524,%edx
   0x00005555555a0c47 <XFIXNUM+6>:	lea    0x4143d2(%rip),%rsi        # 0x5555559b5020
   0x00005555555a0c4e <XFIXNUM+13>:	lea    0x414437(%rip),%rdi        # 0x5555559b508c

1314	XFIXNUM (Lisp_Object a)
   0x00005555555a0c55 <XFIXNUM+20>:	mov    %rsp,%rbp

1315	{
1316	  eassert (FIXNUMP (a));
   0x00005555555a0c58 <XFIXNUM+23>:	call   0x5555555b8f19 <die>
   0x00005555555a0c5d <unwind_narrowed_begv.cold+0>:	call   0x5555555a0c41 <XFIXNUM>

./src/xdisp.c:
3735	}
   0x00005555555a0c62 <Ftrace_redisplay.cold+0>:	call   0x5555555a0c41 <XFIXNUM>

./src/lisp.h:
1799	XVECTOR (Lisp_Object a)
   0x00005555555a0c67 <XVECTOR+0>:	push   %rbp

1800	{
1801	  eassert (VECTORLIKEP (a));
   0x00005555555a0c68 <XVECTOR+1>:	mov    $0x709,%edx
   0x00005555555a0c6d <XVECTOR+6>:	lea    0x4143ac(%rip),%rsi        # 0x5555559b5020
   0x00005555555a0c74 <XVECTOR+13>:	lea    0x41441d(%rip),%rdi        # 0x5555559b5098

1799	XVECTOR (Lisp_Object a)
   0x00005555555a0c7b <XVECTOR+20>:	mov    %rsp,%rbp

1800	{
1801	  eassert (VECTORLIKEP (a));
   0x00005555555a0c7e <XVECTOR+23>:	call   0x5555555b8f19 <die>

1802	  struct Lisp_Vector *v = XUNTAG (a, Lisp_Vectorlike, struct Lisp_Vector);
1803	  igc_check_fwd (v, true);
1804	  return v;
1805	}
1806
1807	INLINE ptrdiff_t
1808	ASIZE (Lisp_Object array)
1809	{
1810	  ptrdiff_t size = XVECTOR (array)->header.size;
1811	  eassume (0 <= size);
1812	  return size;
1813	}
1814
1815	INLINE ptrdiff_t
1816	gc_asize (Lisp_Object array)
1817	{
1818	  /* Like ASIZE, but also can be used in the garbage collector.  */
1819	  return XVECTOR (array)->header.size & ~ARRAY_MARK_FLAG;
1820	}
1821
1822	INLINE ptrdiff_t
1823	PVSIZE (Lisp_Object pv)
1824	{
1825	  return ASIZE (pv) & PSEUDOVECTOR_SIZE_MASK;
1826	}
1827
1828	INLINE bool
1829	VECTORP (Lisp_Object x)
1830	{
1831	  return VECTORLIKEP (x) && ! (ASIZE (x) & PSEUDOVECTOR_FLAG);
1832	}
1833
1834	INLINE void
1835	CHECK_VECTOR (Lisp_Object x)
1836	{
1837	  CHECK_TYPE (VECTORP (x), Qvectorp, x);
1838	}
1839
1840
1841	/* A pseudovector is like a vector, but has other non-Lisp components.  */
1842
1843	INLINE enum pvec_type
1844	PSEUDOVECTOR_TYPE (const struct Lisp_Vector *v)
1845	{
1846	  ptrdiff_t size = v->header.size;
1847	  return (size & PSEUDOVECTOR_FLAG
1848	          ? (size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_AREA_BITS
1849	          : PVEC_NORMAL_VECTOR);
1850	}
1851
1852	/* Can't be used with PVEC_NORMAL_VECTOR.  */
1853	INLINE bool
1854	PSEUDOVECTOR_TYPEP (const struct vectorlike_header *a, enum pvec_type code)
1855	{
1856	  /* We don't use PSEUDOVECTOR_TYPE here so as to avoid a shift
1857	   * operation when `code' is known.  */
1858	  return ((a->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
1859		  == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS)));
1860	}
1861
1862	/* A boolvector is a kind of vectorlike, with contents like a string.  */
1863
1864	struct Lisp_Bool_Vector
1865	  {
1866	    /* HEADER.SIZE is the vector's size field.  It doesn't have the real size,
1867	       just the subtype information.  */
1868	    struct vectorlike_header header;
1869	    /* The size in bits; at most BOOL_VECTOR_LENGTH_MAX.  */
1870	    EMACS_INT size;
1871	    /* The actual bits, packed into bytes.
1872	       Zeros fill out the last word if needed.
1873	       The bits are in little-endian order in the bytes, and
1874	       the bytes are in little-endian order in the words.  */
1875	    bits_word data[FLEXIBLE_ARRAY_MEMBER];
1876	  } GCALIGNED_STRUCT;
1877
1878	/* Some handy constants for calculating sizes
1879	   and offsets, mostly of vectorlike objects.
1880
1881	   The garbage collector assumes that the initial part of any struct
1882	   that starts with a struct vectorlike_header followed by N
1883	   Lisp_Objects (some possibly in arrays and/or a trailing flexible
1884	   array) will be laid out like a struct Lisp_Vector with N
1885	   Lisp_Objects.  This assumption is true in practice on known Emacs
1886	   targets even though the C standard does not guarantee it.  This
1887	   header contains a few sanity checks that should suffice to detect
1888	   violations of this assumption on plausible practical hosts.  */
1889
1890	enum
1891	  {
1892	    header_size = offsetof (struct Lisp_Vector, contents),
1893	    bool_header_size = offsetof (struct Lisp_Bool_Vector, data),
1894	    word_size = sizeof (Lisp_Object)
1895	  };
1896
1897	/* A bool vector's length must be a fixnum for XFIXNUM (Flength (...)).
1898	   Also, it is limited object size, which must fit in both ptrdiff_t and
1899	   size_t including header overhead and trailing alignment.  */
1900	#define BOOL_VECTOR_LENGTH_MAX \
1901	  min (MOST_POSITIVE_FIXNUM, \
1902	       ((INT_MULTIPLY_OVERFLOW (min (PTRDIFF_MAX, SIZE_MAX) - bool_header_size,\
1903					(EMACS_INT) BOOL_VECTOR_BITS_PER_CHAR) \
1904		 ? EMACS_INT_MAX \
1905		 : ((min (PTRDIFF_MAX, SIZE_MAX) - bool_header_size) \
1906		    * (EMACS_INT) BOOL_VECTOR_BITS_PER_CHAR)) \
1907		- (BITS_PER_BITS_WORD - 1)))
1908
1909	/* The number of data words and bytes in a bool vector with SIZE bits.  */
1910
1911	INLINE EMACS_INT
1912	bool_vector_words (EMACS_INT size)
1913	{
1914	  eassume (0 <= size && size <= EMACS_INT_MAX - (BITS_PER_BITS_WORD - 1));
1915	  return (size + (BITS_PER_BITS_WORD - 1)) / BITS_PER_BITS_WORD;
1916	}
1917
1918	INLINE EMACS_INT
1919	bool_vector_bytes (EMACS_INT size)
1920	{
1921	  eassume (0 <= size && size <= EMACS_INT_MAX - (BITS_PER_BITS_WORD - 1));
1922	  return (size + (BOOL_VECTOR_BITS_PER_CHAR - 1)) / BOOL_VECTOR_BITS_PER_CHAR;
1923	}
1924
1925	INLINE bits_word
1926	bits_word_to_host_endian (bits_word val)
1927	{
1928	#ifndef WORDS_BIGENDIAN
1929	  return val;
1930	#else
1931	  if (BITS_WORD_MAX >> 31 == 1)
1932	    return bswap_32 (val);
1933	  if (BITS_WORD_MAX >> 31 >> 31 >> 1 == 1)
1934	    return bswap_64 (val);
1935	  {
1936	    int i;
1937	    bits_word r = 0;
1938	    for (i = 0; i < sizeof val; i++)
1939	      {
1940		r = ((r << 1 << (CHAR_BIT - 1))
1941		     | (val & ((1u << 1 << (CHAR_BIT - 1)) - 1)));
1942		val = val >> 1 >> (CHAR_BIT - 1);
1943	      }
1944	    return r;
1945	  }
1946	#endif
1947	}
1948
1949	INLINE bool
1950	BOOL_VECTOR_P (Lisp_Object a)
1951	{
1952	  return PSEUDOVECTORP (a, PVEC_BOOL_VECTOR);
1953	}
1954
1955	INLINE void
1956	CHECK_BOOL_VECTOR (Lisp_Object x)
1957	{
1958	  CHECK_TYPE (BOOL_VECTOR_P (x), Qbool_vector_p, x);
1959	}
1960
1961	INLINE struct Lisp_Bool_Vector *
1962	XBOOL_VECTOR (Lisp_Object a)
1963	{
1964	  eassert (BOOL_VECTOR_P (a));
1965	  struct Lisp_Bool_Vector *v
1966	    = XUNTAG (a, Lisp_Vectorlike, struct Lisp_Bool_Vector);
1967	  igc_check_fwd (v, true);
1968	  return v;
1969	}
1970
1971	INLINE EMACS_INT
1972	bool_vector_size (Lisp_Object a)
1973	{
1974	  EMACS_INT size = XBOOL_VECTOR (a)->size;
1975	  eassume (0 <= size);
1976	  return size;
1977	}
1978
1979	INLINE bits_word *
1980	bool_vector_data (Lisp_Object a)
1981	{
1982	  return XBOOL_VECTOR (a)->data;
1983	}
1984
1985	INLINE unsigned char *
1986	bool_vector_uchar_data (Lisp_Object a)
1987	{
1988	  return (unsigned char *) bool_vector_data (a);
1989	}
1990
1991	/* True if A's Ith bit is set.  */
1992
1993	INLINE bool
1994	bool_vector_bitref (Lisp_Object a, EMACS_INT i)
1995	{
1996	  eassume (0 <= i);
1997	  eassert (i < bool_vector_size (a));
1998	  return !! (bool_vector_uchar_data (a)[i / BOOL_VECTOR_BITS_PER_CHAR]
1999		     & (1 << (i % BOOL_VECTOR_BITS_PER_CHAR)));
2000	}
2001
2002	INLINE Lisp_Object
2003	bool_vector_ref (Lisp_Object a, EMACS_INT i)
2004	{
2005	  return bool_vector_bitref (a, i) ? Qt : Qnil;
2006	}
2007
2008	/* Set A's Ith bit to B.  */
2009
2010	INLINE void
2011	bool_vector_set (Lisp_Object a, EMACS_INT i, bool b)
2012	{
2013	  eassume (0 <= i);
2014	  eassert (i < bool_vector_size (a));
2015
2016	  unsigned char *addr
2017	    = &bool_vector_uchar_data (a)[i / BOOL_VECTOR_BITS_PER_CHAR];
2018	  if (b)
2019	    *addr |= 1 << (i % BOOL_VECTOR_BITS_PER_CHAR);
2020	  else
2021	    *addr &= ~ (1 << (i % BOOL_VECTOR_BITS_PER_CHAR));
2022	}
2023
2024	/* Conveniences for dealing with Lisp arrays.  */
2025
2026	INLINE Lisp_Object
2027	AREF (Lisp_Object array, ptrdiff_t idx)
   0x00005555555a0c83 <AREF+0>:	push   %rbp

2028	{
2029	  eassert (0 <= idx && idx < gc_asize (array));
   0x00005555555a0c84 <AREF+1>:	mov    $0x7ed,%edx
   0x00005555555a0c89 <AREF+6>:	lea    0x414390(%rip),%rsi        # 0x5555559b5020
   0x00005555555a0c90 <AREF+13>:	lea    0x414ad9(%rip),%rdi        # 0x5555559b5770

2027	AREF (Lisp_Object array, ptrdiff_t idx)
   0x00005555555a0c97 <AREF+20>:	mov    %rsp,%rbp

2028	{
2029	  eassert (0 <= idx && idx < gc_asize (array));
   0x00005555555a0c9a <AREF+23>:	call   0x5555555b8f19 <die>
   0x00005555555a0c9f <AREF.cold+0>:	call   0x5555555a0c83 <AREF>

2030	  return XVECTOR (array)->contents[idx];
2031	}
   0x00005555555a0ca4 <AREF-369244>:	call   0x5555555a0c67 <XVECTOR>

1513	XCONS (Lisp_Object a)
   0x00005555555a0ca9 <XCONS+0>:	push   %rbp

1514	{
1515	  eassert (CONSP (a));
   0x00005555555a0caa <XCONS+1>:	mov    $0x5eb,%edx
   0x00005555555a0caf <XCONS+6>:	lea    0x41436a(%rip),%rsi        # 0x5555559b5020
   0x00005555555a0cb6 <XCONS+13>:	lea    0x4143c5(%rip),%rdi        # 0x5555559b5082

1513	XCONS (Lisp_Object a)
   0x00005555555a0cbd <XCONS+20>:	mov    %rsp,%rbp

1514	{
1515	  eassert (CONSP (a));
   0x00005555555a0cc0 <XCONS+23>:	call   0x5555555b8f19 <die>

1516	  struct Lisp_Cons *c = XUNTAG (a, Lisp_Cons, struct Lisp_Cons);
1517	  igc_check_fwd (c, false);
1518	  return c;
1519	}
1520
1521	/* Take the car or cdr of something known to be a cons cell.  */
1522	/* The _addr functions shouldn't be used outside of the minimal set
1523	   of code that has to know what a cons cell looks like.  Other code not
1524	   part of the basic lisp implementation should assume that the car and cdr
1525	   fields are not accessible.  (What if we want to switch to
1526	   a copying collector someday?  Cached cons cell field addresses may be
1527	   invalidated at arbitrary points.)  */
1528	INLINE Lisp_Object *
1529	xcar_addr (Lisp_Object c)
1530	{
1531	  return &XCONS (c)->u.s.car;
1532	}
1533	INLINE Lisp_Object *
1534	xcdr_addr (Lisp_Object c)
1535	{
1536	  return &XCONS (c)->u.s.u.cdr;
1537	}
1538
1539	/* Use these from normal code.  */
1540
1541	INLINE Lisp_Object
1542	(XCAR) (Lisp_Object c)
1543	{
   0x00005555555a0cc5 <XCAR.cold+0>:	push   %rbp
   0x00005555555a0cc6 <XCAR-369306>:	mov    %rsp,%rbp
   0x00005555555a0cc9 <XCAR-369303>:	call   0x5555555a0ca9 <XCONS>

1544	  return lisp_h_XCAR (c);
1545	}
1546
1547	INLINE Lisp_Object
1548	(XCDR) (Lisp_Object c)
1549	{
   0x00005555555a0cce <XCDR.cold+0>:	push   %rbp
   0x00005555555a0ccf <XCDR-369329>:	mov    %rsp,%rbp
   0x00005555555a0cd2 <XCDR-369326>:	call   0x5555555a0ca9 <XCONS>

1550	  return lisp_h_XCDR (c);
1551	}
1552
1553	/* Use these to set the fields of a cons cell.
1554
1555	   Note that both arguments may refer to the same object, so 'n'
1556	   should not be read after 'c' is first modified.  */
1557	INLINE void
1558	XSETCAR (Lisp_Object c, Lisp_Object n)
1559	{
1560	  *xcar_addr (c) = n;
1561	}
1562	INLINE void
1563	XSETCDR (Lisp_Object c, Lisp_Object n)
1564	{
1565	  *xcdr_addr (c) = n;
1566	}
1567
1568	/* Take the car or cdr of something whose type is not known.  */
1569	INLINE Lisp_Object
1570	CAR (Lisp_Object c)
1571	{
1572	  if (CONSP (c))
1573	    return XCAR (c);
1574	  if (!NILP (c))
1575	    wrong_type_argument (Qlistp, c);
1576	  return Qnil;
1577	}
1578	INLINE Lisp_Object
1579	CDR (Lisp_Object c)
1580	{
1581	  if (CONSP (c))
1582	    return XCDR (c);
1583	  if (!NILP (c))
1584	    wrong_type_argument (Qlistp, c);
1585	  return Qnil;
1586	}
1587
1588	/* Take the car or cdr of something whose type is not known.  */
1589	INLINE Lisp_Object
1590	CAR_SAFE (Lisp_Object c)
1591	{
1592	  return CONSP (c) ? XCAR (c) : Qnil;
1593	}
1594	INLINE Lisp_Object
1595	CDR_SAFE (Lisp_Object c)
1596	{
1597	  return CONSP (c) ? XCDR (c) : Qnil;
1598	}
1599
1600	#ifdef HAVE_MPS
1601	/* When using MPS, Lisp_String data is actually a pointer to the
1602	   flexible "data" array in this struct. */
1603	struct Lisp_String_Data
1604	{
1605	  GC_HEADER
1606	  unsigned char data[FLEXIBLE_ARRAY_MEMBER];
1607	};
1608	#endif
1609
1610	/* In a string or vector, the sign bit of u.s.size is the gc mark bit.  */
1611
1612	struct Lisp_String
1613	{
1614	  GC_HEADER
1615	  union
1616	  {
1617	    struct
1618	    {
1619	      /* Number of characters in string; MSB is used as the mark bit.  */
1620	      ptrdiff_t size;
1621	      /* If nonnegative, number of bytes in the string (which is multibyte).
1622		 If negative, the string is unibyte:
1623		 -1 for data normally allocated
1624		 -2 for data in rodata (C string constants)
1625		 -3 for data that must be immovable (used for bytecode)  */
1626	      ptrdiff_t size_byte;
1627
1628	      INTERVAL intervals;	/* Text properties in this string.  */
1629	      unsigned char *data;
1630	    } s;
1631	    struct Lisp_String *next;
1632	    GCALIGNED_UNION_MEMBER
1633	  } u;
1634	};
1635	static_assert (GCALIGNED (struct Lisp_String));
1636
1637	INLINE bool
1638	STRINGP (Lisp_Object x)
1639	{
1640	  return TAGGEDP (x, Lisp_String);
1641	}
1642
1643	INLINE void
1644	CHECK_STRING (Lisp_Object x)
1645	{
1646	  CHECK_TYPE (STRINGP (x), Qstringp, x);
1647	}
1648
1649	INLINE struct Lisp_String *
1650	XSTRING (Lisp_Object a)
   0x00005555555a0cd7 <XSTRING+0>:	push   %rbp

1651	{
1652	  eassert (STRINGP (a));
   0x00005555555a0cd8 <XSTRING+1>:	mov    $0x674,%edx
End of assembler dump.



HTH, and thanks for your attention, Gregor




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76427; Package emacs. (Wed, 26 Feb 2025 17:32:02 GMT) Full text and rfc822 format available.

Message #29 received at 76427 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> protonmail.com>
To: Gregor Zattler <telegraph <at> gmx.net>
Cc: 76427 <at> debbugs.gnu.org
Subject: Re: bug#76427: 31.0.50;
 feature/igc: terminate_due_to_signal (sig=sig <at> entry=6,
 backtrace_limit=backtrace_limit <at> entry=2147483647) at ./src/emacs.c:425
Date: Wed, 26 Feb 2025 17:30:59 +0000
"Gregor Zattler" <telegraph <at> gmx.net> writes:

> Hi Pip,

Hello!

>> indicating that read_char restored a jump buffer from stack space that
>> was no longer reserved.

The code looks fine (sorry it took a while to read): while it's very
unusual that Emacs copies jmp_buf structures (rather than pointers to
them), that doesn't appear to be the problem here.  (I don't think it's
safe either, because longjmping to a half-copied jmpbuf is likely to
cause trouble, but I have no evidence that has happened here).

I have not been able to verify that this comment in keyboard.c is
accurate:

      c = c_volatile;
      /* Handle quits while reading the keyboard.  */
      /* We must have saved the outer value of getcjmp here,
	 so restore it now.  */
      restore_getcjmp (save_jump);

One potential problem is that there are two jmpbufs called save_jump,
one in read_char and one in read_event_from_main_queue, and we may be
restoring from the one in read_char after saving to the one in
read_event_from_main_queue.  But again, no evidence that this is what is
in fact happening, and I don't know which recent compiler change may
have resulted in so many potentially read_char-setjmp related crashes
lately.

I suspect that if we clean up keyboard.c to store, on the heap, a
pointer to an on-stack jmpbuf, rather than storing an entire jmpbuf on
the heap and memcpy-ing to and fro, we would likely either catch the bug
(there's some evidence it may be a use-after-free, longjmping to a
jmpbuf whose stack pointer is no longer valid because the function has
exited) or work around any underlying GCC bug (somewhat worryingly, I
ran into an internal compiler error when playing with this code, but
it's not reproducible and may not be related, or maybe it's specific to
the gentoo gcc).

In any case, while I don't really know a good way to do it, could we
find a way to include the .comment ELF section of the Emacs executable
in M-x report-emacs-bug?  We desperately need that information to be
able to reproduce compiler-specific bugs.

(Maybe it's good enough to capture the gcc version at configure time,
though of course it's possible for gcc to be updated between configure
time and build time).

> HTH, and thanks for your attention, Gregor

Thanks, it does help and disprove that theory!

Pip





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76427; Package emacs. (Wed, 26 Feb 2025 22:16:02 GMT) Full text and rfc822 format available.

Message #32 received at 76427 <at> debbugs.gnu.org (full text, mbox):

From: Gregor Zattler <telegraph <at> gmx.net>
To: Pip Cet <pipcet <at> protonmail.com>
Cc: 76427 <at> debbugs.gnu.org
Subject: Re: bug#76427: 31.0.50; feature/igc: terminate_due_to_signal
 (sig=sig <at> entry=6, backtrace_limit=backtrace_limit <at> entry=2147483647) at
 ./src/emacs.c:425
Date: Wed, 26 Feb 2025 23:14:55 +0100
Hi Pip, Emacs developers,
* Pip Cet <pipcet <at> protonmail.com> [2025-02-26; 17:30 GMT]:
> (Maybe it's good enough to capture the gcc version at configure time,
> though of course it's possible for gcc to be updated between configure
> time and build time).

this laptop is on debian bookworm, it
happens to have .deb files in
/var/cache/apt/archives since 2025-02-12
and none of them is GCC related.  I
therefore assume that the version while
building the Emacs binary in question on
2025-02-16 is the same as now:

$ gcc --version
gcc (Debian 12.2.0-14) 12.2.0


Ciao; Gregor
--
 -... --- .-. . -.. ..--.. ...-.-




This bug report was last modified 108 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.