Skip to content
This repository has been archived by the owner on Oct 25, 2022. It is now read-only.

dtcristo/wasmtime-ruby

main
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
lib
 
 
 
 
src
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Deprecated: Replaced by official embedding.

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

About

Ruby bindings for Wasmtime, a WebAssembly runtime

Resources

License

Stars

Watchers

Forks