@amritk/nish-x86_64-linux 0.18.0 → 0.21.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 +58 -28
- package/bin/nish +0 -0
- package/docs/AI.md +2759 -0
- package/package.json +3 -2
- package/runtime/browser.d.ts +14 -0
- package/runtime/browser.mjs +88 -0
- package/runtime/core/arrays.d.ts +18 -0
- package/runtime/core/arrays.mjs +125 -0
- package/runtime/core/checks.mjs +20 -0
- package/runtime/core/host.d.ts +70 -0
- package/runtime/core/host.mjs +311 -0
- package/runtime/core/numbers.d.ts +53 -0
- package/runtime/core/numbers.mjs +316 -0
- package/runtime/core/result.d.ts +41 -0
- package/runtime/core/result.mjs +127 -0
- package/runtime/core/strings.d.ts +14 -0
- package/runtime/core/strings.mjs +169 -0
- package/runtime/core.d.ts +9 -0
- package/runtime/core.mjs +55 -0
- package/runtime/host.d.ts +6 -0
- package/runtime/nish.d.ts +99 -5
- package/runtime/nish.h +289 -19
- package/runtime/nish.mjs +39 -3
- package/runtime/node.mjs +383 -0
- package/runtime/runtime-aes.c +490 -0
- package/runtime/runtime-bytes.c +401 -0
- package/runtime/runtime-cross.c +366 -0
- package/runtime/runtime-host.c +8 -7
- package/runtime/runtime-net.c +93 -34
- package/runtime/runtime-os.c +214 -16
- package/runtime/runtime-parallel.c +590 -107
- package/runtime/runtime-simd.c +235 -11
- package/runtime/runtime-term.c +504 -0
- package/runtime/runtime-wasm.c +5 -14
- package/runtime/runtime.c +257 -17
- package/runtime/shim.mjs +6 -915
- package/runtime/sqlite/LICENSE.md +85 -0
- package/runtime/sqlite/README.md +45 -0
- package/runtime/sqlite/nish-sqlite.c +359 -0
- package/runtime/sqlite/sqlite3.c +271131 -0
- package/runtime/sqlite/sqlite3.h +14447 -0
- package/scripts/build.sh +437 -28
- package/std/LICENSE-fast-float +23 -0
- package/std/LICENSE-fdlibm +8 -0
- package/std/README.md +108 -58
- package/std/base64.ts +116 -0
- package/std/bytes.ts +419 -0
- package/std/cli.ts +328 -0
- package/std/collections.ts +6 -5
- package/std/crypto/LICENSE-crypt_blowfish +26 -0
- package/std/crypto/LICENSE-libsecp256k1 +19 -0
- package/std/crypto/aes.ts +238 -76
- package/std/crypto/base64url.ts +125 -0
- package/std/crypto/bcrypt.ts +760 -0
- package/std/crypto/chacha20poly1305.ts +43 -9
- package/std/crypto/ed25519.ts +840 -0
- package/std/crypto/hkdf.ts +304 -12
- package/std/crypto/hmac.ts +382 -54
- package/std/crypto/p256.ts +932 -61
- package/std/crypto/x25519.ts +55 -37
- package/std/crypto/x509-random.ts +71 -0
- package/std/crypto/x509.ts +20 -131
- package/std/json-tokenizer.ts +4237 -0
- package/std/json-typed.ts +1014 -0
- package/std/json-value.ts +1182 -0
- package/std/json.ts +1202 -34
- package/std/math.ts +608 -0
- package/std/net/buffer-pool.ts +151 -0
- package/std/net/hpack.ts +416 -112
- package/std/net/http-fields.ts +93 -0
- package/std/net/http1-server.ts +501 -62
- package/std/net/http1.ts +31 -6
- package/std/net/http2-tls.ts +112 -24
- package/std/net/http2.ts +333 -75
- package/std/net/http3-server.ts +261 -43
- package/std/net/http3.ts +187 -28
- package/std/net/postgres.ts +1875 -0
- package/std/net/prefork.ts +412 -0
- package/std/net/quic-listener.ts +108 -11
- package/std/net/quic-packet.ts +243 -82
- package/std/net/quic-recovery.ts +361 -30
- package/std/net/quic-stream.ts +424 -24
- package/std/net/quic.ts +519 -167
- package/std/net/router.ts +676 -0
- package/std/net/tls/codec.ts +426 -27
- package/std/net/tls/record-server.ts +478 -132
- package/std/net/tls/record.ts +133 -42
- package/std/net/tls/schedule.ts +464 -55
- package/std/net/tls/ticket.ts +610 -0
- package/std/net/tls-tcp.ts +196 -53
- package/std/net/tls.ts +1018 -260
- package/std/net/url.ts +571 -0
- package/std/random.ts +94 -0
- package/std/regex.ts +4274 -0
- package/std/sqlite.ts +391 -0
- package/std/term-io.ts +978 -0
- package/std/term-pixels.ts +874 -0
- package/std/term-probe.ts +459 -0
- package/std/term-rate.ts +993 -0
- package/std/term.ts +2453 -0
- package/std/text.ts +90 -7
- package/std/threads.ts +438 -14
- package/std/yaml-lines.ts +141 -0
- package/std/yaml.ts +4675 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The strings of the core: an Nish string is its UTF-8 bytes, so every length
|
|
3
|
+
* and offset here counts bytes. Only the web's `TextEncoder` and `TextDecoder`
|
|
4
|
+
* are used, and the decoder keeps a leading byte-order mark, as a cut through
|
|
5
|
+
* the bytes must. Decoding is lossy where native is not: bytes that are not
|
|
6
|
+
* UTF-8, or a cut through a character, decode to U+FFFD, whose three bytes
|
|
7
|
+
* then change the string's length.
|
|
8
|
+
*/
|
|
9
|
+
import { panicIndex, panicSlice, toIndex } from "./checks.mjs";
|
|
10
|
+
|
|
11
|
+
const ENCODER = new TextEncoder();
|
|
12
|
+
const DECODER = new TextDecoder("utf-8", { ignoreBOM: true });
|
|
13
|
+
|
|
14
|
+
/** The string `bytesOf` encoded last, and its bytes. */
|
|
15
|
+
let lastString = "";
|
|
16
|
+
let lastBytes = new Uint8Array(0);
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The UTF-8 bytes of `s`, which is what an Nish string holds. The last string
|
|
20
|
+
* encoded is kept with its bytes, so a loop of `s.charCodeAt(i)` over one
|
|
21
|
+
* string encodes it once rather than once per byte. Nothing here writes to
|
|
22
|
+
* the bytes it is handed.
|
|
23
|
+
*/
|
|
24
|
+
function bytesOf(s) {
|
|
25
|
+
if (s !== lastString) {
|
|
26
|
+
lastBytes = ENCODER.encode(s);
|
|
27
|
+
lastString = s;
|
|
28
|
+
}
|
|
29
|
+
return lastBytes;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* `s.length`: UTF-8 byte length for strings (arrays keep their own `.length`).
|
|
34
|
+
* The engine's encoder outruns a count in JavaScript, and the loop condition
|
|
35
|
+
* `i < s.length` then leaves the bytes for the `s.charCodeAt(i)` it guards.
|
|
36
|
+
*/
|
|
37
|
+
export function strLen(x) {
|
|
38
|
+
return typeof x === "string" ? bytesOf(x).length : x.length;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* `s?.length` in a `?.` chain: `undefined` when the chain has stopped at a
|
|
43
|
+
* `null` or `undefined` link, as `?.` answers, and the byte length otherwise.
|
|
44
|
+
* The chain is its argument, so it is evaluated once and its short circuit
|
|
45
|
+
* kept.
|
|
46
|
+
*/
|
|
47
|
+
export function strLenOpt(x) {
|
|
48
|
+
return x === null || x === undefined ? undefined : strLen(x);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** `s.charCodeAt(i)`: the byte at `i`, bounds-checked as `a[i]` is (JavaScript answers NaN). */
|
|
52
|
+
export function charCodeAt(s, i) {
|
|
53
|
+
const bytes = bytesOf(s);
|
|
54
|
+
const k = toIndex(i);
|
|
55
|
+
if (!(k >= 0 && k < bytes.length)) panicIndex(k, bytes.length);
|
|
56
|
+
return bytes[k];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** `s.substring(a, b)`: JavaScript's clamp and swap, over byte offsets. */
|
|
60
|
+
export function substring(s, a, b) {
|
|
61
|
+
const bytes = bytesOf(s);
|
|
62
|
+
const clamp = (v) => Math.max(0, Math.min(toIndex(v), bytes.length));
|
|
63
|
+
const from = clamp(a);
|
|
64
|
+
const to = b === undefined ? bytes.length : clamp(b);
|
|
65
|
+
return DECODER.decode(bytes.subarray(Math.min(from, to), Math.max(from, to)));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* `s.slice(a, b)`: the bytes of `[a, b)` with no clamp, `b` defaulting to the
|
|
70
|
+
* byte length (WP15 §4). Out of range panics rather than clamping, so the two
|
|
71
|
+
* compares the native code emits are reproduced here rather than JavaScript's
|
|
72
|
+
* negative-from-the-end rule.
|
|
73
|
+
*/
|
|
74
|
+
export function slice(s, a, b) {
|
|
75
|
+
const bytes = bytesOf(s);
|
|
76
|
+
const from = toIndex(a);
|
|
77
|
+
const to = b === undefined ? bytes.length : toIndex(b);
|
|
78
|
+
if (!(from >= 0 && from <= to && to <= bytes.length)) panicSlice(from, to, bytes.length);
|
|
79
|
+
return DECODER.decode(bytes.subarray(from, to));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Whether `needle` sits in `bytes` at byte offset `at`. */
|
|
83
|
+
function bytesAt(bytes, at, needle) {
|
|
84
|
+
if (!(at >= 0 && at + needle.length <= bytes.length)) return false;
|
|
85
|
+
for (let j = 0; j < needle.length; j++) {
|
|
86
|
+
if (bytes[at + j] !== needle[j]) return false;
|
|
87
|
+
}
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* `s.indexOf(sub, from)`: the first *byte* offset at or after `from`, or -1.
|
|
93
|
+
* `from` is converted as JavaScript's `ToIntegerOrInfinity` converts it (NaN
|
|
94
|
+
* is 0) and clamped into `[0, len]`, so an empty `sub` is found at `from`.
|
|
95
|
+
* The engine's `indexOf` over the bytes finds each candidate for `sub`'s
|
|
96
|
+
* first byte, and only those are compared in full.
|
|
97
|
+
*/
|
|
98
|
+
export function indexOf(s, sub, from) {
|
|
99
|
+
const haystack = bytesOf(s);
|
|
100
|
+
const at = from === undefined ? 0 : toIndex(from);
|
|
101
|
+
const start = Number.isNaN(at) ? 0 : Math.max(0, Math.min(at, haystack.length));
|
|
102
|
+
if (sub.length === 0) return start;
|
|
103
|
+
const needle = ENCODER.encode(sub);
|
|
104
|
+
const last = haystack.length - needle.length;
|
|
105
|
+
for (let i = haystack.indexOf(needle[0], start); i >= 0 && i <= last; i = haystack.indexOf(needle[0], i + 1)) {
|
|
106
|
+
if (bytesAt(haystack, i, needle)) return i;
|
|
107
|
+
}
|
|
108
|
+
return -1;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** `nish_str_at`: whether `sub`'s bytes sit at byte offset `at`. */
|
|
112
|
+
function occursAt(s, at, sub) {
|
|
113
|
+
return bytesAt(bytesOf(s), at, ENCODER.encode(sub));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function startsWith(s, sub) {
|
|
117
|
+
return occursAt(s, 0, sub);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function endsWith(s, sub) {
|
|
121
|
+
const bytes = bytesOf(s);
|
|
122
|
+
const needle = ENCODER.encode(sub);
|
|
123
|
+
return bytesAt(bytes, bytes.length - needle.length, needle);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* `String.fromCharCode(c)`: the one-unit string of `c & 0xFF`. Under 128 that
|
|
128
|
+
* is the one byte native builds; from 128 it is the Latin-1 character, two
|
|
129
|
+
* UTF-8 bytes where native holds one (LANGUAGE.md's C row).
|
|
130
|
+
*/
|
|
131
|
+
export function fromCharCode(code) {
|
|
132
|
+
return String.fromCharCode(toIndex(code) & 0xff);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* `String.fromBytes(bytes, start, end)`: the bytes of `[start, end)`, one
|
|
137
|
+
* code unit each as `fromCharCode` builds them, checked as `s.slice`'s range
|
|
138
|
+
* is and failing with its panic. The copy into a `Uint8Array` reduces each
|
|
139
|
+
* element to a byte as a `Buffer` store does, and the string is built a chunk
|
|
140
|
+
* at a time so that no call passes more arguments than the engine takes.
|
|
141
|
+
*/
|
|
142
|
+
export function fromBytes(bytes, start, end) {
|
|
143
|
+
const from = toIndex(start);
|
|
144
|
+
const to = toIndex(end);
|
|
145
|
+
if (!(from >= 0 && from <= to && to <= bytes.length)) panicSlice(from, to, bytes.length);
|
|
146
|
+
const out = new Uint8Array(to - from);
|
|
147
|
+
for (let i = from; i < to; i++) out[i - from] = bytes[i];
|
|
148
|
+
let text = "";
|
|
149
|
+
for (let i = 0; i < out.length; i += 8192) {
|
|
150
|
+
text += String.fromCharCode.apply(null, out.subarray(i, i + 8192));
|
|
151
|
+
}
|
|
152
|
+
return text;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* `String.fromBytes(bytes, start, end)` as `--emit-ts` writes it: the bytes of
|
|
157
|
+
* `[start, end)` decoded as UTF-8, which is the string a native program holds,
|
|
158
|
+
* checked as `fromBytes`'s range is. A sequence that is not UTF-8 decodes to
|
|
159
|
+
* U+FFFD where native keeps the bytes. `fromBytes` above stays the
|
|
160
|
+
* one-unit-per-byte reading the prelude's programs are pinned to.
|
|
161
|
+
*/
|
|
162
|
+
export function utf8FromBytes(bytes, start, end) {
|
|
163
|
+
const from = toIndex(start);
|
|
164
|
+
const to = toIndex(end);
|
|
165
|
+
if (!(from >= 0 && from <= to && to <= bytes.length)) panicSlice(from, to, bytes.length);
|
|
166
|
+
const out = new Uint8Array(to - from);
|
|
167
|
+
for (let i = from; i < to; i++) out[i - from] = bytes[i];
|
|
168
|
+
return DECODER.decode(out);
|
|
169
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `nish/runtime`: the host-agnostic core (runtime/core.mjs). Pair it with
|
|
3
|
+
* `nish/runtime/node` or `nish/runtime/browser`, which install a host.
|
|
4
|
+
*/
|
|
5
|
+
export * from "./core/arrays.js";
|
|
6
|
+
export * from "./core/host.js";
|
|
7
|
+
export * from "./core/numbers.js";
|
|
8
|
+
export * from "./core/result.js";
|
|
9
|
+
export * from "./core/strings.js";
|
package/runtime/core.mjs
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nish builtins, host-agnostic (WP13 differential testing, WP33 R3).
|
|
3
|
+
*
|
|
4
|
+
* The differential runner (tests/differential/run.js) rewrites an Nish
|
|
5
|
+
* program into plain JavaScript and runs it under Node with this module as
|
|
6
|
+
* `__nish` (`runtime/shim.mjs`, which is this core with `runtime/node.mjs`
|
|
7
|
+
* installed as its host). Every helper here reproduces the *runtime* semantics the compiled
|
|
8
|
+
* binary has (runtime/runtime.c and runtime/runtime-os.c, the system-call half,
|
|
9
|
+
* plus the intrinsics in docs/wp7-runtime.md) where JavaScript's own semantics
|
|
10
|
+
* differ:
|
|
11
|
+
*
|
|
12
|
+
* - `number` is a 32-bit integer in the default mode (`--number-mode i32`),
|
|
13
|
+
* `i64` is a 64-bit integer, both wrapping; JS has doubles and BigInt.
|
|
14
|
+
* - `u8`/`u16`/`u32`/`u64` are unsigned and wrapping, and JavaScript has no
|
|
15
|
+
* unsigned integers at all: the narrow three live in a `number` masked
|
|
16
|
+
* back into range (`& 0xFF`, `& 0xFFFF`, `>>> 0`) and `u64` is a BigInt
|
|
17
|
+
* kept in range with `BigInt.asUintN(64, x)`.
|
|
18
|
+
* - `f32` is a 32-bit float and JavaScript has only doubles, so every `f32`
|
|
19
|
+
* result is rounded with `Math.fround`.
|
|
20
|
+
* - `s.length` is the UTF-8 byte length, and so is every index the string
|
|
21
|
+
* methods take or return: `charCodeAt` yields a byte (and bounds-checks
|
|
22
|
+
* instead of returning `NaN`), `substring` cuts on byte offsets, and
|
|
23
|
+
* `indexOf` answers with one. `slice` cuts on byte offsets too and panics
|
|
24
|
+
* on a range the string does not contain, where JavaScript would clamp and
|
|
25
|
+
* read a negative offset from the end. `String.fromCharCode` builds a
|
|
26
|
+
* one-byte string from the low 8 bits, and `String.fromBytes` one such
|
|
27
|
+
* string per byte of its range.
|
|
28
|
+
* - `a[i]` is bounds-checked: out of range prints
|
|
29
|
+
* `index out of range: <i> >= <len>` to stderr and exits 1, and so is
|
|
30
|
+
* `a.pop()` on an empty array, which has no `undefined` to return.
|
|
31
|
+
* - `toI32/toI64` from f64 saturate (NaN -> 0), integer conversions wrap.
|
|
32
|
+
* - `console.log(x)` never prints the `n` suffix of an i64 and writes
|
|
33
|
+
* synchronously so `process.exit` cannot lose output.
|
|
34
|
+
* - file I/O errors print `nish: cannot read <path>` and exit 1.
|
|
35
|
+
* - a directory listing is sorted by UTF-8 bytes, which is `strcmp`'s order
|
|
36
|
+
* and not `Array#sort`'s UTF-16 one; `monotonicNanos` reads a clock whose
|
|
37
|
+
* origin is arbitrary, so two readings can agree with a native run and a
|
|
38
|
+
* single reading never can.
|
|
39
|
+
* - `process.argv[0]` is the program (the script here, the executable
|
|
40
|
+
* natively); `parseInt` is base 10 only and saturates into i32 (0 for no
|
|
41
|
+
* digits); `parseFloat`/`Number` accept ASCII whitespace, decimal forms,
|
|
42
|
+
* `Infinity`, and a `0x` hex prefix (parseFloat too, unlike JS).
|
|
43
|
+
*
|
|
44
|
+
* The core names no `node:` module and neither `process` nor `Buffer`: what it
|
|
45
|
+
* needs of the world goes through the host `runtime/core/host.mjs` holds, so
|
|
46
|
+
* another adapter can stand where `runtime/node.mjs` stands. A check in
|
|
47
|
+
* `tests/run.js` (`runtime-hosts`) holds it to that.
|
|
48
|
+
*
|
|
49
|
+
* The rewrite rules that call these helpers are listed in docs/wp13-differential.md.
|
|
50
|
+
*/
|
|
51
|
+
export * from "./core/arrays.mjs";
|
|
52
|
+
export * from "./core/host.mjs";
|
|
53
|
+
export * from "./core/numbers.mjs";
|
|
54
|
+
export * from "./core/result.mjs";
|
|
55
|
+
export * from "./core/strings.mjs";
|
package/runtime/nish.d.ts
CHANGED
|
@@ -112,10 +112,10 @@ declare function Err<T, E>(error: E): Result<T, E>;
|
|
|
112
112
|
|
|
113
113
|
/**
|
|
114
114
|
* The disposable protocol `using` reads (WP29 P2, docs/wp29-thread-surface.md
|
|
115
|
-
* §5): declared here so that a program using `nish/threads`'s scope
|
|
116
|
-
* `arena()` needs no `"ESNext.Disposable"` in its `lib`.
|
|
117
|
-
* `using` only for a `scope()
|
|
118
|
-
* `nish/threads`.
|
|
115
|
+
* §5): declared here so that a program using `nish/threads`'s scope, a
|
|
116
|
+
* `Mutex`'s lock or `arena()` needs no `"ESNext.Disposable"` in its `lib`.
|
|
117
|
+
* `nish` itself takes `using` only for a `scope()`, a `lock()` or an
|
|
118
|
+
* `arena()`, and `[Symbol.dispose]` only in `nish/threads`.
|
|
119
119
|
*/
|
|
120
120
|
interface SymbolConstructor {
|
|
121
121
|
readonly dispose: unique symbol;
|
|
@@ -124,6 +124,16 @@ interface Disposable {
|
|
|
124
124
|
[Symbol.dispose](): void;
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
+
/**
|
|
128
|
+
* `String.fromBytes` is Nish's, not JavaScript's, so it merges into the
|
|
129
|
+
* `StringConstructor` `lib.es2022` declares. Under `runtime/nish.mjs` each byte
|
|
130
|
+
* becomes one UTF-16 unit, as `String.fromCharCode`'s does.
|
|
131
|
+
*/
|
|
132
|
+
interface StringConstructor {
|
|
133
|
+
/** The bytes of `bytes[start..end)` as one string; panics unless `0 <= start <= end <= bytes.length`. */
|
|
134
|
+
fromBytes(bytes: readonly u8[], start: number, end: number): string;
|
|
135
|
+
}
|
|
136
|
+
|
|
127
137
|
interface Console {
|
|
128
138
|
/** `x` and a newline to stdout. Statement position; exactly one argument. */
|
|
129
139
|
log(x: string | number | boolean): void;
|
|
@@ -161,6 +171,8 @@ declare function toF64(x: number | boolean): f64;
|
|
|
161
171
|
/** Reinterpret the 64 bits of an `f64`, never convert the value. */
|
|
162
172
|
declare function f64ToBits(x: f64): i64;
|
|
163
173
|
declare function bitsToF64(bits: i64): f64;
|
|
174
|
+
/** Reinterpret the 32 bits of an `f32`, never convert the value. */
|
|
175
|
+
declare function f32ToBits(x: f32): i32;
|
|
164
176
|
|
|
165
177
|
// ---- Constant time (WP34 N6) ------------------------------------------------
|
|
166
178
|
|
|
@@ -193,7 +205,7 @@ declare function isExecutableSync(path: string): boolean;
|
|
|
193
205
|
// ---- Unsafe (`nish:unsafe`) --------------------------------------------------
|
|
194
206
|
//
|
|
195
207
|
// Declared as globals so `tsc` reads a program that imports them, as every
|
|
196
|
-
// `nish:` export is, but `nish` refuses a call to any of the
|
|
208
|
+
// `nish:` export is, but `nish` refuses a call to any of the six that is not
|
|
197
209
|
// imported from `nish:unsafe`: the import is the module's visible opt-in.
|
|
198
210
|
|
|
199
211
|
/** `xs[i]` with no bounds check: undefined behaviour when `i` is out of range. */
|
|
@@ -206,6 +218,8 @@ declare function wrappingAdd<T extends i32 | i64>(a: T, b: T): T;
|
|
|
206
218
|
declare function wrappingSub<T extends i32 | i64>(a: T, b: T): T;
|
|
207
219
|
/** `a * b` wrapped to the operands' width. */
|
|
208
220
|
declare function wrappingMul<T extends i32 | i64>(a: T, b: T): T;
|
|
221
|
+
/** The `NUL`-terminated bytes at `p`, copied into a string: undefined behaviour unless `p` is a live C string. */
|
|
222
|
+
declare function readCString(p: CPtr): string;
|
|
209
223
|
|
|
210
224
|
// ---- Streams and files (globals: Nish has no package resolution) ---------
|
|
211
225
|
|
|
@@ -266,6 +280,28 @@ declare function spawnSync(argv: string[]): number;
|
|
|
266
280
|
* either path is refused, as `writeFileSync` refuses one, and the answer is -1.
|
|
267
281
|
*/
|
|
268
282
|
declare function spawnSyncTo(argv: string[], stdoutPath: string, stderrPath: string): number;
|
|
283
|
+
/**
|
|
284
|
+
* Start `argv[0]` through `PATH` without waiting: the child's pid, or a
|
|
285
|
+
* negative errno. The child is the program's until `waitPid` reaps it. No
|
|
286
|
+
* reading under Node, which throws.
|
|
287
|
+
*/
|
|
288
|
+
declare function spawn(argv: string[]): i32;
|
|
289
|
+
/**
|
|
290
|
+
* Send `sig` to `pid`: 0, or a negative errno (-3 when no such process). `sig`
|
|
291
|
+
* is 0, 2, 9 or 15, and anything else, like a `pid` of 0 or below, is -22.
|
|
292
|
+
*/
|
|
293
|
+
declare function kill(pid: i32, sig: i32): i32;
|
|
294
|
+
/**
|
|
295
|
+
* Wait for the child `pid`, or any child for -1: `[pid, status]`, the status
|
|
296
|
+
* as `spawnSync` answers it. Flag 1 is WNOHANG, under which `[0, 0]` means a
|
|
297
|
+
* child remains and none has exited; a failure is `[-errno, 0]`, `[-10, 0]`
|
|
298
|
+
* with no child to wait for. No reading under Node, which throws.
|
|
299
|
+
*/
|
|
300
|
+
declare function waitPid(pid: i32, flags: i32): i32[];
|
|
301
|
+
/** How many CPUs the program may use: at least 1, with or without `--threads`. */
|
|
302
|
+
declare function availableParallelism(): i32;
|
|
303
|
+
/** Bytes of physical memory, or -1 when the host does not say. */
|
|
304
|
+
declare function totalMemory(): i64;
|
|
269
305
|
/** One environment variable, or `null` when it is unset (an empty value is a set variable). */
|
|
270
306
|
declare function getenv(name: string): string | null;
|
|
271
307
|
/**
|
|
@@ -305,6 +341,8 @@ declare function netAddress(out: u8[], host: string, port: i32): i32;
|
|
|
305
341
|
declare function netLocalPort(fd: i32): i32;
|
|
306
342
|
/** A listening TCP socket with `SO_REUSEADDR`; `"::"` hears IPv4 and IPv6. */
|
|
307
343
|
declare function tcpListen(host: string, port: i32, backlog: i32): i32;
|
|
344
|
+
/** `tcpListen`'s socket, with `SO_REUSEPORT` for flag 1 and `TCP_NODELAY` on each accepted socket for flag 2; any other bit is -22. */
|
|
345
|
+
declare function tcpListenFlags(host: string, port: i32, backlog: i32, flags: i32): i32;
|
|
308
346
|
/** The next connection's descriptor, its address in `peer`; -11 when none waits. */
|
|
309
347
|
declare function tcpAccept(fd: i32, peer: u8[]): i32;
|
|
310
348
|
/** Up to `len` bytes into `buf` from `off`: the count, 0 at end of stream, or -11. */
|
|
@@ -344,6 +382,33 @@ declare function pollRemove(loop: i32, fd: i32): i32;
|
|
|
344
382
|
/** Wait up to `timeoutMs` (negative: forever); pairs `ready[2k]` token, `ready[2k + 1]` events (4: hang-up or error). */
|
|
345
383
|
declare function pollWait(loop: i32, ready: i32[], timeoutMs: i32): i32;
|
|
346
384
|
|
|
385
|
+
// ---- `nish:term` ------------------------------------------------------------------
|
|
386
|
+
//
|
|
387
|
+
// stdin without blocking and the terminal it may be: the frame clock and the
|
|
388
|
+
// keys of a terminal UI, with no `net` capability. -11 is "nothing is
|
|
389
|
+
// waiting" and -25 "not a terminal" on every platform; any other failure is
|
|
390
|
+
// the host's `-errno`. Under WASI the reading works, `readStdin` waiting for
|
|
391
|
+
// its bytes (ask `waitStdin` first), and the terminal answers -25. Under Node `isTerminal` and `terminalSize` answer and the other four
|
|
392
|
+
// throw.
|
|
393
|
+
|
|
394
|
+
/** Up to `len` bytes of stdin into `buf` from `off`, never blocking: the count, 0 at end of stream, or -11 when nothing is waiting. */
|
|
395
|
+
declare function readStdin(buf: u8[], off: i32, len: i32): i32;
|
|
396
|
+
/** Wait up to `timeoutMs` (negative: forever) for stdin to be readable (its end and an error count): `true` when it is, `false` when the time passed. */
|
|
397
|
+
declare function waitStdin(timeoutMs: i32): boolean;
|
|
398
|
+
/** Whether descriptor `fd` is a terminal (`isatty`). */
|
|
399
|
+
declare function isTerminal(fd: i32): boolean;
|
|
400
|
+
/** `[columns, rows]` of the terminal on stdout, else stderr; `[-25, 0]` when neither is one, `[0, 0]` when it has no size set. */
|
|
401
|
+
declare function terminalSize(): i32[];
|
|
402
|
+
/**
|
|
403
|
+
* Raw mode on stdin's terminal, or the mode it had back: 0, -25 when stdin is
|
|
404
|
+
* not a terminal. No echo, no line editing; Ctrl-C stays SIGINT and "\n"
|
|
405
|
+
* still starts a line. The terminal is put back at exit, on a panic and on
|
|
406
|
+
* every signal that ends the program, SIGKILL aside.
|
|
407
|
+
*/
|
|
408
|
+
declare function setRawMode(on: boolean): i32;
|
|
409
|
+
/** Bytes the runtime writes to the terminal on stdout at exit, on a panic and on every signal that ends the program (SIGKILL aside), before termios is restored. Replaces the previous string; "" clears it. 0, -25 when stdout is not a terminal, -7 (E2BIG) past NISH_TERM_RESTORE_MAX bytes. The cap is 4096 bytes. */
|
|
410
|
+
declare function setTerminalRestore(bytes: string): i32;
|
|
411
|
+
|
|
347
412
|
// ---- `Date` and `crypto` (WP34 N3) -----------------------------------------------
|
|
348
413
|
//
|
|
349
414
|
// `lib.es2022` already declares `Date`, whose `now()` is Nish's one member of it,
|
|
@@ -400,6 +465,16 @@ declare module "nish:process" {
|
|
|
400
465
|
* at either path is refused, and the answer is -1.
|
|
401
466
|
*/
|
|
402
467
|
export function spawnSyncTo(argv: string[], stdoutPath: string, stderrPath: string): number;
|
|
468
|
+
/** Start a child without waiting: its pid, or a negative errno. */
|
|
469
|
+
export function spawn(argv: string[]): i32;
|
|
470
|
+
/** Send 0, 2, 9 or 15 to `pid`: 0, or a negative errno; any other signal is -22. */
|
|
471
|
+
export function kill(pid: i32, sig: i32): i32;
|
|
472
|
+
/** `[pid, status]` for a child that exited, `[0, 0]` under WNOHANG (flag 1) with none, or `[-errno, 0]`. */
|
|
473
|
+
export function waitPid(pid: i32, flags: i32): i32[];
|
|
474
|
+
/** How many CPUs the program may use, at least 1. */
|
|
475
|
+
export function availableParallelism(): i32;
|
|
476
|
+
/** Bytes of physical memory, or -1. */
|
|
477
|
+
export function totalMemory(): i64;
|
|
403
478
|
/**
|
|
404
479
|
* A monotonic clock in nanoseconds. The origin is arbitrary, so only the
|
|
405
480
|
* difference between two reads is meaningful.
|
|
@@ -424,6 +499,8 @@ declare module "nish:net" {
|
|
|
424
499
|
export function netLocalPort(fd: i32): i32;
|
|
425
500
|
/** A listening TCP socket with `SO_REUSEADDR`; `"::"` hears IPv4 and IPv6. */
|
|
426
501
|
export function tcpListen(host: string, port: i32, backlog: i32): i32;
|
|
502
|
+
/** `tcpListen`'s socket, with `SO_REUSEPORT` for flag 1 and `TCP_NODELAY` on each accepted socket for flag 2; any other bit is -22. */
|
|
503
|
+
export function tcpListenFlags(host: string, port: i32, backlog: i32, flags: i32): i32;
|
|
427
504
|
/** The next connection's descriptor, its address in `peer`; -11 when none waits. */
|
|
428
505
|
export function tcpAccept(fd: i32, peer: u8[]): i32;
|
|
429
506
|
/** Up to `len` bytes into `buf` from `off`: the count, 0 at end of stream, or -11. */
|
|
@@ -474,6 +551,8 @@ declare module "nish:unsafe" {
|
|
|
474
551
|
export function wrappingSub<T extends i32 | i64>(a: T, b: T): T;
|
|
475
552
|
/** `a * b` wrapped to the operands' width. */
|
|
476
553
|
export function wrappingMul<T extends i32 | i64>(a: T, b: T): T;
|
|
554
|
+
/** The `NUL`-terminated bytes at `p`, copied into a string: undefined behaviour unless `p` is a live C string. */
|
|
555
|
+
export function readCString(p: CPtr): string;
|
|
477
556
|
}
|
|
478
557
|
|
|
479
558
|
declare module "nish:io" {
|
|
@@ -485,6 +564,21 @@ declare module "nish:io" {
|
|
|
485
564
|
export function panic(message: string): never;
|
|
486
565
|
}
|
|
487
566
|
|
|
567
|
+
declare module "nish:term" {
|
|
568
|
+
/** Up to `len` bytes of stdin into `buf` from `off`, never blocking: the count, 0 at end of stream, or -11 when nothing is waiting. */
|
|
569
|
+
export function readStdin(buf: u8[], off: i32, len: i32): i32;
|
|
570
|
+
/** Wait up to `timeoutMs` (negative: forever) for stdin to be readable (its end and an error count): `true` when it is, `false` when the time passed. */
|
|
571
|
+
export function waitStdin(timeoutMs: i32): boolean;
|
|
572
|
+
/** Whether descriptor `fd` is a terminal (`isatty`). */
|
|
573
|
+
export function isTerminal(fd: i32): boolean;
|
|
574
|
+
/** `[columns, rows]` of the terminal on stdout, else stderr; `[-25, 0]` when neither is one, `[0, 0]` when it has no size set. */
|
|
575
|
+
export function terminalSize(): i32[];
|
|
576
|
+
/** Raw mode on stdin's terminal (0), or the mode it had back; -25 when stdin is not a terminal. Restored at exit, on a panic and on every signal that ends the program, SIGKILL aside. */
|
|
577
|
+
export function setRawMode(on: boolean): i32;
|
|
578
|
+
/** Bytes the runtime writes to the terminal on stdout at exit, on a panic and on every signal that ends the program (SIGKILL aside), before termios is restored. Replaces the previous string; "" clears it. 0, -25 when stdout is not a terminal, -7 (E2BIG) past NISH_TERM_RESTORE_MAX bytes. */
|
|
579
|
+
export function setTerminalRestore(bytes: string): i32;
|
|
580
|
+
}
|
|
581
|
+
|
|
488
582
|
// `nish:secret` has source behind it, `std/secret.ts`, but a program imports it
|
|
489
583
|
// by this name, so `tsc` reads these declarations rather than that file. The
|
|
490
584
|
// class is declared with a private constructor and a private field: `tsc` then
|