@scriptc/compiler 0.1.3 → 0.1.4

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 (147) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +200 -51
  2. package/dist/backend/c/async.d.ts +25 -0
  3. package/dist/backend/c/async.js +167 -0
  4. package/dist/backend/c/async.js.map +1 -1
  5. package/dist/backend/c/c-emitter.d.ts +10 -0
  6. package/dist/backend/c/c-emitter.js +14 -2
  7. package/dist/backend/c/c-emitter.js.map +1 -1
  8. package/dist/backend/c/exprs.js +293 -51
  9. package/dist/backend/c/exprs.js.map +1 -1
  10. package/dist/backend/c/types.js +2 -0
  11. package/dist/backend/c/types.js.map +1 -1
  12. package/dist/backend/link-plan.d.ts +2 -1
  13. package/dist/backend/link-plan.js +2 -1
  14. package/dist/backend/link-plan.js.map +1 -1
  15. package/dist/backend/llvm/emitter.js +20 -6
  16. package/dist/backend/llvm/emitter.js.map +1 -1
  17. package/dist/backend/llvm/expr-bytes.d.ts +1 -1
  18. package/dist/backend/llvm/expr-bytes.js +8 -8
  19. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  20. package/dist/backend/llvm/expr-callbacks.d.ts +9 -0
  21. package/dist/backend/llvm/expr-callbacks.js +125 -0
  22. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  23. package/dist/backend/llvm/expr-context.d.ts +14 -2
  24. package/dist/backend/llvm/expr-dispatch.js +1 -0
  25. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  26. package/dist/backend/llvm/expr-primitives.d.ts +1 -1
  27. package/dist/backend/llvm/expr-primitives.js +30 -9
  28. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  29. package/dist/backend/llvm/expr-primitives.test.d.ts +1 -0
  30. package/dist/backend/llvm/expr-primitives.test.js +38 -0
  31. package/dist/backend/llvm/expr-primitives.test.js.map +1 -0
  32. package/dist/backend/llvm/expr-stream-callbacks.d.ts +3 -0
  33. package/dist/backend/llvm/expr-stream-callbacks.js +69 -0
  34. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  35. package/dist/backend/llvm/lib-filesystem.js +68 -10
  36. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  37. package/dist/backend/llvm/lib-network.js +18 -2
  38. package/dist/backend/llvm/lib-network.js.map +1 -1
  39. package/dist/backend/llvm/lib-process.js +156 -6
  40. package/dist/backend/llvm/lib-process.js.map +1 -1
  41. package/dist/backend/llvm/lib-shared.js +36 -0
  42. package/dist/backend/llvm/lib-shared.js.map +1 -1
  43. package/dist/backend/llvm/lib-stream.js +23 -0
  44. package/dist/backend/llvm/lib-stream.js.map +1 -1
  45. package/dist/backend/native-toolchain.d.ts +3 -0
  46. package/dist/backend/native-toolchain.js +3 -1
  47. package/dist/backend/native-toolchain.js.map +1 -1
  48. package/dist/backend/runtime-pack.test.js +28 -10
  49. package/dist/backend/runtime-pack.test.js.map +1 -1
  50. package/dist/backend/targets.d.ts +4 -0
  51. package/dist/backend/targets.js +13 -0
  52. package/dist/backend/targets.js.map +1 -1
  53. package/dist/backend/targets.test.js +8 -1
  54. package/dist/backend/targets.test.js.map +1 -1
  55. package/dist/coverage/surface-manifest.js +8 -0
  56. package/dist/coverage/surface-manifest.js.map +1 -1
  57. package/dist/diagnostics/diagnostic.js +1 -1
  58. package/dist/diagnostics/diagnostic.js.map +1 -1
  59. package/dist/executable/executable-cache.d.ts +2 -0
  60. package/dist/executable/executable-cache.js +3 -0
  61. package/dist/executable/executable-cache.js.map +1 -1
  62. package/dist/frontend/fork-target.d.ts +17 -0
  63. package/dist/frontend/fork-target.js +256 -0
  64. package/dist/frontend/fork-target.js.map +1 -0
  65. package/dist/frontend/lowering/abstract-equality.d.ts +6 -0
  66. package/dist/frontend/lowering/abstract-equality.js +250 -0
  67. package/dist/frontend/lowering/abstract-equality.js.map +1 -0
  68. package/dist/frontend/lowering/lower-assert.js +71 -2
  69. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  70. package/dist/frontend/lowering/lower-builtins.d.ts +50 -23
  71. package/dist/frontend/lowering/lower-builtins.js +939 -106
  72. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  73. package/dist/frontend/lowering/lower-calls.d.ts +29 -21
  74. package/dist/frontend/lowering/lower-calls.js +573 -121
  75. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  76. package/dist/frontend/lowering/lower-classes.js +39 -8
  77. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  78. package/dist/frontend/lowering/lower-containers.js +150 -0
  79. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  80. package/dist/frontend/lowering/lower-event-emitter.js +212 -21
  81. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  82. package/dist/frontend/lowering/lower-exprs.js +135 -83
  83. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  84. package/dist/frontend/lowering/lower-inspect.d.ts +4 -0
  85. package/dist/frontend/lowering/lower-inspect.js +1 -1
  86. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  87. package/dist/frontend/lowering/lower-island.d.ts +6 -3
  88. package/dist/frontend/lowering/lower-island.js +165 -6
  89. package/dist/frontend/lowering/lower-island.js.map +1 -1
  90. package/dist/frontend/lowering/lower-modules.d.ts +6 -0
  91. package/dist/frontend/lowering/lower-modules.js +184 -38
  92. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  93. package/dist/frontend/lowering/lower-namespaces.js +7 -0
  94. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  95. package/dist/frontend/lowering/lower-server.d.ts +1 -1
  96. package/dist/frontend/lowering/lower-server.js +130 -27
  97. package/dist/frontend/lowering/lower-server.js.map +1 -1
  98. package/dist/frontend/lowering/lower-stmts.js +118 -15
  99. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  100. package/dist/frontend/lowering/lower-stream.d.ts +3 -0
  101. package/dist/frontend/lowering/lower-stream.js +7 -0
  102. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  103. package/dist/frontend/lowering/lowerer.d.ts +86 -9
  104. package/dist/frontend/lowering/lowerer.js +412 -72
  105. package/dist/frontend/lowering/lowerer.js.map +1 -1
  106. package/dist/frontend/lowering/surfaces.d.ts +26 -0
  107. package/dist/frontend/lowering/surfaces.js +140 -77
  108. package/dist/frontend/lowering/surfaces.js.map +1 -1
  109. package/dist/frontend/npm-static-declarations.d.ts +4 -0
  110. package/dist/frontend/npm-static-declarations.js +56 -0
  111. package/dist/frontend/npm-static-declarations.js.map +1 -1
  112. package/dist/frontend/npm-static-declarations.test.js +23 -2
  113. package/dist/frontend/npm-static-declarations.test.js.map +1 -1
  114. package/dist/frontend/npm-static.js +6 -5
  115. package/dist/frontend/npm-static.js.map +1 -1
  116. package/dist/frontend/npm.d.ts +15 -3
  117. package/dist/frontend/npm.js +80 -8
  118. package/dist/frontend/npm.js.map +1 -1
  119. package/dist/frontend/npm.test.js +76 -9
  120. package/dist/frontend/npm.test.js.map +1 -1
  121. package/dist/frontend/program.js +92 -10
  122. package/dist/frontend/program.js.map +1 -1
  123. package/dist/frontend/resolve.d.ts +6 -0
  124. package/dist/frontend/resolve.js +7 -4
  125. package/dist/frontend/resolve.js.map +1 -1
  126. package/dist/frontend/type-mapper.d.ts +5 -0
  127. package/dist/frontend/type-mapper.js +64 -24
  128. package/dist/frontend/type-mapper.js.map +1 -1
  129. package/dist/index.d.ts +5 -0
  130. package/dist/index.js +24 -3
  131. package/dist/index.js.map +1 -1
  132. package/dist/ir/ir.d.ts +93 -47
  133. package/dist/ir/ir.js +63 -4
  134. package/dist/ir/ir.js.map +1 -1
  135. package/dist/ir/ir.test.js +14 -1
  136. package/dist/ir/ir.test.js.map +1 -1
  137. package/dist/ir/serialize.d.ts +1 -1
  138. package/dist/ir/serialize.js +1 -1
  139. package/dist/ir/serialize.js.map +1 -1
  140. package/dist/ir/validate.js +165 -13
  141. package/dist/ir/validate.js.map +1 -1
  142. package/dist/library/int-infer.test.js +4 -4
  143. package/dist/library/int-infer.test.js.map +1 -1
  144. package/dist/library/library-cache.test.js +5 -5
  145. package/dist/library/library-cache.test.js.map +1 -1
  146. package/package.json +17 -17
  147. package/surface-manifest.json +132 -38
