]> git.eshelyaron.com Git - emacs.git/commitdiff
* lisp/emacs-lisp/cconv.el (cconv-closure-convert-rec): Let the byte
authorStefan Monnier <monnier@iro.umontreal.ca>
Mon, 21 Feb 2011 23:40:54 +0000 (18:40 -0500)
committerStefan Monnier <monnier@iro.umontreal.ca>
Mon, 21 Feb 2011 23:40:54 +0000 (18:40 -0500)
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.

lisp/ChangeLog
lisp/cedet/ChangeLog
lisp/cedet/semantic/wisent/comp.el
lisp/emacs-lisp/bytecomp.el
lisp/emacs-lisp/cconv.el

index 4e2e87ab60fa259563e4333726d88594c696a00b..f7a62bc8385d0f9e0731ec619403c4f96063974d 100644 (file)
@@ -1,3 +1,12 @@
+2011-02-21  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * emacs-lisp/cconv.el (cconv-closure-convert-rec): Let the byte
+       compiler choose the representation of closures.
+       (cconv--env-var): Remove.
+       * emacs-lisp/bytecomp.el (byte-compile--env-var): New var.
+       (byte-compile-make-closure, byte-compile-get-closed-var):
+       New functions.
+
 2011-02-21  Stefan Monnier  <monnier@iro.umontreal.ca>
 
        * subr.el (with-output-to-temp-buffer): New macro.
index b6d5cff6b5108a02a1b843fa2f1b397e73c2e083..fa3f633d1acd3526d19334d70269a4f9299da489 100644 (file)
@@ -1,3 +1,8 @@
+2011-02-21  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * semantic/wisent/comp.el (wisent-byte-compile-grammar):
+       Macroexpand before passing to byte-compile-form.
+
 2011-01-13  Stefan Monnier  <monnier@iro.umontreal.ca>
 
        * srecode/srt-mode.el (srecode-template-mode): Use define-derived-mode.
index c3243c12923df74a0444e08dc4139bc2c3603600..6b473f9ad817b175b99f6f355606905724158036 100644 (file)
@@ -3452,15 +3452,13 @@ where:
   (if (wisent-automaton-p grammar)
       grammar ;; Grammar already compiled just return it
     (wisent-with-context compile-grammar
-      (let* ((gc-cons-threshold 1000000)
-             automaton)
+      (let* ((gc-cons-threshold 1000000))
         (garbage-collect)
        (setq wisent-new-log-flag t)
        ;; Parse input grammar
        (wisent-parse-grammar grammar start-list)
        ;; Generate the LALR(1) automaton
-       (setq automaton (wisent-parser-automaton))
-       automaton))))
+       (wisent-parser-automaton)))))
 \f
 ;;;; --------------------------
 ;;;; Byte compile input grammar
@@ -3476,7 +3474,15 @@ Automatically called by the Emacs Lisp byte compiler as a
   ;; automaton internal data structure.  Then, because the internal
   ;; data structure contains an obarray, convert it to a lisp form so
   ;; it can be byte-compiled.
-  (byte-compile-form (wisent-automaton-lisp-form (eval form))))
+  (byte-compile-form
+   ;; FIXME: we macroexpand here since `byte-compile-form' expects
+   ;; macroexpanded code, but that's just a workaround: for lexical-binding
+   ;; the lisp form should have to pass through closure-conversion and
+   ;; `wisent-byte-compile-grammar' is called much too late for that.
+   ;; Why isn't this `wisent-automaton-lisp-form' performed at
+   ;; macroexpansion time?  --Stef
+   (macroexpand-all
+    (wisent-automaton-lisp-form (eval form)))))
 
 (put 'wisent-compile-grammar 'byte-compile 'wisent-byte-compile-grammar)
 
index 8892a27b29c37a878587bf46a32f261c8d8c1340..771306bb0e68c016fe7b01d22413771411f11e40 100644 (file)
@@ -3339,6 +3339,24 @@ discarding."
   "Output byte codes to store the top-of-stack value at position STACK-POS in the stack."
   (byte-compile-out 'byte-stack-set (- byte-compile-depth (1+ stack-pos))))
 
+(byte-defop-compiler-1 internal-make-closure byte-compile-make-closure)
+(byte-defop-compiler-1 internal-get-closed-var byte-compile-get-closed-var)
+
+(defconst byte-compile--env-var (make-symbol "env"))
+
+(defun byte-compile-make-closure (form)
+  ;; FIXME: don't use `curry'!
+  (byte-compile-form
+   (unless for-effect
+     `(curry (function (lambda (,byte-compile--env-var . ,(nth 1 form))
+                         . ,(nthcdr 3 form)))
+             (vector . ,(nth 2 form))))
+   for-effect))
+
+(defun byte-compile-get-closed-var (form)
+  (byte-compile-form (unless for-effect
+                       `(aref ,byte-compile--env-var ,(nth 1 form)))
+                     for-effect))
 
 ;; Compile a function that accepts one or more args and is right-associative.
 ;; We do it by left-associativity so that the operations
index 66e5051c2f13d6d8683c09a563e06f0857166e15..6aa4b7e0a6145a845d6adf94eebb6704c467d38b 100644 (file)
@@ -71,6 +71,8 @@
 ;;; Code:
 
 ;;; TODO:
+;; - canonize code in macro-expand so we don't have to handle (let (var) body)
+;;   and other oddities.
 ;; - Change new byte-code representation, so it directly gives the
 ;;   number of mandatory and optional arguments as well as whether or
 ;;   not there's a &rest arg.
@@ -229,7 +231,6 @@ Returns a form where all lambdas don't have any free variables."
     res))
 
 (defconst cconv--dummy-var (make-symbol "ignored"))
