Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Nice but damn, I'm about to implement closures in llvm, but there's only a TODO at that point ;)


Closures are trivial: a structure with a function pointer as a first element (i.e., the structure alignment is function pointer-compatible) and the captured environment following it. Pointer to this structure is passed as the first argument.

The only potentially funny bit with the closures is construction of a set of potentially mutually recursive closures - in such case you have to defer filling in the corresponding environment fields until all the closure structures are allocated.


What language are you working on?

I guess for closures you simply copy all the locals that they capture into a heap allocated structure that also has the pointer to the closure code.


I have never implemented this, so I'm sure this will be incomplete and possibly slightly inaccurate, but that is not quite true. Some of the issues: copying may not be appropriate if your data is mutable (multiple closures can share a value or it might be modified in the 'regular' code after the closure is created), or if the code does identity checks later on.

Also, for performance, it may be beneficial to skip the 'put a local on the stack' part and create a to-be-captured object directly on the heap.

I see somebody posted https://news.ycombinator.com/item?id=8580501, which points to the Wikipedia entry on 'spaghetti trees', the conceptual view on the needed data structures (which one may recognize from reading SICP, although I do not remember it using the term)

Many implementations, at runtime, will implement the 'main line' of the tree as a 'real stack', but that can be risky, as you will have to make sure that no closures survive the point where any locals they refer to get removed from the stack (what does C++ here? Declare it undefined behaviour or make it impossible?)


It's an inhouse shader language that is compiled to different targets, one of which is llvm another is glsl. In our case you are probably right, but it would have been nice to see a simple example. Of course there's many implementations in other open source languages, but it's much more work to analyse such large code bases.


You can always check how Haskell, Rust and Clojure-LLVM do it, just to cite three examples.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: