diff options
| -rw-r--r-- | core/c/libc/setjmp.odin | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/core/c/libc/setjmp.odin b/core/c/libc/setjmp.odin index 9eb12853c..c5b07b893 100644 --- a/core/c/libc/setjmp.odin +++ b/core/c/libc/setjmp.odin @@ -17,8 +17,19 @@ when ODIN_OS == "windows" { // necessarily export a symbol named setjmp but rather _setjmp in the case // of musl, glibc, BSD libc, and msvcrt. // - // TODO(mv): Some description of the extra argument, and maybe a link describing - // it in more detail? + /// NOTE(dweiler): UCRT has two implementations of longjmp. One that performs + // stack unwinding and one that doesn't. The choice of which to use depends on a + // flag which is set inside the jmp_buf structure given to setjmp. The default + // behavior is to unwind the stack. Within Odin, we cannot use the stack + // unwinding version as the unwinding information isn't present. To opt-in to + // the regular non-unwinding version we need a way to set this flag. Since the + // location of the flag within the struct is not defined or part of the ABI and + // can change between versions of UCRT, we must rely on setjmp to set it. It + // turns out that setjmp receives this flag in the RDX register on Win64, this + // just so happens to coincide with the second argument of a function in the + // Win64 ABI. By giving our setjmp a second argument with the value of zero, + // the RDX register will contain zero and correctly set the flag to disable + // stack unwinding. @(link_name="_setjmp") setjmp :: proc(env: ^jmp_buf, hack: rawptr = nil) -> int ---; } |