Changeset 10792

Show
Ignore:
Timestamp:
06/06/05 14:32:23 (3 years ago)
Author:
rtoy
Message:

Fix CALL-METHOD used outside of emf from.

Fix from Gerd, cmucl-imp, 2005-06-04 for the following test:

(define-method-combination mc ()

((primary () :required t))
`(restart-case (call-method ,(first primary))

()))

(defgeneric foo ()

(:method-combination mc)
(:method () nil))

(foo)

It turns out this is caused by RESTART-CASE macroexpanding its case
expression, which it does to see if it starts with ERROR or similar.
An ANSI thing, if I remember correctly.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/pcl/combin.lisp

    r9975 r10191  
    469469 
    470470;;; 
     471;;; Return true if a fast-method-call to METHOD can be inlined. 
     472;;; 
     473;;; We don't generate funcalls for standard accessor methods because 
     474;;; they have a fast function, but that's not what is actually to be 
     475;;; called.  What is called is a closure over MAKE-STD-*-METHOD-FUNCTION. 
     476;;; 
     477(defun inlinable-method-p (method) 
     478  (and (eq *boot-state* 'complete) 
     479       *inline-methods-in-emfs* 
     480       (not (standard-accessor-method-p method)))) 
     481 
     482;;; 
    471483;;; Return a form for calling METHOD's fast function.  METATYPES is a 
    472484;;; list of metatypes, whose length is used to figure out the names of 
    473 ;;; required emf parameters.  APPLY? true means the method has a &rest 
     485;;; required emf parameters.  REST? true means the method has a &rest 
    474486;;; arg.  CALLABLE-VAR is the name of a closed-over variable 
    475487;;; containing a FAST-METHOD-CALL instance corresponding to the 
     
    486498 
    487499;;; 
    488 ;;; Return a form for successive calls to the fast functions of 
    489 ;;; the methods in METHODS.  LIST-VAR is the name of a  
    490 ;;; variable containing a list of FAST-METHOD-CALL structures 
    491 ;;; corresponding to the method function calls. 
    492 ;;; 
    493 (defun make-direct-calls (methods metatypes rest? list-var) 
    494   (collect ((calls)) 
    495     (dolist (method methods) 
    496       (calls `(let ((.call. (pop .list.))) 
    497                 ,(make-direct-call method metatypes rest? '.call.)))) 
    498     `(let ((.list. ,list-var)) 
    499        (declare (ignorable .list.)) 
    500        ,@(calls)))) 
    501  
    502 ;;; 
    503500;;; Return the list of methods from a CALL-METHOD-LIST form. 
    504501;;; 
    505502(defun call-method-list-methods (call-method-list) 
    506   (mapcar (lambda (call-method) (cadr call-method)) 
    507           (cdr call-method-list))) 
     503  (loop for call-method-form in (cdr call-method-list) 
     504        collect (second call-method-form))) 
    508505 
    509506;;; 
     
    516513;;; 
    517514(defun memf-test-converter (form gf method-alist-p wrappers-p) 
    518   (case (car-safe form) 
    519     ;; 
    520     (call-method 
    521      (case (get-method-call-type gf form method-alist-p wrappers-p) 
    522        (fast-method-call 
    523         (let ((method (cadr form))) 
    524           (if (and (eq *boot-state* 'complete) *inline-methods-in-emfs*) 
    525               (method-function-name method) 
    526               '.fast-call-method.))) 
    527        (t '.call-method.))) 
    528     ;; 
    529     (call-method-list 
    530      (case (get-method-list-call-type gf form method-alist-p wrappers-p) 
    531        (fast-method-call 
    532         (if (and (eq *boot-state* 'complete) *inline-methods-in-emfs*) 
    533             (mapcar #'method-function-name (call-method-list-methods form)) 
    534             '.fast-call-method-list.)) 
    535        (t '.call-method-list.))) 
    536     ;; 
    537     (check-applicable-keywords 
    538      'check-applicable-keywords) 
    539     (t 
    540      (default-test-converter form)))) 
     515  (flet ((method-key (method) 
     516           (cond ((inlinable-method-p method) 
     517                  (method-function-name method)) 
     518                 ((eq (get-method-call-type gf form method-alist-p wrappers-p) 
     519                      'fast-method-call) 
     520                  '.fast-call-method.) 
     521                 (t '.call-method.)))) 
     522    (case (car-safe form) 
     523      ;; 
     524      (call-method 
     525       (if (eq (get-method-call-type gf form method-alist-p wrappers-p) 
     526               'fast-method-call) 
     527           (method-key (second form)) 
     528           '.call-method.)) 
     529      ;; 
     530      (call-method-list 
     531       (mapcar #'method-key (call-method-list-methods form))) 
     532      ;; 
     533      (check-applicable-keywords 
     534       'check-applicable-keywords) 
     535      (t 
     536       (default-test-converter form))))) 
    541537 
    542538;;; 
     
    546542;;; closure variables. 
    547543;;; 
    548 (defun memf-code-converter (form gf metatypes applyp method-alist-p 
     544(defun memf-code-converter (form gf metatypes rest? method-alist-p 
    549545                            wrappers-p) 
    550   (case (car-safe form) 
    551     ;; 
    552     ;; (CALL-METHOD <method-object> &optional <next-methods>) 
    553     (call-method 
    554      (let ((method (cadr form)) 
    555            (callable-var (gensym)) 
    556            (call-type (get-method-call-type gf form method-alist-p 
    557                                             wrappers-p))) 
    558        (if (and (eq call-type 'fast-method-call) 
    559                 (eq *boot-state* 'complete) 
    560                 *inline-methods-in-emfs*) 
    561            (values (make-direct-call method metatypes applyp callable-var) 
    562                    (list callable-var)) 
    563            (values (make-emf-call metatypes applyp callable-var call-type) 
    564                    (list callable-var))))) 
    565     ;; 
    566     ;; (CALL-METHOD-LIST <call-method-form>*) 
    567     ;; where each CALL-METHOD form is (CALL-METHOD <method>) 
    568     (call-method-list 
    569      (let ((list-var (gensym)) 
    570            (call-type (get-method-list-call-type gf form method-alist-p 
    571                                                  wrappers-p))) 
    572        (if (and (eq call-type 'fast-method-call) 
    573                 (eq *boot-state* 'complete) 
    574                 *inline-methods-in-emfs*) 
    575            (let ((methods (call-method-list-methods form))) 
    576              (values (make-direct-calls methods metatypes applyp list-var) 
    577                      (list list-var))) 
    578            (values `(dolist (.tem. ,list-var) 
    579                       ,(make-emf-call metatypes applyp '.tem. call-type)) 
    580                    (list list-var))))) 
    581     ;; 
    582     (check-applicable-keywords 
    583      (values `(check-applicable-keywords .dfun-rest-arg. 
    584                                          .keyargs-start. .valid-keys.) 
    585               '(.keyargs-start. .valid-keys.))) 
    586     (t 
    587      (default-code-converter form)))) 
     546  (labels ((make-call (call-type method metatypes rest? callable-var) 
     547             (if (and (eq call-type 'fast-method-call) 
     548                      (inlinable-method-p method)) 
     549                 (make-direct-call method metatypes rest? callable-var) 
     550                 (make-emf-call metatypes rest? callable-var call-type))) 
     551            
     552           (make-calls (call-type methods metatypes rest? list-var) 
     553             `(let ((.list. ,list-var)) 
     554                (declare (ignorable .list.)) 
     555                ,@(loop for method in methods collect 
     556                          `(let ((.call. (pop .list.))) 
     557                             ,(make-call call-type method metatypes 
     558                                         rest? '.call.)))))) 
     559    (case (car-safe form) 
     560      ;; 
     561      ;; (CALL-METHOD <method-object> &optional <next-methods>) 
     562      (call-method 
     563       (let ((method (cadr form)) 
     564             (callable-var (gensym)) 
     565             (call-type (get-method-call-type gf form method-alist-p 
     566                                              wrappers-p))) 
     567         (values (make-call call-type method metatypes rest? callable-var) 
     568                 (list callable-var)))) 
     569      ;; 
     570      ;; (CALL-METHOD-LIST <call-method-form>*) 
     571      ;; where each CALL-METHOD form is (CALL-METHOD <method>) 
     572      (call-method-list 
     573       (let ((list-var (gensym)) 
     574             (call-type (get-method-list-call-type gf form method-alist-p 
     575                                                   wrappers-p)) 
     576             (methods (call-method-list-methods form))) 
     577         (values (make-calls call-type methods metatypes rest? list-var) 
     578                 (list list-var)))) 
     579      ;; 
     580      (check-applicable-keywords 
     581       (values `(check-applicable-keywords .dfun-rest-arg. 
     582                                           .keyargs-start. .valid-keys.) 
     583               '(.keyargs-start. .valid-keys.))) 
     584      (t 
     585       (default-code-converter form))))) 
    588586 
    589587(defun memf-constant-converter (form gf)