Subject: bug#78898: Make read/readevalloop reentrant

From: Lynn Winebarger <[email-masked]>
Date: Sat, 2 Aug 2025 08:39:41 -0400

On Sat, Aug 2, 2025 at 7:42 AM Lynn Winebarger <[email-masked]> wrote:
> On Wed, Jul 30, 2025 at 9:08 AM Lynn Winebarger <[email-masked]> wrote:
> > Without the added block scope, the change becomes very simple.   No
> > new test failures (relative to the baseline commit of master) have
> > been added.  I can add a slow path for the case where the stack is
> > almost overflowing or the input is just ridiculously complicated.  For
> > files being loaded, I'd prefer to add a different source type that
> > either memory maps the file or slurps it into memory so we can safely
> > gauge a worst-case size for the slow path.  A similar approach would
> > apply to buffers, since they are already in memory.  For other stream
> > types being read, I think erroring out on expressions that would
> > overflow the stack is reasonable, given I can build emacs and run all
> > the tests without an overflow.  Stefan's preferred benchmark technique
> > would be problematic though.  It would almost certainly either
> > overflow or take the slow path.
>
> Another way to make this safer is to stop accumulating sequences on
> the stack and "reduce" those stack entries early (with Fcons).  That
> way, Stefan's benchmark would only add 1 to the maximum stack depth,
> rather than making the number of top-level forms the minimum stack
> depth.
> That will be my next increment.
Retract that.  It's already being done that way, so the maximum stack
depth should be approximately the maximum nesting depth of the
s-expression being read.

I'm a little confused about the reluctance to just allocate the read
stack on the C stack and aborting the read if it's too deep.

Then my next step may be to add a source type for sucking elc files
straight into memory (or memory mapping if available), to eliminate
the need for copying to a read buffer in the most common case.

Lynn