@amritk/nish-x86_64-linux 0.20.0 → 0.22.1

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.
Files changed (74) hide show
  1. package/INSTALL.md +52 -10
  2. package/bin/nish +0 -0
  3. package/docs/AI.md +2777 -0
  4. package/package.json +2 -1
  5. package/runtime/browser.d.ts +6 -0
  6. package/runtime/browser.mjs +77 -0
  7. package/runtime/core/arrays.d.ts +36 -0
  8. package/runtime/core/arrays.mjs +153 -0
  9. package/runtime/core/checks.mjs +20 -0
  10. package/runtime/core/host.d.ts +80 -0
  11. package/runtime/core/host.mjs +325 -0
  12. package/runtime/core/numbers.d.ts +66 -0
  13. package/runtime/core/numbers.mjs +343 -0
  14. package/runtime/core/result.d.ts +45 -0
  15. package/runtime/core/result.mjs +140 -0
  16. package/runtime/core/strings.d.ts +14 -0
  17. package/runtime/core/strings.mjs +169 -0
  18. package/runtime/core.d.ts +9 -0
  19. package/runtime/core.mjs +55 -0
  20. package/runtime/host.d.ts +6 -0
  21. package/runtime/nish.d.ts +46 -2
  22. package/runtime/nish.h +75 -2
  23. package/runtime/nish.mjs +23 -3
  24. package/runtime/node.mjs +386 -0
  25. package/runtime/runtime-bytes.c +401 -0
  26. package/runtime/runtime-cross.c +1 -1
  27. package/runtime/runtime-host.c +1 -1
  28. package/runtime/runtime-net.c +12 -1
  29. package/runtime/runtime-os.c +1 -1
  30. package/runtime/runtime-parallel.c +1 -1
  31. package/runtime/runtime-simd.c +231 -7
  32. package/runtime/runtime-term.c +504 -0
  33. package/runtime/runtime-wasm.c +0 -11
  34. package/runtime/runtime.c +190 -6
  35. package/runtime/shim.mjs +6 -985
  36. package/runtime/sqlite/LICENSE.md +85 -0
  37. package/runtime/sqlite/README.md +45 -0
  38. package/runtime/sqlite/nish-sqlite.c +359 -0
  39. package/runtime/sqlite/sqlite3.c +271131 -0
  40. package/runtime/sqlite/sqlite3.h +14447 -0
  41. package/scripts/build.sh +311 -59
  42. package/std/LICENSE-fast-float +23 -0
  43. package/std/LICENSE-fdlibm +8 -0
  44. package/std/README.md +32 -12
  45. package/std/base64.ts +116 -0
  46. package/std/bytes.ts +256 -0
  47. package/std/cli.ts +344 -0
  48. package/std/collections.ts +6 -5
  49. package/std/crypto/LICENSE-crypt_blowfish +26 -0
  50. package/std/crypto/base64url.ts +125 -0
  51. package/std/crypto/bcrypt.ts +1557 -0
  52. package/std/crypto/hmac.ts +138 -2
  53. package/std/crypto/x509.ts +11 -122
  54. package/std/json-tokenizer.ts +2998 -57
  55. package/std/json-value.ts +22 -3
  56. package/std/json.ts +87 -8
  57. package/std/math.ts +608 -0
  58. package/std/net/http1-server.ts +282 -40
  59. package/std/net/http1.ts +40 -21
  60. package/std/net/http3-server.ts +50 -12
  61. package/std/net/postgres.ts +2294 -0
  62. package/std/net/prefork.ts +23 -3
  63. package/std/net/quic-listener.ts +20 -4
  64. package/std/random.ts +66 -4
  65. package/std/regex.ts +4274 -0
  66. package/std/sqlite.ts +391 -0
  67. package/std/term-io.ts +978 -0
  68. package/std/term-pixels.ts +874 -0
  69. package/std/term-probe.ts +459 -0
  70. package/std/term-rate.ts +993 -0
  71. package/std/term.ts +2453 -0
  72. package/std/text.ts +90 -7
  73. package/std/yaml-lines.ts +141 -0
  74. package/std/yaml.ts +4675 -0
package/scripts/build.sh CHANGED
@@ -3,20 +3,23 @@
3
3
  #
4
4
  # scripts/build.sh <module.ll> [more .ll/.c files...] -o <out> [--profile debug|speed|size|wasm|wasi|napi]
5
5
  #
6
- # The C runtime is eight translation units and is named as one: an input
6
+ # The C runtime is ten translation units and is named as one: an input
7
7
  # <dir>/runtime.c also compiles <dir>/runtime-os.c, the half that wraps the
8
8
  # system calls (files, directories, subprocesses, the environment, the clock),
9
9
  # <dir>/runtime-parallel.c, the half that divides a range of work across
10
10
  # threads, <dir>/runtime-cross.c, the copies that carry a string or an array
11
11
  # from one thread's arena to another's, <dir>/runtime-host.c, the wall clock, entropy, file times and
12
12
  # signals, <dir>/runtime-net.c, the sockets of `nish:net`,
