Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv10563
Modified Files: compiler.lisp Log Message: For funobjs with &key arguments, have the keyword constants be reliably placed in proper sequence at the tail end of the funobj-constants list. This in preparation for improved &key arguments parsing.
--- /project/movitz/cvsroot/movitz/compiler.lisp 2006/05/05 18:37:32 1.170 +++ /project/movitz/cvsroot/movitz/compiler.lisp 2006/05/26 18:39:48 1.171 @@ -8,7 +8,7 @@ ;;;; Created at: Wed Oct 25 12:30:49 2000 ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: compiler.lisp,v 1.170 2006/05/05 18:37:32 ffjeld Exp $ +;;;; $Id: compiler.lisp,v 1.171 2006/05/26 18:39:48 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------
@@ -768,13 +768,18 @@
(defun finalize-funobj (funobj) "Calculate funobj's constants, jumpers." - (loop with all-constants-plist = () and all-jumper-sets = () + (loop with all-key-args-constants = nil + with all-constants-plist = () and all-jumper-sets = () for (nil . function-env) in (function-envs funobj) - ;; (borrowed-bindings body-code) in code-specs + ;; (borrowed-bindings body-code) in code-specs as body-code = (extended-code function-env) - as (const-plist jumper-sets) = + as (const-plist jumper-sets key-args-constants) = (multiple-value-list (find-code-constants-and-jumpers body-code)) - do (loop for (constant usage) on const-plist by #'cddr + do (when key-args-constants + (assert (not all-key-args-constants) () + "only one &key parsing allowed per funobj.") + (setf all-key-args-constants key-args-constants)) + (loop for (constant usage) on const-plist by #'cddr do (incf (getf all-constants-plist constant 0) usage)) (loop for (name set) on jumper-sets by #'cddr do (assert (not (getf all-jumper-sets name)) () @@ -783,6 +788,7 @@ finally (multiple-value-bind (const-list num-jumpers jumpers-map) (layout-funobj-vector all-constants-plist + all-key-args-constants all-jumper-sets (length (borrowed-bindings funobj))) (setf (movitz-funobj-num-jumpers funobj) num-jumpers @@ -2704,7 +2710,7 @@
(defun find-code-constants-and-jumpers (code &key include-programs) "Return code's constants (a plist of constants and their usage-counts) and jumper-sets." - (let (jumper-sets constants) + (let (jumper-sets constants key-args-set) (labels ((process-binding (binding) "Some bindings are really references to constants." (typecase binding @@ -2743,6 +2749,8 @@ (assert (not (getf jumper-sets name)) () "Duplicate jumper declaration for ~S." name) (setf (getf jumper-sets name) set))) + (:declare-key-arg-set + (setf key-args-set (cdr instruction))) (t (when (listp instruction) (dolist (binding (find-read-bindings instruction)) (process-binding binding))))) @@ -2750,9 +2758,21 @@ (when sub (process sub)))))) (process code) (map nil #'process include-programs)) - (values constants jumper-sets))) + (if (not key-args-set) + (values constants jumper-sets nil) + (loop with key-args-constants = nil + for (object count) on constants by #'cddr + if (not (member object key-args-set)) + append (list object count) into non-key-constants + else + do (setf key-args-constants + (merge 'list key-args-constants (list (cons object count)) #'< + :key (lambda (x) + (position (car x) key-args-set)))) + finally + (return (values non-key-constants jumper-sets key-args-constants))))))
-(defun layout-funobj-vector (constants jumper-sets num-borrowing-slots) +(defun layout-funobj-vector (constants key-args-constants jumper-sets num-borrowing-slots) (let* ((jumpers (loop with x for set in (cdr jumper-sets) by #'cddr unless (search set x) @@ -2762,11 +2782,12 @@ (values (append jumpers (make-list num-borrowing-slots :initial-element *movitz-nil*) (mapcar (lambda (x) (movitz-read (car x))) - (sort (loop for (constant count) on constants by #'cddr - unless (or (eq constant *movitz-nil*) - (eq constant (image-t-symbol *image*))) - collect (cons constant count)) - #'< :key #'cdr))) + (append (sort (loop for (constant count) on constants by #'cddr + unless (or (eq constant *movitz-nil*) + (eq constant (image-t-symbol *image*))) + collect (cons constant count)) + #'< :key #'cdr) + key-args-constants))) num-jumpers (loop for (name set) on jumper-sets by #'cddr collect (cons name set))))) @@ -2808,6 +2829,8 @@ (t (case (instruction-is i) ((nil) (return nil)) ; a label, most likely + ((:declare-key-arg-set :declare-label-set) + nil) ((:lexical-control-transfer :load-lambda) (return nil)) ; not sure about these. ((:call) @@ -4014,7 +4037,9 @@ (list* (append pf (car sub-instr)) (cdr sub-instr))) (t (list* pf sub-instr)))))))) - (:declare-label-set nil) + ((:declare-label-set + :declare-key-arg-set) + nil) (:local-function-init (destructuring-bind (function-binding) (operands instruction) @@ -4956,63 +4981,72 @@ (t #+ignore (pushnew (movitz-print (movitz-funobj-name funobj)) (aref *xx* (length key-vars))) - (loop with rest-binding = (movitz-binding rest-var env) - for key-var in key-vars - as key-var-name = (decode-keyword-formal key-var) - as binding = (movitz-binding key-var-name env) - as supplied-p-var = (optional-function-argument-supplied-p-var binding) - as supplied-p-binding = (movitz-binding supplied-p-var env) - and keyword-ok-label = (make-symbol (format nil "keyword-~A-ok" key-var-name)) - and keyword-not-supplied-label = (gensym) - do (assert binding) - if (not (movitz-constantp (optional-function-argument-init-form binding))) - append - `((:init-lexvar ,binding) - (:load-constant ,(movitz-read (keyword-function-argument-keyword-name binding)) :ecx) - (:load-lexical ,rest-binding :ebx) - (:call (:edi ,(global-constant-offset 'keyword-search))) - (:jz ',keyword-not-supplied-label) - (:store-lexical ,binding :eax :type t) - ,@(when supplied-p-var - `((:movl (:edi ,(global-constant-offset 't-symbol)) :eax) - (:init-lexvar ,supplied-p-binding - :init-with-register :eax - :init-with-type (eql ,(image-t-symbol *image*))))) - (:jmp ',keyword-ok-label) - ,keyword-not-supplied-label - ,@(when supplied-p-var - `((:store-lexical ,supplied-p-binding :edi :type null))) - ,@(compiler-call #'compile-form - :form (optional-function-argument-init-form binding) - :env env - :funobj funobj - :result-mode binding) - ,keyword-ok-label) - else append - (append (when supplied-p-var - `((:init-lexvar ,supplied-p-binding - :init-with-register :edi - :init-with-type null))) - (compiler-call #'compile-form - :form (list 'muerte.cl:quote - (eval-form (optional-function-argument-init-form binding) - env)) - :env env - :funobj funobj - :result-mode :eax) - `((:load-constant - ,(movitz-read (keyword-function-argument-keyword-name binding)) :ecx) - (:load-lexical ,rest-binding :ebx) - (:call (:edi ,(global-constant-offset 'keyword-search)))) - (when supplied-p-var - `((:jz ',keyword-not-supplied-label) - (:movl (:edi ,(global-constant-offset 't-symbol)) :ebx) - (:store-lexical ,supplied-p-binding :ebx - :type (eql ,(image-t-symbol *image*))) - ,keyword-not-supplied-label)) - `((:init-lexvar ,binding - :init-with-register :eax - :init-with-type t))))))) + #+ignore + (when key-vars + (warn "KEY-FUN: ~D" (length key-vars))) + (append + `((:declare-key-arg-set ,@(mapcar (lambda (k) + (movitz-read + (keyword-function-argument-keyword-name + (movitz-binding (decode-keyword-formal k) env)))) + key-vars))) + (loop with rest-binding = (movitz-binding rest-var env) + for key-var in key-vars + as key-var-name = (decode-keyword-formal key-var) + as binding = (movitz-binding key-var-name env) + as supplied-p-var = (optional-function-argument-supplied-p-var binding) + as supplied-p-binding = (movitz-binding supplied-p-var env) + and keyword-ok-label = (make-symbol (format nil "keyword-~A-ok" key-var-name)) + and keyword-not-supplied-label = (gensym) + do (assert binding) + if (not (movitz-constantp (optional-function-argument-init-form binding))) + append + `((:init-lexvar ,binding) + (:load-constant ,(movitz-read (keyword-function-argument-keyword-name binding)) :ecx) + (:load-lexical ,rest-binding :ebx) + (:call (:edi ,(global-constant-offset 'keyword-search))) + (:jz ',keyword-not-supplied-label) + (:store-lexical ,binding :eax :type t) + ,@(when supplied-p-var + `((:movl (:edi ,(global-constant-offset 't-symbol)) :eax) + (:init-lexvar ,supplied-p-binding + :init-with-register :eax + :init-with-type (eql ,(image-t-symbol *image*))))) + (:jmp ',keyword-ok-label) + ,keyword-not-supplied-label + ,@(when supplied-p-var + `((:store-lexical ,supplied-p-binding :edi :type null))) + ,@(compiler-call #'compile-form + :form (optional-function-argument-init-form binding) + :env env + :funobj funobj + :result-mode binding) + ,keyword-ok-label) + else append + (append (when supplied-p-var + `((:init-lexvar ,supplied-p-binding + :init-with-register :edi + :init-with-type null))) + (compiler-call #'compile-form + :form (list 'muerte.cl:quote + (eval-form (optional-function-argument-init-form binding) + env)) + :env env + :funobj funobj + :result-mode :eax) + `((:load-constant + ,(movitz-read (keyword-function-argument-keyword-name binding)) :ecx) + (:load-lexical ,rest-binding :ebx) + (:call (:edi ,(global-constant-offset 'keyword-search)))) + (when supplied-p-var + `((:jz ',keyword-not-supplied-label) + (:movl (:edi ,(global-constant-offset 't-symbol)) :ebx) + (:store-lexical ,supplied-p-binding :ebx + :type (eql ,(image-t-symbol *image*))) + ,keyword-not-supplied-label)) + `((:init-lexvar ,binding + :init-with-register :eax + :init-with-type t)))))))) need-normalized-ecx-p)))
(defun make-special-funarg-shadowing (env function-body)