[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: byte compiling defcustom
From: |
Stefan Monnier |
Subject: |
Re: byte compiling defcustom |
Date: |
Fri, 16 Nov 2007 10:25:13 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/23.0.50 (gnu/linux) |
> (defvar foo (if (featurep 'xemacs) 'bar 'baz) "doc")
> (defcustom foo1 (if (featurep 'xemacs) 'bar 'baz) "doc")
> Are compiled to:
> (defvar foo 'baz (#$ . 543))
> (custom-declare-variable 'foo1 '(if (featurep 'xemacs) 'bar 'baz) '(#$ .
> 581))
> The initial value expression for defcustom is saved and gets
> recalculated later in some cases. So it cannot in general be
> optimized.
He probably meant "compiled" as much as "optimized".
The same holds of keyword arguments to custom-declare-variable, by the way.
> This particular simplification could be done even in defcustom, since
> (featurep 'xemacs) is effectively a constant. But why bother
> to implement that optimization? It works fine as it is now.
The patch below implements the desired feature: it byte-compiles the
default-value-expression (first part of the hunk) as well as any
keyword arguments (second part of the hunk). Notice that the second
part actually simplifies the code.
To me the main benefit is not so much efficiency as better warnings.
Stefan
PS: While fiddling with it, I discovered that (defvar foo 1 "haha") is
byte compiled into itself (more or less), whereas (defvar foo 1)
gets "open coded" as
(byte-code "..." [current-load-list foo default-boundp set-default 1] 3)
so it won't call Fdefvar and will hence circumvent the check added to
defvar to detect when defvar is used within a `let' binding:
{ /* Check if there is really a global binding rather than just a let
binding that shadows the global unboundness of the var. */
struct specbinding *pdl = specpdl_ptr;
while (--pdl >= specpdl)
{
if (EQ (pdl->symbol, sym) && !pdl->func
&& EQ (pdl->old_value, Qunbound))
{
message_with_string ("Warning: defvar ignored because %s is
let-bound",
SYMBOL_NAME (sym), 1);
break;
}
}
}
Maybe those defvars shouldn't be open-coded?
--- orig/lisp/emacs-lisp/bytecomp.el
+++ mod/lisp/emacs-lisp/bytecomp.el
@@ -2309,18 +2309,16 @@
;; (byte-compile-nogroup-warn form))
(when (byte-compile-warning-enabled-p 'free-vars)
(push (nth 1 (nth 1 form)) byte-compile-special-variables))
+ (when (eq (car-safe (nth 2 form)) 'quote)
+ ;; (nth 2 form) is meant to evaluate to an expression, so if we have the
+ ;; final value already, we can byte-compile it.
+ (setcar (cdr (nth 2 form))
+ (byte-compile-top-level (cadr (nth 2 form)) nil 'file)))
(let ((tail (nthcdr 4 form)))
(while tail
- ;; If there are any (function (lambda ...)) expressions, compile
- ;; those functions.
- (if (and (consp (car tail))
- (eq (car (car tail)) 'function)
- (consp (nth 1 (car tail))))
- (setcar tail (byte-compile-lambda (nth 1 (car tail))))
- ;; Likewise for a bare lambda.
- (if (and (consp (car tail))
- (eq (car (car tail)) 'lambda))
- (setcar tail (byte-compile-lambda (car tail)))))
+ (unless (keywordp (car tail)) ;No point optimizing keywords.
+ ;; Compile the keyword arguments.
+ (setcar tail (byte-compile-top-level (car tail) nil 'file)))
(setq tail (cdr tail))))
form)
- byte compiling defcustom, Dan Nicolaescu, 2007/11/14
- Re: byte compiling defcustom, Richard Stallman, 2007/11/15
- Re: byte compiling defcustom,
Stefan Monnier <=
- Re: byte compiling defcustom, Richard Stallman, 2007/11/16
- Re: byte compiling defcustom, Dan Nicolaescu, 2007/11/17
- Re: byte compiling defcustom, Luc Teirlinck, 2007/11/17
- Re: byte compiling defcustom, Dan Nicolaescu, 2007/11/17
- Re: byte compiling defcustom, Luc Teirlinck, 2007/11/17
- Re: byte compiling defcustom, Luc Teirlinck, 2007/11/17
- Re: byte compiling defcustom, Richard Stallman, 2007/11/18
- disappearing custom menu (was: Re: byte compiling defcustom), Dan Nicolaescu, 2007/11/18