Subject: bug#60996: 29.0.60; Native compile fails to remove temp file for trampoline

From: Andrea Corallo <[email-masked]>
Date: Fri, 27 Jan 2023 09:51:04 +0000

Eli Zaretskii <[email-masked]> writes:

>> Cc: [email-masked], [email-masked]
>> Date: Thu, 26 Jan 2023 20:38:45 +0200
>> From: Eli Zaretskii <[email-masked]>
>> 
>> > The only case where we might do that AFAIR is when
>> > `inhibit-automatic-native-compilation' is used.  This was the infamous
>> > mechanism that was installed by Lars where, if I'm not wrong, we are
>> > supposed to compile a trampoline, load it, and remove it to pretend we
>> > didn't compiled anything :x
>> 
>> OK, this seems to be what is happening here, because we compile the
>> trampoline to a temporary directory.  Otherwise, I don't see why we
>> would do that, and why we would delete a trampoline we just compiled.
>
> Actually, I don't think I see where we delete the trampoline that we
> generated when inhibit-automatic-native-compilation is non-nil.  Can
> you point me to the code which does that?

Sure, the code behind this mechanism is not straightforward and took me
a bit to decipher it as well yesterday.

In `comp-trampoline-compile' when `inhibit-automatic-native-compilation'
is not nil we invoke `comp--native-compile' with the `output' parameter
set to null.

`comp--native-compile' after compiling does two things:

1- If the compilation input was a file returns the .eln filename

2- If the input was a lambda (the case for trampolines) it does return
the compiled subr.  To do that it preforms a load of the eln before
returning.

So in general what `comp--native-compile' returns is:

              (if (stringp function-or-file)
                   data
                 ;; So we return the compiled function.
                 (native-elisp-load data)))

But at the end of `comp--native-compile' this when was added

(when (and (not (stringp function-or-file))
                      (not output)
                      comp-ctxt
                      (comp-ctxt-output comp-ctxt)
                      (file-exists-p (comp-ctxt-output comp-ctxt)))
             (delete-file (comp-ctxt-output comp-ctxt)))

Took me a while to actually realize this is the unwindform of an
enormous `unwind-protect'.  Anyway this is the code that when `output'
is null (the case for trampolines) tries to performs the file
deletetion.

Best Regards

  Andrea