@amritk/nish-aarch64-darwin 0.34.0 → 0.35.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/INSTALL.md +16 -12
- package/bin/nish +0 -0
- package/docs/AI.md +77 -14
- package/package.json +1 -1
- package/runtime/async.d.mts +49 -0
- package/runtime/async.mjs +27 -0
- package/runtime/nish.d.ts +72 -0
- package/runtime/nish.h +6 -2
- package/runtime/nish.mjs +4 -0
- package/runtime/runtime-net.c +22 -0
- package/runtime/runtime-shm.c +93 -2
- package/std/README.md +131 -131
- package/std/bytes.ts +28 -5
- package/std/crypto/base64url.ts +42 -21
- package/std/crypto/bcrypt.ts +222 -183
- package/std/net/http1-codec.ts +262 -92
- package/std/net/http1-server.ts +87 -9
- package/std/net/http3-server.ts +30 -6
- package/std/net/postgres.ts +129 -40
- package/std/net/quic-recovery.ts +36 -8
- package/std/net/quic.ts +664 -59
- package/std/sync/ring.ts +236 -16
- package/std/sync/shm.ts +29 -0
package/runtime/runtime-shm.c
CHANGED
|
@@ -52,12 +52,24 @@
|
|
|
52
52
|
* answer -95, as `setIdlePriority` does on Darwin, and on wasi creating or
|
|
53
53
|
* opening a region answers -95 too.
|
|
54
54
|
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
55
|
+
* **A window** (`nishshm_lend`) is a `u8[]` whose data is a range of the
|
|
56
|
+
* mapping, so a program writes the region with `copyBytes` and index stores
|
|
57
|
+
* and no copy. Its header is a record of this file's, malloc'd (never the
|
|
58
|
+
* arena: a `region()` would free it under the program) and never freed: the
|
|
59
|
+
* program may keep the array past `nishshm_give_back` and `nishshm_close`,
|
|
60
|
+
* and both leave it a header of length 0 and no data, so an index after them
|
|
61
|
+
* is a bounds panic, not a read of an unmapped page. A loop lends again with
|
|
62
|
+
* the window it gave back as `reuse`, which re-points that header and takes
|
|
63
|
+
* no memory.
|
|
64
|
+
*
|
|
65
|
+
* Results are 0 or a count on success and a negated errno on failure. The
|
|
66
|
+
* table is a fixed array, a mapping is the kernel's, and a window's header is
|
|
67
|
+
* the one allocation. */
|
|
57
68
|
|
|
58
69
|
#define _GNU_SOURCE /* `syscall`, for the futex */
|
|
59
70
|
#include <errno.h>
|
|
60
71
|
#include <stdint.h>
|
|
72
|
+
#include <stdlib.h>
|
|
61
73
|
#include <string.h>
|
|
62
74
|
|
|
63
75
|
#include "nish.h"
|
|
@@ -90,10 +102,20 @@
|
|
|
90
102
|
/* The longest name. Darwin's shm_open takes 31 bytes with its leading '/'. */
|
|
91
103
|
#define NISHSHM_NAME_MAX 30
|
|
92
104
|
|
|
105
|
+
/* A window `lend` made: a `u8[]` header whose data is the mapping. The header
|
|
106
|
+
comes first, so the program's array pointer is the record's. */
|
|
107
|
+
typedef struct nishshm_window {
|
|
108
|
+
nish_array hdr;
|
|
109
|
+
uint8_t *lent; /* `hdr.data` as lent; NULL once given back */
|
|
110
|
+
uint64_t lent_len; /* the length lent */
|
|
111
|
+
struct nishshm_window *next; /* the region's next window */
|
|
112
|
+
} nishshm_window;
|
|
113
|
+
|
|
93
114
|
typedef struct nishshm_region {
|
|
94
115
|
uint8_t *base; /* the mapping, NULL while the slot is free */
|
|
95
116
|
uint64_t size; /* its length in bytes */
|
|
96
117
|
int32_t gen; /* the high bits of the slot's handle: 0 never used, 32767 retired */
|
|
118
|
+
nishshm_window *windows; /* every window this mapping lent, given back or not */
|
|
97
119
|
} nishshm_region;
|
|
98
120
|
|
|
99
121
|
/* NULL until this thread first maps a region. Slot 0 is never used, so no
|
|
@@ -312,6 +334,65 @@ void nishshm_write(int32_t h, int32_t at, const uint8_t *src, uint64_t n, uint64
|
|
|
312
334
|
memcpy(dst, src + off, len);
|
|
313
335
|
}
|
|
314
336
|
|
|
337
|
+
/* -- windows ----------------------------------------------------------------- */
|
|
338
|
+
|
|
339
|
+
/* The record of `a` among the region's windows, or NULL. A pointer walk, so a
|
|
340
|
+
header no window has is never read as one. */
|
|
341
|
+
static nishshm_window *window_of(nishshm_region *r, const nish_array *a) {
|
|
342
|
+
nishshm_window *w = r->windows;
|
|
343
|
+
while (w != NULL && &w->hdr != a) w = w->next;
|
|
344
|
+
return w;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/* A `u8[]` of `len` bytes whose data is the region's bytes at `at`, checked as
|
|
348
|
+
a byte copy's window is. `reuse` NULL takes a new header, which is malloc'd
|
|
349
|
+
and never freed: the program may hold it after any giveBack or close, so it
|
|
350
|
+
must stay a header, one that reads as empty. Otherwise `reuse` must be a
|
|
351
|
+
window this region lent and was given back, and is re-pointed. */
|
|
352
|
+
nish_array *nishshm_lend(int32_t h, int32_t at, int32_t len, nish_array *reuse) {
|
|
353
|
+
nishshm_region *r = region_checked(h);
|
|
354
|
+
uint8_t *p = window(h, at, (uint64_t)(int64_t)len, 0, (uint64_t)(int64_t)len);
|
|
355
|
+
nishshm_window *w;
|
|
356
|
+
if (reuse != NULL) {
|
|
357
|
+
w = window_of(r, reuse);
|
|
358
|
+
if (__builtin_expect(w == NULL || w->lent != NULL, 0))
|
|
359
|
+
shm_fail("reuse of length ", (int64_t)reuse->len,
|
|
360
|
+
" is not a window this region lent and was given back", 0, NULL);
|
|
361
|
+
} else {
|
|
362
|
+
w = (nishshm_window *)malloc(sizeof *w);
|
|
363
|
+
if (__builtin_expect(w == NULL, 0))
|
|
364
|
+
shm_fail("lend of ", len, " bytes found no memory for the window's header", 0, NULL);
|
|
365
|
+
w->next = r->windows;
|
|
366
|
+
r->windows = w;
|
|
367
|
+
}
|
|
368
|
+
w->hdr.len = w->hdr.cap = (uint64_t)len;
|
|
369
|
+
w->hdr.data = (char *)p;
|
|
370
|
+
w->lent = p;
|
|
371
|
+
w->lent_len = (uint64_t)len;
|
|
372
|
+
return &w->hdr;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/* Empties a lent window and answers its length. A pop or a shorter `length`
|
|
376
|
+
keeps the window; a push that moved its data took it out of the region, and
|
|
377
|
+
that, a second giveBack, or another region's window, panics. */
|
|
378
|
+
int32_t nishshm_give_back(int32_t h, nish_array *a) {
|
|
379
|
+
nishshm_region *r = region_checked(h);
|
|
380
|
+
nishshm_window *w = window_of(r, a);
|
|
381
|
+
if (__builtin_expect(w == NULL || w->lent == NULL, 0))
|
|
382
|
+
shm_fail("window of length ", (int64_t)a->len,
|
|
383
|
+
" is not lent by this region: it was given back, or another region lent it", 0,
|
|
384
|
+
NULL);
|
|
385
|
+
if (__builtin_expect((uint8_t *)a->data != w->lent || a->len > w->lent_len, 0))
|
|
386
|
+
shm_fail("window of length ", (int64_t)a->len,
|
|
387
|
+
" is no longer the region's bytes: a push moved it, so it cannot be given back", 0,
|
|
388
|
+
NULL);
|
|
389
|
+
int32_t n = (int32_t)a->len;
|
|
390
|
+
a->len = a->cap = 0;
|
|
391
|
+
a->data = NULL;
|
|
392
|
+
w->lent = NULL;
|
|
393
|
+
return n;
|
|
394
|
+
}
|
|
395
|
+
|
|
315
396
|
/* -- regions ----------------------------------------------------------------- */
|
|
316
397
|
|
|
317
398
|
int32_t nishshm_size(int32_t h) { return (int32_t)region_checked(h)->size; }
|
|
@@ -486,6 +567,16 @@ int32_t nishshm_unlink(const char *name) {
|
|
|
486
567
|
int32_t nishshm_close(int32_t h) {
|
|
487
568
|
nishshm_region *r = region_of(h);
|
|
488
569
|
if (r == NULL) return -9;
|
|
570
|
+
/* Every window still on the mapping reads as empty before the pages go: one
|
|
571
|
+
a push moved off it is the program's array now, and is left alone. */
|
|
572
|
+
for (nishshm_window *w = r->windows; w != NULL; w = w->next) {
|
|
573
|
+
if (w->lent != NULL && (uint8_t *)w->hdr.data == w->lent) {
|
|
574
|
+
w->hdr.len = w->hdr.cap = 0;
|
|
575
|
+
w->hdr.data = NULL;
|
|
576
|
+
}
|
|
577
|
+
w->lent = NULL;
|
|
578
|
+
}
|
|
579
|
+
r->windows = NULL;
|
|
489
580
|
munmap(r->base, (size_t)r->size);
|
|
490
581
|
r->base = NULL;
|
|
491
582
|
r->size = 0;
|