summaryrefslogtreecommitdiff
path: root/Lisp/compiler-macros.lisp
blob: 2661687d2224eca44a9c3409b07bf42a3628a113 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
(in-package #:mulk.objective-cl)


;; Optimise constant method names away by converting them to selectors
;; at load-time.
(define-compiler-macro primitive-invoke (&whole form
                                         receiver method-name return-type
                                         &rest args)
  (if (and (constantp method-name)
           (not (and (listp method-name)
                     (eq 'load-time-value (car method-name)))))
      `(primitive-invoke ,receiver
                         (load-time-value (handler-case
                                              (selector ,method-name)
                                            (serious-condition ()
                                              (warn
                                               (make-condition
                                                'simple-style-warning
                                                :format-control
                                                "~S designates an unknown ~
                                                 method selector."
                                                :format-arguments
                                                (list ,method-name)))
                                              ,method-name)))
                         ,return-type ,@args)
      form))


;; Do the same optimisations for INVOKE-BY-NAME as for PRIMITIVE-INVOKE.
(define-compiler-macro invoke-by-name (&whole form
                                       receiver method-name &rest args)
  (if (and (constantp method-name)
           (not (and (listp method-name)
                     (eq 'load-time-value (car method-name)))))
      `(invoke-by-name
        ,receiver
        (load-time-value (handler-case
                             (selector ,method-name)
                           (serious-condition ()
                             (warn
                              (make-condition 'simple-style-warning
                                              :format-control
                                              "~S designates an unknown ~
                                               method selector."
                                              :format-arguments
                                              (list ,method-name)))
                             ,method-name)))
        ,@args)
      form))


;; This compiler macro is a bit more complicated than the preceding
;; ones.
(define-compiler-macro invoke (receiver message-start &rest message-components)
  (multiple-value-bind (method-name args)
      (split-method-call message-start message-components)
    `(invoke-by-name
      ,receiver
      (load-time-value (handler-case
                           (selector ',method-name)
                         (serious-condition ()
                           (warn
                            (make-condition 'simple-style-warning
                                            :format-control
                                            "~S designates an unknown ~
                                               method selector."
                                            :format-arguments
                                            (list ',method-name)))
                           ',method-name)))
      ,@args)))