13
- # <dir>/runtime-simd.c, the byte searches that read a vector at a time, and
14
- # <dir>/runtime-aes.c, AES-GCM on the CPU's AES instructions. Each of those
13
+ # <dir>/runtime-simd.c, the byte searches that read a vector at a time,
14
+ # <dir>/runtime-aes.c, AES-GCM on the CPU's AES instructions,
15
+ # <dir>/runtime-term.c, stdin and the terminal of `nish:term`, and
16
+ # <dir>/runtime-bytes.c, the byte-class runs of `nish/bytes`. Each of those
15
17
  # files says why they are compiled and measured apart.
16
18
  #
17
19
  # Profiles:
18
20
  # debug clang defaults: no optimisation, symbols kept. The "before" number.
19
- # speed -O3 + LTO + section GC + strip. Rust `--release` equivalent.
21
+ # speed -O3 + LTO + section GC + strip. Rust `--release` equivalent. With
22
+ # lld, LTO code generation runs on every core.
20
23
  # size -Oz + LTO + section GC + strip + no unwind tables. Rust
21
24
  # `opt-level="z"`, `panic="abort"`, `strip=true` equivalent.
22
25
  # wasm wasm32 freestanding module exporting every non-internal function;
@@ -68,6 +71,20 @@
68
71
  # stops with SIGILL on a CPU without AVX2. `nish --link --cpu x86-64-v3`
69
72
  # passes it through.
70
73
  #
74
+ # SQLite: an input .ll that declares an `sqlite3_*` or `nishsqlite_*` function
75
+ # also compiles and links every runtime/sqlite/*.c, the vendored amalgamation
76
+ # (runtime/sqlite/README.md). Any other program compiles none of it. sqlite3.c
77
+ # is compiled to native code at the profile's level, even where the profile
78
+ # compiles to LTO bitcode. The options are most of SQLite's recommended set
79
+ # (see the defaults below), with THREADSAFE=0 (=2 under --threads).
80
+ # NISH_SQLITE_CFLAGS is appended to them: its first line, split on whitespace
81
+ # with no quoting, and a relative -I in it names a directory below
82
+ # runtime/sqlite/, where each unit is compiled. A -D or -U in it for one of
83
+ # their names replaces it. The napi profile compiles SQLite -fPIC and
84
+ # -fvisibility=hidden, so an addon does not export its symbols. Every profile
85
+ # but wasm links it; wasm has no libc to build it on and is refused with exit 2.
86
+ # On wasi, SQLite locks with dot files and has no WAL shared memory.
87
+ #
71
88
  # The runtime compiled once (the debug, speed and size profiles only; `nish
72
89
  # --link` and `nish run` use these through their runtime cache, src/compile.ts):
73
90
  # --runtime-objects <dir> compile the runtime.c input and its seven siblings,
@@ -80,7 +97,13 @@
80
97
  # runtime.c input, after compiling every other input
81
98
  # with its own $CC -c, all at once. The link line is
82
99
  # the one the profile always uses.
83
- # Both refuse the wasm, wasi and napi profiles and --pgo-*, with exit 2.
100
+ # --sqlite-objects <dir> compile runtime/sqlite/*.c alone, into
101
+ # <dir>/<unit>.o, as a link of a program that calls
102
+ # SQLite would, and link nothing. Takes no inputs and
103
+ # no -o, and prints nothing on success.
104
+ # --sqlite-from <dir> link <dir>/<unit>.o in place of compiling
105
+ # runtime/sqlite/, when the IR calls SQLite.
106
+ # All four refuse the wasm, wasi and napi profiles and --pgo-*, with exit 2.
84
107
  #
85
108
  # Works on Linux (clang + lld preferred, GNU ld tolerated) and macOS (Apple ld64
86
109
  # or Homebrew llvm). Set CC to pick a compiler (default: clang on PATH).
@@ -95,6 +118,8 @@ threads=0 # --threads: -DNISH_THREADS, the thread-l
95
118
  objects_to="" # --runtime-objects <dir>: compile the runtime alone, into <dir>
96
119
  objects_from="" # --runtime-from <dir>: link against the runtime compiled there
97
120
  cpu="" # --cpu x86-64-v3: the one CPU level above the baseline (WP38 S2)
121
+ sqlite_to="" # --sqlite-objects <dir>: compile runtime/sqlite/ alone, into <dir>
122
+ sqlite_from="" # --sqlite-from <dir>: link runtime/sqlite/ compiled there
98
123
  while [ $# -gt 0 ]; do
99
124
  case "$1" in
100
125
  -o) out="$2"; shift 2 ;;
@@ -106,15 +131,17 @@ while [ $# -gt 0 ]; do
106
131
  cpu="$2"; shift 2 ;;
107
132
  --runtime-objects) objects_to="$2"; shift 2 ;;
108
133
  --runtime-from) objects_from="$2"; shift 2 ;;
134
+ --sqlite-objects) sqlite_to="$2"; shift 2 ;;
135
+ --sqlite-from) sqlite_from="$2"; shift 2 ;;
109
136
  --pgo-generate) pgo=(-fprofile-generate); shift ;;
110
137
  --pgo-use)
111
138
  [ -f "$2" ] || { echo "error: --pgo-use: profile '$2' not found (run the instrumented binary, then llvm-profdata merge)" >&2; exit 2; }
112
139
  pgo=("-fprofile-use=$2"); shift 2 ;;
