The problems there don't apply I believe because Rust closures don't require an executable stack.
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/Sour... [2] https://www.mikeash.com/pyblog/friday-qa-2010-02-12-trampoli...
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.
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.