[movitz-cvs] CVS movitz

ffjeld ffjeld at common-lisp.net
Mon Feb 19 20:24:38 UTC 2007


Update of /project/movitz/cvsroot/movitz
In directory clnet:/tmp/cvs-serv30554

Modified Files:
	compiler.lisp 
Log Message:
First implementation of new &key-parsing strategy.


--- /project/movitz/cvsroot/movitz/compiler.lisp	2007/02/17 19:24:28	1.174
+++ /project/movitz/cvsroot/movitz/compiler.lisp	2007/02/19 20:24:38	1.175
@@ -8,7 +8,7 @@
 ;;;; Created at:    Wed Oct 25 12:30:49 2000
 ;;;; Distribution:  See the accompanying file COPYING.
 ;;;;                
-;;;; $Id: compiler.lisp,v 1.174 2007/02/17 19:24:28 ffjeld Exp $
+;;;; $Id: compiler.lisp,v 1.175 2007/02/19 20:24:38 ffjeld Exp $
 ;;;;                
 ;;;;------------------------------------------------------------------
 
@@ -789,6 +789,9 @@
 	(multiple-value-bind (const-list num-jumpers jumpers-map borrower-map)
 	    (layout-funobj-vector all-constants-plist
 				  all-key-args-constants
+				  #+ignore (mapcar (lambda (x)
+						     (cons (movitz-read x) 1))
+						   '(:a :b :c :d))
 				  all-jumper-sets
 				  (borrowed-bindings funobj))
 	  (setf (movitz-funobj-num-jumpers funobj) num-jumpers
@@ -2655,7 +2658,7 @@
 (defun make-binding-map () nil)
 
 (defun new-binding-located-p (binding map)
-  (check-type binding (or binding (cons keyword binding)))
+  (check-type binding (or null binding (cons keyword binding)))
   (and (assoc binding map) t))
 
 (defun frame-map-size (map)
@@ -2830,19 +2833,9 @@
 			(when sub (process sub))))))
       (process code)
       (map nil #'process include-programs))
-    (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))))))
+    (loop for key-arg in key-args-set
+	do (remf constants key-arg))
+    (values constants jumper-sets key-args-set)))
 
 (defun layout-funobj-vector (constants key-args-constants jumper-sets borrowing-bindings)
   (let* ((jumpers (loop with x
@@ -2851,7 +2844,12 @@
 		      do (setf x (nconc x (copy-list set)))
 		      finally (return x)))
 	 (num-jumpers (length jumpers))
-	 (stuff (append key-args-constants
+	 (stuff (append (mapcar (lambda (c)
+				  (cons c 1))
+				key-args-constants)
+			(when key-args-constants
+			  (list (cons (movitz-read 0)
+				      1)))
 			(sort (loop for (constant count) on constants by #'cddr
 				  unless (or (eq constant *movitz-nil*)
 					     (eq constant (image-t-symbol *image*)))
@@ -3136,9 +3134,11 @@
 			       (funobj-binding))))
 			  (:init-lexvar
 			   (destructuring-bind (binding &key init-with-register init-with-type
-							     protect-registers protect-carry)
+							     protect-registers protect-carry
+							     shared-reference-p)
 			       (cdr instruction)
-			     (declare (ignore protect-registers protect-carry init-with-type))
+			     (declare (ignore protect-registers protect-carry init-with-type
+					      shared-reference-p))
 			     (cond
 			      ((not init-with-register)
 			       (take-note-of-init binding pc))
@@ -3320,6 +3320,9 @@
 		 (when (and (binding-lended-p binding)
 			    (not (typep binding 'borrowed-binding))
 			    (not (getf (binding-lending binding) :stack-cons-location)))
+		   #+ignore
+		   (assert (not (typep binding 'keyword-function-argument)) ()
+		     "Can't lend keyword binding ~S." binding)
 		   ;; (warn "assigning lending-cons for ~W at ~D" binding stack-frame-position)
 		   (let ((cons-pos (frame-map-next-free-location frame-map function-env 2)))
 		     (setf (new-binding-location (cons :lended-cons binding) frame-map)
@@ -3346,6 +3349,40 @@
 			(plusp (car (gethash binding var-counts '(0)))))
 	       (setf (new-binding-location binding frame-map)
 		 (forwarding-binding-target binding))))	     
+      ;; Keyword bindings
+      (flet ((set-exclusive-location (binding location)
+	       (assert (not (rassoc location frame-map))
+		   () "Fixed location ~S for ~S is taken by ~S."
+		   location binding (rassoc location frame-map))
+	       (setf (new-binding-location binding frame-map) location)))
+	(when (key-vars-p function-env)
+	  (when (= 0 (rest-args-position function-env))
+	    (set-exclusive-location (loop for var in (required-vars function-env)
+					as binding = (movitz-binding var function-env nil)
+					thereis (when (= 0 (function-argument-argnum binding))
+						  binding))
+				    1))
+	  (when (>= 1 (rest-args-position function-env))
+	    (set-exclusive-location (loop for var in (required-vars function-env)
+					as binding = (movitz-binding var function-env nil)
+					thereis (when (= 1 (function-argument-argnum binding))
+						  binding))
+				    2)))
+	(loop for key-var in (key-vars function-env)
+	    as key-binding =
+	      (or (movitz-binding key-var function-env nil)
+		  (error "No binding for key-var ~S." key-var))
+	    as supplied-p-binding =
+	      (when (optional-function-argument-supplied-p-var key-binding)
+		(or (movitz-binding (optional-function-argument-supplied-p-var key-binding)
+				    function-env nil)
+		    (error "No binding for supplied-p-var ~S."
+			   (optional-function-argument-supplied-p-var key-binding))))
+	    as location upfrom 3 by 2
+	    do (set-exclusive-location key-binding location)
+	       (assert supplied-p-binding)
+	       (set-exclusive-location supplied-p-binding (1+ location))))
+      ;; Now, use assing-env-bindings on the remaining bindings.
       (loop for env in
 	    (loop with z = nil
 		for b being the hash-keys of var-counts using (hash-value c)
@@ -4293,7 +4330,7 @@
   "From a (normal) <lambda-list>, add bindings to <env>."
   (let ((arg-pos 0))
     (multiple-value-bind (required-vars optional-vars rest-var key-vars auxes allow-p
-			  min-args max-args edx-var oddeven key-p)
+			  min-args max-args edx-var oddeven key-vars-p)
 	(decode-normal-lambda-list lambda-list)
       (declare (ignore auxes))
       (setf (min-args env) min-args
@@ -4356,6 +4393,8 @@
 		    (movitz-env-add-binding env (make-instance 'supplied-p-function-argument
 					       :name supplied-p-parameter)))
 		  formal)))
+	(when (or rest-var key-vars-p)
+	  (setf (rest-args-position env) arg-pos))
 	(when rest-var
 	  (check-type rest-var symbol)
 	  (let ((formal (shadow-when-special rest-var env)))
@@ -4363,11 +4402,30 @@
 	    (movitz-env-add-binding env (make-instance 'rest-function-argument
 				       :name formal
 				       :argnum (post-incf arg-pos)))))
-	(when key-p
-	  ;; We need to check at run-time whether keyword checking is supressed or not.
-	  (setf (allow-other-keys-var env)
-	    (movitz-env-add-binding env (make-instance 'located-binding
-					  :name (gensym "allow-other-keys-var-")))))
+;;;	(when key-vars-p
+;;;	  ;; We need to check at run-time whether keyword checking is supressed or not.
+;;;	  (setf (allow-other-keys-var env)
+;;;	    (movitz-env-add-binding env (make-instance 'located-binding
+;;;					  :name (gensym "allow-other-keys-var-")))))
+	(when key-vars-p
+	  (setf (key-vars-p env) t)
+	  (when (>= 1 (rest-args-position env))
+	    (let ((name (gensym "save-ebx-for-keyscan")))
+	      (setf (required-vars env)
+		(append (required-vars env)
+			(list name)))
+	      (movitz-env-add-binding env (make-instance 'register-required-function-argument
+					    :name name
+					    :argnum 1
+					    :declarations '(muerte.cl:ignore)))
+	      (setf (movitz-env-get name 'ignore nil env) t)))
+	  (when (= 0 (rest-args-position env))
+	    (let ((name (gensym "save-eax-for-keyscan")))
+	      (push name (required-vars env))
+	      (movitz-env-add-binding env (make-instance 'register-required-function-argument
+					    :name name
+					    :argnum 0))
+	      (setf (movitz-env-get name 'ignore nil env) t))))
 	(setf (key-vars env)
 	  (loop for spec in key-vars
 	      with rest-var-name =
@@ -4379,21 +4437,23 @@
 							 :argnum (post-incf arg-pos)))
 			   name)))
 	      collect
-		(multiple-value-bind (formal keyword-name init-form supplied-p-parameter)
+		(multiple-value-bind (formal keyword-name init-form supplied-p)
 		    (decode-keyword-formal spec)
-		  (setf formal (shadow-when-special formal env))
-		  (movitz-env-add-binding env (make-instance 'keyword-function-argument
-					     :name formal
-					     'init-form init-form
-					     'supplied-p-var supplied-p-parameter
-					     :keyword-name keyword-name
-					     :rest-var-name rest-var-name))
-		  (when supplied-p-parameter
-		    (setf supplied-p-parameter
-		      (shadow-when-special supplied-p-parameter env))
+		  (let ((formal
+			 (shadow-when-special formal env))
+			(supplied-p-parameter
+			 (or supplied-p
+			     (gensym "supplied-p-"))))
+		    (movitz-env-add-binding env (make-instance 'keyword-function-argument
+						  :name formal
+						  'init-form init-form
+						  'supplied-p-var supplied-p-parameter
+						  :keyword-name keyword-name
+						  :rest-var-name rest-var-name))
 		    (movitz-env-add-binding env (make-instance 'supplied-p-function-argument
-					       :name supplied-p-parameter)))
-		  formal)))
+						  :name (shadow-when-special supplied-p-parameter env)))
+		    formal))))
+	#+ignore
 	(multiple-value-bind (key-decode-map key-decode-shift)
 	    (best-key-encode (key-vars env))  
 	  (setf (key-decode-map env) key-decode-map
@@ -4508,7 +4568,7 @@
 		 (edx-location
 		  (and (edx-var env)
 		       (new-binding-location (edx-var env) frame-map :default nil))))
-	    ;; (warn "l0: ~S, l1: ~S" location-0 location-1)
+	    #+ignore (warn "l0: ~S, l1: ~S" location-0 location-1)
 	    (assert (not (and location-0
 			      (eql location-0 location-1))) ()
 	      "Compiler bug: two bindings in same location.")
@@ -4775,8 +4835,7 @@
 	(required-vars (required-vars env))
 	(optional-vars (optional-vars env))
 	(rest-var (rest-var env))
-	(key-vars (key-vars env))
-	(allow-other-keys-p (allow-other-keys-p env)))
+	(key-vars (key-vars env)))
     (when (and (not rest-var)
 	       key-vars
 	       (not (= 1 (length key-vars))))
@@ -4912,148 +4971,81 @@
 			  :init-with-type list))))
       (when key-vars
 	(play-with-keys key-vars))
-      (cond
+      (when (key-vars-p env)
        ;; &key processing..
-       ((and (not rest-var)
-	     (= 1 (length key-vars)))
-	(let* ((key-var-name (decode-keyword-formal (first key-vars)))
-	       (binding (movitz-binding key-var-name env))
-	       (position (function-argument-argnum
-			  (movitz-binding (keyword-function-argument-rest-var-name binding) env)))
-	       (supplied-p-var (optional-function-argument-supplied-p-var binding))
-	       (supplied-p-binding (movitz-binding supplied-p-var env)))
-	  (setq need-normalized-ecx-p t)
-	  (cond
-	   ((and (movitz-constantp (optional-function-argument-init-form binding))
-		 (< 1 position))
-	    `((:init-lexvar ,binding)
-	      ,@(when supplied-p-var
-		  `((:init-lexvar ,supplied-p-binding)))
-	      ,@(compiler-call #'compile-form
-		  :form (list 'muerte.cl:quote
-			      (eval-form (optional-function-argument-init-form binding) env nil))
-		  :funobj funobj
-		  :env env
-		  :result-mode :ebx)
-	      ,@(when supplied-p-var
-		  `((:store-lexical ,supplied-p-binding :edi :type null)))
-	      (:arg-cmp ,(+ 2 position))
-	      (:jb 'default-done)
-	      (:movl (:ebp (:ecx 4) ,(* -4 (1- position))) :eax)
-	      (:load-constant ,(movitz-read (keyword-function-argument-keyword-name binding)) :eax :op :cmpl)
-	      ,@(if allow-other-keys-p
-		    `((:jne 'default-done))
-		  `((:jne '(:sub-program (unknown-key) (:int 101)))))
-	      ,@(when supplied-p-var
-		  `((:movl (:edi ,(global-constant-offset 't-symbol)) :eax)
-		    (:store-lexical ,supplied-p-binding :eax
-				    :type (eql ,(image-t-symbol *image*)))))
-	      (:movl (:ebp (:ecx 4) ,(* -4 (1- (1+ position)))) :ebx)
-	      default-done
-	      (:store-lexical ,binding :ebx :type t)))
-	   (t `((:init-lexvar ,binding)
-		,@(when supplied-p-var
-		    `((:init-lexvar ,supplied-p-binding)))
-		(:arg-cmp ,(+ 2 position))
-		(:jb '(:sub-program (default)
-		       ,@(append
-			  (when supplied-p-var
-			    `((:store-lexical ,supplied-p-binding :edi
-					      :type null)))
-			  (compiler-call #'compile-form
-			    :form (optional-function-argument-init-form binding)
-			    :funobj funobj
-			    :env env
-			    :result-mode :ebx)
-			  `((:jmp 'default-done)))))
-		,@(case position
-		    (0 `((:load-constant ,(movitz-read (keyword-function-argument-keyword-name binding))
-					 :eax :op :cmpl)))
-		    (1 `((:load-constant ,(movitz-read (keyword-function-argument-keyword-name binding))
-					 :ebx :op :cmpl)))
-		    (t `((:load-constant ,(movitz-read (keyword-function-argument-keyword-name binding))
-					 :eax :op :cmpl))))
-		,@(if allow-other-keys-p
-		      `((:jne 'default))
-		    `((:jne '(:sub-program (unknown-key) (:int 101)))))
-		,@(when supplied-p-var
-		    `((:movl (:edi ,(global-constant-offset 't-symbol)) :eax)
-		      (:store-lexical ,supplied-p-binding :eax
-				      :type (eql ,(image-t-symbol *image*)))))
-		,@(case position
-		    (0 nil)		; it's already in ebx
-		    (t `((:movl (:ebp (:ecx 4) ,(* -4 (1- (1+ position)))) :ebx))))
-		default-done
-		(:store-lexical ,binding :ebx :type t))))))
-       (t #+ignore
-	  (pushnew (movitz-print (movitz-funobj-name funobj))
-		   (aref *xx* (length key-vars)))
-	  #+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)))
+	(setq need-normalized-ecx-p t)
+	(append
+	 `((:declare-key-arg-set ,@(mapcar (lambda (k)
+					     (movitz-read
+					      (keyword-function-argument-keyword-name
+					       (movitz-binding (decode-keyword-formal k) env))))
+					   key-vars)))
+	 (make-immediate-move (* +movitz-fixnum-factor+
+				 (rest-args-position env))
+			      :edx)
+	 `((:call (:edi ,(global-constant-offset 'decode-keyargs-default))))
+	 (unless (allow-other-keys-p env)
+	   `((:testl :eax :eax)
+	     (:jnz '(:sub-program (unknown-keyword)
+		     (:int 72)))))
+	 (loop for key-var in key-vars
+	     as key-location upfrom 3 by 2
+	     as key-var-name =
+	       (decode-keyword-formal key-var)
+	     as binding =
+	       (movitz-binding key-var-name env)
+	     as supplied-p-binding =
+	       (movitz-binding (optional-function-argument-supplied-p-var binding)
+			       env)
+	     as keyword-ok-label = (make-symbol (format nil "keyword-~A-ok" key-var-name))
+	     do (assert binding)
+	     ;;  (not (movitz-constantp (optional-function-argument-init-form binding)))
+	     append
+	       `((:init-lexvar ,binding
+			       :init-with-register ,binding
+			       :init-with-type t
+			       :shared-reference-p t)
+		 (:init-lexvar ,supplied-p-binding
+			       :init-with-register ,supplied-p-binding
+			       :init-with-type t
+			       :shared-reference-p t))
+	     append
+	       (when (optional-function-argument-init-form binding)
+		 `((:cmpl :edi (:ebp ,(stack-frame-offset (1+ key-location))))
+		   (:jne ',keyword-ok-label)
 		   ,@(compiler-call #'compile-form
 		       :form (optional-function-argument-init-form binding)

[187 lines skipped]




More information about the Movitz-cvs mailing list