there are two Win32 functions, RtlCaptureContext and RtlRestoreContext,
that you may find useful. They work under both 32-bit and 64-bit Windows,
so the code will be portable and you don't need assembly.
Thanks, Peter, these are new to me. They're a third option I hadn't
considered until now:
* Runtime: setjmp / longjmp
* Intrinsic: __builtin_setjmp / __builtin_longjmp
* Platform: RtlCaptureContext / RtlRestoreContext
Like in my article, I was able to construct a working C setjmp/longjmp
implementation out of them which passed my u-config test suite, both in
GCC and MSVC. I like having the additional option, but in practice it's
the worst of the three:
* Void return from RtlCaptureContext makes it cumbersome to distinguish
the first return from later returns. This state must be managed outside
the CONTEXT by the caller. The very nature of RtlCaptureContext means you
cannot just wrap it in a function, and so this extra context will likely
be managed using a macro.
* On x64, CONTEXT is 1232 bytes. That's huge! The GCC intrinsic context is
just 40 bytes, and it really only uses the first 24 bytes (rip, rsp, rbp).
* The official documentation is incomplete and slightly incorrect. Oddly
it's more correct in Windows SDK's winnt.h. (Side note: __cdecl is unusual
for a kernel32.dll export!)
* Mingw-w64 does not mark them with useful GCC function attributes. The
first is not returns_twice. Not a big deal, but it definitely makes
volatile more important. The second is not noreturn, leading to false
warnings, which happened to me. (Maybe there's a case where it *can*
return? The documentation is unclear.) In practice I'd probably skip the
winnt.h include and declare them myself with these attributes.
Despite my complaints, this is quite portable across various Windows
compilers while being CRT-free. That's worth something.