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
bug-gnu-emacs <at> gnu.org
:bug#76427
; Package emacs
.
(Wed, 19 Feb 2025 23:20:02 GMT) Full text and rfc822 format available.Gregor Zattler <telegraph <at> gmx.net>
: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
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.
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 -- -... --- .-. . -.. ..--.. ...-.-
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
bug-gnu-emacs <at> gnu.org
:bug#76427
; Package emacs
.
(Thu, 20 Feb 2025 11:50:03 GMT) Full text and rfc822 format available.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
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
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 (©); 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 (©); 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 (©); 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 (©); 0x000055555577a614 <+7620>: call 0x555555753b30 <x_handle_selection_event> 4191 #else 4192 pgtk_handle_selection_event (©); 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 (©); 4579 #else 4580 pgtk_handle_selection_event (©); 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 (©); 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
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
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 -- -... --- .-. . -.. ..--.. ...-.-
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.