fix: auto-update stack_top on thread/fiber context switch in js_check_stack_overflow

When the runtime is called from a different thread or fiber than the one that captured stack_top, the stack pointer comparison produces false positives. This happens in any M:N threading model (green threads, fibers, coroutines) where each execution context has its own stack at an unrelated address.

Detect this by checking if sp falls outside the expected stack range. If so, call JS_UpdateStackTop() to re-anchor before comparing. Zero overhead on the common single-thread path (unlikely branch). Genuine stack overflows are still detected correctly after re-anchoring.
This commit is contained in:
David Roman 2026-03-16 21:12:08 -04:00
parent f1139494d1
commit 451763ba3b

@ -1638,6 +1638,17 @@ static inline BOOL js_check_stack_overflow(JSRuntime *rt, size_t alloca_size)
{
uintptr_t sp;
sp = js_get_stack_pointer() - alloca_size;
/* Detect when the runtime is being called from a different thread or
fiber than the one that set stack_top. In M:N threading models
(green threads, fibers, coroutines), each execution context has its
own stack at an unrelated address. If sp is outside the expected
range, re-anchor stack_top to the current stack before checking.
A genuine overflow has sp just below stack_limit; a context switch
has sp in a completely different address range. */
if (unlikely(sp > rt->stack_top || sp + rt->stack_size < rt->stack_limit)) {
JS_UpdateStackTop(rt);
sp = js_get_stack_pointer() - alloca_size;
}
return unlikely(sp < rt->stack_limit);
}
#endif