Let cconv use :fun-body in special forms that need it.
[emacs.git] / lisp / emacs-lisp / byte-lexbind.el
blob06353e2eea82cb50b9a142475fec1ad4058dc6b3
1 ;;; byte-lexbind.el --- Lexical binding support for byte-compiler
2 ;;
3 ;; Copyright (C) 2001, 2002, 2010, 2011 Free Software Foundation, Inc.
4 ;;
5 ;; Author: Miles Bader <miles@gnu.org>
6 ;; Keywords: lisp, compiler, lexical binding
8 ;; This file is part of GNU Emacs.
10 ;; GNU Emacs is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
25 ;;; Commentary:
28 ;;; Code:
30 (require 'bytecomp-preload "bytecomp")
32 ;; Downward closures aren't implemented yet, so this should always be nil
33 (defconst byte-compile-use-downward-closures nil
34 "If true, use `downward closures', which are closures that don't cons.")
36 (defconst byte-compile-save-window-excursion-uses-eval t
37 "If true, the bytecode for `save-window-excursion' uses eval.
38 This means that the body of the form must be put into a closure.")
40 (defun byte-compile-arglist-vars (arglist)
41 "Return a list of the variables in the lambda argument list ARGLIST."
42 (remq '&rest (remq '&optional arglist)))
45 ;;; Variable extent analysis.
47 ;; A `lforminfo' holds information about lexical bindings in a form, and some
48 ;; other info for analysis. It is a cons-cell, where the car is a list of
49 ;; `lvarinfo' stuctures, which form an alist indexed by variable name, and the
50 ;; cdr is the number of closures found in the form:
52 ;; LFORMINFO : ((LVARINFO ...) . NUM-CLOSURES)"
54 ;; A `lvarinfo' holds information about a single lexical variable. It is a
55 ;; list whose car is the variable name (so an lvarinfo is suitable as an alist
56 ;; entry), and the rest of the of which holds information about the variable:
58 ;; LVARINFO : (VAR NUM-REFS NUM-SETS CLOSED-OVER)
60 ;; NUM-REFS is the number of times the variable's value is used
61 ;; NUM-SETS is the number of times the variable's value is set
62 ;; CLOSED-OVER is non-nil if the variable is referenced
63 ;; anywhere but in its original function-level"
65 ;;; lvarinfo:
67 ;; constructor
68 (defsubst byte-compile-make-lvarinfo (var &optional already-set)
69 (list var 0 (if already-set 1 0) 0 nil))
70 ;; accessors
71 (defsubst byte-compile-lvarinfo-var (vinfo) (car vinfo))
72 (defsubst byte-compile-lvarinfo-num-refs (vinfo) (cadr vinfo))
73 (defsubst byte-compile-lvarinfo-num-sets (vinfo) (nth 3 vinfo))
74 (defsubst byte-compile-lvarinfo-closed-over-p (vinfo) (nth 4 vinfo))
75 ;; setters
76 (defsubst byte-compile-lvarinfo-note-ref (vinfo)
77 (setcar (cdr vinfo) (1+ (cadr vinfo))))
78 (defsubst byte-compile-lvarinfo-note-set (vinfo)
79 (setcar (cddr vinfo) (1+ (nth 3 vinfo))))
80 (defsubst byte-compile-lvarinfo-note-closure (vinfo)
81 (setcar (nthcdr 4 vinfo) t))
83 ;;; lforminfo:
85 ;; constructor
86 (defsubst byte-compile-make-lforminfo ()
87 (cons nil 0))
88 ;; accessors
89 (defalias 'byte-compile-lforminfo-vars 'car)
90 (defalias 'byte-compile-lforminfo-num-closures 'cdr)
91 ;; setters
92 (defsubst byte-compile-lforminfo-add-var (finfo var &optional already-set)
93 (setcar finfo (cons (byte-compile-make-lvarinfo var already-set)
94 (car finfo))))
96 (defun byte-compile-lforminfo-make-closure-flag ()
97 "Return a new `closure-flag'."
98 (cons nil nil))
100 (defsubst byte-compile-lforminfo-note-closure (lforminfo lvarinfo closure-flag)
101 "If a variable reference or definition is inside a closure, record that fact.
102 LFORMINFO describes the form currently being analyzed, and LVARINFO
103 describes the variable. CLOSURE-FLAG is either nil, if currently _not_
104 inside a closure, and otherwise a `closure flag' returned by
105 `byte-compile-lforminfo-make-closure-flag'."
106 (when closure-flag
107 (byte-compile-lvarinfo-note-closure lvarinfo)
108 (unless (car closure-flag)
109 (setcdr lforminfo (1+ (cdr lforminfo)))
110 (setcar closure-flag t))))
112 (defun byte-compile-compute-lforminfo (form &optional special)
113 "Return information about variables lexically bound by FORM.
114 SPECIAL is a list of variables that are special, and so shouldn't be
115 bound lexically (in addition to variable that are considered special
116 because they are declared with `defvar', et al).
118 The result is an `lforminfo' data structure."
119 (and
120 (consp form)
121 (let ((lforminfo (byte-compile-make-lforminfo)))
122 (cond ((eq (car form) 'let)
123 ;; Find the bound variables
124 (dolist (clause (cadr form))
125 (let ((var (if (consp clause) (car clause) clause)))
126 (unless (or (special-variable-p var) (memq var special))
127 (byte-compile-lforminfo-add-var lforminfo var t))))
128 ;; Analyze the body
129 (unless (null (byte-compile-lforminfo-vars lforminfo))
130 (byte-compile-lforminfo-analyze-forms lforminfo form 2
131 special nil)))
132 ((eq (car form) 'let*)
133 (dolist (clause (cadr form))
134 (let ((var (if (consp clause) (car clause) clause)))
135 ;; Analyze each initializer based on the previously
136 ;; bound variables.
137 (when (and (consp clause) lforminfo)
138 (byte-compile-lforminfo-analyze lforminfo (cadr clause)
139 special nil))
140 (unless (or (special-variable-p var) (memq var special))
141 (byte-compile-lforminfo-add-var lforminfo var t))))
142 ;; Analyze the body
143 (unless (null (byte-compile-lforminfo-vars lforminfo))
144 (byte-compile-lforminfo-analyze-forms lforminfo form 2
145 special nil)))
146 ((eq (car form) 'condition-case)
147 ;; `condition-case' currently must dynamically bind the
148 ;; error variable, so do nothing.
150 ((memq (car form) '(defun defmacro))
151 (byte-compile-lforminfo-from-lambda lforminfo (cdr form) special))
152 ((eq (car form) 'lambda)
153 (byte-compile-lforminfo-from-lambda lforminfo form special))
154 ((and (consp (car form)) (eq (caar form) 'lambda))
155 ;; An embedded lambda, which is basically just a `let'
156 (byte-compile-lforminfo-from-lambda lforminfo (cdr form) special)))
157 (if (byte-compile-lforminfo-vars lforminfo)
158 lforminfo
159 nil))))
161 (defun byte-compile-lforminfo-from-lambda (lforminfo lambda special)
162 "Initialize LFORMINFO from the lambda expression LAMBDA.
163 SPECIAL is a list of variables to ignore.
164 The first element of LAMBDA is ignored; it need not actually be `lambda'."
165 ;; Add the arguments
166 (dolist (arg (byte-compile-arglist-vars (cadr lambda)))
167 (byte-compile-lforminfo-add-var lforminfo arg t))
168 ;; Analyze the body
169 (unless (null (byte-compile-lforminfo-vars lforminfo))
170 (byte-compile-lforminfo-analyze-forms lforminfo lambda 2 special nil)))
172 (defun byte-compile-lforminfo-analyze (lforminfo form &optional ignore closure-flag)
173 "Update variable information in LFORMINFO by analyzing FORM.
174 IGNORE is a list of variables that shouldn't be analyzed (usually because
175 they're special, or because some inner binding shadows the version in
176 LFORMINFO). CLOSURE-FLAG should be either nil or a `closure flag' created
177 with `byte-compile-lforminfo-make-closure-flag'; the latter indicates that
178 FORM is inside a lambda expression that may close over some variable in
179 LFORMINFO."
180 (cond ((symbolp form)
181 ;; variable reference
182 (unless (member form ignore)
183 (let ((vinfo (assq form (byte-compile-lforminfo-vars lforminfo))))
184 (when vinfo
185 (byte-compile-lvarinfo-note-ref vinfo)
186 (byte-compile-lforminfo-note-closure lforminfo vinfo
187 closure-flag)))))
188 ;; function call/special form
189 ((consp form)
190 (let ((fun (car form)))
191 (cond
192 ((eq fun 'setq)
193 (pop form)
194 (while form
195 (let ((var (pop form)))
196 (byte-compile-lforminfo-analyze lforminfo (pop form)
197 ignore closure-flag)
198 (unless (member var ignore)
199 (let ((vinfo
200 (assq var (byte-compile-lforminfo-vars lforminfo))))
201 (when vinfo
202 (byte-compile-lvarinfo-note-set vinfo)
203 (byte-compile-lforminfo-note-closure lforminfo vinfo
204 closure-flag)))))))
205 ((and (eq fun 'catch) (not (eq :fun-body (nth 2 form))))
206 ;; tag
207 (byte-compile-lforminfo-analyze lforminfo (cadr form)
208 ignore closure-flag)
209 ;; `catch' uses a closure for the body
210 (byte-compile-lforminfo-analyze-forms
211 lforminfo form 2
212 ignore
213 (or closure-flag
214 (and (not byte-compile-use-downward-closures)
215 (byte-compile-lforminfo-make-closure-flag)))))
216 ((eq fun 'cond)
217 (byte-compile-lforminfo-analyze-clauses lforminfo (cdr form) 0
218 ignore closure-flag))
219 ((eq fun 'condition-case)
220 ;; `condition-case' separates its body/handlers into
221 ;; separate closures.
222 (unless (or (eq (nth 1 form) :fun-body)
223 closure-flag byte-compile-use-downward-closures)
224 ;; condition case is implemented by calling a function
225 (setq closure-flag (byte-compile-lforminfo-make-closure-flag)))
226 ;; value form
227 (byte-compile-lforminfo-analyze lforminfo (nth 2 form)
228 ignore closure-flag)
229 ;; the error variable is always bound dynamically (because
230 ;; of the implementation)
231 (when (cadr form)
232 (push (cadr form) ignore))
233 ;; handlers
234 (byte-compile-lforminfo-analyze-clauses lforminfo
235 (nthcdr 2 form) 1
236 ignore closure-flag))
237 ((eq fun '(defvar defconst))
238 (byte-compile-lforminfo-analyze lforminfo (nth 2 form)
239 ignore closure-flag))
240 ((memq fun '(defun defmacro))
241 (byte-compile-lforminfo-analyze-forms lforminfo form 3
242 ignore closure-flag))
243 ((eq fun 'function)
244 ;; Analyze an embedded lambda expression [note: we only recognize
245 ;; it within (function ...) as the (lambda ...) for is actually a
246 ;; macro returning (function (lambda ...))].
247 (when (and (consp (cadr form)) (eq (car (cadr form)) 'lambda))
248 ;; shadow bound variables
249 (setq ignore
250 (append (byte-compile-arglist-vars (cadr (cadr form)))
251 ignore))
252 ;; analyze body of lambda
253 (byte-compile-lforminfo-analyze-forms
254 lforminfo (cadr form) 2
255 ignore
256 (or closure-flag
257 (byte-compile-lforminfo-make-closure-flag)))))
258 ((eq fun 'let)
259 ;; analyze variable inits
260 (byte-compile-lforminfo-analyze-clauses lforminfo (cadr form) 1
261 ignore closure-flag)
262 ;; shadow bound variables
263 (dolist (clause (cadr form))
264 (push (if (symbolp clause) clause (car clause))
265 ignore))
266 ;; analyze body
267 (byte-compile-lforminfo-analyze-forms lforminfo form 2
268 ignore closure-flag))
269 ((eq fun 'let*)
270 (dolist (clause (cadr form))
271 (if (symbolp clause)
272 ;; shadow bound (to nil) variable
273 (push clause ignore)
274 ;; analyze variable init
275 (byte-compile-lforminfo-analyze lforminfo (cadr clause)
276 ignore closure-flag)
277 ;; shadow bound variable
278 (push (car clause) ignore)))
279 ;; analyze body
280 (byte-compile-lforminfo-analyze-forms lforminfo form 2
281 ignore closure-flag))
282 ((eq fun 'quote)
283 ;; do nothing
285 ((and (eq fun 'save-window-excursion)
286 (not (eq :fun-body (nth 1 form))))
287 ;; `save-window-excursion' currently uses a funny implementation
288 ;; that requires its body forms be put into a closure (it should
289 ;; be fixed to work more like `save-excursion' etc., do).
290 (byte-compile-lforminfo-analyze-forms
291 lforminfo form 2
292 ignore
293 (or closure-flag
294 (and byte-compile-save-window-excursion-uses-eval
295 (not byte-compile-use-downward-closures)
296 (byte-compile-lforminfo-make-closure-flag)))))
297 ((and (consp fun) (eq (car fun) 'lambda))
298 ;; Embedded lambda. These are inlined by the compiler, so
299 ;; we don't treat them like a real closure, more like `let'.
300 ;; analyze inits
301 (byte-compile-lforminfo-analyze-forms lforminfo form 2
302 ignore closure-flag)
304 ;; shadow bound variables
305 (setq ignore (nconc (byte-compile-arglist-vars (cadr fun))
306 ignore))
307 ;; analyze body
308 (byte-compile-lforminfo-analyze-forms lforminfo fun 2
309 ignore closure-flag))
311 ;; For everything else, we just expand each argument (for
312 ;; setq/setq-default this works alright because the
313 ;; variable names are symbols).
314 (byte-compile-lforminfo-analyze-forms lforminfo form 1
315 ignore closure-flag)))))))
317 (defun byte-compile-lforminfo-analyze-forms
318 (lforminfo forms skip ignore closure-flag)
319 "Update variable information in LFORMINFO by analyzing each form in FORMS.
320 The first SKIP elements of FORMS are skipped without analysis. IGNORE
321 is a list of variables that shouldn't be analyzed (usually because
322 they're special, or because some inner binding shadows the version in
323 LFORMINFO). CLOSURE-FLAG should be either nil or a `closure flag' created with
324 `byte-compile-lforminfo-make-closure-flag'; the latter indicates that FORM is
325 inside a lambda expression that may close over some variable in LFORMINFO."
326 (when skip
327 (setq forms (nthcdr skip forms)))
328 (while forms
329 (byte-compile-lforminfo-analyze lforminfo (pop forms)
330 ignore closure-flag)))
332 (defun byte-compile-lforminfo-analyze-clauses
333 (lforminfo clauses skip ignore closure-flag)
334 "Update variable information in LFORMINFO by analyzing each clause in CLAUSES.
335 Each clause is a list of forms; any clause that's not a list is ignored. The
336 first SKIP elements of each clause are skipped without analysis. IGNORE is a
337 list of variables that shouldn't be analyzed (usually because they're special,
338 or because some inner binding shadows the version in LFORMINFO).
339 CLOSURE-FLAG should be either nil or a `closure flag' created with
340 `byte-compile-lforminfo-make-closure-flag'; the latter indicates that FORM is
341 inside a lambda expression that may close over some variable in LFORMINFO."
342 (while clauses
343 (let ((clause (pop clauses)))
344 (when (consp clause)
345 (byte-compile-lforminfo-analyze-forms lforminfo clause skip
346 ignore closure-flag)))))
349 ;;; Lexical environments
351 ;; A lexical environment is an alist, where each element is of the form
352 ;; (VAR . (OFFSET . ENV)) where VAR is either a symbol, for normal
353 ;; variables, or an `heapenv' descriptor for references to heap environment
354 ;; vectors. ENV is either an atom, meaning a `stack allocated' variable
355 ;; (the particular atom serves to indicate the particular function context
356 ;; on whose stack it's allocated), or an `heapenv' descriptor (see above),
357 ;; meaning a variable allocated in a heap environment vector. For the
358 ;; later case, an anonymous `variable' holding a pointer to the environment
359 ;; vector may be located by recursively looking up ENV in the environment
360 ;; as if it were a variable (so the entry for that `variable' will have a
361 ;; non-symbol VAR).
363 ;; We call a lexical environment a `lexenv', and an entry in it a `lexvar'.
365 ;; constructor
366 (defsubst byte-compile-make-lexvar (name offset &optional env)
367 (cons name (cons offset env)))
368 ;; accessors
369 (defsubst byte-compile-lexvar-name (lexvar) (car lexvar))
370 (defsubst byte-compile-lexvar-offset (lexvar) (cadr lexvar))
371 (defsubst byte-compile-lexvar-environment (lexvar) (cddr lexvar))
372 (defsubst byte-compile-lexvar-variable-p (lexvar) (symbolp (car lexvar)))
373 (defsubst byte-compile-lexvar-environment-p (lexvar)
374 (not (symbolp (car lexvar))))
375 (defsubst byte-compile-lexvar-on-stack-p (lexvar)
376 (atom (byte-compile-lexvar-environment lexvar)))
377 (defsubst byte-compile-lexvar-in-heap-p (lexvar)
378 (not (byte-compile-lexvar-on-stack-p lexvar)))
380 (defun byte-compile-make-lambda-lexenv (form closed-over-lexenv)
381 "Return a new lexical environment for a lambda expression FORM.
382 CLOSED-OVER-LEXENV is the lexical environment in which FORM occurs.
383 The returned lexical environment contains two sets of variables:
384 * Variables that were in CLOSED-OVER-LEXENV and used by FORM
385 (all of these will be `heap' variables)
386 * Arguments to FORM (all of these will be `stack' variables)."
387 ;; See if this is a closure or not
388 (let ((closure nil)
389 (lforminfo (byte-compile-make-lforminfo))
390 (args (byte-compile-arglist-vars (cadr form))))
391 ;; Add variables from surrounding lexical environment to analysis set
392 (dolist (lexvar closed-over-lexenv)
393 (when (and (byte-compile-lexvar-in-heap-p lexvar)
394 (not (memq (car lexvar) args)))
395 ;; The variable is located in a heap-allocated environment
396 ;; vector, so FORM may use it. Add it to the set of variables
397 ;; that we'll search for in FORM.
398 (byte-compile-lforminfo-add-var lforminfo (car lexvar))))
399 ;; See how FORM uses these potentially closed-over variables.
400 (byte-compile-lforminfo-analyze lforminfo form args)
401 (let ((lexenv nil))
402 (dolist (vinfo (byte-compile-lforminfo-vars lforminfo))
403 (when (> (byte-compile-lvarinfo-num-refs vinfo) 0)
404 ;; FORM uses VINFO's variable, so it must be a closure.
405 (setq closure t)
406 ;; Make sure that the environment in which the variable is
407 ;; located is accessible (since we only ever pass the
408 ;; innermost environment to closures, if it's in some other
409 ;; envionment, there must be path to it from the innermost
410 ;; one).
411 (unless (byte-compile-lexvar-in-heap-p vinfo)
412 ;; To access the variable from FORM, it must be in the heap.
413 (error
414 "Compiler error: lexical variable `%s' should be heap-allocated but is not"
415 (car vinfo)))
416 (let ((closed-over-lexvar (assq (car vinfo) closed-over-lexenv)))
417 (byte-compile-heapenv-ensure-access
418 byte-compile-current-heap-environment
419 (byte-compile-lexvar-environment closed-over-lexvar))
420 ;; Put this variable in the new lexical environment
421 (push closed-over-lexvar lexenv))))
422 ;; Fill in the initial stack contents
423 (let ((stackpos 0))
424 (when closure
425 ;; Add the magic first argument that holds the environment pointer
426 (push (byte-compile-make-lexvar byte-compile-current-heap-environment
428 lexenv)
429 (setq stackpos (1+ stackpos)))
430 ;; Add entries for each argument
431 (dolist (arg args)
432 (push (byte-compile-make-lexvar arg stackpos) lexenv)
433 (setq stackpos (1+ stackpos)))
434 ;; Return the new lexical environment
435 lexenv))))
437 (defun byte-compile-closure-initial-lexenv-p (lexenv)
438 "Return non-nil if LEXENV is the initial lexical environment for a closure.
439 This only works correctly when passed a new lexical environment as
440 returned by `byte-compile-make-lambda-lexenv' (it works by checking to
441 see whether there are any heap-allocated lexical variables in LEXENV)."
442 (let ((closure nil))
443 (while (and lexenv (not closure))
444 (when (byte-compile-lexvar-environment-p (pop lexenv))
445 (setq closure t)))
446 closure))
449 ;;; Heap environment vectors
451 ;; A `heap environment vector' is heap-allocated vector used to store
452 ;; variable that can't be put onto the stack.
454 ;; They are represented in the compiler by a list of the form
456 ;; (SIZE SIZE-CONST-ID INIT-POSITION . ENVS)
458 ;; SIZE is the current size of the vector (which may be
459 ;; incremented if another variable or environment-reference is added to
460 ;; the end). SIZE-CONST-ID is an `unknown constant id' (as returned by
461 ;; `byte-compile-push-unknown-constant') representing the constant used
462 ;; in the vector initialization code, and INIT-POSITION is a position
463 ;; in the byte-code output (as returned by `byte-compile-delay-out')
464 ;; at which more initialization code can be added.
465 ;; ENVS is a list of other environment vectors accessible form this one,
466 ;; where each element is of the form (ENV . OFFSET).
468 ;; constructor
469 (defsubst byte-compile-make-heapenv (size-const-id init-position)
470 (list 0 size-const-id init-position))
471 ;; accessors
472 (defsubst byte-compile-heapenv-size (heapenv) (car heapenv))
473 (defsubst byte-compile-heapenv-size-const-id (heapenv) (cadr heapenv))
474 (defsubst byte-compile-heapenv-init-position (heapenv) (nth 2 heapenv))
475 (defsubst byte-compile-heapenv-accessible-envs (heapenv) (nthcdr 3 heapenv))
477 (defun byte-compile-heapenv-add-slot (heapenv)
478 "Add a slot to the heap environment HEAPENV and return its offset."
479 (prog1 (car heapenv) (setcar heapenv (1+ (car heapenv)))))
481 (defun byte-compile-heapenv-add-accessible-env (heapenv env offset)
482 "Add to HEAPENV's list of accessible environments, ENV at OFFSET."
483 (setcdr (nthcdr 2 heapenv)
484 (cons (cons env offset)
485 (byte-compile-heapenv-accessible-envs heapenv))))
487 (defun byte-compile-push-heapenv ()
488 "Generate byte-code to push a new heap environment vector.
489 Sets `byte-compile-current-heap-environment' to the compiler descriptor
490 for the new heap environment.
491 Return a `lexvar' descriptor for the new heap environment."
492 (let ((env-stack-pos byte-compile-depth)
493 size-const-id init-position)
494 ;; Generate code to push the vector
495 (byte-compile-push-constant 'make-vector)
496 (setq size-const-id (byte-compile-push-unknown-constant))
497 (byte-compile-push-constant nil)
498 (byte-compile-out 'byte-call 2)
499 (setq init-position (byte-compile-delay-out 3))
500 ;; Now make a heap-environment for the compiler to use
501 (setq byte-compile-current-heap-environment
502 (byte-compile-make-heapenv size-const-id init-position))
503 (byte-compile-make-lexvar byte-compile-current-heap-environment
504 env-stack-pos)))
506 (defun byte-compile-heapenv-ensure-access (heapenv other-heapenv)
507 "Make sure that HEAPENV can be used to access OTHER-HEAPENV.
508 If not, then add a new slot to HEAPENV pointing to OTHER-HEAPENV."
509 (unless (memq heapenv (byte-compile-heapenv-accessible-envs heapenv))
510 (let ((offset (byte-compile-heapenv-add-slot heapenv)))
511 (byte-compile-heapenv-add-accessible-env heapenv other-heapenv offset))))
514 ;;; Variable binding/unbinding
516 (defun byte-compile-non-stack-bindings-p (clauses lforminfo)
517 "Return non-nil if any lexical bindings in CLAUSES are not stack-allocated.
518 LFORMINFO should be information about lexical variables being bound."
519 (let ((vars (byte-compile-lforminfo-vars lforminfo)))
520 (or (not (= (length clauses) (length vars)))
521 (progn
522 (while (and vars clauses)
523 (when (byte-compile-lvarinfo-closed-over-p (pop vars))
524 (setq clauses nil)))
525 (not clauses)))))
527 (defun byte-compile-let-clauses-trivial-init-p (clauses)
528 "Return true if let binding CLAUSES all have a `trivial' init value.
529 Trivial means either a constant value, or a simple variable initialization."
530 (or (null clauses)
531 (and (or (atom (car clauses))
532 (atom (cadr (car clauses)))
533 (eq (car (cadr (car clauses))) 'quote))
534 (byte-compile-let-clauses-trivial-init-p (cdr clauses)))))
536 (defun byte-compile-rearrange-let-clauses (clauses lforminfo)
537 "Return CLAUSES rearranged so non-stack variables come last if possible.
538 Care is taken to only do so when it's clear that the meaning is the same.
539 LFORMINFO should be information about lexical variables being bound."
540 ;; We currently do a very simple job by only exchanging clauses when
541 ;; one has a constant init, or one has a variable init and the other
542 ;; doesn't have a function call init (because that could change the
543 ;; value of the variable). This could be more clever and actually
544 ;; attempt to analyze which variables could possible be changed, etc.
545 (let ((unchanged nil)
546 (lex-non-stack nil)
547 (dynamic nil))
548 (while clauses
549 (let* ((clause (pop clauses))
550 (var (if (consp clause) (car clause) clause))
551 (init (and (consp clause) (cadr clause)))
552 (vinfo (assq var (byte-compile-lforminfo-vars lforminfo))))
553 (cond
554 ((or (and vinfo
555 (not (byte-compile-lvarinfo-closed-over-p vinfo)))
556 (not
557 (or (eq init nil) (eq init t)
558 (and (atom init) (not (symbolp init)))
559 (and (consp init) (eq (car init) 'quote))
560 (byte-compile-let-clauses-trivial-init-p clauses))))
561 (push clause unchanged))
562 (vinfo
563 (push clause lex-non-stack))
565 (push clause dynamic)))))
566 (nconc (nreverse unchanged) (nreverse lex-non-stack) (nreverse dynamic))))
568 (defun byte-compile-maybe-push-heap-environment (&optional lforminfo)
569 "Push a new heap environment if necessary.
570 LFORMINFO should be information about lexical variables being bound.
571 Return a lexical environment containing only the heap vector (or
572 nil if nothing was pushed).
573 Also, `byte-compile-current-heap-environment' and
574 `byte-compile-current-num-closures' are updated to reflect any change (so they
575 should probably be bound by the caller to ensure that the new values have the
576 proper scope)."
577 ;; We decide whether a new heap environment is required by seeing if
578 ;; the number of closures inside the form described by LFORMINFO is
579 ;; the same as the number inside the binding form that created the
580 ;; currently active heap environment.
581 (let ((nclosures
582 (and lforminfo (byte-compile-lforminfo-num-closures lforminfo))))
583 (if (or (null lforminfo)
584 (zerop nclosures)
585 (= nclosures byte-compile-current-num-closures))
586 ;; No need to push a heap environment.
588 (error "Should have been handled by cconv")
589 ;; Have to push one. A heap environment is really just a vector, so
590 ;; we emit bytecodes to create a vector. However, the size is not
591 ;; fixed yet (the vector can grow if subforms use it to store
592 ;; values, and if `access points' to parent heap environments are
593 ;; added), so we use `byte-compile-push-unknown-constant' to push the
594 ;; vector size.
595 (setq byte-compile-current-num-closures nclosures)
596 (list (byte-compile-push-heapenv)))))
598 (defun byte-compile-bind (var init-lexenv &optional lforminfo)
599 "Emit byte-codes to bind VAR and update `byte-compile-lexical-environment'.
600 INIT-LEXENV should be a lexical-environment alist describing the
601 positions of the init value that have been pushed on the stack, and
602 LFORMINFO should be information about lexical variables being bound.
603 Return non-nil if the TOS value was popped."
604 ;; The presence of lexical bindings mean that we may have to
605 ;; juggle things on the stack, either to move them to TOS for
606 ;; dynamic binding, or to put them in a non-stack environment
607 ;; vector.
608 (let ((vinfo (assq var (byte-compile-lforminfo-vars lforminfo))))
609 (cond ((and (null vinfo) (eq var (caar init-lexenv)))
610 ;; VAR is dynamic and is on the top of the
611 ;; stack, so we can just bind it like usual
612 (byte-compile-dynamic-variable-bind var)
614 ((null vinfo)
615 ;; VAR is dynamic, but we have to get its
616 ;; value out of the middle of the stack
617 (let ((stack-pos (cdr (assq var init-lexenv))))
618 (byte-compile-stack-ref stack-pos)
619 (byte-compile-dynamic-variable-bind var)
620 ;; Now we have to store nil into its temporary
621 ;; stack position to avoid problems with GC
622 (byte-compile-push-constant nil)
623 (byte-compile-stack-set stack-pos))
624 nil)
625 ((byte-compile-lvarinfo-closed-over-p vinfo)
626 ;; VAR is lexical, but needs to be in a
627 ;; heap-allocated environment.
628 (unless byte-compile-current-heap-environment
629 (error "No current heap-environment to allocate `%s' in!" var))
630 (let ((init-stack-pos
631 ;; nil if the init value is on the top of the stack,
632 ;; otherwise the position of the init value on the stack.
633 (and (not (eq var (caar init-lexenv)))
634 (byte-compile-lexvar-offset (assq var init-lexenv))))
635 (env-vec-pos
636 ;; Position of VAR in the environment vector
637 (byte-compile-lexvar-offset
638 (assq var byte-compile-lexical-environment)))
639 (env-vec-stack-pos
640 ;; Position of the the environment vector on the stack
641 ;; (the heap-environment must _always_ be available on
642 ;; the stack!)
643 (byte-compile-lexvar-offset
644 (assq byte-compile-current-heap-environment
645 byte-compile-lexical-environment))))
646 (unless env-vec-stack-pos
647 (error "Couldn't find location of current heap environment!"))
648 (when init-stack-pos
649 ;; VAR is not on the top of the stack, so get it
650 (byte-compile-stack-ref init-stack-pos))
651 (byte-compile-stack-ref env-vec-stack-pos)
652 ;; Store the variable into the vector
653 (byte-compile-out 'byte-vec-set env-vec-pos)
654 (when init-stack-pos
655 ;; Store nil into VAR's temporary stack
656 ;; position to avoid problems with GC
657 (byte-compile-push-constant nil)
658 (byte-compile-stack-set init-stack-pos))
659 ;; Push a record of VAR's new lexical binding
660 (push (byte-compile-make-lexvar
661 var env-vec-pos byte-compile-current-heap-environment)
662 byte-compile-lexical-environment)
663 (not init-stack-pos)))
665 ;; VAR is a simple stack-allocated lexical variable
666 (push (assq var init-lexenv)
667 byte-compile-lexical-environment)
668 nil))))
670 (defun byte-compile-unbind (clauses init-lexenv
671 &optional lforminfo preserve-body-value)
672 "Emit byte-codes to unbind the variables bound by CLAUSES.
673 CLAUSES is a `let'-style variable binding list. INIT-LEXENV should be a
674 lexical-environment alist describing the positions of the init value that
675 have been pushed on the stack, and LFORMINFO should be information about
676 the lexical variables that were bound. If PRESERVE-BODY-VALUE is true,
677 then an additional value on the top of the stack, above any lexical binding
678 slots, is preserved, so it will be on the top of the stack after all
679 binding slots have been popped."
680 ;; Unbind dynamic variables
681 (let ((num-dynamic-bindings 0))
682 (if lforminfo
683 (dolist (clause clauses)
684 (unless (assq (if (consp clause) (car clause) clause)
685 (byte-compile-lforminfo-vars lforminfo))
686 (setq num-dynamic-bindings (1+ num-dynamic-bindings))))
687 (setq num-dynamic-bindings (length clauses)))
688 (unless (zerop num-dynamic-bindings)
689 (byte-compile-out 'byte-unbind num-dynamic-bindings)))
690 ;; Pop lexical variables off the stack, possibly preserving the
691 ;; return value of the body.
692 (when init-lexenv
693 ;; INIT-LEXENV contains all init values left on the stack
694 (byte-compile-discard (length init-lexenv) preserve-body-value)))
697 (provide 'byte-lexbind)
699 ;;; byte-lexbind.el ends here