package/dist/ir/ir.d.ts CHANGED
@@ -270,21 +270,21 @@ export type IrType = {
270
270
  } | {
271
271
  kind: "cryptoHmac";
272
272
  }
273
- /** Heap, refcounted closure. `rest` marks a VARIADIC JS function (a
274
- * `...args` rest parameter, or a zero-param function body reading
275
- * `arguments` — test/common's mustCall wrapper): the lifted function
276
- * takes one extra trailing `ScrDyn *` param — a dyn ARRAY carrying the
277
- * call's arguments from index params.length on — which the dyn call
278
- * thunk builds per call. `params` stays the DECLARED (non-rest) list
279
- * (fn.length semantics). Rest-marked values are only ever CALLED
280
- * through the dyn boundary (boxed thunks); direct static calls box
281
- * first (lower-calls). */
273
+ /** Heap, refcounted closure. `rest` marks a variadic function value.
274
+ * `restAbi: "typed"` spells one trailing typed array in `params`; static
275
+ * call sites pack their surplus arguments into it before `callValue`.
276
+ * `restAbi: "jsval"` similarly spells one trailing engine array for an
277
+ * island host callback. An absent `restAbi` is the legacy checked-dynamic
278
+ * JS form: `params` stays the declared non-rest list and the lifted
279
+ * function has one hidden trailing ScrDyn array filled by its boxed call
280
+ * thunk. The backends therefore still see one fixed native closure ABI;
281
+ * only the frontend's call completion observes variadic source arity. */
282
282
  | {
283
283
  kind: "func";
284
284
  params: IrType[];
285
285
  ret: IrType;
286
286
  rest?: true;
287
- restAbi?: "jsval";
287
+ restAbi?: "jsval" | "typed";
288
288
  } | {
289
289
  kind: "object";
290
290
  className: string;
@@ -308,6 +308,15 @@ export type IrType = {
308
308
  kind: "classval";
309
309
  className: string;
310
310
  }
311
+ /** An ECMAScript module namespace object for one statically-known module.
312
+ * `moduleId` is a canonical compiled source-file or builtin identity.
313
+ * Runtime representation is an interned immortal string token: identity
314
+ * is pointer identity, while member reads resolve to live module globals
315
+ * or builtin lowering tables rather than snapshotting export values. */
316
+ | {
317
+ kind: "moduleNs";
318
+ moduleId: string;
319
+ }
311
320
  /** Structural record shape (object literal / interface / type alias over
312
321
  * data properties). `shapeId` indexes IrModule.records; the frontend
313
322
  * interns shapes structurally, so equal shapeId ⇔ equal shape and
@@ -417,9 +426,9 @@ declare const HANDLE_KIND_LIST: readonly ["stats", "fileHandle", "spawnRes", "ch
417
426
  export type HandleKind = typeof HANDLE_KIND_LIST[number];
418
427
  export declare const HANDLE_KINDS: IrKindSet<"child" | "childStream" | "childWriter" | "cryptoHash" | "cryptoHmac" | "dgramSocket" | "fileHandle" | "fsWatcher" | "http2Session" | "http2Stream" | "httpClientReq" | "httpReq" | "httpRes" | "netServer" | "netSocket" | "procStream" | "secureCtx" | "spawnRes" | "stats" | "testCtx">;
419
428
  /** The IR kinds represented as pointers in both native backends. */
420
- declare const POINTER_KIND_LIST: readonly ["string", "bigint", "array", "map", "set", "regex", "bytes", "url", "searchParams", "symbol", "stats", "fileHandle", "spawnRes", "child", "netServer", "netSocket", "http2Session", "http2Stream", "dgramSocket", "testCtx", "httpReq", "httpRes", "httpClientReq", "secureCtx", "cryptoHash", "cryptoHmac", "fsWatcher", "childStream", "childWriter", "func", "object", "classval", "record", "union", "dyn", "jsval", "caught", "promise", "generator"];
429
+ declare const POINTER_KIND_LIST: readonly ["string", "bigint", "array", "map", "set", "regex", "bytes", "url", "searchParams", "symbol", "stats", "fileHandle", "spawnRes", "child", "netServer", "netSocket", "http2Session", "http2Stream", "dgramSocket", "testCtx", "httpReq", "httpRes", "httpClientReq", "secureCtx", "cryptoHash", "cryptoHmac", "fsWatcher", "childStream", "childWriter", "func", "object", "classval", "moduleNs", "record", "union", "dyn", "jsval", "caught", "promise", "generator"];
421
430
  export type PointerKind = typeof POINTER_KIND_LIST[number];
422
- export declare const POINTER_KINDS: IrKindSet<"array" | "bigint" | "bytes" | "caught" | "child" | "childStream" | "childWriter" | "classval" | "cryptoHash" | "cryptoHmac" | "dgramSocket" | "dyn" | "fileHandle" | "fsWatcher" | "func" | "generator" | "http2Session" | "http2Stream" | "httpClientReq" | "httpReq" | "httpRes" | "jsval" | "map" | "netServer" | "netSocket" | "object" | "promise" | "record" | "regex" | "searchParams" | "secureCtx" | "set" | "spawnRes" | "stats" | "string" | "symbol" | "testCtx" | "union" | "url">;
431
+ export declare const POINTER_KINDS: IrKindSet<"array" | "bigint" | "bytes" | "caught" | "child" | "childStream" | "childWriter" | "classval" | "cryptoHash" | "cryptoHmac" | "dgramSocket" | "dyn" | "fileHandle" | "fsWatcher" | "func" | "generator" | "http2Session" | "http2Stream" | "httpClientReq" | "httpReq" | "httpRes" | "jsval" | "map" | "moduleNs" | "netServer" | "netSocket" | "object" | "promise" | "record" | "regex" | "searchParams" | "secureCtx" | "set" | "spawnRes" | "stats" | "string" | "symbol" | "testCtx" | "union" | "url">;
423
432
  /** Runtime RC symbol stem for each IR type kind. An empty stem means the
424
433
  * kind is scalar/unit or uses an emitted per-shape helper (object/record).
425
434
  * Keeping this exhaustive makes a new runtime handle kind a compile error
@@ -549,7 +558,7 @@ export declare function typeEquals(a: IrType, b: IrType): boolean;
549
558
  export declare function isRefCounted(t: IrType): boolean;
550
559
  export interface IrModule {
551
560
  /** Bumped on any breaking IR change; serialize.ts refuses mismatches. */
552
- irVersion: 9;
561
+ irVersion: 11;
553
562
  sourceFile: string;
554
563
  functions: IrFunction[];
555
564
  /** Class shapes. Constructors and methods are ordinary module functions
@@ -1783,7 +1792,7 @@ export type IrLibFn =
1783
1792
  * value / string) — both THROW Node's TypeErrors on non-file schemes,
1784
1793
  * encoded slashes, and non-empty hosts. url.pathToFileURL resolves the
1785
1794
  * path (getcwd) and never throws. */
1786
- | "url.new" | "url.protocol" | "url.host" | "url.hostname" | "url.pathname" | "url.href" | "url.fileURLToPathUrl" | "url.fileURLToPathStr" | "url.pathToFileURL"
1795
+ | "url.new" | "url.protocol" | "url.origin" | "url.username" | "url.password" | "url.host" | "url.hostname" | "url.port" | "url.pathname" | "url.href" | "url.fileURLToPathUrl" | "url.fileURLToPathStr" | "url.pathToFileURL"
1787
1796
  /** pathToFileURL under a win32 TARGET: the same scr_url_from_path call
1788
1797
  * (the runtime selects the win32 arm by _WIN32), but a distinct IR name
1789
1798
  * because that arm THROWS for malformed UNC inputs — may-throw seeds on
@@ -1806,7 +1815,7 @@ export type IrLibFn =
1806
1815
  * bools; sp.size/sp.toString are pure reads. sp.keyAt/sp.valAt are
1807
1816
  * the for-of/forEach desugar's index reads (live — the loop re-reads
1808
1817
  * sp.size each pass). */
1809
- | "sp.new" | "sp.parse" | "sp.copy" | "sp.fromPairs" | "sp.with" | "url.searchParams" | "url.search" | "sp.get" | "sp.getAll" | "sp.append" | "sp.set" | "sp.delete" | "sp.deleteValue" | "sp.has" | "sp.hasValue" | "sp.sort" | "sp.size" | "sp.toString" | "sp.keyAt" | "sp.valAt"
1818
+ | "sp.new" | "sp.parse" | "sp.copy" | "sp.fromPairs" | "sp.with" | "url.searchParams" | "url.search" | "url.hash" | "sp.get" | "sp.getAll" | "sp.append" | "sp.set" | "sp.delete" | "sp.deleteValue" | "sp.has" | "sp.hasValue" | "sp.sort" | "sp.size" | "sp.toString" | "sp.keyAt" | "sp.valAt"
1810
1819
  /** node:querystring (scr_qs.c — link-gated by moduleUsesQs; NOT
1811
1820
  * URLSearchParams: the legacy codec's escaping and '+' rules differ).
1812
1821
  * qs.escape is Node's qsEscape, which encodes exactly the component
@@ -1848,10 +1857,10 @@ export type IrLibFn =
1848
1857
  * parse accepts the ECMAScript BigInt string grammar; fromF64 accepts
1849
1858
  * finite integral Numbers. Arithmetic returns fresh immutable values.
1850
1859
  * cmp returns -1/0/1 as f64; toString accepts a numeric radix. */
1851
- | "bigint.parse" | "bigint.fromF64" | "bigint.neg" | "bigint.not" | "bigint.add" | "bigint.sub" | "bigint.mul" | "bigint.div" | "bigint.mod" | "bigint.pow" | "bigint.and" | "bigint.or" | "bigint.xor" | "bigint.shl" | "bigint.shr" | "bigint.eq" | "bigint.cmp" | "bigint.cmpNumber" | "bigint.truthy" | "bigint.toString" | "bigint.inspect" | "bigint.toF64" | "bigint.asUintN" | "bigint.asIntN" | "bigint.bufferRead" | "bigint.bufferWrite" | "bigint.dataViewGet" | "bigint.dataViewSet"
1860
+ | "bigint.parse" | "bigint.fromF64" | "bigint.neg" | "bigint.not" | "bigint.add" | "bigint.sub" | "bigint.mul" | "bigint.div" | "bigint.mod" | "bigint.pow" | "bigint.and" | "bigint.or" | "bigint.xor" | "bigint.shl" | "bigint.shr" | "bigint.eq" | "bigint.eqString" | "bigint.cmp" | "bigint.cmpNumber" | "bigint.truthy" | "bigint.toString" | "bigint.inspect" | "bigint.toF64" | "bigint.asUintN" | "bigint.asIntN" | "bigint.bufferRead" | "bigint.bufferWrite" | "bigint.dataViewGet" | "bigint.dataViewSet"
1852
1861
  /** fs.statSync → a Stats value (may throw, like the other sync fs
1853
1862
  * calls); the stats.* getters are pure reads on it. */
1854
- | "fs.statSync" | "stats.isFile" | "stats.isDirectory" | "stats.size"
1863
+ | "fs.statSync" | "stats.isFile" | "stats.isDirectory" | "stats.size" | "stats.dev" | "stats.ino"
1855
1864
  /** child_process.spawnSync (scr_child.c): posix_spawn + waitpid + piped
1856
1865
  * utf8 capture — cmd borrowed, args one borrowed string[] (the frontend
1857
1866
  * completes an omitted list to an empty literal), result an owned (+1)
@@ -1879,7 +1888,9 @@ export type IrLibFn =
1879
1888
  * cmd/args borrowed; result an owned (+1) child handle. The loop will
1880
1889
  * not exhaust while any spawned child is unreaped — Node's keep-alive.
1881
1890
  *
1882
- * child.onExit / child.onError — `child.on("exit"|"error", cb)`: the
1891
+ * child.onExit / child.onClose / child.onError — terminal listener
1892
+ * registration through child.on/once. Close uses the exit adapter shape
1893
+ * but fires only after every piped stdio handle reaches EOF. The
1883
1894
  * receiver is borrowed, the CALLBACK MOVES into the child's listener
1884
1895
  * registry (released after the terminal event fires, or at reap for
1885
1896
  * the event that never fires). Both are void (chaining is fenced).
@@ -1891,7 +1902,16 @@ export type IrLibFn =
1891
1902
  * shape — scr_error_new needs no program types). "exit" fires once
1892
1903
  * with the code (f64 arm) or null (signal death); "error" fires only
1893
1904
  * for spawn failure, exactly Node's split. */
1894
- | "cp.spawn" | "child.onExit" | "child.onError"
1905
+ | "cp.spawn"
1906
+ /** Static-native fork startup and IPC. process.forkTarget initializes a
1907
+ * re-executed child's inherited channel and returns its embedded target id
1908
+ * (-1 in the parent). The remaining entries mirror Node's JSON channel. */
1909
+ | "process.forkTarget" | "cp.fork" | "child.connected" | "child.send" | "child.sendCb" | "child.disconnect" | "child.onMessage" | "child.onDisconnect" | "process.connected" | "process.send" | "process.sendCb" | "process.disconnect" | "process.onMessage" | "process.onDisconnect"
1910
+ /** child_process.execFile's callback slice: starts an all-piped child,
1911
+ * captures stdout/stderr, and moves the error-first callback into the
1912
+ * child registry. The callback shape is program-dependent and checked
1913
+ * by the validator/backends. */
1914
+ | "cp.execFile" | "child.onExit" | "child.onClose" | "child.onError"
1895
1915
  /** The ChildProcess lifecycle members (scr_child.c), Node's shapes
1896
1916
  * exactly (SEMANTICS.md has the pinned matrix). child.pid is the
1897
1917
  * checker's `number | undefined` (undefined = spawn failure) and
@@ -1914,12 +1934,14 @@ export type IrLibFn =
1914
1934
  * arm). stream.onData/onEnd register 'data'/'end' listeners (receiver
1915
1935
  * borrowed, CALLBACK MOVES, trailing once-flag, void — chaining
1916
1936
  * fenced): 'data' fires one Buffer chunk per read (zero-param and
1917
- * Buffer-param adapters are runtime-provided; a union-param listener —
1937
+ * Buffer/string adapters are runtime-provided; setEncoding threads
1938
+ * split multibyte sequences through the shared StringDecoder core. A
1939
+ * union-param listener —
1918
1940
  * ngrok's `Buffer | string` — gets a compiler-emitted adapter wrapping
1919
1941
  * the chunk at its Buffer arm), 'end' fires once at EOF, always BEFORE
1920
1942
  * the child's 'exit' (the pinned ordering). A flowing stream keeps the
1921
1943
  * loop alive: usesTimers. */
1922
- | "child.stdout" | "child.stderr" | "stream.onData" | "stream.onEnd"
1944
+ | "child.stdout" | "child.stderr" | "stream.onData" | "stream.onDataStr" | "stream.onEnd" | "stream.childSetEncoding"
1923
1945
  /** The piped-input writer (stdio mode 3 on fd 0). child.stdin answers
1924
1946
  * `Writable | null`; writes copy borrowed data into the nonblocking
1925
1947
  * queue, end/destroy settle it, writable is a pure state read, and
@@ -2071,11 +2093,9 @@ export type IrLibFn =
2071
2093
  * for end-before-head, chunked after an explicit writeHead/write). */
2072
2094
  | "http.createServer"
2073
2095
  /** http.createServer() / http.Server() with no handler — the
2074
- * on("request") route; createServerOpts is the (options[, listener])
2075
- * overload's twin carrying the two lowered parser flags
2076
- * (requireHostHeader: false is already this parser's behavior;
2077
- * joinDuplicateHeaders joins repeated request-header reads ", "). */
2078
- | "http.createServerEmpty" | "http.serverJoinDupHeaders"
2096
+ * on("request") route; option helpers set parser behavior on a fresh
2097
+ * server before the constructor/factory result is returned. */
2098
+ | "http.createServerEmpty" | "http.serverJoinDupHeaders" | "http.serverAllowMissingHostHeader"
2079
2099
  /** The five writable numeric http.Server timeout fields use one
2080
2100
  * selector ABI: 0 timeout, 1 keepAliveTimeout, 2 headersTimeout,
2081
2101
  * 3 requestTimeout, 4 keepAliveTimeoutBuffer. These calls store/read
@@ -2092,9 +2112,9 @@ export type IrLibFn =
2092
2112
  * the callback fires deferred, Node's 'finish' emit). writeHead's
2093
2113
  * statusMessage forms compose in interned helpers: resStatusMsgSet
2094
2114
  * then the ordinary writeHead entry. */
2095
- | "http.resStatusGet" | "http.resStatusSet" | "http.resStatusMsgGet" | "http.resStatusMsgSet" | "http.resGetHeader" | "http.resHasHeader" | "http.resRemoveHeader" | "http.resOnFinish" | "http.reqUrl" | "http.reqMethod" | "http.reqHeader" | "http.reqOnData" | "http.reqOnEnd" | "http.resSetHeader" | "http.resWriteHead" | "http.resWriteHeadN" | "http.resWrite" | "http.resWriteBytes" | "http.resEnd" | "http.resEndStr" | "http.resEndBytes"
2115
+ | "http.resStatusGet" | "http.resStatusSet" | "http.resStatusMsgGet" | "http.resStatusMsgSet" | "http.resGetHeader" | "http.resHasHeader" | "http.resRemoveHeader" | "http.resOnFinish" | "http.reqUrl" | "http.reqMethod" | "http.reqHeader" | "http.reqTrailer" | "http.reqHeaderValues" | "http.reqTrailerValues" | "http.reqOnData" | "http.reqOnEnd" | "http.resSetHeader" | "http.resWriteHead" | "http.resWriteHeadN" | "http.resWrite" | "http.resWriteBytes" | "http.resEnd" | "http.resEndStr" | "http.resEndBytes"
2096
2116
  /** The checked-dynamic chunk twins (the net.sockWriteDyn story). */
2097
- | "http.resWriteDyn" | "http.resEndDyn" | "http.resHeadersSent"
2117
+ | "http.resWriteDyn" | "http.resEndDyn" | "http.resHeadersSent" | "http.resFlushHeaders" | "http.resAddTrailers" | "http.resCork" | "http.resUncork" | "http.resWritableCorked"
2098
2118
  /** The server-surface member follow-ups: reqStatusCode answers the
2099
2119
  * interned `number | undefined` union (negative = the undefined arm —
2100
2120
  * a SERVER request, where Node's statusCode is undefined; every client
@@ -2117,11 +2137,11 @@ export type IrLibFn =
2117
2137
  * line carried none), the undefined arm on server requests (the
2118
2138
  * statusCode split). sockDestroyed is socket.destroyed — true once the
2119
2139
  * fd is gone (destroy() or full close). */
2120
- | "http.reqRawHeaders" | "http.reqStatusMessage"
2140
+ | "http.reqRawHeaders" | "http.reqRawTrailers" | "http.reqStatusMessage"
2121
2141
  /** The `{ ...req.headers }` snapshot feed: [lowercased name, value,
2122
2142
  * ...] pairs in arrival order — the interned %headers.snapshot helper
2123
2143
  * builds the record over it, exactly the process.envPairs pattern. */
2124
- | "http.reqHeaderPairs" | "net.sockDestroyed"
2144
+ | "http.reqHeaderPairs" | "http.reqTrailerPairs" | "net.sockDestroyed"
2125
2145
  /** socket.writable — the write half is open: no end() yet, no FIN sent,
2126
2146
  * fd alive (connecting sockets answer true; writes queue). Node's
2127
2147
  * stream flag. Borrows; never throws. */
@@ -2356,7 +2376,7 @@ export type IrLibFn =
2356
2376
  * idiom reads it through a cast). */
