All Projects → dtcristo → wasmtime-ruby

dtcristo / wasmtime-ruby

Licence: Apache-2.0 license
Ruby bindings for Wasmtime, a WebAssembly runtime

Programming Languages

ruby
36898 projects - #4 most used programming language
rust
11053 projects
WebAssembly
147 projects
Makefile
30231 projects

wasmtime-ruby

Ruby bindings for Wasmtime, a WebAssembly runtime

RubyGems version badge CI status badge

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
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].