Hello,
another question that came up in regards to my JIT-implementation - specific to Win64/MSVC. This one is more of a cleanup/improvement, but still…
So for context, my visual-scripting supports coroutine-style “yield"ing, but with a lot more flexibilty and less restrictions. Notably, having nested yielding-method calls is working transitively w/o any overhead in terms of speed and also how the “code” has to be written. In the interpreter-implementation, this is done by having separate (smaller) stacks for potentially-yielding entries-frames, which are allocated from a pool and used instead of the primary stack. This allows both yield and resume to be O(1) after the initial start, regardless of how many layers deep the call-stack is at the point of the “yield”.
Now with JIT, things become more complicated. Regular methods are handled like a normal “call” opcode with a “ret" on the end. I'd like to use the same logic for yielding-methods, but the main problem here is the preservation of the stack-data in case of a “yield” and subsequent “resume”. In short, to achieve the same characteristics, I'd need to pre-emtively replace the applications stack with a custom one, which is then retained upon yield and later reinstated.
Now this is the primary question: How do I replace the stack of the application with a new one?
I know that RSP is the designated stack-pointer, and I know that I can potentially replace the value of this register to point to another memory-location to serve as a different stack. There is just one problem when trying this on windows:
Replacing RSP with my own stack screws with the programs unwind-information, meaning no stacktrace is present and exceptions are not handled properly while my own stack is used. This is even though I specify a register (R14) as frame-pointer, and register it in the unwind-information via UWOP_SET_FPREG
. The process itself seems to work, since I can add/sub to RSP as much as I want and the unwind still works. So, is there anything else I have to do to make windows/MSVC be able to properly unwind when a custom stack is used? I've not been able to find a single source of information regarding this, so this is probably something that isn't done very often (regular coroutines apparently are implemented entirely different, but that type of implementation is not compatible with my yield-model). Still, somebody got any experience with this type of thing?