2357
2377
  | "net.sockEncrypted" | "http.clientWrite" | "http.clientWriteBytes" | "http.clientEnd" | "http.clientEndStr" | "http.clientEndBytes"
2358
2378
  /** The checked-dynamic chunk twins (the net.sockWriteDyn story). */
2359
- | "http.clientWriteDyn" | "http.clientEndDyn"
2379
+ | "http.clientWriteDyn" | "http.clientEndDyn" | "http.clientFlushHeaders" | "http.clientAddTrailers" | "http.clientCork" | "http.clientUncork" | "http.clientWritableCorked"
2360
2380
  /** request/get with a URL-STRING first argument: the runtime parses it
2361
2381
  * (WHATWG) and dials — throws catchably on an unparsable input or a
2362
2382
  * non-http scheme. */
@@ -2452,11 +2472,15 @@ export type IrLibFn =
2452
2472
  * pair THROWS catchably on failure exactly like the utf8 forms. */
2453
2473
  | "fs.readFileSyncBytes" | "fs.writeFileSyncBytes" | "fsp.readFileBytes"
2454
2474
  /** node:zlib (scr_zlib.c — native-toolchain.ts compiles/links it ONLY when these
2455
- * appear on the IR, the regex/libcurl gating precedent): deflateSync/
2456
- * inflateSync over u8 bytes with Node's default options. deflate never
2457
- * throws (OOM aborts); inflate of corrupt input THROWS Node's error
2458
- * catchably. */
2459
- | "zlib.deflateSync" | "zlib.inflateSync"
2475
+ * appear on the IR, the regex/libcurl gating precedent): one-shot zlib,
2476
+ * raw-DEFLATE, gzip, and auto-detect codecs over u8 bytes with Node's
2477
+ * default options. Compression never throws (OOM aborts); decompression
2478
+ * of corrupt input THROWS Node's error catchably. */
2479
+ | "zlib.deflateSync" | "zlib.inflateSync" | "zlib.deflateRawSync" | "zlib.inflateRawSync" | "zlib.gzipSync" | "zlib.gunzipSync" | "zlib.unzipSync"
2480
+ /** The default-options callback twins run on the executable's shared
2481
+ * native work pool and deliver (Error | null, Buffer) on a later loop
2482
+ * turn. crc32 validates its optional uint32 seed synchronously. */
2483
+ | "zlib.deflateCb" | "zlib.inflateCb" | "zlib.deflateRawCb" | "zlib.inflateRawCb" | "zlib.gzipCb" | "zlib.gunzipCb" | "zlib.unzipCb" | "zlib.crc32"
2460
2484
  /** The Buffer overloads of the raw stream writes — same promptly
2461
2485
  * submitted streams as process.stdoutWrite/stderrWrite, constantly true.
2462
2486
  * The encoding arg is evaluated but ignored for bytes, like Node. The Cb
@@ -2469,7 +2493,12 @@ export type IrLibFn =
2469
2493
  * literal { recursive?, mode? } options (the mkdirSync matrix behind
2470
2494
  * settled promises), unlink, chmod. Failures REJECT (catchable at the
2471
2495
  * await), like the rest of the fsp family. */
