Subject: bug#76546: 30.1; Native compilation is corrupting lambdas/closures stored in variables after some time

From: Andrea Corallo <[email-masked]>
Date: Mon, 14 Apr 2025 05:59:13 -0400

Eli Zaretskii <[email-masked]> writes:

>> Date: Tue, 25 Feb 2025 11:27:58 +0100
>> From: Christian Johansson <[email-masked]>
>> 
>> There is something fishy going on, but it is a very slippery bug, I have 
>> trouble reproducing it but it started to happen when native compilation 
>> was introduced and it has significantly gotten worse with Emacs 30, I 
>> never happened before native-compilation was introduced.
>> 
>> Maybe you can give me some tips in building a reproducible test case? I 
>> will try to explain what happens. So prior to Emacs 30 there was only 
>> one bug I stumbled upon:
>> 
>> 1. When a lambda is stored in a variable in a lexical scoped file it 
>> stores a closure. After some time when native compilation has done its 
>> magic on the variable you will get an error when you try to output it 
>> like this:
>> (format "%S" my-native-compiled-variable) and Emacs crashes.
>> 
>> This happened every time my parser-generator library ran for a long time 
>> and then tried to output a parser file. The only solution to this was to 
>> not byte-compile the file that contained the lambdas that was later 
>> supposed to be printed to a file, this solution worked but it was a 
>> workaround due to this bug.
>> 
>> 
>> 2. After Emacs 30 it seems to corrupt strings with escape sequences 
>> inside lambdas inside variables, like this:
>> 
>> (setq my-lambda (lambda() (looking-at "<\\?=")))
>> 
>> After native-compilation has performed its magic on the variable the 
>> function body will become corrupted and it will become a invalid 
>> function body. This happens now to my major my phps-mode, I have 
>> reproduced the error on two machines with Emacs 30 and it has never 
>> occurred before Emacs 30 and there has been no recent changes to the 
>> plugin. If I just eval the function files anew the problem disappears so 
>> it only happens in compiled files. It however does not happen in 
>> byte-compiled files, only in native compiled files.
>
> Andrea, any comments or suggestions?

I can't reproduce this on master.  I've:

test.el:
======
;; -*- lexical-binding: t -*-                                                        
(setq my-lambda (lambda() (looking-at "<\\?=")))
======

If I run emacs:
$ emacs --batch -eval '(progn (load (native-compile "/home/andcor03/test/test.el")) (funcall my-lambda))'

Seems to work for me.  Not sure if the reproducer should be something
different tho.

  Andrea