1
1
#! /bin/sh
2
2
" :" //# ; exec /usr/bin/env node --experimental-wasi-unstable-preview1 "$0" "$@"
3
3
4
+ import * as wasmerWasi from " @wasmer/wasi" ;
4
5
import fs from " fs/promises" ;
5
6
import path from " path" ;
6
- import { WASI } from " wasi" ;
7
+ import * as nodeWasi from " wasi" ;
7
8
import { RubyVM } from " ../dist/index.cjs.js" ;
8
9
9
- const instantiate = async (rootTestFile) => {
10
+ const instantiateNodeWasi = async (rootTestFile) => {
10
11
const dirname = path.dirname(new URL(import.meta.url).pathname);
11
12
let binaryPath;
12
13
let preopens = {
@@ -20,15 +21,15 @@ const instantiate = async (rootTestFile) => {
20
21
}
21
22
const binary = await fs.readFile(binaryPath);
22
23
const rubyModule = await WebAssembly.compile(binary);
23
- const wasi = new WASI({
24
+ const wasi = new nodeWasi. WASI({
24
25
stdio: " inherit" ,
25
26
args: [" ruby.wasm" ].concat(process.argv.slice(2)),
26
27
env: {
27
28
...process.env,
28
29
// Extend fiber stack size to be able to run test-unit
29
30
" RUBY_FIBER_MACHINE_STACK_SIZE" : String(1024 * 1024 * 20),
30
31
},
31
- preopens: preopens ,
32
+ preopens,
32
33
});
33
34
34
35
const vm = new RubyVM ();
@@ -44,12 +45,82 @@ const instantiate = async (rootTestFile) => {
44
45
wasi.initialize(instance);
45
46
46
47
vm.initialize([" ruby.wasm" , rootTestFile]);
47
- return { instance, vm };
48
+ return { instance, vm, wasi };
48
49
};
49
50
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) => {
51
122
const rootTestFile = " /__root__/test/test_unit.rb" ;
52
- const { vm } = await instantiate(rootTestFile);
123
+ const { vm, wasi } = await instantiate(rootTestFile);
53
124
54
125
Error.stackTraceLimit = Infinity;
55
126
@@ -71,6 +142,20 @@ const main = async () => {
71
142
require_relative ' ${rootTestFile}'
72
143
Test::Unit::AutoRunner.run
73
144
` );
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);
74
159
};
75
160
76
161
main ();
0 commit comments