@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/README.md +1 -232
- package/dist/browser.script.umd.js +166 -130
- package/dist/browser.umd.js +146 -129
- package/dist/cjs/bindgen/interfaces/ruby-js-js-runtime.d.ts +1 -1
- package/dist/cjs/bindgen/interfaces/ruby-js-ruby-runtime.d.ts +2 -9
- package/dist/cjs/bindgen/legacy/intrinsics.js +5 -5
- package/dist/cjs/bindgen/legacy/rb-abi-guest.d.ts +1 -31
- package/dist/cjs/bindgen/legacy/rb-abi-guest.js +16 -84
- package/dist/cjs/bindgen/legacy/rb-js-abi-host.js +1 -2
- package/dist/cjs/binding.d.ts +2 -8
- package/dist/cjs/binding.js +2 -11
- package/dist/cjs/browser.js +9 -11
- package/dist/cjs/browser.script.d.ts +14 -0
- package/dist/cjs/browser.script.js +22 -2
- package/dist/cjs/console.js +1 -2
- package/dist/cjs/node.d.ts +0 -1
- package/dist/cjs/node.js +1 -9
- package/dist/cjs/vm.d.ts +157 -19
- package/dist/cjs/vm.js +120 -21
- package/dist/esm/bindgen/interfaces/ruby-js-js-runtime.d.ts +1 -1
- package/dist/esm/bindgen/interfaces/ruby-js-ruby-runtime.d.ts +2 -9
- package/dist/esm/bindgen/legacy/rb-abi-guest.d.ts +1 -31
- package/dist/esm/bindgen/legacy/rb-abi-guest.js +15 -82
- package/dist/esm/binding.d.ts +2 -8
- package/dist/esm/binding.js +2 -11
- package/dist/esm/browser.js +9 -11
- package/dist/esm/browser.script.d.ts +14 -0
- package/dist/esm/browser.script.js +19 -0
- package/dist/esm/node.d.ts +0 -1
- package/dist/esm/node.js +1 -9
- package/dist/esm/vm.d.ts +157 -19
- package/dist/esm/vm.js +120 -21
- package/dist/index.umd.js +137 -118
- package/package.json +8 -9
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
|
-
* @
|
|
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(
|
|
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(`
|
|
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
|
|
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
|
|
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-
|
|
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-
|
|
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.
|
|
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.
|
|
36
|
-
return 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-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
135
|
-
return [this.
|
|
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.
|
|
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.
|
|
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
|
|
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;
|
package/dist/esm/binding.d.ts
CHANGED
|
@@ -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];
|
package/dist/esm/binding.js
CHANGED
|
@@ -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();
|
package/dist/esm/browser.js
CHANGED
|
@@ -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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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.
|
package/dist/esm/node.d.ts
CHANGED
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 =
|
|
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,
|