ruby_wasm 2.7.2 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3cff5f6f0bb40dae18d6bb5299a9aa21a72f5f6f1eebfa9983361398bb7db244
4
- data.tar.gz: abc40251479c2a0e5b8d7d6b517ad2dde4c85144e0fdd164d9be0ceceada832d
3
+ metadata.gz: f265f5ecf5304134aa15a32d2c6569411e7fa46fba71e66a06efb63604833e27
4
+ data.tar.gz: 6025bc4a2848d28b278ebb096eb27008a0febf0240ae385592b7e31e2330f938
5
5
  SHA512:
6
- metadata.gz: 9767e7f677a4010826be60996865c6f69dcd0c5c55536e7b3dc7800f23370231fac4f2a8b4e36968a685e50474745e61c1cb87e50c80152aec0908c4919e9eec
7
- data.tar.gz: 37deb8d2326a2bad442500e109bb29a218afd730ce522e093a452d49339c913116afe0519ec992686ad058efbb0ccdfb065e5b5927886ff78be6758be320cb52
6
+ metadata.gz: c8e28678938afb6bd47c730e844b167325943be3769cd2d6caf6f75a295da38b3e12db41c3c7cca4b4ef53f6bafb86f06a4f181fac6e6e2350ed574779fd3dbb
7
+ data.tar.gz: 6a3f3df987b7ff6f9a74d1b6f8f68ba529a9ca2bcba094a4f1991c486d27f999df92c005236570d55c0fe9ebf88bb11879d648f3a00798535ed3adc22152c67f
data/CONTRIBUTING.md CHANGED
@@ -129,7 +129,7 @@ $ npm install --save @ruby/wasm-wasi@latest
129
129
  # or if you want the nightly snapshot
130
130
  $ npm install --save @ruby/wasm-wasi@next
131
131
  # or you can specify the exact snapshot version
