@ruby/wasm-wasi 2.6.2-2024-09-04-a → 2.6.2-2024-09-06-a

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/README.md CHANGED
@@ -16,235 +16,4 @@ See [Cheat Sheet](https://github.com/ruby/ruby.wasm/blob/main/docs/cheat_sheet.m
16
16
 
17
17
  ## API
18
18
 
19
- <!-- Generated by documentation.js. Update this documentation by updating the source code. -->
20
-
21
- ### consolePrinter
22
-
23
- Create a console printer that can be used as an overlay of WASI imports.
24
- See the example below for how to use it.
25
-
26
- ```javascript
27
- const imports = {
28
- wasi_snapshot_preview1: wasi.wasiImport,
29
- };
30
- const printer = consolePrinter();
31
- printer.addToImports(imports);
32
-
33
- const instance = await WebAssembly.instantiate(module, imports);
34
- printer.setMemory(instance.exports.memory);
35
- ```
36
-
37
- Note that the `stdout` and `stderr` functions are called with text, not
38
- bytes. This means that bytes written to stdout/stderr will be decoded as
39
- UTF-8 and then passed to the `stdout`/`stderr` functions every time a write
40
- occurs without buffering.
41
-
42
- #### Parameters
43
-
44
- - `$0` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** (optional, default `{stdout:console.log,stderr:console.warn}`)
45
-
46
- - `$0.stdout` &#x20;
47
- - `$0.stderr` &#x20;
48
-
49
- - `stdout` A function that will be called when stdout is written to.
50
- Defaults to `console.log`.
51
- - `stderr` A function that will be called when stderr is written to.
52
- Defaults to `console.warn`.
53
-
54
- Returns **any** An object that can be used as an overlay of WASI imports.
55
-
56
- ### RubyVM
57
-
58
- A Ruby VM instance
59
-
60
- #### Examples
61
-
62
- ```javascript
63
- const wasi = new WASI();
64
- const vm = new RubyVM();
65
- const imports = {
66
- wasi_snapshot_preview1: wasi.wasiImport,
67
- };
68
-
69
- vm.addToImports(imports);
70
-
71
- const instance = await WebAssembly.instantiate(rubyModule, imports);
72
- await vm.setInstance(instance);
73
- wasi.initialize(instance);
74
- vm.initialize();
75
- ```
76
-
77
- #### initialize
78
-
79
- Initialize the Ruby VM with the given command line arguments
80
-
81
- ##### Parameters
82
-
83
- - `args` The command line arguments to pass to Ruby. Must be
84
- an array of strings starting with the Ruby program name. (optional, default `["ruby.wasm","-EUTF-8","-e_=0"]`)
85
-
86
- #### setInstance
87
-
88
- Set a given instance to interact JavaScript and Ruby's
89
- WebAssembly instance. This method must be called before calling
90
- Ruby API.
91
-
92
- ##### Parameters
93
-
94
- - `instance` The WebAssembly instance to interact with. Must
95
- be instantiated from a Ruby built with JS extension, and built
96
- with Reactor ABI instead of command line.
97
-
98
- #### addToImports
99
-
100
- Add intrinsic import entries, which is necessary to interact JavaScript
101
- and Ruby's WebAssembly instance.
102
-
103
- ##### Parameters
104
-
105
- - `imports` The import object to add to the WebAssembly instance
106
-
107
- #### printVersion
108
-
109
- Print the Ruby version to stdout
110
-
111
- #### eval
112
-
113
- Runs a string of Ruby code from JavaScript
114
-
115
- ##### Parameters
116
-
117
- - `code` The Ruby code to run
118
-
119
- ##### Examples
120
-
121
- ```javascript
122
- vm.eval("puts 'hello world'");
123
- const result = vm.eval("1 + 2");
124
- console.log(result.toString()); // 3
125
- ```
126
-
127
- Returns **any** the result of the last expression
128
-
129
- #### evalAsync
130
-
131
- Runs a string of Ruby code with top-level `JS::Object#await`
132
- Returns a promise that resolves when execution completes.
133
-
134
- ##### Parameters
135
-
136
- - `code` The Ruby code to run
137
-
138
- ##### Examples
139
-
140
- ```javascript
141
- const text = await vm.evalAsync(`
142
- require 'js'
143
- response = JS.global.fetch('https://example.com').await
144
- response.text.await
145
- `);
146
- console.log(text.toString()); // <html>...</html>
147
- ```
148
-
149
- Returns **any** a promise that resolves to the result of the last expression
150
-
151
- #### wrap
152
-
153
- Wrap a JavaScript value into a Ruby JS::Object
154
-
155
- ##### Parameters
156
-
157
- - `value` The value to convert to RbValue
158
-
159
- ##### Examples
160
-
161
- ```javascript
162
- const hash = vm.eval(`Hash.new`);
163
- hash.call("store", vm.eval(`"key1"`), vm.wrap(new Object()));
164
- ```
165
-
166
- Returns **any** the RbValue object representing the given JS value
167
-
168
- ### RbValue
169
-
170
- A RbValue is an object that represents a value in Ruby
171
-
172
- #### call
173
-
174
- Call a given method with given arguments
175
-
176
- ##### Parameters
177
-
178
- - `callee` name of the Ruby method to call
179
- - `args` **...any** arguments to pass to the method. Must be an array of RbValue
180
-
181
- ##### Examples
182
-
183
- ```javascript
184
- const ary = vm.eval("[1, 2, 3]");
185
- ary.call("push", vm.wrap(4));
186
- console.log(ary.call("sample").toString());
187
- ```
188
-
189
- Returns **any** The result of the method call as a new RbValue.
190
-
191
- #### callAsync
192
-
193
- Call a given method that may call `JS::Object#await` with given arguments
194
-
195
- ##### Parameters
196
-
197
- - `callee` name of the Ruby method to call
198
- - `args` **...any** arguments to pass to the method. Must be an array of RbValue
199
-
200
- ##### Examples
201
-
202
- ```javascript
203
- const client = vm.eval(`
204
- require 'js'
205
- class HttpClient
206
- def get(url)
207
- JS.global.fetch(url).await
208
- end
209
- end
210
- HttpClient.new
211
- `);
212
- const response = await client.callAsync(
213
- "get",
214
- vm.eval(`"https://example.com"`),
215
- );
216
- ```
217
-
218
- Returns **any** A Promise that resolves to the result of the method call as a new RbValue.
219
-
220
- #### toPrimitive
221
-
222
- - **See**: <https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive>
223
-
224
- ##### Parameters
225
-
226
- - `hint` Preferred type of the result primitive value. `"number"`, `"string"`, or `"default"`.
227
-
228
- #### toString
229
-
230
- Returns a string representation of the value by calling `to_s`
231
-
232
- #### toJS
233
-
234
- Returns a JavaScript object representation of the value
235
- by calling `to_js`.
236
-
237
- Returns null if the value is not convertible to a JavaScript object.
238
-
239
- ### RbError
240
-
241
- **Extends Error**
242
-
243
- Error class thrown by Ruby execution
244
-
245
- ### RbFatalError
246
-
247
- **Extends RbError**
248
-
249
- Error class thrown by Ruby execution when it is not possible to recover.
250
- This is usually caused when Ruby VM is in an inconsistent state.
19
+ See [API Documentation](https://ruby.github.io/ruby.wasm/npm/@ruby/wasm-wasi/) for details.
@@ -248,39 +248,23 @@
248
248
  class RbAbiGuest {
249
249
  constructor() {
250
250
  this._resource0_slab = new Slab();
251
- this._resource1_slab = new Slab();
252
251
  }
253
252
  addToImports(imports) {
254
253
  if (!("canonical_abi" in imports)) imports["canonical_abi"] = {};
255
254
 
256
- imports.canonical_abi['resource_drop_rb-iseq'] = i => {
255
+ imports.canonical_abi['resource_drop_rb-abi-value'] = i => {
257
256
  this._resource0_slab.remove(i).drop();
258
257
  };
259
- imports.canonical_abi['resource_clone_rb-iseq'] = i => {
258
+ imports.canonical_abi['resource_clone_rb-abi-value'] = i => {
260
259
  const obj = this._resource0_slab.get(i);
261
260
  return this._resource0_slab.insert(obj.clone())
262
261
  };
263
- imports.canonical_abi['resource_get_rb-iseq'] = i => {
264
- return this._resource0_slab.get(i)._wasm_val;
265
- };
266
- imports.canonical_abi['resource_new_rb-iseq'] = i => {
267
- this._registry0;
268
- return this._resource0_slab.insert(new RbIseq(i, this));
269
- };
270
-
271
- imports.canonical_abi['resource_drop_rb-abi-value'] = i => {
272
- this._resource1_slab.remove(i).drop();
273
- };
274
- imports.canonical_abi['resource_clone_rb-abi-value'] = i => {
275
- const obj = this._resource1_slab.get(i);
276
- return this._resource1_slab.insert(obj.clone())
277
- };
278
262
  imports.canonical_abi['resource_get_rb-abi-value'] = i => {
279
- return this._resource1_slab.get(i)._wasm_val;
263
+ return this._resource0_slab.get(i)._wasm_val;
280
264
  };
281
265
  imports.canonical_abi['resource_new_rb-abi-value'] = i => {
282
- this._registry1;
283
- return this._resource1_slab.insert(new RbAbiValue(i, this));
266
+ this._registry0;
267
+ return this._resource0_slab.insert(new RbAbiValue(i, this));
284
268
  };
285
269
  }
286
270
 
@@ -300,16 +284,12 @@
300
284
  this.instance = instance;
301
285
  }
302
286
  this._exports = this.instance.exports;
303
- this._registry0 = new FinalizationRegistry(this._exports['canonical_abi_drop_rb-iseq']);
304
- this._registry1 = new FinalizationRegistry(this._exports['canonical_abi_drop_rb-abi-value']);
287
+ this._registry0 = new FinalizationRegistry(this._exports['canonical_abi_drop_rb-abi-value']);
305
288
  }
306
289
  rubyShowVersion() {
307
290
  this._exports['ruby-show-version: func() -> ()']();
308
291
  }
309
- rubyInit() {
310
- this._exports['ruby-init: func() -> ()']();
311
- }
312
- rubySysinit(arg0) {
292
+ rubyInit(arg0) {
313
293
  const memory = this._exports.memory;
314
294
  const realloc = this._exports["cabi_realloc"];
315
295
  const vec1 = arg0;
@@ -323,31 +303,7 @@
323
303
  data_view(memory).setInt32(base + 4, len0, true);
324
304
  data_view(memory).setInt32(base + 0, ptr0, true);
325
305
  }
326
- this._exports['ruby-sysinit: func(args: list<string>) -> ()'](result1, len1);
327
- }
328
- rubyOptions(arg0) {
329
- const memory = this._exports.memory;
330
- const realloc = this._exports["cabi_realloc"];
331
- const vec1 = arg0;
332
- const len1 = vec1.length;
333
- const result1 = realloc(0, 0, 4, len1 * 8);
334
- for (let i = 0; i < vec1.length; i++) {
335
- const e = vec1[i];
336
- const base = result1 + i * 8;
337
- const ptr0 = utf8_encode(e, realloc, memory);
338
- const len0 = UTF8_ENCODED_LEN;
339
- data_view(memory).setInt32(base + 4, len0, true);
340
- data_view(memory).setInt32(base + 0, ptr0, true);
341
- }
342
- const ret = this._exports['ruby-options: func(args: list<string>) -> handle<rb-iseq>'](result1, len1);
343
- return this._resource0_slab.remove(ret);
344
- }
345
- rubyScript(arg0) {
346
- const memory = this._exports.memory;
347
- const realloc = this._exports["cabi_realloc"];
348
- const ptr0 = utf8_encode(arg0, realloc, memory);
349
- const len0 = UTF8_ENCODED_LEN;
350
- this._exports['ruby-script: func(name: string) -> ()'](ptr0, len0);
306
+ this._exports['ruby-init: func(args: list<string>) -> ()'](result1, len1);
351
307
  }
352
308
  rubyInitLoadpath() {
353
309
  this._exports['ruby-init-loadpath: func() -> ()']();
@@ -358,7 +314,7 @@
358
314
  const ptr0 = utf8_encode(arg0, realloc, memory);
359
315
  const len0 = UTF8_ENCODED_LEN;
360
316
  const ret = this._exports['rb-eval-string-protect: func(str: string) -> tuple<handle<rb-abi-value>, s32>'](ptr0, len0);
361
- return [this._resource1_slab.remove(data_view(memory).getInt32(ret + 0, true)), data_view(memory).getInt32(ret + 4, true)];
317
+ return [this._resource0_slab.remove(data_view(memory).getInt32(ret + 0, true)), data_view(memory).getInt32(ret + 4, true)];
362
318
  }
363
319
  rbFuncallvProtect(arg0, arg1, arg2) {
364
320
  const memory = this._exports.memory;
@@ -373,10 +329,10 @@
373
329
  const base = result2 + i * 4;
374
330
  const obj1 = e;
375
331
  if (!(obj1 instanceof RbAbiValue)) throw new TypeError('expected instance of RbAbiValue');
376
- data_view(memory).setInt32(base + 0, this._resource1_slab.insert(obj1.clone()), true);
332
+ data_view(memory).setInt32(base + 0, this._resource0_slab.insert(obj1.clone()), true);
377
333
  }
378
- 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);
379
- return [this._resource1_slab.remove(data_view(memory).getInt32(ret + 0, true)), data_view(memory).getInt32(ret + 4, true)];
334
+ 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);
335
+ return [this._resource0_slab.remove(data_view(memory).getInt32(ret + 0, true)), data_view(memory).getInt32(ret + 4, true)];
380
336
  }