113
- -h|--help) sed -n '2,85p' "$0"; exit 0 ;;
140
+ -h|--help) sed -n '2,/^set -euo pipefail$/{/^set -euo pipefail$/!p;}' "$0"; exit 0 ;; # the header, to the first command
114
141
  *) inputs+=("$1"); shift ;;
115
142
  esac
116
143
  done
117
- [ ${#inputs[@]} -gt 0 ] || { echo "error: no input files" >&2; exit 2; }
144
+ [ ${#inputs[@]} -gt 0 ] || [ -n "$sqlite_to" ] || { echo "error: no input files" >&2; exit 2; }
118
145
  if [ -n "$cpu" ]; then
119
146
  [ "$cpu" = x86-64-v3 ] || { echo "error: --cpu takes x86-64-v3, not '$cpu'" >&2; exit 2; }
120
147
  case "$profile" in
@@ -151,15 +178,27 @@ if [ -n "$objects_to" ] || [ -n "$objects_from" ]; then
151
178
  [ ${#pgo[@]} -eq 0 ] || { echo "error: --runtime-objects and --runtime-from do not take --pgo-*" >&2; exit 2; }
152
179
  [ -z "$objects_to" ] || [ -z "$objects_from" ] || { echo "error: --runtime-objects and --runtime-from are two different builds" >&2; exit 2; }
153
180
  fi
154
- [ -n "$out" ] || [ -n "$objects_to" ] || { echo "error: -o <out> is required" >&2; exit 2; }
181
+ if [ -n "$sqlite_to" ] || [ -n "$sqlite_from" ]; then
182
+ # The cached SQLite objects sit beside the cached runtime and take what it takes.
183
+ case "$profile" in
184
+ debug|speed|size) ;;
185
+ *) echo "error: --sqlite-objects and --sqlite-from take the debug, speed and size profiles, not '$profile'" >&2; exit 2 ;;
186
+ esac
187
+ [ ${#pgo[@]} -eq 0 ] || { echo "error: --sqlite-objects and --sqlite-from do not take --pgo-*" >&2; exit 2; }
188
+ [ -z "$sqlite_to" ] || [ -z "$sqlite_from" ] || { echo "error: --sqlite-objects and --sqlite-from are two different builds" >&2; exit 2; }
189
+ [ -z "$sqlite_to" ] || [ -z "$objects_to$objects_from" ] || { echo "error: --sqlite-objects compiles runtime/sqlite/ alone, without --runtime-objects or --runtime-from" >&2; exit 2; }
190
+ fi
191
+ [ -n "$out" ] || [ -n "$objects_to" ] || [ -n "$sqlite_to" ] || { echo "error: -o <out> is required" >&2; exit 2; }
155
192
 
156
- # The runtime is eight translation units, and a caller names one: whoever passes
193
+ # The runtime is ten translation units, and a caller names one: whoever passes
157
194
  # <dir>/runtime.c gets <dir>/runtime-os.c, <dir>/runtime-parallel.c,
158
- # <dir>/runtime-cross.c, <dir>/runtime-host.c, <dir>/runtime-net.c, <dir>/runtime-simd.c and
159
- # <dir>/runtime-aes.c compiled beside it, on every profile, wasi included:
160
- # runtime-simd.c takes its scalar path there unless the build adds -msimd128,
161
- # and runtime-aes.c compiles to an answer of 0 and stubs that nothing calls,
162
- # because the compiler emits no call to its kernels for wasm32. They were one file until the
195
+ # <dir>/runtime-cross.c, <dir>/runtime-host.c, <dir>/runtime-net.c, <dir>/runtime-simd.c,
196
+ # <dir>/runtime-aes.c, <dir>/runtime-term.c and <dir>/runtime-bytes.c compiled beside it, on every profile,
197
+ # wasi included: runtime-simd.c and runtime-bytes.c take their scalar paths there
198
+ # unless the build adds -msimd128,
199
+ # runtime-aes.c compiles to an answer of 0 and stubs that nothing calls,
200
+ # because the compiler emits no call to its kernels for wasm32, and
201
+ # runtime-term.c reads stdin and answers "not a terminal". They were one file until the
163
202
  # operating-system half was split out for its own size budget, and the parallel
164
203
  # half followed for the same reason (each file's header comment says why), and
165
204
  # a link line is where those splits
@@ -169,7 +208,7 @@ fi
169
208
  # here keeps every one of those correct, and keeps "the runtime" one thing to
170
209
  # name from the outside. A caller that names one itself is left alone, because
171
210
  # naming one object twice is a duplicate-symbol error.
172
- halves="runtime-os.c runtime-parallel.c runtime-cross.c runtime-host.c runtime-net.c runtime-simd.c runtime-aes.c"
211
+ halves="runtime-os.c runtime-parallel.c runtime-cross.c runtime-host.c runtime-net.c runtime-simd.c runtime-aes.c runtime-term.c runtime-bytes.c"
173
212
  for i in ${inputs[@]+"${inputs[@]}"}; do
174
213
  case "$i" in
175
214
  */runtime.c|runtime.c)
@@ -184,9 +223,49 @@ for i in ${inputs[@]+"${inputs[@]}"}; do
184
223
  esac
185
224
  done
186
225
 
226
+ # SQLite (runtime/sqlite/) is an optional unit, and the IR selects it. A module
227
+ # that declares a function of SQLite's C API (`sqlite3_*`) or of the adapter
228
+ # beside it (`nishsqlite_*`) gets every runtime/sqlite/*.c compiled and
229
+ # linked. Any other program compiles none of it, so its link line and binary
230
+ # stay as they were. The test reads `declare` lines, and only before the first
231
+ # `"` on one, rather than any `@sqlite3_` in the file, because a string
232
+ # constant or a quoted name may hold one. It is one rule with `callsSqlite` in
233
+ # src/run-cache.ts, which decides whether a link asks the runtime cache for
234
+ # SQLite's objects; change both or neither. A caller
235
+ # that names a runtime/sqlite/*.c input itself is left alone, as `halves`
236
+ # leaves a runtime half: naming one object twice is a duplicate-symbol error.
237
+ # A tree without the directory still links every program that does not call it.
238
+ sqlite_dir="$(cd "$(dirname "$0")/../runtime/sqlite" 2>/dev/null && pwd -P)" || sqlite_dir=""
239
+ sqlite_wanted=0
240
+ if [ -n "$sqlite_to" ]; then
241
+ if [ ${#inputs[@]} -gt 0 ]; then
242
+ echo "error: --sqlite-objects compiles runtime/sqlite/ alone, not ${inputs[0]}" >&2; exit 2
243
+ fi
244
+ sqlite_wanted=1
245
+ fi
246
+ for i in ${inputs[@]+"${inputs[@]}"}; do
247
+ case "$i" in
248
+ *.ll) if grep -Eq '^declare [^"]*@(sqlite3|nishsqlite)_' "$i"; then sqlite_wanted=1; fi ;;
249
+ esac
250
+ done
251
+ for i in ${inputs[@]+"${inputs[@]}"}; do
252
+ case "$i" in
253
+ *.c) if [ -n "$sqlite_dir" ] && [ "$(cd "$(dirname -- "$i")" && pwd -P)" = "$sqlite_dir" ]; then sqlite_wanted=0; break; fi ;;
254
+ esac
255
+ done
256
+ if [ "$sqlite_wanted" = 1 ] && [ -z "$sqlite_dir" ]; then
257
+ echo "error: the module calls SQLite, and $(dirname "$0")/../runtime/sqlite/ is not there" >&2
258
+ exit 2
259
+ fi
260
+ if [ "$sqlite_wanted" = 1 ] && [ "$profile" = wasm ]; then
261
+ echo "error: the module calls SQLite, which the wasm profile cannot link: it has no libc for runtime/sqlite/sqlite3.c to build on; use --profile wasi" >&2
262
+ exit 2
263
+ fi
264
+
187
265
  CC=${CC:-clang}
188
266
  common=(-Wno-override-module) # our IR is target-neutral; clang fills the triple in
189
267
  elf=() # flags that only make sense for ELF targets
268
+ lld=0 # 1 when the link goes through ld.lld
190
269
 
191
270
  # Platform-specific dead-stripping, symbol stripping and LTO linker selection.
192
271
  case "$(uname -s)" in
@@ -218,7 +297,7 @@ case "$(uname -s)" in
218
297
  gc=(-Wl,--gc-sections -Wl,--as-needed -Wl,-O2 -Wl,--build-id=none); strip_flag=(-s)
219
298
  elf=(-fno-plt)
220
299
  # GNU ld needs the gold plugin for LTO; prefer lld when clang can find it.
221
- if command -v ld.lld >/dev/null 2>&1; then common+=(-fuse-ld=lld); fi ;;
300
+ if command -v ld.lld >/dev/null 2>&1; then common+=(-fuse-ld=lld); lld=1; fi ;;
222
301
  esac
223
302
 
224
303
  # -g: compile everything with debug info and never strip, whatever the profile,
@@ -255,6 +334,39 @@ if [ "$debug" = 1 ]; then common+=(-g); strip_flag=(); fi
255
334
  # float than the baseline build (docs/LANGUAGE.md, "The CPU level").
256
335
  if [ -n "$cpu" ]; then common+=(-march=x86-64-v3 -ffp-contract=off); fi
257
336
 
337
+ # Hardening, on every native profile (the wasm and wasi ones build their own
338
+ # command line and have none of these to give). docs/security/runtime.md
339
+ # records what each one closes and what it costs.
340
+ #
341
+ # The control-flow flag names the target's own scheme: -fcf-protection is an
342
+ # error on arm64 and -mbranch-protection one on x86, so the triple decides.
343
+ # Nish's IR carries both targets' module flags, and each backend reads its own;
344
+ # these make clang's C units agree, because the linker marks the binary only
345
+ # when every object asks for it. -fstack-clash-protection is ELF's alone: on
346
+ # Mach-O clang ignores it with a warning, and the kernel's guard is the stack
347
+ # itself. -z relro -z now leaves the GOT read-only after relocation, and
348
+ # -z noexecstack says so even when an object without the note slips in.
349
+ #
350
+ # -fstack-protector-strong and _FORTIFY_SOURCE reach the C runtime alone: on a
351
+ # .ll input clang adds no ssp attribute and the macro has no source to change,
352
+ # so one flag list serves the one-command link too. FORTIFY wants an optimiser
353
+ # and is left out of debug, where it would only warn. -U first, because a
354
+ # distribution clang may already define it at another level.
355
+ case "$("$CC" -dumpmachine 2>/dev/null)" in
356
+ x86_64*|amd64*) common+=(-fcf-protection=full); landing=1 ;;
357
+ aarch64*|arm64*) common+=(-mbranch-protection=standard); landing=1 ;;
358
+ *) landing=0 ;;
359
+ esac
360
+ common+=(-fstack-protector-strong)
361
+ if [ "$profile" != debug ]; then common+=(-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3); fi
362
+ case "$(uname -s)" in
363
+ Darwin) ;;
364
+ *)
365
+ common+=(-fstack-clash-protection)
366
+ # shellcheck disable=SC2054 # -Wl,<flag> is one argument: the comma is the linker's
367
+ common+=(-Wl,-z,relro,-z,now -Wl,-z,noexecstack) ;;
368
+ esac
369
+
258
370
  tls=()
