diff options
author | Stefan Monnier <monnier@iro.umontreal.ca> | 2011-02-24 22:27:45 -0500 |
---|---|---|
committer | Stefan Monnier <monnier@iro.umontreal.ca> | 2011-02-24 22:27:45 -0500 |
commit | 876c194cbac17a6220dbf406b0a602325978011c (patch) | |
tree | f76a686c53e547a24039d9de2deaf68598e75518 /lisp/emacs-lisp/cconv.el | |
parent | cb9336bd977d3345b86234c36d45228f7fb27eec (diff) | |
download | emacs-876c194cbac17a6220dbf406b0a602325978011c.tar.gz |
Get rid of funvec.
* lisp/emacs-lisp/bytecomp.el (byte-compile-lapcode): Handle new form of
`byte-constant'.
(byte-compile-close-variables, displaying-byte-compile-warnings):
Add edebug spec.
(byte-compile-toplevel-file-form): New fun, split out of
byte-compile-file-form.
(byte-compile-from-buffer): Use it to avoid applying cconv
multiple times.
(byte-compile): Only strip `function' if it's present.
(byte-compile-lambda): Add `reserved-csts' argument.
Use new lexenv arg of byte-compile-top-level.
(byte-compile-reserved-constants): New var.
(byte-compile-constants-vector): Obey it.
(byte-compile-constants-vector): Handle new `byte-constant' form.
(byte-compile-top-level): Add args `lexenv' and `reserved-csts'.
(byte-compile-form): Don't check callargs here.
(byte-compile-normal-call): Do it here instead.
(byte-compile-push-unknown-constant)
(byte-compile-resolve-unknown-constant): Remove, unused.
(byte-compile-make-closure): Use `make-byte-code' rather than `curry',
putting the environment into the "constant" pool.
(byte-compile-get-closed-var): Use special byte-constant.
* lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Handle new
intermediate special form `internal-make-vector'.
(byte-optimize-lapcode): Handle new form of `byte-constant'.
* lisp/help-fns.el (describe-function-1): Don't handle funvecs.
* lisp/emacs-lisp/macroexp.el (macroexpand-all-1): Only convert quote to
function if the content is a lambda expression, not if it's a closure.
* emacs-lisp/eieio-come.el: Remove.
* lisp/emacs-lisp/eieio.el: Don't require eieio-comp.
(defmethod): Do a bit more work to find the body and wrap it into
a function before passing it to eieio-defmethod.
(eieio-defmethod): New arg `code' for it.
* lisp/emacs-lisp/debug.el (debugger-setup-buffer): Don't hide things in
debugger backtrace.
* lisp/emacs-lisp/cl-extra.el (cl-macroexpand-all): Use backquotes, and be
more careful when quoting a function value.
* lisp/emacs-lisp/cconv.el (cconv-freevars): Accept defvar/defconst.
(cconv-closure-convert-rec): Catch stray `internal-make-closure'.
* lisp/Makefile.in (COMPILE_FIRST): Compile pcase and cconv early.
* src/eval.c (Qcurry): Remove.
(funcall_funvec): Remove.
(funcall_lambda): Move new byte-code handling to reduce impact.
Treat all args as lexical in the case of lexbind.
(Fcurry): Remove.
* src/data.c (Qfunction_vector): Remove.
(Ffunvecp): Remove.
* src/lread.c (read1): Revert to calling make_byte_code here.
(read_vector): Don't call make_byte_code any more.
* src/lisp.h (enum pvec_type): Rename back to PVEC_COMPILED.
(XSETCOMPILED): Rename back from XSETFUNVEC.
(FUNVEC_SIZE): Remove.
(FUNVEC_COMPILED_TAG_P, FUNVEC_COMPILED_P): Remove.
(COMPILEDP): Rename back from FUNVECP.
* src/fns.c (Felt): Remove unexplained FUNVEC check.
* src/doc.c (Fdocumentation): Don't handle funvec.
* src/alloc.c (make_funvec, Ffunvec): Remove.
* doc/lispref/vol2.texi (Top):
* doc/lispref/vol1.texi (Top):
* doc/lispref/objects.texi (Programming Types, Funvec Type, Type Predicates):
* doc/lispref/functions.texi (Functions, What Is a Function, FunctionCurrying):
* doc/lispref/elisp.texi (Top): Remove mentions of funvec and curry.
Diffstat (limited to 'lisp/emacs-lisp/cconv.el')
-rw-r--r-- | lisp/emacs-lisp/cconv.el | 43 |
1 files changed, 18 insertions, 25 deletions
diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el index 6aa4b7e0a61..bc7ecb1ad55 100644 --- a/lisp/emacs-lisp/cconv.el +++ b/lisp/emacs-lisp/cconv.el @@ -47,19 +47,14 @@ ;; (lambda (v1 ...) ... fv1 fv2 ...) => (lambda (v1 ... fv1 fv2 ) ... fv1 fv2 .) ;; if the function is suitable for lambda lifting (if all calls are known) ;; -;; (lambda (v1 ...) ... fv ...) => -;; (curry (lambda (env v1 ...) ... env ...) env) -;; if the function has only 1 free variable -;; -;; and finally -;; (lambda (v1 ...) ... fv1 fv2 ...) => -;; (curry (lambda (env v1 ..) .. (aref env 0) (aref env 1) ..) (vector fv1 fv2)) -;; if the function has 2 or more free variables. +;; (lambda (v0 ...) ... fv0 .. fv1 ...) => +;; (internal-make-closure (v0 ...) (fv1 ...) +;; ... (internal-get-closed-var 0) ... (internal-get-closed-var 1) ...) ;; ;; If the function has no free variables, we don't do anything. ;; ;; If a variable is mutated (updated by setq), and it is used in a closure -;; we wrap it's definition with list: (list val) and we also replace +;; we wrap its definition with list: (list val) and we also replace ;; var => (car var) wherever this variable is used, and also ;; (setq var value) => (setcar var value) where it is updated. ;; @@ -71,15 +66,12 @@ ;;; Code: ;;; TODO: +;; - pay attention to `interactive': its arg is run in an empty env. ;; - 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. -;; - Use abstract `make-closure' and `closure-ref' expressions, which bytecomp -;; should turn into building corresponding byte-code function. -;; - don't use `curry', instead build a new compiled-byte-code object -;; (merge the closure env into the static constants pool). ;; - warn about unused lexical vars. ;; - clean up cconv-closure-convert-rec, especially the `let' binding part. ;; - new byte codes for unwind-protect, catch, and condition-case so that @@ -184,8 +176,8 @@ Returns a list of free variables." ;; We call cconv-freevars only for functions(lambdas) ;; defun, defconst, defvar are not allowed to be inside ;; a function (lambda). - ;; FIXME: should be a byte-compile-report-error! - (error "Invalid form: %s inside a function" sym)) + ;; (error "Invalid form: %s inside a function" sym) + (cconv-freevars `(progn ,@(cddr form)) fvrs)) (`(,_ . ,body-forms) ; First element is (like) a function. (dolist (exp body-forms) @@ -537,6 +529,9 @@ Returns a form where all lambdas don't have any free variables." `(internal-make-closure ,vars ,envector . ,body-forms-new))))) + (`(internal-make-closure . ,_) + (error "Internal byte-compiler error: cconv called twice")) + (`(function . ,_) form) ; Same as quote. ;defconst, defvar @@ -599,20 +594,18 @@ Returns a form where all lambdas don't have any free variables." ;condition-case (`(condition-case ,var ,protected-form . ,handlers) - (let ((handlers-new '()) - (newform (cconv-closure-convert-rec + (let ((newform (cconv-closure-convert-rec `(function (lambda () ,protected-form)) emvrs fvrs envs lmenvs))) (setq fvrs (remq var fvrs)) - (dolist (handler handlers) - (push (list (car handler) - (cconv-closure-convert-rec - `(function (lambda (,(or var cconv--dummy-var)) - ,@(cdr handler))) - emvrs fvrs envs lmenvs)) - handlers-new)) `(condition-case :fun-body ,newform - ,@(nreverse handlers-new)))) + ,@(mapcar (lambda (handler) + (list (car handler) + (cconv-closure-convert-rec + (let ((arg (or var cconv--dummy-var))) + `(function (lambda (,arg) ,@(cdr handler)))) + emvrs fvrs envs lmenvs))) + handlers)))) (`(,(and head (or `catch `unwind-protect)) ,form . ,body) `(,head ,(cconv-closure-convert-rec form emvrs fvrs envs lmenvs) |