@joinezco/codeblock 0.0.9 → 0.0.11
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/dist/editor.d.ts +23 -2
- package/dist/editor.js +346 -41
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/lsps/index.d.ts +5 -0
- package/dist/lsps/index.js +9 -2
- package/dist/panels/{footer.d.ts → settings.d.ts} +7 -1
- package/dist/panels/{footer.js → settings.js} +12 -3
- package/dist/panels/terminal.d.ts +3 -0
- package/dist/panels/terminal.js +76 -0
- package/dist/panels/toolbar.d.ts +40 -3
- package/dist/panels/toolbar.js +919 -160
- package/dist/themes/index.js +63 -17
- package/dist/types.d.ts +5 -0
- package/dist/utils/fs.d.ts +7 -0
- package/dist/utils/fs.js +41 -15
- package/dist/workers/fs.worker.d.ts +4 -8
- package/dist/workers/fs.worker.js +27 -53
- package/package.json +14 -12
- package/dist/assets/clike-C8IJ2oj_.js +0 -1
- package/dist/assets/cmake-BQqOBYOt.js +0 -1
- package/dist/assets/dockerfile-C_y-rIpk.js +0 -1
- package/dist/assets/fs.worker-DfanUHpQ.js +0 -21
- package/dist/assets/go-CTD25R5P.js +0 -1
- package/dist/assets/haskell-BWDZoCOh.js +0 -1
- package/dist/assets/index-BAnLzvMk.js +0 -1
- package/dist/assets/index-BBC9WDX6.js +0 -1
- package/dist/assets/index-BEXYxRro.js +0 -1
- package/dist/assets/index-BfYmUKH9.js +0 -13
- package/dist/assets/index-BhaTNAWE.js +0 -1
- package/dist/assets/index-CCbYDSng.js +0 -1
- package/dist/assets/index-CIi8tLT6.js +0 -1
- package/dist/assets/index-CaANcgI2.js +0 -3
- package/dist/assets/index-CkWzFNzm.js +0 -208
- package/dist/assets/index-D_XGv9QZ.js +0 -1
- package/dist/assets/index-DkmiPfkD.js +0 -1
- package/dist/assets/index-DmNlLMQ4.js +0 -6
- package/dist/assets/index-DmX_vI7D.js +0 -1
- package/dist/assets/index-DogEEevD.js +0 -1
- package/dist/assets/index-DsDl5qZV.js +0 -2
- package/dist/assets/index-gAy5mDg-.js +0 -1
- package/dist/assets/index-i5qJLB2h.js +0 -1
- package/dist/assets/javascript.worker-ClsyHOLi.js +0 -552
- package/dist/assets/lua-BgMRiT3U.js +0 -1
- package/dist/assets/perl-CdXCOZ3F.js +0 -1
- package/dist/assets/process-Dw9K5EnD.js +0 -1357
- package/dist/assets/properties-C78fOPTZ.js +0 -1
- package/dist/assets/ruby-B2Rjki9n.js +0 -1
- package/dist/assets/shell-CjFT_Tl9.js +0 -1
- package/dist/assets/swift-BzpIVaGY.js +0 -1
- package/dist/assets/toml-BXUEaScT.js +0 -1
- package/dist/assets/vb-CmGdzxic.js +0 -1
- package/dist/e2e/editor.spec.d.ts +0 -1
- package/dist/e2e/editor.spec.js +0 -309
- package/dist/e2e/example.spec.d.ts +0 -5
- package/dist/e2e/example.spec.js +0 -44
- package/dist/index.html +0 -15
- package/dist/resources/config.json +0 -13
- package/dist/styles.css +0 -7
|
@@ -1,1357 +0,0 @@
|
|
|
1
|
-
/* eslint-disable camelcase */
|
|
2
|
-
import * as constants from "./constants.js";
|
|
3
|
-
import * as utils from "./utils.js";
|
|
4
|
-
import { POLL_EVENT_BUFSIZE, } from "./types.js";
|
|
5
|
-
const CPUTIME_START = utils.msToNs(performance.now());
|
|
6
|
-
let started;
|
|
7
|
-
let mod;
|
|
8
|
-
let myself;
|
|
9
|
-
let programArgs;
|
|
10
|
-
let env;
|
|
11
|
-
onmessage = async (e) => {
|
|
12
|
-
if (!started) {
|
|
13
|
-
if (e.data[0] === "start") {
|
|
14
|
-
started = true;
|
|
15
|
-
[, mod, myself, programArgs, env] = e.data;
|
|
16
|
-
try {
|
|
17
|
-
await start_wasm();
|
|
18
|
-
}
|
|
19
|
-
catch (err) {
|
|
20
|
-
sendToKernel(["console", `Worker failed: ${err}`]);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
// TODO: add class for msg sent to kernel
|
|
26
|
-
function sendToKernel(msg) {
|
|
27
|
-
// @ts-ignore
|
|
28
|
-
postMessage([myself, ...msg]);
|
|
29
|
-
}
|
|
30
|
-
function workerConsoleLog(msg) {
|
|
31
|
-
// you can control debug logs dynamically based on DEBUG env variable
|
|
32
|
-
if (env["DEBUG"] &&
|
|
33
|
-
!(env["DEBUG"] === "0" || env["DEBUG"] === "false" || env["DEBUG"] === "")) {
|
|
34
|
-
sendToKernel(["console", msg]);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
function doExit(exitCode) {
|
|
38
|
-
workerConsoleLog("calling close()");
|
|
39
|
-
sendToKernel(["proc_exit", exitCode]);
|
|
40
|
-
// eslint-disable-next-line no-restricted-globals
|
|
41
|
-
self.close();
|
|
42
|
-
}
|
|
43
|
-
const whenceMap = {
|
|
44
|
-
0: constants.WASI_WHENCE_CUR,
|
|
45
|
-
1: constants.WASI_WHENCE_END,
|
|
46
|
-
2: constants.WASI_WHENCE_SET,
|
|
47
|
-
};
|
|
48
|
-
function WASI(snapshot0 = false) {
|
|
49
|
-
let moduleInstanceExports;
|
|
50
|
-
function setModuleInstance(instance) {
|
|
51
|
-
moduleInstanceExports = instance.exports;
|
|
52
|
-
}
|
|
53
|
-
function environ_sizes_get(environCountPtr, environSizePtr) {
|
|
54
|
-
workerConsoleLog(`environ_sizes_get(0x${environCountPtr.toString(16)}, 0x${environSizePtr.toString(16)})`);
|
|
55
|
-
const view = new DataView(moduleInstanceExports["memory"].buffer);
|
|
56
|
-
const environCount = Object.keys(env).length;
|
|
57
|
-
view.setUint32(environCountPtr, environCount, true);
|
|
58
|
-
const environSize = Object.entries(env).reduce((sum, [key, val]) => sum + new TextEncoder().encode(`${key}=${val}\0`).byteLength, 0);
|
|
59
|
-
view.setUint32(environSizePtr, environSize, true);
|
|
60
|
-
return constants.WASI_ESUCCESS;
|
|
61
|
-
}
|
|
62
|
-
function environ_get(environ, environBuf) {
|
|
63
|
-
workerConsoleLog(`environ_get(${environ.toString(16)}, ${environBuf.toString(16)})`);
|
|
64
|
-
const view = new DataView(moduleInstanceExports["memory"].buffer);
|
|
65
|
-
const view8 = new Uint8Array(moduleInstanceExports["memory"].buffer);
|
|
66
|
-
Object.entries(env).forEach(([key, val], i) => {
|
|
67
|
-
// set pointer address to beginning of next key value pair
|
|
68
|
-
view.setUint32(environ + i * 4, environBuf, true);
|
|
69
|
-
// write string describing the variable to WASM memory
|
|
70
|
-
const variable = new TextEncoder().encode(`${key}=${val}\0`);
|
|
71
|
-
view8.set(variable, environBuf);
|
|
72
|
-
// calculate pointer to next variable
|
|
73
|
-
environBuf += variable.byteLength;
|
|
74
|
-
});
|
|
75
|
-
return constants.WASI_ESUCCESS;
|
|
76
|
-
}
|
|
77
|
-
function args_sizes_get(argc, argvBufSize) {
|
|
78
|
-
workerConsoleLog(`args_sizes_get(${argc.toString(16)}, ${argvBufSize.toString(16)})`);
|
|
79
|
-
const view = new DataView(moduleInstanceExports["memory"].buffer);
|
|
80
|
-
view.setUint32(argc, programArgs.length, true);
|
|
81
|
-
view.setUint32(argvBufSize, new TextEncoder().encode(programArgs.join("")).byteLength +
|
|
82
|
-
programArgs.length, true);
|
|
83
|
-
return constants.WASI_ESUCCESS;
|
|
84
|
-
}
|
|
85
|
-
function args_get(argv, argvBuf) {
|
|
86
|
-
workerConsoleLog(`args_get(${argv}, 0x${argvBuf.toString(16)})`);
|
|
87
|
-
const view = new DataView(moduleInstanceExports["memory"].buffer);
|
|
88
|
-
const view8 = new Uint8Array(moduleInstanceExports["memory"].buffer);
|
|
89
|
-
programArgs.forEach((arg, i) => {
|
|
90
|
-
// set pointer address to beginning of next key value pair
|
|
91
|
-
view.setUint32(argv + i * 4, argvBuf, true);
|
|
92
|
-
// write string describing the argument to WASM memory
|
|
93
|
-
const variable = new TextEncoder().encode(`${arg}\0`);
|
|
94
|
-
view8.set(variable, argvBuf);
|
|
95
|
-
// calculate pointer to next variable
|
|
96
|
-
argvBuf += variable.byteLength;
|
|
97
|
-
});
|
|
98
|
-
return constants.WASI_ESUCCESS;
|
|
99
|
-
}
|
|
100
|
-
function fd_fdstat_get(fd, buf) {
|
|
101
|
-
workerConsoleLog(`fd_fdstat_get(${fd}, 0x${buf.toString(16)})`);
|
|
102
|
-
const view = new DataView(moduleInstanceExports["memory"].buffer);
|
|
103
|
-
// lock, filetype, rights base, rights inheriting, fd flags
|
|
104
|
-
const sharedBuffer = new SharedArrayBuffer(4 + 24);
|
|
105
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
106
|
-
lck[0] = -1;
|
|
107
|
-
const fileType = new Uint8Array(sharedBuffer, 4, 1);
|
|
108
|
-
const rights_base = new BigUint64Array(sharedBuffer, 8, 1);
|
|
109
|
-
const rights_inheriting = new BigUint64Array(sharedBuffer, 16, 1);
|
|
110
|
-
const fd_flags = new Uint8Array(sharedBuffer, 24, 1);
|
|
111
|
-
sendToKernel(["fd_fdstat_get", { sharedBuffer, fd }]);
|
|
112
|
-
Atomics.wait(lck, 0, -1);
|
|
113
|
-
const err = Atomics.load(lck, 0);
|
|
114
|
-
if (err !== constants.WASI_ESUCCESS) {
|
|
115
|
-
workerConsoleLog(`fd_fdstat_get returned ${err}`);
|
|
116
|
-
return err;
|
|
117
|
-
}
|
|
118
|
-
view.setUint8(buf, fileType[0]);
|
|
119
|
-
view.setUint32(buf + 2, fd_flags[0], true);
|
|
120
|
-
view.setBigUint64(buf + 8, rights_base[0], true);
|
|
121
|
-
view.setBigUint64(buf + 16, rights_inheriting[0], true);
|
|
122
|
-
workerConsoleLog(`fd_fdstat_get returned ${err} {file_type: ${fileType[0]} file_flags: 0 rights_base: ${rights_base[0]} rights_inheriting: ${rights_inheriting}}`);
|
|
123
|
-
return constants.WASI_ESUCCESS;
|
|
124
|
-
}
|
|
125
|
-
function fd_write(fd, iovs, iovsLen, nWritten) {
|
|
126
|
-
workerConsoleLog(`fd_write(${fd}, ${iovs}, ${iovsLen}, ${nWritten})`);
|
|
127
|
-
const view = new DataView(moduleInstanceExports["memory"].buffer);
|
|
128
|
-
let writeLen = 0;
|
|
129
|
-
const bufferBytes = [];
|
|
130
|
-
for (let i = 0; i < iovsLen; i += 1) {
|
|
131
|
-
const ptr_pos = iovs + i * 8;
|
|
132
|
-
const buf = view.getUint32(ptr_pos, true);
|
|
133
|
-
const bufLen = view.getUint32(ptr_pos + 4, true);
|
|
134
|
-
const iov = new Uint8Array(moduleInstanceExports["memory"].buffer, buf, bufLen);
|
|
135
|
-
for (let b = 0; b < iov.byteLength; b += 1) {
|
|
136
|
-
bufferBytes.push(iov[b]);
|
|
137
|
-
}
|
|
138
|
-
writeLen += iov.byteLength;
|
|
139
|
-
}
|
|
140
|
-
const sharedBuffer = new SharedArrayBuffer(4 + 4 + writeLen); // lock + written + content
|
|
141
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
142
|
-
const written = new Int32Array(sharedBuffer, 4, 1);
|
|
143
|
-
lck[0] = -1;
|
|
144
|
-
let content = Uint8Array.from(bufferBytes);
|
|
145
|
-
sendToKernel(["fd_write", { sharedBuffer, fd, content }]);
|
|
146
|
-
Atomics.wait(lck, 0, -1);
|
|
147
|
-
const err = Atomics.load(lck, 0);
|
|
148
|
-
if (err === 0) {
|
|
149
|
-
workerConsoleLog(`fd_write written ${written} bytes.`);
|
|
150
|
-
view.setUint32(nWritten, written[0], true);
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
workerConsoleLog(`fd_write returned ${err}.`);
|
|
154
|
-
}
|
|
155
|
-
return err;
|
|
156
|
-
}
|
|
157
|
-
function proc_exit(exitCode) {
|
|
158
|
-
workerConsoleLog(`proc_exit(${exitCode})`);
|
|
159
|
-
doExit(exitCode);
|
|
160
|
-
}
|
|
161
|
-
function random_get(bufPtr, bufLen) {
|
|
162
|
-
workerConsoleLog(`random_get(${bufPtr}, ${bufLen})`);
|
|
163
|
-
const view8 = new Uint8Array(moduleInstanceExports["memory"].buffer);
|
|
164
|
-
const numbers = new Uint8Array(bufLen);
|
|
165
|
-
crypto.getRandomValues(numbers);
|
|
166
|
-
view8.set(numbers, bufPtr);
|
|
167
|
-
return constants.WASI_ESUCCESS;
|
|
168
|
-
}
|
|
169
|
-
function clock_res_get(_clock_id) {
|
|
170
|
-
return placeholder();
|
|
171
|
-
}
|
|
172
|
-
function clock_time_get(clockId, precision, time) {
|
|
173
|
-
workerConsoleLog(`clock_time_get(${clockId}, ${precision}, ${time})`);
|
|
174
|
-
const view = new DataView(moduleInstanceExports["memory"].buffer);
|
|
175
|
-
view.setBigUint64(time, utils.now(clockId, CPUTIME_START), true);
|
|
176
|
-
return constants.WASI_ESUCCESS;
|
|
177
|
-
}
|
|
178
|
-
function fd_close(fd) {
|
|
179
|
-
workerConsoleLog(`fd_close(${fd})`);
|
|
180
|
-
const sharedBuffer = new SharedArrayBuffer(4);
|
|
181
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
182
|
-
lck[0] = -1;
|
|
183
|
-
sendToKernel(["fd_close", { sharedBuffer, fd }]);
|
|
184
|
-
Atomics.wait(lck, 0, -1);
|
|
185
|
-
return Atomics.load(lck, 0);
|
|
186
|
-
}
|
|
187
|
-
function fd_filestat_get(fd, buf) {
|
|
188
|
-
workerConsoleLog(`fd_filestat_get(${fd}, 0x${buf.toString(16)})`);
|
|
189
|
-
const view = new DataView(moduleInstanceExports["memory"].buffer);
|
|
190
|
-
const sharedBuffer = new SharedArrayBuffer(4 + 64); // lock, stat buffer
|
|
191
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
192
|
-
lck[0] = -1;
|
|
193
|
-
const statBuf = new DataView(sharedBuffer, 4);
|
|
194
|
-
sendToKernel(["fd_filestat_get", { sharedBuffer, fd }]);
|
|
195
|
-
Atomics.wait(lck, 0, -1);
|
|
196
|
-
const err = Atomics.load(lck, 0);
|
|
197
|
-
if (err !== constants.WASI_ESUCCESS) {
|
|
198
|
-
workerConsoleLog(`fd_filestat_get returned ${err}`);
|
|
199
|
-
return err;
|
|
200
|
-
}
|
|
201
|
-
const dev = statBuf.getBigUint64(0, true);
|
|
202
|
-
const ino = statBuf.getBigUint64(8, true);
|
|
203
|
-
const fileType = statBuf.getUint8(16);
|
|
204
|
-
const nlink = statBuf.getBigUint64(24, true);
|
|
205
|
-
const size = statBuf.getBigUint64(32, true);
|
|
206
|
-
const atim = statBuf.getBigUint64(40, true);
|
|
207
|
-
const mtim = statBuf.getBigUint64(48, true);
|
|
208
|
-
const ctim = statBuf.getBigUint64(56, true);
|
|
209
|
-
if (snapshot0) {
|
|
210
|
-
// in snapshot0, filetype padding is 3 bytes and nlink is u32 instead of u64
|
|
211
|
-
view.setBigUint64(buf, dev, true);
|
|
212
|
-
view.setBigUint64(buf + 8, ino, true);
|
|
213
|
-
view.setUint8(buf + 16, fileType);
|
|
214
|
-
view.setUint32(buf + 20, Number(nlink), true);
|
|
215
|
-
view.setBigUint64(buf + 24, size, true);
|
|
216
|
-
view.setBigUint64(buf + 32, atim, true);
|
|
217
|
-
view.setBigUint64(buf + 40, mtim, true);
|
|
218
|
-
view.setBigUint64(buf + 48, ctim, true);
|
|
219
|
-
}
|
|
220
|
-
else {
|
|
221
|
-
view.setBigUint64(buf, dev, true);
|
|
222
|
-
view.setBigUint64(buf + 8, ino, true);
|
|
223
|
-
view.setUint8(buf + 16, fileType);
|
|
224
|
-
view.setBigUint64(buf + 24, nlink, true);
|
|
225
|
-
view.setBigUint64(buf + 32, size, true);
|
|
226
|
-
view.setBigUint64(buf + 40, atim, true);
|
|
227
|
-
view.setBigUint64(buf + 48, mtim, true);
|
|
228
|
-
view.setBigUint64(buf + 56, ctim, true);
|
|
229
|
-
}
|
|
230
|
-
workerConsoleLog(`fd_filestat_get returned ${err} {dev: ${dev} ino: ${ino} fileType: ${fileType} nlink: ${nlink} size: ${size} atim: ${atim} mtim: ${mtim} ctim: ${ctim}}`);
|
|
231
|
-
return constants.WASI_ESUCCESS;
|
|
232
|
-
}
|
|
233
|
-
function fd_read(fd, iovs, iovsLen, nRead) {
|
|
234
|
-
workerConsoleLog(`fd_read(${fd}, ${iovs}, ${iovsLen}, ${nRead})`);
|
|
235
|
-
const view = new DataView(moduleInstanceExports["memory"].buffer);
|
|
236
|
-
const view8 = new Uint8Array(moduleInstanceExports["memory"].buffer);
|
|
237
|
-
let read = 0;
|
|
238
|
-
for (let i = 0; i < iovsLen; i += 1) {
|
|
239
|
-
const addr = view.getUint32(iovs + 8 * i, true);
|
|
240
|
-
const len = view.getUint32(iovs + 8 * i + 4, true);
|
|
241
|
-
// TODO: ripe for optimization, addr and len could be put inside a vector and requested all at once
|
|
242
|
-
const sharedBuffer = new SharedArrayBuffer(4 + 4 + len); // lock, read length, read buffer
|
|
243
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
244
|
-
lck[0] = -1;
|
|
245
|
-
const readLen = new Int32Array(sharedBuffer, 4, 1);
|
|
246
|
-
const readBuf = new Uint8Array(sharedBuffer, 8, len);
|
|
247
|
-
sendToKernel([
|
|
248
|
-
"fd_read",
|
|
249
|
-
{ sharedBuffer, fd, len, offset: undefined },
|
|
250
|
-
]);
|
|
251
|
-
Atomics.wait(lck, 0, -1);
|
|
252
|
-
const err = Atomics.load(lck, 0);
|
|
253
|
-
if (err !== constants.WASI_ESUCCESS) {
|
|
254
|
-
return err;
|
|
255
|
-
}
|
|
256
|
-
view8.set(readBuf, addr);
|
|
257
|
-
read += readLen[0];
|
|
258
|
-
}
|
|
259
|
-
if (fd > 2)
|
|
260
|
-
workerConsoleLog(`fd_read read ${read} bytes.`);
|
|
261
|
-
view.setUint32(nRead, read, true);
|
|
262
|
-
return constants.WASI_ESUCCESS;
|
|
263
|
-
}
|
|
264
|
-
function fd_pread(fd, iovs, iovsLen, offset, nRead) {
|
|
265
|
-
if (fd > 2)
|
|
266
|
-
workerConsoleLog(`fd_pread(${fd}, ${iovs}, ${iovsLen}, ${nRead})`);
|
|
267
|
-
const view = new DataView(moduleInstanceExports["memory"].buffer);
|
|
268
|
-
const view8 = new Uint8Array(moduleInstanceExports["memory"].buffer);
|
|
269
|
-
let read = 0;
|
|
270
|
-
for (let i = 0; i < iovsLen; i += 1) {
|
|
271
|
-
const addr = view.getUint32(iovs + 8 * i, true);
|
|
272
|
-
const len = view.getUint32(iovs + 8 * i + 4, true);
|
|
273
|
-
const sharedBuffer = new SharedArrayBuffer(4 + 4 + len); // lock, read length, read buffer
|
|
274
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
275
|
-
lck[0] = -1;
|
|
276
|
-
const readLen = new Int32Array(sharedBuffer, 4, 1);
|
|
277
|
-
const readBuf = new Uint8Array(sharedBuffer, 8, len);
|
|
278
|
-
sendToKernel([
|
|
279
|
-
"fd_pread",
|
|
280
|
-
{ sharedBuffer, fd, len, offset },
|
|
281
|
-
]);
|
|
282
|
-
Atomics.wait(lck, 0, -1);
|
|
283
|
-
const err = Atomics.load(lck, 0);
|
|
284
|
-
if (err !== constants.WASI_ESUCCESS) {
|
|
285
|
-
return err;
|
|
286
|
-
}
|
|
287
|
-
view8.set(readBuf, addr);
|
|
288
|
-
read += readLen[0];
|
|
289
|
-
}
|
|
290
|
-
if (fd > 2)
|
|
291
|
-
workerConsoleLog(`fd_pread read ${read} bytes.`);
|
|
292
|
-
view.setUint32(nRead, read, true);
|
|
293
|
-
return constants.WASI_ESUCCESS;
|
|
294
|
-
}
|
|
295
|
-
function fd_readdir(fd, buf, bufLen, cookie, bufUsedPtr) {
|
|
296
|
-
workerConsoleLog(`fd_readdir(${fd}, ${buf}, ${bufLen}, ${cookie}, ${bufUsedPtr})`);
|
|
297
|
-
const view = new DataView(moduleInstanceExports["memory"].buffer);
|
|
298
|
-
const view8 = new Uint8Array(moduleInstanceExports["memory"].buffer);
|
|
299
|
-
const sharedBuffer = new SharedArrayBuffer(4 + 4 + bufLen); // lock, buf_used, buf
|
|
300
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
301
|
-
lck[0] = -1;
|
|
302
|
-
const bufUsed = new Uint32Array(sharedBuffer, 4, 1);
|
|
303
|
-
const dataBuffer = new Uint8Array(sharedBuffer, 8);
|
|
304
|
-
sendToKernel([
|
|
305
|
-
"fd_readdir",
|
|
306
|
-
{ sharedBuffer, fd, cookie, bufLen },
|
|
307
|
-
]);
|
|
308
|
-
Atomics.wait(lck, 0, -1);
|
|
309
|
-
const err = Atomics.load(lck, 0);
|
|
310
|
-
if (err !== constants.WASI_ESUCCESS) {
|
|
311
|
-
return err;
|
|
312
|
-
}
|
|
313
|
-
view8.set(dataBuffer, buf);
|
|
314
|
-
view.setUint32(bufUsedPtr, bufUsed[0], true);
|
|
315
|
-
return constants.WASI_ESUCCESS;
|
|
316
|
-
}
|
|
317
|
-
function fd_seek(fd, offset, whence, newOffset) {
|
|
318
|
-
workerConsoleLog(`fd_seek(${fd}, ${offset}, ${whence}, ${newOffset})`);
|
|
319
|
-
const view = new DataView(moduleInstanceExports["memory"].buffer);
|
|
320
|
-
const sharedBuffer = new SharedArrayBuffer(4 + 4 + 8); // lock, _padding, file_pos
|
|
321
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
322
|
-
lck[0] = -1;
|
|
323
|
-
const file_pos = new BigUint64Array(sharedBuffer, 8, 1);
|
|
324
|
-
const whence_ = snapshot0 ? whenceMap[whence] : whence;
|
|
325
|
-
sendToKernel([
|
|
326
|
-
"fd_seek",
|
|
327
|
-
{ sharedBuffer, fd, offset, whence: whence_ },
|
|
328
|
-
]);
|
|
329
|
-
Atomics.wait(lck, 0, -1);
|
|
330
|
-
const err = Atomics.load(lck, 0);
|
|
331
|
-
workerConsoleLog(`fd_seek returned ${err}, file_pos = ${file_pos[0]}`);
|
|
332
|
-
if (err !== constants.WASI_ESUCCESS) {
|
|
333
|
-
return err;
|
|
334
|
-
}
|
|
335
|
-
view.setBigUint64(newOffset, file_pos[0], true);
|
|
336
|
-
return constants.WASI_ESUCCESS;
|
|
337
|
-
}
|
|
338
|
-
function path_create_directory(fd, pathPtr, pathLen) {
|
|
339
|
-
const view8 = new Uint8Array(moduleInstanceExports["memory"].buffer);
|
|
340
|
-
const path = new TextDecoder().decode(view8.slice(pathPtr, pathPtr + pathLen));
|
|
341
|
-
workerConsoleLog(`path_create_directory(${fd}, ${path}, ${pathLen}) [path=${path}]`);
|
|
342
|
-
const sharedBuffer = new SharedArrayBuffer(4); // lock
|
|
343
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
344
|
-
lck[0] = -1;
|
|
345
|
-
sendToKernel([
|
|
346
|
-
"path_create_directory",
|
|
347
|
-
{ sharedBuffer, fd, path },
|
|
348
|
-
]);
|
|
349
|
-
Atomics.wait(lck, 0, -1);
|
|
350
|
-
return Atomics.load(lck, 0);
|
|
351
|
-
}
|
|
352
|
-
function path_filestat_get(fd, lookupFlags, pathPtr, pathLen, buf) {
|
|
353
|
-
const view = new DataView(moduleInstanceExports["memory"].buffer);
|
|
354
|
-
const view8 = new Uint8Array(moduleInstanceExports["memory"].buffer);
|
|
355
|
-
const path = new TextDecoder().decode(view8.slice(pathPtr, pathPtr + pathLen));
|
|
356
|
-
workerConsoleLog(`path_filestat_get(${fd}, ${lookupFlags}, ${path}, ${pathLen}, 0x${buf.toString(16)}) [path=${path}]`);
|
|
357
|
-
const sharedBuffer = new SharedArrayBuffer(4 + 64); // lock, stat buffer
|
|
358
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
359
|
-
lck[0] = -1;
|
|
360
|
-
const statBuf = new DataView(sharedBuffer, 4);
|
|
361
|
-
sendToKernel([
|
|
362
|
-
"path_filestat_get",
|
|
363
|
-
{ sharedBuffer, fd, path, lookupFlags },
|
|
364
|
-
]);
|
|
365
|
-
Atomics.wait(lck, 0, -1);
|
|
366
|
-
const err = Atomics.load(lck, 0);
|
|
367
|
-
workerConsoleLog(`path_filestat_get returned ${err}`);
|
|
368
|
-
if (err !== constants.WASI_ESUCCESS) {
|
|
369
|
-
return err;
|
|
370
|
-
}
|
|
371
|
-
const dev = statBuf.getBigUint64(0, true);
|
|
372
|
-
const ino = statBuf.getBigUint64(8, true);
|
|
373
|
-
const fileType = statBuf.getUint8(16);
|
|
374
|
-
const nlink = statBuf.getBigUint64(24, true);
|
|
375
|
-
const size = statBuf.getBigUint64(32, true);
|
|
376
|
-
const atim = statBuf.getBigUint64(40, true);
|
|
377
|
-
const mtim = statBuf.getBigUint64(48, true);
|
|
378
|
-
const ctim = statBuf.getBigUint64(56, true);
|
|
379
|
-
if (snapshot0) {
|
|
380
|
-
view.setBigUint64(buf, dev, true);
|
|
381
|
-
view.setBigUint64(buf + 8, ino, true);
|
|
382
|
-
view.setUint8(buf + 16, fileType);
|
|
383
|
-
view.setUint32(buf + 20, Number(nlink), true);
|
|
384
|
-
view.setBigUint64(buf + 24, size, true);
|
|
385
|
-
view.setBigUint64(buf + 32, atim, true);
|
|
386
|
-
view.setBigUint64(buf + 40, mtim, true);
|
|
387
|
-
view.setBigUint64(buf + 48, ctim, true);
|
|
388
|
-
}
|
|
389
|
-
else {
|
|
390
|
-
view.setBigUint64(buf, dev, true);
|
|
391
|
-
view.setBigUint64(buf + 8, ino, true);
|
|
392
|
-
view.setUint8(buf + 16, fileType);
|
|
393
|
-
view.setBigUint64(buf + 24, nlink, true);
|
|
394
|
-
view.setBigUint64(buf + 32, size, true);
|
|
395
|
-
view.setBigUint64(buf + 40, atim, true);
|
|
396
|
-
view.setBigUint64(buf + 48, mtim, true);
|
|
397
|
-
view.setBigUint64(buf + 56, ctim, true);
|
|
398
|
-
}
|
|
399
|
-
return constants.WASI_ESUCCESS;
|
|
400
|
-
}
|
|
401
|
-
function path_open(dirFd, lookupFlags, pathPtr, pathLen, openFlags, fsRightsBase, fsRightsInheriting, fdFlags, openedFdPtr) {
|
|
402
|
-
const view = new DataView(moduleInstanceExports["memory"].buffer);
|
|
403
|
-
const view8 = new Uint8Array(moduleInstanceExports["memory"].buffer);
|
|
404
|
-
const path = new TextDecoder().decode(view8.slice(pathPtr, pathPtr + pathLen));
|
|
405
|
-
workerConsoleLog(`path_open(dirFd=${dirFd}, lookupFlags=${lookupFlags}, pathPtr=0x${pathPtr.toString(16)}, pathLen=${pathLen}, openFlags=${openFlags}, fsRightsBase=${fsRightsBase}, fsRightsInheriting=${fsRightsInheriting}, fdFlags=${fdFlags}, openedFdPtr=0x${openedFdPtr.toString(16)}) [path=${path}]`);
|
|
406
|
-
const sharedBuffer = new SharedArrayBuffer(4 + 4); // lock, opened fd
|
|
407
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
408
|
-
lck[0] = -1;
|
|
409
|
-
const opened_fd = new Int32Array(sharedBuffer, 4, 1);
|
|
410
|
-
sendToKernel([
|
|
411
|
-
"path_open",
|
|
412
|
-
{
|
|
413
|
-
sharedBuffer,
|
|
414
|
-
dirFd,
|
|
415
|
-
path,
|
|
416
|
-
lookupFlags,
|
|
417
|
-
openFlags,
|
|
418
|
-
fsRightsBase,
|
|
419
|
-
fsRightsInheriting,
|
|
420
|
-
fdFlags,
|
|
421
|
-
},
|
|
422
|
-
]);
|
|
423
|
-
Atomics.wait(lck, 0, -1);
|
|
424
|
-
const err = Atomics.load(lck, 0);
|
|
425
|
-
if (err !== constants.WASI_ESUCCESS) {
|
|
426
|
-
return err;
|
|
427
|
-
}
|
|
428
|
-
view.setUint32(openedFdPtr, opened_fd[0], true);
|
|
429
|
-
return constants.WASI_ESUCCESS;
|
|
430
|
-
}
|
|
431
|
-
// used solely in path_readlink
|
|
432
|
-
function specialParse(syscallDataJson, outputBuffer) {
|
|
433
|
-
const { command, buf_len, buf_ptr, } = JSON.parse(syscallDataJson);
|
|
434
|
-
const json = new TextDecoder().decode(new Uint8Array(moduleInstanceExports["memory"].buffer, buf_ptr, buf_len));
|
|
435
|
-
switch (command) {
|
|
436
|
-
case "spawn": {
|
|
437
|
-
// wasi_ext_lib::spawn needs: int process_exit_status, int child_pid
|
|
438
|
-
if (outputBuffer.byteLength < 8) {
|
|
439
|
-
return {
|
|
440
|
-
exitStatus: constants.WASI_ENOBUFS,
|
|
441
|
-
outputSize: 0,
|
|
442
|
-
};
|
|
443
|
-
}
|
|
444
|
-
// lock + child PID
|
|
445
|
-
const sharedBuffer = new SharedArrayBuffer(4 + 4);
|
|
446
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
447
|
-
lck[0] = -1;
|
|
448
|
-
const { path, args, extended_env, redirects_ptr, n_redirects, background, } = JSON.parse(json);
|
|
449
|
-
workerConsoleLog(`${path} ${args} ${extended_env} ${background} ${redirects_ptr}, ${n_redirects}`);
|
|
450
|
-
const view = new DataView(moduleInstanceExports["memory"].buffer);
|
|
451
|
-
let redirects = [];
|
|
452
|
-
let redirectsPtr = redirects_ptr;
|
|
453
|
-
for (let i = 0; i < n_redirects; i++) {
|
|
454
|
-
const data_ptr = redirectsPtr;
|
|
455
|
-
const fd_dst = view.getUint32(redirectsPtr + 8, true);
|
|
456
|
-
const type = view.getUint32(redirectsPtr + 8 + 4, true);
|
|
457
|
-
// 8 data bytes, 4 fd_dst bytes, 4 type bytes, 0 bytes of padding
|
|
458
|
-
redirectsPtr += 8 + 4 + 4;
|
|
459
|
-
let redirect = {
|
|
460
|
-
type,
|
|
461
|
-
fd_dst,
|
|
462
|
-
path: undefined,
|
|
463
|
-
fd_src: undefined,
|
|
464
|
-
};
|
|
465
|
-
switch (type) {
|
|
466
|
-
case constants.WASI_EXT_REDIRECT_TYPE_READ:
|
|
467
|
-
case constants.WASI_EXT_REDIRECT_TYPE_WRITE:
|
|
468
|
-
case constants.WASI_EXT_REDIRECT_TYPE_APPEND:
|
|
469
|
-
case constants.WASI_EXT_REDIRECT_TYPE_READWRITE: {
|
|
470
|
-
let path_ptr = view.getUint32(data_ptr, true);
|
|
471
|
-
let path_len = view.getUint32(data_ptr + 4, true);
|
|
472
|
-
let path = new TextDecoder().decode(view.buffer.slice(path_ptr, path_ptr + path_len));
|
|
473
|
-
redirect.path = path;
|
|
474
|
-
break;
|
|
475
|
-
}
|
|
476
|
-
case constants.WASI_EXT_REDIRECT_TYPE_PIPEIN:
|
|
477
|
-
case constants.WASI_EXT_REDIRECT_TYPE_PIPEOUT:
|
|
478
|
-
case constants.WASI_EXT_REDIRECT_TYPE_DUPLICATE: {
|
|
479
|
-
let fd_src = view.getUint32(data_ptr, true);
|
|
480
|
-
redirect.fd_src = fd_src;
|
|
481
|
-
break;
|
|
482
|
-
}
|
|
483
|
-
case constants.WASI_EXT_REDIRECT_TYPE_CLOSE: {
|
|
484
|
-
// just skip
|
|
485
|
-
break;
|
|
486
|
-
}
|
|
487
|
-
default: {
|
|
488
|
-
workerConsoleLog(`Spawn: redirect type ${type} not found.`);
|
|
489
|
-
return {
|
|
490
|
-
exitStatus: constants.WASI_EINVAL,
|
|
491
|
-
outputSize: 0,
|
|
492
|
-
};
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
redirects.push(redirect);
|
|
496
|
-
workerConsoleLog(`Redirect[${i}] = type: ${redirect.type}, fd_dst: ${redirect.fd_dst}, path: ${redirect.path}, fd_src: ${redirect.fd_src}`);
|
|
497
|
-
}
|
|
498
|
-
sendToKernel([
|
|
499
|
-
"spawn",
|
|
500
|
-
{
|
|
501
|
-
path,
|
|
502
|
-
args,
|
|
503
|
-
env: { ...env, ...extended_env },
|
|
504
|
-
sharedBuffer,
|
|
505
|
-
background,
|
|
506
|
-
redirects: redirects,
|
|
507
|
-
},
|
|
508
|
-
]);
|
|
509
|
-
// wait for child process to finish
|
|
510
|
-
Atomics.wait(lck, 0, -1);
|
|
511
|
-
const err = Atomics.load(lck, 0);
|
|
512
|
-
const childPID = new Int32Array(sharedBuffer, 4, 1);
|
|
513
|
-
const userBuffer = new Uint32Array(2);
|
|
514
|
-
let exitStatus = constants.EXIT_SUCCESS;
|
|
515
|
-
userBuffer[0] = constants.EXIT_SUCCESS;
|
|
516
|
-
userBuffer[1] = Atomics.load(childPID, 0);
|
|
517
|
-
if (err !== constants.WASI_ESUCCESS) {
|
|
518
|
-
workerConsoleLog(`error: spawned process returned ${err}`);
|
|
519
|
-
if (err === constants.WASI_ENOEXEC) {
|
|
520
|
-
// If the program can't be executed, return additional output message
|
|
521
|
-
userBuffer[0] = constants.WASI_ENOEXEC;
|
|
522
|
-
exitStatus = constants.EXIT_FAILURE;
|
|
523
|
-
}
|
|
524
|
-
else {
|
|
525
|
-
exitStatus = err;
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
let byteResult = new Uint8Array(userBuffer.buffer, 0, 8);
|
|
529
|
-
outputBuffer.set(byteResult, 0);
|
|
530
|
-
return {
|
|
531
|
-
exitStatus: exitStatus,
|
|
532
|
-
outputSize: 8,
|
|
533
|
-
};
|
|
534
|
-
}
|
|
535
|
-
case "chdir": {
|
|
536
|
-
const sharedBuffer = new SharedArrayBuffer(4);
|
|
537
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
538
|
-
lck[0] = -1;
|
|
539
|
-
const { dir } = JSON.parse(json);
|
|
540
|
-
workerConsoleLog(`chdir(${dir})`);
|
|
541
|
-
const dir_ = utils.realpath(dir);
|
|
542
|
-
sendToKernel(["chdir", { dir: dir_, sharedBuffer }]);
|
|
543
|
-
Atomics.wait(lck, 0, -1);
|
|
544
|
-
const err = Atomics.load(lck, 0);
|
|
545
|
-
workerConsoleLog(`chdir returned ${err}`);
|
|
546
|
-
return {
|
|
547
|
-
exitStatus: err,
|
|
548
|
-
outputSize: 0,
|
|
549
|
-
};
|
|
550
|
-
}
|
|
551
|
-
case "getcwd": {
|
|
552
|
-
const { buf_len } = JSON.parse(json);
|
|
553
|
-
workerConsoleLog(`getcwd(${buf_len})`);
|
|
554
|
-
const sharedBuffer = new SharedArrayBuffer(4 + 4 + buf_len);
|
|
555
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
556
|
-
const cwd_len = new Uint32Array(sharedBuffer, 4, 1);
|
|
557
|
-
const cwd_buf = new Uint8Array(sharedBuffer, 8, buf_len);
|
|
558
|
-
lck[0] = -1;
|
|
559
|
-
sendToKernel([
|
|
560
|
-
"getcwd",
|
|
561
|
-
{ bufLen: buf_len, sharedBuffer },
|
|
562
|
-
]);
|
|
563
|
-
Atomics.wait(lck, 0, -1);
|
|
564
|
-
const err = Atomics.load(lck, 0);
|
|
565
|
-
const output = err === constants.EXIT_SUCCESS
|
|
566
|
-
? new TextDecoder().decode(cwd_buf.slice(0, cwd_len[0]))
|
|
567
|
-
: undefined;
|
|
568
|
-
workerConsoleLog(`getcwd returned ${output}`);
|
|
569
|
-
// Check user buffer size is enough
|
|
570
|
-
if (outputBuffer.byteLength <= cwd_len[0]) {
|
|
571
|
-
return {
|
|
572
|
-
exitStatus: constants.WASI_ENOBUFS,
|
|
573
|
-
outputSize: 0,
|
|
574
|
-
};
|
|
575
|
-
}
|
|
576
|
-
outputBuffer.set(cwd_buf.slice(0, cwd_len[0]), 0);
|
|
577
|
-
outputBuffer.set([0], cwd_len[0]);
|
|
578
|
-
return {
|
|
579
|
-
exitStatus: err,
|
|
580
|
-
outputSize: cwd_len[0],
|
|
581
|
-
};
|
|
582
|
-
}
|
|
583
|
-
case "set_env": {
|
|
584
|
-
const sharedBuffer = new SharedArrayBuffer(4);
|
|
585
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
586
|
-
lck[0] = -1;
|
|
587
|
-
const { key, value } = JSON.parse(json);
|
|
588
|
-
workerConsoleLog(`set_env(${key}, ${value})`);
|
|
589
|
-
sendToKernel(["set_env", { key, value, sharedBuffer }]);
|
|
590
|
-
Atomics.wait(lck, 0, -1);
|
|
591
|
-
const err = Atomics.load(lck, 0);
|
|
592
|
-
if (err === constants.WASI_ESUCCESS) {
|
|
593
|
-
if (value === undefined) {
|
|
594
|
-
delete env[key];
|
|
595
|
-
}
|
|
596
|
-
else {
|
|
597
|
-
env[key] = value;
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
return {
|
|
601
|
-
exitStatus: constants.EXIT_SUCCESS,
|
|
602
|
-
outputSize: 0,
|
|
603
|
-
};
|
|
604
|
-
}
|
|
605
|
-
// TODO: rework this, linux uses "stty -echo"/"stty echo"
|
|
606
|
-
// (https://www.thegeeksearch.com/how-to-disable-enable-echo-of-keys-commands-typed-in-linux-shell/)
|
|
607
|
-
case "set_echo": {
|
|
608
|
-
const sharedBuffer = new SharedArrayBuffer(4);
|
|
609
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
610
|
-
lck[0] = -1;
|
|
611
|
-
const { echo } = JSON.parse(json);
|
|
612
|
-
workerConsoleLog(`set_echo(${echo})`);
|
|
613
|
-
sendToKernel([
|
|
614
|
-
"set_echo",
|
|
615
|
-
{ shouldEcho: echo, sharedBuffer },
|
|
616
|
-
]);
|
|
617
|
-
Atomics.wait(lck, 0, -1);
|
|
618
|
-
return {
|
|
619
|
-
exitStatus: constants.EXIT_SUCCESS,
|
|
620
|
-
outputSize: 0,
|
|
621
|
-
};
|
|
622
|
-
}
|
|
623
|
-
case "isatty": {
|
|
624
|
-
// wasi_ext_lib::isatty needs: int
|
|
625
|
-
if (outputBuffer.byteLength < 4) {
|
|
626
|
-
return {
|
|
627
|
-
exitStatus: constants.WASI_ENOBUFS,
|
|
628
|
-
outputSize: 0,
|
|
629
|
-
};
|
|
630
|
-
}
|
|
631
|
-
const sharedBuffer = new SharedArrayBuffer(8);
|
|
632
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
633
|
-
lck[0] = -1;
|
|
634
|
-
const { fd } = JSON.parse(json);
|
|
635
|
-
workerConsoleLog(`isatty(${fd})`);
|
|
636
|
-
sendToKernel(["isatty", { sharedBuffer, fd }]);
|
|
637
|
-
Atomics.wait(lck, 0, -1);
|
|
638
|
-
let err = Atomics.load(lck, 0);
|
|
639
|
-
const isattyPtr = new Uint8Array(sharedBuffer, 4, 4);
|
|
640
|
-
outputBuffer.set(isattyPtr.slice(0, 4), 0);
|
|
641
|
-
return {
|
|
642
|
-
exitStatus: err,
|
|
643
|
-
outputSize: 4,
|
|
644
|
-
};
|
|
645
|
-
}
|
|
646
|
-
case "getpid": {
|
|
647
|
-
// wasi_ext_lib::getpid needs: int pid
|
|
648
|
-
if (outputBuffer.byteLength < 4) {
|
|
649
|
-
return {
|
|
650
|
-
exitStatus: constants.WASI_ENOBUFS,
|
|
651
|
-
outputSize: 0,
|
|
652
|
-
};
|
|
653
|
-
}
|
|
654
|
-
const sharedBuffer = new SharedArrayBuffer(8);
|
|
655
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
656
|
-
const pidPtr = new Int32Array(sharedBuffer, 4, 1);
|
|
657
|
-
lck[0] = -1;
|
|
658
|
-
pidPtr[0] = -1;
|
|
659
|
-
workerConsoleLog(`getpid()`);
|
|
660
|
-
sendToKernel(["getpid", { sharedBuffer }]);
|
|
661
|
-
Atomics.wait(lck, 0, -1);
|
|
662
|
-
const pidArray = new Uint8Array(sharedBuffer, 4, 4);
|
|
663
|
-
outputBuffer.set(pidArray, 0);
|
|
664
|
-
return {
|
|
665
|
-
exitStatus: constants.EXIT_SUCCESS,
|
|
666
|
-
outputSize: 4,
|
|
667
|
-
};
|
|
668
|
-
}
|
|
669
|
-
case "event_source_fd": {
|
|
670
|
-
// wasi_ext_lib::event_source_fd needs: int fd
|
|
671
|
-
if (outputBuffer.byteLength < 4) {
|
|
672
|
-
return {
|
|
673
|
-
exitStatus: constants.WASI_ENOBUFS,
|
|
674
|
-
outputSize: 0,
|
|
675
|
-
};
|
|
676
|
-
}
|
|
677
|
-
const { event_mask: eventMask } = JSON.parse(json);
|
|
678
|
-
const sharedBuffer = new SharedArrayBuffer(4 + 4);
|
|
679
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
680
|
-
workerConsoleLog(`event_source_fd(${eventMask})`);
|
|
681
|
-
if (eventMask === constants.WASI_EXT_NO_EVENT ||
|
|
682
|
-
eventMask >= 1 << constants.WASI_EXT_EVENTS_NUM) {
|
|
683
|
-
return {
|
|
684
|
-
exitStatus: constants.WASI_EINVAL,
|
|
685
|
-
outputSize: 0,
|
|
686
|
-
};
|
|
687
|
-
}
|
|
688
|
-
lck[0] = -1;
|
|
689
|
-
sendToKernel([
|
|
690
|
-
"event_source_fd",
|
|
691
|
-
{ sharedBuffer, eventMask },
|
|
692
|
-
]);
|
|
693
|
-
Atomics.wait(lck, 0, -1);
|
|
694
|
-
let returnCode = Atomics.load(lck, 0);
|
|
695
|
-
const fileDescriptor = new Uint8Array(sharedBuffer, 4, 4);
|
|
696
|
-
outputBuffer.set(fileDescriptor, 0);
|
|
697
|
-
return {
|
|
698
|
-
exitStatus: returnCode,
|
|
699
|
-
outputSize: 4,
|
|
700
|
-
};
|
|
701
|
-
}
|
|
702
|
-
case "attach_sigint": {
|
|
703
|
-
const { event_source_fd: fd } = JSON.parse(json);
|
|
704
|
-
// lock + event source file descriptor
|
|
705
|
-
const sharedBuffer = new SharedArrayBuffer(4 + 4);
|
|
706
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
707
|
-
lck[0] = -1;
|
|
708
|
-
workerConsoleLog(`attach_sigint(${fd})`);
|
|
709
|
-
sendToKernel([
|
|
710
|
-
"attach_sigint",
|
|
711
|
-
{ sharedBuffer, fd },
|
|
712
|
-
]);
|
|
713
|
-
Atomics.wait(lck, 0, -1);
|
|
714
|
-
let returnCode = Atomics.load(lck, 0);
|
|
715
|
-
return {
|
|
716
|
-
exitStatus: returnCode,
|
|
717
|
-
outputSize: 0,
|
|
718
|
-
};
|
|
719
|
-
}
|
|
720
|
-
case "clean_inodes": {
|
|
721
|
-
const sharedBuffer = new SharedArrayBuffer(4);
|
|
722
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
723
|
-
workerConsoleLog("clean_inodes()");
|
|
724
|
-
lck[0] = -1;
|
|
725
|
-
sendToKernel(["clean_inodes", { sharedBuffer }]);
|
|
726
|
-
Atomics.wait(lck, 0, -1);
|
|
727
|
-
return {
|
|
728
|
-
exitStatus: Atomics.load(lck, 0),
|
|
729
|
-
outputSize: 0,
|
|
730
|
-
};
|
|
731
|
-
}
|
|
732
|
-
case "kill": {
|
|
733
|
-
const { process_id: processId, signal: signalNumber, } = JSON.parse(json);
|
|
734
|
-
const sharedBuffer = new SharedArrayBuffer(4);
|
|
735
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
736
|
-
lck[0] = -1;
|
|
737
|
-
workerConsoleLog(`kill(${processId}, ${signalNumber})`);
|
|
738
|
-
sendToKernel([
|
|
739
|
-
"kill",
|
|
740
|
-
{ sharedBuffer, processId, signalNumber },
|
|
741
|
-
]);
|
|
742
|
-
Atomics.wait(lck, 0, -1);
|
|
743
|
-
return {
|
|
744
|
-
exitStatus: Atomics.load(lck, 0),
|
|
745
|
-
outputSize: 0,
|
|
746
|
-
};
|
|
747
|
-
}
|
|
748
|
-
case "ioctl": {
|
|
749
|
-
const { fd, cmd, } = JSON.parse(json);
|
|
750
|
-
const { size, rw, func } = utils.decodeIoctlRequest(BigInt(cmd));
|
|
751
|
-
// lock + arg buffer size used + arg buffer
|
|
752
|
-
const sharedBuffer = new SharedArrayBuffer(4 + size);
|
|
753
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
754
|
-
const sharedArgBuffer = new Uint8Array(sharedBuffer, 4, size);
|
|
755
|
-
workerConsoleLog(`ioctl(${fd}, ${cmd})`);
|
|
756
|
-
lck[0] = -1;
|
|
757
|
-
if (rw === 3 /* utils.ioc.IOWR */ || rw === 1 /* utils.ioc.IOW */)
|
|
758
|
-
sharedArgBuffer.set(outputBuffer); // in this case it is either input or output buffer
|
|
759
|
-
sendToKernel([
|
|
760
|
-
"ioctl",
|
|
761
|
-
{ sharedBuffer, fd, command: func },
|
|
762
|
-
]);
|
|
763
|
-
Atomics.wait(lck, 0, -1);
|
|
764
|
-
let len = 0;
|
|
765
|
-
if (rw === 3 /* utils.ioc.IOWR */ || rw === 2 /* utils.ioc.IOR */) {
|
|
766
|
-
outputBuffer.set(sharedArgBuffer);
|
|
767
|
-
len = size;
|
|
768
|
-
}
|
|
769
|
-
return {
|
|
770
|
-
exitStatus: Atomics.load(lck, 0),
|
|
771
|
-
outputSize: len,
|
|
772
|
-
};
|
|
773
|
-
}
|
|
774
|
-
case "mount": {
|
|
775
|
-
const { source_fd, source, source_len, target_fd, target, target_len, filesystemtype, filesystemtype_len, mountflags, data, data_len, } = JSON.parse(json);
|
|
776
|
-
const view8 = new Uint8Array(moduleInstanceExports["memory"].buffer);
|
|
777
|
-
const sourcePath = new TextDecoder().decode(view8.slice(source, source + source_len));
|
|
778
|
-
const targetPath = new TextDecoder().decode(view8.slice(target, target + target_len));
|
|
779
|
-
const filesystemType = new TextDecoder().decode(view8.slice(filesystemtype, filesystemtype + filesystemtype_len));
|
|
780
|
-
const data_ = new TextDecoder().decode(view8.slice(data, data + data_len));
|
|
781
|
-
workerConsoleLog(`mount(${source_fd}, "${sourcePath}", ${source_len}, ${target_fd}, "${targetPath}", ${target_len}, "${filesystemType}", ${filesystemtype_len}, ${mountflags}, "${data_}", ${data_len})`);
|
|
782
|
-
const sharedBuffer = new SharedArrayBuffer(4);
|
|
783
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
784
|
-
lck[0] = -1;
|
|
785
|
-
sendToKernel([
|
|
786
|
-
"mount",
|
|
787
|
-
{
|
|
788
|
-
sharedBuffer,
|
|
789
|
-
sourceFd: source_fd,
|
|
790
|
-
sourcePath,
|
|
791
|
-
targetFd: target_fd,
|
|
792
|
-
targetPath,
|
|
793
|
-
filesystemType,
|
|
794
|
-
mountFlags: mountflags,
|
|
795
|
-
data: data_,
|
|
796
|
-
},
|
|
797
|
-
]);
|
|
798
|
-
Atomics.wait(lck, 0, -1);
|
|
799
|
-
const exitStatus = Atomics.load(lck, 0);
|
|
800
|
-
workerConsoleLog(`mount returned ${exitStatus}`);
|
|
801
|
-
return {
|
|
802
|
-
exitStatus,
|
|
803
|
-
outputSize: 0,
|
|
804
|
-
};
|
|
805
|
-
}
|
|
806
|
-
case "umount": {
|
|
807
|
-
const { path, path_len, } = JSON.parse(json);
|
|
808
|
-
const view8 = new Uint8Array(moduleInstanceExports["memory"].buffer);
|
|
809
|
-
const path_ = new TextDecoder().decode(view8.slice(path, path + path_len));
|
|
810
|
-
workerConsoleLog(`umount("${path_}", ${path_len}`);
|
|
811
|
-
const sharedBuffer = new SharedArrayBuffer(4);
|
|
812
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
813
|
-
lck[0] = -1;
|
|
814
|
-
sendToKernel([
|
|
815
|
-
"umount",
|
|
816
|
-
{
|
|
817
|
-
path: path_,
|
|
818
|
-
sharedBuffer,
|
|
819
|
-
},
|
|
820
|
-
]);
|
|
821
|
-
Atomics.wait(lck, 0, -1);
|
|
822
|
-
const exitStatus = Atomics.load(lck, 0);
|
|
823
|
-
workerConsoleLog(`umount returned ${exitStatus}`);
|
|
824
|
-
return {
|
|
825
|
-
exitStatus,
|
|
826
|
-
outputSize: 0,
|
|
827
|
-
};
|
|
828
|
-
}
|
|
829
|
-
case "mknod": {
|
|
830
|
-
const { path, dev } = JSON.parse(json);
|
|
831
|
-
workerConsoleLog(`mknod("${path}", ${dev})`);
|
|
832
|
-
const sharedBuffer = new SharedArrayBuffer(4);
|
|
833
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
834
|
-
lck[0] = -1;
|
|
835
|
-
sendToKernel([
|
|
836
|
-
"mknod",
|
|
837
|
-
{
|
|
838
|
-
sharedBuffer,
|
|
839
|
-
path,
|
|
840
|
-
dev
|
|
841
|
-
},
|
|
842
|
-
]);
|
|
843
|
-
Atomics.wait(lck, 0, -1);
|
|
844
|
-
const exitStatus = Atomics.load(lck, 0);
|
|
845
|
-
workerConsoleLog(`mknod returned ${exitStatus}`);
|
|
846
|
-
return {
|
|
847
|
-
exitStatus,
|
|
848
|
-
outputSize: 0
|
|
849
|
-
};
|
|
850
|
-
}
|
|
851
|
-
default: {
|
|
852
|
-
workerConsoleLog(`Special command ${command} not found.`);
|
|
853
|
-
throw Error(`Special command '${command} not found.`);
|
|
854
|
-
}
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
function path_readlink(fd, pathPtr, pathLen, bufferPtr, bufferLen, bufferUsedPtr) {
|
|
858
|
-
workerConsoleLog(`path_readlink(${fd}, ${pathPtr}, ${pathLen}, ${bufferPtr}, ${bufferLen}, ${bufferUsedPtr})`);
|
|
859
|
-
const view8 = new Uint8Array(moduleInstanceExports["memory"].buffer);
|
|
860
|
-
const view = new DataView(moduleInstanceExports["memory"].buffer);
|
|
861
|
-
const path = new TextDecoder().decode(view8.slice(pathPtr, pathPtr + pathLen));
|
|
862
|
-
workerConsoleLog(`path is ${path}, buffer_len = ${bufferLen}, fd = ${fd}`);
|
|
863
|
-
// special case, path_readlink is used for spawning subprocesses
|
|
864
|
-
if (path[0] === "!") {
|
|
865
|
-
const outputBuffer = bufferPtr !== 0
|
|
866
|
-
? new Uint8Array(moduleInstanceExports["memory"].buffer, bufferPtr, bufferLen)
|
|
867
|
-
: new Uint8Array();
|
|
868
|
-
const { exitStatus, outputSize } = specialParse(path.slice(1), outputBuffer);
|
|
869
|
-
// ensure that syscall output doesn't exceed buffer size and the buffer pointer is not NULL
|
|
870
|
-
if (exitStatus !== constants.WASI_ENOBUFS && bufferPtr !== 0) {
|
|
871
|
-
view.setUint32(bufferUsedPtr, outputSize, true);
|
|
872
|
-
}
|
|
873
|
-
return exitStatus;
|
|
874
|
-
}
|
|
875
|
-
const sharedBuffer = new SharedArrayBuffer(4 + bufferLen + 4); // lock, path buffer, buffer used
|
|
876
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
877
|
-
lck[0] = -1;
|
|
878
|
-
const bufferUsed = new Int32Array(sharedBuffer, 4, 1);
|
|
879
|
-
const buffer = new Uint8Array(sharedBuffer, 8, bufferLen);
|
|
880
|
-
sendToKernel([
|
|
881
|
-
"path_readlink",
|
|
882
|
-
{
|
|
883
|
-
sharedBuffer,
|
|
884
|
-
fd,
|
|
885
|
-
path,
|
|
886
|
-
bufferLen,
|
|
887
|
-
},
|
|
888
|
-
]);
|
|
889
|
-
Atomics.wait(lck, 0, -1);
|
|
890
|
-
const err = Atomics.load(lck, 0);
|
|
891
|
-
if (err !== constants.WASI_ESUCCESS) {
|
|
892
|
-
return err;
|
|
893
|
-
}
|
|
894
|
-
view8.set(buffer, bufferPtr);
|
|
895
|
-
view.setUint32(bufferUsedPtr, bufferUsed[0], true);
|
|
896
|
-
return constants.WASI_ESUCCESS;
|
|
897
|
-
}
|
|
898
|
-
function path_remove_directory(fd, pathPtr, pathLen) {
|
|
899
|
-
workerConsoleLog(`path_remove_directory(${fd}, ${pathPtr}, ${pathLen})`);
|
|
900
|
-
const view8 = new Uint8Array(moduleInstanceExports["memory"].buffer);
|
|
901
|
-
const path = new TextDecoder().decode(view8.slice(pathPtr, pathPtr + pathLen));
|
|
902
|
-
const sharedBuffer = new SharedArrayBuffer(4); // lock
|
|
903
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
904
|
-
lck[0] = -1;
|
|
905
|
-
sendToKernel([
|
|
906
|
-
"path_remove_directory",
|
|
907
|
-
{ sharedBuffer, fd, path },
|
|
908
|
-
]);
|
|
909
|
-
Atomics.wait(lck, 0, -1);
|
|
910
|
-
return Atomics.load(lck, 0);
|
|
911
|
-
}
|
|
912
|
-
function path_rename(oldFd, oldPathPtr, oldPathLen, newFd, newPathPtr, newPathLen) {
|
|
913
|
-
const view8 = new Uint8Array(moduleInstanceExports["memory"].buffer);
|
|
914
|
-
const oldPath = new TextDecoder().decode(view8.slice(oldPathPtr, oldPathPtr + oldPathLen));
|
|
915
|
-
const newPath = new TextDecoder().decode(view8.slice(newPathPtr, newPathPtr + newPathLen));
|
|
916
|
-
workerConsoleLog(`path_rename(${oldFd}, ${oldPath}, ${oldPathLen}, ${newFd}, ${newPath}, ${newPathLen})`);
|
|
917
|
-
const sharedBuffer = new SharedArrayBuffer(4);
|
|
918
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
919
|
-
lck[0] = -1;
|
|
920
|
-
sendToKernel([
|
|
921
|
-
"path_rename",
|
|
922
|
-
{ sharedBuffer, oldFd, oldPath, newFd, newPath },
|
|
923
|
-
]);
|
|
924
|
-
Atomics.wait(lck, 0, -1);
|
|
925
|
-
return Atomics.load(lck, 0);
|
|
926
|
-
}
|
|
927
|
-
function path_unlink_file(fd, pathPtr, pathLen) {
|
|
928
|
-
workerConsoleLog(`path_unlink_file(${fd}, ${pathPtr}, ${pathLen})`);
|
|
929
|
-
const view8 = new Uint8Array(moduleInstanceExports["memory"].buffer);
|
|
930
|
-
const path = new TextDecoder().decode(view8.slice(pathPtr, pathPtr + pathLen));
|
|
931
|
-
const sharedBuffer = new SharedArrayBuffer(4); // lock
|
|
932
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
933
|
-
lck[0] = -1;
|
|
934
|
-
sendToKernel([
|
|
935
|
-
"path_unlink_file",
|
|
936
|
-
{ sharedBuffer, fd, path },
|
|
937
|
-
]);
|
|
938
|
-
Atomics.wait(lck, 0, -1);
|
|
939
|
-
return Atomics.load(lck, 0);
|
|
940
|
-
}
|
|
941
|
-
function sched_yield() {
|
|
942
|
-
return placeholder();
|
|
943
|
-
}
|
|
944
|
-
function fd_prestat_get(fd, buf) {
|
|
945
|
-
workerConsoleLog(`fd_prestat_get(${fd}, 0x${buf.toString(16)})`);
|
|
946
|
-
const view = new DataView(moduleInstanceExports["memory"].buffer);
|
|
947
|
-
const sharedBuffer = new SharedArrayBuffer(4 + 4 + 1); // lock, name length, preopen_type
|
|
948
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
949
|
-
lck[0] = -1;
|
|
950
|
-
const nameLen = new Int32Array(sharedBuffer, 4, 1);
|
|
951
|
-
const fileType = new Uint8Array(sharedBuffer, 8, 1);
|
|
952
|
-
sendToKernel(["fd_prestat_get", { sharedBuffer, fd }]);
|
|
953
|
-
Atomics.wait(lck, 0, -1);
|
|
954
|
-
const err = Atomics.load(lck, 0);
|
|
955
|
-
if (err === constants.WASI_ESUCCESS) {
|
|
956
|
-
view.setUint8(buf, fileType[0]);
|
|
957
|
-
view.setUint32(buf + 4, nameLen[0], true);
|
|
958
|
-
workerConsoleLog(`fd_prestat_get returned filetype type ${fileType[0]} of size ${nameLen[0]}`);
|
|
959
|
-
}
|
|
960
|
-
else {
|
|
961
|
-
workerConsoleLog(`fd_prestat_get returned ${err}`);
|
|
962
|
-
}
|
|
963
|
-
return err;
|
|
964
|
-
}
|
|
965
|
-
function fd_prestat_dir_name(fd, pathPtr, pathLen) {
|
|
966
|
-
workerConsoleLog(`fd_prestat_dir_name(${fd}, 0x${pathPtr.toString(16)}, ${pathLen})`);
|
|
967
|
-
const view8 = new Uint8Array(moduleInstanceExports["memory"].buffer);
|
|
968
|
-
const sharedBuffer = new SharedArrayBuffer(4 + pathLen); // lock, path
|
|
969
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
970
|
-
lck[0] = -1;
|
|
971
|
-
const path = new Uint8Array(sharedBuffer, 4, pathLen);
|
|
972
|
-
sendToKernel([
|
|
973
|
-
"fd_prestat_dir_name",
|
|
974
|
-
{ sharedBuffer, fd, pathLen },
|
|
975
|
-
]);
|
|
976
|
-
Atomics.wait(lck, 0, -1);
|
|
977
|
-
const err = Atomics.load(lck, 0);
|
|
978
|
-
if (err === constants.WASI_ESUCCESS) {
|
|
979
|
-
view8.set(path, pathPtr);
|
|
980
|
-
}
|
|
981
|
-
const pathStr = new TextDecoder().decode(view8.slice(pathPtr, pathPtr + pathLen));
|
|
982
|
-
workerConsoleLog(`prestat returned ${err}, "${pathStr}" of size ${pathLen}`);
|
|
983
|
-
return err;
|
|
984
|
-
}
|
|
985
|
-
function fd_datasync() {
|
|
986
|
-
return placeholder();
|
|
987
|
-
}
|
|
988
|
-
function fd_filestat_set_size() {
|
|
989
|
-
return placeholder();
|
|
990
|
-
}
|
|
991
|
-
function fd_sync() {
|
|
992
|
-
return placeholder();
|
|
993
|
-
}
|
|
994
|
-
function path_symlink(oldPathPtr, oldPathLen, newFd, newPathPtr, newPathLen) {
|
|
995
|
-
workerConsoleLog(`path_symlink(0x${oldPathPtr.toString(16)}, ${oldPathLen}, ${newFd}, 0x${newPathPtr.toString(16)}, ${newPathLen})`);
|
|
996
|
-
const view8 = new Uint8Array(moduleInstanceExports["memory"].buffer);
|
|
997
|
-
const oldPath = new TextDecoder().decode(view8.slice(oldPathPtr, oldPathPtr + oldPathLen));
|
|
998
|
-
const newPath = new TextDecoder().decode(view8.slice(newPathPtr, newPathPtr + newPathLen));
|
|
999
|
-
workerConsoleLog(`path_symlink: ${newPath} --> ${oldPath}`);
|
|
1000
|
-
const sharedBuffer = new SharedArrayBuffer(4); // lock
|
|
1001
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
1002
|
-
lck[0] = -1;
|
|
1003
|
-
sendToKernel([
|
|
1004
|
-
"path_symlink",
|
|
1005
|
-
{
|
|
1006
|
-
sharedBuffer,
|
|
1007
|
-
targetPath: oldPath,
|
|
1008
|
-
linkFd: newFd,
|
|
1009
|
-
linkPath: newPath,
|
|
1010
|
-
},
|
|
1011
|
-
]);
|
|
1012
|
-
Atomics.wait(lck, 0, -1);
|
|
1013
|
-
let err = Atomics.load(lck, 0);
|
|
1014
|
-
workerConsoleLog(`path_symlink returned ${err}`);
|
|
1015
|
-
return err;
|
|
1016
|
-
}
|
|
1017
|
-
function path_link(oldFd, oldFlags, oldPathPtr, oldPathLen, newFd, newPathPtr, newPathLen) {
|
|
1018
|
-
workerConsoleLog(`path_link(${oldFd}, ${oldFlags}, ${oldPathPtr}, ${oldPathLen}, ${newFd}, ${newPathPtr}, ${newPathLen})`);
|
|
1019
|
-
const view8 = new Uint8Array(moduleInstanceExports["memory"].buffer);
|
|
1020
|
-
const oldPath = new TextDecoder().decode(view8.slice(oldPathPtr, oldPathPtr + oldPathLen));
|
|
1021
|
-
const newPath = new TextDecoder().decode(view8.slice(newPathPtr, newPathPtr + newPathLen));
|
|
1022
|
-
workerConsoleLog(`path_link: ${newPath} -> ${oldPath}`);
|
|
1023
|
-
const sharedBuffer = new SharedArrayBuffer(4); // lock
|
|
1024
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
1025
|
-
lck[0] = -1;
|
|
1026
|
-
sendToKernel([
|
|
1027
|
-
"path_link",
|
|
1028
|
-
{
|
|
1029
|
-
sharedBuffer,
|
|
1030
|
-
oldFd,
|
|
1031
|
-
oldFlags,
|
|
1032
|
-
oldPath,
|
|
1033
|
-
newFd,
|
|
1034
|
-
newPath,
|
|
1035
|
-
},
|
|
1036
|
-
]);
|
|
1037
|
-
Atomics.wait(lck, 0, -1);
|
|
1038
|
-
return Atomics.load(lck, 0);
|
|
1039
|
-
}
|
|
1040
|
-
function poll_oneoff(subscriptionsPtr, eventsPtr, nSubscriptions, nEvents) {
|
|
1041
|
-
workerConsoleLog(`poll_oneoff(${subscriptionsPtr}, ${eventsPtr}, ${nSubscriptions}, ${nEvents})`);
|
|
1042
|
-
const view = new DataView(moduleInstanceExports["memory"].buffer);
|
|
1043
|
-
// Buffer for sending occured events from kernel back to the process
|
|
1044
|
-
// it can hold up to nSubscriptions events
|
|
1045
|
-
const eventBuf = new SharedArrayBuffer(POLL_EVENT_BUFSIZE * nSubscriptions);
|
|
1046
|
-
var minWaitEnd = BigInt(Number.MAX_SAFE_INTEGER);
|
|
1047
|
-
const fdSubs = new Array();
|
|
1048
|
-
let lastClockUserdata;
|
|
1049
|
-
let lastClock = undefined;
|
|
1050
|
-
for (let i = 0; i < nSubscriptions; i += 1) {
|
|
1051
|
-
const userdata = view.getBigUint64(subscriptionsPtr, true);
|
|
1052
|
-
subscriptionsPtr += 8; // userdata offset
|
|
1053
|
-
const eventType = view.getUint8(subscriptionsPtr);
|
|
1054
|
-
subscriptionsPtr += 1; // tag offset
|
|
1055
|
-
let fdSub;
|
|
1056
|
-
switch (eventType) {
|
|
1057
|
-
case constants.WASI_EVENTTYPE_CLOCK: {
|
|
1058
|
-
subscriptionsPtr += 7; // padding to 8
|
|
1059
|
-
const clockId = view.getUint32(subscriptionsPtr, true);
|
|
1060
|
-
subscriptionsPtr += 8; // clockId offset
|
|
1061
|
-
const timeout = view.getBigUint64(subscriptionsPtr, true);
|
|
1062
|
-
subscriptionsPtr += 8; // timeout offset
|
|
1063
|
-
const precision = view.getBigUint64(subscriptionsPtr, true);
|
|
1064
|
-
subscriptionsPtr += 8; // precision offset
|
|
1065
|
-
const subClockFlags = view.getUint16(subscriptionsPtr, true);
|
|
1066
|
-
subscriptionsPtr += 8; // flags offset + padding to 8
|
|
1067
|
-
const absolute = subClockFlags === 1;
|
|
1068
|
-
workerConsoleLog(`clockId = ${clockId}, timeout = ${timeout}, precision = ${precision}, absolute = ${absolute}`);
|
|
1069
|
-
const n = utils.now(clockId, CPUTIME_START);
|
|
1070
|
-
const end = absolute ? timeout : n + timeout;
|
|
1071
|
-
if (minWaitEnd > end) {
|
|
1072
|
-
minWaitEnd = end;
|
|
1073
|
-
lastClock = {
|
|
1074
|
-
clockId,
|
|
1075
|
-
timeout,
|
|
1076
|
-
precision,
|
|
1077
|
-
flags: subClockFlags,
|
|
1078
|
-
};
|
|
1079
|
-
lastClockUserdata = userdata;
|
|
1080
|
-
}
|
|
1081
|
-
continue;
|
|
1082
|
-
}
|
|
1083
|
-
case constants.WASI_EVENTTYPE_FD_WRITE:
|
|
1084
|
-
case constants.WASI_EVENTTYPE_FD_READ: {
|
|
1085
|
-
subscriptionsPtr += 7; // padding to 8
|
|
1086
|
-
const fd = view.getUint32(subscriptionsPtr, true);
|
|
1087
|
-
subscriptionsPtr += 32; // file descriptor offset + subscription padding
|
|
1088
|
-
workerConsoleLog(`read data from fd = ${fd}`);
|
|
1089
|
-
fdSub = { fd };
|
|
1090
|
-
break;
|
|
1091
|
-
}
|
|
1092
|
-
default:
|
|
1093
|
-
// There is no more event types
|
|
1094
|
-
return constants.WASI_EINVAL;
|
|
1095
|
-
}
|
|
1096
|
-
if (fdSub)
|
|
1097
|
-
fdSubs.push({ userdata, eventType, event: fdSub });
|
|
1098
|
-
}
|
|
1099
|
-
if (lastClock) {
|
|
1100
|
-
fdSubs.push({
|
|
1101
|
-
userdata: lastClockUserdata,
|
|
1102
|
-
eventType: constants.WASI_EVENTTYPE_CLOCK,
|
|
1103
|
-
event: lastClock,
|
|
1104
|
-
});
|
|
1105
|
-
}
|
|
1106
|
-
// lock + number of events that occured
|
|
1107
|
-
const sharedBuffer = new SharedArrayBuffer(4 + 4);
|
|
1108
|
-
const lock = new Int32Array(sharedBuffer, 0, 2);
|
|
1109
|
-
lock[0] = -1;
|
|
1110
|
-
lock[1] = 0;
|
|
1111
|
-
if (fdSubs.length > 0) {
|
|
1112
|
-
sendToKernel([
|
|
1113
|
-
"poll_oneoff",
|
|
1114
|
-
{
|
|
1115
|
-
sharedBuffer,
|
|
1116
|
-
subs: fdSubs,
|
|
1117
|
-
eventBuf,
|
|
1118
|
-
timeout: minWaitEnd,
|
|
1119
|
-
},
|
|
1120
|
-
]);
|
|
1121
|
-
Atomics.wait(lock, 0, -1);
|
|
1122
|
-
}
|
|
1123
|
-
const nOccured = lock[1];
|
|
1124
|
-
new Uint8Array(moduleInstanceExports["memory"].buffer, eventsPtr, nOccured * POLL_EVENT_BUFSIZE).set(new Uint8Array(eventBuf, 0, nOccured * POLL_EVENT_BUFSIZE));
|
|
1125
|
-
view.setInt32(nEvents, nOccured, true);
|
|
1126
|
-
return constants.WASI_ESUCCESS;
|
|
1127
|
-
}
|
|
1128
|
-
const placeholder = () => {
|
|
1129
|
-
workerConsoleLog(`> Entering stub ${new Error().stack.split("\n")[2].trim().split(" ")[1]}`);
|
|
1130
|
-
return constants.WASI_ESUCCESS;
|
|
1131
|
-
};
|
|
1132
|
-
function fd_advice() {
|
|
1133
|
-
return placeholder();
|
|
1134
|
-
}
|
|
1135
|
-
function fd_allocate() {
|
|
1136
|
-
return placeholder();
|
|
1137
|
-
}
|
|
1138
|
-
function fd_fdstat_set_rights() {
|
|
1139
|
-
return placeholder();
|
|
1140
|
-
}
|
|
1141
|
-
function fd_fdstat_set_flags(fd, flags) {
|
|
1142
|
-
workerConsoleLog(`fd_fdstat_set_flags(${fd}, ${flags})`);
|
|
1143
|
-
const sharedBuffer = new SharedArrayBuffer(4); // lock
|
|
1144
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
1145
|
-
lck[0] = -1;
|
|
1146
|
-
sendToKernel([
|
|
1147
|
-
"fd_fdstat_set_flags",
|
|
1148
|
-
{ sharedBuffer, fd, flags },
|
|
1149
|
-
]);
|
|
1150
|
-
Atomics.wait(lck, 0, -1);
|
|
1151
|
-
const err = Atomics.load(lck, 0);
|
|
1152
|
-
workerConsoleLog(`fd_fdstat_set_flags returned error: ${err}`);
|
|
1153
|
-
return err;
|
|
1154
|
-
}
|
|
1155
|
-
function fd_pwrite() {
|
|
1156
|
-
return placeholder();
|
|
1157
|
-
}
|
|
1158
|
-
function fd_renumber(fd, newFd) {
|
|
1159
|
-
// We ignore WASI spec, fd_renumber behaves like dup2 in unix
|
|
1160
|
-
workerConsoleLog(`fd_renumber(${fd}, ${newFd})`);
|
|
1161
|
-
const sharedBuffer = new SharedArrayBuffer(4); // lock
|
|
1162
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
1163
|
-
lck[0] = -1;
|
|
1164
|
-
sendToKernel([
|
|
1165
|
-
"fd_renumber",
|
|
1166
|
-
{ sharedBuffer, fd, newFd },
|
|
1167
|
-
]);
|
|
1168
|
-
Atomics.wait(lck, 0, -1);
|
|
1169
|
-
const err = Atomics.load(lck, 0);
|
|
1170
|
-
workerConsoleLog(`fd_renumber returned error: ${err}`);
|
|
1171
|
-
return err;
|
|
1172
|
-
}
|
|
1173
|
-
function fd_tell(fd, pos) {
|
|
1174
|
-
workerConsoleLog(`fd_tell(${fd}, 0x${pos.toString(16)})`);
|
|
1175
|
-
const view = new DataView(moduleInstanceExports["memory"].buffer);
|
|
1176
|
-
const sharedBuffer = new SharedArrayBuffer(8 + 4); // offset, lock
|
|
1177
|
-
const offset = new BigInt64Array(sharedBuffer, 0, 1);
|
|
1178
|
-
const lck = new Int32Array(sharedBuffer, 8, 1);
|
|
1179
|
-
lck[0] = -1;
|
|
1180
|
-
sendToKernel(["fd_tell", { sharedBuffer, fd }]);
|
|
1181
|
-
Atomics.wait(lck, 0, -1);
|
|
1182
|
-
const err = Atomics.load(lck, 0);
|
|
1183
|
-
if (err === constants.WASI_ESUCCESS) {
|
|
1184
|
-
view.setBigUint64(pos, offset[0], true);
|
|
1185
|
-
workerConsoleLog(`fd_tell returned offset: ${offset[0]}`);
|
|
1186
|
-
}
|
|
1187
|
-
else {
|
|
1188
|
-
workerConsoleLog(`fd_tell returned error: ${err}`);
|
|
1189
|
-
}
|
|
1190
|
-
return err;
|
|
1191
|
-
}
|
|
1192
|
-
function path_filestat_set_times(fd, flags, path, path_len, st_atim, st_mtim, fst_flags) {
|
|
1193
|
-
workerConsoleLog(`path_filestat_set_times(${fd}, ${flags}, ${path}, ${path_len}, ${st_atim}, ${st_mtim}, ${fst_flags})`);
|
|
1194
|
-
const view8 = new Uint8Array(moduleInstanceExports["memory"].buffer);
|
|
1195
|
-
const path_ = new TextDecoder().decode(view8.slice(path, path + path_len));
|
|
1196
|
-
const sharedBuffer = new SharedArrayBuffer(4);
|
|
1197
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
1198
|
-
lck[0] = -1;
|
|
1199
|
-
sendToKernel([
|
|
1200
|
-
"path_filestat_set_times",
|
|
1201
|
-
{
|
|
1202
|
-
sharedBuffer,
|
|
1203
|
-
fd,
|
|
1204
|
-
flags,
|
|
1205
|
-
path: path_,
|
|
1206
|
-
st_atim,
|
|
1207
|
-
st_mtim,
|
|
1208
|
-
fst_flags,
|
|
1209
|
-
},
|
|
1210
|
-
]);
|
|
1211
|
-
Atomics.wait(lck, 0, -1);
|
|
1212
|
-
const err = Atomics.load(lck, 0);
|
|
1213
|
-
workerConsoleLog(`path_filestat_set_times returned ${err}`);
|
|
1214
|
-
return err;
|
|
1215
|
-
}
|
|
1216
|
-
function proc_raise() {
|
|
1217
|
-
return placeholder();
|
|
1218
|
-
}
|
|
1219
|
-
function sock_accept() {
|
|
1220
|
-
return placeholder();
|
|
1221
|
-
}
|
|
1222
|
-
function sock_recv() {
|
|
1223
|
-
return placeholder();
|
|
1224
|
-
}
|
|
1225
|
-
function sock_send() {
|
|
1226
|
-
return placeholder();
|
|
1227
|
-
}
|
|
1228
|
-
function sock_shutdown() {
|
|
1229
|
-
return placeholder();
|
|
1230
|
-
}
|
|
1231
|
-
function fd_advise() {
|
|
1232
|
-
return placeholder();
|
|
1233
|
-
}
|
|
1234
|
-
function fd_filestat_set_times(fd, st_atim, st_mtim, fst_flags) {
|
|
1235
|
-
workerConsoleLog(`fd_filestat_set_times(${fd}, ${st_atim}, ${st_mtim}, ${fst_flags})`);
|
|
1236
|
-
const sharedBuffer = new SharedArrayBuffer(4);
|
|
1237
|
-
const lck = new Int32Array(sharedBuffer, 0, 1);
|
|
1238
|
-
lck[0] = -1;
|
|
1239
|
-
sendToKernel([
|
|
1240
|
-
"fd_filestat_set_times",
|
|
1241
|
-
{
|
|
1242
|
-
sharedBuffer,
|
|
1243
|
-
fd,
|
|
1244
|
-
st_atim,
|
|
1245
|
-
st_mtim,
|
|
1246
|
-
fst_flags,
|
|
1247
|
-
},
|
|
1248
|
-
]);
|
|
1249
|
-
Atomics.wait(lck, 0, -1);
|
|
1250
|
-
const err = Atomics.load(lck, 0);
|
|
1251
|
-
workerConsoleLog(`fd_filestat_set_times returned ${err}`);
|
|
1252
|
-
return err;
|
|
1253
|
-
}
|
|
1254
|
-
return {
|
|
1255
|
-
setModuleInstance,
|
|
1256
|
-
environ_sizes_get,
|
|
1257
|
-
args_sizes_get,
|
|
1258
|
-
fd_prestat_get,
|
|
1259
|
-
fd_fdstat_get,
|
|
1260
|
-
fd_filestat_get,
|
|
1261
|
-
fd_read,
|
|
1262
|
-
fd_write,
|
|
1263
|
-
fd_prestat_dir_name,
|
|
1264
|
-
environ_get,
|
|
1265
|
-
args_get,
|
|
1266
|
-
poll_oneoff,
|
|
1267
|
-
proc_exit,
|
|
1268
|
-
fd_close,
|
|
1269
|
-
fd_seek,
|
|
1270
|
-
random_get,
|
|
1271
|
-
clock_time_get,
|
|
1272
|
-
fd_readdir,
|
|
1273
|
-
path_create_directory,
|
|
1274
|
-
path_filestat_get,
|
|
1275
|
-
path_link,
|
|
1276
|
-
path_open,
|
|
1277
|
-
path_readlink,
|
|
1278
|
-
path_remove_directory,
|
|
1279
|
-
path_rename,
|
|
1280
|
-
path_unlink_file,
|
|
1281
|
-
sched_yield,
|
|
1282
|
-
fd_datasync,
|
|
1283
|
-
fd_filestat_set_size,
|
|
1284
|
-
fd_sync,
|
|
1285
|
-
path_symlink,
|
|
1286
|
-
clock_res_get,
|
|
1287
|
-
fd_advise,
|
|
1288
|
-
fd_allocate,
|
|
1289
|
-
fd_fdstat_set_flags,
|
|
1290
|
-
fd_fdstat_set_rights,
|
|
1291
|
-
fd_tell,
|
|
1292
|
-
fd_filestat_set_times,
|
|
1293
|
-
fd_pread,
|
|
1294
|
-
fd_advice,
|
|
1295
|
-
fd_pwrite,
|
|
1296
|
-
fd_renumber,
|
|
1297
|
-
path_filestat_set_times,
|
|
1298
|
-
proc_raise,
|
|
1299
|
-
sock_accept,
|
|
1300
|
-
sock_recv,
|
|
1301
|
-
sock_send,
|
|
1302
|
-
sock_shutdown,
|
|
1303
|
-
};
|
|
1304
|
-
}
|
|
1305
|
-
async function importWasmModule(module, wasiCallbacksConstructor) {
|
|
1306
|
-
let imps = WebAssembly.Module.imports(module);
|
|
1307
|
-
let wasiCallbacks;
|
|
1308
|
-
if (imps[0].module === "wasi_unstable") {
|
|
1309
|
-
wasiCallbacks = wasiCallbacksConstructor(true);
|
|
1310
|
-
}
|
|
1311
|
-
else if (imps[0].module === "wasi_snapshot_preview1") {
|
|
1312
|
-
wasiCallbacks = wasiCallbacksConstructor(false);
|
|
1313
|
-
}
|
|
1314
|
-
else {
|
|
1315
|
-
throw Error("Unsupported wasm format");
|
|
1316
|
-
}
|
|
1317
|
-
const moduleImports = {
|
|
1318
|
-
wasi_snapshot_preview1: wasiCallbacks,
|
|
1319
|
-
wasi_unstable: wasiCallbacks,
|
|
1320
|
-
};
|
|
1321
|
-
if (WebAssembly.instantiate) {
|
|
1322
|
-
workerConsoleLog("WebAssembly.instantiate");
|
|
1323
|
-
const instance = await WebAssembly.instantiate(module, moduleImports);
|
|
1324
|
-
wasiCallbacks.setModuleInstance(instance);
|
|
1325
|
-
try {
|
|
1326
|
-
// @ts-ignore
|
|
1327
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
1328
|
-
instance.exports._start();
|
|
1329
|
-
doExit(0);
|
|
1330
|
-
}
|
|
1331
|
-
catch (error) {
|
|
1332
|
-
workerConsoleLog(`error: ${error}`);
|
|
1333
|
-
doExit(255);
|
|
1334
|
-
}
|
|
1335
|
-
}
|
|
1336
|
-
else {
|
|
1337
|
-
workerConsoleLog("WebAssembly.instantiate is not supported");
|
|
1338
|
-
}
|
|
1339
|
-
}
|
|
1340
|
-
async function start_wasm() {
|
|
1341
|
-
if (started && mod) {
|
|
1342
|
-
workerConsoleLog("Loading a module");
|
|
1343
|
-
try {
|
|
1344
|
-
await importWasmModule(mod, WASI);
|
|
1345
|
-
}
|
|
1346
|
-
catch (err) {
|
|
1347
|
-
workerConsoleLog(`Failed instantiating WASM module: ${err}`);
|
|
1348
|
-
doExit(255);
|
|
1349
|
-
}
|
|
1350
|
-
workerConsoleLog("done.");
|
|
1351
|
-
}
|
|
1352
|
-
else {
|
|
1353
|
-
setTimeout(() => {
|
|
1354
|
-
start_wasm();
|
|
1355
|
-
}, 0);
|
|
1356
|
-
}
|
|
1357
|
-
}
|