@amritk/nish-x86_64-linux 0.24.0 → 0.26.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.
Files changed (43) hide show
  1. package/bin/nish +0 -0
  2. package/docs/AI.md +45 -4
  3. package/package.json +1 -1
  4. package/runtime/browser.mjs +4 -3
  5. package/runtime/core/host.d.ts +12 -0
  6. package/runtime/core/host.mjs +74 -2
  7. package/runtime/nish.d.ts +148 -0
  8. package/runtime/nish.h +59 -0
  9. package/runtime/nish.mjs +25 -0
  10. package/runtime/node.mjs +136 -6
  11. package/runtime/runtime-net.c +44 -3
  12. package/runtime/runtime-os.c +351 -18
  13. package/scripts/build.sh +13 -3
  14. package/std/README.md +27 -10
  15. package/std/cli-args.ts +1216 -0
  16. package/std/cli-flags.ts +585 -0
  17. package/std/cli.ts +308 -19
  18. package/std/compress/checksum.ts +132 -20
  19. package/std/compress/deflate.ts +638 -248
  20. package/std/compress/gzip.ts +20 -6
  21. package/std/crypto/LICENSE-fiat-crypto-p384 +21 -0
  22. package/std/crypto/p256.ts +63 -1
  23. package/std/crypto/p384.ts +6044 -0
  24. package/std/crypto/pki-roots.ts +322 -0
  25. package/std/crypto/pki.ts +1207 -0
  26. package/std/crypto/rsa.ts +663 -0
  27. package/std/crypto/x509.ts +1054 -58
  28. package/std/net/dns-config.ts +734 -0
  29. package/std/net/dns-message.ts +517 -0
  30. package/std/net/dns-resolver.ts +1015 -0
  31. package/std/net/dns.ts +478 -0
  32. package/std/net/http1-client.ts +1227 -0
  33. package/std/net/http1-server.ts +7 -2
  34. package/std/net/http1.ts +9 -9
  35. package/std/net/postgres.ts +259 -26
  36. package/std/net/tls/client.ts +1094 -0
  37. package/std/net/tls/codec.ts +585 -3
  38. package/std/net/tls/record-client.ts +1192 -0
  39. package/std/net/tls/verify.ts +221 -0
  40. package/std/net/tls-tcp.ts +642 -11
  41. package/std/net/tls.ts +2 -2
  42. package/std/net/url.ts +559 -4
  43. package/std/yaml-write.ts +415 -0
@@ -52,7 +52,7 @@
52
52
  * the length limit is the Kraft-sum repair of the counts per length. Not
53
53
  * ported from another implementation.
54
54
  */
55
- import { uncheckedGet, uncheckedSet } from "nish:unsafe"
55
+ import { uncheckedGet, uncheckedSet, wrappingAdd, wrappingSub } from "nish:unsafe"
56
56
  import { copyBytes } from "nish/bytes"
57
57
 
58
58
  /** Level 0: stored blocks only, the input copied with five bytes of framing per 65,535. */
@@ -134,10 +134,27 @@ const INF_LENGTH: i32 = 1
134
134
  const INF_END: i32 = 2
135
135
  const INF_SLOW: i32 = 3
136
136
  const INF_INVALID: i32 = 4
137
+ /** A pointer to a subtable: its start as the value, its bits as the extra bits, the main table's bits as the length. */
138
+ const INF_SUB: i32 = 5
137
139
 
138
- /** The bits the literal/length and distance tables index directly; a longer code is decoded a bit at a time. */
139
- const INF_LIT_BITS: i32 = 10
140
+ /**
141
+ * The bits the literal/length and distance tables index directly; a longer
142
+ * code is decoded through a subtable after the main table.
143
+ */
144
+ const INF_LIT_BITS: i32 = 11
140
145
  const INF_DIST_BITS: i32 = 8
146
+
147
+ /**
148
+ * The most entries a table with its subtables can need, over every complete
149
+ * code of up to 15 bits: what zlib's `enough` program computes for 288
150
+ * symbols with 11 root bits and for 32 with 8 (`enough 288 11 15`,
151
+ * `enough 32 8 15`), the figures libdeflate sizes its tables by.
152
+ */
153
+ const INF_LIT_ENOUGH: i32 = 2342
154
+ const INF_DIST_ENOUGH: i32 = 402
155
+
156
+ /** The output the fast loop keeps in hand: the longest match and 32 bytes of copy slack. */
157
+ const INF_FAST_ROOM: i32 = 290
141
158
  const INF_CL_BITS: i32 = 7
142
159
 
143
160
  /** The decoder's resumable states. */
