@scriptc/compiler 0.0.11 → 0.0.12

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 +12 -9
  2. package/ambient/scriptc.d.ts +2 -2
  3. package/dist/backend/cc.d.ts +2 -2
  4. package/dist/backend/emission/emit-async.js +1 -1
  5. package/dist/backend/emission/emit-exprs.js +97 -52
  6. package/dist/backend/emission/emit-exprs.js.map +1 -1
  7. package/dist/backend/emission/emit-island.js +1 -1
  8. package/dist/backend/emission/emit-shapes.js +1 -1
  9. package/dist/backend/emission/emit-walkers.d.ts +14 -14
  10. package/dist/backend/emission/emit-walkers.js +44 -44
  11. package/dist/backend/emission/emit-walkers.js.map +1 -1
  12. package/dist/backend/emission/emitter.d.ts +3 -3
  13. package/dist/backend/emission/emitter.js +8 -8
  14. package/dist/backend/emission/may-throw.js +1 -1
  15. package/dist/backend/llvm/dyn.d.ts +10 -10
  16. package/dist/backend/llvm/dyn.js +26 -26
  17. package/dist/backend/llvm/dyn.js.map +1 -1
  18. package/dist/backend/llvm/emitter.js +97 -43
  19. package/dist/backend/llvm/emitter.js.map +1 -1
  20. package/dist/backend/llvm/shapes.js +1 -1
  21. package/dist/backend/llvm/walkers.js +2 -2
  22. package/dist/backend/llvm/walkers.js.map +1 -1
  23. package/dist/diagnostics/diagnostic.d.ts +1 -1
  24. package/dist/diagnostics/diagnostic.js +4 -3
  25. package/dist/diagnostics/diagnostic.js.map +1 -1
  26. package/dist/frontend/lowering/lib-boundary.js +5 -5
  27. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  28. package/dist/frontend/lowering/lower-assert.js +12 -12
  29. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  30. package/dist/frontend/lowering/lower-builtins.d.ts +7 -7
  31. package/dist/frontend/lowering/lower-builtins.js +92 -31
  32. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  33. package/dist/frontend/lowering/lower-calls.d.ts +4 -4
  34. package/dist/frontend/lowering/lower-calls.js +66 -66
  35. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  36. package/dist/frontend/lowering/lower-classes.js +31 -5
  37. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  38. package/dist/frontend/lowering/lower-containers.d.ts +5 -5
  39. package/dist/frontend/lowering/lower-containers.js +19 -19
  40. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  41. package/dist/frontend/lowering/lower-emitter.js +2 -2
  42. package/dist/frontend/lowering/lower-emitter.js.map +1 -1
  43. package/dist/frontend/lowering/lower-exprs.d.ts +7 -7
  44. package/dist/frontend/lowering/lower-exprs.js +158 -112
  45. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  46. package/dist/frontend/lowering/lower-inspect.js +5 -5
  47. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  48. package/dist/frontend/lowering/lower-island.js +12 -3
  49. package/dist/frontend/lowering/lower-island.js.map +1 -1
  50. package/dist/frontend/lowering/lower-modules.js +16 -16
  51. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  52. package/dist/frontend/lowering/lower-namespaces.d.ts +11 -1
  53. package/dist/frontend/lowering/lower-namespaces.js +41 -6
  54. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  55. package/dist/frontend/lowering/lower-server.js +11 -11
  56. package/dist/frontend/lowering/lower-server.js.map +1 -1
  57. package/dist/frontend/lowering/lower-stmts.d.ts +1 -1
  58. package/dist/frontend/lowering/lower-stmts.js +191 -30
  59. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  60. package/dist/frontend/lowering/lower-stream.js +66 -22
  61. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  62. package/dist/frontend/lowering/lowerer.d.ts +10 -10
  63. package/dist/frontend/lowering/lowerer.js +51 -37
  64. package/dist/frontend/lowering/lowerer.js.map +1 -1
  65. package/dist/frontend/lowering/surfaces.js +2 -2
  66. package/dist/frontend/lowering/surfaces.js.map +1 -1
  67. package/dist/frontend/program.js +1 -1
  68. package/dist/frontend/shared.js +7 -7
  69. package/dist/frontend/shared.js.map +1 -1
  70. package/dist/frontend/types.d.ts +2 -2
  71. package/dist/frontend/types.js +15 -15
  72. package/dist/frontend/types.js.map +1 -1
  73. package/dist/index.js +38 -7
  74. package/dist/index.js.map +1 -1
  75. package/dist/ir/nodes.d.ts +110 -98
  76. package/dist/ir/nodes.js +48 -21
  77. package/dist/ir/nodes.js.map +1 -1
  78. package/dist/ir/validate.js +44 -34
  79. package/dist/ir/validate.js.map +1 -1
  80. package/dist/library/int-infer.js +13 -0
  81. package/dist/library/int-infer.js.map +1 -1
  82. package/dist/library/profile.d.ts +8 -6
  83. package/dist/library/profile.js.map +1 -1
  84. package/dist/library/sidecar-validate.js +1 -1
  85. package/dist/library/sidecar-validate.js.map +1 -1
  86. package/dist/library/sidecar.d.ts +1 -1
  87. package/dist/library/sidecar.js +20 -7
  88. package/dist/library/sidecar.js.map +1 -1
  89. package/package.json +2 -2
  90. package/surface-manifest.json +4 -4
