@ruby/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/cjs/vm.js CHANGED
@@ -7,24 +7,111 @@ const rb_js_abi_host_js_1 = require("./bindgen/legacy/rb-js-abi-host.js");
7
7
  const binding_js_1 = require("./binding.js");
8
8
  /**
9
9
  * A Ruby VM instance
10
- *
11
- * @example
12
- *
13
- * const wasi = new WASI();
14
- * const vm = new RubyVM();
15
- * const imports = {
16
- * wasi_snapshot_preview1: wasi.wasiImport,
17
- * };
18
- *
19
- * vm.addToImports(imports);
20
- *
21
- * const instance = await WebAssembly.instantiate(rubyModule, imports);
22
- * await vm.setInstance(instance);
23
- * wasi.initialize(instance);
24
- * vm.initialize();
25
- *
10
+ * @see {@link RubyVM.instantiateComponent} and {@link RubyVM.instantiateModule} to create a new instance
11
+ * @category Essentials
26
12
  */
27
13
  class RubyVM {
14
+ /**
15
+ * Instantiate a Ruby VM with the given WebAssembly Core module with WASI Preview 1 implementation.
16
+ *
17
+ * @param options The options to instantiate the Ruby VM
18
+ * @returns A promise that resolves to the Ruby VM instance and the WebAssembly instance
19
+ * @category Essentials
20
+ *
21
+ * @example
22
+ *
23
+ * import { WASI } from "@bjorn3/browser_wasi_shim";
24
+ * const wasip1 = new WASI([], [], []);
25
+ * const module = await WebAssembly.compile("./path/to/ruby.wasm");
26
+ * const { vm } = await RubyVM.instantiateModule({ module, wasip1 });
27
+ *
28
+ */
29
+ static async instantiateModule(options) {
30
+ var _a, _b;
31
+ const { module, wasip1 } = options;
32
+ const vm = new RubyVM();
33
+ const imports = {
34
+ wasi_snapshot_preview1: wasip1.wasiImport,
35
+ };
36
+ vm.addToImports(imports);
37
+ (_a = options.addToImports) === null || _a === void 0 ? void 0 : _a.call(options, imports);
38
+ const instance = await WebAssembly.instantiate(module, imports);
39
+ await vm.setInstance(instance);
40
+ (_b = options.setMemory) === null || _b === void 0 ? void 0 : _b.call(options, instance.exports.memory);
41
+ wasip1.initialize(instance);
42
+ vm.initialize(options.args);
43
+ return { vm, instance };
44
+ }
45
+ /**
46
+ * Instantiate a Ruby VM with the given WebAssembly component with WASI Preview 2 implementation.
47
+ *
48
+ * @param options The options to instantiate the Ruby VM
49
+ * @returns A promise that resolves to the Ruby VM instance
50
+ * @category Essentials
51
+ *
52
+ * @example
53
+ *
54
+ * // First, you need to transpile the Ruby component to a JavaScript module using jco.
55
+ * // $ jco transpile --no-wasi-shim --instantiation --valid-lifting-optimization ./ruby.component.wasm -o ./component
56
+ * // Then, you can instantiate the Ruby VM with the component:
57
+ *
58
+ * import * as wasip2 from "@bytecodealliance/preview2-shim"
59
+ * import fs from "fs/promises";
60
+ * import path from "path";
61
+ *
62
+ * const { instantiate } = await import("./component/ruby.component.js");
63
+ * const getCoreModule = async (relativePath) => {
64
+ * const buffer = await fs.readFile(path.join("./component", relativePath));
65
+ * return WebAssembly.compile(buffer);
66
+ * }
67
+ *
68
+ * const { vm } = await RubyVM.instantiateComponent({
69
+ * instantiate, getCoreModule, wasip2,
70
+ * });
71
+ *
72
+ */
73
+ static async instantiateComponent(options) {
74
+ let initComponent;
75
+ if ("getCoreModule" in options) {
76
+ // A convenience overload to instantiate with "instantiate" function generated by jco
77
+ initComponent = async (jsRuntime) => {
78
+ const { instantiate, getCoreModule, wasip2 } = options;
79
+ const { cli, clocks, filesystem, io, random, sockets, http } = wasip2;
80
+ const importObject = {
81
+ "ruby:js/js-runtime": jsRuntime,
82
+ "wasi:cli/environment": cli.environment,
83
+ "wasi:cli/exit": cli.exit,
84
+ "wasi:cli/stderr": cli.stderr,
85
+ "wasi:cli/stdin": cli.stdin,
86
+ "wasi:cli/stdout": cli.stdout,
87
+ "wasi:cli/terminal-input": cli.terminalInput,
88
+ "wasi:cli/terminal-output": cli.terminalOutput,
89
+ "wasi:cli/terminal-stderr": cli.terminalStderr,
90
+ "wasi:cli/terminal-stdin": cli.terminalStdin,
91
+ "wasi:cli/terminal-stdout": cli.terminalStdout,
92
+ "wasi:clocks/monotonic-clock": clocks.monotonicClock,
93
+ "wasi:clocks/wall-clock": clocks.wallClock,
94
+ "wasi:filesystem/preopens": filesystem.preopens,
95
+ "wasi:filesystem/types": filesystem.types,
96
+ "wasi:io/error": io.error,
97
+ "wasi:io/poll": io.poll,
98
+ "wasi:io/streams": io.streams,
99
+ "wasi:random/random": random.random,
100
+ "wasi:sockets/tcp": sockets.tcp,
101
+ "wasi:http/types": http.types,
102
+ "wasi:http/incoming-handler": http.incomingHandler,
103
+ "wasi:http/outgoing-handler": http.outgoingHandler,
104
+ };
105
+ const component = await instantiate(getCoreModule, importObject, options.instantiateCore);
106
+ return component.rubyRuntime;
107
+ };
108
+ }
109
+ else {
110
+ initComponent = options.instantiate;
111
+ }
112
+ const vm = await this._instantiate({}, initComponent);
113
+ return { vm };
114
+ }
28
115
  constructor(binding) {
29
116
  this.instance = null;
30
117
  this.interfaceState = {
@@ -73,7 +160,7 @@ class RubyVM {
73
160
  this.transport = new JsValueTransport();
74
161
  this.exceptionFormatter = new RbExceptionFormatter();
75
162
  }
76
- static async _instantiate(initComponent, options) {
163
+ static async _instantiate(options, initComponent) {
77
164
  const binding = new binding_js_1.ComponentBinding();
78
165
  const vm = new RubyVM(binding);
79
166
  class JsAbiValue {
@@ -101,14 +188,21 @@ class RubyVM {
101
188
  * Initialize the Ruby VM with the given command line arguments
102
189
  * @param args The command line arguments to pass to Ruby. Must be
103
190
  * an array of strings starting with the Ruby program name.
191
+ * @category Low-level initialization
104
192
  */
105
193
  initialize(args = ["ruby.wasm", "-EUTF-8", "-e_=0"]) {
106
194
  const c_args = args.map((arg) => arg + "\0");
107
- this.guest.rubyInit();
108
- this.guest.rubySysinit(c_args);
109
- this.guest.rubyOptions(c_args);
195
+ this.guest.rubyInit(c_args);
110
196
  try {
111
- this.eval(`require "/bundle/setup"`);
197
+ this.eval(`
198
+ # Require Bundler standalone setup
199
+ if File.exist?("/bundle/bundler/setup.rb")
200
+ require "/bundle/bundler/setup.rb"
201
+ elsif File.exist?("/bundle/setup.rb")
202
+ # For non-CM builds, which doesn't use Bundler's standalone mode
203
+ require "/bundle/setup.rb"
204
+ end
205
+ `);
112
206
  }
113
207
  catch (e) {
114
208
  console.warn("Failed to load /bundle/setup", e);
@@ -122,6 +216,7 @@ class RubyVM {
122
216
  * @param instance The WebAssembly instance to interact with. Must
123
217
  * be instantiated from a Ruby built with JS extension, and built
124
218
  * with Reactor ABI instead of command line.
219
+ * @category Low-level initialization
125
220
  */
126
221
  async setInstance(instance) {
127
222
  this.instance = instance;
@@ -131,6 +226,7 @@ class RubyVM {
131
226
  * Add intrinsic import entries, which is necessary to interact JavaScript
132
227
  * and Ruby's WebAssembly instance.
133
228
  * @param imports The import object to add to the WebAssembly instance
229
+ * @category Low-level initialization
134
230
  */
135
231
  addToImports(imports) {
136
232
  this.guest.addToImports(imports);
@@ -336,6 +432,7 @@ class RubyVM {
336
432
  * Runs a string of Ruby code from JavaScript
337
433
  * @param code The Ruby code to run
338
434
  * @returns the result of the last expression
435
+ * @category Essentials
339
436
  *
340
437
  * @example
341
438
  * vm.eval("puts 'hello world'");
@@ -351,6 +448,7 @@ class RubyVM {
351
448
  * Returns a promise that resolves when execution completes.
352
449
  * @param code The Ruby code to run
353
450
  * @returns a promise that resolves to the result of the last expression
451
+ * @category Essentials
354
452
  *
355
453
  * @example
356
454
  * const text = await vm.evalAsync(`
@@ -434,6 +532,7 @@ class JsValueTransport {
434
532
  }
435
533
  /**
436
534
  * A RbValue is an object that represents a value in Ruby
535
+ * @category Essentials
437
536
  */
438
537
  class RbValue {
439
538
  /**
@@ -16,7 +16,7 @@ export namespace RubyJsJsRuntime {
16
16
  export function jsValueTypeof(value: JsAbiValue): string;
17
17
  export function jsValueEqual(lhs: JsAbiValue, rhs: JsAbiValue): boolean;
18
18
  export function jsValueStrictlyEqual(lhs: JsAbiValue, rhs: JsAbiValue): boolean;
19
- export function reflectApply(target: JsAbiValue, thisArgument: JsAbiValue, arguments: JsAbiValue[]): JsAbiResult;
19
+ export function reflectApply(target: JsAbiValue, thisArgument: JsAbiValue, arguments: Array<JsAbiValue>): JsAbiResult;
20
20
  export function reflectGet(target: JsAbiValue, propertyKey: string): JsAbiResult;
21
21
  export function reflectSet(target: JsAbiValue, propertyKey: string, value: JsAbiValue): JsAbiResult;
22
22
  export function throwProhibitRewindException(message: string): void;
@@ -1,12 +1,9 @@
1
1
  export namespace RubyJsRubyRuntime {
2
2
  export function rubyShowVersion(): void;
3
- export function rubyInit(): void;
4
- export function rubySysinit(args: string[]): void;
5
- export function rubyOptions(args: string[]): RbIseq;
6
- export function rubyScript(name: string): void;
3
+ export function rubyInit(args: Array<string>): void;
7
4
  export function rubyInitLoadpath(): void;
8
5
  export function rbEvalStringProtect(str: string): [RbAbiValue, number];
9
- export function rbFuncallvProtect(recv: RbAbiValue, mid: RbId, args: RbAbiValue[]): [RbAbiValue, number];
6
+ export function rbFuncallvProtect(recv: RbAbiValue, mid: RbId, args: Array<RbAbiValue>): [RbAbiValue, number];
10
7
  export function rbIntern(name: string): RbId;
11
8
  export function rbErrinfo(): RbAbiValue;
12
9
  export function rbClearErrinfo(): void;
@@ -27,7 +24,6 @@ export namespace RubyJsRubyRuntime {
27
24
  * 4. `export-rb-value-to-js()` returns the staged value
28
25
  */
29
26
  export function exportRbValueToJs(): RbAbiValue;
30
- export { RbIseq };
31
27
  export { RbAbiValue };
32
28
  }
33
29
  import type { JsAbiValue } from './ruby-js-js-runtime.js';
@@ -37,6 +33,3 @@ export type RbId = number;
37
33
 
38
34
  export class RbAbiValue {
39
35
  }
40
-
41
- export class RbIseq {
42
- }
@@ -68,10 +68,7 @@ export class RbAbiGuest {
68
68
  imports?: any,
69
69
  ): Promise<void>;
70
70
  rubyShowVersion(): void;
71
- rubyInit(): void;
72
- rubySysinit(args: string[]): void;
73
- rubyOptions(args: string[]): RbIseq;
74
- rubyScript(name: string): void;
71
+ rubyInit(args: string[]): void;
75
72
  rubyInitLoadpath(): void;
76
73
  rbEvalStringProtect(str: string): [RbAbiValue, number];
77
74
  rbFuncallvProtect(recv: RbAbiValue, mid: RbId, args: RbAbiValue[]): [RbAbiValue, number];
@@ -85,33 +82,6 @@ export class RbAbiGuest {
85
82
  rbSetShouldProhibitRewind(newValue: boolean): boolean;
86
83
  }
87
84
 
88
- export class RbIseq {
89
- // Creates a new strong reference count as a new
90
- // object. This is only required if you're also
91
- // calling `drop` below and want to manually manage
92
- // the reference count from JS.
93
- //
94
- // If you don't call `drop`, you don't need to call
95
- // this and can simply use the object from JS.
96
- clone(): RbIseq;
97
-
98
- // Explicitly indicate that this JS object will no
99
- // longer be used. If the internal reference count
100
- // reaches zero then this will deterministically
101
- // destroy the underlying wasm object.
102
- //
103
- // This is not required to be called from JS. Wasm
104
- // destructors will be automatically called for you
105
- // if this is not called using the JS
106
- // `FinalizationRegistry`.
107
- //
108
- // Calling this method does not guarantee that the
109
- // underlying wasm object is deallocated. Something
110
- // else (including wasm) may be holding onto a
111
- // strong reference count.
112
- drop(): void;
113
- }
114
-
115
85
  export class RbAbiValue {
116
86
  // Creates a new strong reference count as a new
117
87
  // object. This is only required if you're also
@@ -2,38 +2,23 @@ import { data_view, to_uint32, UTF8_DECODER, utf8_encode, UTF8_ENCODED_LEN, Slab
2
2
  export class RbAbiGuest {
3
3
  constructor() {
4
4
  this._resource0_slab = new Slab();
5
- this._resource1_slab = new Slab();
6
5
  }
7
6
  addToImports(imports) {
8
7
  if (!("canonical_abi" in imports))
9
8
  imports["canonical_abi"] = {};
10
- imports.canonical_abi['resource_drop_rb-iseq'] = i => {
9
+ imports.canonical_abi['resource_drop_rb-abi-value'] = i => {
11
10
  this._resource0_slab.remove(i).drop();
12
11
  };
13
- imports.canonical_abi['resource_clone_rb-iseq'] = i => {
12
+ imports.canonical_abi['resource_clone_rb-abi-value'] = i => {
14
13
  const obj = this._resource0_slab.get(i);
15
14
  return this._resource0_slab.insert(obj.clone());
16
15
  };
17
- imports.canonical_abi['resource_get_rb-iseq'] = i => {
18
- return this._resource0_slab.get(i)._wasm_val;
19
- };
20
- imports.canonical_abi['resource_new_rb-iseq'] = i => {
21
- const registry = this._registry0;
22
- return this._resource0_slab.insert(new RbIseq(i, this));
23
- };
24
- imports.canonical_abi['resource_drop_rb-abi-value'] = i => {
25
- this._resource1_slab.remove(i).drop();
26
- };
27
- imports.canonical_abi['resource_clone_rb-abi-value'] = i => {
28
- const obj = this._resource1_slab.get(i);
29
- return this._resource1_slab.insert(obj.clone());
30
- };
31
16
  imports.canonical_abi['resource_get_rb-abi-value'] = i => {
32
- return this._resource1_slab.get(i)._wasm_val;
17
+ return this._resource0_slab.get(i)._wasm_val;
33
18
  };
34
19
  imports.canonical_abi['resource_new_rb-abi-value'] = i => {
35
- const registry = this._registry1;
36
- return this._resource1_slab.insert(new RbAbiValue(i, this));
20
+ const registry = this._registry0;
21
+ return this._resource0_slab.insert(new RbAbiValue(i, this));
37
22
  };
38
23
  }
39
24
  async instantiate(module, imports) {
@@ -54,32 +39,12 @@ export class RbAbiGuest {
54
39
  this.instance = instance;
55
40
  }
56
41
  this._exports = this.instance.exports;
57
- this._registry0 = new FinalizationRegistry(this._exports['canonical_abi_drop_rb-iseq']);
58
- this._registry1 = new FinalizationRegistry(this._exports['canonical_abi_drop_rb-abi-value']);
42
+ this._registry0 = new FinalizationRegistry(this._exports['canonical_abi_drop_rb-abi-value']);
59
43
  }
60
44
  rubyShowVersion() {
61
45
  this._exports['ruby-show-version: func() -> ()']();
62
46
  }
63
- rubyInit() {
64
- this._exports['ruby-init: func() -> ()']();
65
- }
66
- rubySysinit(arg0) {
67
- const memory = this._exports.memory;
68
- const realloc = this._exports["cabi_realloc"];
69
- const vec1 = arg0;
70
- const len1 = vec1.length;
71
- const result1 = realloc(0, 0, 4, len1 * 8);
72
- for (let i = 0; i < vec1.length; i++) {
73
- const e = vec1[i];
74
- const base = result1 + i * 8;
75
- const ptr0 = utf8_encode(e, realloc, memory);
76
- const len0 = UTF8_ENCODED_LEN;
77
- data_view(memory).setInt32(base + 4, len0, true);
78
- data_view(memory).setInt32(base + 0, ptr0, true);
79
- }
80
- this._exports['ruby-sysinit: func(args: list<string>) -> ()'](result1, len1);
81
- }
82
- rubyOptions(arg0) {
47
+ rubyInit(arg0) {
83
48
  const memory = this._exports.memory;
84
49
  const realloc = this._exports["cabi_realloc"];
85
50
  const vec1 = arg0;
@@ -93,15 +58,7 @@ export class RbAbiGuest {
93
58
  data_view(memory).setInt32(base + 4, len0, true);
94
59
  data_view(memory).setInt32(base + 0, ptr0, true);
95
60
  }
96
- const ret = this._exports['ruby-options: func(args: list<string>) -> handle<rb-iseq>'](result1, len1);
97
- return this._resource0_slab.remove(ret);
98
- }
99
- rubyScript(arg0) {
100
- const memory = this._exports.memory;
101
- const realloc = this._exports["cabi_realloc"];
102
- const ptr0 = utf8_encode(arg0, realloc, memory);
103
- const len0 = UTF8_ENCODED_LEN;
104
- this._exports['ruby-script: func(name: string) -> ()'](ptr0, len0);
61
+ this._exports['ruby-init: func(args: list<string>) -> ()'](result1, len1);
105
62
  }
106
63
  rubyInitLoadpath() {
107
64
  this._exports['ruby-init-loadpath: func() -> ()']();
@@ -112,7 +69,7 @@ export class RbAbiGuest {
112
69
  const ptr0 = utf8_encode(arg0, realloc, memory);
113
70
  const len0 = UTF8_ENCODED_LEN;
114
71
  const ret = this._exports['rb-eval-string-protect: func(str: string) -> tuple<handle<rb-abi-value>, s32>'](ptr0, len0);
115
- return [this._resource1_slab.remove(data_view(memory).getInt32(ret + 0, true)), data_view(memory).getInt32(ret + 4, true)];
72
+ return [this._resource0_slab.remove(data_view(memory).getInt32(ret + 0, true)), data_view(memory).getInt32(ret + 4, true)];
116
73
  }
117
74
  rbFuncallvProtect(arg0, arg1, arg2) {
118
75
  const memory = this._exports.memory;
@@ -129,10 +86,10 @@ export class RbAbiGuest {
129
86
  const obj1 = e;
130
87
  if (!(obj1 instanceof RbAbiValue))
131
88
  throw new TypeError('expected instance of RbAbiValue');
132
- data_view(memory).setInt32(base + 0, this._resource1_slab.insert(obj1.clone()), true);
89
+ data_view(memory).setInt32(base + 0, this._resource0_slab.insert(obj1.clone()), true);
133
90
  }
134
- 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);
135
- return [this._resource1_slab.remove(data_view(memory).getInt32(ret + 0, true)), data_view(memory).getInt32(ret + 4, true)];
91
+ 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);
92
+ return [this._resource0_slab.remove(data_view(memory).getInt32(ret + 0, true)), data_view(memory).getInt32(ret + 4, true)];
136
93
  }
137
94
  rbIntern(arg0) {
138
95
  const memory = this._exports.memory;
@@ -144,7 +101,7 @@ export class RbAbiGuest {
144
101
  }
145
102
  rbErrinfo() {
146
103
  const ret = this._exports['rb-errinfo: func() -> handle<rb-abi-value>']();
147
- return this._resource1_slab.remove(ret);
104
+ return this._resource0_slab.remove(ret);
148
105
  }
149
106
  rbClearErrinfo() {
150
107
  this._exports['rb-clear-errinfo: func() -> ()']();
@@ -154,7 +111,7 @@ export class RbAbiGuest {
154
111
  const obj0 = arg0;
155
112
  if (!(obj0 instanceof RbAbiValue))
156
113
  throw new TypeError('expected instance of RbAbiValue');
157
- const ret = this._exports['rstring-ptr: func(value: handle<rb-abi-value>) -> string'](this._resource1_slab.insert(obj0.clone()));
114
+ const ret = this._exports['rstring-ptr: func(value: handle<rb-abi-value>) -> string'](this._resource0_slab.insert(obj0.clone()));
158
115
  const ptr1 = data_view(memory).getInt32(ret + 0, true);
159
116
  const len1 = data_view(memory).getInt32(ret + 4, true);
160
117
  const result1 = UTF8_DECODER.decode(new Uint8Array(memory.buffer, ptr1, len1));
@@ -180,7 +137,7 @@ export class RbAbiGuest {
180
137
  return bool0 == 0 ? false : (bool0 == 1 ? true : throw_invalid_bool());
181
138
  }
182
139
  }
183
- export class RbIseq {
140
+ export class RbAbiValue {
184
141
  constructor(wasm_val, obj) {
185
142
  this._wasm_val = wasm_val;
186
143
  this._obj = obj;
@@ -196,30 +153,6 @@ export class RbIseq {
196
153
  if (this._refcnt !== 0)
197
154
  return;
198
155
  this._obj._registry0.unregister(this);
199
- const dtor = this._obj._exports['canonical_abi_drop_rb-iseq'];
200
- const wasm_val = this._wasm_val;
201
- delete this._obj;
202
- delete this._refcnt;
203
- delete this._wasm_val;
204
- dtor(wasm_val);
205
- }
206
- }
207
- export class RbAbiValue {
208
- constructor(wasm_val, obj) {
209
- this._wasm_val = wasm_val;
210
- this._obj = obj;
211
- this._refcnt = 1;
212
- obj._registry1.register(this, wasm_val, this);
213
- }
214
- clone() {
215
- this._refcnt += 1;
216
- return this;
217
- }
218
- drop() {
219
- this._refcnt -= 1;
220
- if (this._refcnt !== 0)
221
- return;
222
- this._obj._registry1.unregister(this);
223
156
  const dtor = this._obj._exports['canonical_abi_drop_rb-abi-value'];
224
157
  const wasm_val = this._wasm_val;
225
158
  delete this._obj;
@@ -6,10 +6,7 @@ import * as RbAbi from "./bindgen/legacy/rb-abi-guest.js";
6
6
  */
7
7
  export interface Binding {
8
8
  rubyShowVersion(): void;
9
- rubyInit(): void;
10
- rubySysinit(args: string[]): void;
11
- rubyOptions(args: string[]): void;
12
- rubyScript(name: string): void;
9
+ rubyInit(args: string[]): void;
13
10
  rubyInitLoadpath(): void;
14
11
  rbEvalStringProtect(str: string): [RbAbiValue, number];
15
12
  rbFuncallvProtect(recv: RbAbiValue, mid: RbAbi.RbId, args: RbAbiValue[]): [RbAbiValue, number];
@@ -34,10 +31,7 @@ export declare class ComponentBinding implements Binding {
34
31
  constructor();
35
32
  setUnderlying(underlying: typeof RubyJsRubyRuntime): void;
36
33
  rubyShowVersion(): void;
37
- rubyInit(): void;
38
- rubySysinit(args: string[]): void;
39
- rubyOptions(args: string[]): void;
40
- rubyScript(name: string): void;
34
+ rubyInit(args: string[]): void;
41
35
  rubyInitLoadpath(): void;
42
36
  rbEvalStringProtect(str: string): [RbAbiValue, number];
43
37
  rbFuncallvProtect(recv: RbAbiValue, mid: number, args: RbAbiValue[]): [RbAbiValue, number];
@@ -12,17 +12,8 @@ export class ComponentBinding {
12
12
  rubyShowVersion() {
13
13
  this.underlying.rubyShowVersion();
14
14
  }
15
- rubyInit() {
16
- this.underlying.rubyInit();
17
- }
18
- rubySysinit(args) {
19
- this.underlying.rubySysinit(args);
20
- }
21
- rubyOptions(args) {
22
- this.underlying.rubyOptions(args);
23
- }
24
- rubyScript(name) {
25
- this.underlying.rubyScript(name);
15
+ rubyInit(args) {
16
+ this.underlying.rubyInit(args);
26
17
  }
27
18
  rubyInitLoadpath() {
28
19
  this.underlying.rubyInitLoadpath();
@@ -12,18 +12,16 @@ export const DefaultRubyVM = async (rubyModule, options = {}) => {
12
12
  new PreopenDirectory("/", new Map()),
13
13
  ];
14
14
  const wasi = new WASI(args, env, fds, { debug: false });
15
- const vm = new RubyVM();
16
- const imports = {
17
- wasi_snapshot_preview1: wasi.wasiImport,
18
- };
19
- vm.addToImports(imports);
20
15
  const printer = ((_b = options.consolePrint) !== null && _b !== void 0 ? _b : true) ? consolePrinter() : undefined;
21
- printer === null || printer === void 0 ? void 0 : printer.addToImports(imports);
22
- const instance = await WebAssembly.instantiate(rubyModule, imports);
23
- await vm.setInstance(instance);
24
- printer === null || printer === void 0 ? void 0 : printer.setMemory(instance.exports.memory);
25
- wasi.initialize(instance);
26
- vm.initialize();
16
+ const { vm, instance } = await RubyVM.instantiateModule({
17
+ module: rubyModule, wasip1: wasi,
18
+ addToImports: (imports) => {
19
+ printer === null || printer === void 0 ? void 0 : printer.addToImports(imports);
20
+ },
21
+ setMemory: (memory) => {
22
+ printer === null || printer === void 0 ? void 0 : printer.setMemory(memory);
23
+ }
24
+ });
27
25
  return {
28
26
  vm,
29
27
  wasi,
@@ -1,5 +1,19 @@
1
1
  import { DefaultRubyVM } from "./browser.js";
2
+ import { RubyComponentInstantiator } from "./vm.js";
3
+ /**
4
+ * The main entry point of `<script type="text/ruby">`-based scripting with WebAssembly Core Module.
5
+ */
2
6
  export declare const main: (pkg: {
3
7
  name: string;
4
8
  version: string;
5
9
  }, options?: Parameters<typeof DefaultRubyVM>[1]) => Promise<void>;
10
+ /**
11
+ * The main entry point of `<script type="text/ruby">`-based scripting with WebAssembly Component.
12
+ */
13
+ export declare const componentMain: (pkg: {
14
+ name: string;
15
+ version: string;
16
+ }, options: {
17
+ instantiate: RubyComponentInstantiator;
18
+ wasip2: any;
19
+ }) => Promise<void>;
@@ -1,9 +1,28 @@
1
1
  import { __asyncValues } from "tslib";
2
2
  import { DefaultRubyVM } from "./browser.js";
3
+ import { RubyVM } from "./vm.js";
4
+ /**
5
+ * The main entry point of `<script type="text/ruby">`-based scripting with WebAssembly Core Module.
6
+ */
3
7
  export const main = async (pkg, options) => {
4
8
  const response = fetch(`https://cdn.jsdelivr.net/npm/${pkg.name}@${pkg.version}/dist/ruby+stdlib.wasm`);
5
9
  const module = await compileWebAssemblyModule(response);
6
10
  const { vm } = await DefaultRubyVM(module, options);
11
+ await mainWithRubyVM(vm);
12
+ };
13
+ /**
14
+ * The main entry point of `<script type="text/ruby">`-based scripting with WebAssembly Component.
15
+ */
16
+ export const componentMain = async (pkg, options) => {
17
+ const componentUrl = `https://cdn.jsdelivr.net/npm/${pkg.name}@${pkg.version}/dist/component`;
18
+ const fetchComponentFile = (relativePath) => fetch(`${componentUrl}/${relativePath}`);
19
+ const { vm } = await RubyVM.instantiateComponent(Object.assign(Object.assign({}, options), { getCoreModule: (relativePath) => {
20
+ const response = fetchComponentFile(relativePath);
21
+ return compileWebAssemblyModule(response);
22
+ } }));
23
+ await mainWithRubyVM(vm);
24
+ };
25
+ const mainWithRubyVM = async (vm) => {
7
26
  vm.printVersion();
8
27
  globalThis.rubyVM = vm;
9
28
  // Wait for the text/ruby script tag to be read.
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import { WASI } from "wasi";
3
2
  import { RubyVM } from "./vm.js";
4
3
  export declare const DefaultRubyVM: (rubyModule: WebAssembly.Module, options?: {
package/dist/esm/node.js CHANGED
@@ -2,15 +2,7 @@ import { WASI } from "wasi";
2
2
  import { RubyVM } from "./vm.js";
3
3
  export const DefaultRubyVM = async (rubyModule, options = {}) => {
4
4
  const wasi = new WASI({ env: options.env, version: "preview1", returnOnExit: true });
5
- const vm = new RubyVM();
6
- const imports = {
7
- wasi_snapshot_preview1: wasi.wasiImport,
8
- };
9
- vm.addToImports(imports);
10
- const instance = await WebAssembly.instantiate(rubyModule, imports);
11
- await vm.setInstance(instance);
12
- wasi.initialize(instance);
13
- vm.initialize();
5
+ const { vm, instance } = await RubyVM.instantiateModule({ module: rubyModule, wasip1: wasi });
14
6
  return {
15
7
  vm,
16
8
  wasi,