aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2011-02-21 18:40:54 -0500
committerStefan Monnier2011-02-21 18:40:54 -0500
commitcb9336bd977d3345b86234c36d45228f7fb27eec (patch)
treeb4b88a95c633e7d732b31f12a5cfc3f61d579e07
parentf619ad4ca2ce943d53589469c010e451afab97dd (diff)
downloademacs-cb9336bd977d3345b86234c36d45228f7fb27eec.tar.gz
emacs-cb9336bd977d3345b86234c36d45228f7fb27eec.zip
* lisp/emacs-lisp/cconv.el (cconv-closure-convert-rec): Let the byte
compiler choose the representation of closures. (cconv--env-var): Remove. * lisp/emacs-lisp/bytecomp.el (byte-compile--env-var): New var. (byte-compile-make-closure, byte-compile-get-closed-var): New functions. * lisp/cedet/semantic/wisent/comp.el (wisent-byte-compile-grammar): Macroexpand before passing to byte-compile-form.
-rw-r--r--lisp/ChangeLog9
-rw-r--r--lisp/cedet/ChangeLog5
-rw-r--r--lisp/cedet/semantic/wisent/comp.el16
-rw-r--r--lisp/emacs-lisp/bytecomp.el18
-rw-r--r--lisp/emacs-lisp/cconv.el57
5 files changed, 61 insertions, 44 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 4e2e87ab60f..f7a62bc8385 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,14 @@
12011-02-21 Stefan Monnier <monnier@iro.umontreal.ca> 12011-02-21 Stefan Monnier <monnier@iro.umontreal.ca>
2 2
3 * emacs-lisp/cconv.el (cconv-closure-convert-rec): Let the byte
4 compiler choose the representation of closures.
5 (cconv--env-var): Remove.
6 * emacs-lisp/bytecomp.el (byte-compile--env-var): New var.
7 (byte-compile-make-closure, byte-compile-get-closed-var):
8 New functions.
9
102011-02-21 Stefan Monnier <monnier@iro.umontreal.ca>
11
3 * subr.el (with-output-to-temp-buffer): New macro. 12 * subr.el (with-output-to-temp-buffer): New macro.
4 13
5 * simple.el (count-words-region): Don't use interactive-p. 14 * simple.el (count-words-region): Don't use interactive-p.
diff --git a/lisp/cedet/ChangeLog b/lisp/cedet/ChangeLog
index b6d5cff6b51..fa3f633d1ac 100644
--- a/lisp/cedet/ChangeLog
+++ b/lisp/cedet/ChangeLog
@@ -1,3 +1,8 @@
12011-02-21 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * semantic/wisent/comp.el (wisent-byte-compile-grammar):
4 Macroexpand before passing to byte-compile-form.
5
12011-01-13 Stefan Monnier <monnier@iro.umontreal.ca> 62011-01-13 Stefan Monnier <monnier@iro.umontreal.ca>
2 7
3 * srecode/srt-mode.el (srecode-template-mode): Use define-derived-mode. 8 * srecode/srt-mode.el (srecode-template-mode): Use define-derived-mode.
diff --git a/lisp/cedet/semantic/wisent/comp.el b/lisp/cedet/semantic/wisent/comp.el
index c3243c12923..6b473f9ad81 100644
--- a/lisp/cedet/semantic/wisent/comp.el
+++ b/lisp/cedet/semantic/wisent/comp.el
@@ -3452,15 +3452,13 @@ where:
3452 (if (wisent-automaton-p grammar) 3452 (if (wisent-automaton-p grammar)
3453 grammar ;; Grammar already compiled just return it 3453 grammar ;; Grammar already compiled just return it
3454 (wisent-with-context compile-grammar 3454 (wisent-with-context compile-grammar
3455 (let* ((gc-cons-threshold 1000000) 3455 (let* ((gc-cons-threshold 1000000))
3456 automaton)
3457 (garbage-collect) 3456 (garbage-collect)
3458 (setq wisent-new-log-flag t) 3457 (setq wisent-new-log-flag t)
3459 ;; Parse input grammar 3458 ;; Parse input grammar
3460 (wisent-parse-grammar grammar start-list) 3459 (wisent-parse-grammar grammar start-list)
3461 ;; Generate the LALR(1) automaton 3460 ;; Generate the LALR(1) automaton
3462 (setq automaton (wisent-parser-automaton)) 3461 (wisent-parser-automaton)))))
3463 automaton))))
3464 3462
3465;;;; -------------------------- 3463;;;; --------------------------
3466;;;; Byte compile input grammar 3464;;;; Byte compile input grammar
@@ -3476,7 +3474,15 @@ Automatically called by the Emacs Lisp byte compiler as a
3476 ;; automaton internal data structure. Then, because the internal 3474 ;; automaton internal data structure. Then, because the internal
3477 ;; data structure contains an obarray, convert it to a lisp form so 3475 ;; data structure contains an obarray, convert it to a lisp form so
3478 ;; it can be byte-compiled. 3476 ;; it can be byte-compiled.
3479 (byte-compile-form (wisent-automaton-lisp-form (eval form)))) 3477 (byte-compile-form
3478 ;; FIXME: we macroexpand here since `byte-compile-form' expects
3479 ;; macroexpanded code, but that's just a workaround: for lexical-binding
3480 ;; the lisp form should have to pass through closure-conversion and
3481 ;; `wisent-byte-compile-grammar' is called much too late for that.
3482 ;; Why isn't this `wisent-automaton-lisp-form' performed at
3483 ;; macroexpansion time? --Stef
3484 (macroexpand-all
3485 (wisent-automaton-lisp-form (eval form)))))
3480 3486
3481(put 'wisent-compile-grammar 'byte-compile 'wisent-byte-compile-grammar) 3487(put 'wisent-compile-grammar 'byte-compile 'wisent-byte-compile-grammar)
3482 3488
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 8892a27b29c..771306bb0e6 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -3339,6 +3339,24 @@ discarding."
3339 "Output byte codes to store the top-of-stack value at position STACK-POS in the stack." 3339 "Output byte codes to store the top-of-stack value at position STACK-POS in the stack."
3340 (byte-compile-out 'byte-stack-set (- byte-compile-depth (1+ stack-pos)))) 3340 (byte-compile-out 'byte-stack-set (- byte-compile-depth (1+ stack-pos))))
3341 3341
3342(byte-defop-compiler-1 internal-make-closure byte-compile-make-closure)
3343(byte-defop-compiler-1 internal-get-closed-var byte-compile-get-closed-var)
3344
3345(defconst byte-compile--env-var (make-symbol "env"))
3346
3347(defun byte-compile-make-closure (form)
3348 ;; FIXME: don't use `curry'!
3349 (byte-compile-form
3350 (unless for-effect
3351 `(curry (function (lambda (,byte-compile--env-var . ,(nth 1 form))
3352 . ,(nthcdr 3 form)))
3353 (vector . ,(nth 2 form))))
3354 for-effect))
3355
3356(defun byte-compile-get-closed-var (form)
3357 (byte-compile-form (unless for-effect
3358 `(aref ,byte-compile--env-var ,(nth 1 form)))
3359 for-effect))
3342 3360
3343;; Compile a function that accepts one or more args and is right-associative. 3361;; Compile a function that accepts one or more args and is right-associative.
3344;; We do it by left-associativity so that the operations 3362;; We do it by left-associativity so that the operations
diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el
index 66e5051c2f1..6aa4b7e0a61 100644
--- a/lisp/emacs-lisp/cconv.el
+++ b/lisp/emacs-lisp/cconv.el
@@ -71,6 +71,8 @@
71;;; Code: 71;;; Code:
72 72
73;;; TODO: 73;;; TODO:
74;; - canonize code in macro-expand so we don't have to handle (let (var) body)
75;; and other oddities.
74;; - Change new byte-code representation, so it directly gives the 76;; - Change new byte-code representation, so it directly gives the
75;; number of mandatory and optional arguments as well as whether or 77;; number of mandatory and optional arguments as well as whether or
76;; not there's a &rest arg. 78;; not there's a &rest arg.
@@ -229,7 +231,6 @@ Returns a form where all lambdas don't have any free variables."
229 res)) 231 res))
230 232
231(defconst cconv--dummy-var (make-symbol "ignored")) 233(defconst cconv--dummy-var (make-symbol "ignored"))
232(defconst cconv--env-var (make-symbol "env"))
233 234
234(defun cconv--set-diff (s1 s2) 235(defun cconv--set-diff (s1 s2)
235 "Return elements of set S1 that are not in set S2." 236 "Return elements of set S1 that are not in set S2."
@@ -494,32 +495,18 @@ Returns a form where all lambdas don't have any free variables."
494 (envector nil)) 495 (envector nil))
495 (when fv 496 (when fv
496 ;; Here we form our environment vector. 497 ;; Here we form our environment vector.
497 ;; If outer closure contains all 498
498 ;; free variables of this function(and nothing else) 499 (dolist (elm fv)
499 ;; then we use the same environment vector as for outer closure, 500 (push
500 ;; i.e. we leave the environment vector unchanged, 501 (cconv-closure-convert-rec
501 ;; otherwise we build a new environment vector. 502 ;; Remove `elm' from `emvrs' for this call because in case
502 (if (eq (length envs) (length fv)) 503 ;; `elm' is a variable that's wrapped in a cons-cell, we
503 (let ((fv-temp fv)) 504 ;; want to put the cons-cell itself in the closure, rather
504 (while (and fv-temp leave) 505 ;; than just a copy of its current content.
505 (when (not (memq (car fv-temp) fvrs-new)) (setq leave nil)) 506 elm (remq elm emvrs) fvrs envs lmenvs)
506 (setq fv-temp (cdr fv-temp)))) 507 envector)) ; Process vars for closure vector.
507 (setq leave nil)) 508 (setq envector (reverse envector))
508 509 (setq envs fv)
509 (if (not leave)
510 (progn
511 (dolist (elm fv)
512 (push
513 (cconv-closure-convert-rec
514 ;; Remove `elm' from `emvrs' for this call because in case
515 ;; `elm' is a variable that's wrapped in a cons-cell, we
516 ;; want to put the cons-cell itself in the closure, rather
517 ;; than just a copy of its current content.
518 elm (remq elm emvrs) fvrs envs lmenvs)
519 envector)) ; Process vars for closure vector.
520 (setq envector (reverse envector))
521 (setq envs fv))
522 (setq envector `(,cconv--env-var))) ; Leave unchanged.
523 (setq fvrs-new fv)) ; Update substitution list. 510 (setq fvrs-new fv)) ; Update substitution list.
524 511
525 (setq emvrs (cconv--set-diff emvrs vars)) 512 (setq emvrs (cconv--set-diff emvrs vars))
@@ -546,15 +533,9 @@ Returns a form where all lambdas don't have any free variables."
546 ((null envector) 533 ((null envector)
547 `(function (lambda ,vars . ,body-forms-new))) 534 `(function (lambda ,vars . ,body-forms-new)))
548 ; 1 free variable - do not build vector 535 ; 1 free variable - do not build vector
549 ((null (cdr envector))
550 `(curry
551 (function (lambda (,cconv--env-var . ,vars) . ,body-forms-new))
552 ,(car envector)))
553 ; >=2 free variables - build vector
554 (t 536 (t
555 `(curry 537 `(internal-make-closure
556 (function (lambda (,cconv--env-var . ,vars) . ,body-forms-new)) 538 ,vars ,envector . ,body-forms-new)))))
557 (vector . ,envector))))))
558 539
559 (`(function . ,_) form) ; Same as quote. 540 (`(function . ,_) form) ; Same as quote.
560 541
@@ -714,10 +695,8 @@ Returns a form where all lambdas don't have any free variables."
714 (let ((free (memq form fvrs))) 695 (let ((free (memq form fvrs)))
715 (if free ;form is a free variable 696 (if free ;form is a free variable
716 (let* ((numero (- (length fvrs) (length free))) 697 (let* ((numero (- (length fvrs) (length free)))
717 (var (if (null (cdr envs)) 698 ;; Replace form => (aref env #)
718 cconv--env-var 699 (var `(internal-get-closed-var ,numero)))
719 ;; Replace form => (aref env #)
720 `(aref ,cconv--env-var ,numero))))
721 (if (memq form emvrs) ; form => (car (aref env #)) if mutable 700 (if (memq form emvrs) ; form => (car (aref env #)) if mutable
722 `(car ,var) 701 `(car ,var)
723 var)) 702 var))