2472
- | "fsp.mkdirMode" | "fsp.mkdirRecursive" | "fsp.mkdirRecursiveMode" | "fsp.unlink" | "fsp.chmod" | "fsp.rename" | "fsp.readdir" | "fsp.rm" | "fsp.stat"
2496
+ | "fsp.mkdirMode" | "fsp.mkdirRecursive" | "fsp.mkdirRecursiveMode" | "fsp.unlink" | "fsp.chmod" | "fsp.rename" | "fsp.readdir"
2497
+ /** `fs.promises.readdir(path, { withFileTypes: true })` — the settled-
2498
+ * promise twin of fs.readdirTypesSync. The backends assemble the same
2499
+ * call-site-shaped Dirent rows, then move the array into a promise;
2500
+ * scandir failure becomes its rejection. */
2501
+ | "fsp.readdirTypes" | "fsp.rm" | "fsp.stat" | "fsp.realpath" | "fsp.lstat"
2473
2502
  /** fs/promises.open and the statically represented FileHandle surface.
2474
2503
  * Every operation returns an already-settled promise; syscall failures
2475
2504
  * become rejections rather than escaping synchronously. read/write
@@ -2490,7 +2519,11 @@ export type IrLibFn =
2490
2519
  * (the frontend's interned %env.snapshot helper keyed-writes the pairs
2491
2520
  * into a fresh `{ [k: string]: string | undefined }` record). Fresh +1
2492
2521
  * array; never throws. */