259
371
  if [ "$threads" = 1 ]; then
260
372
  common+=(-DNISH_THREADS=1 -ftls-model=initial-exec -pthread)
@@ -274,47 +386,169 @@ case "$profile" in
274
386
  optimise=(-Oz -flto -DNDEBUG ${pgo[@]+"${pgo[@]}"}
275
387
  -ffunction-sections -fdata-sections -fomit-frame-pointer
276
388
  -fno-asynchronous-unwind-tables -fno-unwind-tables ${elf[@]+"${elf[@]}"}
277
- -fno-stack-protector -fvisibility=hidden) ;;
389
+ -fvisibility=hidden) ;;
390
+ napi)
391
+ optimise=(-O3 -flto -DNDEBUG ${pgo[@]+"${pgo[@]}"}
392
+ -ffunction-sections -fdata-sections -fomit-frame-pointer
393
+ -fno-asynchronous-unwind-tables -fno-unwind-tables ${elf[@]+"${elf[@]}"}) ;;
278
394
  esac
279
395
 
396
+ # The speed link splits full LTO's code generation into one partition per core,
397
+ # run in parallel: lld's --lto-partitions, after the whole program is optimised
398
+ # as one module, so inlining does not change. But a partition boundary promotes
399
+ # the internal functions called across it to external ones, and under the
400
+ # control-flow hardening above every external function opens with a landing pad
401
+ # (endbr64, or bti c), which the hot calls then run: fib runs 6.5% more
402
+ # instructions with two partitions than with one. So a target with landing pads
403
+ # links in one partition, and the split is left to the rest. The bytes depend
404
+ # on the count, so one machine links one input to one output, as
405
+ # scripts/bootstrap.sh needs. ld64 and GNU ld have no such flag and link as
406
+ # before, and so does every other profile. The count comes from nproc (Linux),
407
+ # else getconf (both), else sysctl (macOS).
408
+ lto_parts=()
409
+ if [ "$profile" = speed ] && [ "$lld" = 1 ] && [ "$landing" = 0 ]; then
410
+ cores=$(nproc 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null ||
411
+ sysctl -n hw.ncpu 2>/dev/null || echo 1)
412
+ # shellcheck disable=SC2054 # -Wl,<flag> is one argument: the comma is the linker's
413
+ lto_parts=(-Wl,--lto-partitions="$cores")
414
+ fi
415
+
280
416
  # --runtime-objects and --runtime-from: the one-command link split in two, with
