spawn_wasm.mx raw
1 //go:build js && wasm
2
3 package runtime
4
5 import "unsafe"
6
7 // Bridge imports for spawn-boundary SAB channels and domain creation.
8 // These are provided by wasm-worker-host.mjs in the JS host.
9
10 //go:wasmimport bridge channel_create
11 func bridgeChannelCreate(slotSize, slotCount int32) int32
12
13 //go:wasmimport bridge channel_send
14 func bridgeChannelSend(handle int32, srcPtr *byte, srcLen int32)
15
16 //go:wasmimport bridge channel_recv
17 func bridgeChannelRecv(handle int32, dstPtr *byte, dstCap int32) int32
18
19 //go:wasmimport bridge channel_close
20 func bridgeChannelClose(handle int32)
21
22 //go:wasmimport bridge spawn_domain
23 func bridgeSpawnDomain(fnIdx int32, argPtr *byte, argLen int32, chanHandlesPtr *byte, nChans int32)
24
25 //go:wasmimport bridge is_worker_context
26 func bridgeIsWorkerContext() int32
27
28 // SpawnChannelCreate creates a SAB-backed channel for use across a spawn
29 // boundary. slotSize and slotCount must both be powers of two; slotSize
30 // >= 64. Returns an opaque int32 handle stored as a uintptr.
31 func SpawnChannelCreate(slotSize, slotCount int32) uintptr {
32 return uintptr(bridgeChannelCreate(slotSize, slotCount))
33 }
34
35 // SpawnChannelSend sends bytes to a SAB channel identified by handle.
36 func SpawnChannelSend(handle uintptr, data unsafe.Pointer, n int32) {
37 bridgeChannelSend(int32(handle), (*byte)(data), n)
38 }
39
40 // SpawnChannelRecv receives into dst from a SAB channel. Returns byte count
41 // or -1 if the channel is closed.
42 func SpawnChannelRecv(handle uintptr, dst unsafe.Pointer, cap int32) int32 {
43 return bridgeChannelRecv(int32(handle), (*byte)(dst), cap)
44 }
45
46 // SpawnChannelClose marks a SAB channel as closed.
47 func SpawnChannelClose(handle uintptr) {
48 bridgeChannelClose(int32(handle))
49 }
50
51 // SpawnDomain creates a new Worker running the spawned function at fnIdx.
52 // argPtr/argLen carry serialized scalar args; chanHandlesPtr/nChans carry
53 // int32 SAB handles. Called by compiler-emitted spawn site code.
54 //
55 // Panics if not running inside a Web Worker: channel_recv uses Atomics.wait
56 // which is forbidden on the main browser thread. See moxie/wasm deployment docs.
57 func SpawnDomain(fnIdx int32, argPtr unsafe.Pointer, argLen int32, chanHandlesPtr unsafe.Pointer, nChans int32) {
58 if bridgeIsWorkerContext() == 0 {
59 runtimePanic("moxie/spawn: wasm binary must be loaded inside a Web Worker — channel_recv uses Atomics.wait which is blocked on the main thread")
60 }
61 bridgeSpawnDomain(fnIdx, (*byte)(argPtr), argLen, (*byte)(chanHandlesPtr), nChans)
62 }
63