2493
- | "process.envPairs" | "process.exit" | "process.cwd"
2522
+ | "process.envPairs" | "process.exit"
2523
+ /** Numeric process.exitCode write (integer validation, implicit exit status). */
2524
+ | "process.setExitCode"
2525
+ /** The code for process.exit() with no argument, or zero when unset. */
2526
+ | "process.currentExitCode" | "process.cwd"
2494
2527
  /** getpid(2) / getuid(2): zero args → f64. POSIX-only target, so both
2495
2528
  * always answer (the checker's `getuid?` optionality covers Windows —
2496
2529
  * `process.getuid?.()` lowers as the plain call). Never throw. */
@@ -2694,6 +2727,11 @@ export type IrLibFn =
2694
2727
  * render "null"/"undefined") — the WHATWG USVString conversions
2695
2728
  * (URLSearchParams names/values). Borrowed dyn; +1 string. May-throw. */
2696
2729
  | "dyn.toStringCoerce"
2730
+ /** JS ToNumber over a dyn value WITH the object protocol (number-hint
2731
+ * valueOf/toString ordering; user throws propagate). Borrowed dyn;
2732
+ * f64 result, or a throw. Used by statically lowered numeric coercions
2733
+ * whose checker type remained any. */
2734
+ | "dyn.toNumberCoerce"
2697
2735
  /** A read of a `declare`d const NOTHING defines (the bundler-define
2698
2736
  * pattern — __VERSION__): always throws the catchable ReferenceError
2699
2737
  * Node raises at the access ("<name> is not defined"). args[0] is the
@@ -2820,7 +2858,7 @@ export type IrLibFn =
2820
2858
  * the had-listeners bool. emitter.emitError: emit('error', err) —
2821
2859
  * throws err when unhandled. count/countFn/names/listeners/getMax/
2822
2860
  * setMax/setDefaultMax/getDefaultMax are the introspection surface. */
2823
- | "emitter.new" | "emitter.ctor" | "emitter.on" | "emitter.off" | "emitter.checkListener" | "emitter.onDyn" | "emitter.offDyn" | "emitter.removeAll" | "emitter.emit" | "emitter.emitError" | "emitter.count" | "emitter.countFn" | "emitter.names" | "emitter.listeners" | "emitter.setMax" | "emitter.getMax"
2861
+ | "emitter.new" | "emitter.ctor" | "emitter.on" | "emitter.off" | "emitter.checkListener" | "emitter.onDyn" | "emitter.onFlex" | "emitter.offDyn" | "emitter.removeAll" | "emitter.emit" | "emitter.emitFlex" | "emitter.emitError" | "emitter.count" | "emitter.countFn" | "emitter.names" | "emitter.listeners" | "emitter.setMax" | "emitter.getMax"
2824
2862
  /** Stream-'data' registration twins of emitter.on/onDyn (same args):
2825
2863
  * chosen at registration sites whose receiver is stream-rooted, so the
2826
2864
  * backend emits DATA thunks — the runtime's 'data' emission carries
@@ -2980,7 +3018,7 @@ export type IrLibFn =
2980
3018
  * the value's inspection) — the frontend routes null/undefined to a
2981
3019
  * no-op and everything else here (Node throws for falsy values too).
2982
3020
  * All arguments are borrowed. */