281
417
  # every compile it held run at once. A `$CC -c` takes `common` and `optimise`,
282
418
  # which is what the one command compiles each input with -- less
283
- # -fuse-ld=lld, which only names the linker -- so a runtime unit compiles to the
284
- # same object either way: native code for debug, -flto bitcode for speed and
285
- # size, which the link still optimises together with the program. The link
286
- # takes the same line the profile always uses, with objects for sources.
287
- if [ -n "$objects_to" ] || [ -n "$objects_from" ]; then
288
- compile=()
289
- for flag in "${common[@]}"; do
290
- case "$flag" in -fuse-ld=*) ;; *) compile+=("$flag") ;; esac
419
+ # -fuse-ld=lld and the -Wl, flags, which only speak to the linker -- so a
420
+ # runtime unit compiles to the same object either way: native code for debug,
421
+ # -flto bitcode for speed and size, which the link still optimises together
422
+ # with the program. The link takes the same line the profile always uses, with
423
+ # objects for sources.
424
+ compile=()
425
+ for flag in "${common[@]}"; do
426
+ case "$flag" in -fuse-ld=*|-Wl,*) ;; *) compile+=("$flag") ;; esac
427
+ done
428
+ compile+=(${optimise[@]+"${optimise[@]}"})
429
+ # A program's modules are .ll alone, and clang warns that a -U it cannot
430
+ # apply to one went unused, so their compile leaves the FORTIFY pair out.
431
+ module_compile=()
432
+ for flag in "${compile[@]}"; do
433
+ case "$flag" in -U_FORTIFY_SOURCE|-D_FORTIFY_SOURCE=*) ;; *) module_compile+=("$flag") ;; esac
434
+ done
435
+ # Waits for every job, not just the last, and fails when any of them did.
436
+ # bash 3.2 has no `wait -n`, so the jobs are waited for in order.
437
+ pids=()
438
+ join_jobs() {
439
+ local failed=0 pid
440
+ for pid in ${pids[@]+"${pids[@]}"}; do
441
+ wait "$pid" || failed=1
291
442
  done
292
- compile+=(${optimise[@]+"${optimise[@]}"})
293
- # Waits for every job, not just the last, and fails when any of them did.
294
- # bash 3.2 has no `wait -n`, so the jobs are waited for in order.
295
443
  pids=()
296
- join_jobs() {
297
- local failed=0 pid
298
- for pid in ${pids[@]+"${pids[@]}"}; do
299
- wait "$pid" || failed=1
300
- done
444
+ return "$failed"
445
+ }
446
+ # The compiles are this script's children, so a signal that stops it stops
447
+ # them too, before anything they write into is removed. A finished script
448
+ # has waited for every one of them, so there is nothing left to stop.
449
+ stop_jobs() {
450
+ if [ ${#pids[@]} -gt 0 ]; then
451
+ kill "${pids[@]}" 2>/dev/null || true
452
+ wait "${pids[@]}" 2>/dev/null || true
301
453
  pids=()
302
- return "$failed"
303
- }
304
- # The compiles are this script's children, so a signal that stops it stops
305
- # them too, before anything they write into is removed. A finished script
306
- # has waited for every one of them, so there is nothing left to stop.
307
- stop_jobs() {
308
- if [ ${#pids[@]} -gt 0 ]; then
309
- kill "${pids[@]}" 2>/dev/null || true
310
- wait "${pids[@]}" 2>/dev/null || true
311
- pids=()
312
- fi
313
- }
314
- work=""
315
- trap 'stop_jobs; [ -z "$work" ] || rm -rf -- "$work"' EXIT
316
- trap 'exit 130' INT
317
- trap 'exit 143' TERM
454
+ fi
455
+ }
456
+ work=""
457
+ trap 'stop_jobs; [ -z "$work" ] || rm -rf -- "$work"' EXIT
458
+ trap 'exit 130' INT
459
+ trap 'exit 143' TERM
460
+ # A link's own objects go in a private directory of its own and go with it.
461
+ make_work() {
462
+ [ -n "$work" ] || work=$(mktemp -d "${TMPDIR:-/tmp}/nish-link.XXXXXX")
463
+ }
464
+ # A CC named by a relative path is named from here, not from a unit's directory.
465
+ case "$CC" in /*) ;; */*) CC="$(pwd)/$CC" ;; esac
466
+
467
+ # SQLite's compile-time options (https://sqlite.org/compile.html): the set the
468
+ # SQLite project recommends for a program that needs none of the legacy
469
+ # behaviours, less two of it. SQLITE_OMIT_DECLTYPE is left out because it
470
+ # removes sqlite3_column_decltype, which a binding reads to tell a column's
471
+ # declared type. SQLITE_OMIT_AUTOINIT is left out because it makes a call
472
+ # before sqlite3_initialize() undefined behaviour, and the check it saves is
473
+ # a branch in a few entry points. Double-quoted strings are identifiers only. There are no memory
474
+ # statistics, no progress callback, no shared cache and no loadable extensions.
475
+ # Expression depth is bounded by the stack, not a counter. A program has one
476
+ # thread unless it was built with --threads. SQLite takes no mutex for one
477
+ # thread (THREADSAFE=0). Under --threads it is multi-thread mode (=2): no mutex
478
+ # guards a connection, so a program must not share one across threads. wasi
479
+ # has no threads, so it gets 0 whatever the module says. NISH_SQLITE_CFLAGS is
480
+ # appended: `read` takes its first line and splits it on whitespace, so a
481
+ # word cannot hold a space and a quote is an ordinary character. A relative
482
+ # path in it (-Iinclude) resolves against runtime/sqlite/, the directory every
483
+ # unit is compiled from. A -D or -U in it for one of these names replaces the
484
+ # default, so the compile does not warn about a macro defined twice.
485
+ if [ "$threads" = 1 ] && [ "$profile" != wasi ]; then sqlite_threadsafe=2; else sqlite_threadsafe=0; fi
486
+ sqlite_extra=()
487
+ read -r -a sqlite_extra <<< "${NISH_SQLITE_CFLAGS:-}"
488
+ sqlite_defs=()
489
+ for d in -DSQLITE_DQS=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
490
+ -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_OMIT_DEPRECATED \
491
+ -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_USE_ALLOCA \
492
+ -DSQLITE_OMIT_LOAD_EXTENSION "-DSQLITE_THREADSAFE=$sqlite_threadsafe"; do
493
+ name=${d#-D}; name=${name%%=*}
494
+ keep=1
495
+ for e in ${sqlite_extra[@]+"${sqlite_extra[@]}"}; do
496
+ case "$e" in "-D$name"|"-D$name="*|"-U$name") keep=0 ;; esac
497
+ done
498
+ if [ "$keep" = 1 ]; then sqlite_defs+=("$d"); fi
499
+ done
500
+ sqlite_defs+=(${sqlite_extra[@]+"${sqlite_extra[@]}"})
501
+
502
+ # Compiles every runtime/sqlite/*.c with the flags given, all at once, into
503
+ # $1/<unit>.o. Each unit is compiled from inside runtime/sqlite/ by its bare
504
+ # name, as the runtime is, so -g's DWARF names no directory the link was
505
+ # started in. sqlite3.c, the 9.6 MB amalgamation, is compiled to native code
506
+ # even where the profile compiles to LTO bitcode. As bitcode, every link of a
507
+ # program that uses it would generate its code again: measured on a program
508
+ # that opens a database and runs a query, that is 10.6 s a link at -O3,
509
+ # against 0.04 s for the native object. The adapter beside it stays LTO, and
510
+ # it is what inlines into the program. So `-flto` comes off for that one unit
511
+ # alone.
512
+ sqlite_units() {
513
+ local to=$1 unit flag
514
+ local -a flags
515
+ shift
516
+ for unit in "$sqlite_dir"/*.c; do
517
+ unit=${unit##*/}
518
+ flags=()
519
+ for flag in "$@"; do
520
+ case "$unit:$flag" in sqlite3.c:-flto) ;; *) flags+=("$flag") ;; esac
521
+ done
522
+ (cd -- "$sqlite_dir" && exec "$CC" "${flags[@]}" "${sqlite_defs[@]}" -I. -c "$unit" -o "$to/${unit%.c}.o") &
523
+ pids+=("$!")
524
+ done
525
+ join_jobs || { echo "error: runtime/sqlite/ did not compile" >&2; exit 1; }
526
+ }
527
+ # Adds the objects of runtime/sqlite/ to this link, in the order of the units.
528
+ # They are compiled into the link's own directory with the flags given, or
529
+ # taken from --sqlite-from. Nothing is added for a module that does not call
530
+ # SQLite.
531
+ sqlite_objects() {
532
+ local from=$sqlite_from unit
533
+ [ "$sqlite_wanted" = 1 ] || return 0
534
+ if [ -z "$from" ]; then
535
+ make_work
536
+ from="$work/sqlite"
537
+ mkdir -p -- "$from"
538
+ sqlite_units "$from" "$@"
539
+ fi
540
+ for unit in "$sqlite_dir"/*.c; do
541
+ unit=${unit##*/}
542
+ [ -f "$from/${unit%.c}.o" ] || { echo "error: --sqlite-from: $from/${unit%.c}.o is missing" >&2; exit 2; }
543
+ inputs+=("$from/${unit%.c}.o")
544
+ done
545
+ }
546
+
547
+ if [ -n "$sqlite_to" ]; then
548
+ mkdir -p -- "$sqlite_to"
549
+ sqlite_to=$(cd -- "$sqlite_to" && pwd)
550
+ sqlite_units "$sqlite_to" "${compile[@]}"
551
+ exit 0
318
552
  fi