132
- $ npm install --save @ruby/wasm-wasi@2.7.2-2025-10-03-a
132
+ $ npm install --save @ruby/wasm-wasi@2.8.0-2025-12-29-a
133
133
  ```
134
134
 
135
135
 
@@ -138,7 +138,7 @@ $ npm install --save @ruby/wasm-wasi@2.7.2-2025-10-03-a
138
138
  When a new version of Ruby is released, the following steps need to be taken to add support for it in ruby.wasm:
139
139
 
140
140
  1. Update `lib/ruby_wasm/cli.rb`:
141
- - Add a new entry in the `build_source_aliases` method for the new version
141
+ - Add a new entry in the `build_config_aliases` method for the new version
142
142
  - Specify the tarball URL and required default extensions
143
143
 
144
144
  2. Update `Rakefile`:
data/Cargo.lock CHANGED
@@ -1,6 +1,6 @@
1
1
  # This file is automatically @generated by Cargo.
2
2
  # It is not intended for manual editing.
3
- version = 3
3
+ version = 4
4
4
 
5
5
  [[package]]
6
6
  name = "addr2line"
@@ -1037,9 +1037,9 @@ dependencies = [
1037
1037
 
1038
1038
  [[package]]
1039
1039
  name = "magnus"
1040
- version = "0.7.1"
1040
+ version = "0.8.2"
1041
1041
  source = "registry+https://github.com/rust-lang/crates.io-index"
1042
- checksum = "3d87ae53030f3a22e83879e666cb94e58a7bdf31706878a0ba48752994146dab"
1042
+ checksum = "3b36a5b126bbe97eb0d02d07acfeb327036c6319fd816139a49824a83b7f9012"
1043
1043
  dependencies = [
1044
1044
  "bytes",
1045
1045
  "magnus-macros",
@@ -1050,9 +1050,9 @@ dependencies = [
1050
1050
 
1051
1051
  [[package]]
1052
1052
  name = "magnus-macros"
1053
- version = "0.6.0"
1053
+ version = "0.8.0"
1054
1054
  source = "registry+https://github.com/rust-lang/crates.io-index"
1055
- checksum = "5968c820e2960565f647819f5928a42d6e874551cab9d88d75e3e0660d7f71e3"
1055
+ checksum = "47607461fd8e1513cb4f2076c197d8092d921a1ea75bd08af97398f593751892"
1056
1056
  dependencies = [
1057
1057
  "proc-macro2",
1058
1058
  "quote",
@@ -1269,18 +1269,18 @@ dependencies = [
1269
1269
 
1270
1270
  [[package]]
1271
1271
  name = "rb-sys"
1272
- version = "0.9.108"
1272
+ version = "0.9.123"
1273
1273
  source = "registry+https://github.com/rust-lang/crates.io-index"
1274
- checksum = "1e955384e1a4dc64b71d1e4b39ed0edbd77c7bde4a10dfd5ad208e1160fddfa7"
1274
+ checksum = "45fb1a185af97ee456f1c9e56dbe6e2e662bec4fdeaf83c4c28e0e6adfb18816"
1275
1275
  dependencies = [
1276
1276
  "rb-sys-build",
1277
1277
  ]
1278
1278
 
1279
1279
  [[package]]
1280
1280
  name = "rb-sys-build"
1281
- version = "0.9.108"
1281
+ version = "0.9.123"
1282
1282
  source = "registry+https://github.com/rust-lang/crates.io-index"
1283
- checksum = "c167c6571889b2550d6fcb315e8aa60bdb95e47e4b64793e3f65a30dc25afc85"
1283
+ checksum = "a58ebd02d7a6033e6a5f6f8d150c1e9f16506039092b84a73e6bedce6d3adf41"
1284
1284
  dependencies = [
1285
1285
  "bindgen",
1286
1286
  "lazy_static",
@@ -1293,9 +1293,9 @@ dependencies = [
1293
1293
 
1294
1294
  [[package]]
1295
1295
  name = "rb-sys-env"
1296
- version = "0.1.2"
1296
+ version = "0.2.2"
1297
1297
  source = "registry+https://github.com/rust-lang/crates.io-index"
1298
- checksum = "a35802679f07360454b418a5d1735c89716bde01d35b1560fc953c1415a0b3bb"
1298
+ checksum = "08f8d2924cf136a1315e2b4c7460a39f62ef11ee5d522df9b2750fab55b868b6"
1299
1299
 
1300
1300
  [[package]]
1301
1301
  name = "redox_users"
@@ -1841,7 +1841,7 @@ dependencies = [
1841
1841
  "structopt",
1842
1842
  "wasm-encoder 0.212.0",
1843
1843
  "wasmparser 0.212.0",
1844
- "wizer 6.0.0 (git+https://github.com/kateinoigakukun/wizer.git?branch=katei/add-env-option-6.0.0)",
1844
+ "wizer 6.0.0 (git+https://github.com/kateinoigakukun/wizer.git?branch=katei%2Fadd-env-option-6.0.0)",
1845
1845
  ]
1846
1846
 
1847
1847
  [[package]]
@@ -2753,7 +2753,7 @@ dependencies = [
2753
2753
  [[package]]
2754
2754
  name = "wizer"
2755
2755
  version = "6.0.0"
2756
- source = "git+https://github.com/kateinoigakukun/wizer.git?branch=katei/add-env-option-6.0.0#8e7158013eb3d1059504229eff834eb1f3e33949"
2756
+ source = "git+https://github.com/kateinoigakukun/wizer.git?branch=katei%2Fadd-env-option-6.0.0#8e7158013eb3d1059504229eff834eb1f3e33949"
2757
2757
  dependencies = [
2758
2758
  "anyhow",
2759
2759
  "cap-std",
data/Gemfile CHANGED
@@ -8,6 +8,7 @@ group :development do
8
8
  gem "rake"
9
9
  gem "rake-compiler"
10
10
  gem "rb_sys", "0.9.108"
11
+ gem "rdoc", "~> 7.0"
11
12
  end
12
13
 
13
14
  group :check do
data/README.md CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  [![Build ruby.wasm](https://github.com/ruby/ruby.wasm/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/ruby/ruby.wasm/actions/workflows/build.yml)
4
4
 
5
- ruby.wasm is a collection of WebAssembly ports of the [CRuby](https://github.com/ruby/ruby).
6
- It enables running Ruby application on browsers, WASI compatible WebAssembly runtimes, and Edge Computing platforms.
5
+ ruby.wasm is a collection of WebAssembly ports of [CRuby](https://github.com/ruby/ruby).
6
+ It enables running Ruby applications in browsers, WASI compatible WebAssembly runtimes, and Edge Computing platforms.
7
7
 
8
8
  ## Try ruby.wasm (no installation needed)
9
9
 
10
- Try ruby.wasm in [TryRuby](https://try.ruby-lang.org/playground#code=puts+RUBY_DESCRIPTION&engine=cruby-3.2.0dev) in your browser.
10
+ Try ruby.wasm on [TryRuby](https://try.ruby-lang.org/playground#code=puts+RUBY_DESCRIPTION&engine=cruby-3.2.0dev) in your browser.
11
11
 
12
12
  ## Quick Links
13
13
 
@@ -17,13 +17,13 @@ Try ruby.wasm in [TryRuby](https://try.ruby-lang.org/playground#code=puts+RUBY_D
17
17
  - [Complete Examples](https://github.com/ruby/ruby.wasm/tree/main/packages/npm-packages/ruby-wasm-wasi/example)
18
18
  - [Community Showcase](https://github.com/ruby/ruby.wasm/wiki/Showcase)
19
19
 
20
- ## Quick Example: Ruby on Web browser
20
+ ## Quick Example: Ruby in a Web browser
21
21
 
22
- Create and save `index.html` page with the following contents:
22
+ Create and save an `index.html` page with the following contents:
23
23
 
24
24
  ```html
