@bytecodealliance/preview2-shim 0.0.7 → 0.0.8
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 +3 -3
- package/lib/browser/environment.js +14 -0
- package/lib/browser/index.js +30 -14
- package/lib/browser/instance-network.js +3 -0
- package/lib/browser/ip-name-lookup.js +23 -0
- package/lib/browser/monotonic-clock.js +5 -26
- package/lib/browser/network.js +3 -0
- package/lib/browser/tcp-create-socket.js +3 -0
- package/lib/browser/tcp.js +75 -0
- package/lib/browser/udp-create-socket.js +3 -0
- package/lib/browser/udp.js +75 -0
- package/lib/browser/wall-clock.js +6 -9
- package/lib/nodejs/environment.js +13 -1
- package/lib/nodejs/exit.js +0 -1
- package/lib/nodejs/filesystem.js +180 -22
- package/lib/nodejs/index.js +30 -14
- package/lib/nodejs/instance-network.js +3 -0
- package/lib/nodejs/ip-name-lookup.js +23 -0
- package/lib/nodejs/monotonic-clock.js +5 -5
- package/lib/nodejs/network.js +3 -0
- package/lib/nodejs/preopens.js +59 -1
- package/lib/nodejs/streams.js +37 -3
- package/lib/nodejs/tcp-create-socket.js +3 -0
- package/lib/nodejs/tcp.js +75 -0
- package/lib/nodejs/udp-create-socket.js +3 -0
- package/lib/nodejs/udp.js +75 -0
- package/lib/nodejs/wall-clock.js +6 -9
- package/package.json +1 -1
- package/types/imports/filesystem.d.ts +0 -2
- /package/lib/browser/{logging.js → console.js} +0 -0
- /package/lib/nodejs/{logging.js → console.js} +0 -0
package/README.md
CHANGED
|
@@ -8,10 +8,10 @@ Currently supports Node.js and browser versions, but alternative implementations
|
|
|
8
8
|
|
|
9
9
|
| Interface | Node.js | Browser |
|
|
10
10
|
| --------------- | ----------------------------:|-----------------------------:|
|
|
11
|
-
| Clocks | Pending timezone,
|
|
12
|
-
| Filesystem |
|
|
11
|
+
| Clocks | Pending timezone, poll | Pending timezone, poll |
|
|
12
|
+
| Filesystem | Basic read support | :x: |
|
|
13
13
|
| HTTP | :x: | :x: |
|
|
14
|
-
| IO |
|
|
14
|
+
| IO | Basic FS Streams | :x: |
|
|
15
15
|
| Logging | :heavy_check_mark: | :heavy_check_mark: |
|
|
16
16
|
| Poll | :x: | :x: |
|
|
17
17
|
| Random | :heavy_check_mark: | :heavy_check_mark: |
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
let _env;
|
|
2
|
+
export function _setEnv (envObj) {
|
|
3
|
+
_env = Object.entries(envObj);
|
|
4
|
+
}
|
|
5
|
+
|
|
1
6
|
export function getEnvironment () {
|
|
7
|
+
if (!_env) _env = [];
|
|
8
|
+
return _env;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function preopens () {
|
|
2
12
|
return [];
|
|
3
13
|
}
|
|
14
|
+
|
|
15
|
+
export function getArguments () {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
package/lib/browser/index.js
CHANGED
|
@@ -1,29 +1,45 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as console from "./console.js";
|
|
2
2
|
import * as defaultOutgoingHttp from "./default-outgoing-HTTP.js";
|
|
3
3
|
import * as environment from "./environment.js";
|
|
4
4
|
import * as exit from "./exit.js";
|
|
5
5
|
import * as filesystem from "./filesystem.js";
|
|
6
|
-
import * as
|
|
6
|
+
import * as instanceNetwork from "./instance-network.js";
|
|
7
|
+
import * as ipNameLookup from "./ip-name-lookup.js";
|
|
7
8
|
import * as monotonicClock from "./monotonic-clock.js";
|
|
9
|
+
import * as network from "./network.js";
|
|
8
10
|
import * as poll from "./poll.js";
|
|
9
11
|
import * as preopens from "./preopens.js";
|
|
10
12
|
import * as random from "./random.js";
|
|
11
13
|
import * as streams from "./streams.js";
|
|
14
|
+
import * as tcpCreateSocket from "./tcp-create-socket.js";
|
|
15
|
+
import * as tcp from "./tcp.js";
|
|
16
|
+
import * as timezone from "./timezone.js";
|
|
17
|
+
import * as types from "./types.js";
|
|
18
|
+
import * as udpCreateSocket from "./udp-create-socket.js";
|
|
19
|
+
import * as udp from "./udp.js";
|
|
12
20
|
import * as wallClock from "./wall-clock.js";
|
|
13
21
|
|
|
14
22
|
export const importObject = {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
'console': console,
|
|
24
|
+
'default-outgoing-HTTP': defaultOutgoingHttp,
|
|
25
|
+
'environment': environment,
|
|
26
|
+
'exit': exit,
|
|
27
|
+
'filesystem': filesystem,
|
|
28
|
+
'instance-network': instanceNetwork,
|
|
29
|
+
'ip-name-lookup': ipNameLookup,
|
|
30
|
+
'monotonic-clock': monotonicClock,
|
|
31
|
+
'network': network,
|
|
32
|
+
'poll': poll,
|
|
33
|
+
'preopens': preopens,
|
|
34
|
+
'random': random,
|
|
35
|
+
'streams': streams,
|
|
36
|
+
'tcp-create-socket': tcpCreateSocket,
|
|
37
|
+
'tcp': tcp,
|
|
38
|
+
'timezone': timezone,
|
|
39
|
+
'types': types,
|
|
40
|
+
'udp-create-socket': udpCreateSocket,
|
|
41
|
+
'udp': udp,
|
|
42
|
+
'wall-clock': wallClock
|
|
27
43
|
};
|
|
28
44
|
|
|
29
45
|
export { WasiHttp } from "../http/wasi-http.js";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function dropResolveAddressStream () {
|
|
2
|
+
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function subscribe () {
|
|
6
|
+
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function resolveAddresses () {
|
|
10
|
+
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function resolveNextAddress () {
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function nonBlocking () {
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function setNonBlocking () {
|
|
22
|
+
|
|
23
|
+
}
|
|
@@ -3,33 +3,12 @@ export function resolution(clock) {
|
|
|
3
3
|
console.log(`[monotonic-clock] Monotonic clock resolution ${clock}`);
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export function now(clock) {
|
|
9
|
-
if (clock === 0) {
|
|
10
|
-
return hrtimeBigint() - hrStart;
|
|
11
|
-
}
|
|
12
|
-
console.log(`[monotonic clock] Unknown clock ${clock}`);
|
|
6
|
+
function _hrtimeBigint () {
|
|
7
|
+
return BigInt(Math.floor(performance.now() * 1e9));
|
|
13
8
|
}
|
|
14
9
|
|
|
15
|
-
|
|
16
|
-
const baseNow = Math.floor((Date.now() - performance.now()) * 1e-3);
|
|
17
|
-
const clocktime = performance.now() * 1e-3;
|
|
18
|
-
let seconds = Math.floor(clocktime) + baseNow;
|
|
19
|
-
let nanoseconds = Math.floor((clocktime % 1) * 1e9);
|
|
20
|
-
|
|
21
|
-
if (previousTimestamp) {
|
|
22
|
-
seconds = seconds - previousTimestamp[0];
|
|
23
|
-
nanoseconds = nanoseconds - previousTimestamp[1];
|
|
24
|
-
if (nanoseconds < 0) {
|
|
25
|
-
seconds--;
|
|
26
|
-
nanoseconds += 1e9;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return [seconds, nanoseconds];
|
|
30
|
-
}
|
|
10
|
+
let _hrStart = _hrtimeBigint();
|
|
31
11
|
|
|
32
|
-
function
|
|
33
|
-
|
|
34
|
-
return BigInt(diff[0] * 1e9 + diff[1]);
|
|
12
|
+
export function now () {
|
|
13
|
+
return _hrtimeBigint() - _hrStart;
|
|
35
14
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export function subscribe () {
|
|
2
|
+
|
|
3
|
+
}
|
|
4
|
+
export function dropTcpSocket() {
|
|
5
|
+
|
|
6
|
+
}
|
|
7
|
+
export function bind() {
|
|
8
|
+
|
|
9
|
+
}
|
|
10
|
+
export function connect() {
|
|
11
|
+
|
|
12
|
+
}
|
|
13
|
+
export function listen() {
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
export function accept() {
|
|
17
|
+
|
|
18
|
+
}
|
|
19
|
+
export function localAddress() {
|
|
20
|
+
|
|
21
|
+
}
|
|
22
|
+
export function remoteAddress() {
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
export function addressFamily() {
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
export function ipv6Only() {
|
|
29
|
+
|
|
30
|
+
}
|
|
31
|
+
export function setIpv6Only() {
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
export function setListenBacklogSize() {
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
export function keepAlive() {
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
export function setKeepAlive() {
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
export function noDelay() {
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
export function setNoDelay() {
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
export function unicastHopLimit() {
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
export function setUnicastHopLimit() {
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
export function receiveBufferSize() {
|
|
56
|
+
|
|
57
|
+
}
|
|
58
|
+
export function setReceiveBufferSize() {
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
export function sendBufferSize() {
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
export function setSendBufferSize() {
|
|
65
|
+
|
|
66
|
+
}
|
|
67
|
+
export function nonBlocking() {
|
|
68
|
+
|
|
69
|
+
}
|
|
70
|
+
export function setNonBlocking() {
|
|
71
|
+
|
|
72
|
+
}
|
|
73
|
+
export function shutdown() {
|
|
74
|
+
|
|
75
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export function subscribe () {
|
|
2
|
+
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function dropUdpSocket () {
|
|
6
|
+
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function bind () {
|
|
10
|
+
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function connect () {
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function receive () {
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function send () {
|
|
22
|
+
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function localAddress () {
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function remoteAddress () {
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function addressFamily () {
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function ipv6Only () {
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function setIpv6Only () {
|
|
42
|
+
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function unicastHopLimit () {
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function setUnicastHopLimit () {
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function receiveBufferSize () {
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function setReceiveBufferSize () {
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function sendBufferSize () {
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function setSendBufferSize () {
|
|
66
|
+
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function nonBlocking () {
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function setNonBlocking () {
|
|
74
|
+
|
|
75
|
+
}
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
export function now(
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
return { seconds, nanoseconds };
|
|
6
|
-
}
|
|
7
|
-
console.log(`[wall-clock] Unknown clock ${clock}`);
|
|
1
|
+
export function now() {
|
|
2
|
+
const seconds = BigInt(Math.floor(Date.now() / 1e3));
|
|
3
|
+
const nanoseconds = (Date.now() % 1e3) * 1e6;
|
|
4
|
+
return { seconds, nanoseconds };
|
|
8
5
|
}
|
|
9
6
|
|
|
10
|
-
export function resolution(
|
|
11
|
-
console.log(`[wall-clock] Wall clock resolution
|
|
7
|
+
export function resolution() {
|
|
8
|
+
console.log(`[wall-clock] Wall clock resolution`);
|
|
12
9
|
}
|
|
@@ -1,7 +1,19 @@
|
|
|
1
|
+
import process from 'node:process';
|
|
2
|
+
|
|
3
|
+
let _env;
|
|
4
|
+
export function _setEnv (envObj) {
|
|
5
|
+
_env = Object.entries(envObj);
|
|
6
|
+
}
|
|
7
|
+
|
|
1
8
|
export function getEnvironment () {
|
|
2
|
-
|
|
9
|
+
if (!_env) _setEnv(process.env);
|
|
10
|
+
return _env;
|
|
3
11
|
}
|
|
4
12
|
|
|
5
13
|
export function preopens () {
|
|
6
14
|
return [];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function getArguments () {
|
|
18
|
+
return [];
|
|
7
19
|
}
|
package/lib/nodejs/exit.js
CHANGED
package/lib/nodejs/filesystem.js
CHANGED
|
@@ -1,16 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
// type: DescriptorType,
|
|
5
|
-
// nlink: Linkcount,
|
|
6
|
-
// size: Filesize,
|
|
7
|
-
// atim: Timestamp,
|
|
8
|
-
// mtim: Timestamp,
|
|
9
|
-
// ctim: Timestamp,
|
|
10
|
-
// }
|
|
1
|
+
import { openSync, constants, statSync, lstatSync, fstatSync, closeSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { _descriptors, _addOpenedDescriptor, _removeOpenedDescriptor, _getDescriptorType, _setSubdescriptorType, _setDescriptorType, _getFullPath } from './preopens.js';
|
|
3
|
+
import { _createFileStream } from './streams.js';
|
|
11
4
|
|
|
12
5
|
export function readViaStream(fd, offset) {
|
|
13
|
-
|
|
6
|
+
return _createFileStream(fd, offset);
|
|
14
7
|
}
|
|
15
8
|
|
|
16
9
|
export function writeViaStream(fd, offset) {
|
|
@@ -34,7 +27,12 @@ export function getFlags(fd) {
|
|
|
34
27
|
}
|
|
35
28
|
|
|
36
29
|
export function getType(fd) {
|
|
37
|
-
|
|
30
|
+
let type = _getDescriptorType(fd);
|
|
31
|
+
if (type === null) {
|
|
32
|
+
stat(fd);
|
|
33
|
+
type = _getDescriptorType(fd);
|
|
34
|
+
}
|
|
35
|
+
return type;
|
|
38
36
|
}
|
|
39
37
|
|
|
40
38
|
export function setFlags(fd, flags) {
|
|
@@ -57,8 +55,18 @@ export function write(fd, buffer, offset) {
|
|
|
57
55
|
console.log(`[filesystem] WRITE`, fd, buffer, offset);
|
|
58
56
|
}
|
|
59
57
|
|
|
58
|
+
let _dirStreams = [];
|
|
60
59
|
export function readDirectory(fd) {
|
|
61
|
-
|
|
60
|
+
const fullPath = _getFullPath(fd);
|
|
61
|
+
let dirs;
|
|
62
|
+
try {
|
|
63
|
+
dirs = readdirSync(fullPath, { withFileTypes: true });
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
_convertFsError(e);
|
|
67
|
+
}
|
|
68
|
+
_dirStreams.push({ fd, dirs, cursor: 0 });
|
|
69
|
+
return _dirStreams.length - 1;
|
|
62
70
|
}
|
|
63
71
|
|
|
64
72
|
export function sync(fd) {
|
|
@@ -69,12 +77,118 @@ export function createDirectoryAt(fd, path) {
|
|
|
69
77
|
console.log(`[filesystem] CREATE DIRECTORY`, fd, path);
|
|
70
78
|
}
|
|
71
79
|
|
|
72
|
-
|
|
73
|
-
|
|
80
|
+
const nsMagnitude = 1_000_000_000_000n;
|
|
81
|
+
function nsToDateTime (ns) {
|
|
82
|
+
const seconds = ns / nsMagnitude;
|
|
83
|
+
const nanoseconds = Number(ns % seconds);
|
|
84
|
+
return { seconds, nanoseconds };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function _convertFsError (e) {
|
|
88
|
+
switch (e.code) {
|
|
89
|
+
case 'EACCES': throw 'access';
|
|
90
|
+
case 'EAGAIN':
|
|
91
|
+
case 'EWOULDBLOCK': throw 'would-block';
|
|
92
|
+
case 'EALREADY': throw 'already';
|
|
93
|
+
case 'EBADF': throw 'bad-descriptor';
|
|
94
|
+
case 'EBUSY': throw 'busy';
|
|
95
|
+
case 'EDEADLK': throw 'deadlock';
|
|
96
|
+
case 'EDQUOT': throw 'quota';
|
|
97
|
+
case 'EEXIST': throw 'exist';
|
|
98
|
+
case 'EFBIG': throw 'file-too-large';
|
|
99
|
+
case 'EILSEQ': throw 'illegal-byte-sequence';
|
|
100
|
+
case 'EINPROGRESS': throw 'in-progress';
|
|
101
|
+
case 'EINTR': throw 'interrupted';
|
|
102
|
+
case 'EINVAL': throw 'invalid';
|
|
103
|
+
case 'EIO': throw 'io';
|
|
104
|
+
case 'EISDIR': throw 'is-directory';
|
|
105
|
+
case 'ELOOP': throw 'loop';
|
|
106
|
+
case 'EMLINK': throw 'too-many-links';
|
|
107
|
+
case 'EMSGSIZE': throw 'message-size';
|
|
108
|
+
case 'ENAMETOOLONG': throw 'name-too-long'
|
|
109
|
+
case 'ENODEV': throw 'no-device';
|
|
110
|
+
case 'ENOENT': throw 'no-entry';
|
|
111
|
+
case 'ENOLCK': throw 'no-lock';
|
|
112
|
+
case 'ENOMEM': throw 'insufficient-memory';
|
|
113
|
+
case 'ENOSPC': throw 'insufficient-space';
|
|
114
|
+
case 'ENOTDIR': throw 'not-directory';
|
|
115
|
+
case 'ENOTEMPTY': throw 'not-empty';
|
|
116
|
+
case 'ENOTRECOVERABLE': throw 'not-recoverable';
|
|
117
|
+
case 'ENOTSUP': throw 'unsupported';
|
|
118
|
+
case 'ENOTTY': throw 'no-tty';
|
|
119
|
+
case 'ENXIO': throw 'no-such-device';
|
|
120
|
+
case 'EOVERFLOW': throw 'overflow';
|
|
121
|
+
case 'EPERM': throw 'not-permitted';
|
|
122
|
+
case 'EPIPE': throw 'pipe';
|
|
123
|
+
case 'EROFS': throw 'read-only';
|
|
124
|
+
case 'ESPIPE': throw 'invalid-seek';
|
|
125
|
+
case 'ETXTBSY': throw 'text-file-busy';
|
|
126
|
+
case 'EXDEV': throw 'cross-device';
|
|
127
|
+
default: throw e;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function _lookupType (obj) {
|
|
132
|
+
if (obj.isFile())
|
|
133
|
+
return 'regular-file';
|
|
134
|
+
else if (obj.isSocket())
|
|
135
|
+
return 'socket';
|
|
136
|
+
else if (obj.isSymbolicLink())
|
|
137
|
+
return 'symbolic-link';
|
|
138
|
+
else if (obj.isFIFO())
|
|
139
|
+
return 'fifo';
|
|
140
|
+
else if (obj.isDirectory())
|
|
141
|
+
return 'directory';
|
|
142
|
+
else if (obj.isCharacterDevice())
|
|
143
|
+
return 'character-device';
|
|
144
|
+
else if (obj.isBlockDevice())
|
|
145
|
+
return 'block-device';
|
|
146
|
+
return 'unknown';
|
|
74
147
|
}
|
|
75
148
|
|
|
76
|
-
export function
|
|
77
|
-
|
|
149
|
+
export function stat(fd) {
|
|
150
|
+
let stats;
|
|
151
|
+
try {
|
|
152
|
+
stats = fstatSync(fd, { bigint: true });
|
|
153
|
+
}
|
|
154
|
+
catch (e) {
|
|
155
|
+
_convertFsError(e);
|
|
156
|
+
}
|
|
157
|
+
const type = _lookupType(stats);
|
|
158
|
+
_setDescriptorType(fd, type);
|
|
159
|
+
return {
|
|
160
|
+
device: stats.dev,
|
|
161
|
+
inode: stats.ino,
|
|
162
|
+
type,
|
|
163
|
+
linkCount: stats.nlink,
|
|
164
|
+
size: stats.size,
|
|
165
|
+
dataAccessTimestamp: nsToDateTime(stats.atimeNs),
|
|
166
|
+
dataModificationTimestamp: nsToDateTime(stats.mtimeNs),
|
|
167
|
+
statusChangeTimestamp: nsToDateTime(stats.ctimeNs),
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export function statAt(fd, { symlinkFollow }, path) {
|
|
172
|
+
const fullPath = _descriptors[fd].path + path;
|
|
173
|
+
let stats;
|
|
174
|
+
try {
|
|
175
|
+
stats = (symlinkFollow ? statSync : lstatSync)(fullPath, { bigint: true });
|
|
176
|
+
}
|
|
177
|
+
catch (e) {
|
|
178
|
+
_convertFsError(e);
|
|
179
|
+
}
|
|
180
|
+
const type = _lookupType(stats);
|
|
181
|
+
_setSubdescriptorType(fd, path, type);
|
|
182
|
+
return {
|
|
183
|
+
device: stats.dev,
|
|
184
|
+
inode: stats.ino,
|
|
185
|
+
type,
|
|
186
|
+
linkCount: stats.nlink,
|
|
187
|
+
size: stats.size,
|
|
188
|
+
dataAccessTimestamp: nsToDateTime(stats.atimeNs),
|
|
189
|
+
dataModificationTimestamp: nsToDateTime(stats.mtimeNs),
|
|
190
|
+
statusChangeTimestamp: nsToDateTime(stats.ctimeNs),
|
|
191
|
+
};
|
|
78
192
|
}
|
|
79
193
|
|
|
80
194
|
export function setTimesAt(fd) {
|
|
@@ -85,8 +199,45 @@ export function linkAt(fd) {
|
|
|
85
199
|
console.log(`[filesystem] LINK AT`, fd);
|
|
86
200
|
}
|
|
87
201
|
|
|
88
|
-
export function openAt(fd) {
|
|
89
|
-
|
|
202
|
+
export function openAt(fd, pathFlags, path, openFlags, descriptorFlags, modes) {
|
|
203
|
+
// TODO
|
|
204
|
+
// if (pathFlags.symlinkFollow) {
|
|
205
|
+
// // resolve symlink
|
|
206
|
+
// }
|
|
207
|
+
const fullPath = _descriptors[fd].path + path;
|
|
208
|
+
let fsOpenFlags = 0x0;
|
|
209
|
+
if (openFlags.create)
|
|
210
|
+
fsOpenFlags |= constants.O_CREAT;
|
|
211
|
+
if (openFlags.directory)
|
|
212
|
+
fsOpenFlags |= constants.O_DIRECTORY;
|
|
213
|
+
if (openFlags.exclusive)
|
|
214
|
+
fsOpenFlags |= constants.O_EXCL;
|
|
215
|
+
if (openFlags.truncate)
|
|
216
|
+
fsOpenFlags |= constants.O_TRUNC;
|
|
217
|
+
if (descriptorFlags.read && descriptorFlags.write)
|
|
218
|
+
fsOpenFlags |= constants.O_RDWR;
|
|
219
|
+
else if (descriptorFlags.write)
|
|
220
|
+
fsOpenFlags |= constants.O_WRONLY;
|
|
221
|
+
// if (descriptorFlags.fileIntegritySync)
|
|
222
|
+
// if (descriptorFlags.dataIntegritySync)
|
|
223
|
+
// if (descriptorFlags.requestedWriteSync)
|
|
224
|
+
// if (descriptorFlags.mutateDirectory)
|
|
225
|
+
let fsMode = 0x0;
|
|
226
|
+
if (modes.readable)
|
|
227
|
+
fsMode |= 0o444;
|
|
228
|
+
if (modes.writeable)
|
|
229
|
+
fsMode |= 0o222;
|
|
230
|
+
if (modes.executable)
|
|
231
|
+
fsMode |= 0o111;
|
|
232
|
+
let localFd;
|
|
233
|
+
try {
|
|
234
|
+
localFd = openSync(fullPath, fsOpenFlags, fsMode);
|
|
235
|
+
}
|
|
236
|
+
catch (e) {
|
|
237
|
+
_convertFsError(e);
|
|
238
|
+
}
|
|
239
|
+
_addOpenedDescriptor(localFd, path, fd);
|
|
240
|
+
return localFd;
|
|
90
241
|
}
|
|
91
242
|
|
|
92
243
|
export function readlinkAt(fd) {
|
|
@@ -138,13 +289,20 @@ export function unlock(fd) {
|
|
|
138
289
|
}
|
|
139
290
|
|
|
140
291
|
export function dropDescriptor(fd) {
|
|
141
|
-
|
|
292
|
+
_removeOpenedDescriptor(fd);
|
|
293
|
+
closeSync(fd);
|
|
142
294
|
}
|
|
143
295
|
|
|
144
296
|
export function readDirectoryEntry(stream) {
|
|
145
|
-
|
|
297
|
+
const streamValue = _dirStreams[stream];
|
|
298
|
+
if (streamValue.cursor === streamValue.dirs.length)
|
|
299
|
+
return null;
|
|
300
|
+
const dir = streamValue.dirs[streamValue.cursor++];
|
|
301
|
+
const type = _lookupType(dir);
|
|
302
|
+
_setSubdescriptorType(streamValue.fd, '/' + dir.name, type);
|
|
303
|
+
return { inode: null, type, name: dir.name };
|
|
146
304
|
}
|
|
147
305
|
|
|
148
306
|
export function dropDirectoryEntryStream(stream) {
|
|
149
|
-
|
|
307
|
+
_dirStreams.splice(stream, 1);
|
|
150
308
|
}
|
package/lib/nodejs/index.js
CHANGED
|
@@ -1,29 +1,45 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as console from "./console.js";
|
|
2
2
|
import * as defaultOutgoingHttp from "./default-outgoing-HTTP.js";
|
|
3
3
|
import * as environment from "./environment.js";
|
|
4
4
|
import * as exit from "./exit.js";
|
|
5
5
|
import * as filesystem from "./filesystem.js";
|
|
6
|
-
import * as
|
|
6
|
+
import * as instanceNetwork from "./instance-network.js";
|
|
7
|
+
import * as ipNameLookup from "./ip-name-lookup.js";
|
|
7
8
|
import * as monotonicClock from "./monotonic-clock.js";
|
|
9
|
+
import * as network from "./network.js";
|
|
8
10
|
import * as poll from "./poll.js";
|
|
9
11
|
import * as preopens from "./preopens.js";
|
|
10
12
|
import * as random from "./random.js";
|
|
11
13
|
import * as streams from "./streams.js";
|
|
14
|
+
import * as tcpCreateSocket from "./tcp-create-socket.js";
|
|
15
|
+
import * as tcp from "./tcp.js";
|
|
16
|
+
import * as timezone from "./timezone.js";
|
|
17
|
+
import * as types from "./types.js";
|
|
18
|
+
import * as udpCreateSocket from "./udp-create-socket.js";
|
|
19
|
+
import * as udp from "./udp.js";
|
|
12
20
|
import * as wallClock from "./wall-clock.js";
|
|
13
21
|
|
|
14
22
|
export const importObject = {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
'console': console,
|
|
24
|
+
'default-outgoing-HTTP': defaultOutgoingHttp,
|
|
25
|
+
'environment': environment,
|
|
26
|
+
'exit': exit,
|
|
27
|
+
'filesystem': filesystem,
|
|
28
|
+
'instance-network': instanceNetwork,
|
|
29
|
+
'ip-name-lookup': ipNameLookup,
|
|
30
|
+
'monotonic-clock': monotonicClock,
|
|
31
|
+
'network': network,
|
|
32
|
+
'poll': poll,
|
|
33
|
+
'preopens': preopens,
|
|
34
|
+
'random': random,
|
|
35
|
+
'streams': streams,
|
|
36
|
+
'tcp-create-socket': tcpCreateSocket,
|
|
37
|
+
'tcp': tcp,
|
|
38
|
+
'timezone': timezone,
|
|
39
|
+
'types': types,
|
|
40
|
+
'udp-create-socket': udpCreateSocket,
|
|
41
|
+
'udp': udp,
|
|
42
|
+
'wall-clock': wallClock
|
|
27
43
|
};
|
|
28
44
|
|
|
29
45
|
export { WasiHttp } from "../http/wasi-http.js";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function dropResolveAddressStream () {
|
|
2
|
+
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function subscribe () {
|
|
6
|
+
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function resolveAddresses () {
|
|
10
|
+
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function resolveNextAddress () {
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function nonBlocking () {
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function setNonBlocking () {
|
|
22
|
+
|
|
23
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { hrtime } from "node:process";
|
|
2
2
|
|
|
3
|
-
export function resolution() {
|
|
4
|
-
|
|
3
|
+
export function resolution () {
|
|
4
|
+
return 1n;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
let
|
|
8
|
-
export function now() {
|
|
9
|
-
return hrtime.bigint() -
|
|
7
|
+
let _hrStart = hrtime.bigint();
|
|
8
|
+
export function now () {
|
|
9
|
+
return hrtime.bigint() - _hrStart;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export function subscribe (_when, _absolute) {
|
package/lib/nodejs/preopens.js
CHANGED
|
@@ -1,3 +1,61 @@
|
|
|
1
|
+
// default is full permissions
|
|
2
|
+
let preopenCnt = 4;
|
|
3
|
+
export let _descriptors = {
|
|
4
|
+
3: { type: 'directory', path: '/', parent: null, subpathTypes: {} }
|
|
5
|
+
};
|
|
6
|
+
let directories = [[3, '/']];
|
|
7
|
+
|
|
8
|
+
export function _getFullPath (fd) {
|
|
9
|
+
let path = '';
|
|
10
|
+
while (fd) {
|
|
11
|
+
path = _descriptors[fd].path + path;
|
|
12
|
+
fd = _descriptors[fd].parent;
|
|
13
|
+
}
|
|
14
|
+
return path;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function _getDescriptorType (fd) {
|
|
18
|
+
return _descriptors[fd].type;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function _setDescriptorType (fd, type) {
|
|
22
|
+
_descriptors[fd].type = type;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function _setSubdescriptorType (fd, path, type) {
|
|
26
|
+
while (_descriptors[fd].parent) {
|
|
27
|
+
path = _descriptors[fd].path + path;
|
|
28
|
+
fd = _descriptors[fd].parent;
|
|
29
|
+
}
|
|
30
|
+
_descriptors[fd].subpathTypes[path] = type;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function _addOpenedDescriptor (fd, path, parentFd) {
|
|
34
|
+
if (fd < preopenCnt || _descriptors[fd])
|
|
35
|
+
throw 'bad-descriptor';
|
|
36
|
+
let type = null;
|
|
37
|
+
for (const [_path, _type] of Object.entries(_descriptors[parentFd].subpathTypes)) {
|
|
38
|
+
if (_path === path)
|
|
39
|
+
type = _type;
|
|
40
|
+
}
|
|
41
|
+
_descriptors[fd] = { path, type, parent: parentFd, subpathTypes: {} };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function _removeOpenedDescriptor (fd) {
|
|
45
|
+
if (fd < preopenCnt)
|
|
46
|
+
throw 'eperm';
|
|
47
|
+
delete _descriptors[fd];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function _setPreopens (preopens) {
|
|
51
|
+
_descriptors = {};
|
|
52
|
+
directories = [,,];
|
|
53
|
+
for (const [virtualPath, path] of Object.entries(preopens)) {
|
|
54
|
+
_descriptors[preopenCnt] = { type: 'directory', path, parent: null, subpathTypes: {} };
|
|
55
|
+
directories.push([preopenCnt++, virtualPath]);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
1
59
|
export function getStdio () {
|
|
2
60
|
return {
|
|
3
61
|
stdin: 0,
|
|
@@ -7,5 +65,5 @@ export function getStdio () {
|
|
|
7
65
|
}
|
|
8
66
|
|
|
9
67
|
export function getDirectories () {
|
|
10
|
-
return
|
|
68
|
+
return directories;
|
|
11
69
|
}
|
package/lib/nodejs/streams.js
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
import { readSync as fsReadSync } from 'node:fs';
|
|
2
|
+
import { _convertFsError } from './filesystem.js';
|
|
3
|
+
|
|
4
|
+
export let _streams = {};
|
|
5
|
+
let streamCnt = 0;
|
|
6
|
+
export function _createFileStream(fd, offset) {
|
|
7
|
+
// note we only support offset 0
|
|
8
|
+
if (Number(offset) === 0)
|
|
9
|
+
_streams[streamCnt] = {
|
|
10
|
+
type: 'file',
|
|
11
|
+
fd: fd
|
|
12
|
+
};
|
|
13
|
+
return streamCnt++;
|
|
14
|
+
}
|
|
15
|
+
|
|
1
16
|
export function read(s, len) {
|
|
2
17
|
switch (s) {
|
|
3
18
|
case 0:
|
|
@@ -6,8 +21,26 @@ export function read(s, len) {
|
|
|
6
21
|
throw new Error(`TODO: write ${s}`);
|
|
7
22
|
}
|
|
8
23
|
}
|
|
9
|
-
export function blockingRead(s,
|
|
10
|
-
|
|
24
|
+
export function blockingRead(s, len) {
|
|
25
|
+
len = Number(len);
|
|
26
|
+
const stream = _streams[s];
|
|
27
|
+
if (!stream) throw null;
|
|
28
|
+
switch (stream.type) {
|
|
29
|
+
case 'file': {
|
|
30
|
+
const buf = Buffer.alloc(Number(len));
|
|
31
|
+
try {
|
|
32
|
+
const readBytes = fsReadSync(stream.fd, buf, 0, Number(len));
|
|
33
|
+
if (readBytes < Number(len))
|
|
34
|
+
return [new Uint8Array(), true];
|
|
35
|
+
return [new Uint8Array(buf.buffer, 0, readBytes), false];
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
_convertFsError(e);
|
|
39
|
+
}
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
default: throw null;
|
|
43
|
+
}
|
|
11
44
|
}
|
|
12
45
|
export function skip(s, _len) {
|
|
13
46
|
console.log(`[streams] Skip ${s}`);
|
|
@@ -19,7 +52,8 @@ export function subscribeToInputStream(s) {
|
|
|
19
52
|
console.log(`[streams] Subscribe to input stream ${s}`);
|
|
20
53
|
}
|
|
21
54
|
export function dropInputStream(s) {
|
|
22
|
-
|
|
55
|
+
delete _streams[s];
|
|
56
|
+
|
|
23
57
|
}
|
|
24
58
|
export function write(s, buf) {
|
|
25
59
|
switch (s) {
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export function subscribe () {
|
|
2
|
+
|
|
3
|
+
}
|
|
4
|
+
export function dropTcpSocket() {
|
|
5
|
+
|
|
6
|
+
}
|
|
7
|
+
export function bind() {
|
|
8
|
+
|
|
9
|
+
}
|
|
10
|
+
export function connect() {
|
|
11
|
+
|
|
12
|
+
}
|
|
13
|
+
export function listen() {
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
export function accept() {
|
|
17
|
+
|
|
18
|
+
}
|
|
19
|
+
export function localAddress() {
|
|
20
|
+
|
|
21
|
+
}
|
|
22
|
+
export function remoteAddress() {
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
export function addressFamily() {
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
export function ipv6Only() {
|
|
29
|
+
|
|
30
|
+
}
|
|
31
|
+
export function setIpv6Only() {
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
export function setListenBacklogSize() {
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
export function keepAlive() {
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
export function setKeepAlive() {
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
export function noDelay() {
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
export function setNoDelay() {
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
export function unicastHopLimit() {
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
export function setUnicastHopLimit() {
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
export function receiveBufferSize() {
|
|
56
|
+
|
|
57
|
+
}
|
|
58
|
+
export function setReceiveBufferSize() {
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
export function sendBufferSize() {
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
export function setSendBufferSize() {
|
|
65
|
+
|
|
66
|
+
}
|
|
67
|
+
export function nonBlocking() {
|
|
68
|
+
|
|
69
|
+
}
|
|
70
|
+
export function setNonBlocking() {
|
|
71
|
+
|
|
72
|
+
}
|
|
73
|
+
export function shutdown() {
|
|
74
|
+
|
|
75
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export function subscribe () {
|
|
2
|
+
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function dropUdpSocket () {
|
|
6
|
+
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function bind () {
|
|
10
|
+
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function connect () {
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function receive () {
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function send () {
|
|
22
|
+
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function localAddress () {
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function remoteAddress () {
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function addressFamily () {
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function ipv6Only () {
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function setIpv6Only () {
|
|
42
|
+
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function unicastHopLimit () {
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function setUnicastHopLimit () {
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function receiveBufferSize () {
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function setReceiveBufferSize () {
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function sendBufferSize () {
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function setSendBufferSize () {
|
|
66
|
+
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function nonBlocking () {
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function setNonBlocking () {
|
|
74
|
+
|
|
75
|
+
}
|
package/lib/nodejs/wall-clock.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
export function now(
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
return { seconds, nanoseconds };
|
|
6
|
-
}
|
|
7
|
-
console.log(`[wall-clock] now() UNKNOWN CLOCK ${clock}`);
|
|
1
|
+
export function now() {
|
|
2
|
+
const seconds = BigInt(Math.floor(Date.now() / 1e3));
|
|
3
|
+
const nanoseconds = (Date.now() % 1e3) * 1e6;
|
|
4
|
+
return { seconds, nanoseconds };
|
|
8
5
|
}
|
|
9
6
|
|
|
10
|
-
export function resolution(
|
|
11
|
-
console.log(`[wall-clock] Wall clock resolution
|
|
7
|
+
export function resolution() {
|
|
8
|
+
console.log(`[wall-clock] Wall clock resolution`);
|
|
12
9
|
}
|
package/package.json
CHANGED
|
@@ -6,7 +6,6 @@ export namespace Filesystem {
|
|
|
6
6
|
export function syncData(this: Descriptor): void;
|
|
7
7
|
export function getFlags(this: Descriptor): DescriptorFlags;
|
|
8
8
|
export function getType(this: Descriptor): DescriptorType;
|
|
9
|
-
export function setFlags(this: Descriptor, flags: DescriptorFlags): void;
|
|
10
9
|
export function setSize(this: Descriptor, size: Filesize): void;
|
|
11
10
|
export function setTimes(this: Descriptor, dataAccessTimestamp: NewTimestamp, dataModificationTimestamp: NewTimestamp): void;
|
|
12
11
|
export function read(this: Descriptor, length: Filesize, offset: Filesize): [Uint8Array | ArrayBuffer, boolean];
|
|
@@ -138,7 +137,6 @@ export type ErrorCode = 'access' | 'would-block' | 'already' | 'bad-descriptor'
|
|
|
138
137
|
export interface DescriptorFlags {
|
|
139
138
|
read?: boolean,
|
|
140
139
|
write?: boolean,
|
|
141
|
-
nonBlocking?: boolean,
|
|
142
140
|
fileIntegritySync?: boolean,
|
|
143
141
|
dataIntegritySync?: boolean,
|
|
144
142
|
requestedWriteSync?: boolean,
|
|
File without changes
|
|
File without changes
|