[armedbear-devel] Fwd: [armedbear-cvs] r13787 - trunk/abcl/src/org/armedbear/lisp
Blake McBride
blake at mcbride.name
Tue Jan 17 19:59:46 UTC 2012
Great work! Thanks!!
On Tue, Jan 17, 2012 at 1:48 PM, Erik Huelsmann
<ehuelsmann at common-lisp.net> wrote:
> The commit below reduces the number of ANSI failures on my system from 18 to 14!
>
> Bye,
>
> Erik.
>
>
> ---------- Forwarded message ----------
> From: <ehuelsmann at common-lisp.net>
> Date: Tue, Jan 17, 2012 at 8:39 PM
> Subject: [armedbear-cvs] r13787 - trunk/abcl/src/org/armedbear/lisp
> To: armedbear-cvs at common-lisp.net
>
>
> Author: ehuelsmann
> Date: Tue Jan 17 11:39:54 2012
> New Revision: 13787
>
> Log:
> Implement keyword argument verification in the method invocation protocol.
>
> Modified:
> trunk/abcl/src/org/armedbear/lisp/clos.lisp
>
> Modified: trunk/abcl/src/org/armedbear/lisp/clos.lisp
> ==============================================================================
> --- trunk/abcl/src/org/armedbear/lisp/clos.lisp Tue Jan 17 11:38:01
> 2012 (r13786)
> +++ trunk/abcl/src/org/armedbear/lisp/clos.lisp Tue Jan 17 11:39:54
> 2012 (r13787)
> @@ -2027,13 +2027,72 @@
> (unless (subclassp (car classes) specializer)
> (return (values nil t)))))))
>
> +(defun check-applicable-method-keyword-args (gf args
> + keyword-args
> + applicable-keywords)
> + (when (oddp (length keyword-args))
> + (error 'program-error
> + :format-control "Odd number of keyword arguments in call to ~S ~
> +with arguments list ~S"
> + :format-arguments (list gf args)))
> + (unless (getf keyword-args :allow-other-keys)
> + (loop for key in keyword-args by #'cddr
> + unless (or (member key applicable-keywords)
> + (eq key :allow-other-keys))
> + do (error 'program-error
> + :format-control "Invalid keyword argument ~S in call ~
> +to ~S with argument list ~S."
> + :format-arguments (list key gf args)))))
> +
> +(defun compute-applicable-keywords (gf applicable-methods)
> + (let ((applicable-keywords
> + (getf (analyze-lambda-list (generic-function-lambda-list gf))
> + :keywords)))
> + (loop for method in applicable-methods
> + do (multiple-value-bind
> + (keywords allow-other-keys)
> + (function-keywords method)
> + (when allow-other-keys
> + (setf applicable-keywords :any)
> + (return))
> + (setf applicable-keywords
> + (union applicable-keywords keywords))))
> + applicable-keywords))
> +
> +(defun wrap-emfun-for-keyword-args-check (gf emfun non-keyword-args
> + applicable-keywords)
> + #'(lambda (args)
> + (check-applicable-method-keyword-args
> + gf args
> + (nthcdr non-keyword-args args) applicable-keywords)
> + (funcall emfun args)))
> +
> (defun slow-method-lookup (gf args)
> (let ((applicable-methods (%compute-applicable-methods gf args)))
> (if applicable-methods
> - (let ((emfun (funcall (if (eq (class-of gf)
> +the-standard-generic-function-class+)
> - #'std-compute-effective-method-function
> - #'compute-effective-method-function)
> - gf applicable-methods)))
> + (let* ((emfun (funcall (if (eq (class-of gf)
> +the-standard-generic-function-class+)
> + #'std-compute-effective-method-function
> + #'compute-effective-method-function)
> + gf applicable-methods))
> + (non-keyword-args
> + (+ (length (gf-required-args gf))
> + (length (gf-optional-args gf))))
> + (gf-lambda-list (generic-function-lambda-list gf))
> + (checks-required (and (member '&key gf-lambda-list)
> + (not (member '&allow-other-keys
> + gf-lambda-list)))
> + )
> + (applicable-keywords
> + (when checks-required
> + ;; Don't do applicable keyword checks when this is
> + ;; one of the 'exceptional four' or when the gf allows
> + ;; other keywords.
> + (compute-applicable-keywords gf applicable-methods))))
> + (when (and checks-required
> + (not (eq applicable-keywords :any)))
> + (setf emfun
> + (wrap-emfun-for-keyword-args-check gf emfun non-keyword-args
> + applicable-keywords)))
> (cache-emf gf args emfun)
> (funcall emfun args))
> (apply #'no-applicable-method gf args))))
> @@ -2407,6 +2466,7 @@
> (%set-method-function method function)
> (%set-method-fast-function method fast-function)
> (set-reader-method-slot-name method slot-name)
> + (%set-function-keywords method nil nil)
> method))
>
> (defun add-reader-method (class function-name slot-name)
> @@ -2830,8 +2890,7 @@
> ((null tail))
> (unless (memq initarg allowable-initargs)
> (error 'program-error
> - :format-control "Invalid initarg ~S in call to ~S ~
> -with arglist ~S."
> + :format-control "Invalid initarg ~S in call to
> ~S with arglist ~S."
> :format-arguments (list initarg call-site args))))))))
>
> (defun merge-initargs-sets (list1 list2)
> @@ -2949,7 +3008,8 @@
> &rest initargs
> &key &allow-other-keys))
>
> -(defmethod shared-initialize ((instance standard-object) slot-names
> &rest initargs)
> +(defmethod shared-initialize ((instance standard-object) slot-names
> + &rest initargs)
> (std-shared-initialize instance slot-names initargs))
>
> (defmethod shared-initialize ((slot slot-definition) slot-names
> @@ -3372,7 +3432,6 @@
> (:method ((method standard-method))
> (%function-keywords method)))
>
> -
> (setf *gf-initialize-instance* (symbol-function 'initialize-instance))
> (setf *gf-allocate-instance* (symbol-function 'allocate-instance))
> (setf *gf-shared-initialize* (symbol-function 'shared-initialize))
>
> _______________________________________________
> armedbear-cvs mailing list
> armedbear-cvs at common-lisp.net
> http://lists.common-lisp.net/cgi-bin/mailman/listinfo/armedbear-cvs
> _______________________________________________
> armedbear-devel mailing list
> armedbear-devel at common-lisp.net
> http://lists.common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
More information about the armedbear-devel
mailing list