@bytecodealliance/preview2-shim 0.17.2 → 0.17.4

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.
@@ -1,106 +1,109 @@
1
- import { fileURLToPath } from "node:url";
2
- import { createSyncFn } from "../synckit/index.js";
1
+ import { fileURLToPath } from 'node:url';
2
+ import { createSyncFn } from '../synckit/index.js';
3
3
  import {
4
- CALL_MASK,
5
- CALL_TYPE_MASK,
6
- FILE,
7
- HTTP_SERVER_INCOMING_HANDLER,
8
- HTTP,
9
- INPUT_STREAM_BLOCKING_READ,
10
- INPUT_STREAM_BLOCKING_SKIP,
11
- INPUT_STREAM_DISPOSE,
12
- INPUT_STREAM_READ,
13
- INPUT_STREAM_SKIP,
14
- INPUT_STREAM_SUBSCRIBE,
15
- OUTPUT_STREAM_BLOCKING_FLUSH,
16
- OUTPUT_STREAM_BLOCKING_SPLICE,
17
- OUTPUT_STREAM_BLOCKING_WRITE_AND_FLUSH,
18
- OUTPUT_STREAM_BLOCKING_WRITE_ZEROES_AND_FLUSH,
19
- OUTPUT_STREAM_CHECK_WRITE,
20
- OUTPUT_STREAM_DISPOSE,
21
- OUTPUT_STREAM_FLUSH,
22
- OUTPUT_STREAM_SPLICE,
23
- OUTPUT_STREAM_SUBSCRIBE,
24
- OUTPUT_STREAM_WRITE_ZEROES,
25
- OUTPUT_STREAM_WRITE,
26
- POLL_POLL_LIST,
27
- POLL_POLLABLE_BLOCK,
28
- POLL_POLLABLE_DISPOSE,
29
- POLL_POLLABLE_READY,
30
- SOCKET_TCP,
31
- STDERR,
32
- STDIN,
33
- STDOUT,
34
- reverseMap,
35
- } from "./calls.js";
36
- import nodeProcess, { exit, stderr, stdout, env } from "node:process";
4
+ CALL_MASK,
5
+ CALL_TYPE_MASK,
6
+ FILE,
7
+ HTTP_SERVER_INCOMING_HANDLER,
8
+ HTTP,
9
+ INPUT_STREAM_BLOCKING_READ,
10
+ INPUT_STREAM_BLOCKING_SKIP,
11
+ INPUT_STREAM_DISPOSE,
12
+ INPUT_STREAM_READ,
13
+ INPUT_STREAM_SKIP,
14
+ INPUT_STREAM_SUBSCRIBE,
15
+ OUTPUT_STREAM_BLOCKING_FLUSH,
16
+ OUTPUT_STREAM_BLOCKING_SPLICE,
17
+ OUTPUT_STREAM_BLOCKING_WRITE_AND_FLUSH,
18
+ OUTPUT_STREAM_BLOCKING_WRITE_ZEROES_AND_FLUSH,
19
+ OUTPUT_STREAM_CHECK_WRITE,
20
+ OUTPUT_STREAM_DISPOSE,
21
+ OUTPUT_STREAM_FLUSH,
22
+ OUTPUT_STREAM_SPLICE,
23
+ OUTPUT_STREAM_SUBSCRIBE,
24
+ OUTPUT_STREAM_WRITE_ZEROES,
25
+ OUTPUT_STREAM_WRITE,
26
+ POLL_POLL_LIST,
27
+ POLL_POLLABLE_BLOCK,
28
+ POLL_POLLABLE_DISPOSE,
29
+ POLL_POLLABLE_READY,
30
+ SOCKET_TCP,
31
+ STDERR,
32
+ STDIN,
33
+ STDOUT,
34
+ reverseMap,
35
+ } from './calls.js';
36
+ import nodeProcess, { exit, stderr, stdout, env } from 'node:process';
37
37
 
38
38
  const _rawDebug = nodeProcess._rawDebug || console.error.bind(console);
39
39
 
40
40
  const workerPath = fileURLToPath(
41
- new URL("./worker-thread.js", import.meta.url)
41
+ new URL('./worker-thread.js', import.meta.url)
42
42
  );
43
43
 
44
44
  const httpIncomingHandlers = new Map();
45
45
  export function registerIncomingHttpHandler(id, handler) {
46
- httpIncomingHandlers.set(id, handler);
46
+ httpIncomingHandlers.set(id, handler);
47
47
  }
