Re: master: Faster keyword argument checking in CLOS
Stas Boukarev <[email protected]> Sun, 10 May 2026 00:23:53 +0300
| Newsgroups | gmane.lisp.steel-bank.cvs,gmane.lisp.steel-bank.devel |
|---|---|
| Message-ID | <CAF63=12w072sddaRXs+GxtT2FZRsJprbh570PC5G8357N0eJ3A@mail.gmail.com> |
"It is not permitted to supply a keyword argument to a function using a name that is not a symbol. If this situation occurs in a safe call, an error of type program-error must be signaled unless keyword argument checking is suppressed as described in Section 3.4.1.4.1 (Suppressing Keyword Argument Checking)" On Sun, May 10, 2026 at 12:23 AM Charles Zhang via Sbcl-commits <[email protected]> wrote: > > But what’s with the removed tests and the ansi test failure? > > On Saturday, May 9, 2026, 11:19 PM, stassats via Sbcl-commits <[email protected]> wrote: > > The branch "master" has been updated in SBCL: > via c7921a02d8b8ff95914108b2395069bdc7f299aa (commit) > from 9ce4f6ccc4a20abe3161ab68ac60d0f654611f25 (commit) > > - Log ----------------------------------------------------------------- > commit c7921a02d8b8ff95914108b2395069bdc7f299aa > Author: Stas Boukarev <[email protected]> > Date: Sat May 9 22:49:45 2026 +0300 > > Faster keyword argument checking in CLOS > > Copy what convert-more-entry is doing and inline it. > --- > src/pcl/combin.lisp | 68 +++++++++++++++++++++----------------------------- > src/pcl/fngen.lisp | 3 ++- > tests/ansi-tests.sh | 2 +- > tests/clos.impure.lisp | 4 --- > 4 files changed, 32 insertions(+), 45 deletions(-) > > diff --git a/src/pcl/combin.lisp b/src/pcl/combin.lisp > index 6037c651a..7fd56f15e 100644 > --- a/src/pcl/combin.lisp > +++ b/src/pcl/combin.lisp > @@ -576,46 +576,36 @@ > (aver any-keyp) > (values (if allowp t keys) nopt))))) > > -(defun check-applicable-keywords (start valid-keys more-context more-count) > - (let ((allow-other-keys-seen nil) > - (allow-other-keys nil) > - (i start)) > - (declare (type index i more-count) > - (optimize speed)) > - (flet ((current-value () > - (sb-c::%more-arg more-context i))) > - (declare (inline current-value)) > - (collect ((invalid)) > - (loop > - (when (>= i more-count) > - (when (and (invalid) (not allow-other-keys)) > - (%program-error "~@<invalid keyword argument~P: ~ > - ~{~S~^, ~} (valid keys are ~{~S~^, ~}).~@:>" > - (length (invalid)) (invalid) valid-keys)) > - (return)) > - (let ((key (current-value))) > - (incf i) > - (cond > - ((not (symbolp key)) > - (%program-error "~@<keyword argument not a symbol: ~S.~@:>" > - key)) > - ((= i more-count) > - (sb-c::%odd-key-args-error)) > - ((eq key :allow-other-keys) > - ;; only the leftmost :ALLOW-OTHER-KEYS has any effect > - (unless allow-other-keys-seen > - (setq allow-other-keys-seen t > - allow-other-keys (current-value)))) > - ((eq t valid-keys)) > - ((not (memq key valid-keys)) (invalid key)))) > - (incf i)))))) > - > (defun wrap-with-applicable-keyword-check (effective valid-keys keyargs-start) > - `(let ((.valid-keys. ',valid-keys) > - (.keyargs-start. ',keyargs-start)) > - (multiple-value-bind (.more-context. .more-count.) (sb-c::%rest-context .rest.) > - (check-applicable-keywords > - .keyargs-start. .valid-keys. .more-context. .more-count.)) > + `(progn > + (multiple-value-bind (more-context more-count) (sb-c::%rest-context .rest.) > + (declare (ignorable more-context)) > + ;; Similar to what SB-C::CONVERT-MORE-ENTRY does > + (let ((count (- more-count ,keyargs-start))) > + (when ,(if (zerop keyargs-start) > + `(oddp count) > + `(and (plusp count) > + (oddp count))) > + (sb-c::%odd-key-args-error))) > + ,@(unless (eq valid-keys t) > + (let ((restart (sb-c:make-restart-location))) > + `((let (allowp > + (lose (make-unbound-marker)) > + (index more-count)) > + (declare (index index)) > + (loop until (<= index ,keyargs-start) > + do (decf (truly-the index index) 2) > + (let ((key (sb-c::%more-arg more-context index))) > + (case key > + (,(remove :allow-other-keys valid-keys)) > + (:allow-other-keys > + (setf allowp (sb-c::%more-arg more-context (1+ index)))) > + (t > + (setf lose key))))) > + (if (or (unbound-marker-p lose) > + allowp) > + (sb-c::restart-point ,restart) > + (sb-c::%unknown-key-arg-error lose ,restart))))))) > ,effective)) > > ;;;; the STANDARD method combination type. This is coded by hand > diff --git a/src/pcl/fngen.lisp b/src/pcl/fngen.lisp > index 6eb140875..60d2b060a 100644 > --- a/src/pcl/fngen.lisp > +++ b/src/pcl/fngen.lisp > @@ -97,7 +97,8 @@ > > (defun default-constantp (form) > (and (constantp form) > - (not (typep (constant-form-value form) '(or symbol fixnum cons layout))))) > + (not (typep (constant-form-value form) '(or symbol fixnum cons layout > + sb-c::restart-location))))) > > (defun default-test-converter (form) > (if (default-constantp form) > diff --git a/tests/ansi-tests.sh b/tests/ansi-tests.sh > index fb8dc92ce..6e807d0e3 100755 > --- a/tests/ansi-tests.sh > +++ b/tests/ansi-tests.sh > @@ -56,7 +56,7 @@ rm -fr sandbox/scratch > "SUBSTITUTE-IF.FOLD.3" "SUBSTITUTE-IF.FOLD.2" "SUBSTITUTE-IF.FOLD.1" > "SUBSTITUTE.FOLD.4" "SUBSTITUTE.FOLD.3" "SUBSTITUTE.FOLD.2" > "SUBSTITUTE.FOLD.1" "SUBSTITUTE-IF-NOT.FOLD.3" > - "MISC.598" "IMAGPART.4" > + "MISC.598" "IMAGPART.4" "SHARED-INITIALIZE.ERROR.4" > (append #+x86 (list "CIS.4") > #+(or arm riscv (and arm64 (not darwin))) > (list "EXP.ERROR.4" "EXP.ERROR.5" "EXP.ERROR.6" "EXP.ERROR.7" "EXPT.ERROR.4" > diff --git a/tests/clos.impure.lisp b/tests/clos.impure.lisp > index af142e6e9..f8e25dd69 100644 > --- a/tests/clos.impure.lisp > +++ b/tests/clos.impure.lisp > @@ -1352,10 +1352,6 @@ > (assert-error (shared-initialize (make-instance 'shared-initialize-keyword-check) nil :a) > program-error)) > > -(with-test (:name (:check-keyword-args shared-initialize :non-keyword :error)) > - (assert-error (shared-initialize (make-instance 'shared-initialize-keyword-check) nil '(abc) 1) > - program-error)) > - > ;;; verify that we can still detect no primary methods and invalid qualifiers > > (defmethod gf-with-keys-and-no-primary-method :around ((x integer) &key b) > > ----------------------------------------------------------------------- > > > hooks/post-receive > -- > SBCL > > > _______________________________________________ > Sbcl-commits mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/sbcl-commits > > _______________________________________________ > Sbcl-commits mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/sbcl-commits _______________________________________________ Sbcl-commits mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/sbcl-commits