Browse Source

Updated comment for Windows version of setjmp.

vassvik 4 years ago
parent
commit
f9bea5b791
1 changed files with 13 additions and 2 deletions
  1. 13 2
      core/c/libc/setjmp.odin

+ 13 - 2
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 ---;
 	}