48
48
 
49
49
  const instanceId = Math.round(Math.random() * 1000).toString();
50
50
  const DEBUG_DEFAULT = false;
51
51
  const DEBUG =
52
- env.PREVIEW2_SHIM_DEBUG === "0"
53
- ? false
54
- : env.PREVIEW2_SHIM_DEBUG === "1"
55
- ? true
56
- : DEBUG_DEFAULT;
52
+ env.PREVIEW2_SHIM_DEBUG === '0'
53
+ ? false
54
+ : env.PREVIEW2_SHIM_DEBUG === '1'
55
+ ? true
56
+ : DEBUG_DEFAULT;
57
57
 
58
58
  /**
59
59
  * @type {(call: number, id: number | null, payload: any) -> any}
60
60
  */
61
61
  export let ioCall = createSyncFn(workerPath, DEBUG, (type, id, payload) => {
62
- // 'callbacks' from the worker
63
- // ONLY happens for an http server incoming handler, and NOTHING else (not even sockets, since accept is sync!)
64
- if (type !== HTTP_SERVER_INCOMING_HANDLER)
65
- throw new Error(
66
- "Internal error: only incoming handler callback is permitted"
67
- );
68
- const handler = httpIncomingHandlers.get(id);
69
- if (!handler)
70
- throw new Error(
71
- `Internal error: no incoming handler registered for server ${id}`
72
- );
73
- handler(payload);
62
+ // 'callbacks' from the worker
63
+ // ONLY happens for an http server incoming handler, and NOTHING else (not even sockets, since accept is sync!)
64
+ if (type !== HTTP_SERVER_INCOMING_HANDLER) {
65
+ throw new Error(
66
+ 'Internal error: only incoming handler callback is permitted'
67
+ );
68
+ }
69
+ const handler = httpIncomingHandlers.get(id);
70
+ if (!handler) {
71
+ throw new Error(
72
+ `Internal error: no incoming handler registered for server ${id}`
73
+ );
74
+ }
75
+ handler(payload);
74
76
  });
75
77
  if (DEBUG) {
76
- const _ioCall = ioCall;
77
- ioCall = function ioCall(num, id, payload) {
78
- if (typeof id !== "number" && id !== null)
79
- throw new Error("id must be a number or null");
80
- let ret;
81
- try {
82
- _rawDebug(
83
- instanceId,
84
- reverseMap[num & CALL_MASK],
85
- reverseMap[num & CALL_TYPE_MASK],
86
- id,
87
- payload
88
- );
89
- ret = _ioCall(num, id, payload);
90
- return ret;
91
- } catch (e) {
92
- ret = e;
93
- throw ret;
94
- } finally {
95
- _rawDebug(instanceId, "->", ret);
96
- }
97
- };
78
+ const _ioCall = ioCall;
79
+ ioCall = function ioCall(num, id, payload) {
80
+ if (typeof id !== 'number' && id !== null) {
81
+ throw new Error('id must be a number or null');
82
+ }
83
+ let ret;
84
+ try {
85
+ _rawDebug(
86
+ instanceId,
87
+ reverseMap[num & CALL_MASK],
88
+ reverseMap[num & CALL_TYPE_MASK],
89
+ id,
90
+ payload
91
+ );
92
+ ret = _ioCall(num, id, payload);
93
+ return ret;
94
+ } catch (e) {
95
+ ret = e;
96
+ throw ret;
97
+ } finally {
98
+ _rawDebug(instanceId, '->', ret);
99
+ }
100
+ };
98
101
  }
99
102
 
100
- const symbolDispose = Symbol.dispose || Symbol.for("dispose");
103
+ const symbolDispose = Symbol.dispose || Symbol.for('dispose');
101
104
 
102
105
  const finalizationRegistry = new FinalizationRegistry(
103
- (dispose) => void dispose()
106
+ (dispose) => void dispose()
104
107
  );
105
108
 
106
109
  const dummySymbol = Symbol();
@@ -113,148 +116,152 @@ const dummySymbol = Symbol();
113
116
  * @param {(number) => void} disposeFn
114
117
  */
