2.3.0 • Published 2 years ago

ruby-head-wasm-wasi v2.3.0

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

ruby-head-wasm-wasi

WebAssembly port of CRuby with WASI.

This package distributes the latest master branch of CRuby.

Installation

For instaling ruby-head-wasm-wasi family, just run this command in your shell:

$ npm install --save ruby-head-wasm-wasi@latest
# or if you want the nightly snapshot
$ npm install --save ruby-head-wasm-wasi@next
# or you can specify the exact snapshot version
$ npm install --save ruby-head-wasm-wasi@0.3.0-2022-04-16-a

Quick Start (for Node.js)

See the example project for more details.

import fs from "fs/promises";
import { DefaultRubyVM } from "ruby-head-wasm-wasi/dist/node.cjs.js";

const main = async () => {
  const binary = await fs.readFile(
//  Tips: Replace the binary with debug info if you want symbolicated stack trace.
//  (only nightly release for now)
//  "./node_modules/ruby-head-wasm-wasi/dist/ruby.debug.wasm"
    "./node_modules/ruby-head-wasm-wasi/dist/ruby.wasm"
  );
  const module = await WebAssembly.compile(binary);
  const { vm } = await DefaultRubyVM(module);

  vm.eval(`
    luckiness = ["Lucky", "Unlucky"].sample
    puts "You are #{luckiness}"
  `);
};

main();

Then you can run the example project in your terminal:

$ node --experimental-wasi-unstable-preview1 index.node.js

Quick Start (for Browser)

In browser, you need a WASI polyfill See the example project for more details.

<html>
  <script src="https://cdn.jsdelivr.net/npm/ruby-head-wasm-wasi@latest/dist/browser.umd.js"></script>
  <script>
    const { DefaultRubyVM } = window["ruby-wasm-wasi"];
    const main = async () => {
      // Fetch and instntiate WebAssembly binary
      const response = await fetch(
//      Tips: Replace the binary with debug info if you want symbolicated stack trace.
//      (only nightly release for now)
//      "https://cdn.jsdelivr.net/npm/ruby-head-wasm-wasi@latest/dist/ruby.debug.wasm"
        "https://cdn.jsdelivr.net/npm/ruby-head-wasm-wasi@latest/dist/ruby.wasm"
      );
      const buffer = await response.arrayBuffer();
      const module = await WebAssembly.compile(buffer);
      const { vm } = await DefaultRubyVM(module);

      vm.printVersion();
      vm.eval(`
        require "js"
        luckiness = ["Lucky", "Unlucky"].sample
        JS::eval("document.body.innerText = '#{luckiness}'")
      `);
    };

    main();
  </script>
  <body></body>
</html>

APIs

Table of Contents

RubyVM

A Ruby VM instance

Examples

const wasi = new WASI();
const vm = new RubyVM();
const imports = {
  wasi_snapshot_preview1: wasi.wasiImport,
};

vm.addToImports(imports);

const instance = await WebAssembly.instantiate(rubyModule, imports);
await vm.setInstance(instance);
wasi.initialize(instance);

initialize

Initialize the Ruby VM with the given command line arguments

Parameters
  • args The command line arguments to pass to Ruby. Must be an array of strings starting with the Ruby program name. (optional, default ["ruby.wasm","--disable-gems","-e_=0"])

setInstance

Set a given instance to interact JavaScript and Ruby's WebAssembly instance. This method must be called before calling Ruby API.

Parameters
  • instance The WebAssembly instance to interact with. Must be instantiated from a Ruby built with JS extension, and built with Reactor ABI instead of command line.

addToImports

Add intrinsic import entries, which is necessary to interact JavaScript and Ruby's WebAssembly instance.

Parameters
  • imports The import object to add to the WebAssembly instance

printVersion

Print the Ruby version to stdout

eval

Runs a string of Ruby code from JavaScript

Parameters
  • code The Ruby code to run
Examples
vm.eval("puts 'hello world'");
const result = vm.eval("1 + 2");
console.log(result.toString()); // 3

Returns any the result of the last expression

RbValue

A RbValue is an object that represents a value in Ruby

Parameters

  • inner
  • vm
  • exporter

call

Call a given method with given arguments

Parameters
  • callee name of the Ruby method to call
  • args ...any arguments to pass to the method. Must be an array of RbValue
Examples
const ary = vm.eval("[1, 2, 3]");
ary.call("push", 4);
console.log(ary.call("sample").toString());

toPrimitive

Parameters
  • hint

toString

Returns a string representation of the value by calling to_s

toJS

Returns a JavaScript object representation of the value by calling to_js.

Returns null if the value is not convertible to a JavaScript object.

RbError

Extends Error

Error class thrown by Ruby execution

Parameters

  • message

Building the package from source

For building the package from source, you need to prepare a Ruby build produced by WASI SDK, and you need wit-bindgen and wasm-opt in your PATH.

The instructions for building a Ruby targeting WebAssembly are available here.

Then, you can run the following command in your shell:

# Check the directory structure of your Ruby build
$ tree -L 3 path/to/wasm32-unknown-wasi-full-js/
path/to/wasm32-unknown-wasi-full-js/
├── usr
│   └── local
│       ├── bin
│       ├── include
│       ├── lib
│       └── share
└── var
    └── lib
        └── gems
$ ./build-package.sh path/to/wasm32-unknown-wasi-full-js/
Generating "/Users/katei/.ghq/github.com/ruby/ruby.wasm/packages/ruby-head-wasm-wasi/src/bindgen/intrinsics.js"
Generating "/Users/katei/.ghq/github.com/ruby/ruby.wasm/packages/ruby-head-wasm-wasi/src/bindgen/rb-abi-guest.d.ts"
Generating "/Users/katei/.ghq/github.com/ruby/ruby.wasm/packages/ruby-head-wasm-wasi/src/bindgen/rb-abi-guest.js"
Generating "/Users/katei/.ghq/github.com/ruby/ruby.wasm/packages/ruby-head-wasm-wasi/src/bindgen/rb-js-abi-host.d.ts"
Generating "/Users/katei/.ghq/github.com/ruby/ruby.wasm/packages/ruby-head-wasm-wasi/src/bindgen/rb-js-abi-host.js"

src/index.ts → dist/index.umd.js, dist/index.esm.js, dist/index.cjs.js...
created dist/index.umd.js, dist/index.esm.js, dist/index.cjs.js in 682ms
2.3.0

2 years ago

2.2.0

2 years ago

2.1.0

2 years ago

0.6.0

2 years ago

2.0.0

2 years ago

0.5.0

3 years ago

0.4.0

3 years ago

0.3.0

3 years ago

0.2.0

3 years ago

0.1.0

3 years ago