-(defconst cconv--env-var (make-symbol "env"))
 
 (defun cconv--set-diff (s1 s2)
   "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."
             (envector nil))
        (when fv
          ;; Here we form our environment vector.
-         ;; If outer closure contains all
-         ;; free variables of this function(and nothing else)
-         ;; then we use the same environment vector as for outer closure,
-         ;; i.e. we leave the environment vector unchanged,
-         ;; otherwise we build a new environment vector.
-         (if (eq (length envs) (length fv))
-             (let ((fv-temp fv))
-               (while (and fv-temp leave)
-                 (when (not (memq (car fv-temp) fvrs-new)) (setq leave nil))
-                 (setq fv-temp (cdr fv-temp))))
-           (setq leave nil))
-
-         (if (not leave)
-             (progn
-               (dolist (elm fv)
-                 (push
-                  (cconv-closure-convert-rec
-                   ;; Remove `elm' from `emvrs' for this call because in case
-                   ;; `elm' is a variable that's wrapped in a cons-cell, we
-                   ;; want to put the cons-cell itself in the closure, rather
-                   ;; than just a copy of its current content.
-                   elm (remq elm emvrs) fvrs envs lmenvs)
-                  envector))         ; Process vars for closure vector.
-               (setq envector (reverse envector))
-               (setq envs fv))
-           (setq envector `(,cconv--env-var))) ; Leave unchanged.
+
+         (dolist (elm fv)
+           (push
+            (cconv-closure-convert-rec
+             ;; Remove `elm' from `emvrs' for this call because in case
+             ;; `elm' is a variable that's wrapped in a cons-cell, we
+             ;; want to put the cons-cell itself in the closure, rather
+             ;; than just a copy of its current content.
+             elm (remq elm emvrs) fvrs envs lmenvs)
+            envector))              ; Process vars for closure vector.
+         (setq envector (reverse envector))
+         (setq envs fv)
          (setq fvrs-new fv))                ; Update substitution list.
 
        (setq emvrs (cconv--set-diff emvrs vars))
@@ -546,15 +533,9 @@ Returns a form where all lambdas don't have any free variables."
         ((null envector)
          `(function (lambda ,vars . ,body-forms-new)))
                                ; 1 free variable - do not build vector
-        ((null (cdr envector))
-         `(curry
-           (function (lambda (,cconv--env-var . ,vars) . ,body-forms-new))
-           ,(car envector)))
-                                   ; >=2 free variables - build vector
         (t
-         `(curry
-           (function (lambda (,cconv--env-var . ,vars) . ,body-forms-new))
-           (vector . ,envector))))))
+         `(internal-make-closure
+           ,vars ,envector . ,body-forms-new)))))
 
     (`(function . ,_) form)             ; Same as quote.
 
@@ -714,10 +695,8 @@ Returns a form where all lambdas don't have any free variables."
      (let ((free (memq form fvrs)))
        (if free                         ;form is a free variable
            (let* ((numero (- (length fvrs) (length free)))
-                  (var (if (null (cdr envs))
-                           cconv--env-var
-                         ;; Replace form => (aref env #)
-                         `(aref ,cconv--env-var ,numero))))
+                  ;; Replace form => (aref env #)
+                  (var `(internal-get-closed-var ,numero)))
              (if (memq form emvrs) ; form => (car (aref env #)) if mutable
                  `(car ,var)
                var))