319
553
 
320
554
  if [ -n "$objects_to" ]; then
@@ -334,8 +568,6 @@ if [ -n "$objects_to" ]; then
334
568
  # the file `runtime.c` in the runtime's own directory, whichever directory
335
569
  # the first link that compiled it was run in.
336
570
  runtime_dir=$(dirname -- "$runtime")
337
- # A CC named by a relative path is named from here, not from there.
338
- case "$CC" in /*) ;; */*) CC="$(pwd)/$CC" ;; esac
339
571
  for unit in runtime.c $halves; do
340
572
  (cd -- "$runtime_dir" && exec "$CC" "${compile[@]}" -c "$unit" -o "$objects_to/${unit%.c}.o") &
341
573
  pids+=("$!")
@@ -348,15 +580,13 @@ if [ -n "$objects_from" ]; then
348
580
  for unit in runtime.c $halves; do
349
581
  [ -f "$objects_from/${unit%.c}.o" ] || { echo "error: --runtime-from: $objects_from/${unit%.c}.o is missing" >&2; exit 2; }
350
582
  done
351
- # The program's own objects are this link's alone, so they go in a private
352
- # directory of its own and go with it.
353
- work=$(mktemp -d "${TMPDIR:-/tmp}/nish-link.XXXXXX")
583
+ make_work
354
584
  objects=()