2983
- | "assert.ok" | "assert.eqF64" | "assert.eqBigInt" | "assert.eqStr" | "assert.eqBool" | "assert.eqSym" | "assert.eqDyn" | "assert.deepResult" | "assert.sameValue" | "assert.deqEnter" | "assert.deqLeave" | "assert.match" | "assert.throwsNone" | "assert.throwsMismatch" | "assert.throwsRegex" | "assert.shapeBegin" | "assert.shapeStr" | "assert.shapeRe" | "assert.shapeEnd" | "assert.regexErrTest" | "assert.unwantedRejection"
3021
+ | "assert.ok" | "assert.eqF64" | "assert.eqBigInt" | "assert.eqStr" | "assert.eqBool" | "assert.eqSym" | "assert.eqDyn" | "assert.looseResult" | "assert.deepResult" | "assert.sameValue" | "assert.deqEnter" | "assert.deqLeave" | "assert.match" | "assert.throwsNone" | "assert.throwsMismatch" | "assert.throwsRegex" | "assert.shapeBegin" | "assert.shapeStr" | "assert.shapeRe" | "assert.shapeEnd" | "assert.regexErrTest" | "assert.unwantedRejection"
2984
3022
  /** Node's expectsError over an error-INSTANCE expected (assert.throws/
2985
3023
  * rejects second argument): walk the expected dyn error's keys (name,
2986
3024
  * message, code — the %error marker skipped) and deep-compare each
@@ -3134,7 +3172,9 @@ export type IrLibFn =
3134
3172
  * ToInteger truncation of fractional ms) and THROWS Node's "Invalid
3135
3173
  * time value" RangeError on NaN / out-of-range input (may-throw seed).
3136
3174
  * Results: f64 / owned (+1) string. */
3137
- | "date.now" | "date.newNow" | "date.newMs" | "date.newString" | "date.getTime" | "date.valueOf" | "date.toISOString" | "date.toISOStringValue" | "date.getFullYear" | "date.getUTCFullYear" | "date.getMonth" | "date.getUTCMonth" | "date.getDate" | "date.getUTCDate" | "date.getDay" | "date.getUTCDay" | "date.getHours" | "date.getUTCHours" | "date.getMinutes" | "date.getUTCMinutes" | "date.getSeconds" | "date.getUTCSeconds" | "date.getMilliseconds" | "date.getUTCMilliseconds" | "date.getTimezoneOffset"
3175
+ | "date.now" | "date.newNow" | "date.newMs" | "date.newString"
3176
+ /** Date.parse(dateString), with its own reach witness for exact fences. */
3177
+ | "date.parse" | "date.getTime" | "date.valueOf" | "date.toISOString" | "date.toISOStringValue" | "date.getFullYear" | "date.getUTCFullYear" | "date.getMonth" | "date.getUTCMonth" | "date.getDate" | "date.getUTCDate" | "date.getDay" | "date.getUTCDay" | "date.getHours" | "date.getUTCHours" | "date.getMinutes" | "date.getUTCMinutes" | "date.getSeconds" | "date.getUTCSeconds" | "date.getMilliseconds" | "date.getUTCMilliseconds" | "date.getTimezoneOffset"
3138
3178
  /** The composed `new Date(dateString).getTime()` read: one borrowed
3139
3179
  * string, f64 milliseconds since epoch. The parsed grammar is BOUNDED
3140
3180
  * (documented divergence — V8's parser accepts far more): the ASN.1
@@ -3235,7 +3275,7 @@ export type IrLibFn =
3235
3275
  * uv_fs_copyfile behavior); its errors carry BOTH paths — Node's
3236
3276
  * "copyfile 'src' -> 'dest'". lstatSync is statSync without following
3237
3277
  * a trailing symlink (Node reports lstat); stats.isSymbolicLink /
3238
- * stats.blocks / nlink / atimeMs / mtimeMs are pure reads on the widened
3278
+ * stats.dev / ino / blocks / nlink / atimeMs / mtimeMs / ctimeMs are pure reads on the widened
3239
3279
  * snapshot (blocks is allocated 512-byte units; the times are milliseconds
3240
3280
  * with their sub-second fractions, Node's arithmetic).
3241
3281
  * writeFileModeSync is writeFileSync(path, data, { mode }): the mode
@@ -3248,7 +3288,7 @@ export type IrLibFn =
3248
3288
  /** renameSync is the direct two-path syscall wrapper. renameCb defers
3249
3289
  * the operation to the loop and fires a program-shaped Error | null
3250
3290
  * callback through a backend-emitted adapter. */
3251
- | "fs.renameSync" | "fs.renameCb" | "fs.lstatSync"
3291
+ | "fs.renameSync" | "fs.renameCb" | "fs.lstatSync" | "fs.fstatSync" | "fs.fchmodSync" | "fs.fsyncSync" | "fs.linkSync"
3252
3292
  /** fs.openSync(path, flags) → the raw fd as f64; fs.readSync/fs.writeSync
3253
3293
  * over Buffer windows perform sequential I/O when position is -1 and
3254
3294
  * offset-preserving positioned I/O otherwise; fs.writeStrSync is the
@@ -3259,7 +3299,7 @@ export type IrLibFn =
3259
3299
  * Node's ERR_INVALID_ARG_VALUE TypeError text). All throw Node-shaped
3260
3300
  * fs errors (openSync ENOENT/EACCES..., readSync EBADF/range errors,
3261
3301
  * closeSync EBADF). */
3262
- | "fs.openSync" | "fs.readSync" | "fs.writeSync" | "fs.writeStrSync" | "fs.closeSync"
3302
+ | "fs.openSync" | "fs.openNumericSync" | "fs.readSync" | "fs.writeSync" | "fs.writeStrSync" | "fs.closeSync"
3263
3303
  /** fs.watch(path, listener?) → an FSWatcher handle (scr_watch.c —
3264
3304
  * linked, and scr_watch_install() emitted, only when these appear on
3265
3305
  * the IR; moduleUsesFsWatch is the switch). The path opens NOW —
@@ -3282,7 +3322,7 @@ export type IrLibFn =
3282
3322
  * ASN1_TIME_print shape ("Jul 1 00:00:00 2026 GMT" — %2d space-padded
3283
3323
  * day). Same input contract and PEM error as the fingerprint pair
3284
3324
  * (may-throw). */
