7 ms·
The problems there don't apply I believe because Rust closures don't require an executable stack.
by richardwhiuk 7y ago
The 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.
- a1369209993 7y agoNope! You'd do something to the effect of: clo_code: 4C8B1501100000 mov r10 [rel clo_code+0x1008] FF25F30F0000 jmp [rel clo_code+0x1000] 0F1F00 nop3 # one page away... struct clo_slot { void (*func)(void* _R10,...); void* data; }; Edit: to use r10 rather than rotating all the argument registers.
- barrkel 7y agoFor example, every platform that has a virtual machine with JIT compilation support.