115
118
  export function registerDispose(resource, parentResource, id, disposeFn) {
116
- // While strictly speaking all components should handle their disposal,
117
- // this acts as a last-resort to catch all missed drops through the JS GC.
118
- // Mainly for two cases - (1) components which are long lived, that get shut
119
- // down and (2) users that interface with low-level WASI APIs directly in JS
120
- // for various reasons may end up leaning on JS GC inadvertantly.
121
- function finalizer() {
122
- // This has no functional purpose other than to pin a strong reference
123
- // from the child resource's finalizer to the parent resource, to ensure
124
- // that we can never finalize a parent resource before a child resource.
125
- // This makes the generational JS GC become piecewise over child resource
126
- // graphs (generational at each resource hierarchy level at least).
127
- if (parentResource?.[dummySymbol]) return;
128
- disposeFn(id);
129
- }
130
- finalizationRegistry.register(resource, finalizer, finalizer);
131
- return finalizer;
119
+ // While strictly speaking all components should handle their disposal,
120
+ // this acts as a last-resort to catch all missed drops through the JS GC.
121
+ // Mainly for two cases - (1) components which are long lived, that get shut
122
+ // down and (2) users that interface with low-level WASI APIs directly in JS
123
+ // for various reasons may end up leaning on JS GC inadvertantly.
124
+ function finalizer() {
125
+ // This has no functional purpose other than to pin a strong reference
126
+ // from the child resource's finalizer to the parent resource, to ensure
127
+ // that we can never finalize a parent resource before a child resource.
128
+ // This makes the generational JS GC become piecewise over child resource
129
+ // graphs (generational at each resource hierarchy level at least).
130
+ if (parentResource?.[dummySymbol]) {
131
+ return;
132
+ }
133
+ disposeFn(id);
134
+ }
135
+ finalizationRegistry.register(resource, finalizer, finalizer);
136
+ return finalizer;
132
137
  }
133
138
 
134
139
  export function earlyDispose(finalizer) {
135
- finalizationRegistry.unregister(finalizer);
136
- finalizer();
140
+ finalizationRegistry.unregister(finalizer);
141
+ finalizer();
137
142
  }
138
143
 
139
144
  const _Error = Error;
140
145
  const IoError = class Error extends _Error {
141
- constructor(payload) {
142
- super(payload);
143
- this.payload = payload;
144
- }
145
- toDebugString() {
146
- return this.message;
147
- }
146
+ constructor(payload) {
147
+ super(payload);
148
+ this.payload = payload;
149
+ }
150
+ toDebugString() {
151
+ return this.message;
152
+ }
148
153
  };
149
154
 