355
585
  n=0
356
586
  for i in "${inputs[@]}"; do
357
587
  case "$i" in */runtime.c|runtime.c) echo "error: --runtime-from links the runtime in $objects_from, so $i is not an input" >&2; exit 2 ;; esac
358
588
  n=$((n + 1))
359
- "$CC" "${compile[@]}" -c "$i" -o "$work/$n.o" &
589
+ "$CC" "${module_compile[@]}" -c "$i" -o "$work/$n.o" &
360
590
  pids+=("$!")
361
591
  objects+=("$work/$n.o")
362
592
  done
@@ -378,11 +608,12 @@ fi
378
608
  # under `set -u` is a fatal "unbound variable" -- bash 4.4 made it legal, which is
379
609
  # why Linux never noticed. `pgo`, `elf`, `strip_flag` and `libs` are all empty on
380
610
  # ordinary builds, so please do not simplify these back.
611
+ case "$profile" in debug|speed|size) sqlite_objects "${compile[@]}" ;; esac
381
612
  case "$profile" in
382
613
  debug)
383
614
  "$CC" "${common[@]}" "${inputs[@]}" -lm -o "$out" ;;
384
615
  speed|size)
385
- "$CC" "${common[@]}" "${optimise[@]}" \
616
+ "$CC" "${common[@]}" "${optimise[@]}" ${lto_parts[@]+"${lto_parts[@]}"} \
386
617
  "${gc[@]}" ${strip_flag[@]+"${strip_flag[@]}"} "${inputs[@]}" -lm -o "$out" ;;