3285
- | "crypto.x509ValidFrom" | "crypto.x509ValidFromStr" | "crypto.x509ValidTo" | "crypto.x509ValidToStr" | "stats.isSymbolicLink" | "stats.blocks" | "stats.nlink" | "stats.atimeMs" | "stats.mtimeMs" | "fs.writeFileModeSync" | "fs.mkdirModeSync" | "fs.mkdirRecursiveModeSync"
3325
+ | "crypto.x509ValidFrom" | "crypto.x509ValidFromStr" | "crypto.x509ValidTo" | "crypto.x509ValidToStr" | "stats.isSymbolicLink" | "stats.blocks" | "stats.nlink" | "stats.atimeMs" | "stats.mtimeMs" | "stats.ctimeMs" | "fs.writeFileModeSync" | "fs.mkdirModeSync" | "fs.mkdirRecursiveModeSync"
3286
3326
  /** spawnSync with options (scr_child.c): the cp.spawnSync core plus the
3287
3327
  * option slice portless-class CLIs pass — timeout (killSignal fires at
3288
3328
  * the deadline and the result carries error: ETIMEDOUT + the signal,
@@ -3348,6 +3388,13 @@ export type IrExpr =
3348
3388
  value: string;
3349
3389
  type: IrType;
3350
3390
  loc: SrcLoc;
3391
+ }
3392
+ /** The singleton namespace token for one compiled or builtin module. */
3393
+ | {
3394
+ kind: "moduleNsRef";
3395
+ moduleId: string;
3396
+ type: IrType;
3397
+ loc: SrcLoc;
3351
3398
  } | {
3352
3399
  kind: "boolLit";
3353
3400
  value: boolean;
@@ -5258,8 +5305,7 @@ export declare function moduleLibNondeterministicSurface(mod: IrModule): string
5258
5305
  /** The may-throw seed: libCall members that can raise. Every fs.* member
5259
5306
  * EXCEPT existsSync (which, like Node's, swallows errors and returns false)
5260
5307
  * throws a catchable error on failure; json.parse throws a catchable
5261
- * SyntaxError-shaped string on malformed input; process.* members never
5262
- * throw. Backends' may-throw analyses must treat a function containing one
5308
+ * SyntaxError-shaped string on malformed input. Backends' may-throw analyses must treat a function containing one
5263
5309
  * of these as throwing, exactly like a `throw` statement (and must ALSO
5264
5310
  * seed on `dynCheck` and `awaitExpr` nodes, which throw on validation
5265
5311
  * failure / promise rejection). */
package/dist/ir/ir.js CHANGED
@@ -46,6 +46,7 @@ const POINTER_KIND_LIST = [
46
46
  "func",
47
47
  "object",
48
48
  "classval",
49
+ "moduleNs",
49
50
  "record",
50
51
  "union",
51
52
  "dyn",
@@ -96,6 +97,7 @@ export const RUNTIME_RC_STEMS = {
96
97
  func: "scr_closure",
97
98
  object: "",
98
99
  classval: "scr_classobj",
100
+ moduleNs: "scr_str",
99
101
  record: "",
100
102
  union: "scr_union",
101
103
  dyn: "scr_dyn",
@@ -137,6 +139,8 @@ export const REF_TRUTHY_KINDS = new Set([
137
139
  "generator",
138
140
  // A class object is a JS object (constructors are functions): always truthy.
139
141
  "classval",
142
+ // A module namespace object is always truthy.
143
+ "moduleNs",
140
144
  ]);
141
145
  export const F64 = { kind: "f64" };
142
146
  export const BIGINT_T = { kind: "bigint" };
@@ -205,6 +209,7 @@ export function isSupportedArrayElem(t) {
205
209
  case "netServer":
206
210
  case "symbol":
207
211
  case "classval":
212
+ case "moduleNs":
208
213
  return true;
209
214
  default:
210
215
  return false;
@@ -369,11 +374,13 @@ export function typeKey(t) {
369
374
  case "set":
370
375
  return `set<${typeKey(t.elem)}>`;
371
376
  case "func":
372
- return `func(${[...t.params.map(typeKey), ...(t.rest ? [t.restAbi === "jsval" ? "...jsval[]" : "...dyn[]"] : [])].join(",")})=>${typeKey(t.ret)}`;
377
+ return `func(${[...t.params.map(typeKey), ...(t.rest ? [t.restAbi === "jsval" ? "...jsval[]" : t.restAbi === "typed" ? "...typed[]" : "...dyn[]"] : [])].join(",")})=>${typeKey(t.ret)}`;
373
378
  case "object":
374
379
  return `object:${t.className}`;
375
380
  case "classval":
376
381
  return `classval:${t.className}`;
382
+ case "moduleNs":
383
+ return `moduleNs:${t.moduleId}`;
377
384
  case "record":
378
385
  return `record:${t.shapeId}`;
379
386
  case "union":
@@ -403,6 +410,7 @@ export function typeEquals(a, b) {
403
410
  return (b.kind === "func" &&
404
411
  a.params.length === b.params.length &&
405
412
  (a.rest === true) === (b.rest === true) &&
413
+ a.restAbi === b.restAbi &&
406
414
  a.params.every((p, i) => typeEquals(p, b.params[i])) &&
407
415
  typeEquals(a.ret, b.ret));
408
416
  }
@@ -410,6 +418,8 @@ export function typeEquals(a, b) {
410
418
  return b.kind === "object" && a.className === b.className;
411
419
  if (a.kind === "classval")
412
420
  return b.kind === "classval" && a.className === b.className;
421
+ if (a.kind === "moduleNs")
422
+ return b.kind === "moduleNs" && a.moduleId === b.moduleId;
413
423
  // The frontend deduplicates shapes structurally (one shapeId per canonical
414
424
  // field list), so id equality IS structural equality.
415
425
  if (a.kind === "record")
@@ -771,6 +781,7 @@ function isJsonSafeAt(t, getRecord, getUnion, stringify, undefinedAllowed, visit
771
781
  case "caught":
772
782
  case "promise":
773
783
  case "generator":
784
+ case "moduleNs":
774
785
  case "void":
775
786
  return false;
776
787
  // Record fields drop undefined. Stringification also represents it in
@@ -1081,6 +1092,10 @@ export function canDynCheckTo(t, getRecord, getUnion) {
1081
1092
  * back). */
1082
1093
  export function canBoxFuncIntoDyn(t, getRecord, getUnion) {
1083
1094
  return (t.kind === "func" &&
1095
+ // Only the legacy hidden-dyn rest ABI has a checked-dynamic call thunk.
1096
+ // Typed rest stays static (its trailing array is compiler-packed), and
1097
+ // island rest has its separate engine host-callback adapter.
1098
+ (t.rest !== true || t.restAbi === undefined) &&
1084
1099
  // A jsval (island) param converts through scr_jsval_from_dyn in the
1085
1100
  // thunk (wrapped cells unwrap by reference, dyn data deep-copies) —
1086
1101
  // the checker-'any' callback params of the routed-dispatch lane
@@ -1646,7 +1661,10 @@ export function moduleUsesChildProcess(mod) {
1646
1661
  const node = v;
1647
1662
  if (node.kind === "libCall" &&
1648
1663
  typeof node.fn === "string" &&
1649
- (node.fn.startsWith("cp.") || node.fn.startsWith("child.") || node.fn.startsWith("writer.") || node.fn.startsWith("spawnRes."))) {
1664
+ (node.fn.startsWith("cp.") || node.fn.startsWith("child.") || node.fn.startsWith("writer.") || node.fn.startsWith("spawnRes.") ||
1665
+ node.fn === "process.forkTarget" || node.fn === "process.connected" || node.fn === "process.send" ||
1666
+ node.fn === "process.sendCb" || node.fn === "process.disconnect" || node.fn === "process.onMessage" ||
1667
+ node.fn === "process.onDisconnect")) {
1650
1668
  found = true;
1651
1669
  return;
1652
1670
  }
@@ -2097,6 +2115,13 @@ const LIB_MODE_REFUSED_PREFIXES = [
2097
2115
  // exclude — refuse the surface like the rest of the event-loop family.
2098
2116
  ["fs.existsChk", "the async fs callback surface (fs.exists)"],
2099
2117
  ["fs.renameCb", "the async fs callback surface (fs.rename)"],
2118
+ ["zlib.deflateCb", "the async node:zlib callback surface"],
2119
+ ["zlib.inflateCb", "the async node:zlib callback surface"],
2120
+ ["zlib.deflateRawCb", "the async node:zlib callback surface"],
2121
+ ["zlib.inflateRawCb", "the async node:zlib callback surface"],
2122
+ ["zlib.gzipCb", "the async node:zlib callback surface"],
2123
+ ["zlib.gunzipCb", "the async node:zlib callback surface"],
2124
+ ["zlib.unzipCb", "the async node:zlib callback surface"],
2100
2125
  ["process.stdoutWriteBytesCb", "process.stdout.write completion callbacks"],
2101
2126
  ["process.stderrWriteBytesCb", "process.stderr.write completion callbacks"],
2102
2127
  ["timers.", "the timers surface (setTimeout family)"],
@@ -2280,6 +2305,7 @@ export const LIB_NONDETERMINISTIC_PREFIXES = [
2280
2305
  ["process.kill", "process authority (kill)"],
2281
2306
  ["process.umask", "process authority (umask)"],
2282
2307
  ["process.exit", "process authority (exit)"],
2308
+ ["process.setExitCode", "process authority (exit status)"],
2283
2309
  ["fs.", "the filesystem"],
2284
2310
  ["os.", "machine/OS identity"],
2285
2311
  // The CA-store surface reads the host's certificate bundle (and the
@@ -2317,8 +2343,7 @@ export function moduleLibNondeterministicSurface(mod) {
2317
2343
  /** The may-throw seed: libCall members that can raise. Every fs.* member
2318
2344
  * EXCEPT existsSync (which, like Node's, swallows errors and returns false)
2319
2345
  * throws a catchable error on failure; json.parse throws a catchable
2320
- * SyntaxError-shaped string on malformed input; process.* members never
2321
- * throw. Backends' may-throw analyses must treat a function containing one
2346
+ * SyntaxError-shaped string on malformed input. Backends' may-throw analyses must treat a function containing one
2322
2347
  * of these as throwing, exactly like a `throw` statement (and must ALSO
2323
2348
  * seed on `dynCheck` and `awaitExpr` nodes, which throw on validation
2324
2349
  * failure / promise rejection). */
@@ -2397,11 +2422,13 @@ export const MAY_THROW_LIB_FNS = new Set([
2397
2422
  // any of them can throw. emitError additionally THROWS its payload when
2398
2423
  // 'error' has no listener, Node's unhandled-'error' contract.
2399
2424
  "emitter.emit",
2425
+ "emitter.emitFlex",
2400
2426
  "emitter.emitError",
2401
2427
  "emitter.on",
2402
2428
  "emitter.off",
2403
2429
  "emitter.checkListener",
2404
2430
  "emitter.onDyn",
2431
+ "emitter.onFlex",
2405
2432
  "emitter.offDyn",
2406
2433
  "emitter.onData",
2407
2434
  "emitter.onDataDyn",
@@ -2414,8 +2441,27 @@ export const MAY_THROW_LIB_FNS = new Set([
2414
2441
  "net.sockEndDyn",
2415
2442
  "http.resWriteDyn",
2416
2443
  "http.resEndDyn",
2444
+ "http.resAddTrailers",
2445
+ "http.resFlushHeaders",
2446
+ "http.resUncork",
2447
+ "http.resWriteHead",
2448
+ "http.resWriteHeadN",
2449
+ "http.resWriteHeadPairs",
2450
+ "http.resWrite",
2451
+ "http.resWriteBytes",
2452
+ "http.resEnd",
2453
+ "http.resEndStr",
2454
+ "http.resEndBytes",
2417
2455
  "http.clientWriteDyn",
2418
2456
  "http.clientEndDyn",
2457
+ "http.clientAddTrailers",
2458
+ "http.clientFlushHeaders",
2459
+ "http.clientUncork",
2460
+ "http.clientWrite",
2461
+ "http.clientWriteBytes",
2462
+ "http.clientEnd",
2463
+ "http.clientEndStr",
2464
+ "http.clientEndBytes",
2419
2465
  // The URL-string client form throws catchably on an unparsable input
2420
2466
  // ("Invalid URL") or a non-http scheme (ERR_INVALID_PROTOCOL).
2421
2467
  "http.requestUrl",
@@ -2495,6 +2541,7 @@ export const MAY_THROW_LIB_FNS = new Set([
2495
2541
  "http.requestConnCb",
2496
2542
  "process.kill",
2497
2543
  "process.killNum",
2544
+ "process.setExitCode",
2498
2545
  // cpuUsage(prev)'s field validation: negative/non-finite prev fields
2499
2546
  // throw Node's ERR_INVALID_ARG_VALUE RangeError, catchably.
2500
2547
  "process.cpuPrevValidate",
@@ -2511,6 +2558,8 @@ export const MAY_THROW_LIB_FNS = new Set([
2511
2558
  "error.nodeThrow",
2512
2559
  // USVString coercion runs user toString/valueOf — throws propagate.
2513
2560
  "dyn.toStringCoerce",
2561
+ // Numeric coercion runs user valueOf/toString — throws propagate.
2562
+ "dyn.toNumberCoerce",
2514
2563
  "child.kill",
2515
2564
  // The caller's lookup runs synchronously inside the connect call — a
2516
2565
  // throw there propagates like Node's.
@@ -2662,6 +2711,10 @@ export const MAY_THROW_LIB_FNS = new Set([
2662
2711
  "fs.readFileSyncBytes",
2663
2712
  "fs.writeFileSyncBytes",
2664
2713
  "zlib.inflateSync",
2714
+ "zlib.inflateRawSync",
2715
+ "zlib.gunzipSync",
2716
+ "zlib.unzipSync",
2717
+ "zlib.crc32",
2665
2718
  "date.toISOString",
2666
2719
  "date.toISOStringValue",
2667
2720
  "fs.mkdirRecursiveSync",
@@ -2694,6 +2747,7 @@ export const MAY_THROW_LIB_FNS = new Set([
2694
2747
  "assert.eqBool",
2695
2748
  "assert.eqSym",
2696
2749
  "assert.eqDyn",
2750
+ "assert.looseResult",
2697
2751
  "assert.deepResult",
2698
2752
  "assert.match",
2699
2753
  "assert.refEqBytes",
@@ -2719,10 +2773,15 @@ export const MAY_THROW_LIB_FNS = new Set([
2719
2773
  "fs.copyFileSync",
2720
2774
  "fs.renameSync",
2721
2775
  "fs.lstatSync",
2776
+ "fs.fstatSync",
2777
+ "fs.fchmodSync",
2778
+ "fs.fsyncSync",
2779
+ "fs.linkSync",
2722
2780
  "fs.writeFileModeSync",
2723
2781
  "fs.mkdirModeSync",
2724
2782
  "fs.mkdirRecursiveModeSync",
2725
2783
  "fs.openSync",
2784
+ "fs.openNumericSync",
2726
2785
  "fs.readSync",
2727
2786
  "fs.writeSync",
2728
2787
  "fs.writeStrSync",