ruby_wasm 2.5.0 → 2.5.2
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 +7 -7
- data/Cargo.lock +91 -6
- data/Gemfile +1 -1
- data/README.md +9 -9
- data/Rakefile +9 -7
- data/docs/cheat_sheet.md +8 -8
- data/ext/ruby_wasm/Cargo.toml +3 -1
- data/ext/ruby_wasm/src/lib.rs +198 -8
- data/lib/ruby_wasm/build/executor.rb +4 -0
- data/lib/ruby_wasm/build/product/crossruby.rb +59 -25
- data/lib/ruby_wasm/build/product/libyaml.rb +5 -3
- data/lib/ruby_wasm/build/product/openssl.rb +7 -2
- data/lib/ruby_wasm/build/product/product.rb +3 -3
- data/lib/ruby_wasm/build/product/ruby_source.rb +3 -3
- data/lib/ruby_wasm/build/product/wasi_vfs.rb +1 -1
- data/lib/ruby_wasm/build/product/zlib.rb +3 -1
- data/lib/ruby_wasm/build/target.rb +24 -0
- data/lib/ruby_wasm/build/toolchain/wit_bindgen.rb +2 -2
- data/lib/ruby_wasm/build/toolchain.rb +1 -1
- data/lib/ruby_wasm/build.rb +7 -3
- data/lib/ruby_wasm/cli.rb +147 -11
- data/lib/ruby_wasm/feature_set.rb +30 -0
- data/lib/ruby_wasm/packager/component_adapter/wasi_snapshot_preview1.command.wasm +0 -0
- data/lib/ruby_wasm/packager/component_adapter/wasi_snapshot_preview1.reactor.wasm +0 -0
- data/lib/ruby_wasm/packager/component_adapter.rb +14 -0
- data/lib/ruby_wasm/packager/core.rb +199 -5
- data/lib/ruby_wasm/packager/file_system.rb +5 -3
- data/lib/ruby_wasm/packager.rb +22 -82
- data/lib/ruby_wasm/rake_task.rb +1 -0
- data/lib/ruby_wasm/version.rb +1 -1
- data/lib/ruby_wasm.rb +2 -0
- data/package-lock.json +5571 -7015
- data/package.json +3 -3
- data/rakelib/check.rake +23 -10
- data/rakelib/ci.rake +3 -3
- data/rakelib/packaging.rake +44 -15
- data/sig/ruby_wasm/build.rbs +38 -28
- data/sig/ruby_wasm/cli.rbs +27 -3
- data/sig/ruby_wasm/ext.rbs +25 -2
- data/sig/ruby_wasm/feature_set.rbs +12 -0
- data/sig/ruby_wasm/packager.rbs +44 -7
- metadata +9 -10
- data/builders/wasm32-unknown-emscripten/Dockerfile +0 -43
- data/builders/wasm32-unknown-emscripten/entrypoint.sh +0 -7
- data/builders/wasm32-unknown-wasi/Dockerfile +0 -47
- data/builders/wasm32-unknown-wasi/entrypoint.sh +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a8c30db752d99a73771fdaf73c72a139b22757ba34d0cfd20b6b319eb2dae41f
|
4
|
+
data.tar.gz: c00f1796d9e1b2008c6e08690f41e4d8037d43732ce6894480f2ab34bee6439d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e78b6ceb43db9a27b9928aa048b1c4b0ab647053e6205ca68e9d5b1cdb2bee685828e7716ff87a6553a8216d6fe60682af9a76640cb2aab56c8c9f74ebdd5ef
|
7
|
+
data.tar.gz: 6fe16881179f2cfee7c54c24d8d963a774d041e5c225f1cad07300c33ecb04d2cccf7c95b7748cc1a1b48685c1305da781752a7cff27fec5d9ce54482c52b853
|
data/CONTRIBUTING.md
CHANGED
@@ -21,7 +21,7 @@ $ rake --tasks
|
|
21
21
|
$ rake build:download_prebuilt
|
22
22
|
|
23
23
|
# Build Ruby (if you need to build Ruby by yourself)
|
24
|
-
$ rake build:head-wasm32-unknown-
|
24
|
+
$ rake build:head-wasm32-unknown-wasip1-full
|
25
25
|
|
26
26
|
# Build npm package
|
27
27
|
$ rake npm:ruby-head-wasm-wasi
|
@@ -48,15 +48,15 @@ To select a build profile, see [profiles section in README](https://github.com/r
|
|
48
48
|
|
49
49
|
```console
|
50
50
|
# Build only a specific combination of ruby version, profile, and target
|
51
|
-
$ rake build:head-wasm32-unknown-
|
51
|
+
$ rake build:head-wasm32-unknown-wasip1-full
|
52
52
|
# Clean up the build directory
|
53
|
-
$ rake build:head-wasm32-unknown-
|
53
|
+
$ rake build:head-wasm32-unknown-wasip1-full:clean
|
54
54
|
# Force to re-execute "make install"
|
55
|
-
$ rake build:head-wasm32-unknown-
|
55
|
+
$ rake build:head-wasm32-unknown-wasip1-full:remake
|
56
56
|
|
57
57
|
# Output is in the `rubies` directory
|
58
|
-
$ tree -L 3 rubies/head-wasm32-unknown-
|
59
|
-
rubies/head-wasm32-unknown-
|
58
|
+
$ tree -L 3 rubies/head-wasm32-unknown-wasip1-full
|
59
|
+
rubies/head-wasm32-unknown-wasip1-full/
|
60
60
|
├── usr
|
61
61
|
│ └── local
|
62
62
|
│ ├── bin
|
@@ -124,5 +124,5 @@ $ npm install --save @ruby/wasm-wasi@latest
|
|
124
124
|
# or if you want the nightly snapshot
|
125
125
|
$ npm install --save @ruby/wasm-wasi@next
|
126
126
|
# or you can specify the exact snapshot version
|
127
|
-
$ npm install --save @ruby/wasm-wasi@2.5.
|
127
|
+
$ npm install --save @ruby/wasm-wasi@2.5.2-2024-05-04-a
|
128
128
|
```
|
data/Cargo.lock
CHANGED
@@ -1012,6 +1012,7 @@ version = "0.6.2"
|
|
1012
1012
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1013
1013
|
checksum = "4778544796676e8428e9c622460ebf284bea52d8b10db3aeb449d8b5e61b3a13"
|
1014
1014
|
dependencies = [
|
1015
|
+
"bytes",
|
1015
1016
|
"magnus-macros",
|
1016
1017
|
"rb-sys",
|
1017
1018
|
"rb-sys-env",
|
@@ -1268,18 +1269,18 @@ dependencies = [
|
|
1268
1269
|
|
1269
1270
|
[[package]]
|
1270
1271
|
name = "rb-sys"
|
1271
|
-
version = "0.9.
|
1272
|
+
version = "0.9.97"
|
1272
1273
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1273
|
-
checksum = "
|
1274
|
+
checksum = "47d30bcad206b51f2f66121190ca678dce1fdf3a2eae0ac5d838d1818b19bdf5"
|
1274
1275
|
dependencies = [
|
1275
1276
|
"rb-sys-build",
|
1276
1277
|
]
|
1277
1278
|
|
1278
1279
|
[[package]]
|
1279
1280
|
name = "rb-sys-build"
|
1280
|
-
version = "0.9.
|
1281
|
+
version = "0.9.97"
|
1281
1282
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1282
|
-
checksum = "
|
1283
|
+
checksum = "3cbd92f281615f3c2dcb9dcb0f0576624752afbf9a7f99173b37c4b55b62dd8a"
|
1283
1284
|
dependencies = [
|
1284
1285
|
"bindgen",
|
1285
1286
|
"lazy_static",
|
@@ -1362,9 +1363,11 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
|
1362
1363
|
name = "ruby_wasm"
|
1363
1364
|
version = "0.0.0"
|
1364
1365
|
dependencies = [
|
1366
|
+
"bytes",
|
1365
1367
|
"magnus",
|
1366
1368
|
"structopt",
|
1367
1369
|
"wasi-vfs-cli",
|
1370
|
+
"wit-component",
|
1368
1371
|
"wizer",
|
1369
1372
|
]
|
1370
1373
|
|
@@ -1498,6 +1501,15 @@ dependencies = [
|
|
1498
1501
|
"windows-sys 0.48.0",
|
1499
1502
|
]
|
1500
1503
|
|
1504
|
+
[[package]]
|
1505
|
+
name = "spdx"
|
1506
|
+
version = "0.10.4"
|
1507
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1508
|
+
checksum = "29ef1a0fa1e39ac22972c8db23ff89aea700ab96aa87114e1fb55937a631a0c9"
|
1509
|
+
dependencies = [
|
1510
|
+
"smallvec",
|
1511
|
+
]
|
1512
|
+
|
1501
1513
|
[[package]]
|
1502
1514
|
name = "sptr"
|
1503
1515
|
version = "0.3.2"
|
@@ -1892,6 +1904,31 @@ dependencies = [
|
|
1892
1904
|
"leb128",
|
1893
1905
|
]
|
1894
1906
|
|
1907
|
+
[[package]]
|
1908
|
+
name = "wasm-encoder"
|
1909
|
+
version = "0.203.0"
|
1910
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1911
|
+
checksum = "87e3b46a0d9d9143d57aa926c42e2af284b5cb8f0c7b71079afc7a6fca42db50"
|
1912
|
+
dependencies = [
|
1913
|
+
"leb128",
|
1914
|
+
]
|
1915
|
+
|
1916
|
+
[[package]]
|
1917
|
+
name = "wasm-metadata"
|
1918
|
+
version = "0.203.0"
|
1919
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1920
|
+
checksum = "19fbd9b7017bdb3ceb63503a18d1aa7b0d026e18ce659d40b93bd9a15391424f"
|
1921
|
+
dependencies = [
|
1922
|
+
"anyhow",
|
1923
|
+
"indexmap 2.1.0",
|
1924
|
+
"serde",
|
1925
|
+
"serde_derive",
|
1926
|
+
"serde_json",
|
1927
|
+
"spdx",
|
1928
|
+
"wasm-encoder 0.203.0",
|
1929
|
+
"wasmparser 0.203.0",
|
1930
|
+
]
|
1931
|
+
|
1895
1932
|
[[package]]
|
1896
1933
|
name = "wasmparser"
|
1897
1934
|
version = "0.106.0"
|
@@ -1912,6 +1949,17 @@ dependencies = [
|
|
1912
1949
|
"semver",
|
1913
1950
|
]
|
1914
1951
|
|
1952
|
+
[[package]]
|
1953
|
+
name = "wasmparser"
|
1954
|
+
version = "0.203.0"
|
1955
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1956
|
+
checksum = "1b473b35fff082e8c8377f4e2c8d48075e562aa051e48a02229bdcafbf349d37"
|
1957
|
+
dependencies = [
|
1958
|
+
"bitflags 2.4.1",
|
1959
|
+
"indexmap 2.1.0",
|
1960
|
+
"semver",
|
1961
|
+
]
|
1962
|
+
|
1915
1963
|
[[package]]
|
1916
1964
|
name = "wasmprinter"
|
1917
1965
|
version = "0.2.75"
|
@@ -2002,7 +2050,7 @@ dependencies = [
|
|
2002
2050
|
"syn 2.0.48",
|
2003
2051
|
"wasmtime-component-util",
|
2004
2052
|
"wasmtime-wit-bindgen",
|
2005
|
-
"wit-parser",
|
2053
|
+
"wit-parser 0.13.0",
|
2006
2054
|
]
|
2007
2055
|
|
2008
2056
|
[[package]]
|
@@ -2255,7 +2303,7 @@ dependencies = [
|
|
2255
2303
|
"anyhow",
|
2256
2304
|
"heck 0.4.1",
|
2257
2305
|
"indexmap 2.1.0",
|
2258
|
-
"wit-parser",
|
2306
|
+
"wit-parser 0.13.0",
|
2259
2307
|
]
|
2260
2308
|
|
2261
2309
|
[[package]]
|
@@ -2525,6 +2573,25 @@ dependencies = [
|
|
2525
2573
|
"windows-sys 0.52.0",
|
2526
2574
|
]
|
2527
2575
|
|
2576
|
+
[[package]]
|
2577
|
+
name = "wit-component"
|
2578
|
+
version = "0.203.0"
|
2579
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2580
|
+
checksum = "379c4e193d37b3e2c808e99515c2a91dc19e7b3b160adfbb374463875375d6ff"
|
2581
|
+
dependencies = [
|
2582
|
+
"anyhow",
|
2583
|
+
"bitflags 2.4.1",
|
2584
|
+
"indexmap 2.1.0",
|
2585
|
+
"log",
|
2586
|
+
"serde",
|
2587
|
+
"serde_derive",
|
2588
|
+
"serde_json",
|
2589
|
+
"wasm-encoder 0.203.0",
|
2590
|
+
"wasm-metadata",
|
2591
|
+
"wasmparser 0.203.0",
|
2592
|
+
"wit-parser 0.203.0",
|
2593
|
+
]
|
2594
|
+
|
2528
2595
|
[[package]]
|
2529
2596
|
name = "wit-parser"
|
2530
2597
|
version = "0.13.0"
|
@@ -2542,6 +2609,24 @@ dependencies = [
|
|
2542
2609
|
"unicode-xid",
|
2543
2610
|
]
|
2544
2611
|
|
2612
|
+
[[package]]
|
2613
|
+
name = "wit-parser"
|
2614
|
+
version = "0.203.0"
|
2615
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2616
|
+
checksum = "3f547f9154c0fbd020c81c348d703b549bafd16ea68b15927acb5c890467e734"
|
2617
|
+
dependencies = [
|
2618
|
+
"anyhow",
|
2619
|
+
"id-arena",
|
2620
|
+
"indexmap 2.1.0",
|
2621
|
+
"log",
|
2622
|
+
"semver",
|
2623
|
+
"serde",
|
2624
|
+
"serde_derive",
|
2625
|
+
"serde_json",
|
2626
|
+
"unicode-xid",
|
2627
|
+
"wasmparser 0.203.0",
|
2628
|
+
]
|
2629
|
+
|
2545
2630
|
[[package]]
|
2546
2631
|
name = "witx"
|
2547
2632
|
version = "0.9.1"
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -17,17 +17,17 @@ 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 browser
|
20
|
+
## Quick Example: Ruby on Web browser
|
21
21
|
|
22
22
|
Create and save `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.3-wasm-wasi@2.5.
|
26
|
+
<script src="https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.5.2/dist/browser.script.iife.js"></script>
|
27
27
|
<script type="text/ruby">
|
28
28
|
require "js"
|
29
29
|
|
30
|
-
puts RUBY_VERSION #
|
30
|
+
puts RUBY_VERSION # (Printed to the Web browser console)
|
31
31
|
JS.global[:document].write "Hello, world!"
|
32
32
|
</script>
|
33
33
|
</html>
|
@@ -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.3-wasm32-unknown-
|
44
|
-
$ tar xfz ruby-3.3-wasm32-unknown-
|
43
|
+
$ curl -LO https://github.com/ruby/ruby.wasm/releases/latest/download/ruby-3.3-wasm32-unknown-wasip1-full.tar.gz
|
44
|
+
$ tar xfz ruby-3.3-wasm32-unknown-wasip1-full.tar.gz
|
45
45
|
|
46
46
|
# Extract ruby binary not to pack itself
|
47
|
-
$ mv ruby-3.3-wasm32-unknown-
|
47
|
+
$ mv ruby-3.3-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.3-wasm32-unknown-
|
54
|
+
$ rbwasm pack ruby.wasm --dir ./src::/src --dir ./ruby-3.3-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
|
@@ -110,8 +110,8 @@ A _build_ is a combination of ruby version, _profile_, and _target_.
|
|
110
110
|
</thead>
|
111
111
|
<tbody>
|
112
112
|
<tr>
|
113
|
-
<td><code>wasm32-unknown-
|
114
|
-
<td>Targeting WASI
|
113
|
+
<td><code>wasm32-unknown-wasip1</code></td>
|
114
|
+
<td>Targeting <a href="https://github.com/WebAssembly/WASI/tree/main/legacy/preview1">WASI Preview1</a> compatible environments <br>(e.g. Node.js, browsers with polyfill, <a href="https://github.com/bytecodealliance/wasmtime">wasmtime</a>, and so on)</td>
|
115
115
|
</tr>
|
116
116
|
<tr>
|
117
117
|
<td><code>wasm32-unknown-emscripten</code></td>
|
data/Rakefile
CHANGED
@@ -7,6 +7,7 @@ $LOAD_PATH << File.join(File.dirname(__FILE__), "lib")
|
|
7
7
|
require "bundler/gem_tasks"
|
8
8
|
require "ruby_wasm/rake_task"
|
9
9
|
require "ruby_wasm/packager"
|
10
|
+
require "ruby_wasm/cli"
|
10
11
|
|
11
12
|
BUILD_SOURCES = %w[3.3 3.2 head]
|
12
13
|
BUILD_PROFILES = %w[full minimal]
|
@@ -14,7 +15,7 @@ BUILD_PROFILES = %w[full minimal]
|
|
14
15
|
BUILDS =
|
15
16
|
BUILD_SOURCES
|
16
17
|
.product(BUILD_PROFILES)
|
17
|
-
.map { |src, profile| [src, "wasm32-unknown-
|
18
|
+
.map { |src, profile| [src, "wasm32-unknown-wasip1", profile] } +
|
18
19
|
BUILD_SOURCES.map { |src| [src, "wasm32-unknown-emscripten", "full"] }
|
19
20
|
|
20
21
|
NPM_PACKAGES = [
|
@@ -28,26 +29,27 @@ NPM_PACKAGES = [
|
|
28
29
|
name: "ruby-head-wasm-wasi",
|
29
30
|
ruby_version: "head",
|
30
31
|
gemfile: "packages/npm-packages/ruby-wasm-wasi/Gemfile",
|
31
|
-
target: "wasm32-unknown-
|
32
|
+
target: "wasm32-unknown-wasip1",
|
33
|
+
enable_component_model: true,
|
32
34
|
},
|
33
35
|
{
|
34
36
|
name: "ruby-3.3-wasm-wasi",
|
35
37
|
ruby_version: "3.3",
|
36
38
|
gemfile: "packages/npm-packages/ruby-wasm-wasi/Gemfile",
|
37
|
-
target: "wasm32-unknown-
|
39
|
+
target: "wasm32-unknown-wasip1"
|
38
40
|
},
|
39
41
|
{
|
40
42
|
name: "ruby-3.2-wasm-wasi",
|
41
43
|
ruby_version: "3.2",
|
42
44
|
gemfile: "packages/npm-packages/ruby-wasm-wasi/Gemfile",
|
43
|
-
target: "wasm32-unknown-
|
45
|
+
target: "wasm32-unknown-wasip1"
|
44
46
|
},
|
45
|
-
{ name: "ruby-wasm-wasi", target: "wasm32-unknown-
|
47
|
+
{ name: "ruby-wasm-wasi", target: "wasm32-unknown-wasip1" }
|
46
48
|
]
|
47
49
|
|
48
50
|
STANDALONE_PACKAGES = [
|
49
|
-
{ name: "ruby", build: "head-wasm32-unknown-
|
50
|
-
{ name: "irb", build: "head-wasm32-unknown-
|
51
|
+
{ name: "ruby", build: "head-wasm32-unknown-wasip1-full" },
|
52
|
+
{ name: "irb", build: "head-wasm32-unknown-wasip1-full" }
|
51
53
|
]
|
52
54
|
|
53
55
|
LIB_ROOT = File.dirname(__FILE__)
|
data/docs/cheat_sheet.md
CHANGED
@@ -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.3-wasm-wasi@2.5.
|
41
|
+
<script src="https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.5.2/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.5.
|
55
|
-
const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.5.
|
54
|
+
import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.5.2/dist/browser/+esm";
|
55
|
+
const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.5.2/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.5.
|
72
|
+
<script src="https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.5.2/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.3-wasm-wasi@2.5.
|
76
|
+
const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.5.2/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.3-wasm-wasi@2.5.
|
131
|
+
<script src="https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.5.2/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.5.
|
147
|
-
const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.5.
|
146
|
+
import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.5.2/dist/browser/+esm";
|
147
|
+
const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.5.2/dist/ruby+stdlib.wasm");
|
148
148
|
const module = await WebAssembly.compileStreaming(response);
|
149
149
|
const { vm } = await DefaultRubyVM(module);
|
150
150
|
|
data/ext/ruby_wasm/Cargo.toml
CHANGED
@@ -10,7 +10,9 @@ publish = false
|
|
10
10
|
crate-type = ["cdylib"]
|
11
11
|
|
12
12
|
[dependencies]
|
13
|
-
magnus = "0.6.2"
|
13
|
+
magnus = { version = "0.6.2", features = ["bytes"] }
|
14
|
+
bytes = "1"
|
14
15
|
wizer = "4.0.0"
|
15
16
|
wasi-vfs-cli = { git = "https://github.com/kateinoigakukun/wasi-vfs/", tag = "0.5.2" }
|
16
17
|
structopt = "0.3.26"
|
18
|
+
wit-component = "0.203.0"
|
data/ext/ruby_wasm/src/lib.rs
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
use std::path::PathBuf;
|
1
|
+
use std::{collections::HashMap, path::PathBuf};
|
2
2
|
|
3
3
|
use magnus::{
|
4
4
|
eval, exception, function, method,
|
@@ -6,13 +6,13 @@ use magnus::{
|
|
6
6
|
value::{self, InnerValue},
|
7
7
|
wrap, Error, ExceptionClass, RModule, Ruby,
|
8
8
|
};
|
9
|
-
use wizer::Wizer;
|
10
9
|
use structopt::StructOpt;
|
10
|
+
use wizer::Wizer;
|
11
11
|
|
12
12
|
static RUBY_WASM: value::Lazy<RModule> =
|
13
13
|
value::Lazy::new(|ruby| ruby.define_module("RubyWasmExt").unwrap());
|
14
14
|
|
15
|
-
fn preinit(core_module:
|
15
|
+
fn preinit(core_module: bytes::Bytes) -> Result<bytes::Bytes, Error> {
|
16
16
|
let rbwasm_error = eval("RubyWasmExt::Error")?;
|
17
17
|
let rbwasm_error = ExceptionClass::from_value(rbwasm_error).unwrap();
|
18
18
|
let mut wizer = Wizer::new();
|
@@ -26,6 +26,7 @@ fn preinit(core_module: Vec<u8>) -> Result<Vec<u8>, Error> {
|
|
26
26
|
wizer
|
27
27
|
.run(&core_module)
|
28
28
|
.map_err(|e| Error::new(rbwasm_error, format!("failed to run wizer: {}", e)))
|
29
|
+
.map(|output| output.into())
|
29
30
|
}
|
30
31
|
|
31
32
|
struct WasiVfsInner {
|
@@ -50,17 +51,174 @@ impl WasiVfs {
|
|
50
51
|
}
|
51
52
|
|
52
53
|
fn map_dir(&self, guest_dir: String, host_dir: String) {
|
53
|
-
self.0
|
54
|
+
self.0
|
55
|
+
.borrow_mut()
|
56
|
+
.map_dirs
|
57
|
+
.push((guest_dir.into(), host_dir.into()));
|
58
|
+
}
|
59
|
+
|
60
|
+
fn pack(&self, wasm_bytes: bytes::Bytes) -> Result<bytes::Bytes, Error> {
|
61
|
+
let output_bytes = wasi_vfs_cli::pack(&wasm_bytes, self.0.borrow().map_dirs.clone())
|
62
|
+
.map_err(|e| {
|
63
|
+
Error::new(
|
64
|
+
exception::standard_error(),
|
65
|
+
format!("failed to pack wasi vfs: {}", e),
|
66
|
+
)
|
67
|
+
})?;
|
68
|
+
Ok(output_bytes.into())
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
#[wrap(class = "RubyWasmExt::ComponentLink")]
|
73
|
+
struct ComponentLink(std::cell::RefCell<Option<wit_component::Linker>>);
|
74
|
+
|
75
|
+
impl ComponentLink {
|
76
|
+
fn new() -> Self {
|
77
|
+
Self(std::cell::RefCell::new(Some(
|
78
|
+
wit_component::Linker::default(),
|
79
|
+
)))
|
80
|
+
}
|
81
|
+
fn linker(
|
82
|
+
&self,
|
83
|
+
body: impl FnOnce(wit_component::Linker) -> Result<wit_component::Linker, Error>,
|
84
|
+
) -> Result<(), Error> {
|
85
|
+
let mut linker = self.0.take().ok_or_else(|| {
|
86
|
+
Error::new(
|
87
|
+
exception::standard_error(),
|
88
|
+
"linker is already consumed".to_string(),
|
89
|
+
)
|
90
|
+
})?;
|
91
|
+
linker = body(linker)?;
|
92
|
+
self.0.replace(Some(linker));
|
93
|
+
Ok(())
|
94
|
+
}
|
95
|
+
|
96
|
+
fn library(&self, name: String, module: bytes::Bytes, dl_openable: bool) -> Result<(), Error> {
|
97
|
+
self.linker(|linker| {
|
98
|
+
linker.library(&name, &module, dl_openable).map_err(|e| {
|
99
|
+
Error::new(
|
100
|
+
exception::standard_error(),
|
101
|
+
format!("failed to link library: {}", e),
|
102
|
+
)
|
103
|
+
})
|
104
|
+
})
|
105
|
+
}
|
106
|
+
fn adapter(&self, name: String, module: bytes::Bytes) -> Result<(), Error> {
|
107
|
+
self.linker(|linker| {
|
108
|
+
linker.adapter(&name, &module).map_err(|e| {
|
109
|
+
Error::new(
|
110
|
+
exception::standard_error(),
|
111
|
+
format!("failed to link adapter: {}", e),
|
112
|
+
)
|
113
|
+
})
|
114
|
+
})
|
115
|
+
}
|
116
|
+
fn validate(&self, validate: bool) -> Result<(), Error> {
|
117
|
+
self.linker(|linker| Ok(linker.validate(validate)))
|
118
|
+
}
|
119
|
+
fn stack_size(&self, size: u32) -> Result<(), Error> {
|
120
|
+
self.linker(|linker| Ok(linker.stack_size(size)))
|
121
|
+
}
|
122
|
+
fn stub_missing_functions(&self, stub: bool) -> Result<(), Error> {
|
123
|
+
self.linker(|linker| Ok(linker.stub_missing_functions(stub)))
|
124
|
+
}
|
125
|
+
fn use_built_in_libdl(&self, use_libdl: bool) -> Result<(), Error> {
|
126
|
+
self.linker(|linker| Ok(linker.use_built_in_libdl(use_libdl)))
|
127
|
+
}
|
128
|
+
fn encode(&self) -> Result<bytes::Bytes, Error> {
|
129
|
+
// Take the linker out of the cell and consume it
|
130
|
+
let linker = self.0.borrow_mut().take().ok_or_else(|| {
|
131
|
+
Error::new(
|
132
|
+
exception::standard_error(),
|
133
|
+
"linker is already consumed".to_string(),
|
134
|
+
)
|
135
|
+
})?;
|
136
|
+
let encoded = linker.encode().map_err(|e| {
|
137
|
+
Error::new(
|
138
|
+
exception::standard_error(),
|
139
|
+
format!("failed to encode linker: {}", e),
|
140
|
+
)
|
141
|
+
})?;
|
142
|
+
Ok(encoded.into())
|
143
|
+
}
|
144
|
+
}
|
145
|
+
|
146
|
+
#[wrap(class = "RubyWasmExt::ComponentEncode")]
|
147
|
+
struct ComponentEncode(std::cell::RefCell<Option<wit_component::ComponentEncoder>>);
|
148
|
+
|
149
|
+
impl ComponentEncode {
|
150
|
+
fn new() -> Self {
|
151
|
+
Self(std::cell::RefCell::new(Some(
|
152
|
+
wit_component::ComponentEncoder::default(),
|
153
|
+
)))
|
54
154
|
}
|
55
155
|
|
56
|
-
fn
|
57
|
-
|
156
|
+
fn encoder(
|
157
|
+
&self,
|
158
|
+
body: impl FnOnce(
|
159
|
+
wit_component::ComponentEncoder,
|
160
|
+
) -> Result<wit_component::ComponentEncoder, Error>,
|
161
|
+
) -> Result<(), Error> {
|
162
|
+
let mut encoder = self.0.take().ok_or_else(|| {
|
58
163
|
Error::new(
|
59
164
|
exception::standard_error(),
|
60
|
-
|
165
|
+
"encoder is already consumed".to_string(),
|
61
166
|
)
|
62
167
|
})?;
|
63
|
-
|
168
|
+
encoder = body(encoder)?;
|
169
|
+
self.0.replace(Some(encoder));
|
170
|
+
Ok(())
|
171
|
+
}
|
172
|
+
|
173
|
+
fn validate(&self, validate: bool) -> Result<(), Error> {
|
174
|
+
self.encoder(|encoder| Ok(encoder.validate(validate)))
|
175
|
+
}
|
176
|
+
|
177
|
+
fn adapter(&self, name: String, module: bytes::Bytes) -> Result<(), Error> {
|
178
|
+
self.encoder(|encoder| {
|
179
|
+
encoder.adapter(&name, &module).map_err(|e| {
|
180
|
+
Error::new(
|
181
|
+
exception::standard_error(),
|
182
|
+
format!("failed to encode adapter: {}", e),
|
183
|
+
)
|
184
|
+
})
|
185
|
+
})
|
186
|
+
}
|
187
|
+
|
188
|
+
fn module(&self, module: bytes::Bytes) -> Result<(), Error> {
|
189
|
+
self.encoder(|encoder| {
|
190
|
+
encoder.module(&module).map_err(|e| {
|
191
|
+
Error::new(
|
192
|
+
exception::standard_error(),
|
193
|
+
format!("failed to encode module: {}", e),
|
194
|
+
)
|
195
|
+
})
|
196
|
+
})
|
197
|
+
}
|
198
|
+
|
199
|
+
fn realloc_via_memory_grow(&self, realloc: bool) -> Result<(), Error> {
|
200
|
+
self.encoder(|encoder| Ok(encoder.realloc_via_memory_grow(realloc)))
|
201
|
+
}
|
202
|
+
|
203
|
+
fn import_name_map(&self, map: HashMap<String, String>) -> Result<(), Error> {
|
204
|
+
self.encoder(|encoder| Ok(encoder.import_name_map(map)))
|
205
|
+
}
|
206
|
+
|
207
|
+
fn encode(&self) -> Result<bytes::Bytes, Error> {
|
208
|
+
// Take the encoder out of the cell and consume it
|
209
|
+
let encoder = self.0.borrow_mut().take().ok_or_else(|| {
|
210
|
+
Error::new(
|
211
|
+
exception::standard_error(),
|
212
|
+
"encoder is already consumed".to_string(),
|
213
|
+
)
|
214
|
+
})?;
|
215
|
+
let encoded = encoder.encode().map_err(|e| {
|
216
|
+
Error::new(
|
217
|
+
exception::standard_error(),
|
218
|
+
format!("failed to encode component: {}", e),
|
219
|
+
)
|
220
|
+
})?;
|
221
|
+
Ok(encoded.into())
|
64
222
|
}
|
65
223
|
}
|
66
224
|
|
@@ -76,5 +234,37 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
76
234
|
wasi_vfs.define_singleton_method("run_cli", function!(WasiVfs::run_cli, 1))?;
|
77
235
|
wasi_vfs.define_method("map_dir", method!(WasiVfs::map_dir, 2))?;
|
78
236
|
wasi_vfs.define_method("pack", method!(WasiVfs::pack, 1))?;
|
237
|
+
|
238
|
+
let component_link = module.define_class("ComponentLink", ruby.class_object())?;
|
239
|
+
component_link.define_singleton_method("new", function!(ComponentLink::new, 0))?;
|
240
|
+
component_link.define_method("library", method!(ComponentLink::library, 3))?;
|
241
|
+
component_link.define_method("adapter", method!(ComponentLink::adapter, 2))?;
|
242
|
+
component_link.define_method("validate", method!(ComponentLink::validate, 1))?;
|
243
|
+
component_link.define_method("stack_size", method!(ComponentLink::stack_size, 1))?;
|
244
|
+
component_link.define_method(
|
245
|
+
"stub_missing_functions",
|
246
|
+
method!(ComponentLink::stub_missing_functions, 1),
|
247
|
+
)?;
|
248
|
+
component_link.define_method(
|
249
|
+
"use_built_in_libdl",
|
250
|
+
method!(ComponentLink::use_built_in_libdl, 1),
|
251
|
+
)?;
|
252
|
+
component_link.define_method("encode", method!(ComponentLink::encode, 0))?;
|
253
|
+
|
254
|
+
let component_encode = module.define_class("ComponentEncode", ruby.class_object())?;
|
255
|
+
component_encode.define_singleton_method("new", function!(ComponentEncode::new, 0))?;
|
256
|
+
component_encode.define_method("validate", method!(ComponentEncode::validate, 1))?;
|
257
|
+
component_encode.define_method("adapter", method!(ComponentEncode::adapter, 2))?;
|
258
|
+
component_encode.define_method("module", method!(ComponentEncode::module, 1))?;
|
259
|
+
component_encode.define_method(
|
260
|
+
"realloc_via_memory_grow",
|
261
|
+
method!(ComponentEncode::realloc_via_memory_grow, 1),
|
262
|
+
)?;
|
263
|
+
component_encode.define_method(
|
264
|
+
"import_name_map",
|
265
|
+
method!(ComponentEncode::import_name_map, 1),
|
266
|
+
)?;
|
267
|
+
component_encode.define_method("encode", method!(ComponentEncode::encode, 0))?;
|
268
|
+
|
79
269
|
Ok(())
|
80
270
|
}
|