387
618
  wasm)
388
619
  # clang resolves wasm-ld next to its own binary first, then on PATH; ask it
@@ -409,6 +640,21 @@ case "$profile" in
409
640
  if [ "$aes_wanted" = 1 ] && [ "$aes_named" = 0 ]; then
410
641
  inputs+=("$(cd "$(dirname "$0")/../runtime" && pwd)/runtime-aes.c")
411
642
  fi
643
+ # IR of either kind that imports std/json or calls nish/bytes's byte-class runs
644
+ # calls runtime-bytes.c's kernels (src/kernels.ts), which compile freestanding:
645
+ # the scalar path, or the 128-bit one under -msimd128. It is added the same way,
646
+ # only for such IR and only when the caller has not named it.
647
+ bytes_named=0
648
+ bytes_wanted=0
649
+ for i in ${inputs[@]+"${inputs[@]}"}; do
650
+ case "$i" in
651
+ */runtime-bytes.c|runtime-bytes.c) bytes_named=1 ;;
652
+ *.ll) if grep -q '@nish_bytes_skip_' "$i"; then bytes_wanted=1; fi ;;
653
+ esac
654
+ done
655
+ if [ "$bytes_wanted" = 1 ] && [ "$bytes_named" = 0 ]; then
656
+ inputs+=("$(cd "$(dirname "$0")/../runtime" && pwd)/runtime-bytes.c")
657
+ fi
412
658
  # -mbulk-memory lowers llvm.memset/memcpy (`new Array<T>(n)`, `push` growth) to the
413
659
  # memory.fill/memory.copy instructions instead of libc calls the freestanding link lacks.
414
660
  "$CC" -Wno-override-module --target=wasm32-unknown-unknown -Oz -nostdlib -mbulk-memory \
@@ -450,6 +696,10 @@ case "$profile" in
450
696
  exit 2
451
697
  fi
452
698
  fi
699
+ # SQLite builds on wasi-libc as it is: the amalgamation sees __wasi__ and
700
+ # takes dot-file locking, no mmap and no WAL shared memory.
701
+ sqlite_objects --target=wasm32-wasi --sysroot="$sysroot" -Oz -DNDEBUG \
702
+ ${tls[@]+"${tls[@]}"} -ffunction-sections -fdata-sections
453
703
  "$CC" -Wno-override-module --target=wasm32-wasi --sysroot="$sysroot" -Oz -DNDEBUG \
454
704
  ${tls[@]+"${tls[@]}"} \
455
705
  -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--strip-all \
@@ -476,9 +726,11 @@ case "$profile" in
476
726
  case "$(uname -s)" in Darwin) shared+=(-Wl,-undefined,dynamic_lookup) ;; esac
477
727
  # runtime/nish.h is the public ABI header the generated shim includes.
478
728
  runtime_inc="$(cd "$(dirname "$0")/../runtime" && pwd)"
479
- "$CC" "${common[@]}" -O3 -flto -DNDEBUG ${pgo[@]+"${pgo[@]}"} -I"$node_inc" -I"$runtime_inc" \
480
- -ffunction-sections -fdata-sections -fomit-frame-pointer \
481
- -fno-asynchronous-unwind-tables -fno-unwind-tables ${elf[@]+"${elf[@]}"} \
729
+ # SQLite's API stays inside the addon: a Node linked against a system
730
+ # libsqlite3 exports the same names, and a call bound to that copy would
731
+ # run another version with other options.
732
+ sqlite_objects "${compile[@]}" -fPIC -fvisibility=hidden
733
+ "$CC" "${common[@]}" "${optimise[@]}" -I"$node_inc" -I"$runtime_inc" \
482
734
  "${shared[@]}" "${gc[@]}" ${strip_flag[@]+"${strip_flag[@]}"} "${inputs[@]}" -lm -o "$out" ;;
483
735
  *) echo "error: unknown profile '$profile'" >&2; exit 2 ;;
484
736
  esac
@@ -0,0 +1,23 @@
1
+ Boost Software License - Version 1.0 - August 17th, 2003
2
+
3
+ Permission is hereby granted, free of charge, to any person or organization
4
+ obtaining a copy of the software and accompanying documentation covered by
5
+ this license (the "Software") to use, reproduce, display, distribute,
6
+ execute, and transmit the Software, and to prepare derivative works of the
7
+ Software, and to permit third-parties to whom the Software is furnished to
8
+ do so, all subject to the following:
9
+
10
+ The copyright notices in the Software and this entire statement, including
11
+ the above license grant, this restriction and the following disclaimer,
12
+ must be included in all copies of the Software, in whole or in part, and
13
+ all derivative works of the Software, unless such copies or derivative
14
+ works are solely in the form of machine-executable object code generated by
15
+ a source language processor.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
20
+ SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
21
+ FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
22
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,8 @@
1
+ ====================================================
2
+ Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
3
+
4
+ Developed at SunPro, a Sun Microsystems, Inc. business.
5
+ Permission to use, copy, modify, and distribute this
6
+ software is freely granted, provided that this notice
7
+ is preserved.
8
+ ====================================================