MLAMBDA: fix local property cleanup when binding fails
commit9e5f9a1b519dd12566c80390ad8038f2380ad3da
authorKris Katterjohn <katterjohn@gmail.com>
Sat, 15 Jan 2022 20:24:39 +0000 (15 15:24 -0500)
committerKris Katterjohn <katterjohn@gmail.com>
Sat, 15 Jan 2022 20:24:39 +0000 (15 15:24 -0500)
treec7baed5a9504c0fe82806ad507961945718ff57b
parent18d335607ab232e41a540d52d072f3655f915cd4
MLAMBDA: fix local property cleanup when binding fails

NIL is pushed onto the LOCLIST pdl early on in MLAMBDA, but MUNLOCAL
does not necessarily get called if an error occurs before evaluating
the body of the lambda expression.  This is a very old bug in Maxima.

One problem is related to the validation of parameters, and this is
only a problem when simp:false.  If an error occurs while validating
the lambda parameters, then MUNLOCAL is not called and LOCLIST does
not get cleaned up.  (See my commit 07287100 which started validating
lambda expressions during simplification.  Before this commit, this
problem also occurred when simp:true.)

Another problem is related to the attempt at actually binding the
parameters.  There is an UNWIND-PROTECT that is meant to handle
cleanup, but if binding fails then the cleanup does not actually
occur, and so LOCLIST does not get cleaned up.

LOCLIST not being cleaned up can cause various problems, such as the
leaking of local properties and the fact that LOCLIST can continue to
grow as errors occur:

(%i1) f () := (local (q), q () := 'oops, lambda ([], 1) (1))$

(%i2) f ()$
<error>

(%i3) q ();
(%o3) oops

(%i4) :lisp loclist
(($Q))

(%i4) f ()$
<error>

(%i5) :lisp loclist
(($Q) ($Q))

Now we wait until binding succeeds before pushing onto LOCLIST.  This
fixes both of the problems described above.

No problems with the test suite or share test suite.
src/mlisp.lisp