25
25
  <html>
26
- <script src="https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.2/dist/browser.script.iife.js"></script>
26
+ <script src="https://cdn.jsdelivr.net/npm/@ruby/4.0-wasm-wasi@2.9.0/dist/browser.script.iife.js"></script>
27
27
  <script type="text/ruby">
28
28
  require "js"
29
29
 
@@ -40,18 +40,18 @@ Dependencies: [wasmtime](https://github.com/bytecodealliance/wasmtime)
40
40
  ```console
41
41
  $ gem install ruby_wasm
42
42
  # Download a prebuilt Ruby release
43
- $ curl -LO https://github.com/ruby/ruby.wasm/releases/latest/download/ruby-3.4-wasm32-unknown-wasip1-full.tar.gz
44
- $ tar xfz ruby-3.4-wasm32-unknown-wasip1-full.tar.gz
43
+ $ curl -LO https://github.com/ruby/ruby.wasm/releases/latest/download/ruby-4.0-wasm32-unknown-wasip1-full.tar.gz
44
+ $ tar xfz ruby-4.0-wasm32-unknown-wasip1-full.tar.gz
45
45
 
46
46
  # Extract ruby binary not to pack itself
47
- $ mv ruby-3.4-wasm32-unknown-wasip1-full/usr/local/bin/ruby ruby.wasm
47
+ $ mv ruby-4.0-wasm32-unknown-wasip1-full/usr/local/bin/ruby ruby.wasm
48
48
 
49
49
  # Put your app code
50
50
  $ mkdir src
51
51
  $ echo "puts 'Hello'" > src/my_app.rb
52
52
 
53
53
  # Pack the whole directory under /usr and your app dir
54
- $ rbwasm pack ruby.wasm --dir ./src::/src --dir ./ruby-3.4-wasm32-unknown-wasip1-full/usr::/usr -o my-ruby-app.wasm
54
+ $ rbwasm pack ruby.wasm --dir ./src::/src --dir ./ruby-4.0-wasm32-unknown-wasip1-full/usr::/usr -o my-ruby-app.wasm
55
55
 
56
56
  # Run the packed scripts
57
57
  $ wasmtime my-ruby-app.wasm /src/my_app.rb
@@ -71,6 +71,11 @@ See the `README.md` of each package for more detail and its usage.
71
71
  </tr>
72
72
  </thead>
73
73
  <tbody>
74
+ <tr>
75
+ <td><a href="/packages/npm-packages/ruby-4.0-wasm-wasi">@ruby/4.0-wasm-wasi</a></td>
76
+ <td>CRuby 4.0 built on WASI with JS interop support</td>
77
+ <td><a href="https://www.npmjs.com/package/@ruby/4.0-wasm-wasi" rel="nofollow"><img src="https://badge.fury.io/js/@ruby%2F4.0-wasm-wasi.svg" alt="npm version" style="max-width: 100%;"></a></td>
78
+ </tr>
74
79
  <tr>
75
80
  <td><a href="/packages/npm-packages/ruby-3.4-wasm-wasi">@ruby/3.4-wasm-wasi</a></td>
76
81
  <td>CRuby 3.4 built on WASI with JS interop support</td>
@@ -150,7 +155,7 @@ A _build_ is a combination of ruby version, _profile_, and _target_.
150
155
 
151
156
  The current WASI target build does not yet support `Thread` related APIs. Specifically, WASI does not yet have an API for creating and managing threads yet.
152
157
 
153
- Also there is no support for networking. It is one of the goal of WASI to support networking in the future, but it is not yet implemented.
158
+ Also there is no support for networking. It is one of the goals of WASI to support networking in the future, but it is not yet implemented.
154
159
 
155
160
 
156
161
  ## Contributing
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ require "ruby_wasm/rake_task"
9
9
  require "ruby_wasm/packager"
10
10
  require "ruby_wasm/cli"
11
11
 
12
- BUILD_SOURCES = %w[3.4 3.3 3.2 head]
12
+ BUILD_SOURCES = %w[4.0 3.4 3.3 3.2 head]
13
13
  BUILD_PROFILES = %w[full minimal]
14
14
 
15
15
  BUILDS =
@@ -29,14 +29,20 @@ NPM_PACKAGES = [
29
29
  name: "ruby-head-wasm-wasi",
30
30
  ruby_version: "head",
31
31
  gemfile: "packages/npm-packages/ruby-head-wasm-wasi/Gemfile",
32
- target: "wasm32-unknown-wasip1",
32
+ target: "wasm32-unknown-wasip1"
33
33
  },
34
34
  {
35
35
  name: "ruby-head-wasm-wasip2",
36
36
  ruby_version: "head",
37
37
  gemfile: "packages/npm-packages/ruby-head-wasm-wasip2/Gemfile",
38
38
  target: "wasm32-unknown-wasip2",
39
- enable_component_model: true,
39
+ enable_component_model: true
40
+ },
41
+ {
42
+ name: "ruby-4.0-wasm-wasi",
43
+ ruby_version: "4.0",
44
+ gemfile: "packages/npm-packages/ruby-4.0-wasm-wasi/Gemfile",
45
+ target: "wasm32-unknown-wasip1"
40
46
  },
41
47
  {
42
48
  name: "ruby-3.4-wasm-wasi",
@@ -66,16 +72,6 @@ STANDALONE_PACKAGES = [
66
72
 
67
73
  LIB_ROOT = File.dirname(__FILE__)
68
74
 
69
- TOOLCHAINS = {}
70
- BUILDS
71
- .map { |_, target, _| target }
72
- .uniq
73
- .each do |target|
74
- build_dir = File.join(LIB_ROOT, "build")
75
- toolchain = RubyWasm::Toolchain.get(target, build_dir)
76
- TOOLCHAINS[toolchain.name] = toolchain
77
- end
78
-
79
75
  class BuildTask < Struct.new(:name, :target, :build_command)
80
76
  def ruby_cache_key
81
77
  return @key if @key
data/docs/cheat_sheet.md CHANGED
@@ -8,10 +8,10 @@
8
8
 
9
9
  ## Node.js
10
10
 
11
- To install the package, install `@ruby/3.4-wasm-wasi` and `@ruby/wasm-wasi` from npm:
11
+ To install the package, install `@ruby/4.0-wasm-wasi` and `@ruby/wasm-wasi` from npm:
12
12
 
13
13
  ```console
14
- npm install --save @ruby/3.4-wasm-wasi @ruby/wasm-wasi
14
+ npm install --save @ruby/4.0-wasm-wasi @ruby/wasm-wasi
15
15
  ```
16
16
 
17
17
  Then instantiate a Ruby VM by the following code:
@@ -20,7 +20,7 @@ Then instantiate a Ruby VM by the following code:
20
20
  import fs from "fs/promises";
21
21
  import { DefaultRubyVM } from "@ruby/wasm-wasi/dist/node";
22
22
 
23
- const binary = await fs.readFile("./node_modules/@ruby/3.4-wasm-wasi/dist/ruby.wasm");
23
+ const binary = await fs.readFile("./node_modules/@ruby/4.0-wasm-wasi/dist/ruby.wasm");
24
24
  const module = await WebAssembly.compile(binary);
25
25
  const { vm } = await DefaultRubyVM(module);
26
26
  vm.eval(`puts "hello world"`);
@@ -38,7 +38,7 @@ The easiest way to run Ruby on browser is to use `browser.script.iife.js` script
38
38
 
39
39
  ```html
40
40
  <html>
41
- <script src="https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.2/dist/browser.script.iife.js"></script>
41
+ <script src="https://cdn.jsdelivr.net/npm/@ruby/4.0-wasm-wasi@2.9.0/dist/browser.script.iife.js"></script>
42
42
  <script type="text/ruby">
43
43
  require "js"
44
44
  JS.global[:document].write "Hello, world!"
@@ -51,8 +51,8 @@ If you want to control Ruby VM from JavaScript, you can use `@ruby/wasm-wasi` pa
51
51
  ```html
52
52
  <html>
53
53
  <script type="module">
54
- import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.7.2/dist/browser/+esm";
55
- const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.2/dist/ruby+stdlib.wasm");
54
+ import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.9.0/dist/browser/+esm";
55
+ const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/4.0-wasm-wasi@2.9.0/dist/ruby+stdlib.wasm");
56
56
  const module = await WebAssembly.compileStreaming(response);
57
57
  const { vm } = await DefaultRubyVM(module);
58
58
 
@@ -69,11 +69,11 @@ If you want to control Ruby VM from JavaScript, you can use `@ruby/wasm-wasi` pa
69
69
 
70
70
  ```html
71
71
  <html>
72
- <script src="https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.7.2/dist/browser.umd.js"></script>
72
+ <script src="https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.9.0/dist/browser.umd.js"></script>
73
73
  <script>
74
74
  const main = async () => {
75
75
  const { DefaultRubyVM } = window["ruby-wasm-wasi"];
76
- const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.2/dist/ruby+stdlib.wasm");
76
+ const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/4.0-wasm-wasi@2.9.0/dist/ruby+stdlib.wasm");
77
77
  const module = await WebAssembly.compileStreaming(response);
78
78
  const { vm } = await DefaultRubyVM(module);
79
79
 
@@ -128,7 +128,7 @@ end
128
128
 
129
129
  ```html
130
130
  <html>
131
- <script src="https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.2/dist/browser.script.iife.js"></script>
131
+ <script src="https://cdn.jsdelivr.net/npm/@ruby/4.0-wasm-wasi@2.9.0/dist/browser.script.iife.js"></script>
132
132
  <script type="text/ruby" data-eval="async">
133
133
  require "js"
134
134
 
@@ -143,8 +143,8 @@ Or using `@ruby/wasm-wasi` package API `RubyVM#evalAsync`:
143
143
  ```html
144
144
  <html>
145
145
  <script type="module">
146
- import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.7.2/dist/browser/+esm";
147
- const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.2/dist/ruby+stdlib.wasm");
146
+ import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.9.0/dist/browser/+esm";
147
+ const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/4.0-wasm-wasi@2.9.0/dist/ruby+stdlib.wasm");
148
148
  const module = await WebAssembly.compileStreaming(response);
149
149
  const { vm } = await DefaultRubyVM(module);
150
150
 
data/docs/faq.md CHANGED
@@ -6,9 +6,9 @@
6
6
 
7
7
  # FAQ
8
8
 
9
- ## Where my `puts` output goes?
9
+ ## Where does my `puts` output go?
10
10
 
11
- By default, `puts` output goes to `STDOUT` which is a JavaScript `console.log` function. You can override it by setting `$stdout` to a Ruby object which has `write` method.
11
+ By default, `puts` output goes to `STDOUT` which is a JavaScript `console.log` function. You can override it by setting `$stdout` to a Ruby object which has a `write` method.
12
12
 
13
13
  ```ruby
14
14
  $stdout = Object.new.tap do |obj|
@@ -10,7 +10,7 @@ publish = false
10
10
  crate-type = ["cdylib"]
11
11
 
12
12
  [dependencies]
13
- magnus = { version = "0.7.1", features = ["bytes"] }
13
+ magnus = { version = "0.8", features = ["bytes"] }
14
14
  bytes = "1"
15
15
  wizer = "6.0.0"
16
16
  wasi-vfs-cli = { git = "https://github.com/kateinoigakukun/wasi-vfs/", tag = "v0.5.3-p1" }
@@ -1,7 +1,7 @@
1
1
  use std::{collections::HashMap, env, path::PathBuf, time::SystemTime};
2
2
 
3
3
  use magnus::{
4
- eval, exception, function, method,
4
+ eval, function, method,
5
5
  prelude::*,
6
6
  value::{self, InnerValue},
7
7
  wrap, Error, ExceptionClass, RModule, Ruby,
@@ -37,14 +37,19 @@ struct WasiVfsInner {
37
37
  #[wrap(class = "RubyWasmExt::WasiVfs")]
38
38
  struct WasiVfs(std::cell::RefCell<WasiVfsInner>);
39
39
 
40
+ /// Create a `magnus::Error` using Ruby's `StandardError`.
41
+ ///
42
+ /// Panics if called when no Ruby VM is available.
43
+ fn ruby_standard_error(message: impl Into<String>) -> Error {
44
+ let ruby = magnus::Ruby::get().expect("Ruby VM is not available");
45
+ Error::new(ruby.exception_standard_error(), message.into())
46
+ }
47
+
40
48
  impl WasiVfs {
41
49
  fn run_cli(args: Vec<String>) -> Result<(), Error> {
42
- wasi_vfs_cli::App::from_iter(args).execute().map_err(|e| {
43
- Error::new(
44
- exception::standard_error(),
45
- format!("failed to run wasi vfs cli: {}", e),
46
- )
47
- })
50
+ wasi_vfs_cli::App::from_iter(args)
51
+ .execute()
52
+ .map_err(|e| ruby_standard_error(format!("failed to run wasi vfs cli: {}", e)))
48
53
  }
49
54
 
50
55
  fn new() -> Self {
@@ -60,12 +65,7 @@ impl WasiVfs {
60
65
 
61
66
  fn pack(&self, wasm_bytes: bytes::Bytes) -> Result<bytes::Bytes, Error> {
62
67
  let output_bytes = wasi_vfs_cli::pack(&wasm_bytes, self.0.borrow().map_dirs.clone())
63
- .map_err(|e| {
64
- Error::new(
65
- exception::standard_error(),
66
- format!("failed to pack wasi vfs: {}", e),
67
- )
68
- })?;
68
+ .map_err(|e| ruby_standard_error(format!("failed to pack wasi vfs: {}", e)))?;
69
69
  Ok(output_bytes.into())
70
70
  }
71
71
  }
@@ -83,12 +83,10 @@ impl ComponentLink {
83
83
  &self,
84
84
  body: impl FnOnce(wit_component::Linker) -> Result<wit_component::Linker, Error>,
85
85
  ) -> Result<(), Error> {
86
- let mut linker = self.0.take().ok_or_else(|| {
87
- Error::new(
88
- exception::standard_error(),
89
- "linker is already consumed".to_string(),
90
- )
91
- })?;
86
+ let mut linker = self
87
+ .0
88
+ .take()
89
+ .ok_or_else(|| ruby_standard_error("linker is already consumed"))?;
92
90
  linker = body(linker)?;
93
91
  self.0.replace(Some(linker));
94
92
  Ok(())
@@ -96,22 +94,16 @@ impl ComponentLink {
96
94
 
97
95
  fn library(&self, name: String, module: bytes::Bytes, dl_openable: bool) -> Result<(), Error> {
98
96
  self.linker(|linker| {
99
- linker.library(&name, &module, dl_openable).map_err(|e| {
100
- Error::new(
101
- exception::standard_error(),
102
- format!("failed to link library: {}", e),
103
- )
104
- })
97
+ linker
98
+ .library(&name, &module, dl_openable)
99
+ .map_err(|e| ruby_standard_error(format!("failed to link library: {}", e)))
105
100
  })
106
101
  }
107
102
  fn adapter(&self, name: String, module: bytes::Bytes) -> Result<(), Error> {
108
103
  self.linker(|linker| {
109
- linker.adapter(&name, &module).map_err(|e| {
110
- Error::new(
111
- exception::standard_error(),
112
- format!("failed to link adapter: {}", e),
113
- )
114
- })
104
+ linker
105
+ .adapter(&name, &module)
106
+ .map_err(|e| ruby_standard_error(format!("failed to link adapter: {}", e)))
115
107
  })
116
108
  }
117
109
  fn validate(&self, validate: bool) -> Result<(), Error> {
@@ -128,18 +120,14 @@ impl ComponentLink {
128
120
  }
129
121
  fn encode(&self) -> Result<bytes::Bytes, Error> {
130
122
  // Take the linker out of the cell and consume it
131
- let linker = self.0.borrow_mut().take().ok_or_else(|| {
132
- Error::new(
133
- exception::standard_error(),
134
- "linker is already consumed".to_string(),
135
- )
136
- })?;
137
- let encoded = linker.encode().map_err(|e| {
138
- Error::new(
139
- exception::standard_error(),
140
- format!("failed to encode linker: {}", e),
141
- )
142
- })?;
123
+ let linker = self
124
+ .0
125
+ .borrow_mut()
126
+ .take()
127
+ .ok_or_else(|| ruby_standard_error("linker is already consumed"))?;
128
+ let encoded = linker
129
+ .encode()
130
+ .map_err(|e| ruby_standard_error(format!("failed to encode linker: {}", e)))?;
143
131
  Ok(encoded.into())
144
132
  }
145
133
  }
@@ -160,12 +148,10 @@ impl ComponentEncode {
160
148
  wit_component::ComponentEncoder,
161
149
  ) -> Result<wit_component::ComponentEncoder, Error>,
162
150
  ) -> Result<(), Error> {
163
- let mut encoder = self.0.take().ok_or_else(|| {
164
- Error::new(
165
- exception::standard_error(),
166
- "encoder is already consumed".to_string(),
167
- )
168
- })?;
151
+ let mut encoder = self
152
+ .0
153
+ .take()
154
+ .ok_or_else(|| ruby_standard_error("encoder is already consumed"))?;
169
155
  encoder = body(encoder)?;
170
156
  self.0.replace(Some(encoder));
171
157
  Ok(())
@@ -177,23 +163,17 @@ impl ComponentEncode {
177
163
 
178
164
  fn adapter(&self, name: String, module: bytes::Bytes) -> Result<(), Error> {
179
165
  self.encoder(|encoder| {
180
- encoder.adapter(&name, &module).map_err(|e| {
181
- Error::new(
182
- exception::standard_error(),
183
- format!("failed to encode adapter: {}", e),
184
- )
185
- })
166
+ encoder
167
+ .adapter(&name, &module)
168
+ .map_err(|e| ruby_standard_error(format!("failed to encode adapter: {}", e)))
186
169
  })
187
170
  }
188
171
 
189
172
  fn module(&self, module: bytes::Bytes) -> Result<(), Error> {
190
173
  self.encoder(|encoder| {
191
- encoder.module(&module).map_err(|e| {
192
- Error::new(
193
- exception::standard_error(),
194
- format!("failed to encode module: {}", e),
195
- )
196
- })
174
+ encoder
175
+ .module(&module)
176
+ .map_err(|e| ruby_standard_error(format!("failed to encode module: {}", e)))
197
177
  })
198
178
  }
199
179
 
@@ -207,18 +187,14 @@ impl ComponentEncode {
207
187
 
208
188
  fn encode(&self) -> Result<bytes::Bytes, Error> {
209
189
  // Take the encoder out of the cell and consume it
210
- let encoder = self.0.borrow_mut().take().ok_or_else(|| {
211
- Error::new(
212
- exception::standard_error(),
213
- "encoder is already consumed".to_string(),
214
- )
215
- })?;
216
- let encoded = encoder.encode().map_err(|e| {
217
- Error::new(
218
- exception::standard_error(),
219
- format!("failed to encode component: {}", e),
220
- )
221
- })?;
190
+ let encoder = self
191
+ .0
192
+ .borrow_mut()
193
+ .take()
194
+ .ok_or_else(|| ruby_standard_error("encoder is already consumed"))?;
195
+ let encoded = encoder
196
+ .encode()
197
+ .map_err(|e| ruby_standard_error(format!("failed to encode component: {}", e)))?;
222
198
  Ok(encoded.into())
223
199
  }
224
200
  }
@@ -235,12 +211,10 @@ impl WasiVirt {
235
211
  &self,
236
212
  body: impl FnOnce(&mut wasi_virt::WasiVirt) -> Result<R, Error>,
237
213
  ) -> Result<R, Error> {
238
- let mut virt = self.0.take().ok_or_else(|| {
239
- Error::new(
240
- exception::standard_error(),
241
- "wasi virt is already consumed".to_string(),
242
- )
243
- })?;
214
+ let mut virt = self
215
+ .0
216
+ .take()
217
+ .ok_or_else(|| ruby_standard_error("wasi virt is already consumed"))?;
244
218
  let result = body(&mut virt)?;
245
219
  self.0.replace(Some(virt));
246
220
  Ok(result)
@@ -269,10 +243,7 @@ impl WasiVirt {
269
243
  fn finish(&self) -> Result<bytes::Bytes, Error> {
270
244
  self.virt(|virt| {
271
245
  let result = virt.finish().map_err(|e| {
272
- Error::new(
273
- exception::standard_error(),
274
- format!("failed to generate virtualization adapter: {}", e),
275
- )
246
+ ruby_standard_error(format!("failed to generate virtualization adapter: {}", e))
276
247
  })?;
277
248
  Ok(result.adapter.into())
278
249
  })
@@ -282,19 +253,11 @@ impl WasiVirt {
282
253
  let virt_adapter = self.finish()?;
283
254
  let tmpdir = env::temp_dir();
284
255
  let tmp_virt = tmpdir.join(format!("virt{}.wasm", timestamp()));
285
- std::fs::write(&tmp_virt, &virt_adapter).map_err(|e| {
286
- Error::new(
287
- exception::standard_error(),
288
- format!("failed to write virt adapter: {}", e),
289
- )
290
- })?;
256
+ std::fs::write(&tmp_virt, &virt_adapter)
257
+ .map_err(|e| ruby_standard_error(format!("failed to write virt adapter: {}", e)))?;
291
258
  let tmp_component = tmpdir.join(format!("component{}.wasm", timestamp()));
292
- std::fs::write(&tmp_component, &component_bytes).map_err(|e| {
293
- Error::new(
294
- exception::standard_error(),
295
- format!("failed to write component: {}", e),
296
- )
297
- })?;
259
+ std::fs::write(&tmp_component, &component_bytes)
260
+ .map_err(|e| ruby_standard_error(format!("failed to write component: {}", e)))?;
298
261
 
299
262
  use wasm_compose::{composer, config};
300
263
  let config = config::Config {
@@ -302,12 +265,9 @@ impl WasiVirt {
302
265
  ..Default::default()
303
266
  };
304
267
  let composer = composer::ComponentComposer::new(&tmp_component, &config);
305
- let composed = composer.compose().map_err(|e| {
306
- Error::new(
307
- exception::standard_error(),
308
- format!("failed to compose component: {}", e),
309
- )
310
- })?;
268
+ let composed = composer
269
+ .compose()
270
+ .map_err(|e| ruby_standard_error(format!("failed to compose component: {}", e)))?;
311
271
  return Ok(composed.into());
312
272
 
313
273
  fn timestamp() -> u64 {
@@ -322,7 +282,7 @@ impl WasiVirt {
322
282
  #[magnus::init]
323
283
  fn init(ruby: &Ruby) -> Result<(), Error> {
324
284
  let module = RUBY_WASM.get_inner_with(ruby);
325
- module.define_error("Error", exception::standard_error())?;
285
+ module.define_error("Error", ruby.exception_standard_error())?;
326
286
 
327
287
  module.define_singleton_method("preinitialize", function!(preinit, 1))?;
328
288
 
@@ -147,6 +147,16 @@ module RubyWasm
147
147
  end
148
148
  end
149
149
 
150
+ class SilentExecutor
151
+ def system(*args, chdir: nil, env: nil)
152
+ # @type var kwargs: Hash[Symbol, untyped]
153
+ kwargs = {}
154
+ kwargs[:chdir] = chdir if chdir
155
+ kwargs[:exception] = true
156
+ __skip__ = env ? Kernel.system(env, *args, **kwargs) : Kernel.system(*args, **kwargs)
157
+ end
158
+ end
159
+
150
160
  # Human readable status printer for the build.
151
161
  class StatusPrinter
152
162
  def initialize