@scriptc/compiler 0.0.8 → 0.0.10

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 (90) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +13 -0
  2. package/dist/backend/cc.js +14 -0
  3. package/dist/backend/cc.js.map +1 -1
  4. package/dist/backend/emission/emit-exprs.js +244 -17
  5. package/dist/backend/emission/emit-exprs.js.map +1 -1
  6. package/dist/backend/emission/emit-types.d.ts +3 -0
  7. package/dist/backend/emission/emit-types.js +12 -0
  8. package/dist/backend/emission/emit-types.js.map +1 -1
  9. package/dist/backend/emission/emit-walkers.d.ts +7 -5
  10. package/dist/backend/emission/emit-walkers.js +52 -12
  11. package/dist/backend/emission/emit-walkers.js.map +1 -1
  12. package/dist/backend/emission/emitter.d.ts +1 -1
  13. package/dist/backend/emission/emitter.js +30 -9
  14. package/dist/backend/emission/emitter.js.map +1 -1
  15. package/dist/backend/llvm/dyn.d.ts +1 -0
  16. package/dist/backend/llvm/dyn.js +83 -1
  17. package/dist/backend/llvm/dyn.js.map +1 -1
  18. package/dist/backend/llvm/emitter.js +357 -20
  19. package/dist/backend/llvm/emitter.js.map +1 -1
  20. package/dist/diagnostics/diagnostic.d.ts +73 -14
  21. package/dist/diagnostics/diagnostic.js +112 -31
  22. package/dist/diagnostics/diagnostic.js.map +1 -1
  23. package/dist/diagnostics/render.js +8 -0
  24. package/dist/diagnostics/render.js.map +1 -1
  25. package/dist/frontend/lowering/lib-boundary.js +11 -1
  26. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  27. package/dist/frontend/lowering/lower-assert.js +16 -0
  28. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  29. package/dist/frontend/lowering/lower-builtins.d.ts +24 -0
  30. package/dist/frontend/lowering/lower-builtins.js +256 -3
  31. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  32. package/dist/frontend/lowering/lower-calls.d.ts +71 -11
  33. package/dist/frontend/lowering/lower-calls.js +942 -18
  34. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  35. package/dist/frontend/lowering/lower-classes.js +27 -1
  36. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  37. package/dist/frontend/lowering/lower-containers.d.ts +21 -2
  38. package/dist/frontend/lowering/lower-containers.js +386 -53
  39. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  40. package/dist/frontend/lowering/lower-dgram.js +92 -17
  41. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  42. package/dist/frontend/lowering/lower-emitter.js +54 -0
  43. package/dist/frontend/lowering/lower-emitter.js.map +1 -1
  44. package/dist/frontend/lowering/lower-exprs.js +231 -17
  45. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  46. package/dist/frontend/lowering/lower-modules.js +33 -2
  47. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  48. package/dist/frontend/lowering/lower-namespaces.d.ts +25 -11
  49. package/dist/frontend/lowering/lower-namespaces.js +50 -15
  50. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  51. package/dist/frontend/lowering/lower-server.js +211 -4
  52. package/dist/frontend/lowering/lower-server.js.map +1 -1
  53. package/dist/frontend/lowering/lower-stmts.d.ts +1 -5
  54. package/dist/frontend/lowering/lower-stmts.js +660 -19
  55. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  56. package/dist/frontend/lowering/lower-stream.js +92 -5
  57. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  58. package/dist/frontend/lowering/lowerer.d.ts +102 -15
  59. package/dist/frontend/lowering/lowerer.js +378 -30
  60. package/dist/frontend/lowering/lowerer.js.map +1 -1
  61. package/dist/frontend/lowering/surfaces.js +20 -3
  62. package/dist/frontend/lowering/surfaces.js.map +1 -1
  63. package/dist/frontend/npm-static-rewrite.d.ts +7 -2
  64. package/dist/frontend/npm-static-rewrite.js +566 -138
  65. package/dist/frontend/npm-static-rewrite.js.map +1 -1
  66. package/dist/frontend/npm-static.js +11 -2
  67. package/dist/frontend/npm-static.js.map +1 -1
  68. package/dist/frontend/program.js +5 -5
  69. package/dist/frontend/program.js.map +1 -1
  70. package/dist/frontend/shared.d.ts +6 -1
  71. package/dist/frontend/shared.js +46 -1
  72. package/dist/frontend/shared.js.map +1 -1
  73. package/dist/frontend/types.d.ts +13 -0
  74. package/dist/frontend/types.js +88 -9
  75. package/dist/frontend/types.js.map +1 -1
  76. package/dist/index.js +169 -32
  77. package/dist/index.js.map +1 -1
  78. package/dist/ir/nodes.d.ts +230 -12
  79. package/dist/ir/nodes.js +85 -6
  80. package/dist/ir/nodes.js.map +1 -1
  81. package/dist/ir/validate.js +109 -9
  82. package/dist/ir/validate.js.map +1 -1
  83. package/dist/library/fence-eval.d.ts +77 -0
  84. package/dist/library/fence-eval.js +385 -0
  85. package/dist/library/fence-eval.js.map +1 -0
  86. package/dist/library/profile.d.ts +11 -1
  87. package/dist/library/profile.js +102 -18
  88. package/dist/library/profile.js.map +1 -1
  89. package/package.json +2 -2
  90. package/surface-manifest.json +10 -3
@@ -437,8 +437,16 @@ export declare function isSupportedMapValue(t: IrType): boolean;
437
437
  /** The INDEX-SIGNATURE value fence (`{ [k: string]: V }` shapes): the map
438
438
  * VALUE kinds — the overflow portion IS a string-keyed map — plus dyn
439
439
  * (`unknown`, an unknown-valued pricing-table shape: overflow reads surface ordinary
440
- * dyn values validated by the usual checked casts). Shared frontend
441
- * (mapType) / validator. */
440
+ * dyn values validated by the usual checked casts) and three kinds the
441
+ * overflow store carries that user Maps don't admit yet:
442
+ * func — `Record<string, () => void>`, the command-registry pattern
443
+ * (scr_closure adapters; closures are cycle-headered and traced,
444
+ * so a handler capturing its own registry collects)
445
+ * map/set — `Record<string, Map<K, V>>`/`Record<string, Set<T>>`
446
+ * nested-container tables (scr_map adapters; a map value's own
447
+ * cycle capability propagates through the trace fixpoint)
448
+ * Nested index-signature RECORDS ride the record kind like any other.
449
+ * Shared frontend (mapType) / validator. */
442
450
  export declare function isSupportedIndexValue(t: IrType): boolean;