150
155
  function streamIoErrorCall(call, id, payload) {
151
- try {
152
- return ioCall(call, id, payload);
153
- } catch (e) {
154
- if (e.tag === "closed") throw e;
155
- if (e.tag === "last-operation-failed") {
156
- e.val = new IoError(Object.assign(new Error(e.val.message), e.val));
157
- throw e;
156
+ try {
157
+ return ioCall(call, id, payload);
158
+ } catch (e) {
159
+ if (e.tag === 'closed') {
160
+ throw e;
161
+ }
162
+ if (e.tag === 'last-operation-failed') {
163
+ e.val = new IoError(Object.assign(new Error(e.val.message), e.val));
164
+ throw e;
165
+ }
166
+ // any invalid error is a trap
167
+ console.trace(e);
168
+ exit(1);
158
169
  }
159
- // any invalid error is a trap
160
- console.trace(e);
161
- exit(1);
162
- }
163
170
  }
164
171
 
165
172
  class InputStream {
166
- #id;
167
- #streamType;
168
- #finalizer;
169
- read(len) {
170
- return streamIoErrorCall(
171
- INPUT_STREAM_READ | this.#streamType,
172
- this.#id,
173
- len
174
- );
175
- }
176
- blockingRead(len) {
177
- return streamIoErrorCall(
178
- INPUT_STREAM_BLOCKING_READ | this.#streamType,
179
- this.#id,
180
- len
181
- );
182
- }
183
- skip(len) {
184
- return streamIoErrorCall(
185
- INPUT_STREAM_SKIP | this.#streamType,
186
- this.#id,
187
- len
188
- );
189
- }
190
- blockingSkip(len) {
191
- return streamIoErrorCall(
192
- INPUT_STREAM_BLOCKING_SKIP | this.#streamType,
193
- this.#id,
194
- len
195
- );
196
- }
197
- subscribe() {
198
- return pollableCreate(
199
- ioCall(INPUT_STREAM_SUBSCRIBE | this.#streamType, this.#id),
200
- this
201
- );
202
- }
203
- static _id(stream) {
204
- return stream.#id;
205
- }
206
- /**
207
- * @param {FILE | SOCKET_TCP | STDIN | HTTP} streamType
208
- */
209
- static _create(streamType, id) {
210
- const stream = new InputStream();
211
- stream.#id = id;
212
- stream.#streamType = streamType;
213
- let disposeFn;
214
- switch (streamType) {
215
- case FILE:
216
- disposeFn = fileInputStreamDispose;
217
- break;
218
- case SOCKET_TCP:
219
- disposeFn = socketTcpInputStreamDispose;
220
- break;
221
- case STDIN:
222
- disposeFn = stdinInputStreamDispose;
223
- break;
224
- case HTTP:
225
- disposeFn = httpInputStreamDispose;
226
- break;
227
- default:
228
- throw new Error(
229
- "wasi-io trap: Dispose function not created for stream type " +
230
- reverseMap[streamType]
173
+ #id;
174
+ #streamType;
175
+ #finalizer;
176
+ read(len) {
177
+ return streamIoErrorCall(
178
+ INPUT_STREAM_READ | this.#streamType,
179
+ this.#id,
180
+ len
231
181
  );
232
182
  }
233
- stream.#finalizer = registerDispose(stream, null, id, disposeFn);
234
- return stream;
235
- }
236
- [symbolDispose]() {
237
- if (this.#finalizer) {
238
- earlyDispose(this.#finalizer);
239
- this.#finalizer = null;
183
+ blockingRead(len) {
184
+ return streamIoErrorCall(
185
+ INPUT_STREAM_BLOCKING_READ | this.#streamType,
186
+ this.#id,
187
+ len
188
+ );
189
+ }
190
+ skip(len) {
191
+ return streamIoErrorCall(
192
+ INPUT_STREAM_SKIP | this.#streamType,
193
+ this.#id,
194
+ len
195
+ );
196
+ }
197
+ blockingSkip(len) {
198
+ return streamIoErrorCall(
199
+ INPUT_STREAM_BLOCKING_SKIP | this.#streamType,
200
+ this.#id,
201
+ len
202
+ );
203
+ }
204
+ subscribe() {
205
+ return pollableCreate(
206
+ ioCall(INPUT_STREAM_SUBSCRIBE | this.#streamType, this.#id),
207
+ this
208
+ );
209
+ }
210
+ static _id(stream) {
211
+ return stream.#id;
212
+ }
213
+ /**
214
+ * @param {FILE | SOCKET_TCP | STDIN | HTTP} streamType
215
+ */
216
+ static _create(streamType, id) {
217
+ const stream = new InputStream();
218
+ stream.#id = id;
219
+ stream.#streamType = streamType;
220
+ let disposeFn;
221
+ switch (streamType) {
222
+ case FILE:
223
+ disposeFn = fileInputStreamDispose;
224
+ break;
225
+ case SOCKET_TCP:
226
+ disposeFn = socketTcpInputStreamDispose;
227
+ break;
228
+ case STDIN:
229
+ disposeFn = stdinInputStreamDispose;
230
+ break;
231
+ case HTTP:
232
+ disposeFn = httpInputStreamDispose;
233
+ break;
234
+ default:
235
+ throw new Error(
236
+ 'wasi-io trap: Dispose function not created for stream type ' +
237
+ reverseMap[streamType]
238
+ );
239
+ }
240
+ stream.#finalizer = registerDispose(stream, null, id, disposeFn);
241
+ return stream;
242
+ }
243
+ [symbolDispose]() {
244
+ if (this.#finalizer) {
245
+ earlyDispose(this.#finalizer);
246
+ this.#finalizer = null;
247
+ }
240
248
  }
241
- }
242
249
  }
243
250
 
244
251
  function fileInputStreamDispose(id) {
245
- ioCall(INPUT_STREAM_DISPOSE | FILE, id, null);
252
+ ioCall(INPUT_STREAM_DISPOSE | FILE, id, null);
246
253
  }
247
254
 
248
255
  function socketTcpInputStreamDispose(id) {
249
- ioCall(INPUT_STREAM_DISPOSE | SOCKET_TCP, id, null);
256
+ ioCall(INPUT_STREAM_DISPOSE | SOCKET_TCP, id, null);
250
257
  }
251
258
 
252
259
  function stdinInputStreamDispose(id) {
253
- ioCall(INPUT_STREAM_DISPOSE | STDIN, id, null);
260
+ ioCall(INPUT_STREAM_DISPOSE | STDIN, id, null);
254
261
  }
255
262
 
256
263
  function httpInputStreamDispose(id) {
257
- ioCall(INPUT_STREAM_DISPOSE | HTTP, id, null);
264
+ ioCall(INPUT_STREAM_DISPOSE | HTTP, id, null);
258
265
  }
259
266
 
260
267
  export const inputStreamCreate = InputStream._create;
@@ -264,137 +271,142 @@ export const inputStreamId = InputStream._id;
264
271
  delete InputStream._id;
265
272
 
266
273
  class OutputStream {
267
- #id;
268
- #streamType;
269
- #finalizer;
270
- checkWrite(len) {
271
- return streamIoErrorCall(
272
- OUTPUT_STREAM_CHECK_WRITE | this.#streamType,
273
- this.#id,
274
- len
275
- );
276
- }
277
- write(buf) {
278
- if (this.#streamType <= STDERR) return this.blockingWriteAndFlush(buf);
279
- return streamIoErrorCall(
280
- OUTPUT_STREAM_WRITE | this.#streamType,
281
- this.#id,
282
- buf
283
- );
284
- }
285
- blockingWriteAndFlush(buf) {
286
- if (this.#streamType <= STDERR) {
287
- const stream = this.#streamType === STDERR ? stderr : stdout;
288
- return void stream.write(buf);
274
+ #id;
275
+ #streamType;
276
+ #finalizer;
277
+ checkWrite(len) {
278
+ return streamIoErrorCall(
279
+ OUTPUT_STREAM_CHECK_WRITE | this.#streamType,
280
+ this.#id,
281
+ len
282
+ );
289
283
  }
290
- return streamIoErrorCall(
291
- OUTPUT_STREAM_BLOCKING_WRITE_AND_FLUSH | this.#streamType,
292
- this.#id,
293
- buf
294
- );
295
- }
296
- flush() {
297
- return streamIoErrorCall(OUTPUT_STREAM_FLUSH | this.#streamType, this.#id);
298
- }
299
- blockingFlush() {
300
- return streamIoErrorCall(
301
- OUTPUT_STREAM_BLOCKING_FLUSH | this.#streamType,
302
- this.#id
303
- );
304
- }
305
- writeZeroes(len) {
306
- return streamIoErrorCall(
307
- OUTPUT_STREAM_WRITE_ZEROES | this.#streamType,
308
- this.#id,
309
- len
310
- );
311
- }
312
- blockingWriteZeroesAndFlush(len) {
313
- return streamIoErrorCall(
314
- OUTPUT_STREAM_BLOCKING_WRITE_ZEROES_AND_FLUSH | this.#streamType,
315
- this.#id,
316
- len
317
- );
318
- }
319
- splice(src, len) {
320
- return streamIoErrorCall(
321
- OUTPUT_STREAM_SPLICE | this.#streamType,
322
- this.#id,
323
- { src: src.#id, len }
324
- );
325
- }
326
- blockingSplice(src, len) {
327
- return streamIoErrorCall(
328
- OUTPUT_STREAM_BLOCKING_SPLICE | this.#streamType,
329
- this.#id,
330
- { src: inputStreamId(src), len }
331
- );
332
- }
333
- subscribe() {
334
- return pollableCreate(
335
- ioCall(OUTPUT_STREAM_SUBSCRIBE | this.#streamType, this.#id)
336
- );
337
- }
338
-
339
- static _id(outputStream) {
340
- return outputStream.#id;
341
- }
342
- /**
343
- * @param {OutputStreamType} streamType
344
- * @param {any} createPayload
345
- */
346
- static _create(streamType, id) {
347
- const stream = new OutputStream();
348
- stream.#id = id;
349
- stream.#streamType = streamType;
350
- let disposeFn;
351
- switch (streamType) {
352
- case STDOUT:
353
- disposeFn = stdoutOutputStreamDispose;
354
- break;
355
- case STDERR:
356
- disposeFn = stderrOutputStreamDispose;
357
- break;
358
- case SOCKET_TCP:
359
- disposeFn = socketTcpOutputStreamDispose;
360
- break;
361
- case FILE:
362
- disposeFn = fileOutputStreamDispose;
363
- break;
364
- case HTTP:
365
- return stream;
366
- default:
367
- throw new Error(
368
- "wasi-io trap: Dispose function not created for stream type " +
369
- reverseMap[streamType]
284
+ write(buf) {
285
+ if (this.#streamType <= STDERR) {
286
+ return this.blockingWriteAndFlush(buf);
287
+ }
288
+ return streamIoErrorCall(
289
+ OUTPUT_STREAM_WRITE | this.#streamType,
290
+ this.#id,
291
+ buf
370
292
  );
371
293
  }
372
- stream.#finalizer = registerDispose(stream, null, id, disposeFn);
373
- return stream;
374
- }
375
-
376
- [symbolDispose]() {
377
- if (this.#finalizer) {
378
- earlyDispose(this.#finalizer);
379
- this.#finalizer = null;
294
+ blockingWriteAndFlush(buf) {
295
+ if (this.#streamType <= STDERR) {
296
+ const stream = this.#streamType === STDERR ? stderr : stdout;
297
+ return void stream.write(buf);
298
+ }
299
+ return streamIoErrorCall(
300
+ OUTPUT_STREAM_BLOCKING_WRITE_AND_FLUSH | this.#streamType,
301
+ this.#id,
302
+ buf
303
+ );
304
+ }
305
+ flush() {
306
+ return streamIoErrorCall(
307
+ OUTPUT_STREAM_FLUSH | this.#streamType,
308
+ this.#id
309
+ );
310
+ }
311
+ blockingFlush() {
312
+ return streamIoErrorCall(
313
+ OUTPUT_STREAM_BLOCKING_FLUSH | this.#streamType,
314
+ this.#id
315
+ );
316
+ }
317
+ writeZeroes(len) {
318
+ return streamIoErrorCall(
319
+ OUTPUT_STREAM_WRITE_ZEROES | this.#streamType,
320
+ this.#id,
321
+ len
322
+ );
323
+ }
324
+ blockingWriteZeroesAndFlush(len) {
325
+ return streamIoErrorCall(
326
+ OUTPUT_STREAM_BLOCKING_WRITE_ZEROES_AND_FLUSH | this.#streamType,
327
+ this.#id,
328
+ len
329
+ );
330
+ }
331
+ splice(src, len) {
332
+ return streamIoErrorCall(
333
+ OUTPUT_STREAM_SPLICE | this.#streamType,
334
+ this.#id,
335
+ { src: src.#id, len }
336
+ );
337
+ }
338
+ blockingSplice(src, len) {
339
+ return streamIoErrorCall(
340
+ OUTPUT_STREAM_BLOCKING_SPLICE | this.#streamType,
341
+ this.#id,
342
+ { src: inputStreamId(src), len }
343
+ );
344
+ }
345
+ subscribe() {
346
+ return pollableCreate(
347
+ ioCall(OUTPUT_STREAM_SUBSCRIBE | this.#streamType, this.#id)
348
+ );
349
+ }
350
+
351
+ static _id(outputStream) {
352
+ return outputStream.#id;
353
+ }
354
+ /**
355
+ * @param {OutputStreamType} streamType
356
+ * @param {any} createPayload
357
+ */
358
+ static _create(streamType, id) {
359
+ const stream = new OutputStream();
360
+ stream.#id = id;
361
+ stream.#streamType = streamType;
362
+ let disposeFn;
363
+ switch (streamType) {
364
+ case STDOUT:
365
+ disposeFn = stdoutOutputStreamDispose;
366
+ break;
367
+ case STDERR:
368
+ disposeFn = stderrOutputStreamDispose;
369
+ break;
370
+ case SOCKET_TCP:
371
+ disposeFn = socketTcpOutputStreamDispose;
372
+ break;
373
+ case FILE:
374
+ disposeFn = fileOutputStreamDispose;
375
+ break;
376
+ case HTTP:
377
+ return stream;
378
+ default:
379
+ throw new Error(
380
+ 'wasi-io trap: Dispose function not created for stream type ' +
381
+ reverseMap[streamType]
382
+ );
383
+ }
384
+ stream.#finalizer = registerDispose(stream, null, id, disposeFn);
385
+ return stream;
386
+ }
387
+
388
+ [symbolDispose]() {
389
+ if (this.#finalizer) {
390
+ earlyDispose(this.#finalizer);
391
+ this.#finalizer = null;
392
+ }
380
393
  }
381
- }
382
394
  }
383
395
 
384
396
  function stdoutOutputStreamDispose(id) {
385
- ioCall(OUTPUT_STREAM_DISPOSE | STDOUT, id);
397
+ ioCall(OUTPUT_STREAM_DISPOSE | STDOUT, id);
386
398
  }
387
399
 
388
400
  function stderrOutputStreamDispose(id) {
389
- ioCall(OUTPUT_STREAM_DISPOSE | STDERR, id);
401
+ ioCall(OUTPUT_STREAM_DISPOSE | STDERR, id);
390
402
  }
391
403
 
392
404
  function socketTcpOutputStreamDispose(id) {
393
- ioCall(OUTPUT_STREAM_DISPOSE | SOCKET_TCP, id);
405
+ ioCall(OUTPUT_STREAM_DISPOSE | SOCKET_TCP, id);
394
406
  }
395
407
 
396
408
  function fileOutputStreamDispose(id) {
397
- ioCall(OUTPUT_STREAM_DISPOSE | FILE, id);
409
+ ioCall(OUTPUT_STREAM_DISPOSE | FILE, id);
398
410
  }
399
411
 
400
412
  export const outputStreamCreate = OutputStream._create;
@@ -408,113 +420,117 @@ export const error = { Error: IoError };
408
420
  export const streams = { InputStream, OutputStream };
409
421
 
410
422
  function pollableDispose(id) {
411
- ioCall(POLL_POLLABLE_DISPOSE, id);
423
+ ioCall(POLL_POLLABLE_DISPOSE, id);
412
424
  }
413
425
 
414
- const rep = Symbol.for("cabiRep");
426
+ const rep = Symbol.for('cabiRep');
415
427
 
416
428
  class Pollable {
417
- #finalizer;
418
- ready() {
419
- return ioCall(POLL_POLLABLE_READY, this[rep]);
420
- }
421
- block() {
422
- ioCall(POLL_POLLABLE_BLOCK, this[rep]);
423
- }
424
- static _create(id, parent) {
425
- const pollable = new Pollable();
426
- pollable[rep] = id;
427
- pollable.#finalizer = registerDispose(
428
- pollable,
429
- parent,
430
- id,
431
- pollableDispose
432
- );
433
- return pollable;
434
- }
435
- [symbolDispose]() {
436
- if (this.#finalizer && this[rep]) {
437
- earlyDispose(this.#finalizer);
438
- this.#finalizer = null;
429
+ #finalizer;
430
+ ready() {
431
+ return ioCall(POLL_POLLABLE_READY, this[rep]);
432
+ }
433
+ block() {
434
+ ioCall(POLL_POLLABLE_BLOCK, this[rep]);
435
+ }
436
+ static _create(id, parent) {
437
+ const pollable = new Pollable();
438
+ pollable[rep] = id;
439
+ pollable.#finalizer = registerDispose(
440
+ pollable,
441
+ parent,
442
+ id,
443
+ pollableDispose
444
+ );
445
+ return pollable;
446
+ }
447
+ [symbolDispose]() {
448
+ if (this.#finalizer && this[rep]) {
449
+ earlyDispose(this.#finalizer);
450
+ this.#finalizer = null;
451
+ }
439
452
  }
440
- }
441
453
  }
442
454
 
443
- const cabiLowerSymbol = Symbol.for("cabiLower");
455
+ const cabiLowerSymbol = Symbol.for('cabiLower');
444
456
  const T_FLAG = 1 << 30;
445
457
 
446
- Pollable.prototype.ready[cabiLowerSymbol] = function ({
447
- resourceTables: [table],
458
+ Pollable.prototype.ready[cabiLowerSymbol] = function({
459
+ resourceTables: [table],
448
460
  }) {
449
- return function pollableReady(handle) {
450
- const rep = table[(handle << 1) + 1] & ~T_FLAG;
451
- const ready = ioCall(POLL_POLLABLE_READY, rep);
452
- return ready ? 1 : 0;
453
- };
461
+ return function pollableReady(handle) {
462
+ const rep = table[(handle << 1) + 1] & ~T_FLAG;
463
+ const ready = ioCall(POLL_POLLABLE_READY, rep);
464
+ return ready ? 1 : 0;
465
+ };
454
466
  };
455
467
 
456
- Pollable.prototype.block[cabiLowerSymbol] = function ({
457
- resourceTables: [table],
468
+ Pollable.prototype.block[cabiLowerSymbol] = function({
469
+ resourceTables: [table],
458
470
  }) {
459
- return function pollableBlock(handle) {
460
- const rep = table[(handle << 1) + 1] & ~T_FLAG;
461
- ioCall(POLL_POLLABLE_BLOCK, rep);
462
- };
471
+ return function pollableBlock(handle) {
472
+ const rep = table[(handle << 1) + 1] & ~T_FLAG;
473
+ ioCall(POLL_POLLABLE_BLOCK, rep);
474
+ };
463
475
  };
464
476
 
465
- Pollable[Symbol.for("cabiDispose")] = function pollableDispose(rep) {
466
- ioCall(POLL_POLLABLE_DISPOSE, rep);
477
+ Pollable[Symbol.for('cabiDispose')] = function pollableDispose(rep) {
478
+ ioCall(POLL_POLLABLE_DISPOSE, rep);
467
479
  };
468
480
 
469
481
  export const pollableCreate = Pollable._create;
470
482
  delete Pollable._create;
471
483
 
472
484
  export const poll = {
473
- Pollable,
474
- poll(list) {
475
- return ioCall(
476
- POLL_POLL_LIST,
477
- null,
478
- list.map((pollable) => pollable[rep])
479
- );
480
- },
485
+ Pollable,
486
+ poll(list) {
487
+ return ioCall(
488
+ POLL_POLL_LIST,
489
+ null,
490
+ list.map((pollable) => pollable[rep])
491
+ );
492
+ },
481
493
  };
482
494
 
483
- poll.poll[cabiLowerSymbol] = function ({ memory, realloc, resourceTables: [table] }) {
484
- return function pollPollList (listPtr, len, retptr) {
485
- const handleList = new Uint32Array(memory.buffer, listPtr, len);
486
- const repList = Array(len);
487
- for (let i = 0; i < len; i++) {
488
- const handle = handleList[i];
489
- repList[i] = table[(handle << 1) + 1] & ~T_FLAG;
490
- }
491
- const result = ioCall(POLL_POLL_LIST, null, repList);
492
- const ptr = realloc(0, 0, 4, result.byteLength);
493
- const out = new Uint32Array(memory.buffer, ptr, result.length);
494
- out.set(result);
495
- const ret = new Uint32Array(memory.buffer, retptr, 2);
496
- ret[0] = ptr;
497
- ret[1] = result.length;
498
- return retptr;
499
- };
495
+ poll.poll[cabiLowerSymbol] = function({
496
+ memory,
497
+ realloc,
498
+ resourceTables: [table],
499
+ }) {
500
+ return function pollPollList(listPtr, len, retptr) {
501
+ const handleList = new Uint32Array(memory.buffer, listPtr, len);
502
+ const repList = Array(len);
503
+ for (let i = 0; i < len; i++) {
504
+ const handle = handleList[i];
505
+ repList[i] = table[(handle << 1) + 1] & ~T_FLAG;
506
+ }
507
+ const result = ioCall(POLL_POLL_LIST, null, repList);
508
+ const ptr = realloc(0, 0, 4, result.byteLength);
509
+ const out = new Uint32Array(memory.buffer, ptr, result.length);
510
+ out.set(result);
511
+ const ret = new Uint32Array(memory.buffer, retptr, 2);
512
+ ret[0] = ptr;
513
+ ret[1] = result.length;
514
+ return retptr;
515
+ };
500
516
  };
501
517
 
502
518
  export function createPoll(call, id, initPayload) {
503
- return pollableCreate(ioCall(call, id, initPayload));
519
+ return pollableCreate(ioCall(call, id, initPayload));
504
520
  }
505
521
 
506
522
  export function createPollLower(call, id, table) {
507
- return function (initPayload) {
508
- const rep = ioCall(call, id, initPayload);
509
- const free = table[0] & ~T_FLAG;
510
- if (free === 0) {
511
- table.push(0);
512
- table.push(rep | T_FLAG);
513
- return (table.length >> 1) - 1;
514
- }
515
- table[0] = table[free << 1];
516
- table[free << 1] = 0;
517
- table[(free << 1) + 1] = rep | T_FLAG;
518
- return free;
519
- };
523
+ return function(initPayload) {
524
+ const rep = ioCall(call, id, initPayload);
525
+ const free = table[0] & ~T_FLAG;
526
+ if (free === 0) {
527
+ table.push(0);
528
+ table.push(rep | T_FLAG);
529
+ return (table.length >> 1) - 1;
530
+ }
531
+ table[0] = table[free << 1];
532
+ table[free << 1] = 0;
533
+ table[(free << 1) + 1] = rep | T_FLAG;
534
+ return free;
535
+ };
520
536
  }