11#! /bin/sh
22" :" //# ; exec /usr/bin/env node --experimental-wasi-unstable-preview1 "$0" "$@"
33
4+ import * as wasmerWasi from " @wasmer/wasi" ;
45import fs from " fs/promises" ;
56import path from " path" ;
6- import { WASI } from " wasi" ;
7+ import * as nodeWasi from " wasi" ;
78import { RubyVM } from " ../dist/index.cjs.js" ;
89
9- const instantiate = async (rootTestFile) => {
10+ const instantiateNodeWasi = async (rootTestFile) => {
1011 const dirname = path.dirname(new URL(import.meta.url).pathname);
1112 let binaryPath;
1213 let preopens = {
@@ -20,15 +21,15 @@ const instantiate = async (rootTestFile) => {
2021 }
2122 const binary = await fs.readFile(binaryPath);
2223 const rubyModule = await WebAssembly.compile(binary);
23- const wasi = new WASI({
24+ const wasi = new nodeWasi. WASI({
2425 stdio: " inherit" ,
2526 args: [" ruby.wasm" ].concat(process.argv.slice(2)),
2627 env: {
2728 ...process.env,
2829 // Extend fiber stack size to be able to run test-unit
2930 " RUBY_FIBER_MACHINE_STACK_SIZE" : String(1024 * 1024 * 20),
3031 },
31- preopens: preopens ,
32+ preopens,
3233 });
3334
3435 const vm = new RubyVM ();
@@ -44,12 +45,82 @@ const instantiate = async (rootTestFile) => {
4445 wasi.initialize(instance);
4546
4647 vm.initialize([" ruby.wasm" , rootTestFile]);
47- return { instance, vm };
48+ return { instance, vm, wasi };
4849};
4950
50- const main = async () => {
51+ const instantiateWasmerWasi = async (rootTestFile) => {
52+ await wasmerWasi.init ();
53+
54+ const memFs = new wasmerWasi.MemFS ();
55+ const walk = async (dir) => {
56+ const names = await fs.readdir(dir);
57+ const files = await Promise.all(names.map(async name => {
58+ if (( await fs.stat(path.join(dir, name)) ).isDirectory()) {
59+ return walk(path.join(dir, name));
60+ } else {
61+ return [path.join(dir, name)];
62+ }
63+ }));
64+ return files.flat ();
65+ };
66+ const mkdirpMemFs = (guestPath) => {
67+ const parts = guestPath.split(' /' );
68+ for (let i = 2; i < = parts.length; i++) {
69+ memFs.createDir(parts.slice(0, i).join(' /' ));
70+ }
71+ };
72+ const loadToMemFs = async (guestPath, hostPath) => {
73+ const hostFiles = await walk(hostPath);
74+ await Promise.all(hostFiles.map(async hostFile => {
75+ const guestFile = path.join(guestPath, path.relative(hostPath, hostFile));
76+ mkdirpMemFs(path.dirname(guestFile));
77+ const contents = await fs.readFile(hostFile);
78+ memFs.open(guestFile, { write: true, create: true }).write(contents);
79+ }));
80+ };
81+
82+ const dirname = path.dirname(new URL(import.meta.url).pathname);
83+ await loadToMemFs(' /__root__/test' , path.join(dirname, ' ../test' ));
84+ const preopens = {
85+ __root__: ' /__root__' ,
86+ };
87+
88+ const binaryPath = path.join(dirname, " ../dist/ruby+stdlib.wasm" );
89+ if (process.env.RUBY_ROOT) {
90+ console.error(' For now, testing with RUBY_ROOT is not supported.' );
91+ }
92+
93+ const binary = await fs.readFile(binaryPath);
94+ const rubyModule = await WebAssembly.compile(binary);
95+
96+ const wasi = new wasmerWasi.WASI({
97+ args: [" ruby.wasm" ].concat(process.argv.slice(2)),
98+ env: {
99+ ...process.env,
100+ // Extend fiber stack size to be able to run test-unit
101+ " RUBY_FIBER_MACHINE_STACK_SIZE" : String(1024 * 1024 * 20),
102+ },
103+ preopens,
104+ fs: memFs,
105+ });
106+
107+ const vm = new RubyVM ();
108+ const imports = wasi.getImports(rubyModule);
109+ vm.addToImports(imports);
110+
111+ const instance = await WebAssembly.instantiate(rubyModule, imports);
112+ wasi.instantiate(instance);
113+ await vm.setInstance(instance);
114+
115+ instance.exports._initialize ();
116+ vm.initialize([" ruby.wasm" , rootTestFile]);
117+
118+ return { instance, vm, wasi };
119+ };
120+
121+ const test = async (instantiate) => {
51122 const rootTestFile = " /__root__/test/test_unit.rb" ;
52- const { vm } = await instantiate(rootTestFile);
123+ const { vm, wasi } = await instantiate(rootTestFile);
53124
54125 Error.stackTraceLimit = Infinity;
55126
@@ -71,6 +142,20 @@ const main = async () => {
71142 require_relative ' ${rootTestFile}'
72143 Test::Unit::AutoRunner.run
73144 ` );
145+
146+ // TODO(makenowjust): override ` wasi_snapshot_preview1.fd_write` for output to stdout/stderr.
147+ // See ` src/browser.ts` .
148+ if (wasi.getStderrString) {
149+ console.error(wasi.getStderrString ());
150+ }
151+ if (wasi.getStdoutString) {
152+ console.log(wasi.getStdoutString ());
153+ }
154+ };
155+
156+ const main = async () => {
157+ await test(instantiateNodeWasi);
158+ await test(instantiateWasmerWasi);
74159};
75160
76161main ();
0 commit comments