@scriptc/compiler 0.0.11 → 0.0.13

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 (97) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +153 -24
  2. package/ambient/scriptc.d.ts +2 -2
  3. package/dist/backend/cc.d.ts +10 -2
  4. package/dist/backend/cc.js +12 -0
  5. package/dist/backend/cc.js.map +1 -1
  6. package/dist/backend/emission/emit-async.js +1 -1
  7. package/dist/backend/emission/emit-exprs.js +235 -64
  8. package/dist/backend/emission/emit-exprs.js.map +1 -1
  9. package/dist/backend/emission/emit-island.js +1 -1
  10. package/dist/backend/emission/emit-shapes.js +1 -1
  11. package/dist/backend/emission/emit-walkers.d.ts +14 -14
  12. package/dist/backend/emission/emit-walkers.js +44 -44
  13. package/dist/backend/emission/emit-walkers.js.map +1 -1
  14. package/dist/backend/emission/emitter.d.ts +3 -3
  15. package/dist/backend/emission/emitter.js +8 -8
  16. package/dist/backend/emission/may-throw.js +1 -1
  17. package/dist/backend/llvm/dyn.d.ts +10 -10
  18. package/dist/backend/llvm/dyn.js +26 -26
  19. package/dist/backend/llvm/dyn.js.map +1 -1
  20. package/dist/backend/llvm/emitter.js +140 -49
  21. package/dist/backend/llvm/emitter.js.map +1 -1
  22. package/dist/backend/llvm/shapes.js +1 -1
  23. package/dist/backend/llvm/walkers.js +2 -2
  24. package/dist/backend/llvm/walkers.js.map +1 -1
  25. package/dist/diagnostics/diagnostic.d.ts +1 -1
  26. package/dist/diagnostics/diagnostic.js +4 -3
  27. package/dist/diagnostics/diagnostic.js.map +1 -1
  28. package/dist/frontend/lowering/crypto-tables.d.ts +7 -0
  29. package/dist/frontend/lowering/crypto-tables.js +139 -0
  30. package/dist/frontend/lowering/crypto-tables.js.map +1 -0
  31. package/dist/frontend/lowering/lib-boundary.js +5 -5
  32. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  33. package/dist/frontend/lowering/lower-assert.js +12 -12
  34. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  35. package/dist/frontend/lowering/lower-builtins.d.ts +45 -27
  36. package/dist/frontend/lowering/lower-builtins.js +203 -70
  37. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  38. package/dist/frontend/lowering/lower-calls.d.ts +4 -4
  39. package/dist/frontend/lowering/lower-calls.js +74 -66
  40. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  41. package/dist/frontend/lowering/lower-classes.js +41 -7
  42. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  43. package/dist/frontend/lowering/lower-containers.d.ts +5 -5
  44. package/dist/frontend/lowering/lower-containers.js +19 -19
  45. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  46. package/dist/frontend/lowering/lower-emitter.js +2 -2
  47. package/dist/frontend/lowering/lower-emitter.js.map +1 -1
  48. package/dist/frontend/lowering/lower-exprs.d.ts +7 -7
  49. package/dist/frontend/lowering/lower-exprs.js +227 -119
  50. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  51. package/dist/frontend/lowering/lower-inspect.js +5 -5
  52. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  53. package/dist/frontend/lowering/lower-island.js +12 -3
  54. package/dist/frontend/lowering/lower-island.js.map +1 -1
  55. package/dist/frontend/lowering/lower-modules.js +17 -17
  56. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  57. package/dist/frontend/lowering/lower-namespaces.d.ts +11 -1
  58. package/dist/frontend/lowering/lower-namespaces.js +41 -6
  59. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  60. package/dist/frontend/lowering/lower-server.d.ts +21 -0
  61. package/dist/frontend/lowering/lower-server.js +278 -23
  62. package/dist/frontend/lowering/lower-server.js.map +1 -1
  63. package/dist/frontend/lowering/lower-stmts.d.ts +1 -1
  64. package/dist/frontend/lowering/lower-stmts.js +195 -34
  65. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  66. package/dist/frontend/lowering/lower-stream.js +67 -23
  67. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  68. package/dist/frontend/lowering/lowerer.d.ts +31 -13
  69. package/dist/frontend/lowering/lowerer.js +99 -45
  70. package/dist/frontend/lowering/lowerer.js.map +1 -1
  71. package/dist/frontend/lowering/surfaces.d.ts +6 -0
  72. package/dist/frontend/lowering/surfaces.js +78 -2
  73. package/dist/frontend/lowering/surfaces.js.map +1 -1
  74. package/dist/frontend/program.js +1 -1
  75. package/dist/frontend/shared.js +7 -7
  76. package/dist/frontend/shared.js.map +1 -1
  77. package/dist/frontend/types.d.ts +2 -2
  78. package/dist/frontend/types.js +27 -15
  79. package/dist/frontend/types.js.map +1 -1
  80. package/dist/index.js +44 -8
  81. package/dist/index.js.map +1 -1
  82. package/dist/ir/nodes.d.ts +208 -106
  83. package/dist/ir/nodes.js +100 -22
  84. package/dist/ir/nodes.js.map +1 -1
  85. package/dist/ir/validate.js +96 -38
  86. package/dist/ir/validate.js.map +1 -1
  87. package/dist/library/int-infer.js +13 -0
  88. package/dist/library/int-infer.js.map +1 -1
  89. package/dist/library/profile.d.ts +8 -6
  90. package/dist/library/profile.js.map +1 -1
  91. package/dist/library/sidecar-validate.js +1 -1
  92. package/dist/library/sidecar-validate.js.map +1 -1
  93. package/dist/library/sidecar.d.ts +1 -1
  94. package/dist/library/sidecar.js +20 -7
  95. package/dist/library/sidecar.js.map +1 -1
  96. package/package.json +2 -2
  97. package/surface-manifest.json +289 -4
