diff options
| author | Andrea Corallo | 2020-03-23 15:57:48 +0000 |
|---|---|---|
| committer | Andrea Corallo | 2020-03-23 20:37:59 +0000 |
| commit | f8b07ff4f318d799a471c9363903e3929fd5c844 (patch) | |
| tree | 060a73d3902fe84ecdbad5a8464f652b22a5eb4c | |
| parent | eb1d22b136a3f7a49b4060553b79ee188f55a498 (diff) | |
| download | emacs-f8b07ff4f318d799a471c9363903e3929fd5c844.tar.gz emacs-f8b07ff4f318d799a471c9363903e3929fd5c844.zip | |
Guard against function redefinition during deferred load
| -rw-r--r-- | lisp/emacs-lisp/comp.el | 10 | ||||
| -rw-r--r-- | src/comp.c | 39 |
2 files changed, 39 insertions, 10 deletions
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el index 273b41f5427..c6f2ca13aab 100644 --- a/lisp/emacs-lisp/comp.el +++ b/lisp/emacs-lisp/comp.el | |||
| @@ -1160,12 +1160,15 @@ the annotation emission." | |||
| 1160 | (cl-defgeneric comp-emit-for-top-level (form for-late-load) | 1160 | (cl-defgeneric comp-emit-for-top-level (form for-late-load) |
| 1161 | "Emit the limple code for top level FORM.") | 1161 | "Emit the limple code for top level FORM.") |
| 1162 | 1162 | ||
| 1163 | (cl-defmethod comp-emit-for-top-level ((form byte-to-native-function) _) | 1163 | (cl-defmethod comp-emit-for-top-level ((form byte-to-native-function) |
| 1164 | for-late-load) | ||
| 1164 | (let* ((name (byte-to-native-function-name form)) | 1165 | (let* ((name (byte-to-native-function-name form)) |
| 1165 | (f (gethash name (comp-ctxt-funcs-h comp-ctxt))) | 1166 | (f (gethash name (comp-ctxt-funcs-h comp-ctxt))) |
| 1166 | (args (comp-func-args f))) | 1167 | (args (comp-func-args f))) |
| 1167 | (cl-assert (and name f)) | 1168 | (cl-assert (and name f)) |
| 1168 | (comp-emit (comp-call 'comp--register-subr | 1169 | (comp-emit (comp-call (if for-late-load |
| 1170 | 'comp--late-register-subr | ||
| 1171 | 'comp--register-subr) | ||
| 1169 | (make-comp-mvar :constant name) | 1172 | (make-comp-mvar :constant name) |
| 1170 | (make-comp-mvar :constant (comp-args-base-min args)) | 1173 | (make-comp-mvar :constant (comp-args-base-min args)) |
| 1171 | (make-comp-mvar :constant (if (comp-args-p args) | 1174 | (make-comp-mvar :constant (if (comp-args-p args) |
| @@ -2186,6 +2189,9 @@ display a message." | |||
| 2186 | (save-excursion | 2189 | (save-excursion |
| 2187 | (goto-char (point-max)) | 2190 | (goto-char (point-max)) |
| 2188 | (insert msg "\n"))) | 2191 | (insert msg "\n"))) |
| 2192 | ;; `comp-deferred-pending-h' should be empty at this stage. | ||
| 2193 | ;; Reset it anyway. | ||
| 2194 | (setf comp-deferred-pending-h (make-hash-table :equal #'eq)) | ||
| 2189 | (message msg)))) | 2195 | (message msg)))) |
| 2190 | 2196 | ||
| 2191 | 2197 | ||
diff --git a/src/comp.c b/src/comp.c index b563f27da8f..3205a29a104 100644 --- a/src/comp.c +++ b/src/comp.c | |||
| @@ -3401,14 +3401,16 @@ maybe_defer_native_compilation (Lisp_Object function_name, | |||
| 3401 | Lisp_Object src = | 3401 | Lisp_Object src = |
| 3402 | concat2 (CALL1I (file-name-sans-extension, Vload_file_name), | 3402 | concat2 (CALL1I (file-name-sans-extension, Vload_file_name), |
| 3403 | build_pure_c_string (".el")); | 3403 | build_pure_c_string (".el")); |
| 3404 | if (!NILP (Ffile_exists_p (src))) | 3404 | if (NILP (Ffile_exists_p (src))) |
| 3405 | { | 3405 | return; |
| 3406 | comp_deferred_compilation = false; | 3406 | |
| 3407 | Frequire (intern_c_string ("comp"), Qnil, Qnil); | 3407 | /* Really happening. */ |
| 3408 | comp_deferred_compilation = true; | 3408 | Fputhash (function_name, definition, Vcomp_deferred_pending_h); |
| 3409 | CALLN (Ffuncall, intern_c_string ("native-compile-async"), src, Qnil, | 3409 | comp_deferred_compilation = false; |
| 3410 | Qlate); | 3410 | Frequire (intern_c_string ("comp"), Qnil, Qnil); |
| 3411 | } | 3411 | comp_deferred_compilation = true; |
| 3412 | CALLN (Ffuncall, intern_c_string ("native-compile-async"), src, Qnil, | ||
| 3413 | Qlate); | ||
| 3412 | } | 3414 | } |
| 3413 | 3415 | ||
| 3414 | 3416 | ||
| @@ -3584,6 +3586,21 @@ DEFUN ("comp--register-subr", Fcomp__register_subr, Scomp__register_subr, | |||
| 3584 | return Qnil; | 3586 | return Qnil; |
| 3585 | } | 3587 | } |
| 3586 | 3588 | ||
| 3589 | DEFUN ("comp--late-register-subr", Fcomp__late_register_subr, | ||
| 3590 | Scomp__late_register_subr, 7, 7, 0, | ||
| 3591 | doc: /* This gets called by late_top_level_run during load | ||
| 3592 | phase to register each exported subr. */) | ||
| 3593 | (Lisp_Object name, Lisp_Object minarg, Lisp_Object maxarg, | ||
| 3594 | Lisp_Object c_name, Lisp_Object doc, Lisp_Object intspec, | ||
| 3595 | Lisp_Object comp_u) | ||
| 3596 | { | ||
| 3597 | if (!NILP (Fequal (Fsymbol_function (name), | ||
| 3598 | Fgethash (name, Vcomp_deferred_pending_h, Qnil)))) | ||
| 3599 | Fcomp__register_subr (name, minarg, maxarg, c_name, doc, intspec, comp_u); | ||
| 3600 | Fremhash (name, Vcomp_deferred_pending_h); | ||
| 3601 | return Qnil; | ||
| 3602 | } | ||
| 3603 | |||
| 3587 | /* Load related routines. */ | 3604 | /* Load related routines. */ |
| 3588 | DEFUN ("native-elisp-load", Fnative_elisp_load, Snative_elisp_load, 1, 2, 0, | 3605 | DEFUN ("native-elisp-load", Fnative_elisp_load, Snative_elisp_load, 1, 2, 0, |
| 3589 | doc: /* Load native elisp code FILE. | 3606 | doc: /* Load native elisp code FILE. |
| @@ -3714,6 +3731,7 @@ syms_of_comp (void) | |||
| 3714 | defsubr (&Scomp__release_ctxt); | 3731 | defsubr (&Scomp__release_ctxt); |
| 3715 | defsubr (&Scomp__compile_ctxt_to_file); | 3732 | defsubr (&Scomp__compile_ctxt_to_file); |
| 3716 | defsubr (&Scomp__register_subr); | 3733 | defsubr (&Scomp__register_subr); |
| 3734 | defsubr (&Scomp__late_register_subr); | ||
| 3717 | defsubr (&Snative_elisp_load); | 3735 | defsubr (&Snative_elisp_load); |
| 3718 | 3736 | ||
| 3719 | staticpro (&comp.exported_funcs_h); | 3737 | staticpro (&comp.exported_funcs_h); |
| @@ -3742,6 +3760,11 @@ syms_of_comp (void) | |||
| 3742 | DEFVAR_LISP ("comp-native-path-postfix", Vcomp_native_path_postfix, | 3760 | DEFVAR_LISP ("comp-native-path-postfix", Vcomp_native_path_postfix, |
| 3743 | doc: /* Postifix to be added to the .eln compilation path. */); | 3761 | doc: /* Postifix to be added to the .eln compilation path. */); |
| 3744 | Vcomp_native_path_postfix = Qnil; | 3762 | Vcomp_native_path_postfix = Qnil; |
| 3763 | |||
| 3764 | DEFVAR_LISP ("comp-deferred-pending-h", Vcomp_deferred_pending_h, | ||
| 3765 | doc: /* Hash table symbol-name -> function-value. For | ||
| 3766 | internal use during */); | ||
| 3767 | Vcomp_deferred_pending_h = CALLN (Fmake_hash_table, QCtest, Qeq); | ||
| 3745 | } | 3768 | } |
| 3746 | 3769 | ||
| 3747 | #endif /* HAVE_NATIVE_COMP */ | 3770 | #endif /* HAVE_NATIVE_COMP */ |