@amritk/nish-aarch64-darwin 0.35.0 → 0.37.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 +73 -59
- package/bin/nish +0 -0
- package/docs/AI.md +50 -4
- package/package.json +1 -1
- package/runtime/async.d.mts +2 -0
- package/runtime/async.mjs +7 -0
- package/runtime/nish.d.ts +4849 -430
- package/runtime/nish.h +25 -0
- package/runtime/page.d.ts +53 -0
- package/runtime/page.mjs +146 -0
- package/runtime/runtime-async.c +557 -0
- package/runtime/runtime-wasm.c +63 -7
- package/runtime/vite.d.ts +30 -0
- package/runtime/vite.mjs +150 -0
- package/scripts/build.sh +252 -15
- package/std/README.md +107 -82
- package/std/base64.ts +34 -5
- package/std/bytes.ts +279 -59
- package/std/cli-args.ts +296 -70
- package/std/cli-flags.ts +184 -19
- package/std/cli.ts +475 -54
- package/std/collections.ts +121 -23
- package/std/compress/checksum.ts +44 -14
- package/std/compress/deflate.ts +224 -111
- package/std/compress/gzip.ts +217 -53
- package/std/compress/zlib.ts +63 -7
- package/std/crypto/aes.ts +128 -52
- package/std/crypto/base64url.ts +29 -5
- package/std/crypto/bcrypt-batch.ts +101 -34
- package/std/crypto/bcrypt.ts +93 -27
- package/std/crypto/chacha20poly1305.ts +69 -14
- package/std/crypto/ct.ts +32 -13
- package/std/crypto/ed25519.ts +66 -16
- package/std/crypto/hkdf.ts +198 -13
- package/std/crypto/hmac.ts +242 -37
- package/std/crypto/jwt.ts +204 -72
- package/std/crypto/p256.ts +222 -72
- package/std/crypto/p384.ts +51 -23
- package/std/crypto/pki-roots.ts +32 -2
- package/std/crypto/pki.ts +99 -30
- package/std/crypto/rsa.ts +56 -22
- package/std/crypto/sha1.ts +3 -0
- package/std/crypto/sha256.ts +24 -1
- package/std/crypto/sha512.ts +99 -14
- package/std/crypto/x25519.ts +163 -24
- package/std/crypto/x509-random.ts +10 -0
- package/std/crypto/x509.ts +133 -66
- package/std/host/ring.ts +124 -0
- package/std/json-equal.ts +31 -11
- package/std/json-format.ts +112 -13
- package/std/json-number.ts +76 -26
- package/std/json-pointer.ts +23 -1
- package/std/json-tokenizer.ts +126 -51
- package/std/json-typed.ts +757 -96
- package/std/json-value.ts +438 -157
- package/std/json.ts +170 -38
- package/std/map.ts +25 -7
- package/std/math.ts +36 -4
- package/std/net/buffer-pool.ts +42 -11
- package/std/net/dns-config.ts +109 -23
- package/std/net/dns-message.ts +62 -7
- package/std/net/dns-resolver.ts +247 -53
- package/std/net/dns.ts +203 -35
- package/std/net/fetch.ts +1267 -290
- package/std/net/handler.ts +296 -80
- package/std/net/hpack.ts +290 -77
- package/std/net/http-compress.ts +152 -36
- package/std/net/http-fields.ts +85 -9
- package/std/net/http1-client-codec.ts +129 -44
- package/std/net/http1-codec.ts +279 -114
- package/std/net/http1-server.ts +409 -139
- package/std/net/http2-frame.ts +289 -51
- package/std/net/http2-tls.ts +152 -49
- package/std/net/http2.ts +314 -160
- package/std/net/http3-frame.ts +165 -27
- package/std/net/http3-server.ts +282 -131
- package/std/net/http3.ts +377 -173
- package/std/net/outbound.ts +37 -3
- package/std/net/postgres-carrier.ts +144 -8
- package/std/net/postgres.ts +898 -260
- package/std/net/prefork.ts +202 -65
- package/std/net/qpack.ts +120 -32
- package/std/net/quic-conn-ack.ts +60 -12
- package/std/net/quic-conn-cid.ts +135 -27
- package/std/net/quic-conn-params.ts +109 -22
- package/std/net/quic-datagram.ts +50 -3
- package/std/net/quic-frame.ts +333 -23
- package/std/net/quic-listener.ts +161 -75
- package/std/net/quic-packet.ts +373 -73
- package/std/net/quic-recovery.ts +287 -65
- package/std/net/quic-stream.ts +436 -146
- package/std/net/quic.ts +693 -323
- package/std/net/router.ts +87 -40
- package/std/net/tls/client.ts +167 -51
- package/std/net/tls/codec.ts +494 -68
- package/std/net/tls/record-client.ts +140 -73
- package/std/net/tls/record-server.ts +233 -105
- package/std/net/tls/record.ts +142 -36
- package/std/net/tls/schedule.ts +235 -26
- package/std/net/tls/ticket.ts +161 -40
- package/std/net/tls/verify.ts +57 -10
- package/std/net/tls-tcp.ts +308 -95
- package/std/net/tls.ts +276 -102
- package/std/net/upstream.ts +81 -45
- package/std/net/url.ts +109 -22
- package/std/net/websocket.ts +140 -26
- package/std/net/webtransport.ts +243 -106
- package/std/pair.ts +10 -2
- package/std/random.ts +42 -15
- package/std/regex.ts +422 -257
- package/std/region.ts +70 -15
- package/std/secret.ts +52 -11
- package/std/sort.ts +17 -2
- package/std/sqlite.ts +256 -35
- package/std/sync/ring.ts +229 -56
- package/std/sync/shm.ts +203 -23
- package/std/term-io.ts +154 -78
- package/std/term-pixels.ts +144 -19
- package/std/term-probe.ts +77 -35
- package/std/term-rate.ts +199 -118
- package/std/term.ts +400 -175
- package/std/testing.ts +130 -32
- package/std/text.ts +84 -17
- package/std/threads.ts +248 -56
- package/std/yaml-json.ts +111 -97
- package/std/yaml-lines.ts +47 -15
- package/std/yaml-write.ts +45 -30
- package/std/yaml.ts +764 -384
package/runtime/nish.h
CHANGED
|
@@ -153,6 +153,31 @@ void *nish_region_enter(uint64_t r);
|
|
|
153
153
|
void nish_region_leave(uint64_t r, void *root);
|
|
154
154
|
void nish_region_free(uint64_t r);
|
|
155
155
|
|
|
156
|
+
/* ---- The async executor (runtime-async.c) --------------------------------
|
|
157
|
+
* Linked only into a program whose IR names `@nish_async_`
|
|
158
|
+
* (docs/wp49-async-server.md, "Stage 5, part 1"). `nish_async_spawn` answers
|
|
159
|
+
* a node for a task of `kind` whose frame is `bytes` long, the frame 32 bytes
|
|
160
|
+
* in, with a region of its own; `nish_async_enter` makes a node the running
|
|
161
|
+
* task and enters its region, answering the task it displaced, which
|
|
162
|
+
* `nish_async_leave` restores; `nish_async_done` frees a finished task's
|
|
163
|
+
* region and reuses its node. `nish_async_wait_fd` (`dir` 0 readable, 1
|
|
164
|
+
* writable) and `nish_async_sleep` answer a token `nish_async_poll` reads: -1
|
|
165
|
+
* pending, 1 ready, 0 failed. `nish_async_next` answers the next task to
|
|
166
|
+
* resume, blocking in the kernel until one is ready, or null when nothing is
|
|
167
|
+
* ready and nothing waits. `nish_async_stat` answers 0: nodes allocated, 1:
|
|
168
|
+
* completions dropped because their task had finished, 2: spawned tasks not yet
|
|
169
|
+
* finished. */
|
|
170
|
+
void *nish_async_spawn(int32_t kind, uint64_t bytes);
|
|
171
|
+
void *nish_async_enter(void *node);
|
|
172
|
+
void nish_async_leave(void *node, void *prev);
|
|
173
|
+
void nish_async_done(void *node);
|
|
174
|
+
uint64_t nish_async_wait_fd(int32_t fd, int32_t dir);
|
|
175
|
+
uint64_t nish_async_sleep(int32_t ms);
|
|
176
|
+
int32_t nish_async_poll(uint64_t token);
|
|
177
|
+
void *nish_async_next(void);
|
|
178
|
+
void *nish_async_copy_str(const void *s);
|
|
179
|
+
int32_t nish_async_stat(int32_t which);
|
|
180
|
+
|
|
156
181
|
/* ---- String operations ------------------------------------------------- */
|
|
157
182
|
/* Copy `len` bytes into a new arena string (`bytes` need not be terminated). */
|
|
158
183
|
nish_str *nish_str_new(const char *bytes, uint64_t len);
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `nish/page`: the page-side helpers for a wasm module built with
|
|
3
|
+
* `--profile wasm-host` (docs/guide/using-nish/interop.md).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The objects a host module hands the program as `HostHandle<"kind">` values.
|
|
8
|
+
* Slot 0 is "none" and is never handed out; `get` and `take` throw a
|
|
9
|
+
* RangeError on a handle that names no object.
|
|
10
|
+
*/
|
|
11
|
+
export declare class HostTable<T> {
|
|
12
|
+
/** Stores `value` and answers its handle, never 0, typed as the handle the caller returns. */
|
|
13
|
+
add<H extends number = number>(value: T): H;
|
|
14
|
+
/** The object `handle` names. */
|
|
15
|
+
get(handle: number): T;
|
|
16
|
+
/** Removes the object `handle` names and answers it. */
|
|
17
|
+
take(handle: number): T;
|
|
18
|
+
/** How many objects the table holds. */
|
|
19
|
+
readonly size: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** A `layout` entry the loader answers for module storage. */
|
|
23
|
+
export interface RingField {
|
|
24
|
+
readonly at: number;
|
|
25
|
+
readonly length: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** The page's half of a `nish/host/ring` ring. */
|
|
29
|
+
export interface Ring {
|
|
30
|
+
/** The number of slots, the storage's length less two. */
|
|
31
|
+
readonly capacity: number;
|
|
32
|
+
/** The words put and not yet taken. */
|
|
33
|
+
size(): number;
|
|
34
|
+
/** The words `push` would still take. */
|
|
35
|
+
free(): number;
|
|
36
|
+
/** Puts `word` (an i32) at the tail; false, and nothing changed, when full. */
|
|
37
|
+
push(word: number): boolean;
|
|
38
|
+
/** Takes the word at the head; 0, and nothing changed, when empty. */
|
|
39
|
+
shift(): number;
|
|
40
|
+
/** Empties the ring. */
|
|
41
|
+
clear(): void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** The ring held in module storage `field` of the loaded module's `memory`. */
|
|
45
|
+
export declare function ringOver(memory: { readonly buffer: ArrayBuffer }, field: RingField): Ring;
|
|
46
|
+
|
|
47
|
+
/** A panic as the loader reports it. */
|
|
48
|
+
export interface PagePanic {
|
|
49
|
+
readonly message: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** The default `onPanic`: `console.error("nish: " + panic.message)`. */
|
|
53
|
+
export declare function reportPanic(panic: PagePanic): void;
|
package/runtime/page.mjs
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// nish/page: the page-side helpers for a wasm module built with
|
|
2
|
+
// `--profile wasm-host` (docs/wp50-wasm-host.md §11): the typed handle table a
|
|
3
|
+
// host module keeps its objects in, the page's half of `nish/host/ring`, and
|
|
4
|
+
// the default `onPanic` reporter. Plain ECMAScript with no imports, so a
|
|
5
|
+
// browser loads it as it is.
|
|
6
|
+
|
|
7
|
+
/** What a slot holds when no object is in it: the free list is never searched. */
|
|
8
|
+
const EMPTY = Symbol("empty");
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The objects a host module hands the program as `HostHandle<"kind">`
|
|
12
|
+
* values: `add` answers a handle, `get` reads it and `take` removes it. Slot 0
|
|
13
|
+
* is "none" and is never handed out, and a handle that names no object (0, a
|
|
14
|
+
* taken slot, a number no `add` answered) throws a RangeError rather than
|
|
15
|
+
* answering `undefined`: thrown inside an import, that ends the module, which
|
|
16
|
+
* is what a program holding a forged handle has earned. A taken slot is handed
|
|
17
|
+
* out again by a later `add`, so a stale handle the program kept names the
|
|
18
|
+
* newer object; it can reach only what the table holds.
|
|
19
|
+
*/
|
|
20
|
+
export class HostTable {
|
|
21
|
+
#slots = [EMPTY];
|
|
22
|
+
#free = [];
|
|
23
|
+
|
|
24
|
+
/** Stores `value` and answers its handle, never 0. */
|
|
25
|
+
add(value) {
|
|
26
|
+
const reused = this.#free.pop();
|
|
27
|
+
if (reused !== undefined) {
|
|
28
|
+
this.#slots[reused] = value;
|
|
29
|
+
return reused;
|
|
30
|
+
}
|
|
31
|
+
this.#slots.push(value);
|
|
32
|
+
return this.#slots.length - 1;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** The object `handle` names. */
|
|
36
|
+
get(handle) {
|
|
37
|
+
return this.#slots[this.#check(handle)];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Removes the object `handle` names and answers it; the handle names nothing after. */
|
|
41
|
+
take(handle) {
|
|
42
|
+
const at = this.#check(handle);
|
|
43
|
+
const value = this.#slots[at];
|
|
44
|
+
this.#slots[at] = EMPTY;
|
|
45
|
+
this.#free.push(at);
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** How many objects the table holds. */
|
|
50
|
+
get size() {
|
|
51
|
+
return this.#slots.length - 1 - this.#free.length;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
#check(handle) {
|
|
55
|
+
if (
|
|
56
|
+
!Number.isInteger(handle) ||
|
|
57
|
+
handle <= 0 ||
|
|
58
|
+
handle >= this.#slots.length ||
|
|
59
|
+
this.#slots[handle] === EMPTY
|
|
60
|
+
) {
|
|
61
|
+
throw new RangeError(`nish: no host object has handle ${handle}`);
|
|
62
|
+
}
|
|
63
|
+
return handle;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The page's half of a `nish/host/ring` ring held in module storage: `memory`
|
|
69
|
+
* is the loaded module's `memory` and `field` its `layout` entry, an
|
|
70
|
+
* `Int32Array` of two counts and the slots. The words are read through one
|
|
71
|
+
* `Int32Array` view, made again only when a growing memory replaced its
|
|
72
|
+
* buffer. The arithmetic is the module's (`std/host/ring.ts`): the head and
|
|
73
|
+
* the tail are counts modulo twice the capacity, reduced before every use, so
|
|
74
|
+
* counts the program wrote out of protocol are never read out of bounds.
|
|
75
|
+
*/
|
|
76
|
+
export const ringOver = (memory, field) => {
|
|
77
|
+
const at = field.at;
|
|
78
|
+
const length = field.length;
|
|
79
|
+
if (!Number.isInteger(at) || at < 0 || at % 4 !== 0 || !Number.isInteger(length) || length < 0) {
|
|
80
|
+
throw new RangeError("nish: a ring is an Int32Array's layout entry: { at, length }");
|
|
81
|
+
}
|
|
82
|
+
const capacity = length > 2 ? length - 2 : 0;
|
|
83
|
+
const twice = capacity * 2;
|
|
84
|
+
let view = null;
|
|
85
|
+
const words = () => {
|
|
86
|
+
if (view === null || view.buffer !== memory.buffer) {
|
|
87
|
+
view = new Int32Array(memory.buffer, at, length);
|
|
88
|
+
}
|
|
89
|
+
return view;
|
|
90
|
+
};
|
|
91
|
+
const count = (c) => {
|
|
92
|
+
const r = c % twice;
|
|
93
|
+
return r < 0 ? r + twice : r;
|
|
94
|
+
};
|
|
95
|
+
const size = () => {
|
|
96
|
+
if (capacity === 0) {
|
|
97
|
+
return 0;
|
|
98
|
+
}
|
|
99
|
+
const w = words();
|
|
100
|
+
const n = count(count(w[1]) - count(w[0]));
|
|
101
|
+
return n > capacity ? capacity : n;
|
|
102
|
+
};
|
|
103
|
+
return {
|
|
104
|
+
capacity,
|
|
105
|
+
size,
|
|
106
|
+
free: () => capacity - size(),
|
|
107
|
+
/** Puts `word` (an i32) at the tail; false, and nothing changed, when the ring is full. */
|
|
108
|
+
push(word) {
|
|
109
|
+
if (capacity === 0 || size() >= capacity) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
const w = words();
|
|
113
|
+
const tail = count(w[1]);
|
|
114
|
+
w[2 + (tail % capacity)] = word;
|
|
115
|
+
w[1] = count(tail + 1);
|
|
116
|
+
return true;
|
|
117
|
+
},
|
|
118
|
+
/** Takes the word at the head; 0, and nothing changed, when the ring is empty. */
|
|
119
|
+
shift() {
|
|
120
|
+
if (capacity === 0 || size() === 0) {
|
|
121
|
+
return 0;
|
|
122
|
+
}
|
|
123
|
+
const w = words();
|
|
124
|
+
const head = count(w[0]);
|
|
125
|
+
const word = w[2 + (head % capacity)];
|
|
126
|
+
w[0] = count(head + 1);
|
|
127
|
+
return word;
|
|
128
|
+
},
|
|
129
|
+
/** Empties the ring: the head catches up with the tail. */
|
|
130
|
+
clear() {
|
|
131
|
+
if (length >= 2) {
|
|
132
|
+
const w = words();
|
|
133
|
+
w[0] = w[1];
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* The reporter a loader calls when no `onPanic` was given: the panic's message
|
|
141
|
+
* on the console, as a native program prints it on stderr. The loader throws
|
|
142
|
+
* `NishPanic` after it either way.
|
|
143
|
+
*/
|
|
144
|
+
export const reportPanic = (panic) => {
|
|
145
|
+
console.error("nish: " + panic.message);
|
|
146
|
+
};
|