You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I think it would be very useful if functions could capture variables from their lexical scope as a constant. I know that enabling mutation from inside the closure makes ownership rules a bit hard and I read elsewhere that's why there are no closures yet, but perhaps limiting to constants would help enough to get us part way there?
Yeah, this has been discussed a while ago. To make this work, a function enclosing a variable would have to take it as an additional argument. To give a bit of background for others wondering:
WASM does not have nested functions as one is used to in JS, so
which obviously detaches the enclosed variable, leaving it technically mutable, but not propagating changes back to the closure, but is still a ok-ish placeholder until there's something better.
A proper implementation that allows mutating the variable would need to allocate a closure on the heap that contains a and redirect all accesses in both foo and bar to the closure. Issue here is lifetime because a function isn't represented by a heap object itself, making it necessary to find another way to free the closure's memory once the lifetime of all functions referencing it ends. This problem can be illustrated in
where the lifetime of the reference to bar returned by foo is the reference for the closure's lifetime. Also note that foo could be called multiple times, returning multiple closures that must become collected somehow.
We already discussed about closures and I think it definitely could implement before function references proposal. One main question is how handle closure's lifetime without GC/RC
Thinking about this a bit more: One first step to solve the GC issue could be to wrap a function table index in a heap object and returning a pointer to that instead of just a bare function index, of the form
where ClosureData is just a blob of data with no static type information. Instead, static type information goes into compiled functions in the form of loads and their offsets (if that's possible, still thinking). Now, whenever a function is called indirectly, the function index is loaded and data appended to the call. The reference to a function then becomes a reference to the closure (indexes aren't collected anyway), making the closure itself and its data collectible once not referenced anymore.
One missing building block for this is that the compiler must evaluate the conditions leading to a closure in a pre-pass, so it can replace accesses to locals before it sees the closure using them. That's the hard part (because the compiler is single-pass currently) :)
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Activity
dcodeIO commentedon Mar 28, 2019
Yeah, this has been discussed a while ago. To make this work, a function enclosing a variable would have to take it as an additional argument. To give a bit of background for others wondering:
WASM does not have nested functions as one is used to in JS, so
would have to compile to something like
which obviously detaches the enclosed variable, leaving it technically mutable, but not propagating changes back to the closure, but is still a ok-ish placeholder until there's something better.
A proper implementation that allows mutating the variable would need to allocate a closure on the heap that contains
aand redirect all accesses in bothfooandbarto the closure. Issue here is lifetime because a function isn't represented by a heap object itself, making it necessary to find another way to free the closure's memory once the lifetime of all functions referencing it ends. This problem can be illustrated inwhere the lifetime of the reference to
barreturned byfoois the reference for the closure's lifetime. Also note thatfoocould be called multiple times, returning multiple closures that must become collected somehow.singpolyma-shopify commentedon Mar 28, 2019
I'm working around it by using a
Closureclass for now, but it makes me feel like an old-timey Java dev ;)MaxGraey commentedon Mar 28, 2019
We already discussed about closures and I think it definitely could implement before
function references proposal. One main question is how handle closure's lifetime without GC/RCdcodeIO commentedon Mar 28, 2019
Thinking about this a bit more: One first step to solve the GC issue could be to wrap a function table index in a heap object and returning a pointer to that instead of just a bare function index, of the form
where
ClosureDatais just a blob of data with no static type information. Instead, static type information goes into compiled functions in the form of loads and their offsets (if that's possible, still thinking). Now, whenever a function is called indirectly, the function index is loaded anddataappended to the call. The reference to a function then becomes a reference to the closure (indexes aren't collected anyway), making the closure itself and its data collectible once not referenced anymore.One missing building block for this is that the compiler must evaluate the conditions leading to a closure in a pre-pass, so it can replace accesses to locals before it sees the closure using them. That's the hard part (because the compiler is single-pass currently) :)
stale commentedon Apr 27, 2019
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.