aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2015-02-05 14:28:16 -0500
committerStefan Monnier2015-02-05 14:28:16 -0500
commitad5a7c86d017ce8e9ff1312331ef09181be823bf (patch)
treef8382a7c42f6844bacf48f03d9480ba8134ba6cc
parent10927c1a0f39d527d9ea1fc4605a0ef400bdff4a (diff)
downloademacs-ad5a7c86d017ce8e9ff1312331ef09181be823bf.tar.gz
emacs-ad5a7c86d017ce8e9ff1312331ef09181be823bf.zip
Add (:documentation <form>) for dynamically-generated docstrings
* lisp/emacs-lisp/bytecomp.el: (byte-compile-initial-macro-environment): Use macroexp-progn. (byte-compile-cl-warn): Don't silence use of cl-macroexpand-all. (byte-compile-file-form-defvar-function): Rename from byte-compile-file-form-define-abbrev-table. (defvaralias, byte-compile-file-form-custom-declare-variable): Use it. (byte-compile): Use byte-compile-top-level rather than byte-compile-lambda so we can compile non-values. (byte-compile-form): Add warnings for failed uses of lexical vars via quoted symbols. (byte-compile-unfold-bcf): Improve message for failed inlining. (byte-compile-make-closure): Handle new format of internal-make-closure for dynamically-generated docstrings. * lisp/emacs-lisp/cconv.el (cconv--convert-function): Add `docstring' argument. (cconv-convert): Use it to handle the new (:documentation ...) form. (cconv-analyze-form): Handle the new (:documentation ...) form. * src/eval.c (Ffunction): Handle the new (:documentation ...) form. (syms_of_eval): Declare `:documentation'.
-rw-r--r--etc/NEWS4
-rw-r--r--lisp/ChangeLog19
-rw-r--r--lisp/emacs-lisp/bytecomp.el59
-rw-r--r--lisp/emacs-lisp/cconv.el31
-rw-r--r--src/ChangeLog5
-rw-r--r--src/eval.c22
6 files changed, 107 insertions, 33 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 72e23562868..d72d01f233e 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -599,6 +599,10 @@ in languages like German where downcasing rules depend on grammar.
599 599
600* Lisp Changes in Emacs 25.1 600* Lisp Changes in Emacs 25.1
601 601
602** lexical closures can use (:documentation <form>) to build their docstring.
603It should be placed right where the docstring would be, and <form> is then
604evaluated (and should return a string) when the closure is built.
605
602** define-inline provides a new way to define inlinable functions. 606** define-inline provides a new way to define inlinable functions.
603 607
604** New function macroexpand-1 to perform a single step of macroexpansion. 608** New function macroexpand-1 to perform a single step of macroexpansion.
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 694a35be61d..51e944c9729 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,24 @@
12015-02-05 Stefan Monnier <monnier@iro.umontreal.ca> 12015-02-05 Stefan Monnier <monnier@iro.umontreal.ca>
2 2
3 * emacs-lisp/cconv.el (cconv--convert-function):
4 Add `docstring' argument.
5 (cconv-convert): Use it to handle the new (:documentation ...) form.
6 (cconv-analyze-form): Handle the new (:documentation ...) form.
7
8 * emacs-lisp/bytecomp.el:
9 (byte-compile-initial-macro-environment): Use macroexp-progn.
10 (byte-compile-cl-warn): Don't silence use of cl-macroexpand-all.
11 (byte-compile-file-form-defvar-function): Rename from
12 byte-compile-file-form-define-abbrev-table.
13 (defvaralias, byte-compile-file-form-custom-declare-variable): Use it.
14 (byte-compile): Use byte-compile-top-level rather than
15 byte-compile-lambda so we can compile non-values.
16 (byte-compile-form): Add warnings for failed uses of lexical vars via
17 quoted symbols.
18 (byte-compile-unfold-bcf): Improve message for failed inlining.
19 (byte-compile-make-closure): Handle new format of internal-make-closure
20 for dynamically-generated docstrings.
21
3 * delsel.el: Deprecate the `kill' option. Use lexical-binding. 22 * delsel.el: Deprecate the `kill' option. Use lexical-binding.
4 (open-line): Delete like all other commands, instead of killing. 23 (open-line): Delete like all other commands, instead of killing.
5 (delete-active-region): Don't define any return any value. 24 (delete-active-region): Don't define any return any value.
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 2bd8d07851b..548aaa9626b 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -31,6 +31,10 @@
31;; faster. [`LAP' == `Lisp Assembly Program'.] 31;; faster. [`LAP' == `Lisp Assembly Program'.]
32;; The user entry points are byte-compile-file and byte-recompile-directory. 32;; The user entry points are byte-compile-file and byte-recompile-directory.
33 33
34;;; Todo:
35
36;; - Turn "not bound at runtime" functions into autoloads.
37
34;;; Code: 38;;; Code:
35 39
36;; ======================================================================== 40;; ========================================================================
@@ -450,7 +454,7 @@ Return the compile-time value of FORM."
450 (eval-when-compile . ,(lambda (&rest body) 454 (eval-when-compile . ,(lambda (&rest body)
451 (let ((result nil)) 455 (let ((result nil))
452 (byte-compile-recurse-toplevel 456 (byte-compile-recurse-toplevel
453 (cons 'progn body) 457 (macroexp-progn body)
454 (lambda (form) 458 (lambda (form)
455 (setf result 459 (setf result
456 (byte-compile-eval 460 (byte-compile-eval
@@ -459,7 +463,7 @@ Return the compile-time value of FORM."
459 (list 'quote result)))) 463 (list 'quote result))))
460 (eval-and-compile . ,(lambda (&rest body) 464 (eval-and-compile . ,(lambda (&rest body)
461 (byte-compile-recurse-toplevel 465 (byte-compile-recurse-toplevel
462 (cons 'progn body) 466 (macroexp-progn body)
463 (lambda (form) 467 (lambda (form)
464 ;; Don't compile here, since we don't know 468 ;; Don't compile here, since we don't know
465 ;; whether to compile as byte-compile-form 469 ;; whether to compile as byte-compile-form
@@ -1458,7 +1462,7 @@ extra args."
1458 ;; These would sometimes be warned about 1462 ;; These would sometimes be warned about
1459 ;; but such warnings are never useful, 1463 ;; but such warnings are never useful,
1460 ;; so don't warn about them. 1464 ;; so don't warn about them.
1461 macroexpand cl-macroexpand-all 1465 macroexpand
1462 cl--compiling-file)))) 1466 cl--compiling-file))))
1463 (byte-compile-warn "function `%s' from cl package called at runtime" 1467 (byte-compile-warn "function `%s' from cl package called at runtime"
1464 func))) 1468 func)))
@@ -2319,10 +2323,12 @@ list that represents a doc string reference.
2319 form)) 2323 form))
2320 2324
2321(put 'define-abbrev-table 'byte-hunk-handler 2325(put 'define-abbrev-table 'byte-hunk-handler
2322 'byte-compile-file-form-define-abbrev-table) 2326 'byte-compile-file-form-defvar-function)
2323(defun byte-compile-file-form-define-abbrev-table (form) 2327(put 'defvaralias 'byte-hunk-handler 'byte-compile-file-form-defvar-function)
2324 (if (eq 'quote (car-safe (car-safe (cdr form)))) 2328
2325 (byte-compile--declare-var (car-safe (cdr (cadr form))))) 2329(defun byte-compile-file-form-defvar-function (form)
2330 (pcase-let (((or `',name (let name nil)) (nth 1 form)))
2331 (if name (byte-compile--declare-var name)))
2326 (byte-compile-keep-pending form)) 2332 (byte-compile-keep-pending form))
2327 2333
2328(put 'custom-declare-variable 'byte-hunk-handler 2334(put 'custom-declare-variable 'byte-hunk-handler
@@ -2330,8 +2336,7 @@ list that represents a doc string reference.
2330(defun byte-compile-file-form-custom-declare-variable (form) 2336(defun byte-compile-file-form-custom-declare-variable (form)
2331 (when (byte-compile-warning-enabled-p 'callargs) 2337 (when (byte-compile-warning-enabled-p 'callargs)
2332 (byte-compile-nogroup-warn form)) 2338 (byte-compile-nogroup-warn form))
2333 (byte-compile--declare-var (nth 1 (nth 1 form))) 2339 (byte-compile-file-form-defvar-function form))
2334 (byte-compile-keep-pending form))
2335 2340
2336(put 'require 'byte-hunk-handler 'byte-compile-file-form-require) 2341(put 'require 'byte-hunk-handler 'byte-compile-file-form-require)
2337(defun byte-compile-file-form-require (form) 2342(defun byte-compile-file-form-require (form)
@@ -2580,17 +2585,11 @@ If FORM is a lambda or a macro, byte-compile it as a function."
2580 fun) 2585 fun)
2581 (t 2586 (t
2582 (when (symbolp form) 2587 (when (symbolp form)
2583 (unless (memq (car-safe fun) '(closure lambda))
2584 (error "Don't know how to compile %S" fun))
2585 (setq lexical-binding (eq (car fun) 'closure)) 2588 (setq lexical-binding (eq (car fun) 'closure))
2586 (setq fun (byte-compile--reify-function fun))) 2589 (setq fun (byte-compile--reify-function fun)))
2587 (unless (eq (car-safe fun) 'lambda)
2588 (error "Don't know how to compile %S" fun))
2589 ;; Expand macros. 2590 ;; Expand macros.
2590 (setq fun (byte-compile-preprocess fun)) 2591 (setq fun (byte-compile-preprocess fun))
2591 ;; Get rid of the `function' quote added by the `lambda' macro. 2592 (setq fun (byte-compile-top-level fun nil 'eval))
2592 (if (eq (car-safe fun) 'function) (setq fun (cadr fun)))
2593 (setq fun (byte-compile-lambda fun))
2594 (if macro (push 'macro fun)) 2593 (if macro (push 'macro fun))
2595 (if (symbolp form) 2594 (if (symbolp form)
2596 (fset form fun) 2595 (fset form fun)
@@ -2966,6 +2965,16 @@ for symbols generated by the byte compiler itself."
2966 (interactive-only 2965 (interactive-only
2967 (or (get fn 'interactive-only) 2966 (or (get fn 'interactive-only)
2968 (memq fn byte-compile-interactive-only-functions)))) 2967 (memq fn byte-compile-interactive-only-functions))))
2968 (when (memq fn '(set symbol-value run-hooks ;; add-to-list
2969 add-hook remove-hook run-hook-with-args
2970 run-hook-with-args-until-success
2971 run-hook-with-args-until-failure))
2972 (pcase (cdr form)
2973 (`(',var . ,_)
2974 (when (assq var byte-compile-lexical-variables)
2975 (byte-compile-log-warning
2976 (format "%s cannot use lexical var `%s'" fn var)
2977 nil :error)))))
2969 (when (macroexp--const-symbol-p fn) 2978 (when (macroexp--const-symbol-p fn)
2970 (byte-compile-warn "`%s' called as a function" fn)) 2979 (byte-compile-warn "`%s' called as a function" fn))
2971 (when (and (byte-compile-warning-enabled-p 'interactive-only) 2980 (when (and (byte-compile-warning-enabled-p 'interactive-only)
@@ -3079,8 +3088,9 @@ for symbols generated by the byte compiler itself."
3079 (dotimes (_ (- (/ (1+ fmax2) 2) alen)) 3088 (dotimes (_ (- (/ (1+ fmax2) 2) alen))
3080 (byte-compile-push-constant nil))) 3089 (byte-compile-push-constant nil)))
3081 ((zerop (logand fmax2 1)) 3090 ((zerop (logand fmax2 1))
3082 (byte-compile-log-warning "Too many arguments for inlined function" 3091 (byte-compile-log-warning
3083 nil :error) 3092 (format "Too many arguments for inlined function %S" form)
3093 nil :error)
3084 (byte-compile-discard (- alen (/ fmax2 2)))) 3094 (byte-compile-discard (- alen (/ fmax2 2))))
3085 (t 3095 (t
3086 ;; Turn &rest args into a list. 3096 ;; Turn &rest args into a list.
@@ -3453,15 +3463,22 @@ discarding."
3453 (if byte-compile--for-effect (setq byte-compile--for-effect nil) 3463 (if byte-compile--for-effect (setq byte-compile--for-effect nil)
3454 (let* ((vars (nth 1 form)) 3464 (let* ((vars (nth 1 form))
3455 (env (nth 2 form)) 3465 (env (nth 2 form))
3456 (body (nthcdr 3 form)) 3466 (docstring-exp (nth 3 form))
3467 (body (nthcdr 4 form))
3457 (fun 3468 (fun
3458 (byte-compile-lambda `(lambda ,vars . ,body) nil (length env)))) 3469 (byte-compile-lambda `(lambda ,vars . ,body) nil (length env))))
3459 (cl-assert (> (length env) 0)) ;Otherwise, we don't need a closure. 3470 (cl-assert (or (> (length env) 0)
3471 docstring-exp)) ;Otherwise, we don't need a closure.
3460 (cl-assert (byte-code-function-p fun)) 3472 (cl-assert (byte-code-function-p fun))
3461 (byte-compile-form `(make-byte-code 3473 (byte-compile-form `(make-byte-code
3462 ',(aref fun 0) ',(aref fun 1) 3474 ',(aref fun 0) ',(aref fun 1)
3463 (vconcat (vector . ,env) ',(aref fun 2)) 3475 (vconcat (vector . ,env) ',(aref fun 2))
3464 ,@(nthcdr 3 (mapcar (lambda (x) `',x) fun))))))) 3476 ,@(let ((rest (nthcdr 3 (mapcar (lambda (x) `',x) fun))))
3477 (if docstring-exp
3478 `(,(car rest)
3479 ,docstring-exp
3480 ,@(cddr rest))
3481 rest)))))))
3465 3482
3466(defun byte-compile-get-closed-var (form) 3483(defun byte-compile-get-closed-var (form)
3467 "Byte-compile the special `internal-get-closed-var' form." 3484 "Byte-compile the special `internal-get-closed-var' form."
diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el
index e9d33e6c646..fa824075933 100644
--- a/lisp/emacs-lisp/cconv.el
+++ b/lisp/emacs-lisp/cconv.el
@@ -48,7 +48,7 @@
48;; if the function is suitable for lambda lifting (if all calls are known) 48;; if the function is suitable for lambda lifting (if all calls are known)
49;; 49;;
50;; (lambda (v0 ...) ... fv0 .. fv1 ...) => 50;; (lambda (v0 ...) ... fv0 .. fv1 ...) =>
51;; (internal-make-closure (v0 ...) (fv1 ...) 51;; (internal-make-closure (v0 ...) (fv0 ...) <doc>
52;; ... (internal-get-closed-var 0) ... (internal-get-closed-var 1) ...) 52;; ... (internal-get-closed-var 0) ... (internal-get-closed-var 1) ...)
53;; 53;;
54;; If the function has no free variables, we don't do anything. 54;; If the function has no free variables, we don't do anything.
@@ -65,6 +65,14 @@
65;; 65;;
66;;; Code: 66;;; Code:
67 67
68;; PROBLEM cases found during conversion to lexical binding.
69;; We should try and detect and warn about those cases, even
70;; for lexical-binding==nil to help prepare the migration.
71;; - Uses of run-hooks, and friends.
72;; - Cases where we want to apply the same code to different vars depending on
73;; some test. These sometimes use a (let ((foo (if bar 'a 'b)))
74;; ... (symbol-value foo) ... (set foo ...)).
75
68;; TODO: (not just for cconv but also for the lexbind changes in general) 76;; TODO: (not just for cconv but also for the lexbind changes in general)
69;; - let (e)debug find the value of lexical variables from the stack. 77;; - let (e)debug find the value of lexical variables from the stack.
70;; - make eval-region do the eval-sexp-add-defvars dance. 78;; - make eval-region do the eval-sexp-add-defvars dance.
@@ -87,9 +95,8 @@
87;; the bytecomp only compiles it once. 95;; the bytecomp only compiles it once.
88;; - Since we know here when a variable is not mutated, we could pass that 96;; - Since we know here when a variable is not mutated, we could pass that
89;; info to the byte-compiler, e.g. by using a new `immutable-let'. 97;; info to the byte-compiler, e.g. by using a new `immutable-let'.
90;; - add tail-calls to bytecode.c and the byte compiler.
91;; - call known non-escaping functions with `goto' rather than `call'. 98;; - call known non-escaping functions with `goto' rather than `call'.
92;; - optimize mapcar to a while loop. 99;; - optimize mapc to a dolist loop.
93 100
94;; (defmacro dlet (binders &rest body) 101;; (defmacro dlet (binders &rest body)
95;; ;; Works in both lexical and non-lexical mode. 102;; ;; Works in both lexical and non-lexical mode.
@@ -195,7 +202,7 @@ Returns a form where all lambdas don't have any free variables."
195 (unless (memq (car b) s) (push b res))) 202 (unless (memq (car b) s) (push b res)))
196 (nreverse res))) 203 (nreverse res)))
197 204
198(defun cconv--convert-function (args body env parentform) 205(defun cconv--convert-function (args body env parentform &optional docstring)
199 (cl-assert (equal body (caar cconv-freevars-alist))) 206 (cl-assert (equal body (caar cconv-freevars-alist)))
200 (let* ((fvs (cdr (pop cconv-freevars-alist))) 207 (let* ((fvs (cdr (pop cconv-freevars-alist)))
201 (body-new '()) 208 (body-new '())
@@ -240,11 +247,11 @@ Returns a form where all lambdas don't have any free variables."
240 `(,@(nreverse special-forms) (let ,letbind . ,body-new))))) 247 `(,@(nreverse special-forms) (let ,letbind . ,body-new)))))
241 248
242 (cond 249 (cond
243 ((null envector) ;if no freevars - do nothing 250 ((not (or envector docstring)) ;If no freevars - do nothing.
244 `(function (lambda ,args . ,body-new))) 251 `(function (lambda ,args . ,body-new)))
245 (t 252 (t
246 `(internal-make-closure 253 `(internal-make-closure
247 ,args ,envector . ,body-new))))) 254 ,args ,envector ,docstring . ,body-new)))))
248 255
249(defun cconv-convert (form env extend) 256(defun cconv-convert (form env extend)
250 ;; This function actually rewrites the tree. 257 ;; This function actually rewrites the tree.
@@ -407,7 +414,9 @@ places where they originally did not directly appear."
407 cond-forms))) 414 cond-forms)))
408 415
409 (`(function (lambda ,args . ,body) . ,_) 416 (`(function (lambda ,args . ,body) . ,_)
410 (cconv--convert-function args body env form)) 417 (let ((docstring (if (eq :documentation (car-safe (car body)))
418 (cconv-convert (cadr (pop body)) env extend))))
419 (cconv--convert-function args body env form docstring)))
411 420
412 (`(internal-make-closure . ,_) 421 (`(internal-make-closure . ,_)
413 (byte-compile-report-error 422 (byte-compile-report-error
@@ -533,7 +542,7 @@ FORM is the parent form that binds this var."
533 ;; use = `(,binder ,read ,mutated ,captured ,called) 542 ;; use = `(,binder ,read ,mutated ,captured ,called)
534 (pcase vardata 543 (pcase vardata
535 (`(,_ nil nil nil nil) nil) 544 (`(,_ nil nil nil nil) nil)
536 (`((,(and (pred (lambda (var) (eq ?_ (aref (symbol-name var) 0)))) var) . ,_) 545 (`((,(and var (guard (eq ?_ (aref (symbol-name var) 0)))) . ,_)
537 ,_ ,_ ,_ ,_) 546 ,_ ,_ ,_ ,_)
538 (byte-compile-log-warning 547 (byte-compile-log-warning
539 (format "%s `%S' not left unused" varkind var)))) 548 (format "%s `%S' not left unused" varkind var))))
@@ -643,6 +652,8 @@ and updates the data stored in ENV."
643 (cconv--analyze-use vardata form "variable")))) 652 (cconv--analyze-use vardata form "variable"))))
644 653
645 (`(function (lambda ,vrs . ,body-forms)) 654 (`(function (lambda ,vrs . ,body-forms))
655 (when (eq :documentation (car-safe (car body-forms)))
656 (cconv-analyze-form (cadr (pop body-forms)) env))
646 (cconv--analyze-function vrs body-forms env form)) 657 (cconv--analyze-function vrs body-forms env form))
647 658
648 (`(setq . ,forms) 659 (`(setq . ,forms)
@@ -665,6 +676,10 @@ and updates the data stored in ENV."
665 (dolist (forms cond-forms) 676 (dolist (forms cond-forms)
666 (dolist (form forms) (cconv-analyze-form form env)))) 677 (dolist (form forms) (cconv-analyze-form form env))))
667 678
679 ;; ((and `(quote ,v . ,_) (guard (assq v env)))
680 ;; (byte-compile-log-warning
681 ;; (format "Possible confusion variable/symbol for `%S'" v)))
682
668 (`(quote . ,_) nil) ; quote form 683 (`(quote . ,_) nil) ; quote form
669 (`(function . ,_) nil) ; same as quote 684 (`(function . ,_) nil) ; same as quote
670 685
diff --git a/src/ChangeLog b/src/ChangeLog
index 2c9b6c8375b..15d8d27a921 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
12015-02-05 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * eval.c (Ffunction): Handle the new (:documentation ...) form.
4 (syms_of_eval): Declare `:documentation'.
5
12015-02-05 Martin Rudalics <rudalics@gmx.at> 62015-02-05 Martin Rudalics <rudalics@gmx.at>
2 7
3 * xdisp.c (Fwindow_text_pixel_size): Remove optional BUFFER 8 * xdisp.c (Fwindow_text_pixel_size): Remove optional BUFFER
diff --git a/src/eval.c b/src/eval.c
index b98b224e622..e828da9288f 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -575,10 +575,23 @@ usage: (function ARG) */)
575 if (!NILP (Vinternal_interpreter_environment) 575 if (!NILP (Vinternal_interpreter_environment)
576 && CONSP (quoted) 576 && CONSP (quoted)
577 && EQ (XCAR (quoted), Qlambda)) 577 && EQ (XCAR (quoted), Qlambda))
578 /* This is a lambda expression within a lexical environment; 578 { /* This is a lambda expression within a lexical environment;
579 return an interpreted closure instead of a simple lambda. */ 579 return an interpreted closure instead of a simple lambda. */
580 return Fcons (Qclosure, Fcons (Vinternal_interpreter_environment, 580 Lisp_Object cdr = XCDR (quoted);
581 XCDR (quoted))); 581 Lisp_Object tmp = cdr;
582 if (CONSP (tmp)
583 && (tmp = XCDR (tmp), CONSP (tmp))
584 && (tmp = XCAR (tmp), CONSP (tmp))
585 && (EQ (QCdocumentation, XCAR (tmp))))
586 { /* Handle the special (:documentation <form>) to build the docstring
587 dynamically. */
588 Lisp_Object docstring = eval_sub (Fcar (XCDR (tmp)));
589 CHECK_STRING (docstring);
590 cdr = Fcons (XCAR (cdr), Fcons (docstring, XCDR (XCDR (cdr))));
591 }
592 return Fcons (Qclosure, Fcons (Vinternal_interpreter_environment,
593 cdr));
594 }
582 else 595 else
583 /* Simply quote the argument. */ 596 /* Simply quote the argument. */
584 return quoted; 597 return quoted;
@@ -3668,6 +3681,7 @@ before making `inhibit-quit' nil. */);
3668 DEFSYM (Qand_rest, "&rest"); 3681 DEFSYM (Qand_rest, "&rest");
3669 DEFSYM (Qand_optional, "&optional"); 3682 DEFSYM (Qand_optional, "&optional");
3670 DEFSYM (Qclosure, "closure"); 3683 DEFSYM (Qclosure, "closure");
3684 DEFSYM (QCdocumentation, ":documentation");
3671 DEFSYM (Qdebug, "debug"); 3685 DEFSYM (Qdebug, "debug");
3672 3686
3673 DEFVAR_LISP ("inhibit-debugger", Vinhibit_debugger, 3687 DEFVAR_LISP ("inhibit-debugger", Vinhibit_debugger,