aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2012-11-09 17:20:47 -0500
committerStefan Monnier2012-11-09 17:20:47 -0500
commit32e5c58ca969ec30d31520da52c9866cafa62927 (patch)
treeaab212d158443e5a04d5828b78a26eca4d5db88c
parentda03ef8a9d38ef6f059aaeddb8c97dc7e76d3917 (diff)
downloademacs-32e5c58ca969ec30d31520da52c9866cafa62927.tar.gz
emacs-32e5c58ca969ec30d31520da52c9866cafa62927.zip
Provide new `defalias-fset-function' symbol property.
* src/lisp.h (AUTOLOADP): New macro. * src/eval.c (Fautoload): Don't attach to loadhist, call Fdefalias instead. * src/data.c (Ffset): Remove special ad-advice-info handling. (Fdefalias): Handle autoload definitions and new Qdefalias_fset_function. (Fsubr_arity): CSE. (Finteractive_form): Simplify. (Fquo): Don't insist on having at least 2 arguments. (Qdefalias_fset_function): New var. * lisp/emacs-lisp/advice.el (ad-set-advice-info): Set defalias-fset-function. (ad--defalias-fset): New function. (ad-safe-fset): Remove. (ad-make-freeze-definition): Use cl-letf*.
-rw-r--r--etc/NEWS3
-rw-r--r--lisp/ChangeLog7
-rw-r--r--lisp/emacs-lisp/advice.el150
-rw-r--r--src/ChangeLog13
-rw-r--r--src/data.c71
-rw-r--r--src/eval.c21
-rw-r--r--src/lisp.h2
7 files changed, 134 insertions, 133 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 177f91066ac..dd8ad72ba94 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -38,6 +38,9 @@ spurious warnings about an unused var.
38** Docstrings can be made dynamic by adding a `dynamic-docstring-function' 38** Docstrings can be made dynamic by adding a `dynamic-docstring-function'
39text-property on the first char. 39text-property on the first char.
40 40
41** The `defalias-fset-function' property lets you catch calls to defalias
42and redirect them to your own function instead of `fset'.
43
41* Changes in Emacs 24.4 on non-free operating systems 44* Changes in Emacs 24.4 on non-free operating systems
42 45
43 46
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 6f10e311eac..a07749e4f18 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,12 @@
12012-11-09 Stefan Monnier <monnier@iro.umontreal.ca> 12012-11-09 Stefan Monnier <monnier@iro.umontreal.ca>
2 2
3 * emacs-lisp/advice.el (ad-set-advice-info): Set defalias-fset-function.
4 (ad--defalias-fset): New function.
5 (ad-safe-fset): Remove.
6 (ad-make-freeze-definition): Use cl-letf*.
7
82012-11-09 Stefan Monnier <monnier@iro.umontreal.ca>
9
3 * subr.el (dolist): Don't bind VAR in RESULT. 10 * subr.el (dolist): Don't bind VAR in RESULT.
4 11
5 * emacs-lisp/advice.el: Miscellaneous cleanup. Use lexical-binding. 12 * emacs-lisp/advice.el: Miscellaneous cleanup. Use lexical-binding.
diff --git a/lisp/emacs-lisp/advice.el b/lisp/emacs-lisp/advice.el
index 92becb8bea9..42c25a4613d 100644
--- a/lisp/emacs-lisp/advice.el
+++ b/lisp/emacs-lisp/advice.el
@@ -1846,8 +1846,12 @@ On each iteration VAR will be bound to the name of an advised function
1846(defmacro ad-get-advice-info-macro (function) 1846(defmacro ad-get-advice-info-macro (function)
1847 `(get ,function 'ad-advice-info)) 1847 `(get ,function 'ad-advice-info))
1848 1848
1849(defmacro ad-set-advice-info (function advice-info) 1849(defsubst ad-set-advice-info (function advice-info)
1850 `(put ,function 'ad-advice-info ,advice-info)) 1850 (cond
1851 (advice-info (put function 'defalias-fset-function #'ad--defalias-fset))
1852 ((get function 'defalias-fset-function)
1853 (put function 'defalias-fset-function nil)))
1854 (put function 'ad-advice-info advice-info))
1851 1855
1852(defmacro ad-copy-advice-info (function) 1856(defmacro ad-copy-advice-info (function)
1853 `(copy-tree (get ,function 'ad-advice-info))) 1857 `(copy-tree (get ,function 'ad-advice-info)))
@@ -1954,18 +1958,10 @@ Redefining advices affect the construction of an advised definition."
1954;; @@ Dealing with automatic advice activation via `fset/defalias': 1958;; @@ Dealing with automatic advice activation via `fset/defalias':
1955;; ================================================================ 1959;; ================================================================
1956 1960
1957;; Since Emacs 19.26 the built-in versions of `fset' and `defalias' 1961;; Automatic activation happens when a function gets defined via `defalias',
1958;; take care of automatic advice activation, hence, we don't have to 1962;; which calls the `defalias-fset-function' (which we set to
1959;; hack it anymore by advising `fset/defun/defmacro/byte-code/etc'. 1963;; `ad--defalias-fset') instead of `fset', if non-nil.
1960 1964
1961;; The functionality of the new `fset' is as follows:
1962;;
1963;; fset(sym,newdef)
1964;; assign NEWDEF to SYM
1965;; if (get SYM 'ad-advice-info)
1966;; ad-activate-internal(SYM, nil)
1967;; return (symbol-function SYM)
1968;;
1969;; Whether advised definitions created by automatic activations will be 1965;; Whether advised definitions created by automatic activations will be
1970;; compiled depends on the value of `ad-default-compilation-action'. 1966;; compiled depends on the value of `ad-default-compilation-action'.
1971 1967
@@ -1977,6 +1973,10 @@ Redefining advices affect the construction of an advised definition."
1977;; to `ad-activate' by using `ad-with-auto-activation-disabled' where 1973;; to `ad-activate' by using `ad-with-auto-activation-disabled' where
1978;; appropriate, especially in a safe version of `fset'. 1974;; appropriate, especially in a safe version of `fset'.
1979 1975
1976(defun ad--defalias-fset (function definition)
1977 (fset function definition)
1978 (ad-activate-internal function nil))
1979
1980;; For now define `ad-activate-internal' to the dummy definition: 1980;; For now define `ad-activate-internal' to the dummy definition:
1981(defun ad-activate-internal (_function &optional _compile) 1981(defun ad-activate-internal (_function &optional _compile)
1982 "Automatic advice activation is disabled. `ad-start-advice' enables it." 1982 "Automatic advice activation is disabled. `ad-start-advice' enables it."
@@ -1994,12 +1994,6 @@ Redefining advices affect the construction of an advised definition."
1994 `(let ((ad-activate-on-top-level nil)) 1994 `(let ((ad-activate-on-top-level nil))
1995 ,@body)) 1995 ,@body))
1996 1996
1997(defun ad-safe-fset (symbol definition)
1998 "A safe `fset' which will never call `ad-activate-internal' recursively."
1999 (ad-with-auto-activation-disabled
2000 (fset symbol definition)))
2001
2002
2003;; @@ Access functions for original definitions: 1997;; @@ Access functions for original definitions:
2004;; ============================================ 1998;; ============================================
2005;; The advice-info of an advised function contains its `origname' which is 1999;; The advice-info of an advised function contains its `origname' which is
@@ -2019,8 +2013,7 @@ Redefining advices affect the construction of an advised definition."
2019 (symbol-function origname)))) 2013 (symbol-function origname))))
2020 2014
2021(defmacro ad-set-orig-definition (function definition) 2015(defmacro ad-set-orig-definition (function definition)
2022 `(ad-safe-fset 2016 `(fset (ad-get-advice-info-field ,function 'origname) ,definition))
2023 (ad-get-advice-info-field ,function 'origname) ,definition))
2024 2017
2025(defmacro ad-clear-orig-definition (function) 2018(defmacro ad-clear-orig-definition (function)
2026 `(fmakunbound (ad-get-advice-info-field ,function 'origname))) 2019 `(fmakunbound (ad-get-advice-info-field ,function 'origname)))
@@ -3151,7 +3144,7 @@ advised definition from scratch."
3151 (ad-set-advice-info function old-advice-info) 3144 (ad-set-advice-info function old-advice-info)
3152 ;; Don't `fset' function to nil if it was previously unbound: 3145 ;; Don't `fset' function to nil if it was previously unbound:
3153 (if function-defined-p 3146 (if function-defined-p
3154 (ad-safe-fset function old-definition) 3147 (fset function old-definition)
3155 (fmakunbound function))))) 3148 (fmakunbound function)))))
3156 3149
3157 3150
@@ -3182,61 +3175,54 @@ advised definition from scratch."
3182 (error 3175 (error
3183 "ad-make-freeze-definition: `%s' is not yet defined" 3176 "ad-make-freeze-definition: `%s' is not yet defined"
3184 function)) 3177 function))
3185 (let* ((name (ad-advice-name advice)) 3178 (cl-letf*
3186 ;; With a unique origname we can have multiple freeze advices 3179 ((name (ad-advice-name advice))
3187 ;; for the same function, each overloading the previous one: 3180 ;; With a unique origname we can have multiple freeze advices
3188 (unique-origname 3181 ;; for the same function, each overloading the previous one:
3189 (intern (format "%s-%s-%s" (ad-make-origname function) class name))) 3182 (unique-origname
3190 (orig-definition 3183 (intern (format "%s-%s-%s" (ad-make-origname function) class name)))
3191 ;; If FUNCTION is already advised, we'll use its current origdef 3184 (orig-definition
3192 ;; as the original definition of the frozen advice: 3185 ;; If FUNCTION is already advised, we'll use its current origdef
3193 (or (ad-get-orig-definition function) 3186 ;; as the original definition of the frozen advice:
3194 (symbol-function function))) 3187 (or (ad-get-orig-definition function)
3195 (old-advice-info 3188 (symbol-function function)))
3196 (if (ad-is-advised function) 3189 (old-advice-info
3197 (ad-copy-advice-info function))) 3190 (if (ad-is-advised function)
3198 (real-docstring-fn 3191 (ad-copy-advice-info function)))
3199 (symbol-function 'ad-make-advised-definition-docstring)) 3192 ;; Make sure we construct a proper docstring:
3200 (real-origname-fn 3193 ((symbol-function 'ad-make-advised-definition-docstring)
3201 (symbol-function 'ad-make-origname)) 3194 #'ad-make-freeze-docstring)
3202 (frozen-definition 3195 ;; Make sure `unique-origname' is used as the origname:
3203 (unwind-protect 3196 ((symbol-function 'ad-make-origname) (lambda (_x) unique-origname))
3204 (progn 3197 (frozen-definition
3205 ;; Make sure we construct a proper docstring: 3198 (unwind-protect
3206 (ad-safe-fset 'ad-make-advised-definition-docstring 3199 (progn
3207 'ad-make-freeze-docstring) 3200 ;; No we reset all current advice information to nil and
3208 ;; Make sure `unique-origname' is used as the origname: 3201 ;; generate an advised definition that's solely determined
3209 (ad-safe-fset 'ad-make-origname (lambda (_x) unique-origname)) 3202 ;; by ADVICE and the current origdef of FUNCTION:
3210 ;; No we reset all current advice information to nil and 3203 (ad-set-advice-info function nil)
3211 ;; generate an advised definition that's solely determined 3204 (ad-add-advice function advice class position)
3212 ;; by ADVICE and the current origdef of FUNCTION: 3205 ;; The following will provide proper real docstrings as
3213 (ad-set-advice-info function nil) 3206 ;; well as a definition that will make the compiler happy:
3214 (ad-add-advice function advice class position) 3207 (ad-set-orig-definition function orig-definition)
3215 ;; The following will provide proper real docstrings as 3208 (ad-make-advised-definition function))
3216 ;; well as a definition that will make the compiler happy: 3209 ;; Restore the old advice state:
3217 (ad-set-orig-definition function orig-definition) 3210 (ad-set-advice-info function old-advice-info))))
3218 (ad-make-advised-definition function))
3219 ;; Restore the old advice state:
3220 (ad-set-advice-info function old-advice-info)
3221 ;; Restore functions:
3222 (ad-safe-fset
3223 'ad-make-advised-definition-docstring real-docstring-fn)
3224 (ad-safe-fset 'ad-make-origname real-origname-fn))))
3225 (if frozen-definition 3211 (if frozen-definition
3226 (let* ((macro-p (ad-macro-p frozen-definition)) 3212 (let* ((macro-p (ad-macro-p frozen-definition))
3227 (body (cdr (if macro-p 3213 (body (cdr (if macro-p
3228 (ad-lambdafy frozen-definition) 3214 (ad-lambdafy frozen-definition)
3229 frozen-definition)))) 3215 frozen-definition))))
3230 `(progn 3216 `(progn
3231 (if (not (fboundp ',unique-origname)) 3217 (if (not (fboundp ',unique-origname))
3232 (fset ',unique-origname 3218 (fset ',unique-origname
3233 ;; avoid infinite recursion in case the function 3219 ;; avoid infinite recursion in case the function
3234 ;; we want to freeze is already advised: 3220 ;; we want to freeze is already advised:
3235 (or (ad-get-orig-definition ',function) 3221 (or (ad-get-orig-definition ',function)
3236 (symbol-function ',function)))) 3222 (symbol-function ',function))))
3237 (,(if macro-p 'defmacro 'defun) 3223 (,(if macro-p 'defmacro 'defun)
3238 ,function 3224 ,function
3239 ,@body)))))) 3225 ,@body))))))
3240 3226
3241 3227
3242;; @@ Activation and definition handling: 3228;; @@ Activation and definition handling:
@@ -3269,7 +3255,7 @@ The current definition and its cache-id will be put into the cache."
3269 (let ((verified-cached-definition 3255 (let ((verified-cached-definition
3270 (if (ad-verify-cache-id function) 3256 (if (ad-verify-cache-id function)
3271 (ad-get-cache-definition function)))) 3257 (ad-get-cache-definition function))))
3272 (ad-safe-fset function 3258 (fset function
3273 (or verified-cached-definition 3259 (or verified-cached-definition
3274 (ad-make-advised-definition function))) 3260 (ad-make-advised-definition function)))
3275 (if (ad-should-compile function compile) 3261 (if (ad-should-compile function compile)
@@ -3311,7 +3297,7 @@ the value of `ad-redefinition-action' and de/activate again."
3311 (error "ad-handle-definition (see its doc): `%s' %s" 3297 (error "ad-handle-definition (see its doc): `%s' %s"
3312 function "invalidly redefined") 3298 function "invalidly redefined")
3313 (if (eq ad-redefinition-action 'discard) 3299 (if (eq ad-redefinition-action 'discard)
3314 (ad-safe-fset function original-definition) 3300 (fset function original-definition)
3315 (ad-set-orig-definition function current-definition) 3301 (ad-set-orig-definition function current-definition)
3316 (if (eq ad-redefinition-action 'warn) 3302 (if (eq ad-redefinition-action 'warn)
3317 (message "ad-handle-definition: `%s' got redefined" 3303 (message "ad-handle-definition: `%s' got redefined"
@@ -3386,7 +3372,7 @@ a call to `ad-activate'."
3386 (if (not (ad-get-orig-definition function)) 3372 (if (not (ad-get-orig-definition function))
3387 (error "ad-deactivate: `%s' has no original definition" 3373 (error "ad-deactivate: `%s' has no original definition"
3388 function) 3374 function)
3389 (ad-safe-fset function (ad-get-orig-definition function)) 3375 (fset function (ad-get-orig-definition function))
3390 (ad-set-advice-info-field function 'active nil) 3376 (ad-set-advice-info-field function 'active nil)
3391 (eval (ad-make-hook-form function 'deactivation)) 3377 (eval (ad-make-hook-form function 'deactivation))
3392 function))))) 3378 function)))))
@@ -3424,7 +3410,7 @@ Use in emergencies."
3424 (completing-read "Recover advised function: " obarray nil t)))) 3410 (completing-read "Recover advised function: " obarray nil t))))
3425 (cond ((ad-is-advised function) 3411 (cond ((ad-is-advised function)
3426 (cond ((ad-get-orig-definition function) 3412 (cond ((ad-get-orig-definition function)
3427 (ad-safe-fset function (ad-get-orig-definition function)) 3413 (fset function (ad-get-orig-definition function))
3428 (ad-clear-orig-definition function))) 3414 (ad-clear-orig-definition function)))
3429 (ad-set-advice-info function nil) 3415 (ad-set-advice-info function nil)
3430 (ad-pop-advised-function function)))) 3416 (ad-pop-advised-function function))))
@@ -3658,8 +3644,7 @@ undone on exit of this macro."
3658 (setq index -1) 3644 (setq index -1)
3659 (mapcar (lambda (function) 3645 (mapcar (lambda (function)
3660 (setq index (1+ index)) 3646 (setq index (1+ index))
3661 `(ad-safe-fset 3647 `(fset ',function
3662 ',function
3663 (or (ad-get-orig-definition ',function) 3648 (or (ad-get-orig-definition ',function)
3664 ,(car (nth index current-bindings))))) 3649 ,(car (nth index current-bindings)))))
3665 functions)) 3650 functions))
@@ -3670,8 +3655,7 @@ undone on exit of this macro."
3670 (setq index -1) 3655 (setq index -1)
3671 (mapcar (lambda (function) 3656 (mapcar (lambda (function)
3672 (setq index (1+ index)) 3657 (setq index (1+ index))
3673 `(ad-safe-fset 3658 `(fset ',function
3674 ',function
3675 ,(car (nth index current-bindings)))) 3659 ,(car (nth index current-bindings))))
3676 functions)))))) 3660 functions))))))
3677 3661
@@ -3684,7 +3668,7 @@ undone on exit of this macro."
3684 (interactive) 3668 (interactive)
3685 ;; Advising `ad-activate-internal' means death!! 3669 ;; Advising `ad-activate-internal' means death!!
3686 (ad-set-advice-info 'ad-activate-internal nil) 3670 (ad-set-advice-info 'ad-activate-internal nil)
3687 (ad-safe-fset 'ad-activate-internal 'ad-activate)) 3671 (fset 'ad-activate-internal 'ad-activate))
3688 3672
3689(defun ad-stop-advice () 3673(defun ad-stop-advice ()
3690 "Stop the automatic advice handling magic. 3674 "Stop the automatic advice handling magic.
@@ -3692,7 +3676,7 @@ You should only need this in case of Advice-related emergencies."
3692 (interactive) 3676 (interactive)
3693 ;; Advising `ad-activate-internal' means death!! 3677 ;; Advising `ad-activate-internal' means death!!
3694 (ad-set-advice-info 'ad-activate-internal nil) 3678 (ad-set-advice-info 'ad-activate-internal nil)
3695 (ad-safe-fset 'ad-activate-internal 'ad-activate-internal-off)) 3679 (fset 'ad-activate-internal 'ad-activate-internal-off))
3696 3680
3697(defun ad-recover-normality () 3681(defun ad-recover-normality ()
3698 "Undo all advice related redefinitions and unadvises everything. 3682 "Undo all advice related redefinitions and unadvises everything.
@@ -3700,7 +3684,7 @@ Use only in REAL emergencies."
3700 (interactive) 3684 (interactive)
3701 ;; Advising `ad-activate-internal' means death!! 3685 ;; Advising `ad-activate-internal' means death!!
3702 (ad-set-advice-info 'ad-activate-internal nil) 3686 (ad-set-advice-info 'ad-activate-internal nil)
3703 (ad-safe-fset 'ad-activate-internal 'ad-activate-internal-off) 3687 (fset 'ad-activate-internal 'ad-activate-internal-off)
3704 (ad-recover-all) 3688 (ad-recover-all)
3705 (ad-do-advised-functions (function) 3689 (ad-do-advised-functions (function)
3706 (message "Oops! Left over advised function %S" function) 3690 (message "Oops! Left over advised function %S" function)
diff --git a/src/ChangeLog b/src/ChangeLog
index 43d60936d70..da3e96bbcc3 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@
12012-11-09 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * lisp.h (AUTOLOADP): New macro.
4 * eval.c (Fautoload): Don't attach to loadhist, call Fdefalias instead.
5 * data.c (Ffset): Remove special ad-advice-info handling.
6 (Fdefalias): Handle autoload definitions and new Qdefalias_fset_function.
7 (Fsubr_arity): CSE.
8 (Finteractive_form): Simplify.
9 (Fquo): Don't insist on having at least 2 arguments.
10 (Qdefalias_fset_function): New var.
11
12012-11-09 Jan Djärv <jan.h.d@swipnet.se> 122012-11-09 Jan Djärv <jan.h.d@swipnet.se>
2 13
3 * image.c (xpm_make_color_table_h): Change to hashtest_equal. 14 * image.c (xpm_make_color_table_h): Change to hashtest_equal.
@@ -26,7 +37,7 @@
26 37
272012-11-09 Jan Djärv <jan.h.d@swipnet.se> 382012-11-09 Jan Djärv <jan.h.d@swipnet.se>
28 39
29 * nsfont.m (ns_descriptor_to_entity): Qcondesed and Qexpanded has 40 * nsfont.m (ns_descriptor_to_entity): Qcondensed and Qexpanded has
30 been removed, so remove them here also. 41 been removed, so remove them here also.
31 42
322012-11-09 Stefan Monnier <monnier@iro.umontreal.ca> 432012-11-09 Stefan Monnier <monnier@iro.umontreal.ca>
diff --git a/src/data.c b/src/data.c
index abcdd4dca0d..663e25e7063 100644
--- a/src/data.c
+++ b/src/data.c
@@ -80,7 +80,7 @@ static Lisp_Object Qsubrp, Qmany, Qunevalled;
80Lisp_Object Qfont_spec, Qfont_entity, Qfont_object; 80Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
81static Lisp_Object Qdefun; 81static Lisp_Object Qdefun;
82 82
83Lisp_Object Qinteractive_form; 83Lisp_Object Qinteractive_form, Qdefalias_fset_function;
84 84
85static void swap_in_symval_forwarding (struct Lisp_Symbol *, struct Lisp_Buffer_Local_Value *); 85static void swap_in_symval_forwarding (struct Lisp_Symbol *, struct Lisp_Buffer_Local_Value *);
86 86
@@ -444,7 +444,7 @@ DEFUN ("floatp", Ffloatp, Sfloatp, 1, 1, 0,
444} 444}
445 445
446 446
447/* Extract and set components of lists */ 447/* Extract and set components of lists. */
448 448
449DEFUN ("car", Fcar, Scar, 1, 1, 0, 449DEFUN ("car", Fcar, Scar, 1, 1, 0,
450 doc: /* Return the car of LIST. If arg is nil, return nil. 450 doc: /* Return the car of LIST. If arg is nil, return nil.
@@ -608,27 +608,18 @@ DEFUN ("fset", Ffset, Sfset, 2, 2, 0,
608 (register Lisp_Object symbol, Lisp_Object definition) 608 (register Lisp_Object symbol, Lisp_Object definition)
609{ 609{
610 register Lisp_Object function; 610 register Lisp_Object function;
611
612 CHECK_SYMBOL (symbol); 611 CHECK_SYMBOL (symbol);
613 if (NILP (symbol) || EQ (symbol, Qt))
614 xsignal1 (Qsetting_constant, symbol);
615 612
616 function = XSYMBOL (symbol)->function; 613 function = XSYMBOL (symbol)->function;
617 614
618 if (!NILP (Vautoload_queue) && !EQ (function, Qunbound)) 615 if (!NILP (Vautoload_queue) && !EQ (function, Qunbound))
619 Vautoload_queue = Fcons (Fcons (symbol, function), Vautoload_queue); 616 Vautoload_queue = Fcons (Fcons (symbol, function), Vautoload_queue);
620 617
621 if (CONSP (function) && EQ (XCAR (function), Qautoload)) 618 if (AUTOLOADP (function))
622 Fput (symbol, Qautoload, XCDR (function)); 619 Fput (symbol, Qautoload, XCDR (function));
623 620
624 set_symbol_function (symbol, definition); 621 set_symbol_function (symbol, definition);
625 /* Handle automatic advice activation. */ 622
626 if (CONSP (XSYMBOL (symbol)->plist)
627 && !NILP (Fget (symbol, Qad_advice_info)))
628 {
629 call2 (Qad_activate_internal, symbol, Qnil);
630 definition = XSYMBOL (symbol)->function;
631 }
632 return definition; 623 return definition;
633} 624}
634 625
@@ -642,15 +633,32 @@ The return value is undefined. */)
642 (register Lisp_Object symbol, Lisp_Object definition, Lisp_Object docstring) 633 (register Lisp_Object symbol, Lisp_Object definition, Lisp_Object docstring)
643{ 634{
644 CHECK_SYMBOL (symbol); 635 CHECK_SYMBOL (symbol);
645 if (CONSP (XSYMBOL (symbol)->function)
646 && EQ (XCAR (XSYMBOL (symbol)->function), Qautoload))
647 LOADHIST_ATTACH (Fcons (Qt, symbol));
648 if (!NILP (Vpurify_flag) 636 if (!NILP (Vpurify_flag)
649 /* If `definition' is a keymap, immutable (and copying) is wrong. */ 637 /* If `definition' is a keymap, immutable (and copying) is wrong. */
650 && !KEYMAPP (definition)) 638 && !KEYMAPP (definition))
651 definition = Fpurecopy (definition); 639 definition = Fpurecopy (definition);
652 definition = Ffset (symbol, definition); 640
653 LOADHIST_ATTACH (Fcons (Qdefun, symbol)); 641 {
642 bool autoload = AUTOLOADP (definition);
643 if (NILP (Vpurify_flag) || !autoload)
644 { /* Only add autoload entries after dumping, because the ones before are
645 not useful and else we get loads of them from the loaddefs.el. */
646
647 if (AUTOLOADP (XSYMBOL (symbol)->function))
648 /* Remember that the function was already an autoload. */
649 LOADHIST_ATTACH (Fcons (Qt, symbol));
650 LOADHIST_ATTACH (Fcons (autoload ? Qautoload : Qdefun, symbol));
651 }
652 }
653
654 { /* Handle automatic advice activation. */
655 Lisp_Object hook = Fget (symbol, Qdefalias_fset_function);
656 if (!NILP (hook))
657 call2 (hook, symbol, definition);
658 else
659 Ffset (symbol, definition);
660 }
661
654 if (!NILP (docstring)) 662 if (!NILP (docstring))
655 Fput (symbol, Qfunction_documentation, docstring); 663 Fput (symbol, Qfunction_documentation, docstring);
656 /* We used to return `definition', but now that `defun' and `defmacro' expand 664 /* We used to return `definition', but now that `defun' and `defmacro' expand
@@ -680,12 +688,10 @@ function with `&rest' args, or `unevalled' for a special form. */)
680 CHECK_SUBR (subr); 688 CHECK_SUBR (subr);
681 minargs = XSUBR (subr)->min_args; 689 minargs = XSUBR (subr)->min_args;
682 maxargs = XSUBR (subr)->max_args; 690 maxargs = XSUBR (subr)->max_args;
683 if (maxargs == MANY) 691 return Fcons (make_number (minargs),
684 return Fcons (make_number (minargs), Qmany); 692 maxargs == MANY ? Qmany
685 else if (maxargs == UNEVALLED) 693 : maxargs == UNEVALLED ? Qunevalled
686 return Fcons (make_number (minargs), Qunevalled); 694 : make_number (maxargs));
687 else
688 return Fcons (make_number (minargs), make_number (maxargs));
689} 695}
690 696
691DEFUN ("subr-name", Fsubr_name, Ssubr_name, 1, 1, 0, 697DEFUN ("subr-name", Fsubr_name, Ssubr_name, 1, 1, 0,
@@ -711,7 +717,7 @@ Value, if non-nil, is a list \(interactive SPEC). */)
711 return Qnil; 717 return Qnil;
712 718
713 /* Use an `interactive-form' property if present, analogous to the 719 /* Use an `interactive-form' property if present, analogous to the
714 function-documentation property. */ 720 function-documentation property. */
715 fun = cmd; 721 fun = cmd;
716 while (SYMBOLP (fun)) 722 while (SYMBOLP (fun))
717 { 723 {
@@ -735,6 +741,8 @@ Value, if non-nil, is a list \(interactive SPEC). */)
735 if ((ASIZE (fun) & PSEUDOVECTOR_SIZE_MASK) > COMPILED_INTERACTIVE) 741 if ((ASIZE (fun) & PSEUDOVECTOR_SIZE_MASK) > COMPILED_INTERACTIVE)
736 return list2 (Qinteractive, AREF (fun, COMPILED_INTERACTIVE)); 742 return list2 (Qinteractive, AREF (fun, COMPILED_INTERACTIVE));
737 } 743 }
744 else if (AUTOLOADP (fun))
745 return Finteractive_form (Fautoload_do_load (fun, cmd, Qnil));
738 else if (CONSP (fun)) 746 else if (CONSP (fun))
739 { 747 {
740 Lisp_Object funcar = XCAR (fun); 748 Lisp_Object funcar = XCAR (fun);
@@ -742,14 +750,6 @@ Value, if non-nil, is a list \(interactive SPEC). */)
742 return Fassq (Qinteractive, Fcdr (Fcdr (XCDR (fun)))); 750 return Fassq (Qinteractive, Fcdr (Fcdr (XCDR (fun))));
743 else if (EQ (funcar, Qlambda)) 751 else if (EQ (funcar, Qlambda))
744 return Fassq (Qinteractive, Fcdr (XCDR (fun))); 752 return Fassq (Qinteractive, Fcdr (XCDR (fun)));
745 else if (EQ (funcar, Qautoload))
746 {
747 struct gcpro gcpro1;
748 GCPRO1 (cmd);
749 Fautoload_do_load (fun, cmd, Qnil);
750 UNGCPRO;
751 return Finteractive_form (cmd);
752 }
753 } 753 }
754 return Qnil; 754 return Qnil;
755} 755}
@@ -2695,10 +2695,10 @@ usage: (* &rest NUMBERS-OR-MARKERS) */)
2695 return arith_driver (Amult, nargs, args); 2695 return arith_driver (Amult, nargs, args);
2696} 2696}
2697 2697
2698DEFUN ("/", Fquo, Squo, 2, MANY, 0, 2698DEFUN ("/", Fquo, Squo, 1, MANY, 0,
2699 doc: /* Return first argument divided by all the remaining arguments. 2699 doc: /* Return first argument divided by all the remaining arguments.
2700The arguments must be numbers or markers. 2700The arguments must be numbers or markers.
2701usage: (/ DIVIDEND DIVISOR &rest DIVISORS) */) 2701usage: (/ DIVIDEND &rest DIVISORS) */)
2702 (ptrdiff_t nargs, Lisp_Object *args) 2702 (ptrdiff_t nargs, Lisp_Object *args)
2703{ 2703{
2704 ptrdiff_t argnum; 2704 ptrdiff_t argnum;
@@ -3063,6 +3063,7 @@ syms_of_data (void)
3063 DEFSYM (Qfont_object, "font-object"); 3063 DEFSYM (Qfont_object, "font-object");
3064 3064
3065 DEFSYM (Qinteractive_form, "interactive-form"); 3065 DEFSYM (Qinteractive_form, "interactive-form");
3066 DEFSYM (Qdefalias_fset_function, "defalias-fset-function");
3066 3067
3067 defsubr (&Sindirect_variable); 3068 defsubr (&Sindirect_variable);
3068 defsubr (&Sinteractive_form); 3069 defsubr (&Sinteractive_form);
diff --git a/src/eval.c b/src/eval.c
index 975204da017..dcd48cb7250 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1876,26 +1876,19 @@ this does nothing and returns nil. */)
1876 CHECK_STRING (file); 1876 CHECK_STRING (file);
1877 1877
1878 /* If function is defined and not as an autoload, don't override. */ 1878 /* If function is defined and not as an autoload, don't override. */
1879 if ((CONSP (XSYMBOL (function)->function) 1879 if (!EQ (XSYMBOL (function)->function, Qunbound)
1880 && EQ (XCAR (XSYMBOL (function)->function), Qautoload))) 1880 && !AUTOLOADP (XSYMBOL (function)->function))
1881 /* Remember that the function was already an autoload. */
1882 LOADHIST_ATTACH (Fcons (Qt, function));
1883 else if (!EQ (XSYMBOL (function)->function, Qunbound))
1884 return Qnil; 1881 return Qnil;
1885 1882
1886 if (NILP (Vpurify_flag)) 1883 if (!NILP (Vpurify_flag) && EQ (docstring, make_number (0)))
1887 /* Only add entries after dumping, because the ones before are
1888 not useful and else we get loads of them from the loaddefs.el. */
1889 LOADHIST_ATTACH (Fcons (Qautoload, function));
1890 else if (EQ (docstring, make_number (0)))
1891 /* `read1' in lread.c has found the docstring starting with "\ 1884 /* `read1' in lread.c has found the docstring starting with "\
1892 and assumed the docstring will be provided by Snarf-documentation, so it 1885 and assumed the docstring will be provided by Snarf-documentation, so it
1893 passed us 0 instead. But that leads to accidental sharing in purecopy's 1886 passed us 0 instead. But that leads to accidental sharing in purecopy's
1894 hash-consing, so we use a (hopefully) unique integer instead. */ 1887 hash-consing, so we use a (hopefully) unique integer instead. */
1895 docstring = make_number (XUNTAG (function, Lisp_Symbol)); 1888 docstring = make_number (XHASH (function));
1896 return Ffset (function, 1889 return Fdefalias (function,
1897 Fpurecopy (list5 (Qautoload, file, docstring, 1890 list5 (Qautoload, file, docstring, interactive, type),
1898 interactive, type))); 1891 Qnil);
1899} 1892}
1900 1893
1901Lisp_Object 1894Lisp_Object
diff --git a/src/lisp.h b/src/lisp.h
index e2c1cc0e169..72e38fa4653 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1694,6 +1694,8 @@ typedef struct {
1694#define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker) 1694#define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker)
1695#define SAVE_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value) 1695#define SAVE_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value)
1696 1696
1697#define AUTOLOADP(x) (CONSP (x) && EQ (Qautoload, XCAR (x)))
1698
1697#define INTFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Int) 1699#define INTFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Int)
1698#define BOOLFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Bool) 1700#define BOOLFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Bool)
1699#define OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Obj) 1701#define OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Obj)