@@ -246,7 +246,7 @@ declare var process: {
246
246
  on(event: "SIGINT" | "SIGTERM", listener: () => void): void;
247
247
  on(event: "exit", listener: (code: number) => void): void;
248
248
  /* 'warning' — Node's process-warning channel: listeners receive the
249
- * warning Error (as a DOM value); emitWarning and the runtime's
249
+ * warning Error (as a dyn value); emitWarning and the runtime's
250
250
  * deprecation sites dispatch synchronously (SEMANTICS.md). */
251
251
  on(event: "warning", listener: (warning: Error & { code?: string }) => void): void;
252
252
  /* 'unhandledRejection' — dispatched per never-observed rejection at
@@ -266,7 +266,7 @@ declare var process: {
266
266
  emitWarning(warning: string | Error, ...args: any[]): void;
267
267
  };
268
268
 
269
- /* ── globals a real CLI's sources reference (all @types/node or DOM-lib
269
+ /* ── globals a real CLI's sources reference (all @types/node or dyn-lib
270
270
  * territory; the fallback declares the slice so projects PREFLIGHT and
271
271
  * every reached use lands on the SC2020 fence — or a real lowering where
272
272
  * one exists — instead of "Cannot find name"). With @types/node these
@@ -341,7 +341,7 @@ declare var AbortController: { new (): AbortController };
341
341
  * them below): base64 → binary string and back, Latin-1 domain like the
342
342
  * WHATWG originals. The parameter is `unknown` because WebIDL ToStrings
343
343
  * whatever arrives (Node's atob(null) decodes "null") — the coercion
344
- * runs in the runtime over the DOM kind, and the Node suite exercises
344
+ * runs in the runtime over the dyn kind, and the Node suite exercises
345
345
  * it; malformed input throws the catchable DOMException
346
346
  * InvalidCharacterError, the zero-argument call Node's TypeError
347
347
  * [ERR_MISSING_ARGS]. */
@@ -711,7 +711,7 @@ declare module "timers/promises" {
711
711
  * traceSync/traceCallback run Node's publish choreography in the runtime
712
712
  * (context defaults to a fresh {}); tracePromise is declared (the member
713
713
  * exists in Node) but fences at the call site — the traced function's
714
- * promise cannot cross the DOM boundary yet. */
714
+ * promise cannot cross the checked-dynamic tree boundary yet. */
715
715
  declare module "node:diagnostics_channel" {
716
716
  export type ChannelListener = (message: unknown, name: string) => void;
717
717
  export interface Channel {
@@ -814,15 +814,18 @@ declare var performance: import("node:perf_hooks").Performance;
814
814
  * Dynamic specifiers fence: a compiled binary's module graph is fixed at
815
815
  * build time. builtinModules is the baked Node v24 list (a fresh
816
816
  * mutable array per read where Node ships one frozen singleton);
817
- * isBuiltin and syncBuiltinESMExports fence per site. Bare "module"
818
- * stays a package specifier (an npm package by that name exists); only
819
- * the node: spelling names the builtin. */
817
+ * isBuiltin and syncBuiltinESMExports fence per site. Both spellings
818
+ * name the builtin, like in Node (the builtin wins over the npm package
819
+ * named "module" for the bare specifier there too). */
820
820
  declare module "node:module" {
821
821
  export function createRequire(filename: string | URL): (id: string) => unknown;
822
822
  export const builtinModules: string[];
823
823
  export function isBuiltin(moduleName: string): boolean;
824
824
  export function syncBuiltinESMExports(): void;
825
825
  }
826
+ declare module "module" {
827
+ export * from "node:module";
828
+ }
826
829
  /* import.meta: module-loader metadata with no value representation —
827
830
  * every read fences (SC1090) EXCEPT as createRequire's base, where it
828
831
  * only NAMES the containing file (import.meta.url, import.meta.filename,
@@ -2523,7 +2526,7 @@ declare module "http2" {
2523
2526
  setTimeout(msecs: number, callback?: () => void): void;
2524
2527
  ping(callback: (err: Error | null, duration: number, payload: Uint8Array) => void): boolean;
2525
2528
  /* The settings surface rides the checked-dynamic machinery (records
2526
- * cross as DOM values — the suite's mustCall listeners are dyn). */
2529
+ * cross as dyn values — the suite's mustCall listeners are dyn). */
2527
2530
  settings(settings?: any, callback?: any): void;
2528
2531
  readonly localSettings: any;
2529
2532
  readonly remoteSettings: any;
@@ -2786,7 +2789,7 @@ declare module "node:tty" {
2786
2789
  declare module "async_hooks" {
2787
2790
  /* AsyncLocalStorage: fiber-carried context snapshots — run/getStore/
2788
2791
  * exit/enterWith/disable lower onto the runtime's active-slot machinery
2789
- * (als.* libCalls); values cross as DOM values. */
2792
+ * (als.* libCalls); values cross as dyn values. */
2790
2793
  export class AsyncLocalStorage<T = any> {
2791
2794
  constructor();
2792
2795
  run<R>(store: T, callback: (...args: any[]) => R, ...args: any[]): R;
@@ -1,12 +1,12 @@
1
1
  /* scriptc's shipped declarations — the ALWAYS-SHIPPED CORE. Programs
2
2
  * compile against the REAL TypeScript standard library (lib.es2023, no
3
- * DOM, no @types): the checker sees the full standard surface, and the
3
+ * dyn, no @types): the checker sees the full standard surface, and the
4
4
  * LOWERER is the scope fence — any reached use of standard-library surface
5
5
  * without a lowering is a SC2020 diagnostic at its use site. This file
6
6
  * declares only what the es2023 lib does not:
7
7
  *
8
8
  * 1. scriptc's own primitives (comptime, __island_eval).
9
- * 2. setTimeout/clearTimeout and the Timeout handle (Node/DOM territory the
9
+ * 2. setTimeout/clearTimeout and the Timeout handle (Node/dyn territory the
10
10
  * lib files don't cover; plain declarations, so with @types/node present
11
11
  * they MERGE as overloads instead of colliding — the Timeout handle maps
12
12
  * to the numeric timer id either way, and .unref()/.ref()/.hasRef() are
@@ -65,12 +65,12 @@ export interface CcOptions {
65
65
  dynInvoke?: boolean;
66
66
  /** The program uses the diagnostics_channel surface (index.ts detects
67
67
  * dc.* libCalls on the IR): compiles scr_dc.c — pure data structure
68
- * over the DOM (no loop hooks, no install), cross-compiles everywhere.
68
+ * over the checked-dynamic tree (no loop hooks, no install), cross-compiles everywhere.
69
69
  * Channel-free binaries keep their exact size class. */
70
70
  dc?: boolean;
71
71
  /** The program uses the checked-dynamic async surfaces
72
72
  * (moduleUsesDynAsync on the IR, or the dynInvoke/dc gates — their TUs
73
- * call into this one): compiles scr_async_dyn.c — DOM-promise
73
+ * call into this one): compiles scr_async_dyn.c — dyn-promise
74
74
  * reactions, AsyncLocalStorage, the unhandledRejection/warning
75
75
  * process events. */
76
76
  dynAsync?: boolean;
@@ -902,7 +902,7 @@ export function streamCbThunkFor(E, kind, cbT) {
902
902
  const isDonePos = kind === "e" ? false
903
903
  : (kind === "w" || kind === "t") ? pos === 2 : (kind === "f" || kind === "l") ? pos === 0 : pos === 1;
904
904
  // The JS lane's implicitly-any parameters: each position boxes into
905
- // dyn by kind — the chunk as DOM bytes, the encoding as a string,
905
+ // dyn by kind — the chunk as dyn bytes, the encoding as a string,
906
906
  // the error as the boundary's {name, message} shape (null when
907
907
  // none), and the completion callback as a CALLABLE dyn whose glue
908
908
  // dispatches to the runtime's *_done entry (the closure's one cap
@@ -1,4 +1,4 @@
1
- import { arrayOf, BOOL, BYTES_U8, bytesOf, canMarshalFuncIntoIsland, CHILDSTREAM_T, DYN, F64, isRefCounted, isUnitType, MAY_THROW_LIB_FNS, RUNTIME_ERROR_CLASSES, STRING, typeEquals } from "../../ir/nodes.js";
1
+ import { arrayOf, BOOL, BYTES_U8, bytesOf, canMarshalFuncIntoIsland, CHILDSTREAM_T, DYN, F64, islandPromisePayloadTag, isRefCounted, isUnitType, MAY_THROW_LIB_FNS, RUNTIME_ERROR_CLASSES, STRING, typeEquals } from "../../ir/nodes.js";
2
2
  import { boxAccess, BYTES_NUM_KIND_C, BYTES_NUM_VAR_C, bytesElemKindC, cDecl, cFnPtrCast, cNumberLiteral, cStringLiteral, cType, DV_GET_KIND_C, DV_SET_KIND_C, elemAccess, mapKeyAccess, mapKeyKindC, mapValKindC, retainCallC, vAdapters } from "./emit-types.js";
3
3
  import { mangleClassNew, mangleClassRetain, mangleClassStruct, mangleField, mangleFnClosure, mangleFunction, mangleGlobal, mangleLocal, mangleRecordNew, mangleRecordStruct, mangleVtStruct } from "../mangle.js";
4
4
  import { OVERFLOW_MEMBER } from "./emit-shapes.js";
@@ -190,7 +190,7 @@ export function emitExpr(E, e) {
190
190
  return E.emitExpr(e.result);
191
191
  }
192
192
  case "dynDestrCheck": {
193
- // RequireObjectCoercible with V8's destructuring TypeError. DOM
193
+ // RequireObjectCoercible with V8's destructuring TypeError. dyn
194
194
  // values check in the runtime helper and pass through unchanged
195
195
  // (same temp, same ownership); island values check in the engine
196
196
  // (a fresh +1 cell for the same value comes back).
@@ -207,7 +207,7 @@ export function emitExpr(E, e) {
207
207
  }
208
208
  case "dynIterN": {
209
209
  // GetIterator + first-N steps as a fresh array (V8's exact
210
- // not-iterable TypeError on non-iterables): the DOM helper for
210
+ // not-iterable TypeError on non-iterables): the dyn helper for
211
211
  // dyn operands, the engine's real iterator protocol for island
212
212
  // ones.
213
213
  const v = E.emitExpr(e.value);
@@ -301,11 +301,11 @@ export function emitExpr(E, e) {
301
301
  E.currentFrame().push({ name, type: e.type });
302
302
  return { name, type: e.type };
303
303
  }
304
- // A dyn (DOM) receiver — the `rawName?.match(re)` step: the nullish
304
+ // A dyn (dyn) receiver — the `rawName?.match(re)` step: the nullish
305
305
  // test reads the node's kind tag; the unit path is the undefined
306
- // DOM singleton (dyn results) or nothing (void bodies), the body
306
+ // dyn singleton (dyn results) or nothing (void bodies), the body
307
307
  // runs over the bound receiver otherwise (the validated dynamic
308
- // dispatch, its result converted back into the DOM by the
308
+ // dispatch, its result converted back into the checked-dynamic tree by the
309
309
  // frontend's dynFrom wrap).
310
310
  if (e.receiver.type.kind === "dyn") {
311
311
  const r = E.emitExpr(e.receiver);
@@ -381,7 +381,7 @@ export function emitExpr(E, e) {
381
381
  return { name: "", type: e.type };
382
382
  }
383
383
  // A dyn-typed chain (`pricing?.[key]` over an unknown-valued index
384
- // signature): the unit path is the undefined DOM value — dyn
384
+ // signature): the unit path is the undefined dyn value — dyn
385
385
  // represents undefined directly, no union wrapper exists.
386
386
  if (e.type.kind === "dyn") {
387
387
  const name = `sc_t${E.tempCounter++}`;
@@ -578,7 +578,7 @@ export function emitExpr(E, e) {
578
578
  return E.newTemp(e.type, `scr_caught_to_string(${v.name})`);
579
579
  }
580
580
  if (v.type.kind === "dyn") {
581
- // String(unknown): dispatch over the DOM kind (dynToStrHelper —
581
+ // String(unknown): dispatch over the dyn kind (dynToStrHelper —
582
582
  // Node's String() incl. arrays-join and "[object Object]").
583
583
  return E.newTemp(e.type, `${E.dynToStrHelper()}(${v.name})`);
584
584
  }
@@ -1597,10 +1597,10 @@ export function emitExpr(E, e) {
1597
1597
  return E.newTemp(e.type, `scr_map_keys_js_order(${obj.name}->${OVERFLOW_MEMBER})`);
1598
1598
  }
1599
1599
  case "dynFrom": {
1600
- // Static value → fresh DOM tree (+1) through the interned per-type
1600
+ // Static value → fresh dyn tree (+1) through the interned per-type
1601
1601
  // converter; the operand stays borrowed (frame-released as usual).
1602
1602
  // Bare unit literals (an `undefined`/`null` stored under an
1603
- // `unknown` index signature) are the DOM unit values directly.
1603
+ // `unknown` index signature) are the dyn unit values directly.
1604
1604
  if (e.value.kind === "unitLit") {
1605
1605
  return E.newTemp(e.type, e.value.unit === "undefined"
1606
1606
  ? "scr_dyn_retain(scr_dyn_undefined())"
@@ -1608,7 +1608,7 @@ export function emitExpr(E, e) {
1608
1608
  }
1609
1609
  const v = E.emitExpr(e.value);
1610
1610
  if (v.type.kind === "func") {
1611
- // A closure boxes as the DOM's function kind: retained closure +
1611
+ // A closure boxes as the checked-dynamic tree's function kind: retained closure +
1612
1612
  // the per-signature call thunk + the interned signature key. The
1613
1613
  // best-effort name rides along for inspect/error rendering (NULL
1614
1614
  // when the lowering had none).
@@ -1620,8 +1620,8 @@ export function emitExpr(E, e) {
1620
1620
  return E.newTemp(e.type, `${E.toDynHelper(v.type)}(${v.name})`);
1621
1621
  }
1622
1622
  case "dynFromJsval": {
1623
- // Island value → DOM: the by-reference wrap (scr_dyn_from_jsval
1624
- // retains the cell in; engine scalars normalize to native DOM
1623
+ // Island value → dyn: the by-reference wrap (scr_dyn_from_jsval
1624
+ // retains the cell in; engine scalars normalize to native dyn
1625
1625
  // kinds at wrap time). Operand borrowed, result +1, never throws.
1626
1626
  const v = E.emitExpr(e.value);
1627
1627
  return E.newTemp(e.type, `scr_dyn_from_jsval(${v.name})`);
@@ -1635,11 +1635,11 @@ export function emitExpr(E, e) {
1635
1635
  const callee = E.emitExpr(e.callee);
1636
1636
  const what = cStringLiteral(Buffer.from(e.calleeName, "utf8"));
1637
1637
  if (e.spreads !== undefined && e.spreads.length > 0) {
1638
- // The RUNTIME-ARITY form (`f(...args)`): one fresh DOM array
1638
+ // The RUNTIME-ARITY form (`f(...args)`): one fresh dyn array
1639
1639
  // collects the arguments left-to-right — plain args move in
1640
1640
  // (push takes ownership), spread args FLATTEN (push_spread
1641
1641
  // retains elements in and throws V8's spread-call TypeError for
1642
- // non-iterable DOM kinds, checked per spread — JS's
1642
+ // non-iterable dyn kinds, checked per spread — JS's
1643
1643
  // ArgumentListEvaluation order) — then apply calls through the
1644
1644
  // array's elements (borrowed, exactly scr_dyn_call).
1645
1645
  const spreadAt = new Map(e.spreads.map((s) => [s.arg, s.what]));
@@ -1685,7 +1685,7 @@ export function emitExpr(E, e) {
1685
1685
  return E.fallibleTemp(e.type, `scr_dyn_invoke(${recv.name}, ${method}, ${argsExpr}, ${args.length}, ${what})`);
1686
1686
  }
1687
1687
  case "dynArrLit": {
1688
- // A DOM array built element-by-element: ownership of each dyn
1688
+ // A dyn array built element-by-element: ownership of each dyn
1689
1689
  // element MOVES into the array (scr_dyn_arr_push's contract).
1690
1690
  const arr = E.newTemp(e.type, "scr_dyn_new_arr()");
1691
1691
  for (const el of e.elems) {
@@ -1696,7 +1696,7 @@ export function emitExpr(E, e) {
1696
1696
  return arr;
1697
1697
  }
1698
1698
  case "dynObjLit": {
1699
- // A DOM object built member-by-member: key then value, source
1699
+ // A dyn object built member-by-member: key then value, source
1700
1700
  // order (JS's literal evaluation). scr_dyn_key_set BORROWS all
1701
1701
  // three (the member retains the value in), so key/value temps
1702
1702
  // release with the frame as usual; the receiver is a fresh OBJ,
@@ -1890,7 +1890,7 @@ export function emitExpr(E, e) {
1890
1890
  return E.newTemp(e.type, `${u.name}->tag ${e.negated ? "!=" : "=="} ${e.tag}`);
1891
1891
  }
1892
1892
  case "dynKeyGet": {
1893
- // Keyed read on the DOM through the one interned helper — the
1893
+ // Keyed read on the checked-dynamic tree through the one interned helper — the
1894
1894
  // non-optional form throws JS's TypeError on an undefined/null
1895
1895
  // receiver, and HANDLE receivers can throw the loud unmodeled-
1896
1896
  // property ladder on EITHER form, so both ride a fallible temp;
@@ -1927,7 +1927,7 @@ export function emitExpr(E, e) {
1927
1927
  const r = E.emitExpr(e.right);
1928
1928
  const [d, s, st] = e.left.type.kind === "dyn" ? [l, r, e.right.type] : [r, l, e.left.type];
1929
1929
  const test = st.kind === "dyn"
1930
- ? // dyn vs dyn: whole-DOM strict equality (scalars by value,
1930
+ ? // dyn vs dyn: whole-dyn strict equality (scalars by value,
1931
1931
  // units by kind, reference kinds by node identity).
1932
1932
  `scr_dyn_strict_eq(${l.name}, ${r.name})`
1933
1933
  : st.kind === "string"
@@ -1938,7 +1938,7 @@ export function emitExpr(E, e) {
1938
1938
  return E.newTemp(e.type, e.negated ? `!${test}` : test);
1939
1939
  }
1940
1940
  case "dynTest": {
1941
- // A pure kind compare on the DOM node — borrowed; only the truthy
1941
+ // A pure kind compare on the dyn node — borrowed; only the truthy
1942
1942
  // form also reads a scalar payload. ISLAND-held nodes (the jsval
1943
1943
  // kind — engine objects/arrays/functions only, scalars normalize
1944
1944
  // at wrap time) route the tests that depend on the engine's
@@ -1954,20 +1954,20 @@ export function emitExpr(E, e) {
1954
1954
  // engine's own typeof.
1955
1955
  `(${d.name}->kind == SCR_DYN_OBJ || ${d.name}->kind == SCR_DYN_ARR || ${d.name}->kind == SCR_DYN_BYTES || ${d.name}->kind == SCR_DYN_HANDLE || ${d.name}->kind == SCR_DYN_PROMISE || ${d.name}->kind == SCR_DYN_NULL || scr_dyn_isl_typeof_is(${d.name}, "object"))`
1956
1956
  : e.test === "truthy"
1957
- ? // ToBoolean over the DOM: bool by value; number falsy for
1957
+ ? // ToBoolean over the checked-dynamic tree: bool by value; number falsy for
1958
1958
  // 0, -0 (== 0 in C), and NaN (self-inequality); string
1959
1959
  // falsy when empty; obj/arr/bytes/func/handle always true;
1960
1960
  // JSVAL through the runtime's routed arm (the bigint 0n
1961
1961
  // edge); the remaining kinds (undefined, null) always false.
1962
1962
  `(${d.name}->kind == SCR_DYN_BOOL ? ${d.name}->v.b : ${d.name}->kind == SCR_DYN_NUM ? (${d.name}->v.num == ${d.name}->v.num && ${d.name}->v.num != 0) : ${d.name}->kind == SCR_DYN_STR ? ${d.name}->v.str->len != 0 : ${d.name}->kind == SCR_DYN_JSVAL ? scr_dyn_truthy(${d.name}) : (${d.name}->kind == SCR_DYN_OBJ || ${d.name}->kind == SCR_DYN_ARR || ${d.name}->kind == SCR_DYN_BYTES || ${d.name}->kind == SCR_DYN_FUNC || ${d.name}->kind == SCR_DYN_HANDLE || ${d.name}->kind == SCR_DYN_PROMISE))`
1963
1963
  : e.test === "error"
1964
- ? // `u instanceof Error`: the DOM's error encoding — an
1964
+ ? // `u instanceof Error`: the checked-dynamic tree's error encoding — an
1965
1965
  // object carrying the reserved "%error" marker key
1966
1966
  // (built by caughtToDyn for Error payloads) — or a real
1967
1967
  // engine Error held by reference.
1968
1968
  `((${d.name}->kind == SCR_DYN_OBJ && scr_dyn_obj_get(${d.name}, "%error", 6) != NULL) || scr_dyn_isl_is_error(${d.name}))`
1969
1969
  : e.test === "array"
1970
- ? // Array.isArray: the DOM's array kind, or the engine's
1970
+ ? // Array.isArray: the checked-dynamic tree's array kind, or the engine's
1971
1971
  // own answer for an engine-held value.
1972
1972
  `(${d.name}->kind == SCR_DYN_ARR || scr_dyn_isl_is_array(${d.name}))`
1973
1973
  : e.test === "function"
@@ -2030,7 +2030,7 @@ export function emitExpr(E, e) {
2030
2030
  throw new Error(`emitter bug: caughtNarrow to ${e.type.kind}`);
2031
2031
  }
2032
2032
  case "caughtToDyn": {
2033
- // The caught snapshot converting to a dyn DOM value (an unknown
2033
+ // The caught snapshot converting to a dyn value (an unknown
2034
2034
  // slot) — the interned runtime-kind dispatch. Box borrowed; the
2035
2035
  // result is a fresh tree (+1). Never throws.
2036
2036
  const c = E.emitExpr(e.value);
@@ -2091,7 +2091,7 @@ export function emitExpr(E, e) {
2091
2091
  const rc = vAdapters(t);
2092
2092
  if (t.kind === "dyn") {
2093
2093
  // The thrown-dyn representation (REF + dyn adapters): catch
2094
- // bindings and the unhandled dispatch see the DOM value
2094
+ // bindings and the unhandled dispatch see the dyn value
2095
2095
  // itself — identity preserved.
2096
2096
  E.line(`scr_throw_ref(${reason.name}, &${rc.retain}, &${rc.release}, NULL);${E.srcComment(e.loc)}`);
2097
2097
  }
@@ -2230,11 +2230,11 @@ export function emitExpr(E, e) {
2230
2230
  // abandons (releases are NULL-tolerant).
2231
2231
  return finish(`(scr_jsval_cast_fail(${arg(0)}, ${arg(1)}), NULL)`);
2232
2232
  case "json.parse":
2233
- // Borrows the text; returns +1 on a fresh DOM, or throws a
2233
+ // Borrows the text; returns +1 on a fresh dyn, or throws a
2234
2234
  // catchable SyntaxError-shaped string (may-throw seed set).
2235
2235
  return finish(`scr_json_parse(${arg(0)})`);
2236
2236
  case "dyn.defineProps":
2237
- // Object.defineProperties over DOM values: both borrowed,
2237
+ // Object.defineProperties over dyn values: both borrowed,
2238
2238
  // result the target (+1); throws catchably (may-throw seed).
2239
2239
  return finish(`scr_dyn_define_props(${arg(0)}, ${arg(1)})`);
2240
2240
  case "dyn.keySet":
@@ -2243,12 +2243,20 @@ export function emitExpr(E, e) {
2243
2243
  // non-object receivers (may-throw seed set).
2244
2244
  return finish(`scr_dyn_key_set(${arg(0)}, ${arg(1)}, ${arg(2)})`);
2245
2245
  case "dyn.iterPack":
2246
- // Destructuring pack over a dyn source: both borrowed, fresh
2247
- // array +1; throws V8's destructuring TypeError on
2248
- // non-iterable DOM kinds (may-throw seed set).
2246
+ // Destructuring/for-of pack over a dyn source: both borrowed,
2247
+ // fresh array +1; throws V8's not-iterable TypeError on
2248
+ // non-iterable dyn kinds and drains wrapped engine values
2249
+ // through the engine's protocol (may-throw seed set).
2249
2250
  return finish(`scr_dyn_iter_pack(${arg(0)}, ${arg(1)})`);
2251
+ case "dyn.arrLen":
2252
+ // The for-of pack's length (borrowed; never throws).
2253
+ return finish(`scr_dyn_arr_len(${arg(0)})`);
2254
+ case "dyn.arrAt":
2255
+ // The for-of pack's element at index (+1; never throws — the
2256
+ // undefined singleton past the end).
2257
+ return finish(`scr_dyn_arr_at(${arg(0)}, ${arg(1)})`);
2250
2258
  case "dyn.typeof":
2251
- // Bare typeof on a dyn value: the DOM kind's JS answer (+1).
2259
+ // Bare typeof on a dyn value: the dyn kind's JS answer (+1).
2252
2260
  return finish(`scr_dyn_typeof(${arg(0)})`);
2253
2261
  case "dyn.toString":
2254
2262
  // Receiver-kind-dispatched toString (+1); throws Node's
@@ -2531,7 +2539,7 @@ export function emitExpr(E, e) {
2531
2539
  // borrows, +1 result, never throws.
2532
2540
  case "regexp.escape":
2533
2541
  return finish(`scr_regexp_escape(${arg(0)})`);
2534
- // The WHATWG base64 globals (scr_string.c): DOM arg borrowed
2542
+ // The WHATWG base64 globals (scr_string.c): dyn arg borrowed
2535
2543
  // (WebIDL ToString in the runtime), +1 string result; malformed
2536
2544
  // input throws the catchable DOMException InvalidCharacterError
2537
2545
  // (may-throw seed set). The zero-argument form always throws
@@ -4797,7 +4805,7 @@ export function emitExpr(E, e) {
4797
4805
  // Borrowed receiver; +1 "name: message" (Node's toString rules).
4798
4806
  return finish(`scr_error_to_string(${arg(0)})`);
4799
4807
  case "error.newDom":
4800
- // new DOMException(message?, nameOrOptions?) — both DOM args
4808
+ // new DOMException(message?, nameOrOptions?) — both dyn args
4801
4809
  // borrowed (WebIDL resolution runs in the runtime); +1
4802
4810
  // %DOMException. Never throws.
4803
4811
  return finish(`scr_domex_new(${arg(0)}, ${arg(1)})`);
@@ -4808,7 +4816,7 @@ export function emitExpr(E, e) {
4808
4816
  // `'cause' in e` — the options form's own-property record.
4809
4817
  return finish(`scr_domex_has_cause(${arg(0)})`);
4810
4818
  case "error.domCause":
4811
- // +1 cause DOM value (the DOM undefined when absent).
4819
+ // +1 cause dyn value (the dyn undefined when absent).
4812
4820
  return finish(`scr_domex_cause(${arg(0)})`);
4813
4821
  case "error.domClone":
4814
4822
  // WebIDL serialization: name/message copy, code re-derives.
@@ -4818,7 +4826,7 @@ export function emitExpr(E, e) {
4818
4826
  case "dyn.objKeys":
4819
4827
  return finish(`scr_dyn_obj_keys(${arg(0)})`);
4820
4828
  case "dyn.assign":
4821
- // Object.assign over DOM values: own members copy, the target
4829
+ // Object.assign over dyn values: own members copy, the target
4822
4830
  // returns (+1); non-object receivers throw like Node.
4823
4831
  return finish(`scr_dyn_assign(${arg(0)}, ${arg(1)})`);
4824
4832
  case "dyn.packPush":
@@ -4843,7 +4851,7 @@ export function emitExpr(E, e) {
4843
4851
  // (+1). Never throws.
4844
4852
  return finish(`scr_dyn_new_obj_null_proto()`);
4845
4853
  case "dyn.hasOwn":
4846
- // Object.hasOwn over a DOM receiver (throws on nullish, like
4854
+ // Object.hasOwn over a dyn receiver (throws on nullish, like
4847
4855
  // Node's ToObject).
4848
4856
  return finish(`scr_dyn_has_own(${arg(0)}, ${arg(1)})`);
4849
4857
  case "dyn.objValues":
@@ -4851,11 +4859,11 @@ export function emitExpr(E, e) {
4851
4859
  case "dyn.objEntries":
4852
4860
  return finish(`scr_dyn_obj_entries(${arg(0)})`);
4853
4861
  case "dyn.errInstanceof":
4854
- // The from_error cache resolves the DOM value to its runtime
4862
+ // The from_error cache resolves the dyn value to its runtime
4855
4863
  // error; the class's stamped interval answers. Never throws.
4856
4864
  return finish(`scr_dyn_err_instanceof(${arg(0)}, ${arg(1)})`);
4857
4865
  case "dyn.structuredClone":
4858
- // Deep DOM clone (+1); option/DataClone/cycle errors throw
4866
+ // Deep dyn clone (+1); option/DataClone/cycle errors throw
4859
4867
  // (may-throw seed set). Both args borrowed.
4860
4868
  return finish(`scr_structured_clone(${arg(0)}, ${arg(1)})`);
4861
4869
  case "dyn.cloneMissing":
@@ -5410,7 +5418,7 @@ export function emitExpr(E, e) {
5410
5418
  return finish(`scr_assert_eq_sym(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`);
5411
5419
  case "assert.eqDyn":
5412
5420
  // The quartet over checked-dynamic operands: SameValue /
5413
- // DOM-walk deep equality, assertion_error.js messages.
5421
+ // dyn-walk deep equality, assertion_error.js messages.
5414
5422
  return finish(`scr_assert_eq_dyn(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`);
5415
5423
  case "assert.deepResult":
5416
5424
  return finish(`scr_assert_deep_result(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)})`);
@@ -5675,14 +5683,14 @@ export function emitExpr(E, e) {
5675
5683
  }
5676
5684
  case "jsonStringify": {
5677
5685
  // Type-directed serialization: the STATIC type picks an emitted
5678
- // serializer (interned per type) — no DOM, no runtime dispatch. The
5686
+ // serializer (interned per type) — no dyn, no runtime dispatch. The
5679
5687
  // value temp is BORROWED (released with this statement's frame);
5680
5688
  // the result string is owned (+1). Throws only over CYCLE-CAPABLE
5681
5689
  // types (recursive records — the circular-structure TypeError) and
5682
5690
  // dyn roots; everything else keeps the throw-free path.
5683
5691
  const v = E.emitExpr(e.value);
5684
- // A dyn root: the runtime's DOM walker (scr_dyn_format_j — the %j
5685
- // serializer IS JSON.stringify over the DOM: number/string/bool/
5692
+ // A dyn root: the runtime's dyn walker (scr_dyn_format_j — the %j
5693
+ // serializer IS JSON.stringify over the checked-dynamic tree: number/string/bool/
5686
5694
  // null/array/object exact, dropped members omitted, a dropped ROOT
5687
5695
  // becomes the text "undefined", a runtime handle inside the tree
5688
5696
  // throws) — fallible, so the pending-exception check runs.
@@ -5714,7 +5722,7 @@ export function emitExpr(E, e) {
5714
5722
  return E.newTemp(e.type, `${E.jsonIndentHelper()}(${compact.name}, ${cStringLiteral(bytes)}, ${bytes.length})`);
5715
5723
  }
5716
5724
  case "dynCheck": {
5717
- // The dynamic boundary: validate the DOM against the target type
5725
+ // The dynamic boundary: validate the checked-dynamic tree against the target type
5718
5726
  // and BUILD the typed value (+1) — or throw a catchable
5719
5727
  // TypeError-shaped, path-annotated string. The dyn temp is BORROWED;
5720
5728
  // the result joins the frame BEFORE the pending check so an unwind
@@ -5866,7 +5874,7 @@ export function emitExpr(E, e) {
5866
5874
  return { name: "", type: e.type };
5867
5875
  }
5868
5876
  case "dyn":
5869
- // The DOM-crossing await: void fulfillments (a boxed
5877
+ // The checked-dynamic tree-crossing await: void fulfillments (a boxed
5870
5878
  // promise<void> that skipped its adapter) answer the
5871
5879
  // undefined VALUE, never NULL.
5872
5880
  read = `scr_await_dyn(${pr.name})`;
@@ -6071,7 +6079,7 @@ export function emitExpr(E, e) {
6071
6079
  case "string":
6072
6080
  return E.newTemp(e.type, `scr_jsval_from_str(${v.name})`);
6073
6081
  case "dyn":
6074
- // A CHECKED-DYNAMIC (DOM) value entering the island: deep
6082
+ // A CHECKED-DYNAMIC (dyn) value entering the island: deep
6075
6083
  // copy, data kinds only — boxed functions/handles/promises
6076
6084
  // throw the catchable TypeError in the runtime.
6077
6085
  return E.fallibleTemp(e.type, `scr_jsval_from_dyn(${v.name})`);
@@ -6082,6 +6090,20 @@ export function emitExpr(E, e) {
6082
6090
  case "url":
6083
6091
  // A URL crossing IN: an engine URL instance built from href.
6084
6092
  return E.fallibleTemp(e.type, `scr_jsval_from_url(${v.name})`);
6093
+ case "promise": {
6094
+ // A STATIC promise crossing IN: a real engine thenable
6095
+ // settled when the scriptc promise settles (the async-
6096
+ // callback return bridge). from_promise takes ownership of a
6097
+ // +1 — retain past the borrowed frame temp.
6098
+ const tag = islandPromisePayloadTag(e.value.type.inner);
6099
+ if (!tag)
6100
+ throw new Error("emitter bug: jsMarshal of a promise outside the bridge payload domain");
6101
+ const tagC = {
6102
+ void: "SCR_ISLP_VOID", f64: "SCR_ISLP_F64", bool: "SCR_ISLP_BOOL",
6103
+ string: "SCR_ISLP_STR", jsval: "SCR_ISLP_JSVAL", jsvalArr: "SCR_ISLP_JSVAL_ARR",
6104
+ }[tag];
6105
+ return E.fallibleTemp(e.type, `scr_jsval_from_promise(scr_promise_retain(${v.name}), ${tagC})`);
6106
+ }
6085
6107
  case "func": {
6086
6108
  // A closure entering the island as a host function (the
6087
6109
  // package-callback pattern). from_closure retains the closure;
@@ -6258,10 +6280,19 @@ export function emitExpr(E, e) {
6258
6280
  // emits u8 targets (canExitIslandToType).
6259
6281
  return E.fallibleTemp(e.type, `scr_jsval_exit_bytes(${v.name})`);
6260
6282
  default: {
6283
+ // `any[]`-declared slot: the engine array exits Array.isArray-
6284
+ // gated, elements BY REFERENCE (identity crosses; the spine is
6285
+ // a snapshot copy). JSON-safe element types keep the round
6286
+ // trip below.
6287
+ if (e.type.kind === "array" && e.type.elem.kind === "jsval") {
6288
+ return E.fallibleTemp(e.type, `scr_jsval_exit_jsval_arr(${v.name})`);
6289
+ }
6261
6290
  // An undefined-armed union target: the engine's undefined takes
6262
6291
  // the undefined arm FIRST — JSON cannot spell it (to_json would
6263
6292
  // refuse the exit) — then null and data ride the round trip
6264
- // into the union's dynCheck like any composite.
6293
+ // into the union's dynCheck like any composite (or, for the
6294
+ // `any[] | undefined` defaulted-parameter spelling, the
6295
+ // jsval-element array exit wrapped into the data arm).
6265
6296
  const undefTag = e.type.kind === "union" ? E.undefinedArmTag(e.type) : -1;
6266
6297
  if (e.type.kind === "union" && undefTag >= 0) {
6267
6298
  const name = `sc_t${E.tempCounter++}`;
@@ -6273,11 +6304,23 @@ export function emitExpr(E, e) {
6273
6304
  E.line(`} else {`);
6274
6305
  E.indent++;
6275
6306
  E.frames.push([]);
6276
- const json = E.fallibleTemp(STRING, `scr_jsval_to_json(${v.name})`);
6277
- const dom = E.fallibleTemp(DYN, `scr_json_parse(${json.name})`);
6278
- const out = E.fallibleTemp(e.type, `${E.dynCheckHelper(e.type)}(${dom.name}, NULL)`);
6279
- E.moveTemp(out);
6280
- E.line(`${name} = ${out.name};`);
6307
+ const unionDef = E.unionsById.get(e.type.unionId);
6308
+ const dataArms = unionDef ? unionDef.arms.flatMap((a, i) => (isUnitType(a) ? [] : [{ a, i }])) : [];
6309
+ const jsvalArr = dataArms.length === 1 && dataArms[0].a.kind === "array" && dataArms[0].a.elem.kind === "jsval" ? dataArms[0] : null;
6310
+ if (jsvalArr) {
6311
+ // The `any[] | undefined` defaulted-parameter spelling:
6312
+ // the engine array exits BY REFERENCE into the data arm.
6313
+ const arr = E.fallibleTemp(jsvalArr.a, `scr_jsval_exit_jsval_arr(${v.name})`);
6314
+ E.moveTemp(arr);
6315
+ E.line(`${name} = scr_union_new_ref(${jsvalArr.i}, ${arr.name}, &scr_arr_retain_v, &scr_arr_release_v, NULL);`);
6316
+ }
6317
+ else {
6318
+ const json = E.fallibleTemp(STRING, `scr_jsval_to_json(${v.name})`);
6319
+ const dom = E.fallibleTemp(DYN, `scr_json_parse(${json.name})`);
6320
+ const out = E.fallibleTemp(e.type, `${E.dynCheckHelper(e.type)}(${dom.name}, NULL)`);
6321
+ E.moveTemp(out);
6322
+ E.line(`${name} = ${out.name};`);
6323
+ }
6281
6324
  E.releaseFrame(E.frames.pop());
6282
6325
  E.indent--;
6283
6326
  E.line(`}`);
@@ -6299,7 +6342,9 @@ export function emitExpr(E, e) {
6299
6342
  const v = E.emitExpr(e.value);
6300
6343
  const payload = e.type.kind === "promise" && e.type.inner.kind === "void"
6301
6344
  ? "SCR_ISLP_VOID"
6302
- : "SCR_ISLP_JSVAL";
6345
+ : e.type.kind === "promise" && e.type.inner.kind === "array" && e.type.inner.elem.kind === "jsval"
6346
+ ? "SCR_ISLP_JSVAL_ARR" // `any[]` fulfillment: the Array.isArray-gated by-reference exit at settle
6347
+ : "SCR_ISLP_JSVAL";
6303
6348
  return E.fallibleTemp(e.type, `scr_jsval_bridge_promise(${v.name}, ${payload})`);
6304
6349
  }
6305
6350
  default: {