diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 3bec3e61df9..38f5dcc993b 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -1421,6 +1421,8 @@ when (and (listp el) ;; make sure we're at the correct op (eq (nth 1 el) 'byte-constant) (eq (nth 2 el) orig-table)) + ;; jump tables are never resused, so we do this exactly + ;; once. do (setf (nth 2 el) last-constant) and return nil)))) ;; lap = ( [ (pc . (op . arg)) ]* ) (push (cons optr (cons bytedecomp-op (or offset 0))) diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 14678e91ee3..6e8442291f8 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -3135,8 +3135,8 @@ for symbols generated by the byte compiler itself." ;; lexical-binding, but it's not true in general, and it's not true for ;; code output by bytecomp.el with lexical-binding. ;; We also restore the value of `byte-compile-depth' and remove TAG depths - ;; accordingly when inlining byte-switch lap code, as documented in - ;; `byte-compile-cond-jump-table'. + ;; accordingly when inlining lapcode containing lap-code, exactly as + ;; documented in `byte-compile-cond-jump-table'. (let ((endtag (byte-compile-make-tag)) last-jump-tag ;; last TAG we have jumped to last-depth ;; last value of `byte-compile-depth' @@ -3150,8 +3150,12 @@ for symbols generated by the byte compiler itself." (cond ((eq (car op) 'TAG) (when (or (member op switch-tags) (member op switch-default-tags)) + ;; This TAG is used in a jump table, this means the last goto + ;; was to a done/default TAG, and thus it's cddr should be set to nil. (when last-jump-tag (setcdr (cdr last-jump-tag) nil)) + ;; Also, restore the value of `byte-compile-depth' to what it was + ;; before the last goto. (setq byte-compile-depth last-depth last-jump-tag nil)) (byte-compile-out-tag op)) @@ -3160,6 +3164,8 @@ for symbols generated by the byte compiler itself." last-jump-tag (cdr op)) (byte-compile-goto (car op) (cdr op)) (when last-switch + ;; The last op was byte-switch, this goto jumps to a "default" TAG + ;; (when no value in the jump table is satisfied). (push (cdr op) switch-default-tags) (setcdr (cdr (cdr op)) nil) (setq byte-compile-depth last-depth @@ -3169,8 +3175,10 @@ for symbols generated by the byte compiler itself." (byte-compile-goto 'byte-goto endtag)) (t (when (eq (car op) 'byte-switch) + ;; The last constant is a jump table. (push last-constant byte-compile-jump-tables) (setq last-switch t) + ;; Push all TAGs in the jump to switch-tags. (maphash #'(lambda (_k tag) (push tag switch-tags)) last-constant)) @@ -4018,7 +4026,7 @@ that suppresses all warnings during execution of BODY." The condition for each clause is of the form (TEST VAR VALUE). VAR is a variable. TEST and VAR are the same throughout all conditions. -VALUE is either a constant or a quoted form. +VALUE satisfies `macroexp-const-p'. Return a list of the form ((TEST . VAR) ((VALUE BODY) ...))" (let ((cases '())