381
337
  rbIntern(arg0) {
382
338
  const memory = this._exports.memory;
@@ -388,7 +344,7 @@
388
344
  }
389
345
  rbErrinfo() {
390
346
  const ret = this._exports['rb-errinfo: func() -> handle<rb-abi-value>']();
391
- return this._resource1_slab.remove(ret);
347
+ return this._resource0_slab.remove(ret);
392
348
  }
393
349
  rbClearErrinfo() {
394
350
  this._exports['rb-clear-errinfo: func() -> ()']();
@@ -397,7 +353,7 @@
397
353
  const memory = this._exports.memory;
398
354
  const obj0 = arg0;
399
355
  if (!(obj0 instanceof RbAbiValue)) throw new TypeError('expected instance of RbAbiValue');
400
- const ret = this._exports['rstring-ptr: func(value: handle<rb-abi-value>) -> string'](this._resource1_slab.insert(obj0.clone()));
356
+ const ret = this._exports['rstring-ptr: func(value: handle<rb-abi-value>) -> string'](this._resource0_slab.insert(obj0.clone()));
401
357
  const ptr1 = data_view(memory).getInt32(ret + 0, true);
402
358
  const len1 = data_view(memory).getInt32(ret + 4, true);
403
359
  const result1 = UTF8_DECODER.decode(new Uint8Array(memory.buffer, ptr1, len1));
@@ -424,7 +380,7 @@
424
380
  }
