emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r109210: Autoload more carefully from


From: Stefan Monnier
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r109210: Autoload more carefully from Lisp. Follow aliases for function properties.
Date: Wed, 25 Jul 2012 21:27:33 -0400
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 109210
committer: Stefan Monnier <address@hidden>
branch nick: trunk
timestamp: Wed 2012-07-25 21:27:33 -0400
message:
  Autoload more carefully from Lisp.  Follow aliases for function properties.
  * lisp/subr.el (autoloadp): New function.
  (symbol-file): Use it.
  (function-get): New function.
  * lisp/emacs-lisp/macroexp.el (macroexp--expand-all): Use function-get and
  autoload-do-load.
  * lisp/emacs-lisp/lisp-mode.el (lisp-font-lock-syntactic-face-function)
  (lisp-indent-function):
  * lisp/emacs-lisp/gv.el (gv-get):
  * lisp/emacs-lisp/edebug.el (get-edebug-spec, edebug-basic-spec):
  * lisp/emacs-lisp/byte-opt.el (byte-optimize-form):
  * lisp/emacs-lisp/bytecomp.el (byte-compile-arglist-warn):
  * lisp/emacs-lisp/autoload.el (make-autoload, autoload-print-form):
  Use function-get.
  * lisp/emacs-lisp/cl.el: Don't propagate function properties any more.
  
  * src/eval.c (Fautoload_do_load): Rename from do_autoload, export to Lisp,
  add argument, tune behavior, and adjust all callers.
  
  * lisp/speedbar.el (speedbar-add-localized-speedbar-support):
  * lisp/emacs-lisp/disass.el (disassemble-internal):
  * lisp/desktop.el (desktop-load-file):
  * lisp/help-fns.el (help-function-arglist, find-lisp-object-file-name)
  (describe-function-1):
  * lisp/emacs-lisp/find-func.el (find-function-noselect):
  * lisp/emacs-lisp/elp.el (elp-instrument-function):
  * lisp/emacs-lisp/advice.el (ad-has-proper-definition):
  * lisp/apropos.el (apropos-safe-documentation, apropos-macrop):
  * lisp/emacs-lisp/debug.el (debug-on-entry):
  * lisp/emacs-lisp/cl-macs.el (cl-compiler-macroexpand):
  * lisp/emacs-lisp/byte-opt.el (byte-compile-inline-expand):
  * lisp/calc/calc.el (name): Use autoloadp & autoload-do-load.
modified:
  etc/NEWS
  lisp/ChangeLog
  lisp/apropos.el
  lisp/calc/calc.el
  lisp/desktop.el
  lisp/emacs-lisp/advice.el
  lisp/emacs-lisp/autoload.el
  lisp/emacs-lisp/byte-opt.el
  lisp/emacs-lisp/bytecomp.el
  lisp/emacs-lisp/cl-macs.el
  lisp/emacs-lisp/cl.el
  lisp/emacs-lisp/debug.el
  lisp/emacs-lisp/disass.el
  lisp/emacs-lisp/edebug.el
  lisp/emacs-lisp/elp.el
  lisp/emacs-lisp/find-func.el
  lisp/emacs-lisp/gv.el
  lisp/emacs-lisp/lisp-mode.el
  lisp/emacs-lisp/macroexp.el
  lisp/emacs-lisp/pcase.el
  lisp/help-fns.el
  lisp/speedbar.el
  lisp/subr.el
  src/ChangeLog
  src/data.c
  src/eval.c
  src/keyboard.c
  src/keymap.c
  src/lisp.h
=== modified file 'etc/NEWS'
--- a/etc/NEWS  2012-07-22 04:11:49 +0000
+++ b/etc/NEWS  2012-07-26 01:27:33 +0000
@@ -498,6 +498,10 @@
 
 * Lisp changes in Emacs 24.2
 
+** New functions `autoloadp' and `autoload-do-load'.
+
+** `function-get' fetches the property of a function, following aliases.
+
 ** `toggle-read-only' accepts a second argument specifying whether to
 print a message, if called from Lisp.
 

=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2012-07-25 23:11:23 +0000
+++ b/lisp/ChangeLog    2012-07-26 01:27:33 +0000
@@ -1,3 +1,37 @@
+2012-07-26  Stefan Monnier  <address@hidden>
+
+       Autoload from Lisp with more care.  Follow aliases when looking for
+       function properties.
+       * subr.el (autoloadp): New function.
+       (symbol-file): Use it.
+       (function-get): New function.
+       * emacs-lisp/macroexp.el (macroexp--expand-all): Use function-get and
+       autoload-do-load.
+       * emacs-lisp/lisp-mode.el (lisp-font-lock-syntactic-face-function)
+       (lisp-indent-function):
+       * emacs-lisp/gv.el (gv-get):
+       * emacs-lisp/edebug.el (get-edebug-spec, edebug-basic-spec):
+       * emacs-lisp/byte-opt.el (byte-optimize-form):
+       * emacs-lisp/bytecomp.el (byte-compile-arglist-warn):
+       * emacs-lisp/autoload.el (make-autoload, autoload-print-form):
+       Use function-get.
+       * emacs-lisp/cl.el: Don't propagate function properties any more.
+
+       * speedbar.el (speedbar-add-localized-speedbar-support):
+       * emacs-lisp/disass.el (disassemble-internal):
+       * desktop.el (desktop-load-file):
+       * help-fns.el (help-function-arglist, find-lisp-object-file-name)
+       (describe-function-1):
+       * emacs-lisp/find-func.el (find-function-noselect):
+       * emacs-lisp/elp.el (elp-instrument-function):
+       * emacs-lisp/advice.el (ad-has-proper-definition):
+       * apropos.el (apropos-safe-documentation, apropos-macrop):
+       * emacs-lisp/debug.el (debug-on-entry):
+       * emacs-lisp/cl-macs.el (cl-compiler-macroexpand):
+       * emacs-lisp/byte-opt.el (byte-compile-inline-expand):
+       * calc/calc.el (name): Use autoloadp & autoload-do-load.
+
+
 2012-07-25  Alp Aker  <address@hidden>
 
        * international/mule-cmds.el (ucs-insert): Mark it as an obsolete

