Skip to content

Commit 1ae40fc

Browse files
ledsunkateinoigakukun
authored andcommitted
Expose WASI preopens through DefaultRubyVM
1 parent 544db2d commit 1ae40fc

4 files changed

Lines changed: 75 additions & 2 deletions

File tree

‎packages/npm-packages/ruby-wasm-wasi/example/README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ $ # Open http://localhost:8000/script-src
1717
```console
1818
$ npm install
1919
$ node index.node.js
20+
$ node preopens.node.js
2021
```
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import fs from "fs/promises";
2+
import { DefaultRubyVM } from "@ruby/wasm-wasi/dist/node";
3+
4+
// $ node preopens.node.js
5+
6+
const binary = await fs.readFile(
7+
"./node_modules/@ruby/head-wasm-wasi/dist/ruby.wasm",
8+
);
9+
const module = await WebAssembly.compile(binary);
10+
const { vm } = await DefaultRubyVM(module, {
11+
preopens: {
12+
"/app": "./require_relative",
13+
},
14+
});
15+
16+
// /app/main.rb uses require_relative to load /app/greeting.rb.
17+
vm.eval('require "/app/main"');

‎packages/npm-packages/ruby-wasm-wasi/src/node.ts‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,17 @@ import { RubyVM } from "./vm.js";
33

44
export const DefaultRubyVM = async (
55
rubyModule: WebAssembly.Module,
6-
options: { env?: Record<string, string> | undefined } = {},
6+
options: {
7+
env?: Record<string, string> | undefined;
8+
preopens?: Record<string, string>;
9+
} = {},
710
) => {
8-
const wasi = new WASI({ env: options.env, version: "preview1", returnOnExit: true });
11+
const wasi = new WASI({
12+
env: options.env,
13+
preopens: options.preopens,
14+
version: "preview1",
15+
returnOnExit: true,
16+
});
917
const { vm, instance } = await RubyVM.instantiateModule({ module: rubyModule, wasip1: wasi });
1018

1119
return {

‎packages/npm-packages/ruby-wasm-wasi/test/package.test.js‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as path from "path";
22
import * as fs from "fs/promises";
3+
import * as os from "os";
34
import { WASI } from "wasi";
45
import { RubyVM } from "../src/index";
56
import { DefaultRubyVM } from "../src/node";
@@ -59,6 +60,52 @@ describe("Packaging validation", () => {
5960
vm.eval(`require "stringio"`);
6061
});
6162

63+
test("DefaultRubyVM WASI preopens with require_relative", async () => {
64+
const mod = await loadWasmModule(`ruby+stdlib.wasm`);
65+
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "ruby-wasm-preopen-"));
66+
const nestedDir = path.join(tempDir, "nested");
67+
const entryFile = path.join(tempDir, "entry.rb");
68+
const helperFile = path.join(nestedDir, "helper.rb");
69+
70+
try {
71+
await fs.mkdir(nestedDir);
72+
await fs.writeFile(entryFile, [
73+
"PREOPEN_ENTRY_FILE = __FILE__",
74+
"require_relative './nested/helper'",
75+
].join("\n"));
76+
await fs.writeFile(helperFile, "PREOPEN_HELPER_FILE = __FILE__\n");
77+
78+
const { vm } = await DefaultRubyVM(mod, {
79+
preopens: { "/app": tempDir },
80+
});
81+
expect(vm.eval(`require "/app/entry"`).toString()).toBe("true");
82+
expect(vm.eval(`require "/app/entry"`).toString()).toBe("false");
83+
84+
expect(vm.eval("PREOPEN_ENTRY_FILE").toString()).toBe("/app/entry.rb");
85+
expect(vm.eval("PREOPEN_HELPER_FILE").toString()).toBe(
86+
"/app/nested/helper.rb",
87+
);
88+
expect(
89+
vm.eval('$LOADED_FEATURES.include?("/app/entry.rb")').toString(),
90+
).toBe("true");
91+
expect(
92+
vm
93+
.eval('$LOADED_FEATURES.include?("/app/nested/helper.rb")')
94+
.toString(),
95+
).toBe("true");
96+
expect(
97+
vm
98+
.eval(`$LOADED_FEATURES.include?(${JSON.stringify(entryFile)})`)
99+
.toString(),
100+
).toBe("false");
101+
expect(vm.eval(`File.file?(${JSON.stringify(entryFile)})`).toString()).toBe(
102+
"false",
103+
);
104+
} finally {
105+
await fs.rm(tempDir, { recursive: true, force: true });
106+
}
107+
});
108+
62109
test.each([
63110
{ file: "ruby+stdlib.wasm", stdlib: true },
64111
{ file: "ruby.debug+stdlib.wasm", stdlib: true },

0 commit comments

Comments
 (0)