aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2011-02-17 16:19:13 -0500
committerStefan Monnier2011-02-17 16:19:13 -0500
commitb38b1ec071ee9752da53f2485902165fe728e8fa (patch)
tree318ca7399de648f910626f666a1d6e62d71e081c
parentce5b520a3758e22c6516e0d864d8c1a3512bf457 (diff)
downloademacs-b38b1ec071ee9752da53f2485902165fe728e8fa.tar.gz
emacs-b38b1ec071ee9752da53f2485902165fe728e8fa.zip
Various compiler bug-fixes. MPC seems to run correctly now.
* lisp/files.el (lexical-binding): Add a safe-local-variable property. * lisp/emacs-lisp/byte-opt.el (byte-inline-lapcode): Check how many elements are added to the stack. (byte-compile-splice-in-already-compiled-code): Don't touch lexical nor byte-compile-depth now that byte-inline-lapcode does it for us. (byte-compile-inline-expand): Don't inline dynbind byte code into lexbind code, since it has to be done differently. * lisp/emacs-lisp/bytecomp.el (byte-compile-arglist-warn): Correctly extract arglist from `closure's. (byte-compile-cl-warn): Compiler-macros are run earlier now. (byte-compile-top-level): Bind byte-compile-lexical-environment to nil, except for lambdas. (byte-compile-form): Don't run the compiler-macro expander here. (byte-compile-let): Merge with byte-compile-let*. Don't preserve-body-value if the body's value was discarded. * lisp/emacs-lisp/cconv.el (cconv--set-diff, cconv--set-diff-map) (cconv--map-diff, cconv--map-diff-elem, cconv--map-diff-set): New funs. (cconv--env-var): New constant. (cconv-closure-convert-rec): Use it and use them. Fix a typo that ended up forgetting to remove entries from lmenvs in `let'. For `lambda' use the outer `fvrs' when building the closure and don't forget to remove `vars' from the `emvrs' and `lmenvs' of the body. * lisp/emacs-lisp/cl-macs.el (cl-byte-compile-block): Disable optimization in lexbind, because it needs a different implementation. * src/bytecode.c (exec_byte_code): Fix handling of &rest. * src/eval.c (Vinternal_interpreter_environment): Remove. (syms_of_eval): Do declare Vinternal_interpreter_environment as a global lisp var, but unintern it to hide it. (Fcommandp): * src/data.c (Finteractive_form): Understand `closure's.
-rw-r--r--lisp/ChangeLog31
-rw-r--r--lisp/doc-view.el4
-rw-r--r--lisp/emacs-lisp/byte-opt.el63
-rw-r--r--lisp/emacs-lisp/bytecomp.el149
-rw-r--r--lisp/emacs-lisp/cconv.el144
-rw-r--r--lisp/emacs-lisp/cl-loaddefs.el2
-rw-r--r--lisp/emacs-lisp/cl-macs.el8
-rw-r--r--lisp/emacs-lisp/pcase.el3
-rw-r--r--lisp/files.el25
-rw-r--r--lisp/help-fns.el2
-rw-r--r--src/ChangeLog10
-rw-r--r--src/bytecode.c4
-rw-r--r--src/data.c2
-rw-r--r--src/eval.c34
-rw-r--r--src/lisp.h2
15 files changed, 281 insertions, 202 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index b972f17909a..142deda9505 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,34 @@
12011-02-17 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * files.el (lexical-binding): Add a safe-local-variable property.
4
5 * emacs-lisp/cl-macs.el (cl-byte-compile-block): Disable optimization
6 in lexbind, because it needs a different implementation.
7
8 * emacs-lisp/cconv.el (cconv--set-diff, cconv--set-diff-map)
9 (cconv--map-diff, cconv--map-diff-elem, cconv--map-diff-set): New funs.
10 (cconv--env-var): New constant.
11 (cconv-closure-convert-rec): Use it and use them. Fix a typo that
12 ended up forgetting to remove entries from lmenvs in `let'.
13 For `lambda' use the outer `fvrs' when building the closure and don't
14 forget to remove `vars' from the `emvrs' and `lmenvs' of the body.
15
16 * emacs-lisp/bytecomp.el (byte-compile-arglist-warn):
17 Correctly extract arglist from `closure's.
18 (byte-compile-cl-warn): Compiler-macros are run earlier now.
19 (byte-compile-top-level): Bind byte-compile-lexical-environment to nil,
20 except for lambdas.
21 (byte-compile-form): Don't run the compiler-macro expander here.
22 (byte-compile-let): Merge with byte-compile-let*.
23 Don't preserve-body-value if the body's value was discarded.
24
25 * emacs-lisp/byte-opt.el (byte-inline-lapcode): Check how many elements
26 are added to the stack.
27 (byte-compile-splice-in-already-compiled-code): Don't touch lexical nor
28 byte-compile-depth now that byte-inline-lapcode does it for us.
29 (byte-compile-inline-expand): Don't inline dynbind byte code into
30 lexbind code, since it has to be done differently.
31
12011-02-12 Stefan Monnier <monnier@iro.umontreal.ca> 322011-02-12 Stefan Monnier <monnier@iro.umontreal.ca>
2 33
3 * emacs-lisp/byte-lexbind.el: Delete. 34 * emacs-lisp/byte-lexbind.el: Delete.
diff --git a/lisp/doc-view.el b/lisp/doc-view.el
index 4f8c338409b..7bead624cc7 100644
--- a/lisp/doc-view.el
+++ b/lisp/doc-view.el
@@ -1,5 +1,5 @@
1;;; -*- lexical-binding: t -*- 1;;; doc-view.el --- View PDF/PostScript/DVI files in Emacs -*- lexical-binding: t -*-
2;;; doc-view.el --- View PDF/PostScript/DVI files in Emacs 2
3 3
4;; Copyright (C) 2007-2011 Free Software Foundation, Inc. 4;; Copyright (C) 2007-2011 Free Software Foundation, Inc.
5;; 5;;
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index 71960ad54dc..12df3251267 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -248,7 +248,18 @@
248;; are no collisions, and that byte-compile-tag-number is reasonable 248;; are no collisions, and that byte-compile-tag-number is reasonable
249;; after this is spliced in. The provided list is destroyed. 249;; after this is spliced in. The provided list is destroyed.
250(defun byte-inline-lapcode (lap) 250(defun byte-inline-lapcode (lap)
251 (setq byte-compile-output (nconc (nreverse lap) byte-compile-output))) 251 ;; "Replay" the operations: we used to just do
252 ;; (setq byte-compile-output (nconc (nreverse lap) byte-compile-output))
253 ;; but that fails to update byte-compile-depth, so we had to assume
254 ;; that `lap' ends up adding exactly 1 element to the stack. This
255 ;; happens to be true for byte-code generated by bytecomp.el without
256 ;; lexical-binding, but it's not true in general, and it's not true for
257 ;; code output by bytecomp.el with lexical-binding.
258 (dolist (op lap)
259 (cond
260 ((eq (car op) 'TAG) (byte-compile-out-tag op))
261 ((memq (car op) byte-goto-ops) (byte-compile-goto (car op) (cdr op)))
262 (t (byte-compile-out (car op) (cdr op))))))
252 263
253(defun byte-compile-inline-expand (form) 264(defun byte-compile-inline-expand (form)
254 (let* ((name (car form)) 265 (let* ((name (car form))
@@ -266,25 +277,32 @@
266 (cdr (assq name byte-compile-function-environment))))) 277 (cdr (assq name byte-compile-function-environment)))))
267 (if (and (consp fn) (eq (car fn) 'autoload)) 278 (if (and (consp fn) (eq (car fn) 'autoload))
268 (error "File `%s' didn't define `%s'" (nth 1 fn) name)) 279 (error "File `%s' didn't define `%s'" (nth 1 fn) name))
269 (if (and (symbolp fn) (not (eq fn t))) 280 (cond
270 (byte-compile-inline-expand (cons fn (cdr form))) 281 ((and (symbolp fn) (not (eq fn t))) ;A function alias.
271 (if (byte-code-function-p fn) 282 (byte-compile-inline-expand (cons fn (cdr form))))
272 (let (string) 283 ((and (byte-code-function-p fn)
273 (fetch-bytecode fn) 284 ;; FIXME: This works to inline old-style-byte-codes into
274 (setq string (aref fn 1)) 285 ;; old-style-byte-codes, but not mixed cases (not sure
275 ;; Isn't it an error for `string' not to be unibyte?? --stef 286 ;; about new-style into new-style).
276 (if (fboundp 'string-as-unibyte) 287 (not lexical-binding)
277 (setq string (string-as-unibyte string))) 288 (not (and (>= (length fn) 7)
278 ;; `byte-compile-splice-in-already-compiled-code' 289 (aref fn 6)))) ;6 = COMPILED_PUSH_ARGS
279 ;; takes care of inlining the body. 290 ;; (message "Inlining %S byte-code" name)
280 (cons `(lambda ,(aref fn 0) 291 (fetch-bytecode fn)
281 (byte-code ,string ,(aref fn 2) ,(aref fn 3))) 292 (let ((string (aref fn 1)))
282 (cdr form))) 293 ;; Isn't it an error for `string' not to be unibyte?? --stef
283 (if (eq (car-safe fn) 'lambda) 294 (if (fboundp 'string-as-unibyte)
284 (macroexpand-all (cons fn (cdr form)) 295 (setq string (string-as-unibyte string)))
285 byte-compile-macro-environment) 296 ;; `byte-compile-splice-in-already-compiled-code'
286 ;; Give up on inlining. 297 ;; takes care of inlining the body.
287 form)))))) 298 (cons `(lambda ,(aref fn 0)
299 (byte-code ,string ,(aref fn 2) ,(aref fn 3)))
300 (cdr form))))
301 ((eq (car-safe fn) 'lambda)
302 (macroexpand-all (cons fn (cdr form))
303 byte-compile-macro-environment))
304 (t ;; Give up on inlining.
305 form)))))
288 306
289;; ((lambda ...) ...) 307;; ((lambda ...) ...)
290(defun byte-compile-unfold-lambda (form &optional name) 308(defun byte-compile-unfold-lambda (form &optional name)
@@ -1298,10 +1316,7 @@
1298 (if (not (memq byte-optimize '(t lap))) 1316 (if (not (memq byte-optimize '(t lap)))
1299 (byte-compile-normal-call form) 1317 (byte-compile-normal-call form)
1300 (byte-inline-lapcode 1318 (byte-inline-lapcode
1301 (byte-decompile-bytecode-1 (nth 1 form) (nth 2 form) t)) 1319 (byte-decompile-bytecode-1 (nth 1 form) (nth 2 form) t))))
1302 (setq byte-compile-maxdepth (max (+ byte-compile-depth (nth 3 form))
1303 byte-compile-maxdepth))
1304 (setq byte-compile-depth (1+ byte-compile-depth))))
1305 1320
1306(put 'byte-code 'byte-compile 'byte-compile-splice-in-already-compiled-code) 1321(put 'byte-code 'byte-compile 'byte-compile-splice-in-already-compiled-code)
1307 1322
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index e9beb0c5792..d3ac50a671a 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -752,9 +752,10 @@ BYTES and PC are updated after evaluating all the arguments."
752 (bytes-var (car (last args 2))) 752 (bytes-var (car (last args 2)))
753 (pc-var (car (last args)))) 753 (pc-var (car (last args))))
754 `(setq ,bytes-var ,(if (null (cdr byte-exprs)) 754 `(setq ,bytes-var ,(if (null (cdr byte-exprs))
755 `(cons ,@byte-exprs ,bytes-var) 755 `(progn (assert (<= 0 ,(car byte-exprs)))
756 `(nconc (list ,@(reverse byte-exprs)) ,bytes-var)) 756 (cons ,@byte-exprs ,bytes-var))
757 ,pc-var (+ ,(length byte-exprs) ,pc-var)))) 757 `(nconc (list ,@(reverse byte-exprs)) ,bytes-var))
758 ,pc-var (+ ,(length byte-exprs) ,pc-var))))
758 759
759(defmacro byte-compile-push-bytecode-const2 (opcode const2 bytes pc) 760(defmacro byte-compile-push-bytecode-const2 (opcode const2 bytes pc)
760 "Push OPCODE and the two-byte constant CONST2 onto BYTES, and add 3 to PC. 761 "Push OPCODE and the two-byte constant CONST2 onto BYTES, and add 3 to PC.
@@ -817,7 +818,7 @@ CONST2 may be evaulated multiple times."
817 ;; These insns all put their operand into one extra byte. 818 ;; These insns all put their operand into one extra byte.
818 (byte-compile-push-bytecodes opcode off bytes pc)) 819 (byte-compile-push-bytecodes opcode off bytes pc))
819 ((= opcode byte-discardN) 820 ((= opcode byte-discardN)
820 ;; byte-discardN is wierd in that it encodes a flag in the 821 ;; byte-discardN is weird in that it encodes a flag in the
821 ;; top bit of its one-byte argument. If the argument is 822 ;; top bit of its one-byte argument. If the argument is
822 ;; too large to fit in 7 bits, the opcode can be repeated. 823 ;; too large to fit in 7 bits, the opcode can be repeated.
823 (let ((flag (if (eq op 'byte-discardN-preserve-tos) #x80 0))) 824 (let ((flag (if (eq op 'byte-discardN-preserve-tos) #x80 0)))
@@ -1330,11 +1331,11 @@ extra args."
1330 (eq 'lambda (car-safe (cdr-safe old))) 1331 (eq 'lambda (car-safe (cdr-safe old)))
1331 (setq old (cdr old))) 1332 (setq old (cdr old)))
1332 (let ((sig1 (byte-compile-arglist-signature 1333 (let ((sig1 (byte-compile-arglist-signature
1333 (if (eq 'lambda (car-safe old)) 1334 (pcase old
1334 (nth 1 old) 1335 (`(lambda ,args . ,_) args)
1335 (if (byte-code-function-p old) 1336 (`(closure ,_ ,_ ,args . ,_) args)
1336 (aref old 0) 1337 ((pred byte-code-function-p) (aref old 0))
1337 '(&rest def))))) 1338 (t '(&rest def)))))
1338 (sig2 (byte-compile-arglist-signature (nth 2 form)))) 1339 (sig2 (byte-compile-arglist-signature (nth 2 form))))
1339 (unless (byte-compile-arglist-signatures-congruent-p sig1 sig2) 1340 (unless (byte-compile-arglist-signatures-congruent-p sig1 sig2)
1340 (byte-compile-set-symbol-position (nth 1 form)) 1341 (byte-compile-set-symbol-position (nth 1 form))
@@ -1402,14 +1403,7 @@ extra args."
1402 ;; but such warnings are never useful, 1403 ;; but such warnings are never useful,
1403 ;; so don't warn about them. 1404 ;; so don't warn about them.
1404 macroexpand cl-macroexpand-all 1405 macroexpand cl-macroexpand-all
1405 cl-compiling-file))) 1406 cl-compiling-file))))
1406 ;; Avoid warnings for things which are safe because they
1407 ;; have suitable compiler macros, but those aren't
1408 ;; expanded at this stage. There should probably be more
1409 ;; here than caaar and friends.
1410 (not (and (eq (get func 'byte-compile)
1411 'cl-byte-compile-compiler-macro)
1412 (string-match "\\`c[ad]+r\\'" (symbol-name func)))))
1413 (byte-compile-warn "function `%s' from cl package called at runtime" 1407 (byte-compile-warn "function `%s' from cl package called at runtime"
1414 func))) 1408 func)))
1415 form) 1409 form)
@@ -2701,8 +2695,8 @@ If FORM is a lambda or a macro, byte-compile it as a function."
2701 (if (eq (car-safe form) 'list) 2695 (if (eq (car-safe form) 'list)
2702 (byte-compile-top-level (nth 1 bytecomp-int)) 2696 (byte-compile-top-level (nth 1 bytecomp-int))
2703 (setq bytecomp-int (list 'interactive 2697 (setq bytecomp-int (list 'interactive
2704 (byte-compile-top-level 2698 (byte-compile-top-level
2705 (nth 1 bytecomp-int))))))) 2699 (nth 1 bytecomp-int)))))))
2706 ((cdr bytecomp-int) 2700 ((cdr bytecomp-int)
2707 (byte-compile-warn "malformed interactive spec: %s" 2701 (byte-compile-warn "malformed interactive spec: %s"
2708 (prin1-to-string bytecomp-int))))) 2702 (prin1-to-string bytecomp-int)))))
@@ -2788,6 +2782,9 @@ If FORM is a lambda or a macro, byte-compile it as a function."
2788 (byte-compile-tag-number 0) 2782 (byte-compile-tag-number 0)
2789 (byte-compile-depth 0) 2783 (byte-compile-depth 0)
2790 (byte-compile-maxdepth 0) 2784 (byte-compile-maxdepth 0)
2785 (byte-compile-lexical-environment
2786 (when (eq output-type 'lambda)
2787 byte-compile-lexical-environment))
2791 (byte-compile-output nil)) 2788 (byte-compile-output nil))
2792 (if (memq byte-optimize '(t source)) 2789 (if (memq byte-optimize '(t source))
2793 (setq form (byte-optimize-form form for-effect))) 2790 (setq form (byte-optimize-form form for-effect)))
@@ -2798,14 +2795,13 @@ If FORM is a lambda or a macro, byte-compile it as a function."
2798 (stringp (nth 1 form)) (vectorp (nth 2 form)) 2795 (stringp (nth 1 form)) (vectorp (nth 2 form))
2799 (natnump (nth 3 form))) 2796 (natnump (nth 3 form)))
2800 form 2797 form
2801 ;; Set up things for a lexically-bound function 2798 ;; Set up things for a lexically-bound function.
2802 (when (and lexical-binding (eq output-type 'lambda)) 2799 (when (and lexical-binding (eq output-type 'lambda))
2803 ;; See how many arguments there are, and set the current stack depth 2800 ;; See how many arguments there are, and set the current stack depth
2804 ;; accordingly 2801 ;; accordingly.
2805 (dolist (var byte-compile-lexical-environment) 2802 (setq byte-compile-depth (length byte-compile-lexical-environment))
2806 (setq byte-compile-depth (1+ byte-compile-depth)))
2807 ;; If there are args, output a tag to record the initial 2803 ;; If there are args, output a tag to record the initial
2808 ;; stack-depth for the optimizer 2804 ;; stack-depth for the optimizer.
2809 (when (> byte-compile-depth 0) 2805 (when (> byte-compile-depth 0)
2810 (byte-compile-out-tag (byte-compile-make-tag)))) 2806 (byte-compile-out-tag (byte-compile-make-tag))))
2811 ;; Now compile FORM 2807 ;; Now compile FORM
@@ -2964,9 +2960,10 @@ That command is designed for interactive use only" bytecomp-fn))
2964 ;; for CL compiler macros since the symbol may be 2960 ;; for CL compiler macros since the symbol may be
2965 ;; `cl-byte-compile-compiler-macro' but if CL isn't 2961 ;; `cl-byte-compile-compiler-macro' but if CL isn't
2966 ;; loaded, this function doesn't exist. 2962 ;; loaded, this function doesn't exist.
2967 (or (not (memq bytecomp-handler 2963 (and (not (eq bytecomp-handler
2968 '(cl-byte-compile-compiler-macro))) 2964 ;; Already handled by macroexpand-all.
2969 (functionp bytecomp-handler))) 2965 'cl-byte-compile-compiler-macro))
2966 (functionp bytecomp-handler)))
2970 (funcall bytecomp-handler form) 2967 (funcall bytecomp-handler form)
2971 (byte-compile-normal-call form)) 2968 (byte-compile-normal-call form))
2972 (if (byte-compile-warning-enabled-p 'cl-functions) 2969 (if (byte-compile-warning-enabled-p 'cl-functions)
@@ -3612,7 +3609,7 @@ discarding."
3612(byte-defop-compiler-1 while) 3609(byte-defop-compiler-1 while)
3613(byte-defop-compiler-1 funcall) 3610(byte-defop-compiler-1 funcall)
3614(byte-defop-compiler-1 let) 3611(byte-defop-compiler-1 let)
3615(byte-defop-compiler-1 let*) 3612(byte-defop-compiler-1 let* byte-compile-let)
3616 3613
3617(defun byte-compile-progn (form) 3614(defun byte-compile-progn (form)
3618 (byte-compile-body-do-effect (cdr form))) 3615 (byte-compile-body-do-effect (cdr form)))
@@ -3819,10 +3816,8 @@ Return the offset in the form (VAR . OFFSET)."
3819 (byte-compile-push-constant nil))))) 3816 (byte-compile-push-constant nil)))))
3820 3817
3821(defun byte-compile-not-lexical-var-p (var) 3818(defun byte-compile-not-lexical-var-p (var)
3822 (or (not (symbolp var)) ; form is not a list 3819 (or (not (symbolp var))
3823 (if (eval-when-compile (fboundp 'special-variable-p)) 3820 (special-variable-p var)
3824 (special-variable-p var)
3825 (boundp var))
3826 (memq var byte-compile-bound-variables) 3821 (memq var byte-compile-bound-variables)
3827 (memq var '(nil t)) 3822 (memq var '(nil t))
3828 (keywordp var))) 3823 (keywordp var)))
@@ -3833,9 +3828,8 @@ INIT-LEXENV should be a lexical-environment alist describing the
3833positions of the init value that have been pushed on the stack. 3828positions of the init value that have been pushed on the stack.
3834Return non-nil if the TOS value was popped." 3829Return non-nil if the TOS value was popped."
3835 ;; The presence of lexical bindings mean that we may have to 3830 ;; The presence of lexical bindings mean that we may have to
3836 ;; juggle things on the stack, either to move them to TOS for 3831 ;; juggle things on the stack, to move them to TOS for
3837 ;; dynamic binding, or to put them in a non-stack environment 3832 ;; dynamic binding.
3838 ;; vector.
3839 (cond ((not (byte-compile-not-lexical-var-p var)) 3833 (cond ((not (byte-compile-not-lexical-var-p var))
3840 ;; VAR is a simple stack-allocated lexical variable 3834 ;; VAR is a simple stack-allocated lexical variable
3841 (push (assq var init-lexenv) 3835 (push (assq var init-lexenv)
@@ -3883,56 +3877,41 @@ binding slots have been popped."
3883 3877
3884(defun byte-compile-let (form) 3878(defun byte-compile-let (form)
3885 "Generate code for the `let' form FORM." 3879 "Generate code for the `let' form FORM."
3886 ;; First compute the binding values in the old scope. 3880 (let ((clauses (cadr form))
3887 (let ((varlist (car (cdr form))) 3881 (init-lexenv nil))
3888 (init-lexenv nil)) 3882 (when (eq (car form) 'let)
3889 (dolist (var varlist) 3883 ;; First compute the binding values in the old scope.
3890 (push (byte-compile-push-binding-init var) init-lexenv)) 3884 (dolist (var clauses)
3891 ;; Now do the bindings, execute the body, and undo the bindings. 3885 (push (byte-compile-push-binding-init var) init-lexenv)))
3892 (let ((byte-compile-bound-variables byte-compile-bound-variables) ;new scope 3886 ;; New scope.
3893 (varlist (reverse (car (cdr form)))) 3887 (let ((byte-compile-bound-variables byte-compile-bound-variables)
3894 (byte-compile-lexical-environment byte-compile-lexical-environment)) 3888 (byte-compile-lexical-environment byte-compile-lexical-environment))
3895 (dolist (var varlist) 3889 ;; Bind the variables.
3896 (let ((var (if (consp var) (car var) var))) 3890 ;; For `let', do it in reverse order, because it makes no
3897 (cond ((null lexical-binding) 3891 ;; semantic difference, but it is a lot more efficient since the
3898 ;; If there are no lexical bindings, we can do things simply. 3892 ;; values are now in reverse order on the stack.
3899 (byte-compile-dynamic-variable-bind var)) 3893 (dolist (var (if (eq (car form) 'let) (reverse clauses) clauses))
3900 ((byte-compile-bind var init-lexenv) 3894 (unless (eq (car form) 'let)
3901 (pop init-lexenv))))) 3895 (push (byte-compile-push-binding-init var) init-lexenv))
3896 (let ((var (if (consp var) (car var) var)))
3897 (cond ((null lexical-binding)
3898 ;; If there are no lexical bindings, we can do things simply.
3899 (byte-compile-dynamic-variable-bind var))
3900 ((byte-compile-bind var init-lexenv)
3901 (pop init-lexenv)))))
3902 ;; Emit the body. 3902 ;; Emit the body.
3903 (byte-compile-body-do-effect (cdr (cdr form))) 3903 (let ((init-stack-depth byte-compile-depth))
3904 ;; Unbind the variables. 3904 (byte-compile-body-do-effect (cdr (cdr form)))
3905 (if lexical-binding 3905 ;; Unbind the variables.
3906 ;; Unbind both lexical and dynamic variables. 3906 (if lexical-binding
3907 (byte-compile-unbind varlist init-lexenv t) 3907 ;; Unbind both lexical and dynamic variables.
3908 ;; Unbind dynamic variables. 3908 (progn
3909 (byte-compile-out 'byte-unbind (length varlist)))))) 3909 (assert (or (eq byte-compile-depth init-stack-depth)
3910 3910 (eq byte-compile-depth (1+ init-stack-depth))))
3911(defun byte-compile-let* (form) 3911 (byte-compile-unbind clauses init-lexenv (> byte-compile-depth
3912 "Generate code for the `let*' form FORM." 3912 init-stack-depth)))
3913 (let ((byte-compile-bound-variables byte-compile-bound-variables) ;new scope 3913 ;; Unbind dynamic variables.
3914 (clauses (cadr form)) 3914 (byte-compile-out 'byte-unbind (length clauses)))))))
3915 (init-lexenv nil)
3916 ;; bind these to restrict the scope of any changes
3917
3918 (byte-compile-lexical-environment byte-compile-lexical-environment))
3919 ;; Bind the variables
3920 (dolist (var clauses)
3921 (push (byte-compile-push-binding-init var) init-lexenv)
3922 (let ((var (if (consp var) (car var) var)))
3923 (cond ((null lexical-binding)
3924 ;; If there are no lexical bindings, we can do things simply.
3925 (byte-compile-dynamic-variable-bind var))
3926 ((byte-compile-bind var init-lexenv)
3927 (pop init-lexenv)))))
3928 ;; Emit the body
3929 (byte-compile-body-do-effect (cdr (cdr form)))
3930 ;; Unbind the variables
3931 (if lexical-binding
3932 ;; Unbind both lexical and dynamic variables
3933 (byte-compile-unbind clauses init-lexenv t)
3934 ;; Unbind dynamic variables
3935 (byte-compile-out 'byte-unbind (length clauses)))))
3936 3915
3937 3916
3938 3917
@@ -4254,8 +4233,8 @@ binding slots have been popped."
4254 (progn 4233 (progn
4255 ;; ## remove this someday 4234 ;; ## remove this someday
4256 (and byte-compile-depth 4235 (and byte-compile-depth
4257 (not (= (cdr (cdr tag)) byte-compile-depth)) 4236 (not (= (cdr (cdr tag)) byte-compile-depth))
4258 (error "Compiler bug: depth conflict at tag %d" (car (cdr tag)))) 4237 (error "Compiler bug: depth conflict at tag %d" (car (cdr tag))))
4259 (setq byte-compile-depth (cdr (cdr tag)))) 4238 (setq byte-compile-depth (cdr (cdr tag))))
4260 (setcdr (cdr tag) byte-compile-depth))) 4239 (setcdr (cdr tag) byte-compile-depth)))
4261 4240
diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el
index 10464047cd3..d8f5a7da44d 100644
--- a/lisp/emacs-lisp/cconv.el
+++ b/lisp/emacs-lisp/cconv.el
@@ -70,6 +70,15 @@
70;; 70;;
71;;; Code: 71;;; Code:
72 72
73;;; TODO:
74;; - Use abstract `make-closure' and `closure-ref' expressions, which bytecomp
75;; should turn into building corresponding byte-code function.
76;; - don't use `curry', instead build a new compiled-byte-code object
77;; (merge the closure env into the static constants pool).
78;; - use relative addresses for byte-code-stack-ref.
79;; - warn about unused lexical vars.
80;; - clean up cconv-closure-convert-rec, especially the `let' binding part.
81
73(eval-when-compile (require 'cl)) 82(eval-when-compile (require 'cl))
74 83
75(defconst cconv-liftwhen 3 84(defconst cconv-liftwhen 3
@@ -187,14 +196,14 @@ Returns a list of free variables."
187-- TOPLEVEL(optional) is a boolean variable, true if we are at the root of AST 196-- TOPLEVEL(optional) is a boolean variable, true if we are at the root of AST
188 197
189Returns a form where all lambdas don't have any free variables." 198Returns a form where all lambdas don't have any free variables."
190 (message "Entering cconv-closure-convert...") 199 ;; (message "Entering cconv-closure-convert...")
191 (let ((cconv-mutated '()) 200 (let ((cconv-mutated '())
192 (cconv-lambda-candidates '()) 201 (cconv-lambda-candidates '())
193 (cconv-captured '()) 202 (cconv-captured '())
194 (cconv-captured+mutated '())) 203 (cconv-captured+mutated '()))
195 ;; Analyse form - fill these variables with new information 204 ;; Analyse form - fill these variables with new information.
196 (cconv-analyse-form form '() 0) 205 (cconv-analyse-form form '() 0)
197 ;; Calculate an intersection of cconv-mutated and cconv-captured 206 ;; Calculate an intersection of cconv-mutated and cconv-captured.
198 (dolist (mvr cconv-mutated) 207 (dolist (mvr cconv-mutated)
199 (when (memq mvr cconv-captured) ; 208 (when (memq mvr cconv-captured) ;
200 (push mvr cconv-captured+mutated))) 209 (push mvr cconv-captured+mutated)))
@@ -216,14 +225,51 @@ Returns a form where all lambdas don't have any free variables."
216 res)) 225 res))
217 226
218(defconst cconv--dummy-var (make-symbol "ignored")) 227(defconst cconv--dummy-var (make-symbol "ignored"))
228(defconst cconv--env-var (make-symbol "env"))
229
230(defun cconv--set-diff (s1 s2)
231 "Return elements of set S1 that are not in set S2."
232 (let ((res '()))
233 (dolist (x s1)
234 (unless (memq x s2) (push x res)))
235 (nreverse res)))
236
237(defun cconv--set-diff-map (s m)
238 "Return elements of set S that are not in Dom(M)."
239 (let ((res '()))
240 (dolist (x s)
241 (unless (assq x m) (push x res)))
242 (nreverse res)))
243
244(defun cconv--map-diff (m1 m2)
245 "Return the submap of map M1 that has Dom(M2) removed."
246 (let ((res '()))
247 (dolist (x m1)
248 (unless (assq (car x) m2) (push x res)))
249 (nreverse res)))
250
251(defun cconv--map-diff-elem (m x)
252 "Return the map M minus any mapping for X."
253 ;; Here we assume that X appears at most once in M.
254 (let* ((b (assq x m))
255 (res (if b (remq b m) m)))
256 (assert (null (assq x res))) ;; Check the assumption was warranted.
257 res))
219 258
220(defun cconv-closure-convert-rec 259(defun cconv--map-diff-set (m s)
221 (form emvrs fvrs envs lmenvs) 260 "Return the map M minus any mapping for elements of S."
261 ;; Here we assume that X appears at most once in M.
262 (let ((res '()))
263 (dolist (b m)
264 (unless (memq (car b) s) (push b res)))
265 (nreverse res)))
266
267(defun cconv-closure-convert-rec (form emvrs fvrs envs lmenvs)
222 ;; This function actually rewrites the tree. 268 ;; This function actually rewrites the tree.
223 "Eliminates all free variables of all lambdas in given forms. 269 "Eliminates all free variables of all lambdas in given forms.
224Arguments: 270Arguments:
225-- FORM is a piece of Elisp code after macroexpansion. 271-- FORM is a piece of Elisp code after macroexpansion.
226-- LMENVS is a list of environments used for lambda-lifting. Initially empty. 272-- LMENVS is a list of environments used for lambda-lifting. Initially empty.
227-- EMVRS is a list that contains mutated variables that are visible 273-- EMVRS is a list that contains mutated variables that are visible
228within current environment. 274within current environment.
229-- ENVS is an environment(list of free variables) of current closure. 275-- ENVS is an environment(list of free variables) of current closure.
@@ -343,10 +389,9 @@ Returns a form where all lambdas don't have any free variables."
343 (setq lmenvs (remq old-lmenv lmenvs)) 389 (setq lmenvs (remq old-lmenv lmenvs))
344 (push new-lmenv lmenvs) 390 (push new-lmenv lmenvs)
345 (push `(,closedsym ,var) binders-new)))) 391 (push `(,closedsym ,var) binders-new))))
346 ;; we push the element after redefined free variables 392 ;; We push the element after redefined free variables are
347 ;; are processes. this is important to avoid the bug 393 ;; processed. This is important to avoid the bug when free
348 ;; when free variable and the function have the same 394 ;; variable and the function have the same name.
349 ;; name
350 (push (list var new-val) binders-new) 395 (push (list var new-val) binders-new)
351 396
352 (when (eq letsym 'let*) ; update fvrs 397 (when (eq letsym 'let*) ; update fvrs
@@ -355,11 +400,7 @@ Returns a form where all lambdas don't have any free variables."
355 (when emvr-push 400 (when emvr-push
356 (push emvr-push emvrs) 401 (push emvr-push emvrs)
357 (setq emvr-push nil)) 402 (setq emvr-push nil))
358 (let (lmenvs-1) ; remove var from lmenvs if redefined 403 (setq lmenvs (cconv--map-diff-elem lmenvs var))
359 (dolist (iter lmenvs)
360 (when (not (assq var lmenvs))
361 (push iter lmenvs-1)))
362 (setq lmenvs lmenvs-1))
363 (when lmenv-push 404 (when lmenv-push
364 (push lmenv-push lmenvs) 405 (push lmenv-push lmenvs)
365 (setq lmenv-push nil))) 406 (setq lmenv-push nil)))
@@ -368,19 +409,10 @@ Returns a form where all lambdas don't have any free variables."
368 409
369 (let (var fvrs-1 emvrs-1 lmenvs-1) 410 (let (var fvrs-1 emvrs-1 lmenvs-1)
370 ;; Here we update emvrs, fvrs and lmenvs lists 411 ;; Here we update emvrs, fvrs and lmenvs lists
371 (dolist (vr fvrs) 412 (setq fvrs (cconv--set-diff-map fvrs binders-new))
372 ; safely remove 413 (setq emvrs (cconv--set-diff-map emvrs binders-new))
373 (when (not (assq vr binders-new)) (push vr fvrs-1)))
374 (setq fvrs fvrs-1)
375 (dolist (vr emvrs)
376 ; safely remove
377 (when (not (assq vr binders-new)) (push vr emvrs-1)))
378 (setq emvrs emvrs-1)
379 ; push new
380 (setq emvrs (append emvrs emvrs-new)) 414 (setq emvrs (append emvrs emvrs-new))
381 (dolist (vr lmenvs) 415 (setq lmenvs (cconv--set-diff-map lmenvs binders-new))
382 (when (not (assq (car vr) binders-new))
383 (push vr lmenvs-1)))
384 (setq lmenvs (append lmenvs lmenvs-new))) 416 (setq lmenvs (append lmenvs lmenvs-new)))
385 417
386 ;; Here we do the same letbinding as for let* above 418 ;; Here we do the same letbinding as for let* above
@@ -402,9 +434,9 @@ Returns a form where all lambdas don't have any free variables."
402 (symbol-name var)))) 434 (symbol-name var))))
403 435
404 (setq new-lmenv (list (car lmenv))) 436 (setq new-lmenv (list (car lmenv)))
405 (dolist (frv (cdr lmenv)) (if (eq frv var) 437 (dolist (frv (cdr lmenv))
406 (push closedsym new-lmenv) 438 (push (if (eq frv var) closedsym frv)
407 (push frv new-lmenv))) 439 new-lmenv))
408 (setq new-lmenv (reverse new-lmenv)) 440 (setq new-lmenv (reverse new-lmenv))
409 (setq lmenvs (remq lmenv lmenvs)) 441 (setq lmenvs (remq lmenv lmenvs))
410 (push new-lmenv lmenvs) 442 (push new-lmenv lmenvs)
@@ -449,13 +481,9 @@ Returns a form where all lambdas don't have any free variables."
449 (`(quote . ,_) form) ; quote form 481 (`(quote . ,_) form) ; quote form
450 482
451 (`(function . ((lambda ,vars . ,body-forms))) ; function form 483 (`(function . ((lambda ,vars . ,body-forms))) ; function form
452 (let (fvrs-new) ; we remove vars from fvrs 484 (let* ((fvrs-new (cconv--set-diff fvrs vars)) ; Remove vars from fvrs.
453 (dolist (elm fvrs) ;i use such a tricky way to avoid side effects 485 (fv (delete-dups (cconv-freevars form '())))
454 (when (not (memq elm vars)) 486 (leave fvrs-new) ; leave=non-nil if we should leave env unchanged.
455 (push elm fvrs-new)))
456 (setq fvrs fvrs-new))
457 (let* ((fv (delete-dups (cconv-freevars form '())))
458 (leave fvrs) ; leave = non nil if we should leave env unchanged
459 (body-forms-new '()) 487 (body-forms-new '())
460 (letbind '()) 488 (letbind '())
461 (mv nil) 489 (mv nil)
@@ -470,7 +498,7 @@ Returns a form where all lambdas don't have any free variables."
470 (if (eq (length envs) (length fv)) 498 (if (eq (length envs) (length fv))
471 (let ((fv-temp fv)) 499 (let ((fv-temp fv))
472 (while (and fv-temp leave) 500 (while (and fv-temp leave)
473 (when (not (memq (car fv-temp) fvrs)) (setq leave nil)) 501 (when (not (memq (car fv-temp) fvrs-new)) (setq leave nil))
474 (setq fv-temp (cdr fv-temp)))) 502 (setq fv-temp (cdr fv-temp))))
475 (setq leave nil)) 503 (setq leave nil))
476 504
@@ -479,23 +507,30 @@ Returns a form where all lambdas don't have any free variables."
479 (dolist (elm fv) 507 (dolist (elm fv)
480 (push 508 (push
481 (cconv-closure-convert-rec 509 (cconv-closure-convert-rec
510 ;; Remove `elm' from `emvrs' for this call because in case
511 ;; `elm' is a variable that's wrapped in a cons-cell, we
512 ;; want to put the cons-cell itself in the closure, rather
513 ;; than just a copy of its current content.
482 elm (remq elm emvrs) fvrs envs lmenvs) 514 elm (remq elm emvrs) fvrs envs lmenvs)
483 envector)) ; process vars for closure vector 515 envector)) ; Process vars for closure vector.
484 (setq envector (reverse envector)) 516 (setq envector (reverse envector))
485 (setq envs fv)) 517 (setq envs fv))
486 (setq envector `(env))) ; leave unchanged 518 (setq envector `(,cconv--env-var))) ; Leave unchanged.
487 (setq fvrs fv)) ; update substitution list 519 (setq fvrs-new fv)) ; Update substitution list.
488 520
489 ;; the difference between envs and fvrs is explained 521 (setq emvrs (cconv--set-diff emvrs vars))
490 ;; in comment in the beginning of the function 522 (setq lmenvs (cconv--map-diff-set lmenvs vars))
491 (dolist (elm cconv-captured+mutated) ; find mutated arguments 523
492 (setq mv (car elm)) ; used in inner closures 524 ;; The difference between envs and fvrs is explained
525 ;; in comment in the beginning of the function.
526 (dolist (elm cconv-captured+mutated) ; Find mutated arguments
527 (setq mv (car elm)) ; used in inner closures.
493 (when (and (memq mv vars) (eq form (caddr elm))) 528 (when (and (memq mv vars) (eq form (caddr elm)))
494 (progn (push mv emvrs) 529 (progn (push mv emvrs)
495 (push `(,mv (list ,mv)) letbind)))) 530 (push `(,mv (list ,mv)) letbind))))
496 (dolist (elm body-forms) ; convert function body 531 (dolist (elm body-forms) ; convert function body
497 (push (cconv-closure-convert-rec 532 (push (cconv-closure-convert-rec
498 elm emvrs fvrs envs lmenvs) 533 elm emvrs fvrs-new envs lmenvs)
499 body-forms-new)) 534 body-forms-new))
500 535
501 (setq body-forms-new 536 (setq body-forms-new
@@ -509,12 +544,12 @@ Returns a form where all lambdas don't have any free variables."
509 ; 1 free variable - do not build vector 544 ; 1 free variable - do not build vector
510 ((null (cdr envector)) 545 ((null (cdr envector))
511 `(curry 546 `(curry
512 (function (lambda (env . ,vars) . ,body-forms-new)) 547 (function (lambda (,cconv--env-var . ,vars) . ,body-forms-new))
513 ,(car envector))) 548 ,(car envector)))
514 ; >=2 free variables - build vector 549 ; >=2 free variables - build vector
515 (t 550 (t
516 `(curry 551 `(curry
517 (function (lambda (env . ,vars) . ,body-forms-new)) 552 (function (lambda (,cconv--env-var . ,vars) . ,body-forms-new))
518 (vector . ,envector)))))) 553 (vector . ,envector))))))
519 554
520 (`(function . ,_) form) ; same as quote 555 (`(function . ,_) form) ; same as quote
@@ -674,13 +709,10 @@ Returns a form where all lambdas don't have any free variables."
674 (let ((free (memq form fvrs))) 709 (let ((free (memq form fvrs)))
675 (if free ;form is a free variable 710 (if free ;form is a free variable
676 (let* ((numero (- (length fvrs) (length free))) 711 (let* ((numero (- (length fvrs) (length free)))
677 (var '())) 712 (var (if (null (cdr envs))
678 (assert numero) 713 cconv--env-var
679 (if (null (cdr envs)) 714 ;; Replace form => (aref env #)
680 (setq var 'env) 715 `(aref ,cconv--env-var ,numero))))
681 ;replace form =>
682 ;(aref env #)
683 (setq var `(aref env ,numero)))
684 (if (memq form emvrs) ; form => (car (aref env #)) if mutable 716 (if (memq form emvrs) ; form => (car (aref env #)) if mutable
685 `(car ,var) 717 `(car ,var)
686 var)) 718 var))
diff --git a/lisp/emacs-lisp/cl-loaddefs.el b/lisp/emacs-lisp/cl-loaddefs.el
index e10dc10447c..a13e46ccc59 100644
--- a/lisp/emacs-lisp/cl-loaddefs.el
+++ b/lisp/emacs-lisp/cl-loaddefs.el
@@ -282,7 +282,7 @@ Not documented
282;;;;;; do-all-symbols do-symbols dotimes dolist do* do loop return-from 282;;;;;; do-all-symbols do-symbols dotimes dolist do* do loop return-from
283;;;;;; return block etypecase typecase ecase case load-time-value 283;;;;;; return block etypecase typecase ecase case load-time-value
284;;;;;; eval-when destructuring-bind function* defmacro* defun* gentemp 284;;;;;; eval-when destructuring-bind function* defmacro* defun* gentemp
285;;;;;; gensym) "cl-macs" "cl-macs.el" "0904b956872432ae7cc5fa9abcefce63") 285;;;;;; gensym) "cl-macs" "cl-macs.el" "7602128fa01003de9a8df4c752865300")
286;;; Generated autoloads from cl-macs.el 286;;; Generated autoloads from cl-macs.el
287 287
288(autoload 'gensym "cl-macs" "\ 288(autoload 'gensym "cl-macs" "\
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 80e95724f1f..093e4fbf258 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -602,7 +602,13 @@ called from BODY."
602 602
603(put 'cl-block-wrapper 'byte-compile 'cl-byte-compile-block) 603(put 'cl-block-wrapper 'byte-compile 'cl-byte-compile-block)
604(defun cl-byte-compile-block (cl-form) 604(defun cl-byte-compile-block (cl-form)
605 (if (fboundp 'byte-compile-form-do-effect) ; Check for optimizing compiler 605 ;; Here we try to determine if a catch tag is used or not, so as to get rid
606 ;; of the catch when it's not used.
607 (if (and (fboundp 'byte-compile-form-do-effect) ; Optimizing compiler?
608 ;; FIXME: byte-compile-top-level can only be used for code that is
609 ;; closed (as the name implies), so for lexical scoping we should
610 ;; implement this optimization differently.
611 (not lexical-binding))
606 (progn 612 (progn
607 (let* ((cl-entry (cons (nth 1 (nth 1 (nth 1 cl-form))) nil)) 613 (let* ((cl-entry (cons (nth 1 (nth 1 (nth 1 cl-form))) nil))
608 (cl-active-block-names (cons cl-entry cl-active-block-names)) 614 (cl-active-block-names (cons cl-entry cl-active-block-names))
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
index 7990df264a9..a338de251ed 100644
--- a/lisp/emacs-lisp/pcase.el
+++ b/lisp/emacs-lisp/pcase.el
@@ -1,5 +1,4 @@
1;;; -*- lexical-binding: t -*- 1;;; pcase.el --- ML-style pattern-matching macro for Elisp -*- lexical-binding: t -*-
2;;; pcase.el --- ML-style pattern-matching macro for Elisp
3 2
4;; Copyright (C) 2010-2011 Free Software Foundation, Inc. 3;; Copyright (C) 2010-2011 Free Software Foundation, Inc.
5 4
diff --git a/lisp/files.el b/lisp/files.el
index 8b42eaaddb8..e7dd96ca2ff 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -2851,18 +2851,19 @@ asking you for confirmation."
2851;; 2851;;
2852;; For variables defined in the C source code the declaration should go here: 2852;; For variables defined in the C source code the declaration should go here:
2853 2853
2854(mapc (lambda (pair) 2854(dolist (pair
2855 (put (car pair) 'safe-local-variable (cdr pair))) 2855 '((buffer-read-only . booleanp) ;; C source code
2856 '((buffer-read-only . booleanp) ;; C source code 2856 (default-directory . stringp) ;; C source code
2857 (default-directory . stringp) ;; C source code 2857 (fill-column . integerp) ;; C source code
2858 (fill-column . integerp) ;; C source code 2858 (indent-tabs-mode . booleanp) ;; C source code
2859 (indent-tabs-mode . booleanp) ;; C source code 2859 (left-margin . integerp) ;; C source code
2860 (left-margin . integerp) ;; C source code 2860 (no-update-autoloads . booleanp)
2861 (no-update-autoloads . booleanp) 2861 (lexical-binding . booleanp) ;; C source code
2862 (tab-width . integerp) ;; C source code 2862 (tab-width . integerp) ;; C source code
2863 (truncate-lines . booleanp) ;; C source code 2863 (truncate-lines . booleanp) ;; C source code
2864 (word-wrap . booleanp) ;; C source code 2864 (word-wrap . booleanp) ;; C source code
2865 (bidi-display-reordering . booleanp))) ;; C source code 2865 (bidi-display-reordering . booleanp))) ;; C source code
2866 (put (car pair) 'safe-local-variable (cdr pair)))
2866 2867
2867(put 'bidi-paragraph-direction 'safe-local-variable 2868(put 'bidi-paragraph-direction 'safe-local-variable
2868 (lambda (v) (memq v '(nil right-to-left left-to-right)))) 2869 (lambda (v) (memq v '(nil right-to-left left-to-right))))
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index 172a74d8c80..49767e6e9d3 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -530,7 +530,7 @@ suitable file is found, return nil."
530 (let ((fill-begin (point))) 530 (let ((fill-begin (point)))
531 (insert (car high) "\n") 531 (insert (car high) "\n")
532 (fill-region fill-begin (point))) 532 (fill-region fill-begin (point)))
533 (setq doc (cdr high)))) 533 (setq doc (cdr high))))
534 (let* ((obsolete (and 534 (let* ((obsolete (and
535 ;; function might be a lambda construct. 535 ;; function might be a lambda construct.
536 (symbolp function) 536 (symbolp function)
diff --git a/src/ChangeLog b/src/ChangeLog
index 6674fb31ca5..0b2ee8550ca 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,13 @@
12011-02-17 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * eval.c (Vinternal_interpreter_environment): Remove.
4 (syms_of_eval): Do declare Vinternal_interpreter_environment as
5 a global lisp var, but unintern it to hide it.
6 (Fcommandp):
7 * data.c (Finteractive_form): Understand `closure's.
8
9 * bytecode.c (exec_byte_code): Fix handling of &rest.
10
12011-02-12 Stefan Monnier <monnier@iro.umontreal.ca> 112011-02-12 Stefan Monnier <monnier@iro.umontreal.ca>
2 12
3 * bytecode.c (Bvec_ref, Bvec_set): Remove. 13 * bytecode.c (Bvec_ref, Bvec_set): Remove.
diff --git a/src/bytecode.c b/src/bytecode.c
index 9bf6ae45ce9..1ad01aaf8f7 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -500,7 +500,9 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
500 optional = 1; 500 optional = 1;
501 else if (EQ (XCAR (at), Qand_rest)) 501 else if (EQ (XCAR (at), Qand_rest))
502 { 502 {
503 PUSH (Flist (nargs, args)); 503 PUSH (pushed < nargs
504 ? Flist (nargs - pushed, args)
505 : Qnil);
504 pushed = nargs; 506 pushed = nargs;
505 at = Qnil; 507 at = Qnil;
506 break; 508 break;
diff --git a/src/data.c b/src/data.c
index 83da3e103cb..2f17edd3fdc 100644
--- a/src/data.c
+++ b/src/data.c
@@ -755,6 +755,8 @@ Value, if non-nil, is a list \(interactive SPEC). */)
755 else if (CONSP (fun)) 755 else if (CONSP (fun))
756 { 756 {
757 Lisp_Object funcar = XCAR (fun); 757 Lisp_Object funcar = XCAR (fun);
758 if (EQ (funcar, Qclosure))
759 fun = Fcdr (XCDR (fun)), funcar = Fcar (fun);
758 if (EQ (funcar, Qlambda)) 760 if (EQ (funcar, Qlambda))
759 return Fassq (Qinteractive, Fcdr (XCDR (fun))); 761 return Fassq (Qinteractive, Fcdr (XCDR (fun)));
760 else if (EQ (funcar, Qautoload)) 762 else if (EQ (funcar, Qautoload))
diff --git a/src/eval.c b/src/eval.c
index 9adfc983ced..63484d40e1b 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -78,16 +78,6 @@ Lisp_Object Vrun_hooks;
78 78
79Lisp_Object Vautoload_queue; 79Lisp_Object Vautoload_queue;
80 80
81/* When lexical binding is being used, this is non-nil, and contains an
82 alist of lexically-bound variable, or (t), indicating an empty
83 environment. The lisp name of this variable is
84 `internal-interpreter-environment'. Every element of this list
85 can be either a cons (VAR . VAL) specifying a lexical binding,
86 or a single symbol VAR indicating that this variable should use
87 dynamic scoping. */
88
89Lisp_Object Vinternal_interpreter_environment;
90
91/* Current number of specbindings allocated in specpdl. */ 81/* Current number of specbindings allocated in specpdl. */
92 82
93EMACS_INT specpdl_size; 83EMACS_INT specpdl_size;
@@ -2092,9 +2082,11 @@ then strings and vectors are not accepted. */)
2092 if (!CONSP (fun)) 2082 if (!CONSP (fun))
2093 return Qnil; 2083 return Qnil;
2094 funcar = XCAR (fun); 2084 funcar = XCAR (fun);
2085 if (EQ (funcar, Qclosure))
2086 fun = Fcdr (XCDR (fun)), funcar = Fcar (fun);
2095 if (EQ (funcar, Qlambda)) 2087 if (EQ (funcar, Qlambda))
2096 return !NILP (Fassq (Qinteractive, Fcdr (XCDR (fun)))) ? Qt : if_prop; 2088 return !NILP (Fassq (Qinteractive, Fcdr (XCDR (fun)))) ? Qt : if_prop;
2097 if (EQ (funcar, Qautoload)) 2089 else if (EQ (funcar, Qautoload))
2098 return !NILP (Fcar (Fcdr (Fcdr (XCDR (fun))))) ? Qt : if_prop; 2090 return !NILP (Fcar (Fcdr (Fcdr (XCDR (fun))))) ? Qt : if_prop;
2099 else 2091 else
2100 return Qnil; 2092 return Qnil;
@@ -3695,6 +3687,8 @@ mark_backtrace (void)
3695 } 3687 }
3696} 3688}
3697 3689
3690EXFUN (Funintern, 2);
3691
3698void 3692void
3699syms_of_eval (void) 3693syms_of_eval (void)
3700{ 3694{
@@ -3840,19 +3834,27 @@ DECL is a list `(declare ...)' containing the declarations.
3840The value the function returns is not used. */); 3834The value the function returns is not used. */);
3841 Vmacro_declaration_function = Qnil; 3835 Vmacro_declaration_function = Qnil;
3842 3836
3837 /* When lexical binding is being used,
3838 vinternal_interpreter_environment is non-nil, and contains an alist
3839 of lexically-bound variable, or (t), indicating an empty
3840 environment. The lisp name of this variable would be
3841 `internal-interpreter-environment' if it weren't hidden.
3842 Every element of this list can be either a cons (VAR . VAL)
3843 specifying a lexical binding, or a single symbol VAR indicating
3844 that this variable should use dynamic scoping. */
3843 Qinternal_interpreter_environment 3845 Qinternal_interpreter_environment
3844 = intern_c_string ("internal-interpreter-environment"); 3846 = intern_c_string ("internal-interpreter-environment");
3845 staticpro (&Qinternal_interpreter_environment); 3847 staticpro (&Qinternal_interpreter_environment);
3846#if 0 /* Don't export this variable to Elisp, so noone can mess with it 3848 DEFVAR_LISP ("internal-interpreter-environment",
3847 (Just imagine if someone makes it buffer-local). */ 3849 Vinternal_interpreter_environment,
3848 DEFVAR__LISP ("internal-interpreter-environment",
3849 Vinternal_interpreter_environment,
3850 doc: /* If non-nil, the current lexical environment of the lisp interpreter. 3850 doc: /* If non-nil, the current lexical environment of the lisp interpreter.
3851When lexical binding is not being used, this variable is nil. 3851When lexical binding is not being used, this variable is nil.
3852A value of `(t)' indicates an empty environment, otherwise it is an 3852A value of `(t)' indicates an empty environment, otherwise it is an
3853alist of active lexical bindings. */); 3853alist of active lexical bindings. */);
3854#endif
3855 Vinternal_interpreter_environment = Qnil; 3854 Vinternal_interpreter_environment = Qnil;
3855 /* Don't export this variable to Elisp, so noone can mess with it
3856 (Just imagine if someone makes it buffer-local). */
3857 Funintern (Qinternal_interpreter_environment, Qnil);
3856 3858
3857 Vrun_hooks = intern_c_string ("run-hooks"); 3859 Vrun_hooks = intern_c_string ("run-hooks");
3858 staticpro (&Vrun_hooks); 3860 staticpro (&Vrun_hooks);
diff --git a/src/lisp.h b/src/lisp.h
index 906736bacad..0e7eeebc9da 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2855,7 +2855,7 @@ extern void syms_of_lread (void);
2855 2855
2856/* Defined in eval.c */ 2856/* Defined in eval.c */
2857extern Lisp_Object Qautoload, Qexit, Qinteractive, Qcommandp, Qdefun, Qmacro; 2857extern Lisp_Object Qautoload, Qexit, Qinteractive, Qcommandp, Qdefun, Qmacro;
2858extern Lisp_Object Qinhibit_quit; 2858extern Lisp_Object Qinhibit_quit, Qclosure;
2859extern Lisp_Object Vautoload_queue; 2859extern Lisp_Object Vautoload_queue;
2860extern Lisp_Object Vsignaling_function; 2860extern Lisp_Object Vsignaling_function;
2861extern int handling_signal; 2861extern int handling_signal;