@ruby/3.2-wasm-wasi 2.6.2 → 2.7.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.
package/dist/index.umd.js CHANGED
@@ -199,39 +199,23 @@ Please replace your \`require('ruby-3.2-wasm-wasi/dist/index.umd');\` with \`req
199
199
  class RbAbiGuest {
200
200
  constructor() {
201
201
  this._resource0_slab = new Slab();
202
- this._resource1_slab = new Slab();
203
202
  }
204
203
  addToImports(imports) {
205
204
  if (!("canonical_abi" in imports)) imports["canonical_abi"] = {};
206
205
 
207
- imports.canonical_abi['resource_drop_rb-iseq'] = i => {
206
+ imports.canonical_abi['resource_drop_rb-abi-value'] = i => {
208
207
  this._resource0_slab.remove(i).drop();
209
208
  };
210
- imports.canonical_abi['resource_clone_rb-iseq'] = i => {
209
+ imports.canonical_abi['resource_clone_rb-abi-value'] = i => {
211
210
  const obj = this._resource0_slab.get(i);
212
211
  return this._resource0_slab.insert(obj.clone())
213
212
  };
214
- imports.canonical_abi['resource_get_rb-iseq'] = i => {
215
- return this._resource0_slab.get(i)._wasm_val;
216
- };
217
- imports.canonical_abi['resource_new_rb-iseq'] = i => {
218
- this._registry0;
219
- return this._resource0_slab.insert(new RbIseq(i, this));
220
- };
221
-
222
- imports.canonical_abi['resource_drop_rb-abi-value'] = i => {
223
- this._resource1_slab.remove(i).drop();
224
- };
225
- imports.canonical_abi['resource_clone_rb-abi-value'] = i => {
226
- const obj = this._resource1_slab.get(i);
227
- return this._resource1_slab.insert(obj.clone())
228
- };
229
213
  imports.canonical_abi['resource_get_rb-abi-value'] = i => {
230
- return this._resource1_slab.get(i)._wasm_val;
214
+ return this._resource0_slab.get(i)._wasm_val;
231
215
  };
232
216
  imports.canonical_abi['resource_new_rb-abi-value'] = i => {
233
- this._registry1;
234
- return this._resource1_slab.insert(new RbAbiValue(i, this));
217
+ this._registry0;
218
+ return this._resource0_slab.insert(new RbAbiValue(i, this));
235
219
  };
236
220
  }
237
221
 
@@ -251,16 +235,12 @@ Please replace your \`require('ruby-3.2-wasm-wasi/dist/index.umd');\` with \`req
251
235
  this.instance = instance;
252
236
  }
253
237
  this._exports = this.instance.exports;
254
- this._registry0 = new FinalizationRegistry(this._exports['canonical_abi_drop_rb-iseq']);
255
- this._registry1 = new FinalizationRegistry(this._exports['canonical_abi_drop_rb-abi-value']);
238
+ this._registry0 = new FinalizationRegistry(this._exports['canonical_abi_drop_rb-abi-value']);
256
239
  }
257
240
  rubyShowVersion() {
258
241
  this._exports['ruby-show-version: func() -> ()']();
259
242
  }
260
- rubyInit() {
261
- this._exports['ruby-init: func() -> ()']();
262
- }
263
- rubySysinit(arg0) {
243
+ rubyInit(arg0) {
264
244
  const memory = this._exports.memory;
265
245
  const realloc = this._exports["cabi_realloc"];
266
246
  const vec1 = arg0;
@@ -274,31 +254,7 @@ Please replace your \`require('ruby-3.2-wasm-wasi/dist/index.umd');\` with \`req
274
254
  data_view(memory).setInt32(base + 4, len0, true);
275
255
  data_view(memory).setInt32(base + 0, ptr0, true);
276
256
  }
277
- this._exports['ruby-sysinit: func(args: list<string>) -> ()'](result1, len1);
278
- }
279
- rubyOptions(arg0) {
280
- const memory = this._exports.memory;
281
- const realloc = this._exports["cabi_realloc"];
282
- const vec1 = arg0;
283
- const len1 = vec1.length;
284
- const result1 = realloc(0, 0, 4, len1 * 8);
285
- for (let i = 0; i < vec1.length; i++) {
286
- const e = vec1[i];
287
- const base = result1 + i * 8;
288
- const ptr0 = utf8_encode(e, realloc, memory);
289
- const len0 = UTF8_ENCODED_LEN;
290
- data_view(memory).setInt32(base + 4, len0, true);
291
- data_view(memory).setInt32(base + 0, ptr0, true);
292
- }
293
- const ret = this._exports['ruby-options: func(args: list<string>) -> handle<rb-iseq>'](result1, len1);
294
- return this._resource0_slab.remove(ret);
295
- }
296
- rubyScript(arg0) {
297
- const memory = this._exports.memory;
298
- const realloc = this._exports["cabi_realloc"];
299
- const ptr0 = utf8_encode(arg0, realloc, memory);
300
- const len0 = UTF8_ENCODED_LEN;
301
- this._exports['ruby-script: func(name: string) -> ()'](ptr0, len0);
257
+ this._exports['ruby-init: func(args: list<string>) -> ()'](result1, len1);
302
258
  }
303
259
  rubyInitLoadpath() {
304
260
  this._exports['ruby-init-loadpath: func() -> ()']();
@@ -309,7 +265,7 @@ Please replace your \`require('ruby-3.2-wasm-wasi/dist/index.umd');\` with \`req
309
265
  const ptr0 = utf8_encode(arg0, realloc, memory);
310
266
  const len0 = UTF8_ENCODED_LEN;
311
267
  const ret = this._exports['rb-eval-string-protect: func(str: string) -> tuple<handle<rb-abi-value>, s32>'](ptr0, len0);
312
- return [this._resource1_slab.remove(data_view(memory).getInt32(ret + 0, true)), data_view(memory).getInt32(ret + 4, true)];
268
+ return [this._resource0_slab.remove(data_view(memory).getInt32(ret + 0, true)), data_view(memory).getInt32(ret + 4, true)];
313
269
  }
314
270
  rbFuncallvProtect(arg0, arg1, arg2) {
315
271
  const memory = this._exports.memory;
@@ -324,10 +280,10 @@ Please replace your \`require('ruby-3.2-wasm-wasi/dist/index.umd');\` with \`req
324
280
  const base = result2 + i * 4;
325
281
  const obj1 = e;
326
282
  if (!(obj1 instanceof RbAbiValue)) throw new TypeError('expected instance of RbAbiValue');
327
- data_view(memory).setInt32(base + 0, this._resource1_slab.insert(obj1.clone()), true);
283
+ data_view(memory).setInt32(base + 0, this._resource0_slab.insert(obj1.clone()), true);
328
284
  }
329
- const ret = this._exports['rb-funcallv-protect: func(recv: handle<rb-abi-value>, mid: u32, args: list<handle<rb-abi-value>>) -> tuple<handle<rb-abi-value>, s32>'](this._resource1_slab.insert(obj0.clone()), to_uint32(arg1), result2, len2);
330
- return [this._resource1_slab.remove(data_view(memory).getInt32(ret + 0, true)), data_view(memory).getInt32(ret + 4, true)];
285
+ const ret = this._exports['rb-funcallv-protect: func(recv: handle<rb-abi-value>, mid: u32, args: list<handle<rb-abi-value>>) -> tuple<handle<rb-abi-value>, s32>'](this._resource0_slab.insert(obj0.clone()), to_uint32(arg1), result2, len2);
286
+ return [this._resource0_slab.remove(data_view(memory).getInt32(ret + 0, true)), data_view(memory).getInt32(ret + 4, true)];
331
287
  }
332
288
  rbIntern(arg0) {
333
289
  const memory = this._exports.memory;
@@ -339,7 +295,7 @@ Please replace your \`require('ruby-3.2-wasm-wasi/dist/index.umd');\` with \`req
339
295
  }
340
296
  rbErrinfo() {
341
297
  const ret = this._exports['rb-errinfo: func() -> handle<rb-abi-value>']();
342
- return this._resource1_slab.remove(ret);
298
+ return this._resource0_slab.remove(ret);
343
299
  }
344
300
  rbClearErrinfo() {
345
301
  this._exports['rb-clear-errinfo: func() -> ()']();
@@ -348,7 +304,7 @@ Please replace your \`require('ruby-3.2-wasm-wasi/dist/index.umd');\` with \`req
348
304
  const memory = this._exports.memory;
349
305
  const obj0 = arg0;
350
306
  if (!(obj0 instanceof RbAbiValue)) throw new TypeError('expected instance of RbAbiValue');
351
- const ret = this._exports['rstring-ptr: func(value: handle<rb-abi-value>) -> string'](this._resource1_slab.insert(obj0.clone()));
307
+ const ret = this._exports['rstring-ptr: func(value: handle<rb-abi-value>) -> string'](this._resource0_slab.insert(obj0.clone()));
352
308
  const ptr1 = data_view(memory).getInt32(ret + 0, true);
353
309
  const len1 = data_view(memory).getInt32(ret + 4, true);
354
310
  const result1 = UTF8_DECODER.decode(new Uint8Array(memory.buffer, ptr1, len1));
@@ -375,7 +331,7 @@ Please replace your \`require('ruby-3.2-wasm-wasi/dist/index.umd');\` with \`req
375
331
  }
376
332
  }
377
333
 
378
- class RbIseq {
334
+ class RbAbiValue {
379
335
  constructor(wasm_val, obj) {
380
336
  this._wasm_val = wasm_val;
381
337
  this._obj = obj;
@@ -393,33 +349,6 @@ Please replace your \`require('ruby-3.2-wasm-wasi/dist/index.umd');\` with \`req
393
349
  if (this._refcnt !== 0)
394
350
  return;
395
351
  this._obj._registry0.unregister(this);
396
- const dtor = this._obj._exports['canonical_abi_drop_rb-iseq'];
397
- const wasm_val = this._wasm_val;
398
- delete this._obj;
399
- delete this._refcnt;
400
- delete this._wasm_val;
401
- dtor(wasm_val);
402
- }
403
- }
404
-
405
- class RbAbiValue {
406
- constructor(wasm_val, obj) {
407
- this._wasm_val = wasm_val;
408
- this._obj = obj;
409
- this._refcnt = 1;
410
- obj._registry1.register(this, wasm_val, this);
411
- }
412
-
413
- clone() {
414
- this._refcnt += 1;
415
- return this;
416
- }
417
-
418
- drop() {
419
- this._refcnt -= 1;
420
- if (this._refcnt !== 0)
421
- return;
422
- this._obj._registry1.unregister(this);
423
352
  const dtor = this._obj._exports['canonical_abi_drop_rb-abi-value'];
424
353
  const wasm_val = this._wasm_val;
425
354
  delete this._obj;
@@ -720,17 +649,8 @@ Please replace your \`require('ruby-3.2-wasm-wasi/dist/index.umd');\` with \`req
720
649
  rubyShowVersion() {
721
650
  this.underlying.rubyShowVersion();
722
651
  }
723
- rubyInit() {
724
- this.underlying.rubyInit();
725
- }
726
- rubySysinit(args) {
727
- this.underlying.rubySysinit(args);
728
- }
729
- rubyOptions(args) {
730
- this.underlying.rubyOptions(args);
731
- }
732
- rubyScript(name) {
733
- this.underlying.rubyScript(name);
652
+ rubyInit(args) {
653
+ this.underlying.rubyInit(args);
734
654
  }
735
655
  rubyInitLoadpath() {
736
656
  this.underlying.rubyInitLoadpath();
@@ -775,24 +695,111 @@ Please replace your \`require('ruby-3.2-wasm-wasi/dist/index.umd');\` with \`req
775
695
 
776
696
  /**
777
697
  * A Ruby VM instance
778
- *
779
- * @example
780
- *
781
- * const wasi = new WASI();
782
- * const vm = new RubyVM();
783
- * const imports = {
784
- * wasi_snapshot_preview1: wasi.wasiImport,
785
- * };
786
- *
787
- * vm.addToImports(imports);
788
- *
789
- * const instance = await WebAssembly.instantiate(rubyModule, imports);
790
- * await vm.setInstance(instance);
791
- * wasi.initialize(instance);
792
- * vm.initialize();
793
- *
698
+ * @see {@link RubyVM.instantiateComponent} and {@link RubyVM.instantiateModule} to create a new instance
699
+ * @category Essentials
794
700
  */
795
701
  class RubyVM {
702
+ /**
703
+ * Instantiate a Ruby VM with the given WebAssembly Core module with WASI Preview 1 implementation.
704
+ *
705
+ * @param options The options to instantiate the Ruby VM
706
+ * @returns A promise that resolves to the Ruby VM instance and the WebAssembly instance
707
+ * @category Essentials
708
+ *
709
+ * @example
710
+ *
711
+ * import { WASI } from "@bjorn3/browser_wasi_shim";
712
+ * const wasip1 = new WASI([], [], []);
713
+ * const module = await WebAssembly.compile("./path/to/ruby.wasm");
714
+ * const { vm } = await RubyVM.instantiateModule({ module, wasip1 });
715
+ *
716
+ */
717
+ static async instantiateModule(options) {
718
+ var _a, _b;
719
+ const { module, wasip1 } = options;
720
+ const vm = new RubyVM();
721
+ const imports = {
722
+ wasi_snapshot_preview1: wasip1.wasiImport,
723
+ };
724
+ vm.addToImports(imports);
725
+ (_a = options.addToImports) === null || _a === void 0 ? void 0 : _a.call(options, imports);
726
+ const instance = await WebAssembly.instantiate(module, imports);
727
+ await vm.setInstance(instance);
728
+ (_b = options.setMemory) === null || _b === void 0 ? void 0 : _b.call(options, instance.exports.memory);
729
+ wasip1.initialize(instance);
730
+ vm.initialize(options.args);
731
+ return { vm, instance };
732
+ }
733
+ /**
734
+ * Instantiate a Ruby VM with the given WebAssembly component with WASI Preview 2 implementation.
735
+ *
736
+ * @param options The options to instantiate the Ruby VM
737
+ * @returns A promise that resolves to the Ruby VM instance
738
+ * @category Essentials
739
+ *
740
+ * @example
741
+ *
742
+ * // First, you need to transpile the Ruby component to a JavaScript module using jco.
743
+ * // $ jco transpile --no-wasi-shim --instantiation --valid-lifting-optimization ./ruby.component.wasm -o ./component
744
+ * // Then, you can instantiate the Ruby VM with the component:
745
+ *
746
+ * import * as wasip2 from "@bytecodealliance/preview2-shim"
747
+ * import fs from "fs/promises";
748
+ * import path from "path";
749
+ *
750
+ * const { instantiate } = await import("./component/ruby.component.js");
751
+ * const getCoreModule = async (relativePath) => {
752
+ * const buffer = await fs.readFile(path.join("./component", relativePath));
753
+ * return WebAssembly.compile(buffer);
754
+ * }
755
+ *
756
+ * const { vm } = await RubyVM.instantiateComponent({
757
+ * instantiate, getCoreModule, wasip2,
758
+ * });
759
+ *
760
+ */
761
+ static async instantiateComponent(options) {
762
+ let initComponent;
763
+ if ("getCoreModule" in options) {
764
+ // A convenience overload to instantiate with "instantiate" function generated by jco
765
+ initComponent = async (jsRuntime) => {
766
+ const { instantiate, getCoreModule, wasip2 } = options;
767
+ const { cli, clocks, filesystem, io, random, sockets, http } = wasip2;
768
+ const importObject = {
769
+ "ruby:js/js-runtime": jsRuntime,
770
+ "wasi:cli/environment": cli.environment,
771
+ "wasi:cli/exit": cli.exit,
772
+ "wasi:cli/stderr": cli.stderr,
773
+ "wasi:cli/stdin": cli.stdin,
774
+ "wasi:cli/stdout": cli.stdout,
775
+ "wasi:cli/terminal-input": cli.terminalInput,
776
+ "wasi:cli/terminal-output": cli.terminalOutput,
777
+ "wasi:cli/terminal-stderr": cli.terminalStderr,
778
+ "wasi:cli/terminal-stdin": cli.terminalStdin,
779
+ "wasi:cli/terminal-stdout": cli.terminalStdout,
780
+ "wasi:clocks/monotonic-clock": clocks.monotonicClock,
781
+ "wasi:clocks/wall-clock": clocks.wallClock,
782
+ "wasi:filesystem/preopens": filesystem.preopens,
783
+ "wasi:filesystem/types": filesystem.types,
784
+ "wasi:io/error": io.error,
785
+ "wasi:io/poll": io.poll,
786
+ "wasi:io/streams": io.streams,
787
+ "wasi:random/random": random.random,
788
+ "wasi:sockets/tcp": sockets.tcp,
789
+ "wasi:http/types": http.types,
790
+ "wasi:http/incoming-handler": http.incomingHandler,
791
+ "wasi:http/outgoing-handler": http.outgoingHandler,
792
+ };
793
+ const component = await instantiate(getCoreModule, importObject, options.instantiateCore);
794
+ return component.rubyRuntime;
795
+ };
796
+ }
797
+ else {
798
+ initComponent = options.instantiate;
799
+ }
800
+ const vm = await this._instantiate({}, initComponent);
801
+ return { vm };
802
+ }
796
803
  constructor(binding) {
797
804
  this.instance = null;
798
805
  this.interfaceState = {
@@ -841,7 +848,7 @@ Please replace your \`require('ruby-3.2-wasm-wasi/dist/index.umd');\` with \`req
841
848
  this.transport = new JsValueTransport();
842
849
  this.exceptionFormatter = new RbExceptionFormatter();
843
850
  }
844
- static async _instantiate(initComponent, options) {
851
+ static async _instantiate(options, initComponent) {
845
852
  const binding = new ComponentBinding();
846
853
  const vm = new RubyVM(binding);
847
854
  class JsAbiValue {
@@ -869,14 +876,21 @@ Please replace your \`require('ruby-3.2-wasm-wasi/dist/index.umd');\` with \`req
869
876
  * Initialize the Ruby VM with the given command line arguments
870
877
  * @param args The command line arguments to pass to Ruby. Must be
871
878
  * an array of strings starting with the Ruby program name.
879
+ * @category Low-level initialization
872
880
  */
873
881
  initialize(args = ["ruby.wasm", "-EUTF-8", "-e_=0"]) {
874
882
  const c_args = args.map((arg) => arg + "\0");
875
- this.guest.rubyInit();
876
- this.guest.rubySysinit(c_args);
877
- this.guest.rubyOptions(c_args);
883
+ this.guest.rubyInit(c_args);
878
884
  try {
879
- this.eval(`require "/bundle/setup"`);
885
+ this.eval(`
886
+ # Require Bundler standalone setup
887
+ if File.exist?("/bundle/bundler/setup.rb")
888
+ require "/bundle/bundler/setup.rb"
889
+ elsif File.exist?("/bundle/setup.rb")
890
+ # For non-CM builds, which doesn't use Bundler's standalone mode
891
+ require "/bundle/setup.rb"
892
+ end
893
+ `);
880
894
  }
881
895
  catch (e) {
882
896
  console.warn("Failed to load /bundle/setup", e);
@@ -890,6 +904,7 @@ Please replace your \`require('ruby-3.2-wasm-wasi/dist/index.umd');\` with \`req
890
904
  * @param instance The WebAssembly instance to interact with. Must
891
905
  * be instantiated from a Ruby built with JS extension, and built
892
906
  * with Reactor ABI instead of command line.
907
+ * @category Low-level initialization
893
908
  */
894
909
  async setInstance(instance) {
895
910
  this.instance = instance;
@@ -899,6 +914,7 @@ Please replace your \`require('ruby-3.2-wasm-wasi/dist/index.umd');\` with \`req
899
914
  * Add intrinsic import entries, which is necessary to interact JavaScript
900
915
  * and Ruby's WebAssembly instance.
901
916
  * @param imports The import object to add to the WebAssembly instance
917
+ * @category Low-level initialization
902
918
  */
903
919
  addToImports(imports) {
904
920
  this.guest.addToImports(imports);
@@ -1104,6 +1120,7 @@ Please replace your \`require('ruby-3.2-wasm-wasi/dist/index.umd');\` with \`req
1104
1120
  * Runs a string of Ruby code from JavaScript
1105
1121
  * @param code The Ruby code to run
1106
1122
  * @returns the result of the last expression
1123
+ * @category Essentials
1107
1124
  *
1108
1125
  * @example
1109
1126
  * vm.eval("puts 'hello world'");
@@ -1119,6 +1136,7 @@ Please replace your \`require('ruby-3.2-wasm-wasi/dist/index.umd');\` with \`req
1119
1136
  * Returns a promise that resolves when execution completes.
1120
1137
  * @param code The Ruby code to run
1121
1138
  * @returns a promise that resolves to the result of the last expression
1139
+ * @category Essentials
1122
1140
  *
1123
1141
  * @example
1124
1142
  * const text = await vm.evalAsync(`
@@ -1201,6 +1219,7 @@ Please replace your \`require('ruby-3.2-wasm-wasi/dist/index.umd');\` with \`req
1201
1219
  }
1202
1220
  /**
1203
1221
  * A RbValue is an object that represents a value in Ruby
1222
+ * @category Essentials
1204
1223
  */
1205
1224
  class RbValue {
1206
1225
  /**
Binary file
Binary file
package/dist/ruby.wasm CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruby/3.2-wasm-wasi",
3
- "version": "2.6.2",
3
+ "version": "2.7.0",
4
4
  "description": "Ruby 3.2 built on WASI",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/esm/index.js",