ruby_wasm 2.5.0 → 2.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +7 -7
  3. data/Cargo.lock +91 -6
  4. data/Gemfile +1 -1
  5. data/README.md +9 -9
  6. data/Rakefile +8 -7
  7. data/docs/cheat_sheet.md +8 -8
  8. data/ext/ruby_wasm/Cargo.toml +3 -1
  9. data/ext/ruby_wasm/src/lib.rs +198 -8
  10. data/lib/ruby_wasm/build/executor.rb +4 -0
  11. data/lib/ruby_wasm/build/product/crossruby.rb +53 -23
  12. data/lib/ruby_wasm/build/product/libyaml.rb +5 -3
  13. data/lib/ruby_wasm/build/product/openssl.rb +7 -2
  14. data/lib/ruby_wasm/build/product/product.rb +3 -3
  15. data/lib/ruby_wasm/build/product/ruby_source.rb +3 -3
  16. data/lib/ruby_wasm/build/product/wasi_vfs.rb +1 -1
  17. data/lib/ruby_wasm/build/product/zlib.rb +3 -1
  18. data/lib/ruby_wasm/build/target.rb +24 -0
  19. data/lib/ruby_wasm/build/toolchain.rb +1 -1
  20. data/lib/ruby_wasm/build.rb +7 -3
  21. data/lib/ruby_wasm/cli.rb +147 -11
  22. data/lib/ruby_wasm/feature_set.rb +30 -0
  23. data/lib/ruby_wasm/packager/component_adapter/wasi_snapshot_preview1.command.wasm +0 -0
  24. data/lib/ruby_wasm/packager/component_adapter/wasi_snapshot_preview1.reactor.wasm +0 -0
  25. data/lib/ruby_wasm/packager/component_adapter.rb +14 -0
  26. data/lib/ruby_wasm/packager/core.rb +192 -4
  27. data/lib/ruby_wasm/packager/file_system.rb +5 -3
  28. data/lib/ruby_wasm/packager.rb +21 -83
  29. data/lib/ruby_wasm/rake_task.rb +1 -0
  30. data/lib/ruby_wasm/version.rb +1 -1
  31. data/lib/ruby_wasm.rb +2 -0
  32. data/package-lock.json +410 -133
  33. data/package.json +3 -3
  34. data/rakelib/ci.rake +3 -3
  35. data/rakelib/packaging.rake +26 -12
  36. data/sig/ruby_wasm/build.rbs +36 -27
  37. data/sig/ruby_wasm/cli.rbs +27 -3
  38. data/sig/ruby_wasm/ext.rbs +25 -2
  39. data/sig/ruby_wasm/feature_set.rbs +12 -0
  40. data/sig/ruby_wasm/packager.rbs +44 -7
  41. metadata +9 -7
  42. data/builders/wasm32-unknown-emscripten/Dockerfile +0 -43
  43. data/builders/wasm32-unknown-emscripten/entrypoint.sh +0 -7
  44. data/builders/wasm32-unknown-wasi/Dockerfile +0 -47
  45. data/builders/wasm32-unknown-wasi/entrypoint.sh +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f42f03a6e5dcd06b68414f462b48a22402e1944e5535342f3d3b707697ffff42
4
- data.tar.gz: f685a3c61822ab104266c30e1646384a0e5450c9b2eab24d84ad565b03c7b192
3
+ metadata.gz: 141bd526a7aa152f05058c93841d80f242c72137591183a9d5f891bf5ee715fe
4
+ data.tar.gz: 2f491189cc5667b6f601e08c1685ace9fc9992738d264c76587487a91f4bde0b
5
5
  SHA512:
6
- metadata.gz: 96dfec4b5cb068578c121106228bf646246fca5d28b9b7fa94d47a8668bd9ead185cbc29e9f002fd25c302132970bd509ffa27dce3ee967a2c8ea203d6f3df50
7
- data.tar.gz: adbaf753357914c4b25791f39915a62863f61fc062903f21037ce95c8a075b45c14228aa08acfc81ca69fd994a1b473b7fcaf219fad145b4a7cff238b240895e
6
+ metadata.gz: 551d4bf9b6f7485f3a286363671a1f990729a0c626dd0b2b18324146826c3176873301359003ed3978c2a36d1e5ed46d9ddce93b213968bf59f0f9302f02901d
7
+ data.tar.gz: 48ca26f8ccb3e18b39a541e3ab3c41a154a3ddec56890d0b87f3fb88a2d6f16b509558c316cb75182fa80a29c94e76f760731a0d75b0fd089d5b4415cfd46513
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-wasi-full
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-wasi-full
51
+ $ rake build:head-wasm32-unknown-wasip1-full
52
52
  # Clean up the build directory
53
- $ rake build:head-wasm32-unknown-wasi-full:clean
53
+ $ rake build:head-wasm32-unknown-wasip1-full:clean
54
54
  # Force to re-execute "make install"
