News for hackers. Stuff that matters.
Re:How an Engineering Company Chose to Migrate to D by WalterBright on Wednesday June 20, 2018 @02:30PM (#17358228)
D nested functions don't 'capture' variables from their enclosing scope. They can access them just like other code in the enclosing function.

This is achieved by adding a hidden parameter that is a pointer to the enclosing function's stack frame. This forms a threaded list so variables in nested enclosing functions can be accessed by walking that list.

This is the same way Pascal does it.

It also means that taking the address of a nested function produces a pair - a pointer to the function, and this hidden parameter to the enclosing stack frame.

Re:How an Engineering Company Chose to Migrate to D by JdeBP on Thursday June 21, 2018 @06:53AM (#17363812)
It's the same way that MetaWare implemented nested functions in its C/C++ compiler in the 1980s and 1990s, too. On top of that, MetaWare built iterators and an iterator-driven for mechanism. The yield() in an iterator was actually a nested function callback from the iterator to the body of the invoking for statement, which was turned into a nested function under the covers.

* http://jdebp.info./FGA/metaware-iterator-driven-for.html

In theory, the extra frame pointer mechanisms of the ENTER and LEAVE instructions in the Intel ISA were there for supporting this kind of nested function. MetaWare High C/C++ did not use them, preferring to use a variant calling convention where (if I recall correctly) ECX contained the extra hidden parameter.

Re:How an Engineering Company Chose to Migrate to D by WalterBright on Thursday June 21, 2018 @04:29PM (#17369016)
The ENTER and LEAVE instructions only supported dynamic linking (pointer to caller's stack frame) not static linking (pointer to the enclosing function's stack frame).
Re:How an Engineering Company Chose to Migrate to D by JdeBP on Friday June 22, 2018 @10:13AM (#17374081)
That is not in fact true.

ENTER copies M words from the caller's stack frame. The pointer passed by MetaWare High C/C++ in the register could equally well have been placed at the relevant position in the caller's stack frame, just as other arguments are, and an ENTER N,1 used as part of the perilogue.

The only consideration here is speed of the ENTER instruction versus having the hidden pointer in a register, not that this sort of nested function implementation is somehow impossible with ENTER. It's just another case of ENTER is slow and other instructions do the same thing better.

* http://jdebp.info./FGA/function-perilogues.html#Standardx86

(Part of that consideration is making non-nested functions usable via full function pointers.)

Re:How an Engineering Company Chose to Migrate to D by WalterBright on Saturday June 23, 2018 @05:55PM (#17383664)
You're right.
Re:How an Engineering Company Chose to Migrate to D by Rusky on Wednesday June 20, 2018 @05:39PM (#17360028)
That's usually what "capture" means when talking about closures.
Re:How an Engineering Company Chose to Migrate to D by tikue_ on Wednesday June 20, 2018 @05:49PM (#17360116)
At least in Rust, capture granularity is per-variable, so I think closures don't contain a stack frame pointer? Though, I'm not sure why this would matter to a user evaluating Rust's closures vs. D's nested fns?
Re:How an Engineering Company Chose to Migrate to D by steveklabnik on Wednesday June 20, 2018 @05:57PM (#17360173)
It’s a pointer to the environment, and a pointer to the function. So yes, not a stack frame pointer.

The environment is a struct containing what is captured; so for example, it would contain an &T if your closure captures a T by reference. You don’t need to walk a set of stack pointers to find it, just follow the reference directly there.

Re:How an Engineering Company Chose to Migrate to D by WalterBright on Wednesday June 20, 2018 @06:27PM (#17360405)
That's distinctly different from D's, which has a pointer to the enclosing stack frame.

If it is the enclosing function, it's just a single pointer to it. The "walking" comes from if you're accessing the enclosing function's enclosing function's frame.

Re:How an Engineering Company Chose to Migrate to D by steveklabnik on Wednesday June 20, 2018 @07:34PM (#17360857)
Makes perfect sense, thanks. I’m now wondering about the trade offs of these two approaches...