=== modified file 'lisp/apropos.el'
--- a/lisp/apropos.el   2012-07-10 11:51:54 +0000
+++ b/lisp/apropos.el   2012-07-26 01:27:33 +0000
@@ -980,7 +980,7 @@
   (setq function (if (byte-code-function-p function)
                     (if (> (length function) 4)
                         (aref function 4))
-                  (if (eq (car-safe function) 'autoload)
+                  (if (autoloadp function)
                       (nth 2 function)
                     (if (eq (car-safe function) 'lambda)
                         (if (stringp (nth 2 function))
@@ -1114,7 +1114,7 @@
        (consp (setq symbol
                    (symbol-function symbol)))
        (or (eq (car symbol) 'macro)
-          (if (eq (car symbol) 'autoload)
+          (if (autoloadp symbol)
               (memq (nth 4 symbol)
                     '(macro t))))))
 

=== modified file 'lisp/calc/calc.el'
--- a/lisp/calc/calc.el 2012-05-19 03:00:48 +0000
+++ b/lisp/calc/calc.el 2012-07-26 01:27:33 +0000
@@ -914,7 +914,7 @@
 
 ;; Set up the autoloading linkage.
 (let ((name (and (fboundp 'calc-dispatch)
-                 (eq (car-safe (symbol-function 'calc-dispatch)) 'autoload)
+                 (autoloadp (symbol-function 'calc-dispatch))
                  (nth 1 (symbol-function 'calc-dispatch))))
       (p load-path))
 

=== modified file 'lisp/desktop.el'
--- a/lisp/desktop.el   2012-06-21 07:25:56 +0000
+++ b/lisp/desktop.el   2012-07-26 01:27:33 +0000
@@ -1119,11 +1119,8 @@
 
 (defun desktop-load-file (function)
   "Load the file where auto loaded FUNCTION is defined."
-  (when function
-    (let ((fcell (and (fboundp function) (symbol-function function))))
-      (when (and (listp fcell)
-                 (eq 'autoload (car fcell)))
-        (load (cadr fcell))))))
+  (when (fboundp function)
+    (autoload-do-load (symbol-function function) function)))
 
 ;; ----------------------------------------------------------------------------
 ;; Create a buffer, load its file, set its mode, ...;

=== modified file 'lisp/emacs-lisp/advice.el'
--- a/lisp/emacs-lisp/advice.el 2012-02-10 15:50:11 +0000
+++ b/lisp/emacs-lisp/advice.el 2012-07-26 01:27:33 +0000
@@ -2542,7 +2542,7 @@
 For that it has to be fbound with a non-autoload definition."
   (and (symbolp function)
        (fboundp function)
-       (not (eq (car-safe (symbol-function function)) 'autoload))))
+       (not (autoloadp (symbol-function function)))))
 
 ;; The following two are necessary for the sake of packages such as
 ;; ange-ftp which redefine functions via fcell indirection:

=== modified file 'lisp/emacs-lisp/autoload.el'
--- a/lisp/emacs-lisp/autoload.el       2012-07-10 11:51:54 +0000
+++ b/lisp/emacs-lisp/autoload.el       2012-07-26 01:27:33 +0000
@@ -163,23 +163,23 @@
                      ((or `define-generic-mode `define-derived-mode
                           `define-compilation-mode) nil)
                      (_ t)))
-            (body (nthcdr (or (get car 'doc-string-elt) 3) form))
+            (body (nthcdr (or (function-get car 'doc-string-elt) 3) form))
             (doc (if (stringp (car body)) (pop body))))
         ;; Add the usage form at the end where describe-function-1
         ;; can recover it.
        (when (listp args) (setq doc (help-add-fundoc-usage doc args)))
         ;; `define-generic-mode' quotes the name, so take care of that
-        (list 'autoload (if (listp name) name (list 'quote name))
-              file doc
-              (or (and (memq car '(define-skeleton define-derived-mode
-                                    define-generic-mode
-                                    easy-mmode-define-global-mode
-                                    define-global-minor-mode
-                                    define-globalized-minor-mode
-                                    easy-mmode-define-minor-mode
-                                    define-minor-mode)) t)
-                  (eq (car-safe (car body)) 'interactive))
-              (if macrop (list 'quote 'macro) nil))))
+        `(autoload ,(if (listp name) name (list 'quote name))
+           ,file ,doc
+           ,(or (and (memq car '(define-skeleton define-derived-mode
+                                  define-generic-mode
+                                  easy-mmode-define-global-mode
+                                  define-global-minor-mode
+                                  define-globalized-minor-mode
+                                  easy-mmode-define-minor-mode
+                                  define-minor-mode)) t)
+                (eq (car-safe (car body)) 'interactive))
+           ,(if macrop ''macro nil))))
 
      ;; For defclass forms, use `eieio-defclass-autoload'.
      ((eq car 'defclass)
@@ -277,7 +277,7 @@
    ;; Symbols at the toplevel are meaningless.
    ((symbolp form) nil)
    (t
-    (let ((doc-string-elt (get (car-safe form) 'doc-string-elt))
+    (let ((doc-string-elt (function-get (car-safe form) 'doc-string-elt))
          (outbuf autoload-print-form-outbuf))
       (if (and doc-string-elt (stringp (nth doc-string-elt form)))
          ;; We need to hack the printing because the
@@ -356,7 +356,7 @@
   "Insert the section-header line,
 which lists the file name and which functions are in it, etc."
   (insert generate-autoload-section-header)
-  (prin1 (list 'autoloads autoloads load-name file time)
+  (prin1 `(autoloads ,autoloads ,load-name ,file ,time)
         outbuf)
   (terpri outbuf)
   ;; Break that line at spaces, to avoid very long lines.

=== modified file 'lisp/emacs-lisp/byte-opt.el'
--- a/lisp/emacs-lisp/byte-opt.el       2012-07-10 11:51:54 +0000
+++ b/lisp/emacs-lisp/byte-opt.el       2012-07-26 01:27:33 +0000
@@ -249,8 +249,8 @@
   (let* ((name (car form))
          (localfn (cdr (assq name byte-compile-function-environment)))
         (fn (or localfn (and (fboundp name) (symbol-function name)))))
-    (when (and (consp fn) (eq (car fn) 'autoload))
-      (load (nth 1 fn))
+    (when (autoloadp fn)
+      (autoload-do-load fn)
       (setq fn (or (and (fboundp name) (symbol-function name))
                    (cdr (assq name byte-compile-function-environment)))))
     (pcase fn
@@ -586,10 +586,11 @@
   (let (opt new)
     (if (and (consp form)
             (symbolp (car form))
-            (or (and for-effect
-                     ;; we don't have any of these yet, but we might.
-                     (setq opt (get (car form) 'byte-for-effect-optimizer)))
-                (setq opt (get (car form) 'byte-optimizer)))
+            (or ;; (and for-effect
+                ;;      ;; We don't have any of these yet, but we might.
+                ;;      (setq opt (get (car form)
+                 ;;                     'byte-for-effect-optimizer)))
+                (setq opt (function-get (car form) 'byte-optimizer)))
             (not (eq form (setq new (funcall opt form)))))
        (progn
 ;;       (if (equal form new) (error "bogus optimizer -- %s" opt))

=== modified file 'lisp/emacs-lisp/bytecomp.el'
--- a/lisp/emacs-lisp/bytecomp.el       2012-07-13 07:06:09 +0000
+++ b/lisp/emacs-lisp/bytecomp.el       2012-07-26 01:27:33 +0000
@@ -1355,7 +1355,7 @@
            nums sig min max)
        (when calls
           (when (and (symbolp name)
-                     (eq (get name 'byte-optimizer)
+                     (eq (function-get name 'byte-optimizer)
                          'byte-compile-inline-expand))
             (byte-compile-warn "defsubst `%s' was used before it was defined"
                       name))

=== modified file 'lisp/emacs-lisp/cl-macs.el'
--- a/lisp/emacs-lisp/cl-macs.el        2012-07-17 12:58:25 +0000
+++ b/lisp/emacs-lisp/cl-macs.el        2012-07-26 01:27:33 +0000
@@ -2420,8 +2420,8 @@
        (while (and (symbolp func)
                    (not (setq handler (get func 'compiler-macro)))
                    (fboundp func)
-                   (or (not (eq (car-safe (symbol-function func)) 'autoload))
-                       (load (nth 1 (symbol-function func)))))
+                   (or (not (autoloadp (symbol-function func)))
+                       (autoload-do-load (symbol-function func) func)))
          (setq func (symbol-function func)))
        (and handler
             (not (eq form (setq form (apply handler form (cdr form))))))))

=== modified file 'lisp/emacs-lisp/cl.el'
--- a/lisp/emacs-lisp/cl.el     2012-07-13 18:15:22 +0000
+++ b/lisp/emacs-lisp/cl.el     2012-07-26 01:27:33 +0000
@@ -320,16 +320,7 @@
                ))
   (let ((new (if (consp fun) (prog1 (cdr fun) (setq fun (car fun)))
                (intern (format "cl-%s" fun)))))
-    (defalias fun new)
-    ;; If `cl-foo' is declare inline, then make `foo' inline as well, and
-    ;; similarly.  Same for edebug specifications, indent rules and
-    ;; doc-string position.
-    ;; FIXME: For most of them, we should instead follow aliases
-    ;; where applicable.
-    (dolist (prop '(byte-optimizer doc-string-elt edebug-form-spec
-                    lisp-indent-function))
-      (if (get new prop)
-        (put fun prop (get new prop))))))
+    (defalias fun new)))
 
 ;;; Features provided a bit differently in Elisp.
 

=== modified file 'lisp/emacs-lisp/debug.el'
--- a/lisp/emacs-lisp/debug.el  2012-01-19 07:21:25 +0000
+++ b/lisp/emacs-lisp/debug.el  2012-07-26 01:27:33 +0000
@@ -805,9 +805,9 @@
                        ,(interactive-form (symbol-function function))
                        (apply ',(symbol-function function)
                               debug-on-entry-args)))
-    (when (eq (car-safe (symbol-function function)) 'autoload)
+    (when (autoloadp (symbol-function function))
       ;; The function is autoloaded.  Load its real definition.
-      (load (cadr (symbol-function function)) nil noninteractive nil t))
+      (autoload-do-load (symbol-function function) function))
     (when (or (not (consp (symbol-function function)))
              (and (eq (car (symbol-function function)) 'macro)
                   (not (consp (cdr (symbol-function function))))))

=== modified file 'lisp/emacs-lisp/disass.el'
--- a/lisp/emacs-lisp/disass.el 2012-06-07 19:25:48 +0000
+++ b/lisp/emacs-lisp/disass.el 2012-07-26 01:27:33 +0000
@@ -80,14 +80,10 @@
            obj (symbol-function obj)))
     (if (subrp obj)
        (error "Can't disassemble #<subr %s>" name))
-    (when (and (listp obj) (eq (car obj) 'autoload))
-      (load (nth 1 obj))
-      (setq obj (symbol-function name)))
-    (if (eq (car-safe obj) 'macro)     ;handle macros
+    (setq obj (autoload-do-load obj name))
+    (if (eq (car-safe obj) 'macro)     ;Handle macros.
        (setq macro t
              obj (cdr obj)))
-    (when (and (listp obj) (eq (car obj) 'closure))
-      (error "Don't know how to compile an interpreted closure"))
     (if (and (listp obj) (eq (car obj) 'byte-code))
        (setq obj (list 'lambda nil obj)))
     (if (and (listp obj) (not (eq (car obj) 'lambda)))

=== modified file 'lisp/emacs-lisp/edebug.el'
--- a/lisp/emacs-lisp/edebug.el 2012-06-13 15:46:29 +0000
+++ b/lisp/emacs-lisp/edebug.el 2012-07-26 01:27:33 +0000
@@ -242,10 +242,13 @@
 
 (defun get-edebug-spec (symbol)
   ;; Get the spec of symbol resolving all indirection.
-  (let ((edebug-form-spec (get symbol 'edebug-form-spec))
-       indirect)
-    (while (and (symbolp edebug-form-spec)
-               (setq indirect (get edebug-form-spec 'edebug-form-spec)))
+  (let ((edebug-form-spec nil)
+       (indirect symbol))
+    (while
+        (progn
+          (and (symbolp indirect)
+               (setq indirect
+                     (function-get indirect 'edebug-form-spec 'autoload))))
       ;; (edebug-trace "indirection: %s" edebug-form-spec)
       (setq edebug-form-spec indirect))
     edebug-form-spec
@@ -263,7 +266,7 @@
             (setq spec (cdr spec)))
           t))
        ((symbolp spec)
-        (unless (functionp spec) (get spec 'edebug-form-spec)))))
+        (unless (functionp spec) (function-get spec 'edebug-form-spec)))))
 
 ;;; Utilities
 

=== modified file 'lisp/emacs-lisp/elp.el'
--- a/lisp/emacs-lisp/elp.el    2012-01-19 07:21:25 +0000
+++ b/lisp/emacs-lisp/elp.el    2012-07-26 01:27:33 +0000
@@ -258,7 +258,7 @@
     ;; the autoload here, since that could have side effects, and
     ;; elp-instrument-function is similar (in my mind) to defun-ish
     ;; type functionality (i.e. it shouldn't execute the function).
-    (and (eq (car-safe funguts) 'autoload)
+    (and (autoloadp funguts)
         (error "ELP cannot profile autoloaded function: %s" funsym))
     ;; We cannot profile functions used internally during profiling.
     (unless (elp-profilable-p funsym)

=== modified file 'lisp/emacs-lisp/find-func.el'
--- a/lisp/emacs-lisp/find-func.el      2012-01-19 07:21:25 +0000
+++ b/lisp/emacs-lisp/find-func.el      2012-07-26 01:27:33 +0000
@@ -347,8 +347,7 @@
     (if aliases
        (message "%s" aliases))
     (let ((library
-          (cond ((eq (car-safe def) 'autoload)
-                 (nth 1 def))
+          (cond ((autoloadp def) (nth 1 def))
                 ((subrp def)
                  (if lisp-only
                      (error "%s is a built-in function" function))

=== modified file 'lisp/emacs-lisp/gv.el'
--- a/lisp/emacs-lisp/gv.el     2012-07-10 11:27:27 +0000
+++ b/lisp/emacs-lisp/gv.el     2012-07-26 01:27:33 +0000
@@ -84,14 +84,7 @@
   (if (symbolp place)
       (funcall do place (lambda (v) `(setq ,place ,v)))
     (let* ((head (car place))
-           (gf (get head 'gv-expander)))
-      ;; Autoload the head, if applicable, since that might define
-      ;; `gv-expander'.
-      (when (and (null gf) (fboundp head)
-                 (eq 'autoload (car-safe (symbol-function head))))
-        (with-demoted-errors
-          (load (nth 1 (symbol-function head)) 'noerror 'nomsg)
-          (setq gf (get head 'gv-expander))))
+           (gf (function-get head 'gv-expander 'autoload)))
       (if gf (apply gf do (cdr place))
         (let ((me (macroexpand place    ;FIXME: expand one step at a time!
                                ;; (append macroexpand-all-environment

=== modified file 'lisp/emacs-lisp/lisp-mode.el'
--- a/lisp/emacs-lisp/lisp-mode.el      2012-06-27 21:15:13 +0000
+++ b/lisp/emacs-lisp/lisp-mode.el      2012-07-26 01:27:33 +0000
@@ -158,7 +158,8 @@
                                   (goto-char listbeg)
                                   (and (looking-at "([ 
\t\n]*\\(\\(\\sw\\|\\s_\\)+\\)")
                                        (match-string 1)))))
-                 (docelt (and firstsym (get (intern-soft firstsym)
+                 (docelt (and firstsym
+                              (function-get (intern-soft firstsym)
                                             lisp-doc-string-elt-property))))
             (if (and docelt
                      ;; It's a string in a form that can have a docstring.
@@ -1135,7 +1136,8 @@
       (let ((function (buffer-substring (point)
                                        (progn (forward-sexp 1) (point))))
            method)
-       (setq method (or (get (intern-soft function) 'lisp-indent-function)
+       (setq method (or (function-get (intern-soft function)
+                                       'lisp-indent-function)
                         (get (intern-soft function) 'lisp-indent-hook)))
        (cond ((or (eq method 'defun)
                   (and (null method)

=== modified file 'lisp/emacs-lisp/macroexp.el'
--- a/lisp/emacs-lisp/macroexp.el       2012-07-17 08:15:06 +0000
+++ b/lisp/emacs-lisp/macroexp.el       2012-07-26 01:27:33 +0000
@@ -185,12 +185,7 @@
        ;; Macro expand compiler macros.  This cannot be delayed to
        ;; byte-optimize-form because the output of the compiler-macro can
        ;; use macros.
-       (let ((handler nil))
-         (while (and (symbolp func)
-                     (not (setq handler (get func 'compiler-macro)))
-                     (fboundp func))
-           ;; Follow the sequence of aliases.
-           (setq func (symbol-function func)))
+       (let ((handler (function-get func 'compiler-macro)))
          (if (null handler)
              ;; No compiler macro.  We just expand each argument (for
              ;; setq/setq-default this works alright because the variable names
@@ -198,12 +193,9 @@
              (macroexp--all-forms form 1)
            ;; If the handler is not loaded yet, try (auto)loading the
            ;; function itself, which may in turn load the handler.
-           (when (and (not (functionp handler))
-                      (fboundp func) (eq (car-safe (symbol-function func))
-                                         'autoload))
+           (unless (functionp handler)
              (ignore-errors
-               (load (nth 1 (symbol-function func))
-                     'noerror 'nomsg)))
+               (autoload-do-load (indirect-function func) func)))
            (let ((newform (macroexp--compiler-macro handler form)))
              (if (eq form newform)
                  ;; The compiler macro did not find anything to do.

=== modified file 'lisp/emacs-lisp/pcase.el'
--- a/lisp/emacs-lisp/pcase.el  2012-07-11 23:13:41 +0000
+++ b/lisp/emacs-lisp/pcase.el  2012-07-26 01:27:33 +0000
@@ -114,7 +114,8 @@
 
 PRED can take the form
   FUNCTION          in which case it gets called with one argument.
-  (FUN ARG1 .. ARGN) in which case it gets called with N+1 arguments.
+  (FUN ARG1 .. ARGN) in which case it gets called with an N+1'th argument
+                        which is the value being matched.
 A PRED of the form FUNCTION is equivalent to one of the form (FUNCTION).
 PRED patterns can refer to variables bound earlier in the pattern.
 E.g. you can match pairs where the cdr is larger than the car with a pattern

=== modified file 'lisp/help-fns.el'
--- a/lisp/help-fns.el  2012-07-13 14:25:59 +0000
+++ b/lisp/help-fns.el  2012-07-26 01:27:33 +0000
@@ -150,7 +150,7 @@
                     arglist)))
           (unless (zerop rest) (push '&rest arglist) (push 'rest arglist))
           (nreverse arglist))))
-   ((and (eq (car-safe def) 'autoload) (not (eq (nth 4 def) 'keymap)))
+   ((and (autoloadp def) (not (eq (nth 4 def) 'keymap)))
     "[Arg list not available until function definition is loaded.]")
    (t t)))
 
@@ -288,7 +288,7 @@
 found via `load-path'.  The return value can also be `C-source', which
 means that OBJECT is a function or variable defined in C.  If no
 suitable file is found, return nil."
-  (let* ((autoloaded (eq (car-safe type) 'autoload))
+  (let* ((autoloaded (autoloadp type))
         (file-name (or (and autoloaded (nth 1 type))
                        (symbol-file
                         object (if (memq type (list 'defvar 'defface))
@@ -468,7 +468,7 @@
                  (concat beg "Lisp macro"))
                 ((eq (car-safe def) 'closure)
                  (concat beg "Lisp closure"))
-                ((eq (car-safe def) 'autoload)
+                ((autoloadp def)
                  (format "%s autoloaded %s"
                          (if (commandp def) "an interactive" "an")
                          (if (eq (nth 4 def) 'keymap) "keymap"
@@ -563,7 +563,7 @@
             ;; If the function is autoloaded, and its docstring has
             ;; key substitution constructs, load the library.
             (doc (progn
-                   (and (eq (car-safe real-def) 'autoload)
+                   (and (autoloadp real-def)
                         help-enable-auto-load
                         (string-match "\\([^\\]=\\|[^=]\\|\\`\\)\\\\[[{<]"
                                       doc-raw)

=== modified file 'lisp/speedbar.el'
--- a/lisp/speedbar.el  2012-06-08 16:39:49 +0000
+++ b/lisp/speedbar.el  2012-07-26 01:27:33 +0000
@@ -1864,9 +1864,7 @@
              ;; If it is autoloaded, we need to load it now so that
              ;; we have access to the variable -speedbar-menu-items.
              ;; Is this XEmacs safe?
-             (let ((sf (symbol-function v)))
-               (if (and (listp sf) (eq (car sf) 'autoload))
-                   (load-library (car (cdr sf)))))
+              (autoload-do-load (symbol-function v) v)
              (setq speedbar-special-mode-expansion-list (list v))
              (setq v (intern-soft (concat ms "-speedbar-key-map")))
              (if (not v)

=== modified file 'lisp/subr.el'
--- a/lisp/subr.el      2012-07-25 09:34:48 +0000
+++ b/lisp/subr.el      2012-07-26 01:27:33 +0000
@@ -1691,6 +1691,23 @@
 
 ;;; Load history
 
+(defsubst autoloadp (object)
+  "Non-nil if OBJECT is an autoload."
+  (eq 'autoload (car-safe object)))
+
+;; (defun autoload-type (object)
+;;   "Returns the type of OBJECT or `function' or `command' if the type is nil.
+;; OBJECT should be an autoload object."
+;;   (when (autoloadp object)
+;;     (let ((type (nth 3 object)))
+;;       (cond ((null type) (if (nth 2 object) 'command 'function))
+;;             ((eq 'keymap t) 'macro)
+;;             (type)))))
+
+;; (defalias 'autoload-file #'cadr
+;;   "Return the name of the file from which AUTOLOAD will be loaded.
+;; \n\(fn AUTOLOAD)")
+
 (defun symbol-file (symbol &optional type)
   "Return the name of the file that defined SYMBOL.
 The value is normally an absolute file name.  It can also be nil,
@@ -1703,7 +1720,7 @@
 definition, variable definition, or face definition only."
   (if (and (or (null type) (eq type 'defun))
           (symbolp symbol) (fboundp symbol)
-          (eq 'autoload (car-safe (symbol-function symbol))))
+          (autoloadp (symbol-function symbol)))
       (nth 1 (symbol-function symbol))
     (let ((files load-history)
          file)
@@ -2752,6 +2769,20 @@
 form."
   (secure-hash 'sha1 object start end binary))
 
+(defun function-get (f prop &optional autoload)
+  "Return the value of property PROP of function F.
+If AUTOLOAD is non-nil and F is an autoloaded macro, try to autoload
+the macro in the hope that it will set PROP."
+  (let ((val nil))
+    (while (and (symbolp f)
+                (null (setq val (get f prop)))
+                (fboundp f))
+      (let ((fundef (symbol-function f)))
+        (if (and autoload (autoloadp fundef)
+                 (not (equal fundef (autoload-do-load fundef f 'macro))))
+            nil                         ;Re-try `get' on the same `f'.
+          (setq f fundef))))
+    val))
 
 ;;;; Support for yanking and text properties.
 

=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2012-07-25 22:47:42 +0000
+++ b/src/ChangeLog     2012-07-26 01:27:33 +0000
@@ -1,3 +1,8 @@
+2012-07-26  Stefan Monnier  <address@hidden>
+
+       * eval.c (Fautoload_do_load): Rename from do_autoload, export to Lisp,
+       add argument, tune behavior, and adjust all callers.
+
 2012-07-25  Paul Eggert  <address@hidden>
 
        Use typedef for EMACS_INT, EMACS_UINT.

=== modified file 'src/data.c'
--- a/src/data.c        2012-07-19 22:35:58 +0000
+++ b/src/data.c        2012-07-26 01:27:33 +0000
@@ -761,7 +761,7 @@
        {
          struct gcpro gcpro1;
          GCPRO1 (cmd);
-         do_autoload (fun, cmd);
+         Fautoload_do_load (fun, cmd, Qnil);
          UNGCPRO;
          return Finteractive_form (cmd);
        }
@@ -2059,7 +2059,7 @@
   return Qnil;
 }
 
-/* Extract and set vector and string elements */
+/* Extract and set vector and string elements.  */
 
 DEFUN ("aref", Faref, Saref, 2, 2, 0,
        doc: /* Return the element of ARRAY at index IDX.

=== modified file 'src/eval.c'
--- a/src/eval.c        2012-07-20 05:28:00 +0000
+++ b/src/eval.c        2012-07-26 01:27:33 +0000
@@ -988,26 +988,14 @@
        {
          /* SYM is not mentioned in ENVIRONMENT.
             Look at its function definition.  */
+         struct gcpro gcpro1;
+         GCPRO1 (form);
+         def = Fautoload_do_load (def, sym, Qmacro);
+         UNGCPRO;
          if (EQ (def, Qunbound) || !CONSP (def))
            /* Not defined or definition not suitable.  */
            break;
-         if (EQ (XCAR (def), Qautoload))
-           {
-             /* Autoloading function: will it be a macro when loaded?  */
-             tem = Fnth (make_number (4), def);
-             if (EQ (tem, Qt) || EQ (tem, Qmacro))
-               /* Yes, load it and try again.  */
-               {
-                 struct gcpro gcpro1;
-                 GCPRO1 (form);
-                 do_autoload (def, sym);
-                 UNGCPRO;
-                 continue;
-               }
-             else
-               break;
-           }
-         else if (!EQ (XCAR (def), Qmacro))
+         if (!EQ (XCAR (def), Qmacro))
            break;
          else expander = XCDR (def);
        }
@@ -1952,22 +1940,35 @@
    FUNNAME is the symbol which is the function's name.
    FUNDEF is the autoload definition (a list).  */
 
-void
-do_autoload (Lisp_Object fundef, Lisp_Object funname)
+DEFUN ("autoload-do-load", Fautoload_do_load, Sautoload_do_load, 1, 3, 0,
+       doc: /* Load FUNDEF which should be an autoload.
+If non-nil, FUNNAME should be the symbol whose function value is FUNDEF,
+in which case the function returns the new autoloaded function value.
+If equal to `macro', MACRO-ONLY specifies that FUNDEF should only be loaded if
+it is defines a macro.  */)
+  (Lisp_Object fundef, Lisp_Object funname, Lisp_Object macro_only)
 {
   ptrdiff_t count = SPECPDL_INDEX ();
-  Lisp_Object fun;
   struct gcpro gcpro1, gcpro2, gcpro3;
 
+  if (!CONSP (fundef) || !EQ (Qautoload, XCAR (fundef)))
+    return fundef;
+
+  if (EQ (macro_only, Qmacro))
+    {
+      Lisp_Object kind = Fnth (make_number (4), fundef);
+      if (! (EQ (kind, Qt) || EQ (kind, Qmacro)))
+       return fundef;
+    }
+
   /* This is to make sure that loadup.el gives a clear picture
      of what files are preloaded and when.  */
   if (! NILP (Vpurify_flag))
     error ("Attempt to autoload %s while preparing to dump",
           SDATA (SYMBOL_NAME (funname)));
 
-  fun = funname;
   CHECK_SYMBOL (funname);
-  GCPRO3 (fun, funname, fundef);
+  GCPRO3 (funname, fundef, macro_only);
 
   /* Preserve the match data.  */
   record_unwind_save_match_data ();
@@ -1982,18 +1983,28 @@
      The value saved here is to be restored into Vautoload_queue.  */
   record_unwind_protect (un_autoload, Vautoload_queue);
   Vautoload_queue = Qt;
-  Fload (Fcar (Fcdr (fundef)), Qnil, Qt, Qnil, Qt);
+  /* If `macro_only', assume this autoload to be a "best-effort",
+     so don't signal an error if autoloading fails.  */
+  Fload (Fcar (Fcdr (fundef)), macro_only, Qt, Qnil, Qt);
 
   /* Once loading finishes, don't undo it.  */
   Vautoload_queue = Qt;
   unbind_to (count, Qnil);
 
-  fun = Findirect_function (fun, Qnil);
-
-  if (!NILP (Fequal (fun, fundef)))
-    error ("Autoloading failed to define function %s",
-          SDATA (SYMBOL_NAME (funname)));
   UNGCPRO;
+
+  if (NILP (funname))
+    return Qnil;
+  else
+    {
+      Lisp_Object fun = Findirect_function (funname, Qnil);
+
+      if (!NILP (Fequal (fun, fundef)))
+       error ("Autoloading failed to define function %s",
+              SDATA (SYMBOL_NAME (funname)));
+      else
+       return fun;
+    }
 }
 
 
@@ -2200,7 +2211,7 @@
        xsignal1 (Qinvalid_function, original_fun);
       if (EQ (funcar, Qautoload))
        {
-         do_autoload (fun, original_fun);
+         Fautoload_do_load (fun, original_fun, Qnil);
          goto retry;
        }
       if (EQ (funcar, Qmacro))
@@ -2729,7 +2740,6 @@
   ptrdiff_t i;
 
   QUIT;
-  maybe_gc ();
 
   if (++lisp_eval_depth > max_lisp_eval_depth)
     {
@@ -2742,10 +2752,13 @@
   backtrace.next = backtrace_list;
   backtrace_list = &backtrace;
   backtrace.function = &args[0];
-  backtrace.args = &args[1];
+  backtrace.args = &args[1];   /* This also GCPROs them.  */
   backtrace.nargs = nargs - 1;
   backtrace.debug_on_exit = 0;
 
+  /* Call GC after setting up the backtrace, so the latter GCPROs the args.  */
+  maybe_gc ();
+
   if (debug_on_next_call)
     do_debug_on_call (Qlambda);
 
@@ -2857,7 +2870,7 @@
        val = funcall_lambda (fun, numargs, args + 1);
       else if (EQ (funcar, Qautoload))
        {
-         do_autoload (fun, original_fun);
+         Fautoload_do_load (fun, original_fun, Qnil);
          CHECK_CONS_LIST ();
          goto retry;
        }
@@ -3582,6 +3595,7 @@
   defsubr (&Scalled_interactively_p);
   defsubr (&Scommandp);
   defsubr (&Sautoload);
+  defsubr (&Sautoload_do_load);
   defsubr (&Seval);
   defsubr (&Sapply);
   defsubr (&Sfuncall);

=== modified file 'src/keyboard.c'
--- a/src/keyboard.c    2012-07-21 14:11:33 +0000
+++ b/src/keyboard.c    2012-07-26 01:27:33 +0000
@@ -8827,18 +8827,12 @@
 
   next = access_keymap (map, key, 1, 0, 1);
 
-  /* Handle symbol with autoload definition.  */
-  if (SYMBOLP (next) && !NILP (Ffboundp (next))
-      && CONSP (XSYMBOL (next)->function)
-      && EQ (XCAR (XSYMBOL (next)->function), Qautoload))
-    do_autoload (XSYMBOL (next)->function, next);
-
   /* Handle a symbol whose function definition is a keymap
      or an array.  */
   if (SYMBOLP (next) && !NILP (Ffboundp (next))
       && (ARRAYP (XSYMBOL (next)->function)
          || KEYMAPP (XSYMBOL (next)->function)))
-    next = XSYMBOL (next)->function;
+    next = Fautoload_do_load (XSYMBOL (next)->function, next, Qnil);
 
   /* If the keymap gives a function, not an
      array, then call the function with one arg and use
@@ -10282,7 +10276,7 @@
          struct gcpro gcpro1, gcpro2;
 
          GCPRO2 (cmd, prefixarg);
-         do_autoload (final, cmd);
+         Fautoload_do_load (final, cmd, Qnil);
          UNGCPRO;
        }
       else

=== modified file 'src/keymap.c'
--- a/src/keymap.c      2012-07-15 07:57:54 +0000
+++ b/src/keymap.c      2012-07-26 01:27:33 +0000
@@ -225,7 +225,7 @@
    Fdefine_key should cause keymaps to be autoloaded.
 
    This function can GC when AUTOLOAD is non-zero, because it calls
-   do_autoload which can GC.  */
+   Fautoload_do_load which can GC.  */
 
 Lisp_Object
 get_keymap (Lisp_Object object, int error_if_not_keymap, int autoload)
@@ -259,7 +259,7 @@
                  struct gcpro gcpro1, gcpro2;
 
                  GCPRO2 (tem, object);
-                 do_autoload (tem, object);
+                 Fautoload_do_load (tem, object, Qnil);
                  UNGCPRO;
 
                  goto autoload_retry;

=== modified file 'src/lisp.h'
--- a/src/lisp.h        2012-07-25 22:47:42 +0000
+++ b/src/lisp.h        2012-07-26 01:27:33 +0000
@@ -2822,7 +2822,6 @@
 extern _Noreturn void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2);
 extern _Noreturn void verror (const char *, va_list)
   ATTRIBUTE_FORMAT_PRINTF (1, 0);
-extern void do_autoload (Lisp_Object, Lisp_Object);
 extern Lisp_Object un_autoload (Lisp_Object);
 extern void init_eval_once (void);
 extern Lisp_Object safe_call (ptrdiff_t, Lisp_Object *);
@@ -2834,7 +2833,7 @@
 #endif
 extern void syms_of_eval (void);
 
-/* Defined in editfns.c */
+/* Defined in editfns.c.  */
 extern Lisp_Object Qfield;
 extern void insert1 (Lisp_Object);
 extern Lisp_Object format2 (const char *, Lisp_Object, Lisp_Object);
@@ -2851,7 +2850,7 @@
 extern void syms_of_editfns (void);
 extern void set_time_zone_rule (const char *);
 
-/* Defined in buffer.c */
+/* Defined in buffer.c.  */
 extern int mouse_face_overlay_overlaps (Lisp_Object);
 extern _Noreturn void nsberror (Lisp_Object);
 extern void adjust_overlays_for_insert (ptrdiff_t, ptrdiff_t);
@@ -2870,7 +2869,7 @@
 extern void syms_of_buffer (void);
 extern void keys_of_buffer (void);
 
-/* Defined in marker.c */
+/* Defined in marker.c.  */
 
 extern ptrdiff_t marker_position (Lisp_Object);
 extern ptrdiff_t marker_byte_position (Lisp_Object);


reply via email to

[Prev in Thread] Current Thread [Next in Thread]