4 ms·
How does this relate to nested functions in C? (And resulting “infectious executable stacks”?) https://nullprogram.com/blog/2019/11/15/ https://nullprogram.com
by jgtrosh 7y ago
How does this relate to nested functions in C? (And resulting “infectious executable stacks”?)
https://nullprogram.com/blog/2019/11/15/ https://nullprogram.com/blog/2019/11/15/
- Diggsey 7y agoIt doesn't. This is just showing the normal way that callbacks are implemented in vanilla C and how you would make that programming pattern interoperate with Rust closures. Neither one relies on the compiler trickery/runtime code generation described in the earlier article.
- zozbot234 7y agoThe executable stack trick is only required if you want to implement closures that can be called as if they were plain C functions, with only a function pointer and no extra (void *) argument.
- rabidferret 7y agoIt doesn't relate to it at all. The issues around linking to problematic object files mentioned in that article will apply to Rust as well, but that's unrelated to the subject of this article, it's a property of the linker you're using and the toolchain used to compile whatever C dependencies you have
- zabzonk 7y agoC doesn't have nested functions - they are a GCC extension.
- richardwhiuk 7y agoThe problems there don't apply I believe because Rust closures don't require an executable stack.
- mmastrac 7y agoThat's correct - a Rust closure generally [1] can't be converted to a function pointer as it requires both code and state. [1] https://github.com/rust-lang/rust/issues/39817 https://github.com/rust-lang/rust/issues/39817
- twic 7y agoThe whole point of jgtrosh's link is that there is a way to hide data behind a function pointer, so Rust could convert any closure to a function pointer. But it requires writable-and-executable memory, so it's a pretty bad idea (in GCC's implementation, that memory is on the stack, which is an extra bad idea, but i don't think it needs to be).
- mmastrac 7y agoDefinitely. Technically this can also be done via static code trampolines that are mmap'd as well [1]. That approach has been used on iOS in the past to turn blocks into raw function pointers. If you have a platform that allows W+X on code (yikes!), you can do [2] as well. [1] https://github.com/plausiblelabs/plblockimp/blob/master/Source/trampoline_table.c https://github.com/plausiblelabs/plblockimp/blob/master/Sour... [2] https://www.mikeash.com/pyblog/friday-qa-2010-02-12-trampolining-blocks-with-mutable-code.html https://www.mikeash.com/pyblog/friday-qa-2010-02-12-trampoli...
- rabidferret 7y agoAnything that doesn't require W+X would need an entire page allocated per closure, wouldn't it?
- devit 7y agoNo, you can of course allocate W+X pages from the OS and put multiple closures in them using a standard userspace memory allocator. Or if the OS doesn't support W+X allocation at all, then you can have a bunch of tightly packed pregenerated trampolines in the binary.
- saagarjha 7y agoRight, this is how Objective-C's implementation works, except it keeps around one page of trampolines and remaps that around when necessary to be able to "create" more trampolines on the fly, I believe.
- deleted 7y ago[deleted]