@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 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, resolution | Pending timezone, resolution |
12
- | Filesystem | :x: | :x: |
11
+ | Clocks | Pending timezone, poll | Pending timezone, poll |
12
+ | Filesystem | Basic read support | :x: |
13
13
  | HTTP | :x: | :x: |
14
- | IO | :x: | :x: |
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
+ }
@@ -1,29 +1,45 @@
1
- import * as logging from "./logging.js";
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 http from "./http.js";
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
- "default-outgoing-HTTP": defaultOutgoingHttp,
16
- "environment": environment,
17
- "exit": exit,
18
- "filesystem": filesystem,
19
- "http": http,
20
- "logging": logging,
21
- "monotonic-clock": monotonicClock,
22
- "poll": poll,
23
- "preopens": preopens,
24
- "random": random,
25
- "streams": streams,
26
- "wall-clock": wallClock,
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,3 @@
1
+ export function instanceNetwork () {
2
+
3
+ }
@@ -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
- let hrStart = hrtimeBigint();
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
- function hrtime(previousTimestamp) {
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 hrtimeBigint(time) {
33
- const diff = hrtime(time);
34
- return BigInt(diff[0] * 1e9 + diff[1]);
12
+ export function now () {
13
+ return _hrtimeBigint() - _hrStart;
35
14
  }
@@ -0,0 +1,3 @@
1
+ export function dropNetwork () {
2
+
3
+ }
@@ -0,0 +1,3 @@
1
+ export function createTcpSocket () {
2
+
3
+ }
@@ -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,3 @@
1
+ export function createUdpSocket () {
2
+
3
+ }
@@ -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(clock) {
2
- if (clock === 1) {
3
- const seconds = BigInt(Math.floor(Date.now() / 1000));
4
- const nanoseconds = (Date.now() % 1000) * 1000 * 1000;
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(clock) {
11
- console.log(`[wall-clock] Wall clock resolution ${clock}`);
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
- return [];
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
  }
@@ -1,4 +1,3 @@
1
1
  export function exit(status) {
2
- console.log(`[exit] Exit: ${JSON.stringify(status)}`);
3
2
  process.exit(status.tag === 'err' ? 1 : 0);
4
3
  }
@@ -1,16 +1,9 @@
1
- // export interface DescriptorStat {
2
- // dev: Device,
3
- // ino: Inode,
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
- console.log(`[filesystem] READ STREAM ${fd} ${offset}`);
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
- console.log(`[filesystem] GET TYPE ${fd}`);
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
- console.log(`[filesystem] READ DIR`, fd);
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
- export function stat(fd) {
73
- console.log(`[filesystem] STAT`, fd);
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 statAt(fd, pathFlags, path) {
77
- console.log(`[filesystem] STAT`, fd, pathFlags, path);
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
- console.log(`[filesystem] OPEN AT`, fd);
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
- console.log(`[filesystem] DROP DESCRIPTOR`, fd);
292
+ _removeOpenedDescriptor(fd);
293
+ closeSync(fd);
142
294
  }
143
295
 
144
296
  export function readDirectoryEntry(stream) {
145
- console.log(`[filesystem] READ DIRECTRY ENTRY`, stream);
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
- console.log(`[filesystem] DROP DIRECTORY ENTRY`, stream);
307
+ _dirStreams.splice(stream, 1);
150
308
  }
@@ -1,29 +1,45 @@
1
- import * as logging from "./logging.js";
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 http from "./http.js";
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
- "default-outgoing-HTTP": defaultOutgoingHttp,
16
- "environment": environment,
17
- "exit": exit,
18
- "filesystem": filesystem,
19
- "http": http,
20
- "logging": logging,
21
- "monotonic-clock": monotonicClock,
22
- "poll": poll,
23
- "preopens": preopens,
24
- "random": random,
25
- "streams": streams,
26
- "wall-clock": wallClock,
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,3 @@
1
+ export function instanceNetwork () {
2
+
3
+ }
@@ -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
- console.log(`[monotonic-clock] Monotonic clock resolution`);
3
+ export function resolution () {
4
+ return 1n;
5
5
  }
6
6
 
7
- let hrStart = hrtime.bigint();
8
- export function now() {
9
- return hrtime.bigint() - hrStart;
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) {
@@ -0,0 +1,3 @@
1
+ export function dropNetwork () {
2
+
3
+ }
@@ -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
  }
@@ -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, _len) {
10
- console.log(`[streams] Blocking read ${s}`);
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
- console.log(`[streams] Drop input stream ${s}`);
55
+ delete _streams[s];
56
+
23
57
  }
24
58
  export function write(s, buf) {
25
59
  switch (s) {
@@ -0,0 +1,3 @@
1
+ export function createTcpSocket () {
2
+
3
+ }
@@ -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,3 @@
1
+ export function createUdpSocket () {
2
+
3
+ }
@@ -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(clock) {
2
- if (clock === 1) {
3
- const seconds = BigInt(Math.floor(Date.now() / 1000));
4
- const nanoseconds = (Date.now() % 1000) * 1000 * 1000;
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(clock) {
11
- console.log(`[wall-clock] Wall clock resolution ${clock}`);
7
+ export function resolution() {
8
+ console.log(`[wall-clock] Wall clock resolution`);
12
9
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytecodealliance/preview2-shim",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "WASI Preview2 shim for JS environments",
5
5
  "author": "Guy Bedford, Eduardo Rodrigues<16357187+eduardomourar@users.noreply.github.com>",
6
6
  "type": "module",
@@ -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