Skip to content

Commit 984aa36

Browse files
Insert an abstraction layer for the Ruby VM binding
1 parent f4ca5a2 commit 984aa36

File tree

2 files changed

+105
-5
lines changed

2 files changed

+105
-5
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { RubyJsRubyRuntime } from "./bindgen/interfaces/ruby-js-ruby-runtime.js";
2+
import * as RbAbi from "./bindgen/legacy/rb-abi-guest.js";
3+
4+
/**
5+
* This interface bridges between the Ruby runtime and the JavaScript runtime
6+
* and defines how to interact with underlying import/export functions.
7+
*/
8+
export interface Binding {
9+
rubyShowVersion(): void;
10+
rubyInit(): void;
11+
rubySysinit(args: string[]): void;
12+
rubyOptions(args: string[]): void;
13+
rubyScript(name: string): void;
14+
rubyInitLoadpath(): void;
15+
rbEvalStringProtect(str: string): [RbAbi.RbAbiValue, number];
16+
rbFuncallvProtect(recv: RbAbi.RbAbiValue, mid: RbAbi.RbId, args: RbAbi.RbAbiValue[]): [RbAbi.RbAbiValue, number];
17+
rbIntern(name: string): RbAbi.RbId;
18+
rbErrinfo(): RbAbi.RbAbiValue;
19+
rbClearErrinfo(): void;
20+
rstringPtr(value: RbAbi.RbAbiValue): string;
21+
rbVmBugreport(): void;
22+
rbGcEnable(): boolean;
23+
rbGcDisable(): boolean;
24+
rbSetShouldProhibitRewind(newValue: boolean): boolean;
25+
26+
setInstance(instance: WebAssembly.Instance): Promise<void>;
27+
addToImports(imports: WebAssembly.Imports): void;
28+
}
29+
30+
export class LegacyBinding extends RbAbi.RbAbiGuest implements Binding {
31+
async setInstance(instance: WebAssembly.Instance): Promise<void> {
32+
await this.instantiate(instance);
33+
}
34+
}
35+
36+
export class ComponentBinding implements Binding {
37+
underlying: typeof RubyJsRubyRuntime;
38+
39+
constructor(underlying: typeof RubyJsRubyRuntime) {
40+
this.underlying = underlying;
41+
}
42+
43+
rubyShowVersion(): void {
44+
this.underlying.rubyShowVersion();
45+
}
46+
rubyInit(): void {
47+
this.underlying.rubyInit();
48+
}
49+
rubySysinit(args: string[]): void {
50+
this.underlying.rubySysinit(args);
51+
}
52+
rubyOptions(args: string[]) {
53+
this.underlying.rubyOptions(args);
54+
}
55+
rubyScript(name: string): void {
56+
throw new Error("Method not implemented.");
57+
}
58+
rubyInitLoadpath(): void {
59+
throw new Error("Method not implemented.");
60+
}
61+
rbEvalStringProtect(str: string): [RbAbi.RbAbiValue, number] {
62+
throw new Error("Method not implemented.");
63+
}
64+
rbFuncallvProtect(recv: RbAbi.RbAbiValue, mid: number, args: RbAbi.RbAbiValue[]): [RbAbi.RbAbiValue, number] {
65+
throw new Error("Method not implemented.");
66+
}
67+
rbIntern(name: string): number {
68+
throw new Error("Method not implemented.");
69+
}
70+
rbErrinfo(): RbAbi.RbAbiValue {
71+
throw new Error("Method not implemented.");
72+
}
73+
rbClearErrinfo(): void {
74+
throw new Error("Method not implemented.");
75+
}
76+
rstringPtr(value: RbAbi.RbAbiValue): string {
77+
throw new Error("Method not implemented.");
78+
}
79+
rbVmBugreport(): void {
80+
throw new Error("Method not implemented.");
81+
}
82+
rbGcEnable(): boolean {
83+
throw new Error("Method not implemented.");
84+
}
85+
rbGcDisable(): boolean {
86+
throw new Error("Method not implemented.");
87+
}
88+
rbSetShouldProhibitRewind(newValue: boolean): boolean {
89+
throw new Error("Method not implemented.");
90+
}
91+
92+
async setInstance(instance: WebAssembly.Instance): Promise<void> {
93+
// No-op
94+
}
95+
addToImports(imports: WebAssembly.Imports): void {
96+
// No-op
97+
}
98+
}

packages/npm-packages/ruby-wasm-wasi/src/vm.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
JsAbiResult,
66
JsAbiValue,
77
} from "./bindgen/legacy/rb-js-abi-host.js";
8+
import { Binding, LegacyBinding } from "./binding.js";
89

910
/**
1011
* A Ruby VM instance
@@ -26,7 +27,7 @@ import {
2627
*
2728
*/
2829
export class RubyVM {
29-
guest: RbAbi.RbAbiGuest;
30+
guest: Binding;
3031
private instance: WebAssembly.Instance | null = null;
3132
private transport: JsValueTransport;
3233
private exceptionFormatter: RbExceptionFormatter;
@@ -37,8 +38,9 @@ export class RubyVM {
3738
constructor() {
3839
// Wrap exported functions from Ruby VM to prohibit nested VM operation
3940
// if the call stack has sandwitched JS frames like JS -> Ruby -> JS -> Ruby.
40-
const proxyExports = (exports: RbAbi.RbAbiGuest) => {
41-
const excludedMethods: (keyof RbAbi.RbAbiGuest)[] = [
41+
const proxyExports = (exports: Binding) => {
42+
const excludedMethods: (keyof LegacyBinding | keyof Binding)[] = [
43+
"setInstance",
4244
"addToImports",
4345
"instantiate",
4446
"rbSetShouldProhibitRewind",
@@ -75,7 +77,7 @@ export class RubyVM {
7577
}
7678
return exports;
7779
};
78-
this.guest = proxyExports(new RbAbi.RbAbiGuest());
80+
this.guest = proxyExports(new LegacyBinding());
7981
this.transport = new JsValueTransport();
8082
this.exceptionFormatter = new RbExceptionFormatter();
8183
}
@@ -104,7 +106,7 @@ export class RubyVM {
104106
*/
105107
async setInstance(instance: WebAssembly.Instance) {
106108
this.instance = instance;
107-
await this.guest.instantiate(instance);
109+
await this.guest.setInstance(instance);
108110
}
109111

110112
/**

0 commit comments

Comments
 (0)