* bug#11799: 24.1.50; M-x ibuffer: Symbol's function definition is void: cl-minusp
@ 2012-06-27 16:42 Michael Heerdegen
2012-06-28 2:51 ` Stefan Monnier
2012-06-28 3:31 ` Stefan Monnier
0 siblings, 2 replies; 3+ messages in thread
From: Michael Heerdegen @ 2012-06-27 16:42 UTC (permalink / raw)
To: 11799
Hi,
start emacs -Q, and do M-x ibuffer. I get these messages:
Updating buffer list...
Formats have changed, recompiling...
and then this error:
ibuffer-compile-format: Symbol's function definition is void: cl-minusp
There is no such error if I eval (require 'cl-lib) before calling
ibuffer.
Thanks,
Michael.
^ permalink raw reply [flat|nested] 3+ messages in thread
* bug#11799: 24.1.50; M-x ibuffer: Symbol's function definition is void: cl-minusp
2012-06-27 16:42 bug#11799: 24.1.50; M-x ibuffer: Symbol's function definition is void: cl-minusp Michael Heerdegen
@ 2012-06-28 2:51 ` Stefan Monnier
2012-06-28 3:31 ` Stefan Monnier
1 sibling, 0 replies; 3+ messages in thread
From: Stefan Monnier @ 2012-06-28 2:51 UTC (permalink / raw)
To: michael_heerdegen; +Cc: 11799
> ibuffer-compile-format: Symbol's function definition is void: cl-minusp
Hmm... this is annoying: the bytecompiler failed to inline cl-minusp
because it was not yet byte-compiled when we byte-compiled ibuffer.el.
I.e. if you recompile ibuffer.el at the end, it will properly eliminate
cl-minusp.
This is because the byte-optimizer does not know how to inline
a dynamically scoped interpreted function into a lexically scoped
function, or vice-versa. So the inlining can fail.
Once the inlinable function is byte-compiled, the problem disappear,
because we know how to inline it in any context.
Stefan
^ permalink raw reply [flat|nested] 3+ messages in thread
* bug#11799: 24.1.50; M-x ibuffer: Symbol's function definition is void: cl-minusp
2012-06-27 16:42 bug#11799: 24.1.50; M-x ibuffer: Symbol's function definition is void: cl-minusp Michael Heerdegen
2012-06-28 2:51 ` Stefan Monnier
@ 2012-06-28 3:31 ` Stefan Monnier
1 sibling, 0 replies; 3+ messages in thread
From: Stefan Monnier @ 2012-06-28 3:31 UTC (permalink / raw)
To: michael_heerdegen; +Cc: 11799-done
> start emacs -Q, and do M-x ibuffer. I get these messages:
> Updating buffer list...
> Formats have changed, recompiling...
> and then this error:
> ibuffer-compile-format: Symbol's function definition is void: cl-minusp
> There is no such error if I eval (require 'cl-lib) before calling
> ibuffer.
I installed the patch below which should hopefully fix it.
Stefan
=== modified file 'lisp/ChangeLog'
--- lisp/ChangeLog 2012-06-27 21:16:32 +0000
+++ lisp/ChangeLog 2012-06-28 03:29:10 +0000
@@ -1,3 +1,11 @@
+2012-06-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Make inlining of other-mode interpreted functions work.
+ * emacs-lisp/bytecomp.el (byte-compile--refiy-function): New fun.
+ (byte-compile): Use it to fix compilation of lexical-binding closures.
+ * emacs-lisp/byte-opt.el (byte-compile-inline-expand): Compile the
+ function, if needed.
+
2012-06-27 Stefan Monnier <monnier@iro.umontreal.ca>
* help-mode.el (help-make-xrefs): Don't just withstand
=== modified file 'lisp/emacs-lisp/byte-opt.el'
--- lisp/emacs-lisp/byte-opt.el 2012-06-13 13:16:34 +0000
+++ lisp/emacs-lisp/byte-opt.el 2012-06-28 03:25:59 +0000
@@ -266,42 +266,30 @@
;; (message "Inlining byte-code for %S!" name)
;; The byte-code will be really inlined in byte-compile-unfold-bcf.
`(,fn ,@(cdr form)))
- ((or (and `(lambda ,args . ,body) (let env nil))
- `(closure ,env ,args . ,body))
+ ((or `(lambda . ,_) `(closure . ,_))
(if (not (or (eq fn localfn) ;From the same file => same mode.
- (eq (not lexical-binding) (not env)))) ;Same mode.
+ (eq (car fn) ;Same mode.
+ (if lexical-binding 'closure 'lambda))))
;; While byte-compile-unfold-bcf can inline dynbind byte-code into
;; letbind byte-code (or any other combination for that matter), we
;; can only inline dynbind source into dynbind source or letbind
;; source into letbind source.
- ;; FIXME: we could of course byte-compile the inlined function
+ (progn
+ ;; We can of course byte-compile the inlined function
;; first, and then inline its byte-code.
- form
- (let ((renv ()))
- ;; Turn the function's closed vars (if any) into local let bindings.
- (dolist (binding env)
- (cond
- ((consp binding)
- ;; We check shadowing by the args, so that the `let' can be
- ;; moved within the lambda, which can then be unfolded.
- ;; FIXME: Some of those bindings might be unused in `body'.
- (unless (memq (car binding) args) ;Shadowed.
- (push `(,(car binding) ',(cdr binding)) renv)))
- ((eq binding t))
- (t (push `(defvar ,binding) body))))
+ (byte-compile name)
+ `(,(symbol-function name) ,@(cdr form)))
(let ((newfn (if (eq fn localfn)
;; If `fn' is from the same file, it has already
;; been preprocessed!
`(function ,fn)
(byte-compile-preprocess
- (if (null renv)
- `(lambda ,args ,@body)
- `(lambda ,args (let ,(nreverse renv) ,@body)))))))
+ (byte-compile--refiy-function fn)))))
(if (eq (car-safe newfn) 'function)
(byte-compile-unfold-lambda `(,(cadr newfn) ,@(cdr form)))
(byte-compile-log-warning
(format "Inlining closure %S failed" name))
- form)))))
+ form))))
(t ;; Give up on inlining.
form))))
=== modified file 'lisp/emacs-lisp/bytecomp.el'
--- lisp/emacs-lisp/bytecomp.el 2012-06-22 13:42:38 +0000
+++ lisp/emacs-lisp/bytecomp.el 2012-06-28 03:23:27 +0000
@@ -2451,7 +2451,26 @@
(- (position-bytes (point)) (point-min) -1)
(goto-char (point-max))))))
-
+(defun byte-compile--refiy-function (fun)
+ "Return an expression which will evaluate to a function value FUN.
+FUN should be either a `lambda' value or a `closure' value."
+ (pcase-let* (((or (and `(lambda ,args . ,body) (let env nil))
+ `(closure ,env ,args . ,body)) fun)
+ (renv ()))
+ ;; Turn the function's closed vars (if any) into local let bindings.
+ (dolist (binding env)
+ (cond
+ ((consp binding)
+ ;; We check shadowing by the args, so that the `let' can be moved
+ ;; within the lambda, which can then be unfolded. FIXME: Some of those
+ ;; bindings might be unused in `body'.
+ (unless (memq (car binding) args) ;Shadowed.
+ (push `(,(car binding) ',(cdr binding)) renv)))
+ ((eq binding t))
+ (t (push `(defvar ,binding) body))))
+ (if (null renv)
+ `(lambda ,args ,@body)
+ `(lambda ,args (let ,(nreverse renv) ,@body)))))
\f
;;;###autoload
(defun byte-compile (form)
@@ -2459,23 +2478,29 @@
If FORM is a lambda or a macro, byte-compile it as a function."
(displaying-byte-compile-warnings
(byte-compile-close-variables
- (let* ((fun (if (symbolp form)
+ (let* ((lexical-binding lexical-binding)
+ (fun (if (symbolp form)
(and (fboundp form) (symbol-function form))
form))
(macro (eq (car-safe fun) 'macro)))
(if macro
(setq fun (cdr fun)))
- (cond ((eq (car-safe fun) 'lambda)
+ (when (symbolp form)
+ (unless (memq (car-safe fun) '(closure lambda))
+ (error "Don't know how to compile %S" fun))
+ (setq fun (byte-compile--refiy-function fun))
+ (setq lexical-binding (eq (car fun) 'closure)))
+ (unless (eq (car-safe fun) 'lambda)
+ (error "Don't know how to compile %S" fun))
;; Expand macros.
(setq fun (byte-compile-preprocess fun))
;; Get rid of the `function' quote added by the `lambda' macro.
(if (eq (car-safe fun) 'function) (setq fun (cadr fun)))
- (setq fun (if macro
- (cons 'macro (byte-compile-lambda fun))
- (byte-compile-lambda fun)))
+ (setq fun (byte-compile-lambda fun))
+ (if macro (push 'macro fun))
(if (symbolp form)
- (defalias form fun)
- fun)))))))
+ (fset form fun)
+ fun)))))
(defun byte-compile-sexp (sexp)
"Compile and return SEXP."
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-06-28 3:31 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-06-27 16:42 bug#11799: 24.1.50; M-x ibuffer: Symbol's function definition is void: cl-minusp Michael Heerdegen
2012-06-28 2:51 ` Stefan Monnier
2012-06-28 3:31 ` Stefan Monnier
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.