#Saving and restoring the stack (in wasm) - needed for use of async web APIs

6 messages · Page 1 of 1 (latest)

versed vector
#

I have a package rfb which exposes the following functions

  • connect(s: io.Stream) -> Connection
  • getFramebuffer(c: ^Connection)

The details are not important, but but the way I use it in my native application is that I open a tcp socket and then write my own Stream_Proc that reads and writes to the socket. Now I want to port my native application to work in wasm. There are no real sockets, but I can use websockets. Sadly their API is nothing like net.recv_tcp. Instead I have .onmessage function that gets called at random times. So how can I setup my Stream_Proc (in odin) to read from a websocket?

Solution 1:
I can have a SharedMemory object that both JS and WASM can read/write to. My .onmessage handler will put bytes there. My odin Stream_Proc can check if there are bytes in the shared mem and use them. If there aren't I need to suspend my WASM machine and then have JS resume it as it were, after .onmessage gets more data. I don't know how to save the current stack. This blog touches on the topic a little bit https://web.dev/articles/asyncify, using the wasm patching with https://github.com/WebAssembly/binaryen

Solution 2:
Rewrite my rfb package to have some different API, which would be a huge pain in the ass and totally useless for my native use case where I have blocking sockets. I would have to have
pushBytes(b: []byte, c: ^Connection)
and then have some complicated way to check where in the decode process of the rfb protocol the last byte stopped.

Any other ideas?

GitHub

Optimizer and compiler/toolchain library for WebAssembly - WebAssembly/binaryen

storm kettle
#

I think the wasmer/wasi js sdk wraps wasix sockets with websockets. That might just work if you’re compiling to wasi target

versed vector
#

No, I'm compiling for the browser

#

For future reference: In the end I accomplished my job with web workers, SharedMemoryBuffer and Atomics.wait

#

One webworker starts the odin code and provides a read() function that uses Atomics.wait on a shared buffer. The other web workers reads from the websocket and writes to the buffer, potentially unblocking the other worker that returns to the odin code

pulsar minnow
#

can you call promises from odin?