Introduction
This project provides Ruby bindings for Wasmtime, a WebAssembly runtime. This allows you to execute WASM modules from within Ruby executing at near-native speeds in a safe sandboxed environment.
This is pretty experimental and not production ready right now. There are quite a few things that aren't built yet, see TODO section below.
Note: WebAssembly Interface Types support has been temporarily removed from Wasmtime. Only 32 and 64-bit integers and floats are currently supported.
Usage
Install the wasmtime
gem. Pre-compiled binaries are available for
x86_64-linux
and x86_64-darwin-19
. Compiling the native extension requires
Rust with rustup.
gem install wasmtime
WASM has two formats .wasm
(binary) and .wat
(human-readable text). Both
formats are supported. With the following fibonacci.wat
file in your current
directory.
;; fibonacci.wat
(module
(export "fib" (func $fib))
(func $fib (param $n i32) (result i32)
(if (i32.lt_s (get_local $n) (i32.const 2))
(return (i32.const 1))
)
(return
(i32.add
(call $fib (i32.sub (get_local $n) (i32.const 2)))
(call $fib (i32.sub (get_local $n) (i32.const 1)))
)
)
)
)
In a ruby file, require 'wasmtime/require'
to activate the Wasmtime require
patch, allowing you to require any .wasm
or .wat
module as if it were a
Ruby file. Doing so will internally create a Wasmtime::Instance
and define a
Ruby module with functions for each export.
Finally, invoke the fib
export like so.
require 'wasmtime/require'
require_relative 'fibonacci'
puts Fibonacci.fib(11) #=> 89
If you don't like all the magic in the example above, you can do the same without the require patch. If your project is going to be a dependency of others use this approach too.
require 'wasmtime'
instance = Wasmtime::Instance.new('fibonacci.wat')
puts instance.exports['fib'].call(11) #=> 89
Benchmarks
None yet. But they will be impressive.
Examples
More usage examples are provided in examples/
. To run some of these, you first
need to compile the test WASM modules.
Install some Rust tools.
Install Ruby dependencies.
bundle install
Build the WASM modules.
bundle exec rake wasm
Run an example.
ruby examples/fibonacci.rb
Development
Compile Rust native extension.
bundle exec rake compile
Run test suite.
bundle exec rake spec
Format source code.
bundle exec rake format
TODO
- Add support for raw memory access and other types of exports
- Add support for imports
- Implement more of the Wasmtime API
- Add benchmarks for WASM program against ones in pure Ruby and true native
- Add support for WASM Interface Types when they are supported in Wasmtime