@@ -1,4 +1,4 @@
1
- import { arrayOf, BOOL, BYTES_U8, bytesOf, canAdaptDynFuncTo, canConvertToDyn, canExitIslandToType, canMarshalIntoIsland, canMarshalTypedFuncIntoIsland, CHILD_T, CHILDSTREAM_T, DGRAMSOCK_T, DYN, DYN_HANDLE_KINDS, F64, FSWATCHER_T, HTTP2SESSION_T, HTTP2STREAM_T, HTTPCLIENTREQ_T, HTTPREQ_T, HTTPRES_T, isJsonSafeType, isRefCounted, isSupportedIndexValue, isSupportedMapKey, isSupportedMapValue, isSupportedSetElem, isUnitType, jsOpResultKind, JSVAL, NETSERVER_T, NETSOCKET_T, PROCSTREAM_T, REF_TRUTHY_KINDS, REGEX, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, SEARCH_PARAMS_T, SECURECTX_T, SPAWNRES_T, STATS_T, STRING, SYMBOL_T, TESTCTX_T, typeEquals, typeKey, unionFuncSetArmsOk, URL_T, VOID } from "./nodes.js";
1
+ import { arrayOf, BOOL, BYTES_U8, bytesOf, canAdaptDynFuncTo, canConvertToDyn, canExitIslandToType, canMarshalIntoIsland, canMarshalTypedFuncIntoIsland, CHILD_T, CHILDSTREAM_T, DGRAMSOCK_T, DYN, DYN_HANDLE_KINDS, F64, FSWATCHER_T, HTTP2SESSION_T, HTTP2STREAM_T, HTTPCLIENTREQ_T, HTTPREQ_T, HTTPRES_T, islandPromisePayloadTag, isJsonSafeType, isRefCounted, isSupportedIndexValue, isSupportedMapKey, isSupportedMapValue, isSupportedSetElem, isUnitType, jsOpResultKind, JSVAL, NETSERVER_T, NETSOCKET_T, PROCSTREAM_T, REF_TRUTHY_KINDS, REGEX, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, SEARCH_PARAMS_T, SECURECTX_T, SPAWNRES_T, STATS_T, STRING, SYMBOL_T, TESTCTX_T, typeEquals, typeKey, unionFuncSetArmsOk, URL_T, VOID } from "./nodes.js";
2
2
  /** Per-method signature for strIntrinsic: `argTypes` lists every argument
3
3
  * position (optional ones included); `minArgs` is how many may be omitted
4
4
  * from the end (backends fill the documented defaults). Exported for the
@@ -63,6 +63,9 @@ export const LIB_FN_SIGS = {
63
63
  "json.parse": { argTypes: [STRING], result: DYN },
64
64
  "dyn.keySet": { argTypes: [DYN, STRING, DYN], result: VOID },
65
65
  "dyn.iterPack": { argTypes: [DYN, STRING], result: DYN },
66
+ "dyn.arrLen": { argTypes: [DYN], result: F64 },
67
+ "dyn.arrAt": { argTypes: [DYN, F64], result: DYN },
68
+ "dyn.hasKey": { argTypes: [DYN, STRING], result: BOOL },
66
69
  "dyn.toString": { argTypes: [DYN, STRING, STRING], result: STRING },
67
70
  "dyn.defineProps": { argTypes: [DYN, DYN], result: DYN },
68
71
  "dyn.typeof": { argTypes: [DYN], result: STRING },
@@ -173,7 +176,7 @@ export const LIB_FN_SIGS = {
173
176
  "num.fromString": { argTypes: [STRING], result: F64 },
174
177
  "num.isNaN": { argTypes: [F64], result: BOOL },
175
178
  "str.encodeUriComponent": { argTypes: [STRING], result: STRING },
176
- // The base64 globals: the argument is a DOM value (WebIDL ToString
179
+ // The base64 globals: the argument is a dyn value (WebIDL ToString
177
180
  // runs in the runtime); the zero-argument form always throws.
178
181
  "str.atob": { argTypes: [DYN], result: STRING },
179
182
  "str.btoa": { argTypes: [DYN], result: STRING },
@@ -230,7 +233,7 @@ export const LIB_FN_SIGS = {
230
233
  // node:querystring. qs.parse's result is the call site's ParsedUrlQuery
231
234
  // dictionary record (VOID is the networkInterfaces sentinel — the
232
235
  // libCall case checks the structure); qs.stringify's object argument
233
- // is a DOM value (the frontend dynFroms typed records).
236
+ // is a dyn value (the frontend dynFroms typed records).
234
237
  "qs.parse": { argTypes: [STRING, STRING, STRING, F64], result: VOID },
235
238
  "qs.stringify": { argTypes: [DYN, STRING, STRING], result: STRING },
236
239
  "qs.escape": { argTypes: [STRING], result: STRING },
@@ -438,6 +441,9 @@ export const LIB_FN_SIGS = {
438
441
  // program-dependent (checked below); header pairs arrive flat.
439
442
  "http.request": { argTypes: [STRING, F64, STRING, STRING, F64, arrayOf(STRING), BOOL], result: HTTPCLIENTREQ_T },
440
443
  "http.requestCb": { argTypes: [STRING, F64, STRING, STRING, F64, arrayOf(STRING), BOOL, null], result: HTTPCLIENTREQ_T },
444
+ "http.agentNew": { argTypes: [BOOL, BOOL, F64, F64, F64, F64, F64], result: DYN },
445
+ "http.requestAgent": { argTypes: [STRING, F64, STRING, STRING, F64, arrayOf(STRING), BOOL, DYN], result: HTTPCLIENTREQ_T },
446
+ "http.requestAgentCb": { argTypes: [STRING, F64, STRING, STRING, F64, arrayOf(STRING), BOOL, DYN, null], result: HTTPCLIENTREQ_T },
441
447
  "http.requestUrl": { argTypes: [STRING, STRING, BOOL], result: HTTPCLIENTREQ_T },
442
448
  "http.requestUrlCb": { argTypes: [STRING, STRING, BOOL, null], result: HTTPCLIENTREQ_T },
443
449
  "net.sockOnReadable": { argTypes: [NETSOCKET_T, null, BOOL], result: VOID },
@@ -446,6 +452,13 @@ export const LIB_FN_SIGS = {
446
452
  // placeholder the special case overrides).
447
453
  "net.sockRead": { argTypes: [NETSOCKET_T, F64], result: VOID },
448
454
  "net.sockUnshift": { argTypes: [NETSOCKET_T, BYTES_U8], result: VOID },
455
+ "net.sockPause": { argTypes: [NETSOCKET_T], result: NETSOCKET_T },
456
+ "net.sockResume": { argTypes: [NETSOCKET_T], result: NETSOCKET_T },
457
+ "net.sockSetNoDelay": { argTypes: [NETSOCKET_T, BOOL], result: NETSOCKET_T },
458
+ "net.sockDestroySoon": { argTypes: [NETSOCKET_T], result: VOID },
459
+ "net.sockBytesWritten": { argTypes: [NETSOCKET_T], result: F64 },
460
+ "net.sockReadable": { argTypes: [NETSOCKET_T], result: BOOL },
461
+ "net.sockOnFinish": { argTypes: [NETSOCKET_T, { kind: "func", params: [], ret: VOID }], result: VOID },
449
462
  "net.serverEmitConnection": { argTypes: [NETSERVER_T, NETSOCKET_T], result: VOID },
450
463
  // tls/https: cert/key/ca PEM arguments are strings OR Buffers (null =
451
464
  // both accepted; the emitter passes data+len either way).
@@ -459,6 +472,10 @@ export const LIB_FN_SIGS = {
459
472
  "tls.createServerDynCb": { argTypes: [DYN, null], result: NETSERVER_T },
460
473
  "https.createServerDyn": { argTypes: [DYN], result: NETSERVER_T },
461
474
  "https.createServerDynCb": { argTypes: [DYN, null], result: NETSERVER_T },
475
+ "http2.createSecureServerReq": { argTypes: [null, null, null], result: NETSERVER_T },
476
+ "http2.createSecureServerH2Req": { argTypes: [null, null, null], result: NETSERVER_T },
477
+ "http2.createSecureServerDyn": { argTypes: [DYN], result: NETSERVER_T },
478
+ "http2.createSecureServerDynCb": { argTypes: [DYN, null], result: NETSERVER_T },
462
479
  // tls.connect(port, host, opts[, cb]) — port -1 / host "" read the
463
480
  // options record; the callback fires post-handshake (secureConnect).
464
481
  "tls.connect": { argTypes: [F64, STRING, DYN], result: NETSOCKET_T },
@@ -473,6 +490,11 @@ export const LIB_FN_SIGS = {
473
490
  "tls.createSecureContext": { argTypes: [null, null], result: SECURECTX_T },
474
491
  "tls.createSecureContextDyn": { argTypes: [DYN], result: SECURECTX_T },
475
492
  "tls.caCertsChk": { argTypes: [DYN, STRING], result: VOID },
493
+ // The CA-store introspection unit (scr_tls_ca.c): per-type cached PEM
494
+ // string arrays and the default-set replacement.
495
+ "tlsca.get": { argTypes: [STRING], result: arrayOf(STRING) },
496
+ "tlsca.root": { argTypes: [], result: arrayOf(STRING) },
497
+ "tlsca.set": { argTypes: [arrayOf(STRING)], result: VOID },
476
498
  "https.createServer": { argTypes: [null, null, null], result: NETSERVER_T },
477
499
  // http2's allowHTTP1 compatibility server (divergence 57): cert/key
478
500
  // like tls.createServer; the 'request' handler arrives separately via
@@ -560,6 +582,8 @@ export const LIB_FN_SIGS = {
560
582
  "http.requestConnCb": { argTypes: [null, STRING, STRING, F64, arrayOf(STRING), BOOL, null], result: HTTPCLIENTREQ_T },
561
583
  "https.request": { argTypes: [STRING, F64, STRING, STRING, F64, arrayOf(STRING), BOOL, BOOL, null], result: HTTPCLIENTREQ_T },
562
584
  "https.requestCb": { argTypes: [STRING, F64, STRING, STRING, F64, arrayOf(STRING), BOOL, BOOL, null, null], result: HTTPCLIENTREQ_T },
585
+ "https.requestAgent": { argTypes: [STRING, F64, STRING, STRING, F64, arrayOf(STRING), BOOL, BOOL, null, DYN], result: HTTPCLIENTREQ_T },
586
+ "https.requestAgentCb": { argTypes: [STRING, F64, STRING, STRING, F64, arrayOf(STRING), BOOL, BOOL, null, DYN, null], result: HTTPCLIENTREQ_T },
563
587
  // The requestFn binding's runtime-secure rows: https.request's shape
564
588
  // with the leading `secure` bool.
565
589
  "https.requestFn": { argTypes: [BOOL, STRING, F64, STRING, STRING, F64, arrayOf(STRING), BOOL, BOOL, null], result: HTTPCLIENTREQ_T },
@@ -647,7 +671,7 @@ export const LIB_FN_SIGS = {
647
671
  "buffer.isEncoding": { argTypes: [STRING], result: BOOL },
648
672
  "buffer.concatLen": { argTypes: [arrayOf(BYTES_U8), F64], result: BYTES_U8 },
649
673
  // The checked-dynamic compare/equals validators (Node's argument
650
- // ladders over DOM-boxed invalid-input probes).
674
+ // ladders over dyn-boxed invalid-input probes).
651
675
  "buffer.compareChk": { argTypes: [DYN, DYN], result: F64 },
652
676
  "bytes.equalsChk": { argTypes: [BYTES_U8, DYN], result: BOOL },
653
677
  "bytes.compareChk": { argTypes: [BYTES_U8, DYN, DYN, DYN, DYN, DYN], result: F64 },
@@ -726,7 +750,7 @@ export const LIB_FN_SIGS = {
726
750
  // Receiver (any error-hierarchy object) and the program-dependent
727
751
  // `string | undefined` result are checked in the libCall case.
728
752
  "error.code": { argTypes: [null], result: VOID },
729
- // DOMException: construction takes the two DOM args (WebIDL's
753
+ // DOMException: construction takes the two dyn args (WebIDL's
730
754
  // resolution runs in the runtime); the %DOMException result is a
731
755
  // program-dependent object type, checked in the libCall case. The
732
756
  // read surface takes the %DOMException receiver (a null slot — the
@@ -877,7 +901,7 @@ export const LIB_FN_SIGS = {
877
901
  // Symbol strict equality (pointer identity; scr_symbol.c).
878
902
  "assert.eqSym": { argTypes: [{ kind: "symbol" }, { kind: "symbol" }, BOOL, BOOL, STRING, BOOL], result: VOID },
879
903
  // The equality quartet over checked-dynamic operands (the frontend
880
- // boxes a static side into the DOM first).
904
+ // boxes a static side into the checked-dynamic tree first).
881
905
  "assert.eqDyn": { argTypes: [DYN, DYN, BOOL, BOOL, STRING, BOOL], result: VOID },
882
906
  // The throws(fn, {shape}) accumulator: begin/slot calls never throw;
883
907
  // shapeEnd throws the Comparison diff. The error slot is the
@@ -957,7 +981,10 @@ export const LIB_FN_SIGS = {
957
981
  "dc.tcTraceSync": { argTypes: [F64, DYN, DYN, DYN, DYN], result: DYN },
958
982
  "dc.tcTraceCallback": { argTypes: [F64, DYN, F64, DYN, DYN, DYN], result: DYN },
959
983
  "dc.tcTracePromise": { argTypes: [F64, DYN, DYN, DYN, DYN], result: { kind: "promise", inner: DYN } },
960
- "process.onUnhandledRejection": { argTypes: [DYN], result: VOID },
984
+ "process.onUnhandledRejection": { argTypes: [DYN, BOOL], result: VOID },
985
+ "process.offUnhandledRejection": { argTypes: [DYN], result: VOID },
986
+ "process.onRejectionHandled": { argTypes: [DYN, BOOL], result: VOID },
987
+ "process.offRejectionHandled": { argTypes: [DYN], result: VOID },
961
988
  "process.onWarning": { argTypes: [DYN], result: VOID },
962
989
  "process.offWarning": { argTypes: [DYN], result: VOID },
963
990
  "process.emitWarning": { argTypes: [DYN], result: VOID },
@@ -1183,7 +1210,7 @@ export function validateModule(mod) {
1183
1210
  // Unit kinds (undefinedT/nullT) exist only as union arms — a BARE
1184
1211
  // unit field is as malformed as a void one. dyn fields are VALID
1185
1212
  // (`[string, unknown]` entries tuples, `{ v: unknown }` records):
1186
- // the slot holds a DOM value with the overflow map's plumbing.
1213
+ // the slot holds a dyn value with the overflow map's plumbing.
1187
1214
  if (f.type.kind === "void" || f.type.kind === "jsval" ||
1188
1215
  isUnitType(f.type)) {
1189
1216
  errors.push({ message: `record ${rec.id}: field "${f.name}" is ${f.type.kind}`, loc: noLoc });
@@ -1525,7 +1552,10 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
1525
1552
  // Symbol identity IS pointer identity (the frontend's rule).
1526
1553
  e.left.type.kind === "symbol" ||
1527
1554
  e.left.type.kind === "bytes" ||
1528
- e.left.type.kind === "promise")) {
1555
+ e.left.type.kind === "promise" ||
1556
+ // Runtime handles are objects to === (one handle per socket/
1557
+ // request — pointer identity is JS's object equality).
1558
+ DYN_HANDLE_KINDS.has(e.left.type.kind))) {
1529
1559
  // Reference identity: both operands must be the same ref type.
1530
1560
  if (!typeEquals(e.left.type, e.right.type)) {
1531
1561
  err(`bin ${e.op} on references: operand types differ`, e.loc);
@@ -1741,10 +1771,10 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
1741
1771
  }
1742
1772
  break;
1743
1773
  }
1744
- // A dyn (DOM) chain (`rawName?.match(re)` on a JSON.parse result):
1774
+ // A dyn (dyn) chain (`rawName?.match(re)` on a JSON.parse result):
1745
1775
  // the nullish test reads the node's kind tag; the body is the
1746
1776
  // validated dynamic dispatch, its result converted back into the
1747
- // DOM (dynFrom) — so body and result are dyn, or void for
1777
+ // dyn (dynFrom) — so body and result are dyn, or void for
1748
1778
  // statement-position chains.
1749
1779
  if (e.receiver.type.kind === "dyn") {
1750
1780
  if (activeChains.has(e.id))
@@ -1789,7 +1819,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
1789
1819
  break;
1790
1820
  }
1791
1821
  expectType(e.body, e.type, "optChain body");
1792
- // dyn results carry the unit path as the undefined DOM value; every
1822
+ // dyn results carry the unit path as the undefined dyn value; every
1793
1823
  // other value result needs an undefined arm to land on.
1794
1824
  if (e.type.kind !== "dyn") {
1795
1825
  const rdef = e.type.kind === "union" ? unions.get(e.type.unionId) : undefined;
@@ -1821,7 +1851,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
1821
1851
  }
1822
1852
  // The CHECKED-DYNAMIC form: the runtime kind decides (the
1823
1853
  // emitters' scr_dyn_is_nullish arm) — left, right, and result
1824
- // all live in the DOM.
1854
+ // all live in the checked-dynamic tree.
1825
1855
  if (e.left.type.kind === "dyn") {
1826
1856
  if (e.type.kind !== "dyn")
1827
1857
  err("dyn nullish must answer dyn", e.loc);
@@ -1862,6 +1892,21 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
1862
1892
  err(`orDefault left references unknown union ${e.left.type.unionId}`, e.loc);
1863
1893
  break;
1864
1894
  }
1895
+ // Retagged shape: the truthy side is a call to the named helper, so
1896
+ // the arm count is free and the type rule is the helper's signature.
1897
+ if (e.retag !== undefined) {
1898
+ const helper = functions.get(e.retag);
1899
+ if (!helper) {
1900
+ err(`orDefault retag calls undeclared function "${e.retag}"`, e.loc);
1901
+ }
1902
+ else if (helper.params.length !== 1 || !typeEquals(helper.params[0].type, e.left.type)) {
1903
+ err(`orDefault retag ${e.retag} must take exactly the left union`, e.loc);
1904
+ }
1905
+ else if (!typeEquals(callSiteReturnType(helper), e.type)) {
1906
+ err(`orDefault retag ${e.retag} must return the node's type`, e.loc);
1907
+ }
1908
+ break;
1909
+ }
1865
1910
  const rest = def.arms.filter((a) => !isUnitType(a));
1866
1911
  if (rest.length !== 1 || !typeEquals(e.type, rest[0])) {
1867
1912
  err("orDefault type must be the left union's single non-unit arm", e.loc);
@@ -2398,7 +2443,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
2398
2443
  }
2399
2444
  });
2400
2445
  // Result func type must match the target's signature. A VARIADIC
2401
- // (rest-marked) type hides one synthetic trailing DOM-array param
2446
+ // (rest-marked) type hides one synthetic trailing dyn-array param
2402
2447
  // in the lifted function (the thunk fills it) — the type's
2403
2448
  // declared params plus that one must match.
2404
2449
  if (e.type.kind === "func") {
@@ -2771,7 +2816,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
2771
2816
  expectType(e.obj, { kind: "record", shapeId: e.shapeId }, "recordKeyGet receiver");
2772
2817
  expectType(e.key, STRING, "recordKeyGet key");
2773
2818
  // Every reachable value must SURFACE as the result type: identity,
2774
- // an arm of a union result, or (dyn results) a DOM conversion —
2819
+ // an arm of a union result, or (dyn results) a dyn conversion —
2775
2820
  // the frontend's recordKeyResultOk mirror. overflowOnly reads (a
2776
2821
  // literal key naming no declared field) skip the declared check
2777
2822
  // and require the overflow to exist.
@@ -2812,7 +2857,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
2812
2857
  if (e.type.kind !== "dyn")
2813
2858
  err(`dynFrom must be dyn-typed, got ${e.type.kind}`, e.loc);
2814
2859
  // A bare unit literal is legal exactly here (like unionWrap): the
2815
- // DOM has first-class undefined/null values.
2860
+ // dyn has first-class undefined/null values.
2816
2861
  if (e.value.kind === "unitLit") {
2817
2862
  const want = e.value.unit === "undefined" ? "undefinedT" : "nullT";
2818
2863
  if (e.value.type.kind !== want) {
@@ -2821,19 +2866,19 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
2821
2866
  break;
2822
2867
  }
2823
2868
  checkExpr(e.value);
2824
- // Domain: JSON-safe, bytes<u8> (the DOM's bytes kind — payload
2869
+ // Domain: JSON-safe, bytes<u8> (the checked-dynamic tree's bytes kind — payload
2825
2870
  // copied), an undefined-armed union of JSON-safe arms (the
2826
- // undefined arm becomes the undefined DOM value), or a BOXABLE
2827
- // function type (the DOM's function kind — canConvertToDyn folds
2871
+ // undefined arm becomes the undefined dyn value), or a BOXABLE
2872
+ // function type (the checked-dynamic tree's function kind — canConvertToDyn folds
2828
2873
  // all four in).
2829
2874
  const vt = e.value.type;
2830
2875
  if (!canConvertToDyn(vt, (id) => records.get(id), (id) => unions.get(id))) {
2831
- err(`dynFrom of non-DOM-convertible type ${vt.kind}`, e.loc);
2876
+ err(`dynFrom of non-dyn-convertible type ${vt.kind}`, e.loc);
2832
2877
  }
2833
2878
  break;
2834
2879
  }
2835
2880
  case "dynFromJsval": {
2836
- // The jsval→DOM crossing: exactly a jsval operand into a dyn
2881
+ // The jsval→dyn crossing: exactly a jsval operand into a dyn
2837
2882
  // result (the by-reference island wrap; scalars normalize at
2838
2883
  // runtime).
2839
2884
  checkExpr(e.value);
@@ -3013,7 +3058,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
3013
3058
  break;
3014
3059
  }
3015
3060
  case "caughtToDyn": {
3016
- // The caught snapshot converting to a dyn DOM value (an unknown
3061
+ // The caught snapshot converting to a dyn value (an unknown
3017
3062
  // slot): operand caught, result dyn — the runtime dispatch handles
3018
3063
  // every payload kind, so nothing else constrains it.
3019
3064
  checkExpr(e.value);
@@ -3428,9 +3473,14 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
3428
3473
  }
3429
3474
  break;
3430
3475
  }
3431
- if (e.fn === "http.requestCb" || e.fn === "http.requestUrlCb" || e.fn === "http.clientOnResponse") {
3476
+ if (e.fn === "http.requestCb" || e.fn === "http.requestUrlCb" || e.fn === "http.clientOnResponse" ||
3477
+ e.fn === "http.requestAgentCb" || e.fn === "https.requestAgentCb") {
3432
3478
  // The response listener: void, no params or exactly (res: httpReq).
3433
- const cbT = e.args[e.fn === "http.requestCb" ? 7 : e.fn === "http.requestUrlCb" ? 3 : 1]?.type;
3479
+ const cbT = e.args[e.fn === "http.requestCb" ? 7
3480
+ : e.fn === "http.requestUrlCb" ? 3
3481
+ : e.fn === "http.requestAgentCb" ? 8
3482
+ : e.fn === "https.requestAgentCb" ? 10
3483
+ : 1]?.type;
3434
3484
  let ok = cbT?.kind === "func" && cbT.ret.kind === "void" && cbT.params.length <= 1;
3435
3485
  if (ok && cbT?.kind === "func" && cbT.params.length === 1) {
3436
3486
  ok = cbT.params[0].kind === "httpReq";
@@ -4259,7 +4309,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
4259
4309
  }
4260
4310
  // The value's STATIC type drives the emitted serializer — it must be
4261
4311
  // JSON-safe (the frontend rejects the rest with a specific message).
4262
- // A dyn ROOT is the one non-static shape allowed: the runtime's DOM
4312
+ // A dyn ROOT is the one non-static shape allowed: the runtime's dyn
4263
4313
  // walker serializes it (scr_dyn_format_j), no emitted serializer.
4264
4314
  if (e.value.type.kind !== "dyn" &&
4265
4315
  !isJsonSafeType(e.value.type, (id) => records.get(id), (id) => unions.get(id))) {
@@ -4272,24 +4322,24 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
4272
4322
  expectType(e.value, DYN, "dynCheck operand");
4273
4323
  // The target drives the emitted validator/builder: non-dyn,
4274
4324
  // non-void, JSON-representable (closures/class instances can never
4275
- // be found inside a JSON DOM — the frontend rejects those casts).
4325
+ // be found inside a JSON dyn — the frontend rejects those casts).
4276
4326
  // Bare undefined-armed unions of JSON-safe arms are additionally
4277
- // valid: the DOM holds a first-class undefined value (overflow
4327
+ // valid: the checked-dynamic tree holds a first-class undefined value (overflow
4278
4328
  // reads), which matches exactly the undefined arm.
4279
4329
  const jsonOk = (t) => isJsonSafeType(t, (id) => records.get(id), (id) => unions.get(id));
4280
4330
  const undefArmedOk = e.type.kind === "union" &&
4281
4331
  (unions.get(e.type.unionId)?.arms.every((a) => a.kind === "undefinedT" || jsonOk(a)) ??
4282
4332
  false);
4283
- // bytes<u8> targets extract the DOM's bytes kind (a copy).
4333
+ // bytes<u8> targets extract the checked-dynamic tree's bytes kind (a copy).
4284
4334
  const bytesOk = e.type.kind === "bytes" && e.type.elem === "u8";
4285
- // The %Error root extracts the DOM's error encoding (the "%error"
4335
+ // The %Error root extracts the checked-dynamic tree's error encoding (the "%error"
4286
4336
  // marker object caughtToDyn builds) as a fresh runtime error.
4287
4337
  const errorOk = e.type.kind === "object" && e.type.className === "%Error";
4288
- // ADAPTABLE function targets unwrap or wrap the DOM's function
4338
+ // ADAPTABLE function targets unwrap or wrap the checked-dynamic tree's function
4289
4339
  // kind (the checked-dynamic function boundary, nodes.ts).
4290
4340
  const funcOk = e.type.kind === "func" &&
4291
4341
  canAdaptDynFuncTo(e.type, (id) => records.get(id), (id) => unions.get(id));
4292
- // Runtime HANDLE targets unwrap the DOM's handle kind by tag (a
4342
+ // Runtime HANDLE targets unwrap the checked-dynamic tree's handle kind by tag (a
4293
4343
  // retained reference, no copy — DYN_HANDLE_KINDS).
4294
4344
  const handleOk = DYN_HANDLE_KINDS.has(e.type.kind);
4295
4345
  if (!jsonOk(e.type) && !undefArmedOk && !bytesOk && !errorOk && !funcOk && !handleOk) {
@@ -4512,7 +4562,11 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
4512
4562
  // exactly what it produces.
4513
4563
  if (src.kind !== "bytes" &&
4514
4564
  src.kind !== "url" &&
4515
- src.kind !== "dyn" && // DOM values deep-copy in (data kinds; the runtime throws on boxes)
4565
+ src.kind !== "dyn" && // dyn values deep-copy in (data kinds; the runtime throws on boxes)
4566
+ // A STATIC promise crosses as a real engine thenable when its
4567
+ // fulfillment is in the reverse bridge's payload domain
4568
+ // (scr_jsval_from_promise — the async-callback return bridge).
4569
+ !(src.kind === "promise" && islandPromisePayloadTag(src.inner) !== null) &&
4516
4570
  !canMarshalIntoIsland(src, (id) => records.get(id), (id) => unions.get(id)) &&
4517
4571
  !canMarshalTypedFuncIntoIsland(src, (id) => records.get(id), (id) => unions.get(id))) {
4518
4572
  err(`jsMarshal of unmarshalable type ${src.kind}`, e.loc);
@@ -4570,11 +4624,15 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
4570
4624
  case "jsBridgePromise": {
4571
4625
  checkExpr(e.value);
4572
4626
  expectType(e.value, JSVAL, "jsBridgePromise operand");
4573
- // The settled engine value crosses as a HANDLE (or not at all):
4574
- // the bridge never converts payloads — typed uses exit later.
4627
+ // The settled engine value crosses as a HANDLE (or not at all) —
4628
+ // plus the ONE converting payload: an `any[]`-declared
4629
+ // fulfillment exits Array.isArray-gated by reference AT THE
4630
+ // SETTLE (SCR_ISLP_JSVAL_ARR); every other typed use exits later.
4575
4631
  if (e.type.kind !== "promise" ||
4576
- (e.type.inner.kind !== "jsval" && e.type.inner.kind !== "void")) {
4577
- err("jsBridgePromise must be a promise of jsval or void", e.loc);
4632
+ (e.type.inner.kind !== "jsval" &&
4633
+ e.type.inner.kind !== "void" &&
4634
+ !(e.type.inner.kind === "array" && e.type.inner.elem.kind === "jsval"))) {
4635
+ err("jsBridgePromise must be a promise of jsval, void, or jsval-element array", e.loc);
4578
4636
  }
4579
4637
  break;
4580
4638
  }
@@ -4863,8 +4921,8 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
4863
4921
  break;
4864
4922
  case "throw":
4865
4923
  checkExpr(s.value);
4866
- // dyn throws are allowed: the DOM node rides the REF cell arm by
4867
- // reference (the JS-lane `throw err` of a DOM argument).
4924
+ // dyn throws are allowed: the dyn node rides the REF cell arm by
4925
+ // reference (the JS-lane `throw err` of a dyn argument).
4868
4926
  if (s.value.type.kind === "void" || s.value.type.kind === "caught") {
4869
4927
  err(`throw of a ${s.value.type.kind} value`, s.loc);
4870
4928
  }