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 +4 -4
- data/CONTRIBUTING.md +2 -2
- data/Cargo.lock +13 -13
- data/Gemfile +1 -0
- data/README.md +16 -11
- data/Rakefile +9 -13
- data/docs/cheat_sheet.md +11 -11
- data/docs/faq.md +2 -2
- data/ext/ruby_wasm/Cargo.toml +1 -1
- data/ext/ruby_wasm/src/lib.rs +62 -102
- data/lib/ruby_wasm/build/executor.rb +10 -0
- data/lib/ruby_wasm/build/product/crossruby.rb +19 -1
- data/lib/ruby_wasm/build/toolchain.rb +144 -50
- data/lib/ruby_wasm/build.rb +1 -1
- data/lib/ruby_wasm/cli.rb +88 -44
- data/lib/ruby_wasm/packager/core.rb +1 -1
- data/lib/ruby_wasm/packager.rb +1 -1
- data/lib/ruby_wasm/version.rb +1 -1
- data/package-lock.json +26 -12
- data/rakelib/ci.rake +4 -2
- data/rakelib/packaging.rake +11 -9
- data/sig/ruby_wasm/build.rbs +34 -13
- data/sig/ruby_wasm/cli.rbs +2 -2
- data/sig/ruby_wasm/packager.rbs +2 -11
- metadata +3 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f265f5ecf5304134aa15a32d2c6569411e7fa46fba71e66a06efb63604833e27
|
|
4
|
+
data.tar.gz: 6025bc4a2848d28b278ebb096eb27008a0febf0240ae385592b7e31e2330f938
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
|
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 `
|
|
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
|
+
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.
|
|
1040
|
+
version = "0.8.2"
|
|
1041
1041
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1042
|
-
checksum = "
|
|
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.
|
|
1053
|
+
version = "0.8.0"
|
|
1054
1054
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1055
|
-
checksum = "
|
|
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.
|
|
1272
|
+
version = "0.9.123"
|
|
1273
1273
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1274
|
-
checksum = "
|
|
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.
|
|
1281
|
+
version = "0.9.123"
|
|
1282
1282
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1283
|
-
checksum = "
|
|
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.
|
|
1296
|
+
version = "0.2.2"
|
|
1297
1297
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1298
|
-
checksum = "
|
|
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
|
|
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
|
|
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
data/README.md
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/ruby/ruby.wasm/actions/workflows/build.yml)
|
|
4
4
|
|
|
5
|
-
ruby.wasm is a collection of WebAssembly ports of
|
|
6
|
-
It enables running Ruby
|
|
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
|
|
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
|
|
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/
|
|
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-
|
|
44
|
-
$ tar xfz ruby-
|
|
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-
|
|
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-
|
|
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
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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.
|
|
55
|
-
const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/
|
|
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.
|
|
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/
|
|
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/
|
|
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.
|
|
147
|
-
const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/
|
|
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
|
|
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|
|
data/ext/ruby_wasm/Cargo.toml
CHANGED
|
@@ -10,7 +10,7 @@ publish = false
|
|
|
10
10
|
crate-type = ["cdylib"]
|
|
11
11
|
|
|
12
12
|
[dependencies]
|
|
13
|
-
magnus = { version = "0.
|
|
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" }
|
data/ext/ruby_wasm/src/lib.rs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
use std::{collections::HashMap, env, path::PathBuf, time::SystemTime};
|
|
2
2
|
|
|
3
3
|
use magnus::{
|
|
4
|
-
eval,
|
|
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)
|
|
43
|
-
|
|
44
|
-
|
|
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
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
|
100
|
-
|
|
101
|
-
|
|
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
|
|
110
|
-
|
|
111
|
-
|
|
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
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
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
|
|
181
|
-
|
|
182
|
-
|
|
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
|
|
192
|
-
|
|
193
|
-
|
|
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
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
)
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
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
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
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
|
-
|
|
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)
|
|
286
|
-
|
|
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)
|
|
293
|
-
|
|
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
|
|
306
|
-
|
|
307
|
-
|
|
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",
|
|
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
|