@tybys/wasm-util 0.4.0 → 0.5.0
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/README.md +2 -2
- package/dist/wasm-util.d.ts +25 -8
- package/dist/wasm-util.esm-bundler.js +977 -429
- package/dist/wasm-util.esm.js +977 -429
- package/dist/wasm-util.esm.min.js +1 -1
- package/dist/wasm-util.js +978 -428
- package/dist/wasm-util.min.js +1 -1
- package/lib/cjs/asyncify.js +22 -18
- package/lib/cjs/load.js +33 -32
- package/lib/cjs/wasi/fd.js +57 -15
- package/lib/cjs/wasi/index.js +90 -59
- package/lib/cjs/wasi/preview1.js +684 -209
- package/lib/mjs/asyncify.mjs +22 -18
- package/lib/mjs/load.mjs +30 -31
- package/lib/mjs/wasi/fd.mjs +53 -13
- package/lib/mjs/wasi/index.mjs +91 -60
- package/lib/mjs/wasi/preview1.mjs +685 -210
- package/package.json +1 -1
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { _WebAssembly } from "../webassembly.mjs";
|
|
2
2
|
import { resolve } from "./path.mjs";
|
|
3
3
|
import { WasiErrno, WasiRights, FileControlFlag, WasiFileControlFlag, WasiFdFlag, WasiFileType, WasiClockid, WasiFstFlag } from "./types.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { concatBuffer, toFileStat, AsyncTable, SyncTable } from "./fd.mjs";
|
|
5
5
|
import { WasiError } from "./error.mjs";
|
|
6
6
|
import { isPromiseLike } from "./util.mjs";
|
|
7
7
|
import { getRights } from "./rights.mjs";
|
|
8
8
|
import { extendMemory } from "../memory.mjs";
|
|
9
|
+
import { wrapAsyncImport } from "../jspi.mjs";
|
|
9
10
|
function copyMemory(targets, src) {
|
|
10
11
|
if (targets.length === 0 || src.length === 0)
|
|
11
12
|
return 0;
|
|
@@ -64,7 +65,7 @@ function defineName(name, f) {
|
|
|
64
65
|
Object.defineProperty(f, 'name', { value: name });
|
|
65
66
|
return f;
|
|
66
67
|
}
|
|
67
|
-
function syscallWrap(name, f) {
|
|
68
|
+
function syscallWrap(self, name, f) {
|
|
68
69
|
return defineName(name, function () {
|
|
69
70
|
if (process.env.NODE_DEBUG_NATIVE === 'wasi') {
|
|
70
71
|
const args = Array.prototype.slice.call(arguments);
|
|
@@ -74,7 +75,7 @@ function syscallWrap(name, f) {
|
|
|
74
75
|
}
|
|
75
76
|
let r;
|
|
76
77
|
try {
|
|
77
|
-
r = f.apply(
|
|
78
|
+
r = f.apply(self, arguments);
|
|
78
79
|
}
|
|
79
80
|
catch (err) {
|
|
80
81
|
return handleError(err);
|
|
@@ -85,7 +86,7 @@ function syscallWrap(name, f) {
|
|
|
85
86
|
return r;
|
|
86
87
|
});
|
|
87
88
|
}
|
|
88
|
-
function
|
|
89
|
+
function resolvePathSync(fs, fileDescriptor, path, flags) {
|
|
89
90
|
let resolvedPath = resolve(fileDescriptor.realPath, path);
|
|
90
91
|
if ((flags & 1) === 1) {
|
|
91
92
|
try {
|
|
@@ -99,6 +100,20 @@ function resolvePath(fs, fileDescriptor, path, flags) {
|
|
|
99
100
|
}
|
|
100
101
|
return resolvedPath;
|
|
101
102
|
}
|
|
103
|
+
async function resolvePathAsync(fs, fileDescriptor, path, flags) {
|
|
104
|
+
let resolvedPath = resolve(fileDescriptor.realPath, path);
|
|
105
|
+
if ((flags & 1) === 1) {
|
|
106
|
+
try {
|
|
107
|
+
resolvedPath = await fs.promises.readlink(resolvedPath);
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
if (err.code !== 'EINVAL' && err.code !== 'ENOENT') {
|
|
111
|
+
throw err;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return resolvedPath;
|
|
116
|
+
}
|
|
102
117
|
const encoder = new TextEncoder();
|
|
103
118
|
const decoder = new TextDecoder();
|
|
104
119
|
function readStdin() {
|
|
@@ -109,14 +124,8 @@ function readStdin() {
|
|
|
109
124
|
return buffer;
|
|
110
125
|
}
|
|
111
126
|
export class WASI {
|
|
112
|
-
constructor(args, env,
|
|
113
|
-
this.
|
|
114
|
-
if (!(m instanceof _WebAssembly.Memory)) {
|
|
115
|
-
throw new TypeError('"instance.exports.memory" property must be a WebAssembly.Memory');
|
|
116
|
-
}
|
|
117
|
-
_memory.set(this, extendMemory(m));
|
|
118
|
-
};
|
|
119
|
-
this.args_get = syscallWrap('args_get', function (argv, argv_buf) {
|
|
127
|
+
constructor(args, env, fds, asyncFs, fs, asyncify) {
|
|
128
|
+
this.args_get = syscallWrap(this, 'args_get', function (argv, argv_buf) {
|
|
120
129
|
argv = Number(argv);
|
|
121
130
|
argv_buf = Number(argv_buf);
|
|
122
131
|
if (argv === 0 || argv_buf === 0) {
|
|
@@ -135,7 +144,7 @@ export class WASI {
|
|
|
135
144
|
}
|
|
136
145
|
return WasiErrno.ESUCCESS;
|
|
137
146
|
});
|
|
138
|
-
this.args_sizes_get = syscallWrap('args_sizes_get', function (argc, argv_buf_size) {
|
|
147
|
+
this.args_sizes_get = syscallWrap(this, 'args_sizes_get', function (argc, argv_buf_size) {
|
|
139
148
|
argc = Number(argc);
|
|
140
149
|
argv_buf_size = Number(argv_buf_size);
|
|
141
150
|
if (argc === 0 || argv_buf_size === 0) {
|
|
@@ -148,7 +157,7 @@ export class WASI {
|
|
|
148
157
|
view.setUint32(argv_buf_size, encoder.encode(args.join('\0') + '\0').length, true);
|
|
149
158
|
return WasiErrno.ESUCCESS;
|
|
150
159
|
});
|
|
151
|
-
this.environ_get = syscallWrap('environ_get', function (environ, environ_buf) {
|
|
160
|
+
this.environ_get = syscallWrap(this, 'environ_get', function (environ, environ_buf) {
|
|
152
161
|
environ = Number(environ);
|
|
153
162
|
environ_buf = Number(environ_buf);
|
|
154
163
|
if (environ === 0 || environ_buf === 0) {
|
|
@@ -167,7 +176,7 @@ export class WASI {
|
|
|
167
176
|
}
|
|
168
177
|
return WasiErrno.ESUCCESS;
|
|
169
178
|
});
|
|
170
|
-
this.environ_sizes_get = syscallWrap('environ_sizes_get', function (len, buflen) {
|
|
179
|
+
this.environ_sizes_get = syscallWrap(this, 'environ_sizes_get', function (len, buflen) {
|
|
171
180
|
len = Number(len);
|
|
172
181
|
buflen = Number(buflen);
|
|
173
182
|
if (len === 0 || buflen === 0) {
|
|
@@ -179,7 +188,7 @@ export class WASI {
|
|
|
179
188
|
view.setUint32(buflen, encoder.encode(wasi.env.join('\0') + '\0').length, true);
|
|
180
189
|
return WasiErrno.ESUCCESS;
|
|
181
190
|
});
|
|
182
|
-
this.clock_res_get = syscallWrap('clock_res_get', function (id, resolution) {
|
|
191
|
+
this.clock_res_get = syscallWrap(this, 'clock_res_get', function (id, resolution) {
|
|
183
192
|
resolution = Number(resolution);
|
|
184
193
|
if (resolution === 0) {
|
|
185
194
|
return WasiErrno.EINVAL;
|
|
@@ -197,7 +206,7 @@ export class WASI {
|
|
|
197
206
|
default: return WasiErrno.EINVAL;
|
|
198
207
|
}
|
|
199
208
|
});
|
|
200
|
-
this.clock_time_get = syscallWrap('clock_time_get', function (id, _percision, time) {
|
|
209
|
+
this.clock_time_get = syscallWrap(this, 'clock_time_get', function (id, _percision, time) {
|
|
201
210
|
time = Number(time);
|
|
202
211
|
if (time === 0) {
|
|
203
212
|
return WasiErrno.EINVAL;
|
|
@@ -220,35 +229,10 @@ export class WASI {
|
|
|
220
229
|
default: return WasiErrno.EINVAL;
|
|
221
230
|
}
|
|
222
231
|
});
|
|
223
|
-
this.fd_advise = syscallWrap('fd_advise', function (_fd, _offset, _len, _advice) {
|
|
232
|
+
this.fd_advise = syscallWrap(this, 'fd_advise', function (_fd, _offset, _len, _advice) {
|
|
224
233
|
return WasiErrno.ENOSYS;
|
|
225
234
|
});
|
|
226
|
-
this.
|
|
227
|
-
const wasi = _wasi.get(this);
|
|
228
|
-
const fs = getFs(this);
|
|
229
|
-
const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_ALLOCATE, BigInt(0));
|
|
230
|
-
const stat = fs.fstatSync(fileDescriptor.fd, { bigint: true });
|
|
231
|
-
if (stat.size < offset + len) {
|
|
232
|
-
fs.ftruncateSync(fileDescriptor.fd, Number(offset + len));
|
|
233
|
-
}
|
|
234
|
-
return WasiErrno.ESUCCESS;
|
|
235
|
-
});
|
|
236
|
-
this.fd_close = syscallWrap('fd_close', function (fd) {
|
|
237
|
-
const wasi = _wasi.get(this);
|
|
238
|
-
const fileDescriptor = wasi.fds.get(fd, BigInt(0), BigInt(0));
|
|
239
|
-
const fs = getFs(this);
|
|
240
|
-
fs.closeSync(fileDescriptor.fd);
|
|
241
|
-
wasi.fds.remove(fd);
|
|
242
|
-
return WasiErrno.ESUCCESS;
|
|
243
|
-
});
|
|
244
|
-
this.fd_datasync = syscallWrap('fd_datasync', function (fd) {
|
|
245
|
-
const wasi = _wasi.get(this);
|
|
246
|
-
const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_DATASYNC, BigInt(0));
|
|
247
|
-
const fs = getFs(this);
|
|
248
|
-
fs.fdatasyncSync(fileDescriptor.fd);
|
|
249
|
-
return WasiErrno.ESUCCESS;
|
|
250
|
-
});
|
|
251
|
-
this.fd_fdstat_get = syscallWrap('fd_fdstat_get', function (fd, fdstat) {
|
|
235
|
+
this.fd_fdstat_get = syscallWrap(this, 'fd_fdstat_get', function (fd, fdstat) {
|
|
252
236
|
fdstat = Number(fdstat);
|
|
253
237
|
if (fdstat === 0) {
|
|
254
238
|
return WasiErrno.EINVAL;
|
|
@@ -262,10 +246,10 @@ export class WASI {
|
|
|
262
246
|
view.setBigUint64(fdstat + 16, fileDescriptor.rightsInheriting, true);
|
|
263
247
|
return WasiErrno.ESUCCESS;
|
|
264
248
|
});
|
|
265
|
-
this.fd_fdstat_set_flags = syscallWrap('fd_fdstat_set_flags', function (_fd, _flags) {
|
|
249
|
+
this.fd_fdstat_set_flags = syscallWrap(this, 'fd_fdstat_set_flags', function (_fd, _flags) {
|
|
266
250
|
return WasiErrno.ENOSYS;
|
|
267
251
|
});
|
|
268
|
-
this.fd_fdstat_set_rights = syscallWrap('fd_fdstat_set_rights', function (fd, rightsBase, rightsInheriting) {
|
|
252
|
+
this.fd_fdstat_set_rights = syscallWrap(this, 'fd_fdstat_set_rights', function (fd, rightsBase, rightsInheriting) {
|
|
269
253
|
const wasi = _wasi.get(this);
|
|
270
254
|
const fileDescriptor = wasi.fds.get(fd, BigInt(0), BigInt(0));
|
|
271
255
|
if ((rightsBase | fileDescriptor.rightsBase) > fileDescriptor.rightsBase) {
|
|
@@ -279,7 +263,186 @@ export class WASI {
|
|
|
279
263
|
fileDescriptor.rightsInheriting = rightsInheriting;
|
|
280
264
|
return WasiErrno.ESUCCESS;
|
|
281
265
|
});
|
|
282
|
-
this.
|
|
266
|
+
this.fd_prestat_get = syscallWrap(this, 'fd_prestat_get', function (fd, prestat) {
|
|
267
|
+
prestat = Number(prestat);
|
|
268
|
+
if (prestat === 0) {
|
|
269
|
+
return WasiErrno.EINVAL;
|
|
270
|
+
}
|
|
271
|
+
const wasi = _wasi.get(this);
|
|
272
|
+
let fileDescriptor;
|
|
273
|
+
try {
|
|
274
|
+
fileDescriptor = wasi.fds.get(fd, BigInt(0), BigInt(0));
|
|
275
|
+
}
|
|
276
|
+
catch (err) {
|
|
277
|
+
if (err instanceof WasiError)
|
|
278
|
+
return err.errno;
|
|
279
|
+
throw err;
|
|
280
|
+
}
|
|
281
|
+
if (fileDescriptor.preopen !== 1)
|
|
282
|
+
return WasiErrno.EINVAL;
|
|
283
|
+
const { view } = getMemory(this);
|
|
284
|
+
// preopen type is dir(0)
|
|
285
|
+
view.setUint32(prestat, 0, true);
|
|
286
|
+
view.setUint32(prestat + 4, encoder.encode(fileDescriptor.path).length + 1, true);
|
|
287
|
+
return WasiErrno.ESUCCESS;
|
|
288
|
+
});
|
|
289
|
+
this.fd_prestat_dir_name = syscallWrap(this, 'fd_prestat_dir_name', function (fd, path, path_len) {
|
|
290
|
+
path = Number(path);
|
|
291
|
+
path_len = Number(path_len);
|
|
292
|
+
if (path === 0) {
|
|
293
|
+
return WasiErrno.EINVAL;
|
|
294
|
+
}
|
|
295
|
+
const wasi = _wasi.get(this);
|
|
296
|
+
const fileDescriptor = wasi.fds.get(fd, BigInt(0), BigInt(0));
|
|
297
|
+
if (fileDescriptor.preopen !== 1)
|
|
298
|
+
return WasiErrno.EBADF;
|
|
299
|
+
const buffer = encoder.encode(fileDescriptor.path + '\0');
|
|
300
|
+
const size = buffer.length;
|
|
301
|
+
if (size > path_len)
|
|
302
|
+
return WasiErrno.ENOBUFS;
|
|
303
|
+
const { HEAPU8 } = getMemory(this);
|
|
304
|
+
HEAPU8.set(buffer, path);
|
|
305
|
+
return WasiErrno.ESUCCESS;
|
|
306
|
+
});
|
|
307
|
+
this.fd_seek = syscallWrap(this, 'fd_seek', function (fd, offset, whence, newOffset) {
|
|
308
|
+
newOffset = Number(newOffset);
|
|
309
|
+
if (newOffset === 0) {
|
|
310
|
+
return WasiErrno.EINVAL;
|
|
311
|
+
}
|
|
312
|
+
if (fd === 0 || fd === 1 || fd === 2)
|
|
313
|
+
return WasiErrno.ESUCCESS;
|
|
314
|
+
const wasi = _wasi.get(this);
|
|
315
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_SEEK, BigInt(0));
|
|
316
|
+
const r = fileDescriptor.seek(offset, whence);
|
|
317
|
+
const { view } = getMemory(this);
|
|
318
|
+
view.setBigUint64(newOffset, r, true);
|
|
319
|
+
return WasiErrno.ESUCCESS;
|
|
320
|
+
});
|
|
321
|
+
this.fd_tell = syscallWrap(this, 'fd_tell', function (fd, offset) {
|
|
322
|
+
const wasi = _wasi.get(this);
|
|
323
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_TELL, BigInt(0));
|
|
324
|
+
const pos = BigInt(fileDescriptor.pos);
|
|
325
|
+
const { view } = getMemory(this);
|
|
326
|
+
view.setBigUint64(Number(offset), pos, true);
|
|
327
|
+
return WasiErrno.ESUCCESS;
|
|
328
|
+
});
|
|
329
|
+
this.poll_oneoff = syscallWrap(this, 'poll_oneoff', function (_in, _out, _sub, _nevents) {
|
|
330
|
+
return WasiErrno.ENOSYS;
|
|
331
|
+
});
|
|
332
|
+
this.proc_exit = syscallWrap(this, 'proc_exit', function (_rval) {
|
|
333
|
+
return WasiErrno.ESUCCESS;
|
|
334
|
+
});
|
|
335
|
+
this.proc_raise = syscallWrap(this, 'proc_raise', function (_sig) {
|
|
336
|
+
return WasiErrno.ENOSYS;
|
|
337
|
+
});
|
|
338
|
+
this.sched_yield = syscallWrap(this, 'sched_yield', function () {
|
|
339
|
+
return WasiErrno.ESUCCESS;
|
|
340
|
+
});
|
|
341
|
+
this.random_get = typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function'
|
|
342
|
+
? syscallWrap(this, 'random_get', function (buf, buf_len) {
|
|
343
|
+
buf = Number(buf);
|
|
344
|
+
if (buf === 0) {
|
|
345
|
+
return WasiErrno.EINVAL;
|
|
346
|
+
}
|
|
347
|
+
buf_len = Number(buf_len);
|
|
348
|
+
const { HEAPU8 } = getMemory(this);
|
|
349
|
+
let pos;
|
|
350
|
+
const stride = 65536;
|
|
351
|
+
for (pos = 0; pos + stride < buf_len; pos += stride) {
|
|
352
|
+
crypto.getRandomValues(HEAPU8.subarray(buf + pos, buf + pos + stride));
|
|
353
|
+
}
|
|
354
|
+
crypto.getRandomValues(HEAPU8.subarray(buf + pos, buf + buf_len));
|
|
355
|
+
return WasiErrno.ESUCCESS;
|
|
356
|
+
})
|
|
357
|
+
: syscallWrap(this, 'random_get', function (buf, buf_len) {
|
|
358
|
+
buf = Number(buf);
|
|
359
|
+
if (buf === 0) {
|
|
360
|
+
return WasiErrno.EINVAL;
|
|
361
|
+
}
|
|
362
|
+
buf_len = Number(buf_len);
|
|
363
|
+
const { view } = getMemory(this);
|
|
364
|
+
for (let i = buf; i < buf + buf_len; ++i) {
|
|
365
|
+
view.setUint8(i, Math.floor(Math.random() * 256));
|
|
366
|
+
}
|
|
367
|
+
return WasiErrno.ESUCCESS;
|
|
368
|
+
});
|
|
369
|
+
this.sock_recv = syscallWrap(this, 'sock_recv', function () {
|
|
370
|
+
return WasiErrno.ENOTSUP;
|
|
371
|
+
});
|
|
372
|
+
this.sock_send = syscallWrap(this, 'sock_send', function () {
|
|
373
|
+
return WasiErrno.ENOTSUP;
|
|
374
|
+
});
|
|
375
|
+
this.sock_shutdown = syscallWrap(this, 'sock_shutdown', function () {
|
|
376
|
+
return WasiErrno.ENOTSUP;
|
|
377
|
+
});
|
|
378
|
+
_wasi.set(this, {
|
|
379
|
+
fds,
|
|
380
|
+
args,
|
|
381
|
+
env
|
|
382
|
+
});
|
|
383
|
+
if (fs)
|
|
384
|
+
_fs.set(this, fs);
|
|
385
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
386
|
+
const _this = this;
|
|
387
|
+
function defineImport(name, syncVersion, asyncVersion, parameterType, returnType) {
|
|
388
|
+
if (asyncFs) {
|
|
389
|
+
if (asyncify) {
|
|
390
|
+
_this[name] = asyncify.wrapImportFunction(syscallWrap(_this, name, asyncVersion));
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
_this[name] = wrapAsyncImport(syscallWrap(_this, name, asyncVersion), parameterType, returnType);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
_this[name] = syscallWrap(_this, name, syncVersion);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
defineImport('fd_allocate', function fd_allocate(fd, offset, len) {
|
|
401
|
+
const wasi = _wasi.get(this);
|
|
402
|
+
const fs = getFs(this);
|
|
403
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_ALLOCATE, BigInt(0));
|
|
404
|
+
const stat = fs.fstatSync(fileDescriptor.fd, { bigint: true });
|
|
405
|
+
if (stat.size < offset + len) {
|
|
406
|
+
fs.ftruncateSync(fileDescriptor.fd, Number(offset + len));
|
|
407
|
+
}
|
|
408
|
+
return WasiErrno.ESUCCESS;
|
|
409
|
+
}, async function fd_allocate(fd, offset, len) {
|
|
410
|
+
const wasi = _wasi.get(this);
|
|
411
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_ALLOCATE, BigInt(0));
|
|
412
|
+
const h = fileDescriptor.fd;
|
|
413
|
+
const stat = await h.stat({ bigint: true });
|
|
414
|
+
if (stat.size < offset + len) {
|
|
415
|
+
await h.truncate(Number(offset + len));
|
|
416
|
+
}
|
|
417
|
+
return WasiErrno.ESUCCESS;
|
|
418
|
+
}, ['i32', 'i64', 'f64'], ['i32']);
|
|
419
|
+
defineImport('fd_close', function fd_close(fd) {
|
|
420
|
+
const wasi = _wasi.get(this);
|
|
421
|
+
const fileDescriptor = wasi.fds.get(fd, BigInt(0), BigInt(0));
|
|
422
|
+
const fs = getFs(this);
|
|
423
|
+
fs.closeSync(fileDescriptor.fd);
|
|
424
|
+
wasi.fds.remove(fd);
|
|
425
|
+
return WasiErrno.ESUCCESS;
|
|
426
|
+
}, async function fd_close(fd) {
|
|
427
|
+
const wasi = _wasi.get(this);
|
|
428
|
+
const fileDescriptor = wasi.fds.get(fd, BigInt(0), BigInt(0));
|
|
429
|
+
await fileDescriptor.fd.close();
|
|
430
|
+
wasi.fds.remove(fd);
|
|
431
|
+
return WasiErrno.ESUCCESS;
|
|
432
|
+
}, ['i32'], ['i32']);
|
|
433
|
+
defineImport('fd_datasync', function fd_datasync(fd) {
|
|
434
|
+
const wasi = _wasi.get(this);
|
|
435
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_DATASYNC, BigInt(0));
|
|
436
|
+
const fs = getFs(this);
|
|
437
|
+
fs.fdatasyncSync(fileDescriptor.fd);
|
|
438
|
+
return WasiErrno.ESUCCESS;
|
|
439
|
+
}, async function fd_datasync(fd) {
|
|
440
|
+
const wasi = _wasi.get(this);
|
|
441
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_DATASYNC, BigInt(0));
|
|
442
|
+
await fileDescriptor.fd.datasync();
|
|
443
|
+
return WasiErrno.ESUCCESS;
|
|
444
|
+
}, ['i32'], ['i32']);
|
|
445
|
+
defineImport('fd_filestat_get', function fd_filestat_get(fd, buf) {
|
|
283
446
|
buf = Number(buf);
|
|
284
447
|
if (buf === 0)
|
|
285
448
|
return WasiErrno.EINVAL;
|
|
@@ -290,15 +453,32 @@ export class WASI {
|
|
|
290
453
|
const { view } = getMemory(this);
|
|
291
454
|
toFileStat(view, buf, stat);
|
|
292
455
|
return WasiErrno.ESUCCESS;
|
|
293
|
-
})
|
|
294
|
-
|
|
456
|
+
}, async function fd_filestat_get(fd, buf) {
|
|
457
|
+
buf = Number(buf);
|
|
458
|
+
if (buf === 0)
|
|
459
|
+
return WasiErrno.EINVAL;
|
|
460
|
+
const wasi = _wasi.get(this);
|
|
461
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_FILESTAT_GET, BigInt(0));
|
|
462
|
+
const h = fileDescriptor.fd;
|
|
463
|
+
const stat = await h.stat({ bigint: true });
|
|
464
|
+
const { view } = getMemory(this);
|
|
465
|
+
toFileStat(view, buf, stat);
|
|
466
|
+
return WasiErrno.ESUCCESS;
|
|
467
|
+
}, ['i32', 'i32'], ['i32']);
|
|
468
|
+
defineImport('fd_filestat_set_size', function fd_filestat_set_size(fd, size) {
|
|
295
469
|
const wasi = _wasi.get(this);
|
|
296
470
|
const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_FILESTAT_SET_SIZE, BigInt(0));
|
|
297
471
|
const fs = getFs(this);
|
|
298
472
|
fs.ftruncateSync(fileDescriptor.fd, Number(size));
|
|
299
473
|
return WasiErrno.ESUCCESS;
|
|
300
|
-
})
|
|
301
|
-
|
|
474
|
+
}, async function fd_filestat_set_size(fd, size) {
|
|
475
|
+
const wasi = _wasi.get(this);
|
|
476
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_FILESTAT_SET_SIZE, BigInt(0));
|
|
477
|
+
const h = fileDescriptor.fd;
|
|
478
|
+
await h.truncate(Number(size));
|
|
479
|
+
return WasiErrno.ESUCCESS;
|
|
480
|
+
}, ['i32', 'i64'], ['i32']);
|
|
481
|
+
function fdFilestatGetTimes(fd, atim, mtim, flags) {
|
|
302
482
|
const wasi = _wasi.get(this);
|
|
303
483
|
const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_FILESTAT_SET_TIMES, BigInt(0));
|
|
304
484
|
if ((flags & WasiFstFlag.SET_ATIM_NOW) === WasiFstFlag.SET_ATIM_NOW) {
|
|
@@ -307,11 +487,20 @@ export class WASI {
|
|
|
307
487
|
if ((flags & WasiFstFlag.SET_MTIM_NOW) === WasiFstFlag.SET_MTIM_NOW) {
|
|
308
488
|
mtim = BigInt(Date.now() * 1000000);
|
|
309
489
|
}
|
|
490
|
+
return { fileDescriptor, atim, mtim };
|
|
491
|
+
}
|
|
492
|
+
defineImport('fd_filestat_set_times', function fd_filestat_set_times(fd, atim, mtim, flags) {
|
|
493
|
+
const { fileDescriptor, atim: atimRes, mtim: mtimRes } = fdFilestatGetTimes.call(this, fd, atim, mtim, flags);
|
|
310
494
|
const fs = getFs(this);
|
|
311
|
-
fs.futimesSync(fileDescriptor.fd, Number(
|
|
495
|
+
fs.futimesSync(fileDescriptor.fd, Number(atimRes), Number(mtimRes));
|
|
312
496
|
return WasiErrno.ESUCCESS;
|
|
313
|
-
})
|
|
314
|
-
|
|
497
|
+
}, async function fd_filestat_set_times(fd, atim, mtim, flags) {
|
|
498
|
+
const { fileDescriptor, atim: atimRes, mtim: mtimRes } = fdFilestatGetTimes.call(this, fd, atim, mtim, flags);
|
|
499
|
+
const h = fileDescriptor.fd;
|
|
500
|
+
await h.utimes(Number(atimRes), Number(mtimRes));
|
|
501
|
+
return WasiErrno.ESUCCESS;
|
|
502
|
+
}, ['i32', 'i64', 'i64', 'i32'], ['i32']);
|
|
503
|
+
defineImport('fd_pread', function fd_pread(fd, iovs, iovslen, offset, size) {
|
|
315
504
|
iovs = Number(iovs);
|
|
316
505
|
size = Number(size);
|
|
317
506
|
if (iovs === 0 || size === 0) {
|
|
@@ -336,49 +525,51 @@ export class WASI {
|
|
|
336
525
|
nread = buffer ? copyMemory(ioVecs, buffer.subarray(0, bytesRead)) : 0;
|
|
337
526
|
view.setUint32(size, nread, true);
|
|
338
527
|
return WasiErrno.ESUCCESS;
|
|
339
|
-
})
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
if (
|
|
528
|
+
}, async function (fd, iovs, iovslen, offset, size) {
|
|
529
|
+
iovs = Number(iovs);
|
|
530
|
+
size = Number(size);
|
|
531
|
+
if (iovs === 0 || size === 0) {
|
|
343
532
|
return WasiErrno.EINVAL;
|
|
344
533
|
}
|
|
534
|
+
const { HEAPU8, view } = getMemory(this);
|
|
345
535
|
const wasi = _wasi.get(this);
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
view.setUint32(
|
|
536
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_READ | WasiRights.FD_SEEK, BigInt(0));
|
|
537
|
+
let totalSize = 0;
|
|
538
|
+
const ioVecs = Array.from({ length: Number(iovslen) }, (_, i) => {
|
|
539
|
+
const offset = iovs + (i * 8);
|
|
540
|
+
const buf = view.getInt32(offset, true);
|
|
541
|
+
const bufLen = view.getUint32(offset + 4, true);
|
|
542
|
+
totalSize += bufLen;
|
|
543
|
+
return HEAPU8.subarray(buf, buf + bufLen);
|
|
544
|
+
});
|
|
545
|
+
let nread = 0;
|
|
546
|
+
const buffer = new Uint8Array(totalSize);
|
|
547
|
+
buffer._isBuffer = true;
|
|
548
|
+
const { bytesRead } = await fileDescriptor.fd.read(buffer, 0, buffer.length, Number(offset));
|
|
549
|
+
nread = buffer ? copyMemory(ioVecs, buffer.subarray(0, bytesRead)) : 0;
|
|
550
|
+
view.setUint32(size, nread, true);
|
|
361
551
|
return WasiErrno.ESUCCESS;
|
|
362
|
-
});
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
if (
|
|
552
|
+
}, ['i32', 'i32', 'i32', 'i64', 'i32'], ['i32']);
|
|
553
|
+
defineImport('fd_pwrite', function fd_pwrite(fd, iovs, iovslen, offset, size) {
|
|
554
|
+
iovs = Number(iovs);
|
|
555
|
+
size = Number(size);
|
|
556
|
+
if (iovs === 0 || size === 0) {
|
|
367
557
|
return WasiErrno.EINVAL;
|
|
368
558
|
}
|
|
559
|
+
const { HEAPU8, view } = getMemory(this);
|
|
369
560
|
const wasi = _wasi.get(this);
|
|
370
|
-
const fileDescriptor = wasi.fds.get(fd,
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
const
|
|
378
|
-
|
|
561
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_WRITE | WasiRights.FD_SEEK, BigInt(0));
|
|
562
|
+
const buffer = concatBuffer(Array.from({ length: Number(iovslen) }, (_, i) => {
|
|
563
|
+
const offset = iovs + (i * 8);
|
|
564
|
+
const buf = view.getInt32(offset, true);
|
|
565
|
+
const bufLen = view.getUint32(offset + 4, true);
|
|
566
|
+
return HEAPU8.subarray(buf, buf + bufLen);
|
|
567
|
+
}));
|
|
568
|
+
const fs = getFs(this);
|
|
569
|
+
const nwritten = fs.writeSync(fileDescriptor.fd, buffer, 0, buffer.length, Number(offset));
|
|
570
|
+
view.setUint32(size, nwritten, true);
|
|
379
571
|
return WasiErrno.ESUCCESS;
|
|
380
|
-
})
|
|
381
|
-
this.fd_pwrite = syscallWrap('fd_pwrite', function (fd, iovs, iovslen, offset, size) {
|
|
572
|
+
}, async function fd_pwrite(fd, iovs, iovslen, offset, size) {
|
|
382
573
|
iovs = Number(iovs);
|
|
383
574
|
size = Number(size);
|
|
384
575
|
if (iovs === 0 || size === 0) {
|
|
@@ -393,12 +584,11 @@ export class WASI {
|
|
|
393
584
|
const bufLen = view.getUint32(offset + 4, true);
|
|
394
585
|
return HEAPU8.subarray(buf, buf + bufLen);
|
|
395
586
|
}));
|
|
396
|
-
const
|
|
397
|
-
|
|
398
|
-
view.setUint32(size, nwritten, true);
|
|
587
|
+
const { bytesWritten } = await fileDescriptor.fd.write(buffer, 0, buffer.length, Number(offset));
|
|
588
|
+
view.setUint32(size, bytesWritten, true);
|
|
399
589
|
return WasiErrno.ESUCCESS;
|
|
400
|
-
});
|
|
401
|
-
|
|
590
|
+
}, ['i32', 'i32', 'i32', 'i64', 'i32'], ['i32']);
|
|
591
|
+
defineImport('fd_read', function fd_read(fd, iovs, iovslen, size) {
|
|
402
592
|
iovs = Number(iovs);
|
|
403
593
|
size = Number(size);
|
|
404
594
|
if (iovs === 0 || size === 0) {
|
|
@@ -434,22 +624,43 @@ export class WASI {
|
|
|
434
624
|
}
|
|
435
625
|
view.setUint32(size, nread, true);
|
|
436
626
|
return WasiErrno.ESUCCESS;
|
|
437
|
-
})
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
if (
|
|
627
|
+
}, async function fd_read(fd, iovs, iovslen, size) {
|
|
628
|
+
iovs = Number(iovs);
|
|
629
|
+
size = Number(size);
|
|
630
|
+
if (iovs === 0 || size === 0) {
|
|
441
631
|
return WasiErrno.EINVAL;
|
|
442
632
|
}
|
|
443
|
-
|
|
444
|
-
return WasiErrno.ESUCCESS;
|
|
633
|
+
const { HEAPU8, view } = getMemory(this);
|
|
445
634
|
const wasi = _wasi.get(this);
|
|
446
|
-
const fileDescriptor = wasi.fds.get(fd, WasiRights.
|
|
447
|
-
|
|
448
|
-
const {
|
|
449
|
-
|
|
635
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_READ, BigInt(0));
|
|
636
|
+
let totalSize = 0;
|
|
637
|
+
const ioVecs = Array.from({ length: Number(iovslen) }, (_, i) => {
|
|
638
|
+
const offset = iovs + (i * 8);
|
|
639
|
+
const buf = view.getInt32(offset, true);
|
|
640
|
+
const bufLen = view.getUint32(offset + 4, true);
|
|
641
|
+
totalSize += bufLen;
|
|
642
|
+
return HEAPU8.subarray(buf, buf + bufLen);
|
|
643
|
+
});
|
|
644
|
+
let buffer;
|
|
645
|
+
let nread = 0;
|
|
646
|
+
if (fd === 0) {
|
|
647
|
+
if (typeof window === 'undefined' || typeof window.prompt !== 'function') {
|
|
648
|
+
return WasiErrno.ENOTSUP;
|
|
649
|
+
}
|
|
650
|
+
buffer = readStdin();
|
|
651
|
+
nread = buffer ? copyMemory(ioVecs, buffer) : 0;
|
|
652
|
+
}
|
|
653
|
+
else {
|
|
654
|
+
buffer = new Uint8Array(totalSize);
|
|
655
|
+
buffer._isBuffer = true;
|
|
656
|
+
const { bytesRead } = await fileDescriptor.fd.read(buffer, 0, buffer.length, Number(fileDescriptor.pos));
|
|
657
|
+
nread = buffer ? copyMemory(ioVecs, buffer.subarray(0, bytesRead)) : 0;
|
|
658
|
+
fileDescriptor.pos += BigInt(nread);
|
|
659
|
+
}
|
|
660
|
+
view.setUint32(size, nread, true);
|
|
450
661
|
return WasiErrno.ESUCCESS;
|
|
451
|
-
});
|
|
452
|
-
|
|
662
|
+
}, ['i32', 'i32', 'i32', 'i32'], ['i32']);
|
|
663
|
+
defineImport('fd_readdir', function fd_readdir(fd, buf, buf_len, cookie, bufused) {
|
|
453
664
|
buf = Number(buf);
|
|
454
665
|
buf_len = Number(buf_len);
|
|
455
666
|
bufused = Number(bufused);
|
|
@@ -499,28 +710,79 @@ export class WASI {
|
|
|
499
710
|
}
|
|
500
711
|
view.setUint32(bufused, bufferUsed, true);
|
|
501
712
|
return WasiErrno.ESUCCESS;
|
|
502
|
-
})
|
|
503
|
-
|
|
713
|
+
}, async function fd_readdir(fd, buf, buf_len, cookie, bufused) {
|
|
714
|
+
buf = Number(buf);
|
|
715
|
+
buf_len = Number(buf_len);
|
|
716
|
+
bufused = Number(bufused);
|
|
717
|
+
if (buf === 0 || bufused === 0)
|
|
718
|
+
return WasiErrno.ESUCCESS;
|
|
719
|
+
const wasi = _wasi.get(this);
|
|
720
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_READDIR, BigInt(0));
|
|
721
|
+
const fs = getFs(this);
|
|
722
|
+
const entries = await fs.promises.readdir(fileDescriptor.realPath, { withFileTypes: true });
|
|
723
|
+
const { HEAPU8, view } = getMemory(this);
|
|
724
|
+
let bufferUsed = 0;
|
|
725
|
+
for (let i = Number(cookie); i < entries.length; i++) {
|
|
726
|
+
const nameData = encoder.encode(entries[i].name);
|
|
727
|
+
const entryInfo = await fs.promises.stat(resolve(fileDescriptor.realPath, entries[i].name), { bigint: true });
|
|
728
|
+
const entryData = new Uint8Array(24 + nameData.byteLength);
|
|
729
|
+
const entryView = new DataView(entryData.buffer);
|
|
730
|
+
entryView.setBigUint64(0, BigInt(i + 1), true);
|
|
731
|
+
entryView.setBigUint64(8, BigInt(entryInfo.ino ? entryInfo.ino : 0), true);
|
|
732
|
+
entryView.setUint32(16, nameData.byteLength, true);
|
|
733
|
+
let type;
|
|
734
|
+
if (entries[i].isFile()) {
|
|
735
|
+
type = WasiFileType.REGULAR_FILE;
|
|
736
|
+
}
|
|
737
|
+
else if (entries[i].isDirectory()) {
|
|
738
|
+
type = WasiFileType.DIRECTORY;
|
|
739
|
+
}
|
|
740
|
+
else if (entries[i].isSymbolicLink()) {
|
|
741
|
+
type = WasiFileType.SYMBOLIC_LINK;
|
|
742
|
+
}
|
|
743
|
+
else if (entries[i].isCharacterDevice()) {
|
|
744
|
+
type = WasiFileType.CHARACTER_DEVICE;
|
|
745
|
+
}
|
|
746
|
+
else if (entries[i].isBlockDevice()) {
|
|
747
|
+
type = WasiFileType.BLOCK_DEVICE;
|
|
748
|
+
}
|
|
749
|
+
else if (entries[i].isSocket()) {
|
|
750
|
+
type = WasiFileType.SOCKET_STREAM;
|
|
751
|
+
}
|
|
752
|
+
else {
|
|
753
|
+
type = WasiFileType.UNKNOWN;
|
|
754
|
+
}
|
|
755
|
+
entryView.setUint8(20, type);
|
|
756
|
+
entryData.set(nameData, 24);
|
|
757
|
+
const data = entryData.slice(0, Math.min(entryData.length, buf_len - bufferUsed));
|
|
758
|
+
HEAPU8.set(data, buf + bufferUsed);
|
|
759
|
+
bufferUsed += data.byteLength;
|
|
760
|
+
}
|
|
761
|
+
view.setUint32(bufused, bufferUsed, true);
|
|
762
|
+
return WasiErrno.ESUCCESS;
|
|
763
|
+
}, ['i32', 'i32', 'i32', 'i64', 'i32'], ['i32']);
|
|
764
|
+
defineImport('fd_renumber', function fd_renumber(from, to) {
|
|
504
765
|
const wasi = _wasi.get(this);
|
|
505
766
|
wasi.fds.renumber(to, from);
|
|
506
767
|
return WasiErrno.ESUCCESS;
|
|
507
|
-
})
|
|
508
|
-
|
|
768
|
+
}, async function fd_renumber(from, to) {
|
|
769
|
+
const wasi = _wasi.get(this);
|
|
770
|
+
await wasi.fds.renumber(to, from);
|
|
771
|
+
return WasiErrno.ESUCCESS;
|
|
772
|
+
}, ['i32', 'i32'], ['i32']);
|
|
773
|
+
defineImport('fd_sync', function fd_sync(fd) {
|
|
509
774
|
const wasi = _wasi.get(this);
|
|
510
775
|
const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_SYNC, BigInt(0));
|
|
511
776
|
const fs = getFs(this);
|
|
512
777
|
fs.fsyncSync(fileDescriptor.fd);
|
|
513
778
|
return WasiErrno.ESUCCESS;
|
|
514
|
-
})
|
|
515
|
-
this.fd_tell = syscallWrap('fd_tell', function (fd, offset) {
|
|
779
|
+
}, async function fd_sync(fd) {
|
|
516
780
|
const wasi = _wasi.get(this);
|
|
517
|
-
const fileDescriptor = wasi.fds.get(fd, WasiRights.
|
|
518
|
-
|
|
519
|
-
const { view } = getMemory(this);
|
|
520
|
-
view.setBigUint64(Number(offset), pos, true);
|
|
781
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_SYNC, BigInt(0));
|
|
782
|
+
await fileDescriptor.fd.sync();
|
|
521
783
|
return WasiErrno.ESUCCESS;
|
|
522
|
-
});
|
|
523
|
-
|
|
784
|
+
}, ['i32'], ['i32']);
|
|
785
|
+
defineImport('fd_write', function fd_write(fd, iovs, iovslen, size) {
|
|
524
786
|
iovs = Number(iovs);
|
|
525
787
|
size = Number(size);
|
|
526
788
|
if (iovs === 0 || size === 0) {
|
|
@@ -546,8 +808,47 @@ export class WASI {
|
|
|
546
808
|
}
|
|
547
809
|
view.setUint32(size, nwritten, true);
|
|
548
810
|
return WasiErrno.ESUCCESS;
|
|
549
|
-
})
|
|
550
|
-
|
|
811
|
+
}, async function fd_write(fd, iovs, iovslen, size) {
|
|
812
|
+
iovs = Number(iovs);
|
|
813
|
+
size = Number(size);
|
|
814
|
+
if (iovs === 0 || size === 0) {
|
|
815
|
+
return WasiErrno.EINVAL;
|
|
816
|
+
}
|
|
817
|
+
const { HEAPU8, view } = getMemory(this);
|
|
818
|
+
const wasi = _wasi.get(this);
|
|
819
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_WRITE, BigInt(0));
|
|
820
|
+
const buffer = concatBuffer(Array.from({ length: Number(iovslen) }, (_, i) => {
|
|
821
|
+
const offset = iovs + (i * 8);
|
|
822
|
+
const buf = view.getInt32(offset, true);
|
|
823
|
+
const bufLen = view.getUint32(offset + 4, true);
|
|
824
|
+
return HEAPU8.subarray(buf, buf + bufLen);
|
|
825
|
+
}));
|
|
826
|
+
let nwritten;
|
|
827
|
+
if (fd === 1 || fd === 2) {
|
|
828
|
+
nwritten = fileDescriptor.write(buffer);
|
|
829
|
+
}
|
|
830
|
+
else {
|
|
831
|
+
nwritten = await (await (fileDescriptor.fd.write(buffer, 0, buffer.length, Number(fileDescriptor.pos)))).bytesWritten;
|
|
832
|
+
fileDescriptor.pos += BigInt(nwritten);
|
|
833
|
+
}
|
|
834
|
+
view.setUint32(size, nwritten, true);
|
|
835
|
+
return WasiErrno.ESUCCESS;
|
|
836
|
+
}, ['i32', 'i32', 'i32', 'i32'], ['i32']);
|
|
837
|
+
defineImport('path_create_directory', function path_create_directory(fd, path, path_len) {
|
|
838
|
+
path = Number(path);
|
|
839
|
+
path_len = Number(path_len);
|
|
840
|
+
if (path === 0) {
|
|
841
|
+
return WasiErrno.EINVAL;
|
|
842
|
+
}
|
|
843
|
+
const { HEAPU8 } = getMemory(this);
|
|
844
|
+
const wasi = _wasi.get(this);
|
|
845
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.PATH_CREATE_DIRECTORY, BigInt(0));
|
|
846
|
+
let pathString = decoder.decode(HEAPU8.subarray(path, path + path_len));
|
|
847
|
+
pathString = resolve(fileDescriptor.realPath, pathString);
|
|
848
|
+
const fs = getFs(this);
|
|
849
|
+
fs.mkdirSync(pathString);
|
|
850
|
+
return WasiErrno.ESUCCESS;
|
|
851
|
+
}, async function path_create_directory(fd, path, path_len) {
|
|
551
852
|
path = Number(path);
|
|
552
853
|
path_len = Number(path_len);
|
|
553
854
|
if (path === 0) {
|
|
@@ -559,10 +860,10 @@ export class WASI {
|
|
|
559
860
|
let pathString = decoder.decode(HEAPU8.subarray(path, path + path_len));
|
|
560
861
|
pathString = resolve(fileDescriptor.realPath, pathString);
|
|
561
862
|
const fs = getFs(this);
|
|
562
|
-
fs.
|
|
863
|
+
await fs.promises.mkdir(pathString);
|
|
563
864
|
return WasiErrno.ESUCCESS;
|
|
564
|
-
});
|
|
565
|
-
|
|
865
|
+
}, ['i32', 'i32', 'i32'], ['i32']);
|
|
866
|
+
defineImport('path_filestat_get', function path_filestat_get(fd, flags, path, path_len, filestat) {
|
|
566
867
|
path = Number(path);
|
|
567
868
|
path_len = Number(path_len);
|
|
568
869
|
filestat = Number(filestat);
|
|
@@ -584,8 +885,30 @@ export class WASI {
|
|
|
584
885
|
}
|
|
585
886
|
toFileStat(view, filestat, stat);
|
|
586
887
|
return WasiErrno.ESUCCESS;
|
|
587
|
-
})
|
|
588
|
-
|
|
888
|
+
}, async function path_filestat_get(fd, flags, path, path_len, filestat) {
|
|
889
|
+
path = Number(path);
|
|
890
|
+
path_len = Number(path_len);
|
|
891
|
+
filestat = Number(filestat);
|
|
892
|
+
if (path === 0 || filestat === 0) {
|
|
893
|
+
return WasiErrno.EINVAL;
|
|
894
|
+
}
|
|
895
|
+
const { HEAPU8, view } = getMemory(this);
|
|
896
|
+
const wasi = _wasi.get(this);
|
|
897
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.PATH_FILESTAT_GET, BigInt(0));
|
|
898
|
+
let pathString = decoder.decode(HEAPU8.subarray(path, path + path_len));
|
|
899
|
+
const fs = getFs(this);
|
|
900
|
+
pathString = resolve(fileDescriptor.realPath, pathString);
|
|
901
|
+
let stat;
|
|
902
|
+
if ((flags & 1) === 1) {
|
|
903
|
+
stat = await fs.promises.stat(pathString, { bigint: true });
|
|
904
|
+
}
|
|
905
|
+
else {
|
|
906
|
+
stat = await fs.promises.lstat(pathString, { bigint: true });
|
|
907
|
+
}
|
|
908
|
+
toFileStat(view, filestat, stat);
|
|
909
|
+
return WasiErrno.ESUCCESS;
|
|
910
|
+
}, ['i32', 'i32', 'i32', 'i32', 'i32'], ['i32']);
|
|
911
|
+
defineImport('path_filestat_set_times', function path_filestat_set_times(fd, flags, path, path_len, atim, mtim, fst_flags) {
|
|
589
912
|
path = Number(path);
|
|
590
913
|
path_len = Number(path_len);
|
|
591
914
|
if (path === 0)
|
|
@@ -600,7 +923,7 @@ export class WASI {
|
|
|
600
923
|
const wasi = _wasi.get(this);
|
|
601
924
|
const fileDescriptor = wasi.fds.get(fd, WasiRights.PATH_FILESTAT_SET_TIMES, BigInt(0));
|
|
602
925
|
const fs = getFs(this);
|
|
603
|
-
const resolvedPath =
|
|
926
|
+
const resolvedPath = resolvePathSync(fs, fileDescriptor, decoder.decode(HEAPU8.subarray(path, path + path_len)), flags);
|
|
604
927
|
if ((fst_flags & WasiFstFlag.SET_ATIM_NOW) === WasiFstFlag.SET_ATIM_NOW) {
|
|
605
928
|
atim = BigInt(Date.now() * 1000000);
|
|
606
929
|
}
|
|
@@ -609,8 +932,32 @@ export class WASI {
|
|
|
609
932
|
}
|
|
610
933
|
fs.utimesSync(resolvedPath, Number(atim), Number(mtim));
|
|
611
934
|
return WasiErrno.ESUCCESS;
|
|
612
|
-
})
|
|
613
|
-
|
|
935
|
+
}, async function path_filestat_set_times(fd, flags, path, path_len, atim, mtim, fst_flags) {
|
|
936
|
+
path = Number(path);
|
|
937
|
+
path_len = Number(path_len);
|
|
938
|
+
if (path === 0)
|
|
939
|
+
return WasiErrno.EINVAL;
|
|
940
|
+
if ((fst_flags) & ~(WasiFstFlag.SET_ATIM |
|
|
941
|
+
WasiFstFlag.SET_ATIM_NOW |
|
|
942
|
+
WasiFstFlag.SET_MTIM |
|
|
943
|
+
WasiFstFlag.SET_MTIM_NOW)) {
|
|
944
|
+
return WasiErrno.EINVAL;
|
|
945
|
+
}
|
|
946
|
+
const { HEAPU8 } = getMemory(this);
|
|
947
|
+
const wasi = _wasi.get(this);
|
|
948
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.PATH_FILESTAT_SET_TIMES, BigInt(0));
|
|
949
|
+
const fs = getFs(this);
|
|
950
|
+
const resolvedPath = await resolvePathAsync(fs, fileDescriptor, decoder.decode(HEAPU8.subarray(path, path + path_len)), flags);
|
|
951
|
+
if ((fst_flags & WasiFstFlag.SET_ATIM_NOW) === WasiFstFlag.SET_ATIM_NOW) {
|
|
952
|
+
atim = BigInt(Date.now() * 1000000);
|
|
953
|
+
}
|
|
954
|
+
if ((fst_flags & WasiFstFlag.SET_MTIM_NOW) === WasiFstFlag.SET_MTIM_NOW) {
|
|
955
|
+
mtim = BigInt(Date.now() * 1000000);
|
|
956
|
+
}
|
|
957
|
+
await fs.promises.utimes(resolvedPath, Number(atim), Number(mtim));
|
|
958
|
+
return WasiErrno.ESUCCESS;
|
|
959
|
+
}, ['i32', 'i32', 'i32', 'i32', 'i64', 'i64', 'i32'], ['i32']);
|
|
960
|
+
defineImport('path_link', function path_link(old_fd, old_flags, old_path, old_path_len, new_fd, new_path, new_path_len) {
|
|
614
961
|
old_path = Number(old_path);
|
|
615
962
|
old_path_len = Number(old_path_len);
|
|
616
963
|
new_path = Number(new_path);
|
|
@@ -630,20 +977,36 @@ export class WASI {
|
|
|
630
977
|
}
|
|
631
978
|
const { HEAPU8 } = getMemory(this);
|
|
632
979
|
const fs = getFs(this);
|
|
633
|
-
const resolvedOldPath =
|
|
980
|
+
const resolvedOldPath = resolvePathSync(fs, oldWrap, decoder.decode(HEAPU8.subarray(old_path, old_path + old_path_len)), old_flags);
|
|
634
981
|
const resolvedNewPath = resolve(newWrap.realPath, decoder.decode(HEAPU8.subarray(new_path, new_path + new_path_len)));
|
|
635
982
|
fs.linkSync(resolvedOldPath, resolvedNewPath);
|
|
636
983
|
return WasiErrno.ESUCCESS;
|
|
637
|
-
})
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
984
|
+
}, async function path_link(old_fd, old_flags, old_path, old_path_len, new_fd, new_path, new_path_len) {
|
|
985
|
+
old_path = Number(old_path);
|
|
986
|
+
old_path_len = Number(old_path_len);
|
|
987
|
+
new_path = Number(new_path);
|
|
988
|
+
new_path_len = Number(new_path_len);
|
|
989
|
+
if (old_path === 0 || new_path === 0) {
|
|
642
990
|
return WasiErrno.EINVAL;
|
|
643
991
|
}
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
992
|
+
const wasi = _wasi.get(this);
|
|
993
|
+
let oldWrap;
|
|
994
|
+
let newWrap;
|
|
995
|
+
if (old_fd === new_fd) {
|
|
996
|
+
oldWrap = newWrap = wasi.fds.get(old_fd, WasiRights.PATH_LINK_SOURCE | WasiRights.PATH_LINK_TARGET, BigInt(0));
|
|
997
|
+
}
|
|
998
|
+
else {
|
|
999
|
+
oldWrap = wasi.fds.get(old_fd, WasiRights.PATH_LINK_SOURCE, BigInt(0));
|
|
1000
|
+
newWrap = wasi.fds.get(new_fd, WasiRights.PATH_LINK_TARGET, BigInt(0));
|
|
1001
|
+
}
|
|
1002
|
+
const { HEAPU8 } = getMemory(this);
|
|
1003
|
+
const fs = getFs(this);
|
|
1004
|
+
const resolvedOldPath = await resolvePathAsync(fs, oldWrap, decoder.decode(HEAPU8.subarray(old_path, old_path + old_path_len)), old_flags);
|
|
1005
|
+
const resolvedNewPath = resolve(newWrap.realPath, decoder.decode(HEAPU8.subarray(new_path, new_path + new_path_len)));
|
|
1006
|
+
await fs.promises.link(resolvedOldPath, resolvedNewPath);
|
|
1007
|
+
return WasiErrno.ESUCCESS;
|
|
1008
|
+
}, ['i32', 'i32', 'i32', 'i32', 'i32', 'i32', 'i32'], ['i32']);
|
|
1009
|
+
function pathOpen(o_flags, fs_rights_base, fs_rights_inheriting, fs_flags) {
|
|
647
1010
|
const read = (fs_rights_base & (WasiRights.FD_READ |
|
|
648
1011
|
WasiRights.FD_READDIR)) !== BigInt(0);
|
|
649
1012
|
const write = (fs_rights_base & (WasiRights.FD_DATASYNC |
|
|
@@ -688,32 +1051,78 @@ export class WASI {
|
|
|
688
1051
|
if (write && (flags & (FileControlFlag.O_APPEND | FileControlFlag.O_TRUNC)) === 0) {
|
|
689
1052
|
needed_inheriting |= WasiRights.FD_SEEK;
|
|
690
1053
|
}
|
|
1054
|
+
return { flags, needed_base, needed_inheriting };
|
|
1055
|
+
}
|
|
1056
|
+
defineImport('path_open', function path_open(dirfd, dirflags, path, path_len, o_flags, fs_rights_base, fs_rights_inheriting, fs_flags, fd) {
|
|
1057
|
+
path = Number(path);
|
|
1058
|
+
fd = Number(fd);
|
|
1059
|
+
if (path === 0 || fd === 0) {
|
|
1060
|
+
return WasiErrno.EINVAL;
|
|
1061
|
+
}
|
|
1062
|
+
path_len = Number(path_len);
|
|
1063
|
+
fs_rights_base = BigInt(fs_rights_base);
|
|
1064
|
+
fs_rights_inheriting = BigInt(fs_rights_inheriting);
|
|
1065
|
+
const { flags: flagsRes, needed_base: neededBase, needed_inheriting: neededInheriting } = pathOpen(o_flags, fs_rights_base, fs_rights_inheriting, fs_flags);
|
|
691
1066
|
const wasi = _wasi.get(this);
|
|
692
|
-
const fileDescriptor = wasi.fds.get(dirfd,
|
|
1067
|
+
const fileDescriptor = wasi.fds.get(dirfd, neededBase, neededInheriting);
|
|
693
1068
|
const memory = getMemory(this);
|
|
694
1069
|
const HEAPU8 = memory.HEAPU8;
|
|
695
1070
|
const pathString = decoder.decode(HEAPU8.subarray(path, path + path_len));
|
|
696
1071
|
const fs = getFs(this);
|
|
697
|
-
const resolved_path =
|
|
698
|
-
const r = fs.openSync(resolved_path,
|
|
1072
|
+
const resolved_path = resolvePathSync(fs, fileDescriptor, pathString, dirflags);
|
|
1073
|
+
const r = fs.openSync(resolved_path, flagsRes, 0o666);
|
|
699
1074
|
const filetype = wasi.fds.getFileTypeByFd(r);
|
|
700
1075
|
if ((o_flags & WasiFileControlFlag.O_DIRECTORY) !== 0 && filetype !== WasiFileType.DIRECTORY) {
|
|
701
1076
|
return WasiErrno.ENOTDIR;
|
|
702
1077
|
}
|
|
703
|
-
const { base: max_base, inheriting: max_inheriting } = getRights(wasi.fds.stdio, r,
|
|
1078
|
+
const { base: max_base, inheriting: max_inheriting } = getRights(wasi.fds.stdio, r, flagsRes, filetype);
|
|
704
1079
|
const wrap = wasi.fds.insert(r, resolved_path, resolved_path, filetype, fs_rights_base & max_base, fs_rights_inheriting & max_inheriting, 0);
|
|
705
1080
|
const stat = fs.fstatSync(r, { bigint: true });
|
|
706
1081
|
if (stat.isFile()) {
|
|
707
1082
|
wrap.size = stat.size;
|
|
708
|
-
if ((
|
|
1083
|
+
if ((flagsRes & FileControlFlag.O_APPEND) !== 0) {
|
|
709
1084
|
wrap.pos = stat.size;
|
|
710
1085
|
}
|
|
711
1086
|
}
|
|
712
1087
|
const view = memory.view;
|
|
713
1088
|
view.setInt32(fd, wrap.id, true);
|
|
714
1089
|
return WasiErrno.ESUCCESS;
|
|
715
|
-
})
|
|
716
|
-
|
|
1090
|
+
}, async function path_open(dirfd, dirflags, path, path_len, o_flags, fs_rights_base, fs_rights_inheriting, fs_flags, fd) {
|
|
1091
|
+
path = Number(path);
|
|
1092
|
+
fd = Number(fd);
|
|
1093
|
+
if (path === 0 || fd === 0) {
|
|
1094
|
+
return WasiErrno.EINVAL;
|
|
1095
|
+
}
|
|
1096
|
+
path_len = Number(path_len);
|
|
1097
|
+
fs_rights_base = BigInt(fs_rights_base);
|
|
1098
|
+
fs_rights_inheriting = BigInt(fs_rights_inheriting);
|
|
1099
|
+
const { flags: flagsRes, needed_base: neededBase, needed_inheriting: neededInheriting } = pathOpen(o_flags, fs_rights_base, fs_rights_inheriting, fs_flags);
|
|
1100
|
+
const wasi = _wasi.get(this);
|
|
1101
|
+
const fileDescriptor = wasi.fds.get(dirfd, neededBase, neededInheriting);
|
|
1102
|
+
const memory = getMemory(this);
|
|
1103
|
+
const HEAPU8 = memory.HEAPU8;
|
|
1104
|
+
const pathString = decoder.decode(HEAPU8.subarray(path, path + path_len));
|
|
1105
|
+
const fs = getFs(this);
|
|
1106
|
+
const resolved_path = await resolvePathAsync(fs, fileDescriptor, pathString, dirflags);
|
|
1107
|
+
const r = await fs.promises.open(resolved_path, flagsRes, 0o666);
|
|
1108
|
+
const filetype = await wasi.fds.getFileTypeByFd(r);
|
|
1109
|
+
if ((o_flags & WasiFileControlFlag.O_DIRECTORY) !== 0 && filetype !== WasiFileType.DIRECTORY) {
|
|
1110
|
+
return WasiErrno.ENOTDIR;
|
|
1111
|
+
}
|
|
1112
|
+
const { base: max_base, inheriting: max_inheriting } = getRights(wasi.fds.stdio, r.fd, flagsRes, filetype);
|
|
1113
|
+
const wrap = wasi.fds.insert(r, resolved_path, resolved_path, filetype, fs_rights_base & max_base, fs_rights_inheriting & max_inheriting, 0);
|
|
1114
|
+
const stat = await r.stat({ bigint: true });
|
|
1115
|
+
if (stat.isFile()) {
|
|
1116
|
+
wrap.size = stat.size;
|
|
1117
|
+
if ((flagsRes & FileControlFlag.O_APPEND) !== 0) {
|
|
1118
|
+
wrap.pos = stat.size;
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
const view = memory.view;
|
|
1122
|
+
view.setInt32(fd, wrap.id, true);
|
|
1123
|
+
return WasiErrno.ESUCCESS;
|
|
1124
|
+
}, ['i32', 'i32', 'i32', 'i32', 'i32', 'i64', 'i64', 'i32', 'i32'], ['i32']);
|
|
1125
|
+
defineImport('path_readlink', function path_readlink(fd, path, path_len, buf, buf_len, bufused) {
|
|
717
1126
|
path = Number(path);
|
|
718
1127
|
path_len = Number(path_len);
|
|
719
1128
|
buf = Number(buf);
|
|
@@ -737,8 +1146,32 @@ export class WASI {
|
|
|
737
1146
|
HEAPU8[buf + len] = 0;
|
|
738
1147
|
view.setUint32(bufused, len + 1, true);
|
|
739
1148
|
return WasiErrno.ESUCCESS;
|
|
740
|
-
})
|
|
741
|
-
|
|
1149
|
+
}, async function path_readlink(fd, path, path_len, buf, buf_len, bufused) {
|
|
1150
|
+
path = Number(path);
|
|
1151
|
+
path_len = Number(path_len);
|
|
1152
|
+
buf = Number(buf);
|
|
1153
|
+
buf_len = Number(buf_len);
|
|
1154
|
+
bufused = Number(bufused);
|
|
1155
|
+
if (path === 0 || buf === 0 || bufused === 0) {
|
|
1156
|
+
return WasiErrno.EINVAL;
|
|
1157
|
+
}
|
|
1158
|
+
const { HEAPU8, view } = getMemory(this);
|
|
1159
|
+
const wasi = _wasi.get(this);
|
|
1160
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.PATH_READLINK, BigInt(0));
|
|
1161
|
+
let pathString = decoder.decode(HEAPU8.subarray(path, path + path_len));
|
|
1162
|
+
pathString = resolve(fileDescriptor.realPath, pathString);
|
|
1163
|
+
const fs = getFs(this);
|
|
1164
|
+
const link = await fs.promises.readlink(pathString);
|
|
1165
|
+
const linkData = encoder.encode(link);
|
|
1166
|
+
const len = Math.min(linkData.length, buf_len);
|
|
1167
|
+
if (len >= buf_len)
|
|
1168
|
+
return WasiErrno.ENOBUFS;
|
|
1169
|
+
HEAPU8.set(linkData.subarray(0, len), buf);
|
|
1170
|
+
HEAPU8[buf + len] = 0;
|
|
1171
|
+
view.setUint32(bufused, len + 1, true);
|
|
1172
|
+
return WasiErrno.ESUCCESS;
|
|
1173
|
+
}, ['i32', 'i32', 'i32', 'i32', 'i32', 'i32'], ['i32']);
|
|
1174
|
+
defineImport('path_remove_directory', function path_remove_directory(fd, path, path_len) {
|
|
742
1175
|
path = Number(path);
|
|
743
1176
|
path_len = Number(path_len);
|
|
744
1177
|
if (path === 0) {
|
|
@@ -752,8 +1185,22 @@ export class WASI {
|
|
|
752
1185
|
const fs = getFs(this);
|
|
753
1186
|
fs.rmdirSync(pathString);
|
|
754
1187
|
return WasiErrno.ESUCCESS;
|
|
755
|
-
})
|
|
756
|
-
|
|
1188
|
+
}, async function path_remove_directory(fd, path, path_len) {
|
|
1189
|
+
path = Number(path);
|
|
1190
|
+
path_len = Number(path_len);
|
|
1191
|
+
if (path === 0) {
|
|
1192
|
+
return WasiErrno.EINVAL;
|
|
1193
|
+
}
|
|
1194
|
+
const { HEAPU8 } = getMemory(this);
|
|
1195
|
+
const wasi = _wasi.get(this);
|
|
1196
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.PATH_REMOVE_DIRECTORY, BigInt(0));
|
|
1197
|
+
let pathString = decoder.decode(HEAPU8.subarray(path, path + path_len));
|
|
1198
|
+
pathString = resolve(fileDescriptor.realPath, pathString);
|
|
1199
|
+
const fs = getFs(this);
|
|
1200
|
+
await fs.promises.rmdir(pathString);
|
|
1201
|
+
return WasiErrno.ESUCCESS;
|
|
1202
|
+
}, ['i32', 'i32', 'i32'], ['i32']);
|
|
1203
|
+
defineImport('path_rename', function path_rename(old_fd, old_path, old_path_len, new_fd, new_path, new_path_len) {
|
|
757
1204
|
old_path = Number(old_path);
|
|
758
1205
|
old_path_len = Number(old_path_len);
|
|
759
1206
|
new_path = Number(new_path);
|
|
@@ -777,8 +1224,32 @@ export class WASI {
|
|
|
777
1224
|
const fs = getFs(this);
|
|
778
1225
|
fs.renameSync(resolvedOldPath, resolvedNewPath);
|
|
779
1226
|
return WasiErrno.ESUCCESS;
|
|
780
|
-
})
|
|
781
|
-
|
|
1227
|
+
}, async function path_rename(old_fd, old_path, old_path_len, new_fd, new_path, new_path_len) {
|
|
1228
|
+
old_path = Number(old_path);
|
|
1229
|
+
old_path_len = Number(old_path_len);
|
|
1230
|
+
new_path = Number(new_path);
|
|
1231
|
+
new_path_len = Number(new_path_len);
|
|
1232
|
+
if (old_path === 0 || new_path === 0) {
|
|
1233
|
+
return WasiErrno.EINVAL;
|
|
1234
|
+
}
|
|
1235
|
+
const wasi = _wasi.get(this);
|
|
1236
|
+
let oldWrap;
|
|
1237
|
+
let newWrap;
|
|
1238
|
+
if (old_fd === new_fd) {
|
|
1239
|
+
oldWrap = newWrap = wasi.fds.get(old_fd, WasiRights.PATH_RENAME_SOURCE | WasiRights.PATH_RENAME_TARGET, BigInt(0));
|
|
1240
|
+
}
|
|
1241
|
+
else {
|
|
1242
|
+
oldWrap = wasi.fds.get(old_fd, WasiRights.PATH_RENAME_SOURCE, BigInt(0));
|
|
1243
|
+
newWrap = wasi.fds.get(new_fd, WasiRights.PATH_RENAME_TARGET, BigInt(0));
|
|
1244
|
+
}
|
|
1245
|
+
const { HEAPU8 } = getMemory(this);
|
|
1246
|
+
const resolvedOldPath = resolve(oldWrap.realPath, decoder.decode(HEAPU8.subarray(old_path, old_path + old_path_len)));
|
|
1247
|
+
const resolvedNewPath = resolve(newWrap.realPath, decoder.decode(HEAPU8.subarray(new_path, new_path + new_path_len)));
|
|
1248
|
+
const fs = getFs(this);
|
|
1249
|
+
await fs.promises.rename(resolvedOldPath, resolvedNewPath);
|
|
1250
|
+
return WasiErrno.ESUCCESS;
|
|
1251
|
+
}, ['i32', 'i32', 'i32', 'i32', 'i32', 'i32'], ['i32']);
|
|
1252
|
+
defineImport('path_symlink', function path_symlink(old_path, old_path_len, fd, new_path, new_path_len) {
|
|
782
1253
|
old_path = Number(old_path);
|
|
783
1254
|
old_path_len = Number(old_path_len);
|
|
784
1255
|
new_path = Number(new_path);
|
|
@@ -795,8 +1266,25 @@ export class WASI {
|
|
|
795
1266
|
const fs = getFs(this);
|
|
796
1267
|
fs.symlinkSync(oldPath, newPath);
|
|
797
1268
|
return WasiErrno.ESUCCESS;
|
|
798
|
-
})
|
|
799
|
-
|
|
1269
|
+
}, async function path_symlink(old_path, old_path_len, fd, new_path, new_path_len) {
|
|
1270
|
+
old_path = Number(old_path);
|
|
1271
|
+
old_path_len = Number(old_path_len);
|
|
1272
|
+
new_path = Number(new_path);
|
|
1273
|
+
new_path_len = Number(new_path_len);
|
|
1274
|
+
if (old_path === 0 || new_path === 0) {
|
|
1275
|
+
return WasiErrno.EINVAL;
|
|
1276
|
+
}
|
|
1277
|
+
const { HEAPU8 } = getMemory(this);
|
|
1278
|
+
const wasi = _wasi.get(this);
|
|
1279
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.PATH_SYMLINK, BigInt(0));
|
|
1280
|
+
const oldPath = decoder.decode(HEAPU8.subarray(old_path, old_path + old_path_len));
|
|
1281
|
+
let newPath = decoder.decode(HEAPU8.subarray(new_path, new_path + new_path_len));
|
|
1282
|
+
newPath = resolve(fileDescriptor.realPath, newPath);
|
|
1283
|
+
const fs = getFs(this);
|
|
1284
|
+
await fs.promises.symlink(oldPath, newPath);
|
|
1285
|
+
return WasiErrno.ESUCCESS;
|
|
1286
|
+
}, ['i32', 'i32', 'i32', 'i32', 'i32'], ['i32']);
|
|
1287
|
+
defineImport('path_unlink_file', function path_unlink_file(fd, path, path_len) {
|
|
800
1288
|
path = Number(path);
|
|
801
1289
|
path_len = Number(path_len);
|
|
802
1290
|
if (path === 0) {
|
|
@@ -810,58 +1298,30 @@ export class WASI {
|
|
|
810
1298
|
const fs = getFs(this);
|
|
811
1299
|
fs.unlinkSync(pathString);
|
|
812
1300
|
return WasiErrno.ESUCCESS;
|
|
813
|
-
})
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
1301
|
+
}, async function path_unlink_file(fd, path, path_len) {
|
|
1302
|
+
path = Number(path);
|
|
1303
|
+
path_len = Number(path_len);
|
|
1304
|
+
if (path === 0) {
|
|
1305
|
+
return WasiErrno.EINVAL;
|
|
1306
|
+
}
|
|
1307
|
+
const { HEAPU8 } = getMemory(this);
|
|
1308
|
+
const wasi = _wasi.get(this);
|
|
1309
|
+
const fileDescriptor = wasi.fds.get(fd, WasiRights.PATH_UNLINK_FILE, BigInt(0));
|
|
1310
|
+
let pathString = decoder.decode(HEAPU8.subarray(path, path + path_len));
|
|
1311
|
+
pathString = resolve(fileDescriptor.realPath, pathString);
|
|
1312
|
+
const fs = getFs(this);
|
|
1313
|
+
await fs.promises.unlink(pathString);
|
|
824
1314
|
return WasiErrno.ESUCCESS;
|
|
825
|
-
});
|
|
826
|
-
this.
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
const stride = 65536;
|
|
836
|
-
for (pos = 0; pos + stride < buf_len; pos += stride) {
|
|
837
|
-
crypto.getRandomValues(HEAPU8.subarray(buf + pos, buf + pos + stride));
|
|
838
|
-
}
|
|
839
|
-
crypto.getRandomValues(HEAPU8.subarray(buf + pos, buf + buf_len));
|
|
840
|
-
return WasiErrno.ESUCCESS;
|
|
841
|
-
})
|
|
842
|
-
: syscallWrap('random_get', function (buf, buf_len) {
|
|
843
|
-
buf = Number(buf);
|
|
844
|
-
if (buf === 0) {
|
|
845
|
-
return WasiErrno.EINVAL;
|
|
846
|
-
}
|
|
847
|
-
buf_len = Number(buf_len);
|
|
848
|
-
const { view } = getMemory(this);
|
|
849
|
-
for (let i = buf; i < buf + buf_len; ++i) {
|
|
850
|
-
view.setUint8(i, Math.floor(Math.random() * 256));
|
|
851
|
-
}
|
|
852
|
-
return WasiErrno.ESUCCESS;
|
|
853
|
-
});
|
|
854
|
-
this.sock_recv = syscallWrap('sock_recv', function () {
|
|
855
|
-
return WasiErrno.ENOTSUP;
|
|
856
|
-
});
|
|
857
|
-
this.sock_send = syscallWrap('sock_send', function () {
|
|
858
|
-
return WasiErrno.ENOTSUP;
|
|
859
|
-
});
|
|
860
|
-
this.sock_shutdown = syscallWrap('sock_shutdown', function () {
|
|
861
|
-
return WasiErrno.ENOTSUP;
|
|
862
|
-
});
|
|
863
|
-
const fs = filesystem ? filesystem.fs : undefined;
|
|
864
|
-
const fds = new FileDescriptorTable({
|
|
1315
|
+
}, ['i32', 'i32', 'i32'], ['i32']);
|
|
1316
|
+
this._setMemory = function setMemory(m) {
|
|
1317
|
+
if (!(m instanceof _WebAssembly.Memory)) {
|
|
1318
|
+
throw new TypeError('"instance.exports.memory" property must be a WebAssembly.Memory');
|
|
1319
|
+
}
|
|
1320
|
+
_memory.set(_this, extendMemory(m));
|
|
1321
|
+
};
|
|
1322
|
+
}
|
|
1323
|
+
static createSync(args, env, preopens, stdio, fs, print, printErr) {
|
|
1324
|
+
const fds = new SyncTable({
|
|
865
1325
|
size: 3,
|
|
866
1326
|
in: stdio[0],
|
|
867
1327
|
out: stdio[1],
|
|
@@ -870,13 +1330,7 @@ export class WASI {
|
|
|
870
1330
|
print,
|
|
871
1331
|
printErr
|
|
872
1332
|
});
|
|
873
|
-
|
|
874
|
-
fds,
|
|
875
|
-
args,
|
|
876
|
-
env
|
|
877
|
-
});
|
|
878
|
-
if (fs)
|
|
879
|
-
_fs.set(this, fs);
|
|
1333
|
+
const _this = new WASI(args, env, fds, false, fs);
|
|
880
1334
|
if (preopens.length > 0) {
|
|
881
1335
|
for (let i = 0; i < preopens.length; ++i) {
|
|
882
1336
|
const realPath = fs.realpathSync(preopens[i].realPath, 'utf8');
|
|
@@ -884,5 +1338,26 @@ export class WASI {
|
|
|
884
1338
|
fds.insertPreopen(fd, preopens[i].mappedPath, realPath);
|
|
885
1339
|
}
|
|
886
1340
|
}
|
|
1341
|
+
return _this;
|
|
1342
|
+
}
|
|
1343
|
+
static async createAsync(args, env, preopens, stdio, fs, print, printErr, asyncify) {
|
|
1344
|
+
const fds = new AsyncTable({
|
|
1345
|
+
size: 3,
|
|
1346
|
+
in: stdio[0],
|
|
1347
|
+
out: stdio[1],
|
|
1348
|
+
err: stdio[2],
|
|
1349
|
+
print,
|
|
1350
|
+
printErr
|
|
1351
|
+
});
|
|
1352
|
+
const _this = new WASI(args, env, fds, true, fs, asyncify);
|
|
1353
|
+
if (preopens.length > 0) {
|
|
1354
|
+
for (let i = 0; i < preopens.length; ++i) {
|
|
1355
|
+
const entry = preopens[i];
|
|
1356
|
+
const realPath = await fs.promises.realpath(entry.realPath);
|
|
1357
|
+
const fd = await fs.promises.open(realPath, 'r', 0o666);
|
|
1358
|
+
await fds.insertPreopen(fd, entry.mappedPath, realPath);
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
return _this;
|
|
887
1362
|
}
|
|
888
1363
|
}
|