Skip to content

Instantly share code, notes, and snippets.

@kateinoigakukun
Last active September 11, 2023 21:25
Show Gist options
  • Select an option

  • Save kateinoigakukun/5caf3b83b2732b1653e91b0e75ce3390 to your computer and use it in GitHub Desktop.

Select an option

Save kateinoigakukun/5caf3b83b2732b1653e91b0e75ce3390 to your computer and use it in GitHub Desktop.

How to use Bundler and RubyGems on WebAssembly

# Download prebuilt ruby
curl -LO https://github.com/ruby/ruby.wasm/releases/download/2022-08-09-a/ruby-head-wasm32-unknown-wasi-full.tar.gz
tar xfz ruby-head-wasm32-unknown-wasi-full.tar.gz

# Install the same version of native ruby to avoid bundler version mismatch in "BUNDLED WITH" of Gemfile.lock
rbenv install 3.2.0-dev
rbenv local 3.2.0-dev

# Setup Gemfile
bundle init
bundle add syntax_tree

# Install gems in vendor/bundle to mount it on WASI
bundle config set --local path 'vendor/bundle'
bundle install

cat <<EOS > my_app.rb
# 'require "bundler/setup"' is not precisely equivalent to 'bundle exec ...', but enough to load installed gems
require "bundler/setup"
require "syntax_tree"

pp SyntaxTree.parse("1 + 1")
EOS

# Options:
# --mapdir /usr::./head-wasm32-unknown-wasi-full/usr    Map ruby directory
# --mapdir /root::./                                    Map user script directory
# --env BUNDLE_GEMFILE=/root/Gemfile                    Tell bundler where the Gemfile located because WASI has no PWD concept
wasmtime run \
  --mapdir /usr::./head-wasm32-unknown-wasi-full/usr \
  --mapdir /root::./ \
  --env BUNDLE_GEMFILE=/root/Gemfile \
  head-wasm32-unknown-wasi-full/usr/local/bin/ruby -- /root/my_app.rb
@jtippett

jtippett commented Jun 8, 2023

Copy link
Copy Markdown

I've been playing with this trying to get it working. I'll use the dir structure in the repo README, which has src/ instead of root/.

Here's what I run (breaking it into 2 parts - I am not sure how the above could ever work, it needs to be built first, then run, right?)

wasi-vfs pack ruby.wasm --mapdir /src::./src --mapdir /usr::./3_2-wasm32-unknown-wasi-full/usr  -o my-ruby-app.wasm

wasmtime run --env BUNDLE_GEMFILE=/src/Gemfile my-ruby-app.wasm -- src/my_app.rb

Running that I get:

james@black-lagoon wasm % wasmtime run --env BUNDLE_GEMFILE=/src/Gemfile my-ruby-app.wasm -- src/my_app.rb
panicked at 'not yet implemented', src/wasi_snapshot_preview1.rs:594:36
Error: failed to run main module `my-ruby-app.wasm`

Caused by:
    0: failed to invoke command default
    1: error while executing at wasm backtrace:
           0: 0xa007ef - <unknown>!<wasm function 11958>
         [snip a bunch of stack trace....]
          43: 0xa2ce37 - <unknown>!<wasm function 12179>
       note: using the `WASMTIME_BACKTRACE_DETAILS=1` environment variable may show more debugging information
    2: wasm trap: wasm `unreachable` instruction executed

Any ideas? Do I need to be using HEAD instead of ruby-3_2-wasm32-unknown-wasi-full.tar.gz ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment