bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#51982: Erroneous handling of local variables in byte-compiled nested


From: Mattias Engdegård
Subject: bug#51982: Erroneous handling of local variables in byte-compiled nested lambdas
Date: Mon, 22 Nov 2021 18:35:18 +0100

> I just found a case where it doesn't work. A repaired patch will arrive soon 
> (we hope).

Not one but two patches for your enjoyment, representing two alternative 
solutions. Patch A is an extension of the original proposal and is simpler but 
perhaps less performant; patch B is messier but may result in better code.

To connect to the previous example, cconv transforms the function

(defun f (x)
  (lambda ()
    (let ((f (lambda () x)))
      (let ((x 'a))
        (list x (funcall f))))))

with patch A into

(defun f (x)
  (internal-make-closure
   nil (x) nil
   (let ((f (lambda (x) x)))
     (let ((x 'a)
           (closed-x (internal-get-closed-var 0)))
       (list x (funcall f closed-x))))))

and with patch B into

(defun f (x)
  (internal-make-closure
   nil (x) nil
   (let ((f (lambda (x) x)))
     (let ((x 'a))
       (list x (funcall f (internal-get-closed-var 0)))))))

This looks like a wash but the optimiser isn't able to elide that superfluous 
closed-x variable yet, and in Paul's original example the captured variable is 
only used in one conditional branch which makes it a loss to bind it up-front 
whereas it's very cheap to materialise at the call site (a single 
constant-pushing byte op).

On the other hand, patch B does abuse the cconv data structures a little (but 
it works!). We'll see if Stefan can stomach it.

(This reminds me: we should probably declare internal-get-closed-var as pure 
and error-free, even though it's not even an actual function.)

Attachment: bug51982-A.patch
Description: Binary data

Attachment: bug51982-B.patch
Description: Binary data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]