443
451
  export declare function funcOf(params: IrType[], ret: IrType): IrType;
444
452
  /** The union FUNC/SET-arm sibling rule, shared by the frontend's union
@@ -552,6 +560,16 @@ export interface IrLibExport {
552
560
  * backends emit identical bytes by construction. */
553
561
  inboundBytesTrap?: string;
554
562
  }
563
+ /** One runtime-trap overlay row: the profile's teaching (replaces the
564
+ * baseline human line as field 0) and/or remediation (the optional fourth
565
+ * field) for one runtime detected-trap code. At least one of the two is
566
+ * present, or the row is not emitted. Text is profile-validated free of
567
+ * the encoding's reserved bytes (SC4001). */
568
+ export interface IrLibTrapOverlay {
569
+ code: string;
570
+ teaching?: string;
571
+ remediation?: string;
572
+ }
555
573
  export interface IrLibSection {
556
574
  /** The profile's identity string (artifact header comments only). */
557
575
  profileName: string;
@@ -566,6 +584,15 @@ export interface IrLibSection {
566
584
  * posture (every entry prologue resets the arena). */
567
585
  resultResetSymbol: string | null;
568
586
  exports: IrLibExport[];
587
+ /** Profile-declared teaching/remediation overlays for the runtime
588
+ * detected-trap code family (SC4013–SC4019, diagnostics registry): both
589
+ * backends emit these as the program TU's overlay table
590
+ * (scr_library_trap_overlays — flat code/teaching/remediation triples)
591
+ * that the library trap funnel consults when it assembles a detected
592
+ * trap's structured sink message. Only declared codes appear, in the
593
+ * registry family's order, so the two emissions' data is identical by
594
+ * construction. */
595
+ trapOverlays: IrLibTrapOverlay[];
569
596
  /** The ask-2 identity getters (present exactly when the profile
570
597
  * declares a sidecar): pure data returns emitted with NO entry
571
598
  * prologue — exempt from the poisoned guard and every runtime touch
@@ -1171,7 +1198,12 @@ export type IrStrIntrinsicMethod = "length" | "charCodeAt" | "charAt" | "indexOf
1171
1198
  * DataView" RangeError on any bad offset. `dvGetBigUint64Number`/
1172
1199
  * `dvGetBigInt64Number` are the COMPOSED `Number(view.getBigUint64(...))`
1173
1200
  * lowerings — the bare bigint-returning calls are fenced, the wrapped
1174
- * form converts the 8-byte integer to double exactly as Number(bigint). */
1201
+ * form converts the 8-byte integer to double exactly as Number(bigint).
1202
+ * The `dvSet*` setters mirror the getters: [offset, value] plus the
1203
+ * optional bool littleEndian on the multi-byte kinds → void, the same
1204
+ * constant RangeError on any bad offset; values coerce JS-exactly
1205
+ * (integer kinds by modular truncation, Float32 by double→float
1206
+ * rounding). No BIG setters exist — bigint arguments never lower. */
1175
1207
  export type IrBytesIntrinsicMethod = "length" | "byteLength" | "get" | "slice" | "setFrom" | "toString" | "readNum" | "writeNum" | "readNumVar" | "writeNumVar"
1176
1208
  /** The comparison/search/mutation surface (u8 receivers only; see the
1177
1209
  * runtime contract): `equals` [bytes] → bool (never throws);
@@ -1187,7 +1219,7 @@ export type IrBytesIntrinsicMethod = "length" | "byteLength" | "get" | "slice" |
1187
1219
  * f64 copied count, THROWS; `swap16/32/64` [] → the receiver (+1,
1188
1220
  * in-place), THROW; `writeStr` [string, strLit enc, f64 offset, f64
1189
1221
  * length?] → f64 bytes written, THROWS. */
1190
- | "equals" | "compareBuf" | "indexOf" | "lastIndexOf" | "includes" | "indexOfNum" | "lastIndexOfNum" | "includesNum" | "fill" | "fillNum" | "fillStr" | "copy" | "swap16" | "swap32" | "swap64" | "writeStr" | "byteOffset" | "dataViewNew" | "dvGetUint8" | "dvGetInt8" | "dvGetUint16" | "dvGetInt16" | "dvGetUint32" | "dvGetInt32" | "dvGetFloat32" | "dvGetFloat64" | "dvGetBigUint64Number" | "dvGetBigInt64Number";
1222
+ | "equals" | "compareBuf" | "indexOf" | "lastIndexOf" | "includes" | "indexOfNum" | "lastIndexOfNum" | "includesNum" | "fill" | "fillNum" | "fillStr" | "copy" | "swap16" | "swap32" | "swap64" | "writeStr" | "byteOffset" | "dataViewNew" | "dvGetUint8" | "dvGetInt8" | "dvGetUint16" | "dvGetInt16" | "dvGetUint32" | "dvGetInt32" | "dvGetFloat32" | "dvGetFloat64" | "dvGetBigUint64Number" | "dvGetBigInt64Number" | "dvSetUint8" | "dvSetInt8" | "dvSetUint16" | "dvSetInt16" | "dvSetUint32" | "dvSetInt32" | "dvSetFloat32" | "dvSetFloat64";
1191
1223
  /** The bytesIntrinsic methods that can raise a catchable error — backends'
1192
1224
  * may-throw analyses seed on these exactly like MAY_THROW_LIB_FNS. */
1193
1225
  export declare const MAY_THROW_BYTES_METHODS: ReadonlySet<IrBytesIntrinsicMethod>;
@@ -1271,11 +1303,22 @@ export type IrLibFn = "island.eval"
1271
1303
  * OBJ receiver sets the member (later writes win, insertion order
1272
1304
  * preserved — JS exactly); undefined/null throws Node's catchable
1273
1305
  * "Cannot set properties of undefined (setting 'k')"; every other kind
1274
- * throws Node's STRICT-mode "Cannot create property 'k' on <kind>"
1306
+ * throws Node's STRICT-mode "Cannot create property 'k' on <kind>" —
1307
+ * primitives quoting their rendering, V8's "on number '5'"
1275
1308
  * (sloppy mode would silently ignore — suite tests are 'use strict';
1276
1309
  * SEMANTICS.md notes the sloppy divergence: loud, never silent). Void
1277
1310
  * result; in the may-throw seed set. */
1278
1311
  | "dyn.keySet"
1312
+ /** Destructuring pack over a dyn DOM source — `const [a, b] = d`, a
1313
+ * destructured dyn callback param (args: the source and the STATIC
1314
+ * TypeError spelling, "" when the source has none — both borrowed;
1315
+ * result: a fresh DOM array, +1). Iterable kinds collect like spread
1316
+ * (arrays element-by-element, strings by code point, bytes by byte);
1317
+ * every other kind throws V8's destructuring TypeError — the spelling
1318
+ * verbatim when non-empty, else the runtime kind wording ("number 5 is
1319
+ * not iterable (cannot read property Symbol(Symbol.iterator))"). In the
1320
+ * may-throw seed set. */
1321
+ | "dyn.iterPack"
1279
1322
  /** Object.defineProperties over DOM values (args: target, descriptors —
1280
1323
  * both borrowed dyn; result: the target, +1 — JS's return value).
1281
1324
  * Value descriptors become plain own properties on OBJ and FUNC targets
@@ -1434,6 +1477,20 @@ export type IrLibFn = "island.eval"
1434
1477
  * result for negative fractions rounding to zero. The explicit-digits
1435
1478
  * forms keep their island lowering. Results +1; never throw. */
1436
1479
  | "num.toExponential" | "num.toFixed0"
1480
+ /** Object.is over two numbers — the spec's SameValue on doubles: NaN
1481
+ * equals NaN, +0 differs from -0, everything else is `===`. Plain bool
1482
+ * result; never throws. (Union-armed operands take unionEq's sameValue
1483
+ * flag instead — this is the both-f64 fast path.) */
1484
+ | "num.sameValue"
1485
+ /** `new Intl.NumberFormat("en-US").format(x)` and
1486
+ * `x.toLocaleString("en-US")` with DEFAULT options — the one locale
1487
+ * whose data the runtime embeds (Node's default-build locale): decimal
1488
+ * notation, 0–3 fraction digits rounded half-up on the SHORTEST
1489
+ * round-tripping decimal (ICU's rounding input, probed vs Node —
1490
+ * format(1.0005) is "1.001" though toFixed(3) answers "1.000"), ","
1491
+ * grouping every three integer digits, "∞"/"NaN" texts, and "-0" for
1492
+ * negative inputs rounding to zero. Result +1; never throws. */
1493
+ | "intl.numFormatEnUs"
1437
1494
  /** `delete process.env[NAME]` — unsetenv(3): the mutation is visible to
1438
1495
  * every later read (process.envGet asks getenv fresh) and inherited by
1439
1496
  * spawned children, exactly Node. Statement position only (JS's boolean
@@ -1629,7 +1686,18 @@ export type IrLibFn = "island.eval"
1629
1686
  * (handshake-completion timing); on a server without deferred
1630
1687
  * connections (a plain net server) the registration never fires,
1631
1688
  * exactly Node's split. */
1632
- | "net.serverOnSecureConnection" | "net.connect" | "net.connectCb"
1689
+ | "net.serverOnSecureConnection" | "net.connect"
1690
+ /** connect with a validated autoSelectFamilyAttemptTimeout option (the
1691
+ * budget runs Node's validateInt32-from-1 ladder and is then inert —
1692
+ * the single dial has nothing to time). May-throw. */
1693
+ | "net.connectAttempt"
1694
+ /** net.connect/createConnection over a RUNTIME option bag (computed
1695
+ * keys — the invalid-input probes): Node-order validation (the
1696
+ * objectMode trio's ERR_INVALID_ARG_VALUE, validatePort, host string,
1697
+ * autoSelectFamily boolean, the attempt budget), then the trailing
1698
+ * compiler-rendered fence — ALWAYS THROWS (the error.nodeThrow
1699
+ * polymorphic-result carve-out). May-throw seed. */
1700
+ | "net.connectOptsChk" | "net.connectCb"
1633
1701
  /** connect({ port, host, autoSelectFamily: true, lookup }) — the
1634
1702
  * caller-resolver dial (portless's createLoopbackConnection): args
1635
1703
  * [port, host, lookup]. The runtime creates the (connecting) socket
@@ -1671,7 +1739,13 @@ export type IrLibFn = "island.eval"
1671
1739
  * defers the callback to the next turn (SEMANTICS.md documents the
1672
1740
  * blocking divergence); its per-union adapter builds the
1673
1741
  * `Error | null` first argument. */
1674
- | "dgram.createSocket" | "dgram.bind" | "dgram.bindCb" | "dgram.connect" | "dgram.connectCb" | "dgram.sendStr" | "dgram.sendBytes" | "dgram.address" | "dgram.close" | "dgram.closeCb" | "dgram.unref" | "dgram.ref" | "dgram.onMessage" | "dgram.onError" | "dgram.onListening" | "dgram.onClose" | "dgram.onConnect" | "dns.lookup"
1742
+ | "dgram.createSocket" | "dgram.bind" | "dgram.bindCb" | "dgram.connect" | "dgram.connectCb" | "dgram.sendStr" | "dgram.sendBytes"
1743
+ /** The send argument-validation ladder over DOM arguments (Node's
1744
+ * signature shuffle: slice bounds, list/type contracts, port/address
1745
+ * validation, connected-state errors) — a fully-validated unconnected
1746
+ * single-payload send RUNS; callback/list/connected forms meet the
1747
+ * trailing fence. May-throw. */
1748
+ | "dgram.sendChk" | "dgram.address" | "dgram.close" | "dgram.closeCb" | "dgram.unref" | "dgram.ref" | "dgram.onMessage" | "dgram.onError" | "dgram.onListening" | "dgram.onClose" | "dgram.onConnect" | "dns.lookup"
1675
1749
  /** node:test (scr_test.c — linked only when one of these appears on
1676
1750
  * the IR; moduleUsesNodeTest is the switch, and the main epilogue asks
1677
1751
  * scr_test_exit_code() for the process's exit status). Strings are
@@ -1847,7 +1921,17 @@ export type IrLibFn = "island.eval"
1847
1921
  /** tls.createSecureContext({ cert, key }) — parses the PEM pair into an
1848
1922
  * opaque SecureContext handle (secureCtx kind) for SNI callbacks to
1849
1923
  * answer with; cert/key are PEM strings or Buffers like createServer's. */
1850
- | "tls.createSecureContext" | "https.createServer" | "https.request" | "https.requestCb"
1924
+ | "tls.createSecureContext"
1925
+ /** createSecureContext over a RUNTIME options record (the checked-
1926
+ * dynamic lane): Node's typed option validations first (the ciphers/
1927
+ * passphrase/engine/version/timeout/ticketKeys ladders), then the pem
1928
+ * walk — a validated { cert, key } bag builds the real context.
1929
+ * May-throw. */
1930
+ | "tls.createSecureContextDyn"
1931
+ /** tls.getCACertificates(type): validateString + the documented name
1932
+ * set, then the trailing compiler-rendered fence — ALWAYS THROWS (the
1933
+ * error.nodeThrow polymorphic-result carve-out). May-throw seed. */
1934
+ | "tls.caCertsChk" | "https.createServer" | "https.request" | "https.requestCb"
1851
1935
  /** A call through a `const requestFn = tls ? https.request :
1852
1936
  * http.request` binding — the module-function-as-value ternary between
1853
1937
  * the two known clients: the https.request row with a leading `secure`
@@ -1961,6 +2045,51 @@ export type IrLibFn = "island.eval"
1961
2045
  * zero-padded to the total. THROWS Node's 'length' RangeError on a
1962
2046
  * negative/non-integer total (may-throw seed). */
1963
2047
  | "buffer.concatLen"
2048
+ /** The checked-dynamic compare/equals validators (scr_bytes_io.c) —
2049
+ * the lowered form when an argument is NOT statically bytes<u8> (the
2050
+ * invalid-input probes; a dyn from an untyped JS helper): Node's own
2051
+ * argument ladders run at runtime — ERR_INVALID_ARG_TYPE with the
2052
+ * API's argument name ("buf1"/"buf2", "otherBuffer", "target"; offsets
2053
+ * "of type number"), validateOffset's ERR_OUT_OF_RANGE for bad
2054
+ * numbers, undefined offsets taking their Node defaults — and a
2055
+ * well-typed value still computes the real answer. All args borrowed
2056
+ * dyn; compareChk's four offset slots pass the undefined dyn when
2057
+ * syntactically absent. May-throw seeds. */
2058
+ | "buffer.compareChk" | "bytes.equalsChk" | "bytes.compareChk"
2059
+ /** The deprecated `new Buffer(number, 'enc')` string-arm rejection:
2060
+ * always throws Node's ERR_INVALID_ARG_TYPE ("The \"string\" argument
2061
+ * must be of type string. Received ..."). Borrowed dyn; may-throw. */
2062
+ | "buffer.newStringFail"
2063
+ /** fs._toUnixTimestamp(time) over a DOM value: numeric strings and
2064
+ * finite numbers coerce (negatives answer now/1000, Node's shape);
2065
+ * everything else throws Node's ERR_INVALID_ARG_TYPE. May-throw. */
2066
+ | "fs.toUnixTimestamp"
2067
+ /** The fs argument-validation ladders (checked-dynamic lane): each Chk
2068
+ * replicates its API's Node-order validation over DOM values (Node's
2069
+ * exact typed errors — ERR_INVALID_ARG_TYPE/VALUE, ERR_OUT_OF_RANGE),
2070
+ * and a full pass meets the trailing compiler-rendered SC2020 fence
2071
+ * string — so the ALWAYS-THROW forms take the error.nodeThrow
2072
+ * polymorphic-result carve-out. mkdtempSyncChk and the lchmod sync/
2073
+ * promise pair run the REAL operation on a validated pass instead
2074
+ * (macOS lchmod(2); non-APPLE answers Node's not-a-function /
2075
+ * ERR_METHOD_NOT_IMPLEMENTED shapes). May-throw seeds, all of them. */
2076
+ | "fs.existsChk" | "fs.mkdtempChk" | "fs.mkdtempSyncChk" | "fs.readFileChk" | "fs.opendirChk" | "fs.watchFileChk" | "fs.lchmodChk" | "fs.lchmodSyncChk" | "fsp.lchmodChk" | "fs.readChk" | "fs.streamOptsChk"
2077
+ /** The compiler-resolved ERR_INVALID_ARG_TYPE throw with a RUNTIME-
2078
+ * rendered Received tail: args [argname, "of type ..." clause, the
2079
+ * offending DOM value]. ALWAYS THROWS; polymorphic result (the
2080
+ * error.nodeThrow pattern). May-throw seed. */
2081
+ | "error.argTypeThrow"
2082
+ /** The property flavor of argTypeThrow ("The \"options.x\" property
2083
+ * must be ..."): the option-bag ladders' provably-invalid arms. ALWAYS
2084
+ * THROWS; polymorphic result. May-throw seed. */
2085
+ | "error.propTypeThrow"
2086
+ /** The checked-dynamic max-listeners ladders: setMaxChk is the
2087
+ * instance form over a DOM n (non-numbers ERR_INVALID_ARG_TYPE,
2088
+ * negatives/NaN ERR_OUT_OF_RANGE; +1 receiver back — chaining);
2089
+ * setDefaultMaxChk is the static/property form, its second argument
2090
+ * naming the message slot ("setMaxListeners" for the static call,
2091
+ * "defaultMaxListeners" for the module-property assignment). */
2092
+ | "emitter.setMaxChk" | "emitter.setDefaultMaxChk"
1964
2093
  /** The Buffer forms of the fs quartet: readFileSync(path) with NO
1965
2094
  * encoding → bytes<u8> (+1), writeFileSync(path, bytes), and the
1966
2095
  * fs/promises readFile(path) no-encoding form (an already-settled
@@ -2185,6 +2314,20 @@ export type IrLibFn = "island.eval"
2185
2314
  * field to stamp. error.toString: borrowed `%Error`-typed receiver, +1
2186
2315
  * string in Node's "name: message" shape. None of the three throws. */
2187
2316
  | "error.new"
2317
+ /** The compiler-resolved Node-parity throw for always-throwing lowered
2318
+ * arms (ERR_INVALID_THIS receivers, ERR_MISSING_ARGS arity ladders,
2319
+ * the symbol-to-string TypeError): args are [error-kind f64 (the
2320
+ * SCR_ERR_* index: 0 Error, 1 TypeError, 2 RangeError), code (empty =
2321
+ * no code slot), message]. ALWAYS THROWS catchably; the result type is
2322
+ * the replaced expression's own (never materialized — the
2323
+ * global.undefRead pattern). May-throw seed. */
2324
+ | "error.nodeThrow"
2325
+ /** JS ToString over a DOM value WITH the object protocol (a user
2326
+ * toString/valueOf member is CALLED and its throw propagates;
2327
+ * exhaustion throws "Cannot convert object to primitive value"; units
2328
+ * render "null"/"undefined") — the WHATWG USVString conversions
2329
+ * (URLSearchParams names/values). Borrowed dyn; +1 string. May-throw. */
2330
+ | "dyn.toStringCoerce"
2188
2331
  /** A read of a `declare`d const NOTHING defines (the bundler-define
2189
2332
  * pattern — __VERSION__): always throws the catchable ReferenceError
2190
2333
  * Node raises at the access ("<name> is not defined"). args[0] is the
@@ -2239,7 +2382,32 @@ export type IrLibFn = "island.eval"
2239
2382
  * JS). Strings/arrays/bytes answer their index keys; other scalars an
2240
2383
  * empty array; null/undefined throw Node's catchable TypeError
2241
2384
  * ("Cannot convert undefined or null to object"). */
2242
- | "dyn.objKeys" | "dyn.hasOwn" | "dyn.assign" | "dyn.objValues" | "dyn.objEntries"
2385
+ | "dyn.objKeys" | "dyn.hasOwn" | "dyn.assign"
2386
+ /** Variadic Object.assign over CHECKED-DYNAMIC targets (`Object.assign(
2387
+ * {}, ...arr.map(f), tail)` — the option-table merge): the lowering
2388
+ * builds one fresh DOM pack of sources (packPush retains a plain source
2389
+ * in; packPushSpread flattens a spread source through the spread-call
2390
+ * walk — V8's exact TypeError texts, the string arg spelling the spread
2391
+ * expression for the nullish form), so every source evaluates and
2392
+ * flattens BEFORE any copying (JS's ArgumentListEvaluation), then
2393
+ * assignAll copies each pack element's own enumerable keys onto the
2394
+ * target left to right and answers the TARGET (+1) — identity, like JS.
2395
+ * assignAll throws Node's ToObject TypeError on a nullish target. */
2396
+ | "dyn.packPush" | "dyn.packPushSpread"
2397
+ /** The iterated-path spread twin: V8 spells the optimized apply-path
2398
+ * texts (packPushSpread's — the expression named for nullish sources)
2399
+ * only for the SINGLE LAST argument's spread; any other spread position
2400
+ * drives the real iterator protocol, whose failure describes the VALUE
2401
+ * ("object null is not iterable (cannot read property
2402
+ * Symbol(Symbol.iterator))"). The frontend picks by position. */
2403
+ | "dyn.packPushSpreadIter" | "dyn.assignAll"
2404
+ /** `Object.create(null)` (scr_json.c): a fresh NULL-PROTOTYPE DOM
2405
+ * dictionary. The DOM's OBJ dispatch is already own-member-only —
2406
+ * Node's null-proto answer — so the flag's whole job is the observations
2407
+ * that SEE the prototype: inspect's "[Object: null prototype]" prefix
2408
+ * and deepStrictEqual's prototype gate. Never throws. Static builds
2409
+ * only; --dynamic routes Object.create through the engine instead. */
2410
+ | "dyn.objCreateNullProto" | "dyn.objValues" | "dyn.objEntries"
2243
2411
  /** structuredClone over the DOM (scr_json.c): the JSON-safe subset plus
2244
2412
  * bytes (a fresh copy — a Buffer clones as a plain Uint8Array, like
2245
2413
  * Node), deep. Functions and handle kinds throw the spec's catchable
@@ -2343,7 +2511,13 @@ export type IrLibFn = "island.eval"
2343
2511
  * propagates the first error by destroying the rest, calls cb after the
2344
2512
  * last 'close'; answers the destination +1. The Dyn twins take the
2345
2513
  * callback as a checked-dynamic VALUE (mustCall wrappers). */
2346
- | "stream.finished" | "stream.finishedDyn" | "stream.pipeline" | "stream.pipelineDyn" | "readable.newDyn" | "writable.newDyn" | "duplex.newDyn" | "transform.newDyn" | "passthrough.newDyn" | "readable.initDyn" | "writable.initDyn" | "duplex.initDyn" | "transform.initDyn" | "passthrough.initDyn" | "readable.push" | "readable.pushStr" | "readable.pushNull" | "readable.pushU" | "readable.pushDyn" | "readable.unshift" | "readable.unshiftStr" | "readable.read" | "readable.pause" | "readable.resume" | "readable.setEncoding"
2514
+ | "stream.finished" | "stream.finishedDyn" | "stream.pipeline" | "stream.pipelineDyn"
2515
+ /** node:stream/promises — the promise forms over the same machinery:
2516
+ * sp.finished: (s) → a pending void promise the terminal watcher
2517
+ * settles; sp.pipeline: (count, s1..sn) → the callback pipeline's
2518
+ * chaining/destroyer semantics settling a void promise (fulfilled on a
2519
+ * clean finish, rejected with the finish status otherwise). */
2520
+ | "sp.finished" | "sp.pipeline" | "readable.newDyn" | "writable.newDyn" | "duplex.newDyn" | "transform.newDyn" | "passthrough.newDyn" | "readable.initDyn" | "writable.initDyn" | "duplex.initDyn" | "transform.initDyn" | "passthrough.initDyn" | "readable.push" | "readable.pushStr" | "readable.pushNull" | "readable.pushU" | "readable.pushDyn" | "readable.unshift" | "readable.unshiftStr" | "readable.read" | "readable.pause" | "readable.resume" | "readable.setEncoding"
2347
2521
  /** for-await over a readable (the desugared loop's per-pass promise):
2348
2522
  * +1 promise of the next chunk — buffered content, the EOF sentinel
2349
2523
  * (empty Buffer / dyn undefined), or a rejection with the stream's
@@ -3555,6 +3729,23 @@ export type IrExpr = {
3555
3729
  type: IrType;
3556
3730
  loc: SrcLoc;
3557
3731
  }
3732
+ /** Island value → dyn DOM conversion (`type` is always dyn; the operand
3733
+ * is always jsval): the jsval→DOM crossing — an 'any'-typed engine
3734
+ * value flowing into an 'unknown'/'object'/JS-residue slot wraps BY
3735
+ * REFERENCE as the DOM's SCR_DYN_JSVAL kind (scr_dyn_from_jsval).
3736
+ * Engine scalars (number/string/boolean/null/undefined) normalize to
3737
+ * the native DOM kinds at wrap time, so wrapped nodes only ever hold
3738
+ * engine objects/arrays/functions; typeof/truthiness/String()/=== on
3739
+ * the wrapped node route to the engine, un-armed DOM walks fence
3740
+ * loudly, and scr_jsval_from_dyn unwraps the SAME engine value back
3741
+ * (identity round trip). The operand is borrowed; the result is owned
3742
+ * (+1). Never throws. */
3743
+ | {
3744
+ kind: "dynFromJsval";
3745
+ value: IrExpr;
3746
+ type: IrType;
3747
+ loc: SrcLoc;
3748
+ }
3558
3749
  /** CALLING a dyn DOM value — `fn(a, b)` where fn is checked-dynamic (an
3559
3750
  * implicit-any JS binding, a dyn record member, a dynKeyGet result).
3560
3751
  * Arguments are ALREADY dyn-typed (typed values box through dynFrom at
@@ -3567,12 +3758,26 @@ export type IrExpr = {
3567
3758
  * message exactly). A function callee calls through the boxed thunk:
3568
3759
  * per-arg validation against the boxed signature (mismatches throw the
3569
3760
  * path-annotated TypeError), result converted back to dyn. Callee and
3570
- * args are borrowed; the result is owned (+1). MAY THROW. */
3761
+ * args are borrowed; the result is owned (+1). MAY THROW.
3762
+ *
3763
+ * `spreads` (the runtime-arity form — `f(...args)`, the rest-forwarding
3764
+ * idiom): entries name indices into `args` whose DOM values FLATTEN into
3765
+ * the argument vector at the call — JS's spread over the DOM's iterable
3766
+ * kinds (arrays element-by-element, strings by code point, bytes by
3767
+ * byte; every other kind throws V8's exact spread-call TypeError,
3768
+ * catchably — `what` is the spread expression's source spelling, which
3769
+ * the nullish text spells), evaluated and flattened left-to-right (JS's
3770
+ * ArgumentListEvaluation). The emitters build one fresh argument array
3771
+ * and apply through it. */
3571
3772
  | {
3572
3773
  kind: "dynCall";
3573
3774
  callee: IrExpr;
3574
3775
  calleeName: string;
3575
3776
  args: IrExpr[];
3777
+ spreads?: {
3778
+ arg: number;
3779
+ what: string;
3780
+ }[];
3576
3781
  type: IrType;
3577
3782
  loc: SrcLoc;
3578
3783
  }
@@ -3941,11 +4146,15 @@ export type IrExpr = {
3941
4146
  * comparison (`u === "text"`) arrives here after the frontend wraps the
3942
4147
  * plain side (payload identity is preserved by the wrap, so ref-arm
3943
4148
  * semantics stay JS-exact). Operands are borrowed; result is a plain
3944
- * bool. `negated` is the `!==` spelling. */
4149
+ * bool. `negated` is the `!==` spelling. `sameValue` upgrades the f64
4150
+ * arm's compare from `===` to SameValue (NaN equals NaN, +0 differs
4151
+ * from -0) — the Object.is lowering; every other arm's compare is
4152
+ * shared between the two semantics. */
3945
4153
  | {
3946
4154
  kind: "unionEq";
3947
4155
  unionId: string;
3948
4156
  negated: boolean;
4157
+ sameValue: boolean;
3949
4158
  left: IrExpr;
3950
4159
  right: IrExpr;
3951
4160
  type: IrType;
@@ -4117,6 +4326,15 @@ export type IrJsOp = "add" | "sub" | "mul" | "div" | "mod" | "pow" | "neg" | "pl
4117
4326
  * engine, Symbol.hasInstance included; a non-object RHS throws the
4118
4327
  * engine's own TypeError, bridged catchably. */
4119
4328
  | "instanceOf" | "truthy" | "not" | "typeof" | "toStr" | "getProp" | "setProp" | "getIdx" | "setIdx" | "callMethod" | "callFn"
4329
+ /** Spread application on an island callee — `f(...pre, ...s)`, the
4330
+ * rest-forwarding idiom (`(...args) => g(...args)` under --dynamic).
4331
+ * Args are exactly (callee, pre, spread): `pre` is the engine array of
4332
+ * leading fixed arguments (jsOp arrLit), `spread` the spread source;
4333
+ * `name` carries the spread expression's source spelling (V8's nullish
4334
+ * spread-call TypeError spells it). The prelude helper uses REAL spread
4335
+ * syntax, so iterator protocols are the engine's own, with guards
4336
+ * front-running V8's exact spread-call TypeError texts. May throw. */
4337
+ | "callSpread"
4120
4338
  /** `new X(...)` where X is jsval-typed (package-declared classes):
4121
4339
  * JS_CallConstructor — args are the callee then the constructor
4122
4340
  * arguments, mirroring callFn. */
package/dist/ir/nodes.js CHANGED
@@ -155,10 +155,22 @@ export function isSupportedMapValue(t) {
155
155
  /** The INDEX-SIGNATURE value fence (`{ [k: string]: V }` shapes): the map
156
156
  * VALUE kinds — the overflow portion IS a string-keyed map — plus dyn
157
157
  * (`unknown`, an unknown-valued pricing-table shape: overflow reads surface ordinary
158
- * dyn values validated by the usual checked casts). Shared frontend
159
- * (mapType) / validator. */
158
+ * dyn values validated by the usual checked casts) and three kinds the
159
+ * overflow store carries that user Maps don't admit yet:
160
+ * func — `Record<string, () => void>`, the command-registry pattern
161
+ * (scr_closure adapters; closures are cycle-headered and traced,
162
+ * so a handler capturing its own registry collects)
163
+ * map/set — `Record<string, Map<K, V>>`/`Record<string, Set<T>>`
164
+ * nested-container tables (scr_map adapters; a map value's own
165
+ * cycle capability propagates through the trace fixpoint)
166
+ * Nested index-signature RECORDS ride the record kind like any other.
167
+ * Shared frontend (mapType) / validator. */
160
168
  export function isSupportedIndexValue(t) {
161
- return t.kind === "dyn" || isSupportedMapValue(t);
169
+ return (t.kind === "dyn" ||
170
+ t.kind === "func" ||
171
+ t.kind === "map" ||
172
+ t.kind === "set" ||
173
+ isSupportedMapValue(t));
162
174
  }
163
175
  export function funcOf(params, ret) {
164
176
  return { kind: "func", params, ret };
@@ -461,6 +473,14 @@ export const MAY_THROW_BYTES_METHODS = new Set([
461
473
  "dvGetFloat64",
462
474
  "dvGetBigUint64Number",
463
475
  "dvGetBigInt64Number",
476
+ "dvSetUint8",
477
+ "dvSetInt8",
478
+ "dvSetUint16",
479
+ "dvSetInt16",
480
+ "dvSetUint32",
481
+ "dvSetInt32",
482
+ "dvSetFloat32",
483
+ "dvSetFloat64",
464
484
  ]);
465
485
  /** Result-type rule for each island op (the validator enforces it; the
466
486
  * frontend constructs nodes with exactly these). */
@@ -478,6 +498,7 @@ export function jsOpResultKind(op) {
478
498
  case "getIdx":
479
499
  case "callMethod":
480
500
  case "callFn":
501
+ case "callSpread":
481
502
  case "construct":
482
503
  case "globalGet":
483
504
  case "objLit":
@@ -849,7 +870,12 @@ export function canConvertToDyn(t, getRecord, getUnion) {
849
870
  }
850
871
  if (t.kind === "union") {
851
872
  const def = getUnion(t.unionId);
852
- return !!def && def.arms.every((a) => a.kind === "undefinedT" || isJsonSafeType(a, getRecord, getUnion));
873
+ // JSON-safe arms box as before; BOXABLE FUNCTION arms join them (the
874
+ // invalid-input probes iterate `[1, null, () => {}, true]` — the
875
+ // union's func arm crosses through the checked-dynamic function
876
+ // boundary exactly like a bare func dynFrom).
877
+ return !!def && def.arms.every((a) => a.kind === "undefinedT" || isJsonSafeType(a, getRecord, getUnion) ||
878
+ (a.kind === "func" && canBoxFuncIntoDyn(a, getRecord, getUnion)));
853
879
  }
854
880
  return false;
855
881
  }
@@ -925,8 +951,15 @@ export function canDynCheckTo(t, getRecord, getUnion) {
925
951
  * back). */
926
952
  export function canBoxFuncIntoDyn(t, getRecord, getUnion) {
927
953
  return (t.kind === "func" &&
928
- t.params.every((p) => p.kind === "dyn" || canDynCheckTo(p, getRecord, getUnion)) &&
929
- (t.ret.kind === "void" || t.ret.kind === "dyn" || canConvertToDyn(t.ret, getRecord, getUnion)));
954
+ // A jsval (island) param converts through scr_jsval_from_dyn in the
955
+ // thunk (wrapped cells unwrap by reference, DOM data deep-copies) —
956
+ // the checker-'any' callback params of the routed-dispatch lane
957
+ // (`bag.list.map((x) => ...)` with x typed any).
958
+ t.params.every((p) => p.kind === "dyn" || p.kind === "jsval" || canDynCheckTo(p, getRecord, getUnion)) &&
959
+ // A jsval return converts through the by-reference wrap
960
+ // (dynFromJsval — the thunk's result conversion), so engine-returning
961
+ // callbacks box too: the routed-dispatch lane's flatMap shape.
962
+ (t.ret.kind === "void" || t.ret.kind === "dyn" || t.ret.kind === "jsval" || canConvertToDyn(t.ret, getRecord, getUnion)));
930
963
  }
931
964
  /** A closure type a dyn function value can ADAPT to (dynCheck): every
932
965
  * param dyn or dyn-convertible (the adapter converts typed arguments into
@@ -1149,6 +1182,7 @@ export function moduleUsesStream(mod) {
1149
1182
  node.fn.startsWith("passthrough.") ||
1150
1183
  node.fn === "stream.destroy" || node.fn === "stream.destroyErr" ||
1151
1184
  node.fn === "stream.prop" || node.fn === "stream.errored" ||
1185
+ node.fn === "sp.finished" || node.fn === "sp.pipeline" ||
1152
1186
  node.fn.startsWith("stream.set"))) {
1153
1187
  found = true;
1154
1188
  return;
@@ -1708,6 +1742,10 @@ export function moduleUsesTls(mod) {
1708
1742
  /** libCall families a v1 library artifact refuses, with the surface name the SC4005
1709
1743
  * teaching uses. Prefix match over IrLibFn spellings. */
1710
1744
  const LIB_MODE_REFUSED_PREFIXES = [
1745
+ // fs.exists is the one CALLBACK-async fs op with a real implementation:
1746
+ // its fire rides the timer queue (scr_bytes_io.c), which library links
1747
+ // exclude — refuse the surface like the rest of the event-loop family.
1748
+ ["fs.existsChk", "the async fs callback surface (fs.exists)"],
1711
1749
  ["timers.", "the timers surface (setTimeout family)"],
1712
1750
  ["tp.", "the timers/promises surface"],
1713
1751
  ["cp.", "the child_process surface"],
@@ -1946,6 +1984,8 @@ export const MAY_THROW_LIB_FNS = new Set([
1946
1984
  // divergence-66 stance).
1947
1985
  "tls.pemDyn",
1948
1986
  "tls.createServerDyn",
1987
+ "tls.createSecureContextDyn",
1988
+ "tls.caCertsChk",
1949
1989
  "tls.createServerDynCb",
1950
1990
  "https.createServerDyn",
1951
1991
  "https.createServerDynCb",
@@ -2007,6 +2047,8 @@ export const MAY_THROW_LIB_FNS = new Set([
2007
2047
  "stream.finishedDyn",
2008
2048
  "stream.pipeline",
2009
2049
  "stream.pipelineDyn",
2050
+ "sp.finished",
2051
+ "sp.pipeline",
2010
2052
  "readable.newDyn",
2011
2053
  "writable.newDyn",
2012
2054
  "duplex.newDyn",
@@ -2058,6 +2100,10 @@ export const MAY_THROW_LIB_FNS = new Set([
2058
2100
  // A read of a declare-d const nothing defines: always throws Node's
2059
2101
  // catchable ReferenceError.
2060
2102
  "global.undefRead",
2103
+ // The compiler-resolved Node-parity throw: always throws, catchably.
2104
+ "error.nodeThrow",
2105
+ // USVString coercion runs user toString/valueOf — throws propagate.
2106
+ "dyn.toStringCoerce",
2061
2107
  "child.kill",
2062
2108
  // The caller's lookup runs synchronously inside the connect call — a
2063
2109
  // throw there propagates like Node's.
@@ -2104,6 +2150,11 @@ export const MAY_THROW_LIB_FNS = new Set([
2104
2150
  "dyn.objKeys",
2105
2151
  "dyn.hasOwn",
2106
2152
  "dyn.assign",
2153
+ // variadic Object.assign: spread flattening throws V8's spread-call
2154
+ // TypeErrors; the final copy throws ToObject on a nullish target
2155
+ "dyn.packPushSpread",
2156
+ "dyn.packPushSpreadIter",
2157
+ "dyn.assignAll",
2107
2158
  "dyn.objValues",
2108
2159
  "dyn.objEntries",
2109
2160
  "error.domClone",
@@ -2111,6 +2162,8 @@ export const MAY_THROW_LIB_FNS = new Set([
2111
2162
  // throws Node's catchable SyntaxError at construction.
2112
2163
  "regex.new",
2113
2164
  "dyn.keySet",
2165
+ // the destructuring pack throws V8's TypeError on non-iterable DOM kinds
2166
+ "dyn.iterPack",
2114
2167
  "dyn.toString",
2115
2168
  "dyn.defineProps",
2116
2169
  "process.chdir",
@@ -2139,6 +2192,31 @@ export const MAY_THROW_LIB_FNS = new Set([
2139
2192
  "crypto.randomBytesToString",
2140
2193
  "crypto.randomBytes",
2141
2194
  "buffer.concatLen",
2195
+ // The checked-dynamic compare/equals validators: Node's argument
2196
+ // ladders throw ERR_INVALID_ARG_TYPE / ERR_OUT_OF_RANGE catchably.
2197
+ "buffer.compareChk",
2198
+ "bytes.equalsChk",
2199
+ "bytes.compareChk",
2200
+ "buffer.newStringFail",
2201
+ "fs.toUnixTimestamp",
2202
+ "fs.existsChk",
2203
+ "fs.mkdtempChk",
2204
+ "fs.mkdtempSyncChk",
2205
+ "fs.readFileChk",
2206
+ "fs.opendirChk",
2207
+ "fs.watchFileChk",
2208
+ "fs.lchmodChk",
2209
+ "fs.lchmodSyncChk",
2210
+ "fsp.lchmodChk",
2211
+ "fs.readChk",
2212
+ "fs.streamOptsChk",
2213
+ "net.connectAttempt",
2214
+ "net.connectOptsChk",
2215
+ "net.setAutoSelTimeout",
2216
+ "error.argTypeThrow",
2217
+ "error.propTypeThrow",
2218
+ "emitter.setMaxChk",
2219
+ "emitter.setDefaultMaxChk",
2142
2220
  "fs.readFileSyncBytes",
2143
2221
  "fs.writeFileSyncBytes",
2144
2222
  "zlib.inflateSync",
@@ -2159,6 +2237,7 @@ export const MAY_THROW_LIB_FNS = new Set([
2159
2237
  "dgram.connectCb",
2160
2238
  "dgram.sendStr",
2161
2239
  "dgram.sendBytes",
2240
+ "dgram.sendChk",
2162
2241
  "dgram.address",
2163
2242
  "dgram.close",
2164
2243
  "dgram.closeCb",