/wasmer-ruby

💎🕸 WebAssembly runtime for Ruby

Primary LanguageRustMIT LicenseMIT

Wasmer logo

Wasmer Ruby

Build Status License Wasmer on RubyGem Number of downloads API Documentation

Website • Docs • Slack Channel


A complete and mature WebAssembly runtime for Ruby based on Wasmer.

Features

  • Easy to use: The wasmer API mimics the standard WebAssembly API,
  • Fast: wasmer executes the WebAssembly modules as fast as possible, close to native speed,
  • Safe: All calls to WebAssembly will be fast, but more importantly, completely safe and sandboxed.

Documentation: browse the detailed API documentation full of examples.

Examples as tutorials: browser the examples/ directory, it's the best place for a complete introduction!

Quick Introduction

The wasmer package brings the required API to execute WebAssembly modules. In a nutshell, wasmer compiles the WebAssembly module into compiled code, and then executes it. wasmer is designed to work in various environments and platforms. To achieve this, Wasmer (the original runtime) provides multiple engines and multiple compilers.

Succinctly, an engine is responsible to drive the compilation (by using a compiler) and the execution of a WebAssembly module. Wasmer comes with many engines and compilers, but for the Ruby extension, it only provides the JIT engine with the Cranelift compiler. It is subject to change in the future where the user will have the choice to select its own engine and compiler.

Install

To install the wasmer Ruby gem, just run this command in your shell:

$ gem install wasmer

And you're ready to get fun!

View the wasmer gem on RubyGems.

Note: Rust is required to install the Ruby library (Cargo —the build tool for Rust— is used to compile the extension). See how to install Rust.

Example

We highly recommend to read the examples/ directory, which contains a sequence of examples/tutorials. It's the best place to learn by reading examples.

But for the most eager of you, and we know you're numerous you mischievous, there is a quick toy program in examples/appendices/simple.rs, written in Rust:

#[no_mangle]
pub extern fn sum(x: i32, y: i32) -> i32 {
    x + y
}

After compilation to WebAssembly, the examples/appendices/simple.wasm binary file is generated.

Then, we can execute it in Ruby:

require "wasmer"

# Let's define the store, that holds the engine, that holds the compiler.
store = Wasmer::Store.new

# Let's compile the module to be able to execute it!
module_ = Wasmer::Module.new store, IO.read("simple.wasm", mode: "rb")

# Now the module is compiled, we can instantiate it.
instance = Wasmer::Instance.new module_, nil

# Call the exported `sum` function.
result = instance.exports.sum.(5, 37)

puts result # 42!

And then, finally, enjoy by running:

$ ruby examples/appendices/simple.rb

Development

The Ruby extension is written in Rust, with rutie.

First, you need to install Rust and Ruby. We will not make you the affront to explain to you how to install Ruby (if you really need, check rbenv). For Rust though, we advice to use rustup, then:

$ rustup install stable

Then, after installing just, you can simply run:

$ just build

The supported Ruby versions are:

  • Ruby 2.6,
  • Ruby 2.7,
  • Ruby 3.0.

Extensions to rutie

This project provides extensions to rutie, through the rutie-derive and rutie-derive-macros crates (see the crates/ directory). Those crates aim at enhancing rutie by providing a better “Domain Specific Language” (DSL for short) to declare Ruby modules, classes, methods and functions. It's not perfect but it does a good job for the moment. Contributions on that front are welcomed too!

Testing

Running the test-all recipe will automatically build and run all the tests. It includes library tests, along with documentation tests and the examples:

$ just test-all

Documentation

To generate the documentation, run the following command:

$ just doc

All the examples in the documentation are automatically run as tests, called doctests. To run the doctests, run just test.

What is WebAssembly?

Quoting the WebAssembly site:

WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.

About speed:

WebAssembly aims to execute at native speed by taking advantage of common hardware capabilities available on a wide range of platforms.

About safety:

WebAssembly describes a memory-safe, sandboxed execution environment […].

License

The entire project is under the MIT License. Please read the LICENSE file.