зеркало из https://github.com/github/ruby.git
dff70b50d0
the original rb_wasm_setjmp implementation always unwinds to the root call frame to have setjmp compatible interface, and simulate sjlj's undefined behavior. Therefore, every vm_exec call unwinds to main, and a deep call stack makes setjmp call very expensive. The following snippet from optcarrot takes 5s even though it takes less than 0.3s on native. ``` [0x0, 0x4, 0x8, 0xc].map do |attr| (0..7).map do |j| (0...0x10000).map do |i| clr = i[15 - j] * 2 + i[7 - j] clr != 0 ? attr | clr : 0 end end end ``` This patch adds a WASI specialized vm_exec which uses lightweight try-catch API without unwinding to the root frame. After this patch, the above snippet takes only 0.5s. |
||
---|---|---|
.. | ||
tests | ||
GNUmakefile.in | ||
README.md | ||
asyncify.h | ||
fiber.c | ||
fiber.h | ||
machine.c | ||
machine.h | ||
machine_core.S | ||
missing.c | ||
runtime.c | ||
setjmp.c | ||
setjmp.h | ||
setjmp_core.S | ||
wasm-opt |
README.md
WebAssembly / WASI port of Ruby
How to cross-build
Requirement
- Ruby (the same version as the building target version) (baseruby)
- GNU make
- WASI SDK 14.0 or later
- Binaryen version 91
- Linux or macOS build machine
Steps
- Download a prebuilt WASI SDK package from WASI SDK release page.
- Set
WASI_SDK_PATH
environment variable to the root directory of the WASI SDK package.
$ export WASI_SDK_PATH=/path/to/wasi-sdk-X.Y
- Download a prebuilt binaryen from Binaryen release page
- Set PATH environment variable to lookup binaryen tools
$ export PATH=path/to/binaryen:$PATH
- Configure
- You can select which extensions you want to build.
- If you got
Out of bounds memory access
while running the produced ruby, you may need to increase the maximum size of stack.
$ ./configure LDFLAGS="-Xlinker -zstack-size=16777216" \
--host wasm32-unknown-wasi \
--with-destdir=./ruby-wasm32-wasi \
--with-static-linked-ext \
--with-ext=ripper,monitor
- Make
$ make install
Now you have a WASI compatible ruby binary. You can run it by any WebAssembly runtime like wasmtime
, wasmer
, Node.js, or browser with WASI polyfill.
Note: it may take a long time (~20 sec) for the first time for JIT compilation
$ wasmtime ruby-wasm32-wasi/usr/local/bin/ruby --mapdir /::./ruby-wasm32-wasi/ -- -e 'puts RUBY_PLATFORM'
wasm32-wasi
Current Limitation
- No
Thread
support for now. - Spawning a new process is not supported. e.g.
Kernel.spawn
andKernel.system