@@ -166,6 +183,22 @@ export const deflateBound = (n: i32): i32 => {
166
183
  */
167
184
  export const compressBound = (n: i32): i32 => deflateBound(n) + 18
168
185
 
186
+ /**
187
+ * Copies `b[from .. from + 16)` to `b[to .. to + 16)` eight bytes at a time,
188
+ * each word read after the one before it is written, which is LZ77's
189
+ * meaning when `to - from` is at least 8. The caller has checked the range.
190
+ */
191
+ const inflateCopy16 = (b: u8[], to: integer<0, 2147483631>, from: integer<0, 2147483631>): void => {
192
+ deflateStore64(b, to, deflateLoad64(b, from))
193
+ deflateStore64(b, to + 8, deflateLoad64(b, from + 8))
194
+ }
195
+
196
+ /** Stores `w` twice into `b[to .. to + 16)`; the caller has checked the range. */
197
+ const inflateFill16 = (b: u8[], to: integer<0, 2147483631>, w: u64): void => {
198
+ deflateStore64(b, to, w)
199
+ deflateStore64(b, to + 8, w)
200
+ }
201
+
169
202
  /** Panics unless `buf[off .. off + len)` lies inside `buf`. */
170
203
  const deflateWindow = (what: string, buf: u8[], off: i32, len: i32): void => {
171
204
  if (off < 0 || len < 0 || off > toI32(buf.length) - len) {
@@ -195,30 +228,42 @@ const deflateLoad32 = (b: u8[], p: integer<0, 2147483639>): u32 =>
195
228
  (toU32(uncheckedGet(b, p + 2)) << 16) |
196
229
  (toU32(uncheckedGet(b, p + 3)) << 24)
197
230
 
198
- /** The little-endian 64-bit word at `b[p .. p + 8)`; the caller has checked the range. */
231
+ /**
232
+ * The little-endian 64-bit word at `b[p .. p + 8)`; the caller has checked the
233
+ * range. Eight byte loads, not two `deflateLoad32`s: LLVM folds these into
234
+ * one load, and a word built from two halves keeps `deflateStore64` from
235
+ * becoming one store.
236
+ */
199
237
  const deflateLoad64 = (b: u8[], p: integer<0, 2147483639>): u64 =>
200
- toU64(deflateLoad32(b, p)) | (toU64(deflateLoad32(b, p + 4)) << toU64(32))
238
+ toU64(uncheckedGet(b, p)) |
239
+ (toU64(uncheckedGet(b, p + 1)) << toU64(8)) |
240
+ (toU64(uncheckedGet(b, p + 2)) << toU64(16)) |
241
+ (toU64(uncheckedGet(b, p + 3)) << toU64(24)) |
242
+ (toU64(uncheckedGet(b, p + 4)) << toU64(32)) |
243
+ (toU64(uncheckedGet(b, p + 5)) << toU64(40)) |
244
+ (toU64(uncheckedGet(b, p + 6)) << toU64(48)) |
245
+ (toU64(uncheckedGet(b, p + 7)) << toU64(56))
201
246
 
202
247
  /** Stores `w` little-endian into `b[p .. p + 8)`; the caller has checked the range. */
203
248
  const deflateStore64 = (b: u8[], p: integer<0, 2147483639>, w: u64): void => {
204
- uncheckedSet(b, p, toU8(w & toU64(255)))
205
- uncheckedSet(b, p + 1, toU8((w >> toU64(8)) & toU64(255)))
206
- uncheckedSet(b, p + 2, toU8((w >> toU64(16)) & toU64(255)))
207
- uncheckedSet(b, p + 3, toU8((w >> toU64(24)) & toU64(255)))
208
- uncheckedSet(b, p + 4, toU8((w >> toU64(32)) & toU64(255)))
209
- uncheckedSet(b, p + 5, toU8((w >> toU64(40)) & toU64(255)))
210
- uncheckedSet(b, p + 6, toU8((w >> toU64(48)) & toU64(255)))
249
+ uncheckedSet(b, p, toU8(w))
250
+ uncheckedSet(b, p + 1, toU8(w >> toU64(8)))
251
+ uncheckedSet(b, p + 2, toU8(w >> toU64(16)))
252
+ uncheckedSet(b, p + 3, toU8(w >> toU64(24)))
253
+ uncheckedSet(b, p + 4, toU8(w >> toU64(32)))
254
+ uncheckedSet(b, p + 5, toU8(w >> toU64(40)))
255
+ uncheckedSet(b, p + 6, toU8(w >> toU64(48)))
211
256
  uncheckedSet(b, p + 7, toU8(w >> toU64(56)))
212
257
  }
213
258
 
214
259
  /** The number of trailing zero bits of a nonzero `x`. */
215
260
  const deflateCtz64 = (x: u64): i32 => {
261
+ // Both halves, then a select rather than a branch on which is nonzero.
216
262
  const lo: u32 = toU32(x)
217
- if (lo !== 0) {
218
- return toI32(31) - Math.clz32(lo & (toU32(0) - lo))
219
- }
220
263
  const hi: u32 = toU32(x >> toU64(32))
221
- return toI32(63) - Math.clz32(hi & (toU32(0) - hi))
264
+ const low: i32 = toI32(31) - Math.clz32(lo & (toU32(0) - lo))
265
+ const high: i32 = toI32(63) - Math.clz32(hi & (toU32(0) - hi))
266
+ return lo !== 0 ? low : high
222
267
  }
223
268
 
224
269
  /**
@@ -374,11 +419,21 @@ const deflateCanonical = (lens: i32[], n: i32, codes: i32[], count: i32[], next:
374
419
  code = (code + count[l - 1]) << 1
375
420
  next[l] = code
376
421
  }
422
+ // Each length's next code is kept bit-reversed, as it is written, and
423
+ // incremented that way: clear the ones below its highest zero and set it.
424
+ for (let l: i32 = 1; l < 16; l += 1) {
425
+ next[l] = deflateReverse(next[l], l)
426
+ }
377
427
  for (let s: i32 = 0; s < n; s += 1) {
378
428
  const l: i32 = lens[s]
379
429
  if (l > 0 && l < 16) {
380
- codes[s] = deflateReverse(next[l], l)
381
- next[l] += 1
430
+ const r: i32 = next[l]
431
+ codes[s] = r
432
+ const top: i32 = (toI32(1) << l) - 1
433
+ if (r !== top) {
434
+ const bit: i32 = toI32(1) << (31 - toI32(Math.clz32(toU32(r ^ top))))
435
+ next[l] = (r & (bit - 1)) | bit
436
+ }
382
437
  } else {
383
438
  codes[s] = 0
384
439
  }
@@ -1009,38 +1064,57 @@ export class Deflater {
1009
1064
  longest(src: u8[], p: i32, end: i32, histStart: i32): i32 {
1010
1065
  const head: i32[] = this.head
1011
1066
  const prev: i32[] = this.prev
1012
- if (toI32(head.length) !== DEFLATE_HASH_SIZE || toI32(prev.length) !== DEFLATE_WINDOW) {
1067
+ if (
1068
+ toI32(head.length) !== DEFLATE_HASH_SIZE ||
1069
+ toI32(prev.length) !== DEFLATE_WINDOW ||
1070
+ p < 0 ||
1071
+ p > end - 4 ||
1072
+ end > toI32(src.length)
1073
+ ) {
1013
1074
  panic("Deflater.longest: a table is not its size")
1014
1075
  }
1015
- const word: u32 = deflateLoad32(src, p)
1076
+ const delta: i32 = this.delta
1077
+ const minMatch: i32 = this.minMatch
1078
+ const at: integer<0, 2147483639> = p
1079
+ const word: u32 = deflateLoad32(src, at)
1016
1080
  const h: i32 =
1017
- this.minMatch === 3
1081
+ minMatch === 3
1018
1082
  ? toI32(((word << 8) * toU32(DEFLATE_HASH_MUL)) >>> 17)
1019
1083
  : toI32((word * toU32(DEFLATE_HASH_MUL)) >>> 17)
1020
- const v: i32 = p + this.delta
1084
+ const v: i32 = wrappingAdd(p, delta)
1021
1085
  let cand: i32 = uncheckedGet(head, h)
1022
1086
  uncheckedSet(head, h, v)
1023
1087
  uncheckedSet(prev, v & (DEFLATE_WINDOW - 1), cand)
1024
- let maxLen: i32 = end - p
1025
- if (maxLen > DEFLATE_MAX_MATCH) {
1026
- maxLen = DEFLATE_MAX_MATCH
1027
- }
1028
- let best: i32 = this.minMatch - 1
1088
+ // Where a whole longest match fits, eight bytes past `p` can be read
1089
+ // whatever the match, and nothing is clamped.
1090
+ const roomy: boolean = p <= end - DEFLATE_MAX_MATCH
1091
+ const maxLen: i32 = roomy ? DEFLATE_MAX_MATCH : end - p
1092
+ let best: i32 = minMatch - 1
1029
1093
  let bestDist: i32 = 0
1030
1094
  const limit: i32 = v - DEFLATE_WINDOW
1095
+ const floor: i32 = limit > histStart + delta ? limit : histStart + delta
1031
1096
  const nice: i32 = this.niceLength < maxLen ? this.niceLength : maxLen
1032
- const lo: i32 = histStart + this.delta
1033
- const mask: u32 = this.minMatch === 3 ? toU32(0xffffff) : ~toU32(0)
1097
+ const mask: u32 = minMatch === 3 ? toU32(0xffffff) : ~toU32(0)
1034
1098
  let chain: i32 = this.maxChain
1035
- while (cand >= limit && cand >= lo && cand < v && chain > 0) {
1036
- const ci: i32 = cand - this.delta
1037
- if (
1038
- uncheckedGet(src, ci + best) === uncheckedGet(src, p + best) &&
1039
- ci >= 0 &&
1040
- ci <= 2147483639 &&
1041
- ((deflateLoad32(src, ci) ^ word) & mask) === 0
1042
- ) {
1043
- const l: i32 = deflateMatchLength(src, ci, p, maxLen)
1099
+ while (cand >= floor && cand < v && chain > 0) {
1100
+ const cd: i32 = cand - delta
1101
+ if (cd < 0 || cd > 2147483639) {
1102
+ break
1103
+ }
1104
+ const ci: integer<0, 2147483639> = cd
1105
+ // The byte that would make this match the longest yet, first: most
1106
+ // candidates fail on it.
1107
+ if (uncheckedGet(src, ci + best) === uncheckedGet(src, p + best)) {
1108
+ let l: i32 = 0
1109
+ if (roomy) {
1110
+ const x: u64 = deflateLoad64(src, ci) ^ deflateLoad64(src, at)
1111
+ l =
1112
+ x !== toU64(0)
1113
+ ? deflateCtz64(x) >> 3
1114
+ : toI32(8) + deflateMatchLength(src, ci + 8, p + 8, maxLen - 8)
1115
+ } else if (((deflateLoad32(src, ci) ^ word) & mask) === 0) {
1116
+ l = deflateMatchLength(src, ci, p, maxLen)
1117
+ }
1044
1118
  if (l > best) {
1045
1119
  best = l
1046
1120
  bestDist = v - cand
@@ -1052,7 +1126,7 @@ export class Deflater {
1052
1126
  cand = uncheckedGet(prev, cand & (DEFLATE_WINDOW - 1))
1053
1127
  chain -= 1
1054
1128
  }
1055
- if (bestDist === 0 || best < this.minMatch) {
1129
+ if (bestDist === 0 || best < minMatch) {
1056
1130
  return 0
1057
1131
  }
1058
1132
  // A three-byte match far back costs more than its three literals.
@@ -1163,14 +1237,28 @@ export class Deflater {
1163
1237
  let cand: i32 = uncheckedGet(head, h)
1164
1238
  uncheckedSet(head, h, v)
1165
1239
  uncheckedSet(prev, v & (DEFLATE_WINDOW - 1), cand)
1166
- const maxLen: i32 = end - p < DEFLATE_MAX_MATCH ? end - p : DEFLATE_MAX_MATCH
1240
+ const maxLen: i32 = p <= end - DEFLATE_MAX_MATCH ? DEFLATE_MAX_MATCH : end - p
1167
1241
  const nice: i32 = niceLength < maxLen ? niceLength : maxLen
1168
1242
  const limit: i32 = v - DEFLATE_WINDOW
1169
1243
  let chain: i32 = maxChain
1170
1244
  while (cand >= limit && cand >= lo && cand < v && chain > 0) {
1171
1245
  const ci: i32 = cand - delta
1172
1246
  if (ci >= 0 && ci <= 2147483639 && deflateLoad32(src, ci) === word) {
1173
- const l: i32 = 4 + deflateMatchLength(src, ci + 4, p + 4, maxLen - 4)
1247
+ let l: i32 = 0
1248
+ if (p <= end - DEFLATE_MAX_MATCH && ci <= 2147483627) {
1249
+ const a4: i32 = ci + 4
1250
+ const b4: i32 = p + 4
1251
+ let x: u64 = toU64(1)
1252
+ if (a4 >= 0 && a4 <= 2147483639 && b4 >= 0 && b4 <= 2147483639) {
1253
+ x = deflateLoad64(src, a4) ^ deflateLoad64(src, b4)
1254
+ }
1255
+ l =
1256
+ x !== toU64(0)
1257
+ ? toI32(4) + (deflateCtz64(x) >> 3)
1258
+ : toI32(12) + deflateMatchLength(src, ci + 12, p + 12, maxLen - 12)
1259
+ } else {
1260
+ l = 4 + deflateMatchLength(src, ci + 4, p + 4, maxLen - 4)
1261
+ }
1174
1262
  if (l > best) {
1175
1263
  best = l
1176
1264
  bestDist = v - cand
@@ -1193,13 +1281,14 @@ export class Deflater {
1193
1281
  uncheckedSet(df, ds, uncheckedGet(df, ds) + 1)
1194
1282
  // Every position the match covers goes into the chains.
1195
1283
  const stop: i32 = p + best
1196
- let q: i32 = p + 1
1197
- while (q < stop && q >= 0 && q <= last && q <= 2147483639) {
1198
- const hq: i32 = toI32((deflateLoad32(src, q) * toU32(DEFLATE_HASH_MUL)) >>> 17)
1199
- const vq: i32 = q + delta
1284
+ const insertEnd: i32 = stop <= last ? stop : last + 1
1285
+ let vq: i32 = wrappingAdd(p, delta)
1286
+ for (let q: i32 = p + 1; q < insertEnd && q >= 0 && q <= 2147483639; q += 1) {
1287
+ const qa: integer<0, 2147483639> = q
1288
+ const hq: i32 = toI32((deflateLoad32(src, qa) * toU32(DEFLATE_HASH_MUL)) >>> 17)
1289
+ vq = wrappingAdd(vq, 1)
1200
1290
  uncheckedSet(prev, vq & (DEFLATE_WINDOW - 1), uncheckedGet(head, hq))
1201
1291
  uncheckedSet(head, hq, vq)
1202
- q += 1
1203
1292
  }
1204
1293
  p = stop
1205
1294
  } else {
@@ -1532,10 +1621,10 @@ export class Deflater {
1532
1621
  bc += uncheckedGet(lextra, s)
1533
1622
  if (bc >= 32) {
1534
1623
  deflateRoom(out, o, 4)
1535
- uncheckedSet(out, o, toU8(bb & toU64(255)))
1536
- uncheckedSet(out, o + 1, toU8((bb >> toU64(8)) & toU64(255)))
1537
- uncheckedSet(out, o + 2, toU8((bb >> toU64(16)) & toU64(255)))
1538
- uncheckedSet(out, o + 3, toU8((bb >> toU64(24)) & toU64(255)))
1624
+ uncheckedSet(out, o, toU8(bb))
1625
+ uncheckedSet(out, o + 1, toU8(bb >> toU64(8)))
1626
+ uncheckedSet(out, o + 2, toU8(bb >> toU64(16)))
1627
+ uncheckedSet(out, o + 3, toU8(bb >> toU64(24)))
1539
1628
  bb = bb >> toU64(32)
1540
1629
  bc -= 32
1541
1630
  o += 4
@@ -1549,10 +1638,10 @@ export class Deflater {
1549
1638
  }
1550
1639
  if (bc >= 32) {
1551
1640
  deflateRoom(out, o, 4)
1552
- uncheckedSet(out, o, toU8(bb & toU64(255)))
1553
- uncheckedSet(out, o + 1, toU8((bb >> toU64(8)) & toU64(255)))
1554
- uncheckedSet(out, o + 2, toU8((bb >> toU64(16)) & toU64(255)))
1555
- uncheckedSet(out, o + 3, toU8((bb >> toU64(24)) & toU64(255)))
1641
+ uncheckedSet(out, o, toU8(bb))
1642
+ uncheckedSet(out, o + 1, toU8(bb >> toU64(8)))
1643
+ uncheckedSet(out, o + 2, toU8(bb >> toU64(16)))
1644
+ uncheckedSet(out, o + 3, toU8(bb >> toU64(24)))
1556
1645
  bb = bb >> toU64(32)
1557
1646
  bc -= 32
1558
1647
  o += 4
@@ -1570,7 +1659,10 @@ export class Deflater {
1570
1659
  * canonical order that a bit-at-a-time decode walks (§3.2.2).
1571
1660
  */
1572
1661
  export class InflateTable {
1573
- /** `entries[peek]`: value << 16 | kind << 8 | extra << 4 | length. */
1662
+ /**
1663
+ * `entries[peek]`: value << 16 | extra << 11 | kind << 8 | length. The low
1664
+ * byte is the length alone, so a bit buffer shifts by an entry as it is.
1665
+ */
1574
1666
  readonly entries: i32[]
1575
1667
  /** The prefix the table indexes. */
1576
1668
  readonly bits: i32
@@ -1579,15 +1671,36 @@ export class InflateTable {
1579
1671
  /** The symbols, ordered by code. */
1580
1672
  readonly symbols: i32[]
1581
1673
 
1582
- /** A table indexing `bits` bits, for an alphabet of up to `symbols` symbols. */
1583
- constructor(bits: i32, symbols: i32) {
1674
+ /**
1675
+ * A table indexing `bits` bits, for an alphabet of up to `symbols`
1676
+ * symbols, with room for `capacity` entries: the main table and its
1677
+ * subtables.
1678
+ */
1679
+ constructor(bits: i32, symbols: i32, capacity: i32) {
1584
1680
  this.bits = bits
1585
- this.entries = new Array<i32>(1 << bits)
1681
+ this.entries = new Array<i32>(capacity)
1586
1682
  this.count = new Array<i32>(16)
1587
1683
  this.symbols = new Array<i32>(symbols)
1588
1684
  }
1589
1685
  }
1590
1686
 
1687
+ /**
1688
+ * Copies `entries[0 .. end)` to `entries[end .. 2 * end)`: a table for codes
1689
+ * one bit longer, each shorter code repeated under both values of the new
1690
+ * bit. Panics unless `2 * end` is within the table.
1691
+ */
1692
+ const inflateDouble = (entries: i32[], end: i32): void => {
1693
+ if (end < 0 || end > toI32(entries.length) - end) {
1694
+ panic("Inflater.build: a table doubled past its length")
1695
+ }
1696
+ // A counter below a bound needs no overflow check, and the loop without
1697
+ // one is a vector copy.
1698
+ const twice: i32 = end + end
1699
+ for (let j: i32 = end; j < twice; j += 1) {
1700
+ uncheckedSet(entries, j, uncheckedGet(entries, j - end))
1701
+ }
1702
+ }
1703
+
1591
1704
  /** The kind of table `inflateBuild` builds: what each symbol decodes to. */
1592
1705
  const INF_TABLE_LITLEN: i32 = 0
1593
1706
  const INF_TABLE_DIST: i32 = 1
@@ -1610,6 +1723,10 @@ export class Inflater {
1610
1723
  readonly clLens: i32[]
1611
1724
  /** Scratch for building a table. */
1612
1725
  readonly offsets: i32[]
1726
+ /** Each symbol's table entry with a length of 0, per kind of table: `entryOf(kind, s, 0)`. */
1727
+ readonly litEntries: i32[]
1728
+ readonly distEntries: i32[]
1729
+ readonly clEntries: i32[]
1613
1730
  readonly lengthBase: i32[]
1614
1731
  readonly lengthExtra: i32[]
1615
1732
  readonly distBase: i32[]
@@ -1633,11 +1750,11 @@ export class Inflater {
1633
1750
 
1634
1751
  /** Builds the tables, the fixed code's among them. */
1635
1752
  constructor() {
1636
- this.lit = new InflateTable(INF_LIT_BITS, 288)
1637
- this.dist = new InflateTable(INF_DIST_BITS, 32)
1638
- this.codeLengths = new InflateTable(INF_CL_BITS, 19)
1639
- this.fixedLit = new InflateTable(INF_LIT_BITS, 288)
1640
- this.fixedDist = new InflateTable(INF_DIST_BITS, 32)
1753
+ this.lit = new InflateTable(INF_LIT_BITS, 288, INF_LIT_ENOUGH)
1754
+ this.dist = new InflateTable(INF_DIST_BITS, 32, INF_DIST_ENOUGH)
1755
+ this.codeLengths = new InflateTable(INF_CL_BITS, 19, 1 << INF_CL_BITS)
1756
+ this.fixedLit = new InflateTable(INF_LIT_BITS, 288, INF_LIT_ENOUGH)
1757
+ this.fixedDist = new InflateTable(INF_DIST_BITS, 32, INF_DIST_ENOUGH)
1641
1758
  this.lens = new Array<i32>(320)
1642
1759
  this.clLens = new Array<i32>(19)
1643
1760
  this.offsets = new Array<i32>(16)
@@ -1653,6 +1770,9 @@ export class Inflater {
1653
1770
  this.distBase[d] = deflateDistBase(d)
1654
1771
  this.distExtra[d] = deflateDistExtra(d)
1655
1772
  }
1773
+ this.litEntries = new Array<i32>(288)
1774
+ this.distEntries = new Array<i32>(32)
1775
+ this.clEntries = new Array<i32>(19)
1656
1776
  this.state = INF_S_BLOCK
1657
1777
  this.last = false
1658
1778
  this.fixed = false
@@ -1662,6 +1782,15 @@ export class Inflater {
1662
1782
  this.inPos = 0
1663
1783
  this.outPos = 0
1664
1784
  this.consumed = 0
1785
+ for (let s: i32 = 0; s < 288; s += 1) {
1786
+ this.litEntries[s] = this.entryOf(INF_TABLE_LITLEN, s, toI32(0))
1787
+ }
1788
+ for (let s: i32 = 0; s < 32; s += 1) {
1789
+ this.distEntries[s] = this.entryOf(INF_TABLE_DIST, s, toI32(0))
1790
+ }
1791
+ for (let s: i32 = 0; s < 19; s += 1) {
1792
+ this.clEntries[s] = this.entryOf(INF_TABLE_CODELEN, s, toI32(0))
1793
+ }
1665
1794
  for (let s: i32 = 0; s < 288; s += 1) {
1666
1795
  this.lens[s] = deflateFixedLitLength(s)
1667
1796
  }
@@ -1698,7 +1827,7 @@ export class Inflater {
1698
1827
  if (s >= 30) {
1699
1828
  return (INF_INVALID << 8) | len
1700
1829
  }
1701
- return (this.distBase[s] << 16) | (this.distExtra[s] << 4) | len
1830
+ return (this.distBase[s] << 16) | (this.distExtra[s] << 11) | len
1702
1831
  }
1703
1832
  if (s < 256) {
1704
1833
  return (s << 16) | (INF_LITERAL << 8) | len
@@ -1709,7 +1838,7 @@ export class Inflater {
1709
1838
  if (s >= 286) {
1710
1839
  return (INF_INVALID << 8) | len
1711
1840
  }
1712
- return (this.lengthBase[s - 257] << 16) | (INF_LENGTH << 8) | (this.lengthExtra[s - 257] << 4) | len
1841
+ return (this.lengthBase[s - 257] << 16) | (INF_LENGTH << 8) | (this.lengthExtra[s - 257] << 11) | len
1713
1842
  }
1714
1843
 
1715
1844
  /**
@@ -1731,19 +1860,25 @@ export class Inflater {
1731
1860
  n > toI32(syms.length) ||
1732
1861
  toI32(count.length) < 16 ||
1733
1862
  toI32(offs.length) < 16 ||
1734
- toI32(entries.length) !== 1 << bits
1863
+ toI32(entries.length) < 1 << bits
1735
1864
  ) {
1736
1865
  panic("Inflater.build: a table outside its scratch")
1737
1866
  }
1738
1867
  for (let l: i32 = 0; l < 16; l += 1) {
1739
1868
  count[l] = 0
1740
1869
  }
1741
- for (let s: i32 = 0; s < n; s += 1) {
1742
- const l: i32 = lens[from + s]
1743
- if (l < 0 || l > 15) {
1744
- return DEFLATE_ERR_HUFFMAN
1745
- }
1746
- count[l] += 1
1870
+ // `lens[from .. from + n)` was checked above. A length outside 0 to 15
1871
+ // shows in the OR of them all, tested once after the loop.
1872
+ const hi: i32 = from + n
1873
+ let seen: i32 = 0
1874
+ for (let i: i32 = from; i < hi; i += 1) {
1875
+ const l: i32 = uncheckedGet(lens, i)
1876
+ seen = seen | l
1877
+ const c: i32 = l & 15
1878
+ count[c] = wrappingAdd(count[c], 1)
1879
+ }
1880
+ if ((seen & ~15) !== 0) {
1881
+ return DEFLATE_ERR_HUFFMAN
1747
1882
  }
1748
1883
  count[0] = 0
1749
1884
  // The Kraft sum: over-subscribed is an error; incomplete is allowed for
@@ -1760,45 +1895,155 @@ export class Inflater {
1760
1895
  if (left > 0 && codes !== 0 && !(kind !== INF_TABLE_CODELEN && codes === 1 && count[1] === 1)) {
1761
1896
  return DEFLATE_ERR_HUFFMAN
1762
1897
  }
1898
+ // Sorted by length, then symbol, with no branch per symbol: the unused
1899
+ // symbols (length 0) go after the rest, where nothing reads them.
1763
1900
  offs[1] = 0
1764
1901
  for (let l: i32 = 1; l < 15; l += 1) {
1765
1902
  offs[l + 1] = offs[l] + count[l]
1766
1903
  }
1767
- for (let s: i32 = 0; s < n; s += 1) {
1768
- const l: i32 = lens[from + s]
1769
- if (l > 0 && l < 16) {
1770
- const at: i32 = offs[l]
1771
- if (at >= 0 && at < toI32(syms.length)) {
1772
- syms[at] = s
1773
- }
1774
- offs[l] = at + 1
1904
+ offs[0] = codes
1905
+ for (let i: i32 = from; i < hi; i += 1) {
1906
+ const l: i32 = uncheckedGet(lens, i) & 15
1907
+ const at: i32 = offs[l]
1908
+ if (at >= 0 && at < toI32(syms.length)) {
1909
+ syms[at] = i - from
1775
1910
  }
1911
+ offs[l] = wrappingAdd(at, 1)
1776
1912
  }
1777
- // A prefix whose code is longer than the table, or none at all, decodes
1778
- // the slow way, which also finds an undefined code.
1779
1913
  const size: i32 = 1 << bits
1780
1914
  const slow: i32 = INF_SLOW << 8
1781
- for (let i: i32 = 0; i < size; i += 1) {
1782
- uncheckedSet(entries, i, slow)
1915
+ let tmpl: i32[] = this.clEntries
1916
+ if (kind === INF_TABLE_LITLEN) {
1917
+ tmpl = this.litEntries
1918
+ } else if (kind === INF_TABLE_DIST) {
1919
+ tmpl = this.distEntries
1920
+ }
1921
+ let len: i32 = 1
1922
+ while (len < 16 && count[len] === 0) {
1923
+ len += 1
1924
+ }
1925
+ if (left > 0 || len > bits) {
1926
+ // No code, one incomplete one-bit code, or every code longer than the
1927
+ // table: every prefix starts as the slow way, which also finds an
1928
+ // undefined code, and the short codes are written over it.
1929
+ for (let i: i32 = 0; i < size; i += 1) {
1930
+ uncheckedSet(entries, i, slow)
1931
+ }
1932
+ let code: i32 = 0
1933
+ let k: i32 = 0
1934
+ for (let l: i32 = 1; l <= bits && l < 16; l += 1) {
1935
+ const codesHere: i32 = uncheckedGet(count, l)
1936
+ for (let c: i32 = 0; c < codesHere; c += 1) {
1937
+ if (k >= 0 && k < toI32(syms.length)) {
1938
+ const e: i32 = tmpl[syms[k]] | l
1939
+ const step: i32 = 1 << l
1940
+ for (let r: i32 = deflateReverse(code, l); r < size; r += step) {
1941
+ uncheckedSet(entries, r, e)
1942
+ }
1943
+ }
1944
+ k += 1
1945
+ code += 1
1946
+ }
1947
+ code = code << 1
1948
+ }
1949
+ return 0
1783
1950
  }
1951
+ // A complete code whose shortest codes fit the table. The codes in
1952
+ // canonical order, kept bit-reversed (the table is indexed by the
1953
+ // stream's low bits first): each is written once into a table of
1954
+ // `end = 2^len` entries, and the table is doubled by copying each time
1955
+ // the length grows, which repeats every code at every slot it prefixes.
1956
+ // A reversed code is incremented by clearing the ones below its highest
1957
+ // zero and setting that zero.
1784
1958
  let code: i32 = 0
1959
+ let end: i32 = 1 << len
1785
1960
  let k: i32 = 0
1786
- for (let l: i32 = 1; l <= bits && l < 16; l += 1) {
1787
- const codesHere: i32 = uncheckedGet(count, l)
1788
- for (let c: i32 = 0; c < codesHere; c += 1) {
1789
- if (k >= 0 && k < toI32(syms.length)) {
1790
- const e: i32 = this.entryOf(kind, syms[k], l)
1791
- const step: i32 = 1 << l
1792
- for (let r: i32 = deflateReverse(code, l); r < size; r += step) {
1793
- uncheckedSet(entries, r, e)
1794
- }
1961
+ let here: i32 = 0
1962
+ while (len <= bits && len >= 0 && len < toI32(count.length)) {
1963
+ here = count[len]
1964
+ while (here > 0) {
1965
+ if (k < 0 || k >= toI32(syms.length) || code < 0 || code >= end || end > size) {
1966
+ panic("Inflater.build: a code outside its table")
1795
1967
  }
1968
+ uncheckedSet(entries, code, tmpl[syms[k]] | len)
1796
1969
  k += 1
1797
- code += 1
1970
+ if (code === end - 1) {
1971
+ // The last code, all ones: the code is complete within the table.
1972
+ while (end < size) {
1973
+ inflateDouble(entries, end)
1974
+ end = end << 1
1975
+ }
1976
+ return 0
1977
+ }
1978
+ const bit: i32 = toI32(1) << (31 - toI32(Math.clz32(toU32(code ^ (end - 1)))))
1979
+ code = (code & (bit - 1)) | bit
1980
+ here -= 1
1981
+ }
1982
+ len += 1
1983
+ while (len < 16 && count[len] === 0) {
1984
+ len += 1
1985
+ }
1986
+ while (end < size && end < 1 << len) {
1987
+ inflateDouble(entries, end)
1988
+ end = end << 1
1989
+ }
1990
+ }
1991
+ here = len < 16 ? count[len] : 0
1992
+ // Codes longer than the table remain, `here` of them of length `len`,
1993
+ // and `code` is the next, reversed, its low `bits` bits a slot of the
1994
+ // main table. The codes that share a slot get a subtable after the
1995
+ // tables already built, as wide as it takes for them to fill it (the
1996
+ // code is complete, so they do), and the slot points to it. A subtable
1997
+ // entry carries the bits past the main table's as its length.
1998
+ const limit: i32 = toI32(entries.length)
1999
+ let prefix: i32 = -1
2000
+ let start: i32 = 0
2001
+ let subEnd: i32 = size
2002
+ while (true) {
2003
+ if (len < bits || len > 15) {
2004
+ panic("Inflater.build: a code outside its table")
2005
+ }
2006
+ if ((code & (size - 1)) !== prefix) {
2007
+ prefix = code & (size - 1)
2008
+ start = subEnd
2009
+ let subBits: i32 = len - bits
2010
+ let used: i32 = here
2011
+ while (used < 1 << subBits && bits + subBits < 15) {
2012
+ subBits += 1
2013
+ used = (used << 1) + count[bits + subBits]
2014
+ }
2015
+ subEnd = start + (1 << subBits)
2016
+ if (subEnd > limit || prefix < 0) {
2017
+ panic("Inflater.build: a subtable past the table's room")
2018
+ }
2019
+ uncheckedSet(entries, prefix, (start << 16) | (INF_SUB << 8) | (subBits << 11) | bits)
2020
+ }
2021
+ if (k < 0 || k >= toI32(syms.length)) {
2022
+ panic("Inflater.build: a code outside its table")
2023
+ }
2024
+ const e: i32 = tmpl[syms[k]] | (len - bits)
2025
+ k += 1
2026
+ const stride: i32 = toI32(1) << (len - bits)
2027
+ let i: i32 = start + (code >> bits)
2028
+ while (i < subEnd && i >= 0) {
2029
+ uncheckedSet(entries, i, e)
2030
+ i += stride
2031
+ }
2032
+ if (code === (1 << len) - 1) {
2033
+ return 0
2034
+ }
2035
+ const bit: i32 = toI32(1) << (31 - toI32(Math.clz32(toU32(code ^ ((toI32(1) << len) - 1)))))
2036
+ code = (code & (bit - 1)) | bit
2037
+ here -= 1
2038
+ while (here === 0 && len < 15) {
2039
+ const next: i32 = len + 1
2040
+ if (next < 0 || next >= toI32(count.length)) {
2041
+ break
2042
+ }
2043
+ len = next
2044
+ here = count[next]
1798
2045
  }
1799
- code = code << 1
1800
2046
  }
1801
- return 0
1802
2047
  }
1803
2048
 
1804
2049
  /**
@@ -1843,10 +2088,18 @@ export class Inflater {
1843
2088
  if (ip < 0 || end > toI32(src.length)) {
1844
2089
  panic("Inflater.fill: a window outside its input")
1845
2090
  }
1846
- while (bc <= 56 && ip < end) {
1847
- bb = bb | (toU64(uncheckedGet(src, ip)) << toU64(bc))
1848
- ip += 1
1849
- bc += 8
2091
+ if (ip <= end - 8) {
2092
+ // A word at once, whole bytes of it counted, as the fast loop does.
2093
+ const at: integer<0, 2147483639> = ip
2094
+ bb = bb | (deflateLoad64(src, at) << toU64(bc))
2095
+ ip += (63 - bc) >> 3
2096
+ bc = bc | 56
2097
+ } else {
2098
+ while (bc <= 56 && ip < end) {
2099
+ bb = bb | (toU64(uncheckedGet(src, ip)) << toU64(bc))
2100
+ ip += 1
2101
+ bc += 8
2102
+ }
1850
2103
  }
1851
2104
  this.bitBuf = bb
1852
2105
  this.bitCount = bc
@@ -1881,13 +2134,34 @@ export class Inflater {
1881
2134
  * out first (nothing is consumed then: the caller rewinds), or an error.
1882
2135
  */
1883
2136
  readDynamic(src: u8[], end: i32): i32 {
1884
- this.fill(src, end)
1885
- if (this.bitCount < 14) {
2137
+ // The bit buffer in locals: the lengths are stored into an `i32[]`,
2138
+ // which the fields could alias, and every symbol would reload them.
2139
+ let bb: u64 = this.bitBuf
2140
+ let bc: i32 = this.bitCount
2141
+ let ip: i32 = this.inPos
2142
+ if (ip < 0 || end > toI32(src.length)) {
2143
+ panic("Inflater.readDynamic: a window outside its input")
2144
+ }
2145
+ if (ip <= end - 8) {
2146
+ const at: integer<0, 2147483639> = ip
2147
+ bb = bb | (deflateLoad64(src, at) << toU64(bc))
2148
+ ip += (63 - bc) >> 3
2149
+ bc = bc | 56
2150
+ } else {
2151
+ while (bc <= 56 && ip < end) {
2152
+ bb = bb | (toU64(uncheckedGet(src, ip)) << toU64(bc))
2153
+ ip += 1
2154
+ bc += 8
2155
+ }
2156
+ }
2157
+ if (bc < 14) {
1886
2158
  return INFLATE_NEED_INPUT
1887
2159
  }
1888
- const hlit: i32 = this.take(toI32(5)) + 257
1889
- const hdist: i32 = this.take(toI32(5)) + 1
1890
- const hclen: i32 = this.take(toI32(4)) + 4
2160
+ const hlit: i32 = toI32(bb & toU64(31)) + 257
2161
+ const hdist: i32 = toI32((bb >> toU64(5)) & toU64(31)) + 1
2162
+ const hclen: i32 = toI32((bb >> toU64(10)) & toU64(15)) + 4
2163
+ bb = bb >> toU64(14)
2164
+ bc -= 14
1891
2165
  if (hlit > 286 || hdist > 30) {
1892
2166
  return DEFLATE_ERR_HUFFMAN
1893
2167
  }
@@ -1896,11 +2170,26 @@ export class Inflater {
1896
2170
  cl[deflateClOrder(i)] = 0
1897
2171
  }
1898
2172
  for (let i: i32 = 0; i < hclen; i += 1) {
1899
- this.fill(src, end)
1900
- if (this.bitCount < 3) {
1901
- return INFLATE_NEED_INPUT
2173
+ if (bc < 3) {
2174
+ if (ip >= 0 && ip <= end - 8 && ip <= 2147483639) {
2175
+ const at: integer<0, 2147483639> = ip
2176
+ bb = bb | (deflateLoad64(src, at) << toU64(bc))
2177
+ ip += (63 - bc) >> 3
2178
+ bc = bc | 56
2179
+ } else {
2180
+ while (bc <= 56 && ip < end) {
2181
+ bb = bb | (toU64(uncheckedGet(src, ip)) << toU64(bc))
2182
+ ip += 1
2183
+ bc += 8
2184
+ }
2185
+ }
2186
+ if (bc < 3) {
2187
+ return INFLATE_NEED_INPUT
2188
+ }
1902
2189
  }
1903
- cl[deflateClOrder(i)] = this.take(toI32(3))
2190
+ cl[deflateClOrder(i)] = toI32(bb & toU64(7))
2191
+ bb = bb >> toU64(3)
2192
+ bc -= 3
1904
2193
  }
1905
2194
  const r: i32 = this.build(this.codeLengths, cl, toI32(0), toI32(19), INF_TABLE_CODELEN)
1906
2195
  if (r !== 0) {
@@ -1908,20 +2197,38 @@ export class Inflater {
1908
2197
  }
1909
2198
  const lens: i32[] = this.lens
1910
2199
  const entries: i32[] = this.codeLengths.entries
2200
+ if (toI32(entries.length) < 128) {
2201
+ panic("Inflater.readDynamic: the code-length table is not its size")
2202
+ }
1911
2203
  const total: i32 = hlit + hdist
1912
2204
  let i: i32 = 0
1913
2205
  while (i < total) {
1914
- this.fill(src, end)
1915
- const e: i32 = entries[toI32(this.bitBuf & toU64(127))]
2206
+ // A code-length code is at most 7 bits and its repeat count at most 7.
2207
+ if (bc < 14) {
2208
+ if (ip >= 0 && ip <= end - 8 && ip <= 2147483639) {
2209
+ const at: integer<0, 2147483639> = ip
2210
+ bb = bb | (deflateLoad64(src, at) << toU64(bc))
2211
+ ip += (63 - bc) >> 3
2212
+ bc = bc | 56
2213
+ } else {
2214
+ while (bc <= 56 && ip < end) {
2215
+ bb = bb | (toU64(uncheckedGet(src, ip)) << toU64(bc))
2216
+ ip += 1
2217
+ bc += 8
2218
+ }
2219
+ }
2220
+ }
2221
+ const e: i32 = uncheckedGet(entries, toI32(bb & toU64(127)))
1916
2222
  if (((e >> 8) & 7) === INF_SLOW) {
1917
2223
  // Only an incomplete code-length code leaves a prefix unfilled.
1918
- return this.bitCount >= 7 ? DEFLATE_ERR_SYMBOL : INFLATE_NEED_INPUT
2224
+ return bc >= 7 ? DEFLATE_ERR_SYMBOL : INFLATE_NEED_INPUT
1919
2225
  }
1920
2226
  const l: i32 = e & 15
1921
- if (l > this.bitCount) {
2227
+ if (l > bc) {
1922
2228
  return INFLATE_NEED_INPUT
1923
2229
  }
1924
- this.take(l)
2230
+ bb = bb >> toU64(l)
2231
+ bc -= l
1925
2232
  const sym: i32 = e >> 16
1926
2233
  if (sym < 16) {
1927
2234
  if (i < 0 || i >= toI32(lens.length)) {
@@ -1932,26 +2239,27 @@ export class Inflater {
1932
2239
  } else {
1933
2240
  let rep: i32 = 0
1934
2241
  let value: i32 = 0
2242
+ let x: i32 = 0
1935
2243
  if (sym === 16) {
1936
2244
  if (i === 0) {
1937
2245
  return DEFLATE_ERR_HUFFMAN
1938
2246
  }
1939
- if (this.bitCount < 2) {
1940
- return INFLATE_NEED_INPUT
1941
- }
1942
2247
  value = lens[i - 1]
1943
- rep = toI32(3) + this.take(toI32(2))
2248
+ x = 2
2249
+ rep = 3
1944
2250
  } else if (sym === 17) {
1945
- if (this.bitCount < 3) {
1946
- return INFLATE_NEED_INPUT
1947
- }
1948
- rep = toI32(3) + this.take(toI32(3))
2251
+ x = 3
2252
+ rep = 3
1949
2253
  } else {
1950
- if (this.bitCount < 7) {
1951
- return INFLATE_NEED_INPUT
1952
- }
1953
- rep = toI32(11) + this.take(toI32(7))
2254
+ x = 7
2255
+ rep = 11
2256
+ }
2257
+ if (bc < x) {
2258
+ return INFLATE_NEED_INPUT
1954
2259
  }
2260
+ rep += toI32(bb & ((toU64(1) << toU64(x)) - toU64(1)))
2261
+ bb = bb >> toU64(x)
2262
+ bc -= x
1955
2263
  if (i + rep > total) {
1956
2264
  return DEFLATE_ERR_HUFFMAN
1957
2265
  }
@@ -1968,7 +2276,14 @@ export class Inflater {
1968
2276
  if (rl !== 0) {
1969
2277
  return rl
1970
2278
  }
1971
- return this.build(this.dist, lens, hlit, hdist, INF_TABLE_DIST)
2279
+ const rd: i32 = this.build(this.dist, lens, hlit, hdist, INF_TABLE_DIST)
2280
+ if (rd !== 0) {
2281
+ return rd
2282
+ }
2283
+ this.bitBuf = bb
2284
+ this.bitCount = bc
2285
+ this.inPos = ip
2286
+ return 0
1972
2287
  }
1973
2288
 
1974
2289
  /**
@@ -2114,110 +2429,189 @@ export class Inflater {
2114
2429
  const dt: InflateTable = this.fixed ? this.fixedDist : this.dist
2115
2430
  const le: i32[] = lt.entries
2116
2431
  const de: i32[] = dt.entries
2117
- if (toI32(le.length) !== 1 << INF_LIT_BITS || toI32(de.length) !== 1 << INF_DIST_BITS) {
2432
+ if (toI32(le.length) !== INF_LIT_ENOUGH || toI32(de.length) !== INF_DIST_ENOUGH) {
2118
2433
  panic("Inflater.huffman: a table is not its size")
2119
2434
  }
2120
2435
  const litMask: u64 = toU64((1 << INF_LIT_BITS) - 1)
2121
2436
  const distMask: u64 = toU64((1 << INF_DIST_BITS) - 1)
2437
+ // The fast loop runs while eight bytes of input can be loaded and the
2438
+ // longest match, with sixteen bytes of copy slack, fits the output.
2439
+ const inFast: i32 = inEnd - 8
2440
+ const outFast: i32 = outEnd - INF_FAST_ROOM
2122
2441
  let bb: u64 = this.bitBuf
2123
2442
  let bc: i32 = this.bitCount
2124
2443
  let ip: i32 = this.inPos
2125
2444
  let op: i32 = this.outPos
2126
2445
  let status: i32 = 0
2446
+ let ended: boolean = false
2127
2447
  while (true) {
2128
- // The fast loop: while eight bytes of input and the longest match
2129
- // with eight bytes of slack fit, no symbol can run short, so none is
2130
- // checked for it. A symbol the fast loop does not decode (an end of
2131
- // block, a long code, an error) is rewound and left to the careful
2132
- // step below, which then hands back here.
2133
- while (ip >= 0 && ip <= inEnd - 8 && ip <= 2147483639 && op >= 0 && op <= outEnd - 274) {
2134
- const fBb: u64 = bb
2135
- const fBc: i32 = bc
2136
- const fIp: i32 = ip
2137
- bb = bb | (deflateLoad64(src, ip) << toU64(bc))
2138
- ip += (63 - bc) >> 3
2448
+ // The fast loop: after a refill the buffer holds 64 bits of input, of
2449
+ // which it counts the whole bytes (56 to 63), and a length, its extra
2450
+ // bits, a distance and its extra bits take at most 48. So no symbol is
2451
+ // checked for running short, every symbol is decoded here (the end of
2452
+ // the block and errors included), and the next symbol's entry is
2453
+ // looked up before the refill rather than after it, from the 16 or
2454
+ // more bits still in hand, which takes the refill off the chain of
2455
+ // lookups. The careful step below takes over where the input or the
2456
+ // output runs short.
2457
+ //
2458
+ // The bit count may carry borrows above its low byte, which alone is
2459
+ // the count: subtracting a whole entry, whose low byte is its length,
2460
+ // costs no mask, and every shift reads the low six bits only. It is
2461
+ // masked again when the loop ends.
2462
+ if (ip >= 0 && ip <= inFast && ip <= 2147483639 && op <= outFast) {
2463
+ const first: integer<0, 2147483639> = ip
2464
+ bb = bb | (deflateLoad64(src, first) << toU64(bc))
2465
+ ip = wrappingAdd(ip, toI32(7) - ((bc >> 3) & 7))
2139
2466
  bc = bc | 56
2140
2467
  let e: i32 = uncheckedGet(le, toI32(bb & litMask))
2141
- if ((e & 0x700) === 0) {
2142
- // A literal; with at least 41 bits left, so may the next two be.
2143
- const n: i32 = e & 15
2144
- bb = bb >> toU64(n)
2145
- bc -= n
2146
- uncheckedSet(out, op, toU8(e >> 16))
2147
- op += 1
2148
- e = uncheckedGet(le, toI32(bb & litMask))
2468
+ while (true) {
2149
2469
  if ((e & 0x700) === 0) {
2150
- const n2: i32 = e & 15
2151
- bb = bb >> toU64(n2)
2152
- bc -= n2
2470
+ // A literal of at most eleven bits; with 45 or more bits left,
2471
+ // so may the next two be.
2472
+ bb = bb >> toU64(e)
2473
+ bc = wrappingSub(bc, e)
2153
2474
  uncheckedSet(out, op, toU8(e >> 16))
2154
- op += 1
2475
+ op = wrappingAdd(op, 1)
2155
2476
  e = uncheckedGet(le, toI32(bb & litMask))
2156
2477
  if ((e & 0x700) === 0) {
2157
- const n3: i32 = e & 15
2158
- bb = bb >> toU64(n3)
2159
- bc -= n3
2478
+ bb = bb >> toU64(e)
2479
+ bc = wrappingSub(bc, e)
2160
2480
  uncheckedSet(out, op, toU8(e >> 16))
2161
- op += 1
2481
+ op = wrappingAdd(op, 1)
2482
+ e = uncheckedGet(le, toI32(bb & litMask))
2483
+ if ((e & 0x700) === 0) {
2484
+ bb = bb >> toU64(e)
2485
+ bc = wrappingSub(bc, e)
2486
+ uncheckedSet(out, op, toU8(e >> 16))
2487
+ op = wrappingAdd(op, 1)
2488
+ e = uncheckedGet(le, toI32(bb & litMask))
2489
+ }
2490
+ }
2491
+ } else {
2492
+ if ((e & 0x700) === INF_SUB << 8) {
2493
+ // A code longer than the table: its last bits index a subtable.
2494
+ bb = bb >> toU64(e)
2495
+ bc = wrappingSub(bc, e)
2496
+ e = uncheckedGet(le, (e >> 16) + toI32(bb & toU64((toI32(1) << ((e >> 11) & 15)) - 1)))
2497
+ } else if ((e & 0x700) === INF_SLOW << 8) {
2498
+ // Only a table built for an incomplete code (none at all, or
2499
+ // one one-bit code) has these, and every code it does have
2500
+ // is in the table: with all the bits in hand, no code matches.
2501
+ status = DEFLATE_ERR_SYMBOL
2502
+ break
2503
+ }
2504
+ bb = bb >> toU64(e)
2505
+ bc = wrappingSub(bc, e)
2506
+ if ((e & 0x700) !== INF_LENGTH << 8) {
2507
+ if ((e & 0x700) === INF_LITERAL << 8) {
2508
+ uncheckedSet(out, op, toU8(e >> 16))
2509
+ op = wrappingAdd(op, 1)
2510
+ e = uncheckedGet(le, toI32(bb & litMask))
2511
+ } else {
2512
+ if ((e & 0x700) === INF_END << 8) {
2513
+ this.state = INF_S_BLOCK
2514
+ } else {
2515
+ status = DEFLATE_ERR_SYMBOL
2516
+ }
2517
+ ended = true
2518
+ break
2519
+ }
2520
+ } else {
2521
+ const lx: i32 = (e >> 11) & 15
2522
+ const len: i32 = (e >> 16) + toI32(bb & ((toU64(1) << toU64(lx)) - toU64(1)))
2523
+ bb = bb >> toU64(lx)
2524
+ bc = wrappingSub(bc, lx)
2525
+ let d: i32 = uncheckedGet(de, toI32(bb & distMask))
2526
+ if ((d & 0x700) === INF_SUB << 8) {
2527
+ bb = bb >> toU64(d)
2528
+ bc = wrappingSub(bc, d)
2529
+ d = uncheckedGet(de, (d >> 16) + toI32(bb & toU64((toI32(1) << ((d >> 11) & 15)) - 1)))
2530
+ }
2531
+ if ((d & 0x700) !== 0) {
2532
+ // A slow entry, as for the literal/length table, or one of
2533
+ // the two distance codes that decode as errors.
2534
+ status = DEFLATE_ERR_SYMBOL
2535
+ break
2536
+ }
2537
+ bb = bb >> toU64(d)
2538
+ bc = wrappingSub(bc, d)
2539
+ const dx: i32 = (d >> 11) & 15
2540
+ const dist: i32 = (d >> 16) + toI32(bb & ((toU64(1) << toU64(dx)) - toU64(1)))
2541
+ bb = bb >> toU64(dx)
2542
+ bc = wrappingSub(bc, dx)
2543
+ if (dist > op - histStart) {
2544
+ status = DEFLATE_ERR_DISTANCE
2545
+ break
2546
+ }
2547
+ // The next entry, before the copy, so that its lookup and the
2548
+ // copy overlap.
2549
+ e = uncheckedGet(le, toI32(bb & litMask))
2550
+ const stop: i32 = wrappingAdd(op, len)
2551
+ if (dist >= 8) {
2552
+ // Sixteen bytes at a time: a copy runs at most fifteen bytes
2553
+ // past `stop`, inside `outEnd`, and the next symbol
2554
+ // overwrites them. `op` and `op - dist` lie in
2555
+ // [histStart, outEnd - 290], so the bounds in the condition
2556
+ // always hold; they are what lets the positions enter the
2557
+ // copy's range without a check, and the bytes loop after is
2558
+ // what would finish a copy they ever stopped.
2559
+ let to: i32 = op
2560
+ let from: i32 = op - dist
2561
+ while (to < stop && to >= 0 && to <= 2147483631 && from >= 0 && from <= 2147483631) {
2562
+ inflateCopy16(out, to, from)
2563
+ to = wrappingAdd(to, 16)
2564
+ from = wrappingAdd(from, 16)
2565
+ }
2566
+ while (to < stop) {
2567
+ uncheckedSet(out, to, uncheckedGet(out, from))
2568
+ to = wrappingAdd(to, 1)
2569
+ from = wrappingAdd(from, 1)
2570
+ }
2571
+ } else if (dist === 1) {
2572
+ // A run of one byte, sixteen at a time, bounded as above.
2573
+ const four: u64 = toU64(uncheckedGet(out, op - 1)) * toU64(0x01010101)
2574
+ const w: u64 = four | (four << toU64(32))
2575
+ let to: i32 = op
2576
+ while (to < stop && to >= 0 && to <= 2147483631) {
2577
+ inflateFill16(out, to, w)
2578
+ to = wrappingAdd(to, 16)
2579
+ }
2580
+ while (to < stop) {
2581
+ uncheckedSet(out, to, toU8(w))
2582
+ to = wrappingAdd(to, 1)
2583
+ }
2584
+ } else {
2585
+ let from: i32 = op - dist
2586
+ let to: i32 = op
2587
+ while (to < stop) {
2588
+ uncheckedSet(out, to, uncheckedGet(out, from))
2589
+ to = wrappingAdd(to, 1)
2590
+ from = wrappingAdd(from, 1)
2591
+ }
2592
+ }
2593
+ op = stop
2162
2594
  }
2163
2595
  }
2164
- continue
2165
- }
2166
- if (((e >> 8) & 7) !== INF_LENGTH) {
2167
- bb = fBb
2168
- bc = fBc
2169
- ip = fIp
2170
- break
2171
- }
2172
- const n: i32 = e & 15
2173
- bb = bb >> toU64(n)
2174
- const lx: i32 = (e >> 4) & 15
2175
- const len: i32 = (e >> 16) + toI32(bb & ((toU64(1) << toU64(lx)) - toU64(1)))
2176
- bb = bb >> toU64(lx)
2177
- const d: i32 = uncheckedGet(de, toI32(bb & distMask))
2178
- if ((d & 0x700) !== 0) {
2179
- bb = fBb
2180
- bc = fBc
2181
- ip = fIp
2182
- break
2183
- }
2184
- const dn: i32 = d & 15
2185
- const dx: i32 = (d >> 4) & 15
2186
- bb = bb >> toU64(dn)
2187
- const dist: i32 = (d >> 16) + toI32(bb & ((toU64(1) << toU64(dx)) - toU64(1)))
2188
- bb = bb >> toU64(dx)
2189
- bc -= n + lx + dn + dx
2190
- if (dist > op - histStart) {
2191
- status = DEFLATE_ERR_DISTANCE
2192
- break
2193
- }
2194
- let from: i32 = op - dist
2195
- const stop: i32 = op + len
2196
- if (dist >= 8) {
2197
- while (op < stop && from >= 0 && from <= 2147483639 && op >= 0 && op <= 2147483639) {
2198
- deflateStore64(out, op, deflateLoad64(out, from))
2199
- op += 8
2200
- from += 8
2201
- }
2202
- op = stop
2203
- } else {
2204
- while (op < stop && from >= 0 && from < op) {
2205
- uncheckedSet(out, op, uncheckedGet(out, from))
2206
- op += 1
2207
- from += 1
2596
+ if (ip < 0 || ip > inFast || ip > 2147483639 || op > outFast) {
2597
+ break
2208
2598
  }
2209
- op = stop
2599
+ const at: integer<0, 2147483639> = ip
2600
+ bb = bb | (deflateLoad64(src, at) << toU64(bc))
2601
+ ip = wrappingAdd(ip, toI32(7) - ((bc >> 3) & 7))
2602
+ bc = bc | 56
2210
2603
  }
2211
2604
  }
2212
- if (status !== 0) {
2605
+ bc = bc & 63
2606
+ if (status !== 0 || ended) {
2213
2607
  break
2214
2608
  }
2215
2609
  const sBb: u64 = bb
2216
2610
  const sBc: i32 = bc
2217
2611
  const sIp: i32 = ip
2218
- // Refill to at least 56 bits: every symbol, its extra bits, its
2219
- // distance and their extra bits take at most 48.
2220
- if (ip >= 0 && ip <= 2147483639 && ip + 8 <= inEnd) {
2612
+ // Refill to at least 56 bits where eight bytes remain, else as many
2613
+ // as there are: a symbol is decoded only once all its bits are here.
2614
+ if (ip >= 0 && ip <= inFast) {
2221
2615
  bb = bb | (deflateLoad64(src, ip) << toU64(bc))
2222
2616
  ip += (63 - bc) >> 3
2223
2617
  bc = bc | 56
@@ -2228,19 +2622,11 @@ export class Inflater {
2228
2622
  bc += 8
2229
2623
  }
2230
2624
  }
2231
- let e: i32 = uncheckedGet(le, toI32(bb & litMask))
2232
- let kind: i32 = (e >> 8) & 7
2233
- if (kind === INF_SLOW) {
2234
- e = this.slowDecode(lt, INF_TABLE_LITLEN, bb, bc)
2235
- if (e === -1) {
2236
- status = INFLATE_NEED_INPUT
2237
- } else if (e < 0) {
2238
- status = DEFLATE_ERR_SYMBOL
2239
- }
2240
- kind = (e >> 8) & 7
2241
- }
2242
- if (status === 0 && (e & 15) > bc) {
2625
+ const e: i32 = this.lookup(lt, INF_TABLE_LITLEN, le, bb, bc)
2626
+ if (e === -1) {
2243
2627
  status = INFLATE_NEED_INPUT
2628
+ } else if (e < 0) {
2629
+ status = DEFLATE_ERR_SYMBOL
2244
2630
  }
2245
2631
  if (status !== 0) {
2246
2632
  if (status === INFLATE_NEED_INPUT) {
@@ -2253,6 +2639,7 @@ export class Inflater {
2253
2639
  }
2254
2640
  break
2255
2641
  }
2642
+ const kind: i32 = (e >> 8) & 7
2256
2643
  const n: i32 = e & 15
2257
2644
  bb = bb >> toU64(n)
2258
2645
  bc -= n
@@ -2267,7 +2654,7 @@ export class Inflater {
2267
2654
  uncheckedSet(out, op, toU8(e >> 16))
2268
2655
  op += 1
2269
2656
  } else if (kind === INF_LENGTH) {
2270
- const lx: i32 = (e >> 4) & 15
2657
+ const lx: i32 = (e >> 11) & 15
2271
2658
  if (lx > bc) {
2272
2659
  bb = sBb
2273
2660
  bc = sBc
@@ -2278,27 +2665,20 @@ export class Inflater {
2278
2665
  const len: i32 = (e >> 16) + toI32(bb & ((toU64(1) << toU64(lx)) - toU64(1)))
2279
2666
  bb = bb >> toU64(lx)
2280
2667
  bc -= lx
2281
- let d: i32 = uncheckedGet(de, toI32(bb & distMask))
2282
- if (((d >> 8) & 7) === INF_SLOW) {
2283
- d = this.slowDecode(dt, INF_TABLE_DIST, bb, bc)
2284
- if (d === -1) {
2285
- bb = sBb
2286
- bc = sBc
2287
- ip = sIp
2288
- status = more ? INFLATE_NEED_INPUT : DEFLATE_ERR_TRUNCATED
2289
- break
2290
- }
2291
- if (d < 0) {
2292
- status = DEFLATE_ERR_SYMBOL
2293
- break
2294
- }
2668
+ const d: i32 = this.lookup(dt, INF_TABLE_DIST, de, bb, bc)
2669
+ if (d === -1) {
2670
+ bb = sBb
2671
+ bc = sBc
2672
+ ip = sIp
2673
+ status = more ? INFLATE_NEED_INPUT : DEFLATE_ERR_TRUNCATED
2674
+ break
2295
2675
  }
2296
- if (((d >> 8) & 7) === INF_INVALID) {
2676
+ if (d < 0 || ((d >> 8) & 7) === INF_INVALID) {
2297
2677
  status = DEFLATE_ERR_SYMBOL
2298
2678
  break
2299
2679
  }
2300
2680
  const dn: i32 = d & 15
2301
- const dx: i32 = (d >> 4) & 15
2681
+ const dx: i32 = (d >> 11) & 15
2302
2682
  if (dn + dx > bc) {
2303
2683
  bb = sBb
2304
2684
  bc = sBc
@@ -2323,21 +2703,10 @@ export class Inflater {
2323
2703
  }
2324
2704
  let from: i32 = op - dist
2325
2705
  const stop: i32 = op + len
2326
- if (dist >= 8 && stop + 8 <= outEnd) {
2327
- // Eight bytes at a time; a copy may run up to seven bytes past
2328
- // `stop`, inside `outEnd`, which the next symbol overwrites.
2329
- while (op < stop && from >= 0 && from <= 2147483639 && op >= 0 && op <= 2147483639) {
2330
- deflateStore64(out, op, deflateLoad64(out, from))
2331
- op += 8
2332
- from += 8
2333
- }
2334
- op = stop
2335
- } else {
2336
- while (op < stop) {
2337
- uncheckedSet(out, op, uncheckedGet(out, from))
2338
- op += 1
2339
- from += 1
2340
- }
2706
+ while (op < stop) {
2707
+ uncheckedSet(out, op, uncheckedGet(out, from))
2708
+ op += 1
2709
+ from += 1
2341
2710
  }
2342
2711
  } else if (kind === INF_END) {
2343
2712
  this.state = INF_S_BLOCK
@@ -2354,6 +2723,27 @@ export class Inflater {
2354
2723
  return status
2355
2724
  }
2356
2725
 
2726
+ /**
2727
+ * The entry of the symbol at the bottom of `bb`, holding `bc` valid bits,
2728
+ * from `t` (whose entries are `entries`), with its whole code length in
2729
+ * the low four bits, through a subtable or the slow way as the table
2730
+ * says: -1 when the bits run out before the code ends, -2 when no code
2731
+ * matches. A code is decoded only once all its bits are here.
2732
+ */
2733
+ lookup(t: InflateTable, kind: i32, entries: i32[], bb: u64, bc: i32): i32 {
2734
+ const mask: u64 = toU64((1 << t.bits) - 1)
2735
+ let e: i32 = entries[toI32(bb & mask)]
2736
+ if (((e >> 8) & 7) === INF_SUB) {
2737
+ const root: i32 = e & 15
2738
+ const at: i32 = (e >> 16) + toI32((bb >> toU64(root)) & toU64((toI32(1) << ((e >> 11) & 15)) - 1))
2739
+ const sub: i32 = entries[at]
2740
+ e = (sub & ~15) | (root + (sub & 15))
2741
+ } else if (((e >> 8) & 7) === INF_SLOW) {
2742
+ return this.slowDecode(t, kind, bb, bc)
2743
+ }
2744
+ return (e & 15) > bc ? -1 : e
2745
+ }
2746
+
2357
2747
  /**
2358
2748
  * Decompresses the raw DEFLATE stream `src[off .. off + len)` into `out`
2359
2749
  * from `at`, writing at most `limit` bytes and never past `out`'s end, and