- From: Amirouche <amirouche@hyper.dev>
- Date: Mon, 17 May 2021 09:09:44 +0200
- To: public-webassembly@w3.org
Hello all :) I was asked to redirect my query to this mailing list [0]. [0] https://github.com/WebAssembly/design/issues/1294 Like the title suggest I am working on a compiler for Scheme that targets web assembly. I think the problem I face is more general. It is independent of the frontend language, it is not even specific to web assembly, in Linux there is select and epoll to solve the problem I have. The gist of the problem is: > How to make efficient use of cpu and memory in the context of > interactive application? In the backend, that means somehow relying on select, epoll, kqueue, or even io_uring (liburing). Inside a web assembly module, there is no concept of file descriptor, and no way to passively wait for an event happening outside the wasm module. That is the case, and the most common case targeted by web assembly that is: interacting with the browser DOM (or a canvas inside the DOM) or doing XHR. Another common case for web assembly is calling from the JS VM to a web assembly module that does some number crushing such as optimizing a jpeg file or such. My informal proposal is not useful in that case. In the case of a game or a Single Page Application, JS and web assembly need to cooperate: web assembly need to yield back control to JS side, so that the browser event loop can process events, and pass any completed events to web assembly. As far as I understand, at this stage, most likely the JS side, will have control, and wake up web assembly at a given frequency to process events and the "event loop" web assembly side will process those and issue appropriate drawing instruction and register new io events. Web assembly side, my problem is how to implement the event loop without relying on a trampoline. My current approach is to rely a continuation-passing-style (cps) transformation and a trampoline. Every web assembly function returns at least two values: pause, and a continuation callback. If pause is true, the continuation callback is saved in global mutable variable, the trampoline function returns, and yields back control to JS side. Otherwise, when pause is false, the continuation callback is called. Note: The call stack inside trampoline, inside the wasm module is at most one, so tail calls do not grow the stack. IF I am not mistaken, there is an alternative approach that still require a global cps to implement Scheme's call/cc, but given the formal tail call proposal, and two new operations it would aleviate the need for a trampoline to pause the wasm module: (call_with_pause (ref.func $myfunc)) will pause the wasm module, in other words save the current environment and yield back control to js. JavaScript side, when the wasm_module.resume function is called, it will unpause the wasm module by calling $myfunc. There is also `call_with_pause_indirect`. And prolly maybe, the tail equivalent of those. `select`-like function could be implemented with `call_with_pause`. What do you think? - Amirouche ~ https://hyper.dev
Received on Monday, 17 May 2021 07:10:00 UTC