Subject: bug#58509: 29.0.50; Synchronous nativecomp

From: Lars Ingebrigtsen <[email-masked]>
Date: Mon, 17 Oct 2022 13:57:21 +0200

Lars Ingebrigtsen <[email-masked]> writes:

> I.e., EMACS_INHIBIT_AUTOMATIC_NATIVE_COMPILATION=full when forking the
> compiling Emacs would do the trick without introducing yet another
> twiddle here.

Something like the following simple patch.

I think this should fix the fork bomb problem, and it doesn't seem to
introduce any other problems, but I've only tested it for a couple
minutes.

diff --git a/doc/lispref/compile.texi b/doc/lispref/compile.texi
index 6f8431c55c..3ac4e90c2a 100644
--- a/doc/lispref/compile.texi
+++ b/doc/lispref/compile.texi
@@ -993,10 +993,14 @@ Native-Compilation Variables
 While setting this variable disables automatic compilation of Lisp
 files, the compiler may still be invoked to install @dfn{trampolines}
 if any built-in functions are redefined.  However, these trampolines
-will not get written to your cache directory.
+will not get written to your cache directory.  If this variable has
+the special value @code{full}, even trampoline installation is
+inhibited, which means that redefinition of built-in functions isn't
+possible.
 
 You can also use the @samp{EMACS_INHIBIT_AUTOMATIC_NATIVE_COMPILATION}
-environment variable to disable native compilation.
+environment variable to disable automatic native compilation.  If it's
+@samp{"full"}, trampoline generation is also inhibited.
 @end defvar
 
 @defopt native-comp-speed
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index c300c44a8d..91851ad0f4 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -693,6 +693,7 @@ 'native-compiler-error-empty-byte
 (defun comp-subr-trampoline-install (subr-name)
   "Make SUBR-NAME effectively advice-able when called from native code."
   (unless (or (null comp-enable-subr-trampolines)
+              (eq inhibit-automatic-native-compilation 'full)
               (memq subr-name native-comp-never-optimize-functions)
               (gethash subr-name comp-installed-trampolines-h))
     (cl-assert (subr-primitive-p (symbol-function subr-name)))
@@ -3713,9 +3714,13 @@ comp-final
 	(with-temp-buffer
           (unwind-protect
               (if (zerop
-                   (call-process (expand-file-name invocation-name
-                                                   invocation-directory)
-				 nil t t "--batch" "-l" temp-file))
+                   (let ((process-environment
+                          (cons
+                           "EMACS_INHIBIT_AUTOMATIC_NATIVE_COMPILATION=full"
+                           process-environment)))
+                     (call-process (expand-file-name invocation-name
+                                                     invocation-directory)
+				   nil t t "--batch" "-l" temp-file)))
                   (progn
                     (delete-file temp-file)
                     output)
diff --git a/lisp/startup.el b/lisp/startup.el
index 725984b815..7238bcc1cf 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -580,8 +580,12 @@ normal-top-level
 reads the initialization files, etc.
 It is the default value of the variable `top-level'."
   ;; Allow disabling automatic .elc->.eln processing.
-  (setq inhibit-automatic-native-compilation
-        (getenv "EMACS_INHIBIT_AUTOMATIC_NATIVE_COMPILATION"))
+  (let ((inhibit (getenv "EMACS_INHIBIT_AUTOMATIC_NATIVE_COMPILATION")))
+    (when inhibit
+      (setq inhibit-automatic-native-compilation
+            (if (equal inhibit "full")
+                'full
+              t))))
 
   (if command-line-processed
       (message internal--top-level-message)
diff --git a/src/comp.c b/src/comp.c
index 14012634cc..946816e069 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -5682,6 +5682,12 @@ syms_of_comp (void)
 	       Vinhibit_automatic_native_compilation,
 	       doc: /* If non-nil, inhibit automatic native compilation of loaded .elc files.
 
+If `full', also inhibit trampoline generation.  Any other non-nil
+value will inhibit automatic native compilation of loaded .elc files,
+but will still generate trampolines (without writing them to the eln
+cache).  If `full', it's no longer possible to reliably redefine
+built-in functions.
+
 After compilation, each function definition is updated to the native
 compiled one.  */);
   Vinhibit_automatic_native_compilation = Qnil;