[armedbear-cvs] r14054 - trunk/abcl/src/org/armedbear/lisp
ehuelsmann at common-lisp.net
ehuelsmann at common-lisp.net
Sat Aug 4 21:18:01 UTC 2012
Author: ehuelsmann
Date: Sat Aug 4 14:18:00 2012
New Revision: 14054
Log:
More efficient arguments option variable references (&optional and &aux)
and support for supplied-p parameters (&optional) for long form D-M-C.
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 Sat Aug 4 06:57:20 2012 (r14053)
+++ trunk/abcl/src/org/armedbear/lisp/clos.lisp Sat Aug 4 14:18:00 2012 (r14054)
@@ -1254,13 +1254,20 @@
(multiple-value-bind
(whole required optional rest keys aux)
(parse-define-method-combination-args-lambda-list args-lambda-list)
- (let ((gf-lambda-list (gensym))
- (args-var (gensym))
+ (let* ((gf-lambda-list (gensym))
+ (args-var (gensym))
+ (args-len-var (when (or (some #'second optional)
+ (some #'second keys))
+ (gensym)))
+ (binding-forms (gensym))
+ (needs-args-len-var (gensym))
(emf-form (gensym)))
`(let* ((,gf-lambda-list (slot-value ,generic-function-symbol
'sys::lambda-list))
(nreq (length (extract-required-part ,gf-lambda-list)))
(nopt (length (extract-optional-part ,gf-lambda-list)))
+ (,binding-forms)
+ (,needs-args-len-var)
(,emf-form
(let* (,@(when whole
`((,whole ',args-var)))
@@ -1271,22 +1278,37 @@
and i upfrom 0
collect `(,var (when (< ,i nreq)
`(nth ,,i ,',args-var))))
- ,@(loop for (var initform) in optional
+ ,@(loop for (var initform supplied-var) in optional
and i upfrom 0
+ for supplied-binding = (or supplied-var
+ (when initform (gensym)))
+ for var-binding = (gensym)
;; check for excess parameters
;; only assign initform if the parameter
;; isn't in excess: the spec says explicitly
- ;; to bind those in excess to forms evaluating
+ ;; to bind parameters in excess to forms evaluating
;; to nil.
;; This leaves initforms to be used with
;; parameters not supplied in excess, but
- ;; not available arguments list
+ ;; not available in the arguments list
;;
;; Also, if specified, bind "supplied-p"
- collect `(,var (if (< ,i nopt)
- `(nth ,(+ ,i nreq)
- ,',args-var)
- ',initform)))
+ if supplied-binding
+ collect `(,supplied-binding
+ (when (< ,i nopt)
+ (setq ,needs-args-len-var t)
+ (push `(,',supplied-binding
+ (< ,(+ ,i nreq) ,',args-len-var))
+ ,binding-forms)
+ ',supplied-binding))
+ collect `(,var (when (< ,i nopt)
+ (push `(,',var-binding
+ (if ,',supplied-binding
+ (nth ,(+ ,i nreq)
+ ,',args-var)
+ ,',initform))
+ ,binding-forms)
+ ',var-binding)))
,@(loop for ((key var) initform) in keys
;; Same as optional parameters:
;; even though keywords can't be supplied in
@@ -1296,14 +1318,24 @@
(+ ,nreq ,nopt)) ,',key
,',initform)))
,@(loop for (var initform) in aux
- collect `(,var ',initform)))
+ for var-binding = (gensym)
+ collect `(,var (progn
+ (push '(,var-binding ,initform)
+ ,binding-forms)
+ ',var-binding))))
, at forms)))
`(lambda (,',args-var)
- ;; This is the lambda which *is* the effective method
- ;; hence gets called on every method invocation
- ;; be as efficient in this method as we can be
- ,(wrap-with-call-method-macro ,generic-function-symbol
- ',args-var ,emf-form))))))
+ ;; set up bindings to ensure the expressions to which the
+ ;; variables of the arguments option have been bound are
+ ;; evaluated exactly once.
+ (let* (,@(when ,needs-args-len-var
+ `((,',args-len-var (length ,',args-var))))
+ ,@(reverse ,binding-forms))
+ ;; This is the lambda which *is* the effective method
+ ;; hence gets called on every method invocation
+ ;; be as efficient in this method as we can be
+ ,(wrap-with-call-method-macro ,generic-function-symbol
+ ',args-var ,emf-form)))))))
(defun method-combination-type-lambda
(&rest all-args
More information about the armedbear-cvs
mailing list