unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [PATCH] Improve detection of local function calls in methods
@ 2021-08-27 21:41 akater
  2021-08-27 22:59 ` Stefan Monnier
  0 siblings, 1 reply; 6+ messages in thread
From: akater @ 2021-08-27 21:41 UTC (permalink / raw)
  To: emacs-devel


[-- Attachment #1.1: Type: text/plain, Size: 145 bytes --]


Instead of using unreliale and expensive macroexp--fgrep, we record the
relevant calls in the macroexpansion, as suggested in the FIXME entry.


[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 865 bytes --]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: cl--generic-lambda fix --]
[-- Type: text/x-diff, Size: 4091 bytes --]

From 099c63eb1c107531252fde859dee7466de05f210 Mon Sep 17 00:00:00 2001
From: akater <nuclearspace@gmail.com>
Date: Thu, 26 Aug 2021 06:09:07 +0000
Subject: [PATCH] Improve detection of local function calls in methods

* lisp/emacs-lisp/cl-generic.el (cl--generic-lambda):
Rather than `grep' after the fact,
the macroexpansion records directly
when cl-call-next-method or cl-next-method-p are used.
---
 lisp/emacs-lisp/cl-generic.el | 34 +++++++++++++++++++++++++---------
 1 file changed, 25 insertions(+), 9 deletions(-)

diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index 4a69df15bc..d5d77fe553 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -361,6 +361,14 @@ defun cl--generic-split-args (args)
       (cons (nreverse specializers)
             (nreverse (delq nil plain-args)))))
 
+  (defvar cl-generic--uses-cnm nil
+    ;; It would be better to declare the variable special
+    ;; locally where it's used
+    ;; but there is no support for local special declarations in Elisp.
+    "In a runtime environment, keeps a list of flags that indicate
+the presence of `cl-call-next-method' or `cl-next-method-p'
+in a method body.")
+
   (defun cl--generic-lambda (args body)
     "Make the lambda expression for a method with ARGS and BODY."
     (pcase-let* ((`(,spec-args . ,plain-args)
@@ -369,7 +377,7 @@ defun cl--generic-lambda (args body)
                  (macroenv (cons `(cl-generic-current-method-specializers
                                    . ,(lambda () spec-args))
                                  macroexpand-all-environment)))
-      (require 'cl-lib)        ;Needed to expand `cl-flet' and `cl-function'.
+      (require 'cl-lib)        ;Needed to expand `cl-function', `cl-macrolet'.
       (when (interactive-form (cadr fun))
         (message "Interactive forms unsupported in generic functions: %S"
                  (interactive-form (cadr fun))))
@@ -380,21 +388,29 @@ defun cl--generic-lambda (args body)
          (let* ((parsed-body (macroexp-parse-body body))
                 (cnm (make-symbol "cl--cnm"))
                 (nmp (make-symbol "cl--nmp"))
+                (cl-generic--uses-cnm)
                 (nbody (macroexpand-all
-                        `(cl-flet ((cl-call-next-method ,cnm)
-                                   (cl-next-method-p ,nmp))
+                        `(cl-macrolet ((cl-call-next-method
+                                        (&rest args)
+                                        (prog1 `(funcall ,',cnm ,@args)
+                                          (cl-pushnew
+                                           ',cnm cl-generic--uses-cnm
+                                           :test #'eq)))
+                                       (cl-next-method-p
+                                        ()
+                                        (prog1 `(funcall ,',nmp)
+                                          (cl-pushnew
+                                           ',nmp cl-generic--uses-cnm
+                                           :test #'eq))))
                            ,@(cdr parsed-body))
                         macroenv))
-                ;; FIXME: Rather than `grep' after the fact, the
-                ;; macroexpansion should directly set some flag when cnm
-                ;; is used.
-                ;; FIXME: Also, optimize the case where call-next-method is
+                ;; FIXME: Optimize the case where call-next-method is
                 ;; only called with explicit arguments.
-                (uses-cnm (macroexp--fgrep `((,cnm) (,nmp)) nbody)))
+                (uses-cnm cl-generic--uses-cnm))
            (cons (not (not uses-cnm))
                  `#'(lambda (,@(if uses-cnm (list cnm)) ,@args)
                       ,@(car parsed-body)
-                      ,(if (not (assq nmp uses-cnm))
+                      ,(if (not (memq nmp uses-cnm))
                            nbody
                          `(let ((,nmp (lambda ()
                                         (cl--generic-isnot-nnm-p ,cnm))))
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-09-10 15:49 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-27 21:41 [PATCH] Improve detection of local function calls in methods akater
2021-08-27 22:59 ` Stefan Monnier
2021-08-29 11:25   ` akater
2021-09-02 18:34     ` Stefan Monnier
2021-09-10  6:25       ` akater
2021-09-10 15:49         ` Stefan Monnier

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).