ruby.wasmを使ってブラウザ上でKernel#sleep
を呼ぶとエラーが起きます。
<html> <body> <script src="https://cdn.jsdelivr.net/npm/@ruby/head-wasm-wasi@2.4.1-2024-01-05-a/dist/browser.script.iife.js"></script> <script type="text/ruby"> sleep 1 </script> </body> </html>
とりあえずこんなパッチを当てれば動くことはわかっています。
module Kernel def sleep(time) JS.eval("return new Promise((resolve) => setTimeout(resolve, #{time * 1000}))").await end end
現状Promise#new
にコールバックをブロックで渡せないので、JS.eval
を使っています。
これは直せると思います。
もう一つ悩みがあります。
JavaScriptのsetTimeout
を使っています。
WASIのインターフェースを使ったほうがポータブルになりそうな気がします。
Add a sleep function to the Core · Issue #77 · WebAssembly/WASI · GitHub によると
I'm the current API, the way to implement sleep is to use poll_oneoff, polling for a single __WASI_EVENTTYPE_CLOCK event.
poll_oneoff
という関数があるようです。
https://github.com/newpavlov/rust/blob/1e2b711d308be714e6211c125b1a33ac1247f866/src/libstd/sys/wasi/thread.rs#L30-L63をみると、rustではWASI用のThread.sleep
をpoll_oneoff
関数を使って実装しているようです。
これらの情報をみても、ruyb.wasmにどうやって実装したらいいのか皆目見当もつきません。