◐ Shell
clean mode source ↗

Fix cross-thread JSString deinit by wrapping JSObject instead of raw ref by kateinoigakukun · Pull Request #741 · swiftwasm/JavaScriptKit

JSString.Guts previously held a raw JavaScriptObjectRef and released it
unconditionally on whatever thread ran deinit. In the multithreaded Wasm
runtime each thread has its own JSObjectSpace, so releasing a ref on the
wrong thread caused a TypeError crash (BugSnag: rc property of undefined).

JSObject already handles this correctly by capturing ownerTid at init time
and routing deinit through swjs_release_remote when destroyed off-thread.
This change makes Guts hold a JSObject instead of a raw ref, delegating the
correct cross-thread release behaviour to the existing JSObject.deinit path.

Adds a regression test testDeinitJSStringOnDifferentThread that reproduces
the crash deterministically: it forces JS ref allocation on the main thread
via asInternalJSRef(), then drops the last reference on a worker thread.

Fixes the crash seen in v292745-rc4 after upgrading to JavaScriptKit 0.50.2.

https://claude.ai/code/session_01Qhg5GLXZYNJtH63Gs1SwJH