55
- $ rake build:head-wasm32-unknown-wasi-full:remake
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-wasi-full
59
- rubies/head-wasm32-unknown-wasi-full/
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.0-2024-01-28-a
127
+ $ npm install --save @ruby/wasm-wasi@2.5.1-2024-04-21-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.86"
1272
+ version = "0.9.97"
1272
1273
  source = "registry+https://github.com/rust-lang/crates.io-index"
1273
- checksum = "7285f2a7b92f58ab198e3fd59a71d2861478f9c4642f41e83582385818941697"
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.86"
1281
+ version = "0.9.97"
1281
1282
  source = "registry+https://github.com/rust-lang/crates.io-index"
1282
- checksum = "71583945f94dabb6c0dfa63f1b71e929c1901e1e288ef3739ab8bed3b7069550"
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
@@ -7,7 +7,7 @@ gemspec
7
7
  group :development do
8
8
  gem "rake"
9
9
  gem "rake-compiler"
10
- gem "rb_sys", "0.9.85"
10
+ gem "rb_sys", "0.9.97"
11
11
  end
12
12
 
13
13
  group :check do
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.0/dist/browser.script.iife.js"></script>
26
+ <script src="https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.5.1/dist/browser.script.iife.js"></script>
27
27
  <script type="text/ruby">
28
28
  require "js"
29
29
 
30
- puts RUBY_VERSION # => Hello, world! (printed to the browser console)
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-wasi-full.tar.gz
44
- $ tar xfz ruby-3.3-wasm32-unknown-wasi-full.tar.gz
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-wasi-full/usr/local/bin/ruby ruby.wasm
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-wasi-full/usr::/usr -o my-ruby-app.wasm
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-wasi</code></td>
114
- <td>Targeting WASI-compatible environments (e.g. Node.js, browsers with polyfill, <a href="https://github.com/bytecodealliance/wasmtime">wasmtime</a>, and so on)</td>
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-wasi", profile] } +
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,26 @@ 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-wasi"
32
+ target: "wasm32-unknown-wasip1"
32
33
  },
33
34
  {
34
35
  name: "ruby-3.3-wasm-wasi",
35
36
  ruby_version: "3.3",
36
37
  gemfile: "packages/npm-packages/ruby-wasm-wasi/Gemfile",
37
- target: "wasm32-unknown-wasi"
38
+ target: "wasm32-unknown-wasip1"
38
39
  },
39
40
  {
40
41
  name: "ruby-3.2-wasm-wasi",
41
42
  ruby_version: "3.2",
42
43
  gemfile: "packages/npm-packages/ruby-wasm-wasi/Gemfile",
43
- target: "wasm32-unknown-wasi"
44
+ target: "wasm32-unknown-wasip1"
44
45
  },
45
- { name: "ruby-wasm-wasi", target: "wasm32-unknown-wasi" }
46
+ { name: "ruby-wasm-wasi", target: "wasm32-unknown-wasip1" }
46
47
  ]
47
48
 
48
49
  STANDALONE_PACKAGES = [
49
- { name: "ruby", build: "head-wasm32-unknown-wasi-full" },
50
- { name: "irb", build: "head-wasm32-unknown-wasi-full" }
50
+ { name: "ruby", build: "head-wasm32-unknown-wasip1-full" },
51
+ { name: "irb", build: "head-wasm32-unknown-wasip1-full" }
51
52
  ]
52
53
 
53
54
  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.0/dist/browser.script.iife.js"></script>
41
+ <script src="https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.5.1/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.0/dist/browser/+esm";
55
- const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.5.0/dist/ruby+stdlib.wasm");
54
+ import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.5.1/dist/browser/+esm";
55
+ const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.5.1/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.0/dist/browser.umd.js"></script>
72
+ <script src="https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.5.1/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.0/dist/ruby+stdlib.wasm");
76
+ const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.5.1/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.0/dist/browser.script.iife.js"></script>
131
+ <script src="https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.5.1/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.0/dist/browser/+esm";
147
- const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.5.0/dist/ruby+stdlib.wasm");
146
+ import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.5.1/dist/browser/+esm";
147
+ const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.5.1/dist/ruby+stdlib.wasm");
148
148
  const module = await WebAssembly.compileStreaming(response);
149
149
  const { vm } = await DefaultRubyVM(module);
150
150
 
@@ -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"
@@ -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: Vec<u8>) -> Result<Vec<u8>, Error> {
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.borrow_mut().map_dirs.push((guest_dir.into(), host_dir.into()));
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 pack(&self, wasm_bytes: Vec<u8>) -> Result<Vec<u8>, Error> {
57
- let output_bytes = wasi_vfs_cli::pack(&wasm_bytes, self.0.borrow().map_dirs.clone()).map_err(|e| {
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
- format!("failed to pack wasi vfs: {}", e),
165
+ "encoder is already consumed".to_string(),
61
166
  )
62
167
  })?;
63
- Ok(output_bytes)
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
  }
@@ -128,6 +128,10 @@ module RubyWasm
128
128
  FileUtils.mkdir_p(list)
129
129
  end
130
130
 
131
+ def ln_s(src, dest)
132
+ FileUtils.ln_s(src, dest)
133
+ end
134
+
131
135
  def write(path, data)
132
136
  File.write(path, data)
133
137
  end