425
381
  }
426
382
 
427
- class RbIseq {
383
+ class RbAbiValue {
428
384
  constructor(wasm_val, obj) {
429
385
  this._wasm_val = wasm_val;
430
386
  this._obj = obj;
@@ -442,33 +398,6 @@
442
398
  if (this._refcnt !== 0)
443
399
  return;
444
400
  this._obj._registry0.unregister(this);
445
- const dtor = this._obj._exports['canonical_abi_drop_rb-iseq'];
446
- const wasm_val = this._wasm_val;
447
- delete this._obj;
448
- delete this._refcnt;
449
- delete this._wasm_val;
450
- dtor(wasm_val);
451
- }
452
- }
453
-
454
- class RbAbiValue {
455
- constructor(wasm_val, obj) {
456
- this._wasm_val = wasm_val;
457
- this._obj = obj;
458
- this._refcnt = 1;
459
- obj._registry1.register(this, wasm_val, this);
460
- }
461
-
462
- clone() {
463
- this._refcnt += 1;
464
- return this;
465
- }
466
-
467
- drop() {
468
- this._refcnt -= 1;
469
- if (this._refcnt !== 0)
470
- return;
471
- this._obj._registry1.unregister(this);
472
401
  const dtor = this._obj._exports['canonical_abi_drop_rb-abi-value'];
473
402
  const wasm_val = this._wasm_val;
474
403
  delete this._obj;
@@ -769,17 +698,8 @@
769
698
  rubyShowVersion() {
770
699
  this.underlying.rubyShowVersion();
771
700
  }
772
- rubyInit() {
773
- this.underlying.rubyInit();
774
- }
775
- rubySysinit(args) {
776
- this.underlying.rubySysinit(args);
777
- }
778
- rubyOptions(args) {
779
- this.underlying.rubyOptions(args);
780
- }
781
- rubyScript(name) {
782
- this.underlying.rubyScript(name);
701
+ rubyInit(args) {
702
+ this.underlying.rubyInit(args);
783
703
  }
784
704
  rubyInitLoadpath() {
785
705
  this.underlying.rubyInitLoadpath();
@@ -824,24 +744,111 @@
824
744
 
825
745
  /**
826
746
  * A Ruby VM instance
827
- *
828
- * @example
829
- *
830
- * const wasi = new WASI();
831
- * const vm = new RubyVM();
832
- * const imports = {
833
- * wasi_snapshot_preview1: wasi.wasiImport,
834
- * };
835
- *
836
- * vm.addToImports(imports);
837
- *
838
- * const instance = await WebAssembly.instantiate(rubyModule, imports);
839
- * await vm.setInstance(instance);
840
- * wasi.initialize(instance);
841
- * vm.initialize();
842
- *
747
+ * @see {@link RubyVM.instantiateComponent} and {@link RubyVM.instantiateModule} to create a new instance
748
+ * @category Essentials
843
749
  */
844
750
  class RubyVM {
751
+ /**
752
+ * Instantiate a Ruby VM with the given WebAssembly Core module with WASI Preview 1 implementation.
753
+ *
754
+ * @param options The options to instantiate the Ruby VM
755
+ * @returns A promise that resolves to the Ruby VM instance and the WebAssembly instance
756
+ * @category Essentials
757
+ *
758
+ * @example
759
+ *
760
+ * import { WASI } from "@bjorn3/browser_wasi_shim";
761
+ * const wasip1 = new WASI([], [], []);
762
+ * const module = await WebAssembly.compile("./path/to/ruby.wasm");
763
+ * const { vm } = await RubyVM.instantiateModule({ module, wasip1 });
764
+ *
765
+ */
766
+ static async instantiateModule(options) {
767
+ var _a, _b;
768
+ const { module, wasip1 } = options;
769
+ const vm = new RubyVM();
770
+ const imports = {
771
+ wasi_snapshot_preview1: wasip1.wasiImport,
772
+ };
773
+ vm.addToImports(imports);
774
+ (_a = options.addToImports) === null || _a === void 0 ? void 0 : _a.call(options, imports);
775
+ const instance = await WebAssembly.instantiate(module, imports);
776
+ await vm.setInstance(instance);
777
+ (_b = options.setMemory) === null || _b === void 0 ? void 0 : _b.call(options, instance.exports.memory);
778
+ wasip1.initialize(instance);
779
+ vm.initialize(options.args);
780
+ return { vm, instance };
781
+ }
782
+ /**
783
+ * Instantiate a Ruby VM with the given WebAssembly component with WASI Preview 2 implementation.
784
+ *
785
+ * @param options The options to instantiate the Ruby VM
786
+ * @returns A promise that resolves to the Ruby VM instance
787
+ * @category Essentials
788
+ *
789
+ * @example
790
+ *
791
+ * // First, you need to transpile the Ruby component to a JavaScript module using jco.
792
+ * // $ jco transpile --no-wasi-shim --instantiation --valid-lifting-optimization ./ruby.component.wasm -o ./component
793
+ * // Then, you can instantiate the Ruby VM with the component:
794
+ *
795
+ * import * as wasip2 from "@bytecodealliance/preview2-shim"
796
+ * import fs from "fs/promises";
797
+ * import path from "path";
798
+ *
799
+ * const { instantiate } = await import("./component/ruby.component.js");
800
+ * const getCoreModule = async (relativePath) => {
801
+ * const buffer = await fs.readFile(path.join("./component", relativePath));
802
+ * return WebAssembly.compile(buffer);
803
+ * }
804
+ *
805
+ * const { vm } = await RubyVM.instantiateComponent({
806
+ * instantiate, getCoreModule, wasip2,
807
+ * });
808
+ *
809
+ */
810
+ static async instantiateComponent(options) {
811
+ let initComponent;
812
+ if ("getCoreModule" in options) {
813
+ // A convenience overload to instantiate with "instantiate" function generated by jco
814
+ initComponent = async (jsRuntime) => {
815
+ const { instantiate, getCoreModule, wasip2 } = options;
816
+ const { cli, clocks, filesystem, io, random, sockets, http } = wasip2;
817
+ const importObject = {
818
+ "ruby:js/js-runtime": jsRuntime,
819
+ "wasi:cli/environment": cli.environment,
820
+ "wasi:cli/exit": cli.exit,
821
+ "wasi:cli/stderr": cli.stderr,
822
+ "wasi:cli/stdin": cli.stdin,
823
+ "wasi:cli/stdout": cli.stdout,
824
+ "wasi:cli/terminal-input": cli.terminalInput,
825
+ "wasi:cli/terminal-output": cli.terminalOutput,
826
+ "wasi:cli/terminal-stderr": cli.terminalStderr,
827
+ "wasi:cli/terminal-stdin": cli.terminalStdin,
828
+ "wasi:cli/terminal-stdout": cli.terminalStdout,
829
+ "wasi:clocks/monotonic-clock": clocks.monotonicClock,
830
+ "wasi:clocks/wall-clock": clocks.wallClock,
831
+ "wasi:filesystem/preopens": filesystem.preopens,
832
+ "wasi:filesystem/types": filesystem.types,
833
+ "wasi:io/error": io.error,
834
+ "wasi:io/poll": io.poll,
835
+ "wasi:io/streams": io.streams,
836
+ "wasi:random/random": random.random,
837
+ "wasi:sockets/tcp": sockets.tcp,
838
+ "wasi:http/types": http.types,
839
+ "wasi:http/incoming-handler": http.incomingHandler,
840
+ "wasi:http/outgoing-handler": http.outgoingHandler,
841
+ };
842
+ const component = await instantiate(getCoreModule, importObject, options.instantiateCore);
843
+ return component.rubyRuntime;
844
+ };
845
+ }
846
+ else {
847
+ initComponent = options.instantiate;
848
+ }
849
+ const vm = await this._instantiate({}, initComponent);
850
+ return { vm };
851
+ }
845
852
  constructor(binding) {
846
853
  this.instance = null;
847
854
  this.interfaceState = {
@@ -890,7 +897,7 @@
890
897
  this.transport = new JsValueTransport();
891
898
  this.exceptionFormatter = new RbExceptionFormatter();
892
899
  }
893
- static async _instantiate(initComponent, options) {
900
+ static async _instantiate(options, initComponent) {
894
901
  const binding = new ComponentBinding();
895
902
  const vm = new RubyVM(binding);
896
903
  class JsAbiValue {
@@ -918,14 +925,21 @@
918
925
  * Initialize the Ruby VM with the given command line arguments
919
926
  * @param args The command line arguments to pass to Ruby. Must be
920
927
  * an array of strings starting with the Ruby program name.
928
+ * @category Low-level initialization
921
929
  */
922
930
  initialize(args = ["ruby.wasm", "-EUTF-8", "-e_=0"]) {
923
931
  const c_args = args.map((arg) => arg + "\0");
924
- this.guest.rubyInit();
925
- this.guest.rubySysinit(c_args);
926
- this.guest.rubyOptions(c_args);
932
+ this.guest.rubyInit(c_args);
927
933
  try {
928
- this.eval(`require "/bundle/setup"`);
934
+ this.eval(`
935
+ # Require Bundler standalone setup
936
+ if File.exist?("/bundle/bundler/setup.rb")
937
+ require "/bundle/bundler/setup.rb"
938
+ elsif File.exist?("/bundle/setup.rb")
939
+ # For non-CM builds, which doesn't use Bundler's standalone mode
940
+ require "/bundle/setup.rb"
941
+ end
942
+ `);
929
943
  }
930
944
  catch (e) {
931
945
  console.warn("Failed to load /bundle/setup", e);
@@ -939,6 +953,7 @@
939
953
  * @param instance The WebAssembly instance to interact with. Must
940
954
  * be instantiated from a Ruby built with JS extension, and built
941
955
  * with Reactor ABI instead of command line.
956
+ * @category Low-level initialization
942
957
  */
943
958
  async setInstance(instance) {
944
959
  this.instance = instance;
@@ -948,6 +963,7 @@
948
963
  * Add intrinsic import entries, which is necessary to interact JavaScript
949
964
  * and Ruby's WebAssembly instance.
950
965
  * @param imports The import object to add to the WebAssembly instance
966
+ * @category Low-level initialization
951
967
  */
952
968
  addToImports(imports) {
953
969
  this.guest.addToImports(imports);
@@ -1153,6 +1169,7 @@
1153
1169
  * Runs a string of Ruby code from JavaScript
1154
1170
  * @param code The Ruby code to run
1155
1171
  * @returns the result of the last expression
1172
+ * @category Essentials
1156
1173
  *
1157
1174
  * @example
1158
1175
  * vm.eval("puts 'hello world'");
@@ -1168,6 +1185,7 @@
1168
1185
  * Returns a promise that resolves when execution completes.
1169
1186
  * @param code The Ruby code to run
1170
1187
  * @returns a promise that resolves to the result of the last expression
1188
+ * @category Essentials
1171
1189
  *
1172
1190
  * @example
1173
1191
  * const text = await vm.evalAsync(`
@@ -1250,6 +1268,7 @@
1250
1268
  }
1251
1269
  /**
1252
1270
  * A RbValue is an object that represents a value in Ruby
1271
+ * @category Essentials
1253
1272
  */
1254
1273
  class RbValue {
1255
1274
  /**
@@ -1551,18 +1570,16 @@
1551
1570
  new PreopenDirectory("/", new Map()),
1552
1571
  ];
1553
1572
  const wasi = new WASI(args, env, fds, { debug: false });
1554
- const vm = new RubyVM();
1555
- const imports = {
1556
- wasi_snapshot_preview1: wasi.wasiImport,
1557
- };
1558
- vm.addToImports(imports);
1559
1573
  const printer = ((_b = options.consolePrint) !== null && _b !== void 0 ? _b : true) ? consolePrinter() : undefined;
1560
- printer === null || printer === void 0 ? void 0 : printer.addToImports(imports);
1561
- const instance = await WebAssembly.instantiate(rubyModule, imports);
1562
- await vm.setInstance(instance);
1563
- printer === null || printer === void 0 ? void 0 : printer.setMemory(instance.exports.memory);
1564
- wasi.initialize(instance);
1565
- vm.initialize();
1574
+ const { vm, instance } = await RubyVM.instantiateModule({
1575
+ module: rubyModule, wasip1: wasi,
1576
+ addToImports: (imports) => {
1577
+ printer === null || printer === void 0 ? void 0 : printer.addToImports(imports);
1578
+ },
1579
+ setMemory: (memory) => {
1580
+ printer === null || printer === void 0 ? void 0 : printer.setMemory(memory);
1581
+ }
1582
+ });
1566
1583
  return {
1567
1584
  vm,
1568
1585
  wasi,