@scriptc/compiler 0.0.10 → 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 (111) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +63 -15
  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 +131 -54
  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 +33 -9
  14. package/dist/backend/emission/emitter.js.map +1 -1
  15. package/dist/backend/emission/may-throw.js +1 -1
  16. package/dist/backend/llvm/dyn.d.ts +10 -10
  17. package/dist/backend/llvm/dyn.js +26 -26
  18. package/dist/backend/llvm/dyn.js.map +1 -1
  19. package/dist/backend/llvm/emitter.js +156 -47
  20. package/dist/backend/llvm/emitter.js.map +1 -1
  21. package/dist/backend/llvm/shapes.js +1 -1
  22. package/dist/backend/llvm/walkers.js +2 -2
  23. package/dist/backend/llvm/walkers.js.map +1 -1
  24. package/dist/coverage/surface-manifest.js +16 -2
  25. package/dist/coverage/surface-manifest.js.map +1 -1
  26. package/dist/diagnostics/diagnostic.d.ts +21 -8
  27. package/dist/diagnostics/diagnostic.js +48 -14
  28. package/dist/diagnostics/diagnostic.js.map +1 -1
  29. package/dist/frontend/lowering/lib-boundary.js +5 -5
  30. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  31. package/dist/frontend/lowering/lower-assert.js +12 -12
  32. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  33. package/dist/frontend/lowering/lower-builtins.d.ts +63 -7
  34. package/dist/frontend/lowering/lower-builtins.js +327 -35
  35. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  36. package/dist/frontend/lowering/lower-calls.d.ts +4 -4
  37. package/dist/frontend/lowering/lower-calls.js +104 -70
  38. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  39. package/dist/frontend/lowering/lower-classes.d.ts +7 -0
  40. package/dist/frontend/lowering/lower-classes.js +82 -6
  41. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  42. package/dist/frontend/lowering/lower-containers.d.ts +9 -5
  43. package/dist/frontend/lowering/lower-containers.js +88 -26
  44. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  45. package/dist/frontend/lowering/lower-emitter.d.ts +70 -3
  46. package/dist/frontend/lowering/lower-emitter.js +438 -31
  47. package/dist/frontend/lowering/lower-emitter.js.map +1 -1
  48. package/dist/frontend/lowering/lower-exprs.d.ts +87 -12
  49. package/dist/frontend/lowering/lower-exprs.js +630 -125
  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.d.ts +8 -5
  56. package/dist/frontend/lowering/lower-modules.js +157 -63
  57. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  58. package/dist/frontend/lowering/lower-namespaces.d.ts +24 -0
  59. package/dist/frontend/lowering/lower-namespaces.js +158 -16
  60. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  61. package/dist/frontend/lowering/lower-server.js +11 -11
  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 +271 -36
  65. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  66. package/dist/frontend/lowering/lower-stream.js +171 -20
  67. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  68. package/dist/frontend/lowering/lowerer.d.ts +27 -10
  69. package/dist/frontend/lowering/lowerer.js +156 -54
  70. package/dist/frontend/lowering/lowerer.js.map +1 -1
  71. package/dist/frontend/lowering/surfaces.d.ts +44 -0
  72. package/dist/frontend/lowering/surfaces.js +236 -5
  73. package/dist/frontend/lowering/surfaces.js.map +1 -1
  74. package/dist/frontend/npm.d.ts +12 -0
  75. package/dist/frontend/npm.js +30 -0
  76. package/dist/frontend/npm.js.map +1 -1
  77. package/dist/frontend/program.d.ts +25 -0
  78. package/dist/frontend/program.js +145 -136
  79. package/dist/frontend/program.js.map +1 -1
  80. package/dist/frontend/shared.d.ts +1 -1
  81. package/dist/frontend/shared.js +8 -8
  82. package/dist/frontend/shared.js.map +1 -1
  83. package/dist/frontend/types.d.ts +2 -2
  84. package/dist/frontend/types.js +15 -15
  85. package/dist/frontend/types.js.map +1 -1
  86. package/dist/index.d.ts +2 -1
  87. package/dist/index.js +169 -5
  88. package/dist/index.js.map +1 -1
  89. package/dist/ir/nodes.d.ts +174 -106
  90. package/dist/ir/nodes.js +69 -24
  91. package/dist/ir/nodes.js.map +1 -1
  92. package/dist/ir/validate.js +55 -36
  93. package/dist/ir/validate.js.map +1 -1
  94. package/dist/library/fence-eval.js +12 -2
  95. package/dist/library/fence-eval.js.map +1 -1
  96. package/dist/library/int-infer.d.ts +119 -0
  97. package/dist/library/int-infer.js +1314 -0
  98. package/dist/library/int-infer.js.map +1 -0
  99. package/dist/library/int-infer.test.d.ts +1 -0
  100. package/dist/library/int-infer.test.js +279 -0
  101. package/dist/library/int-infer.test.js.map +1 -0
  102. package/dist/library/profile.d.ts +34 -5
  103. package/dist/library/profile.js +77 -13
  104. package/dist/library/profile.js.map +1 -1
  105. package/dist/library/sidecar-validate.js +1 -1
  106. package/dist/library/sidecar-validate.js.map +1 -1
  107. package/dist/library/sidecar.d.ts +24 -1
  108. package/dist/library/sidecar.js +163 -16
  109. package/dist/library/sidecar.js.map +1 -1
  110. package/package.json +2 -2
  111. package/surface-manifest.json +210 -12
@@ -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
  }
@@ -1008,6 +1008,10 @@ export function emitExpr(E, e) {
1008
1008
  // Omitted relative indices default like string slice: start 0,
1009
1009
  // end +Infinity (math.h is always included). Fresh copy, +1.
1010
1010
  return E.newTemp(e.type, `scr_bytes_slice(${r.name}, ${args[0]?.name ?? "0"}, ${args[1]?.name ?? "INFINITY"})`);
1011
+ case "subarray":
1012
+ // Same defaults; the result is a +1 VIEW aliasing the
1013
+ // receiver's storage (subarray / Buffer's slice).
1014
+ return E.newTemp(e.type, `scr_bytes_subarray(${r.name}, ${args[0]?.name ?? "0"}, ${args[1]?.name ?? "INFINITY"})`);
1011
1015
  case "setFrom": {
1012
1016
  // dst.set(src, offset?) — void; throws Node's RangeError on
1013
1017
  // overflow (may-throw seed).
@@ -1063,6 +1067,10 @@ export function emitExpr(E, e) {
1063
1067
  E.emitPendingCheck();
1064
1068
  return t;
1065
1069
  }
1070
+ case "fillElem":
1071
+ // Per-element TypedArray fill (non-u8): slice-style index
1072
+ // defaults, never throws; the receiver comes back +1.
1073
+ return E.newTemp(e.type, `scr_bytes_fill_elem(${r.name}, ${args[0].name}, ${args[1]?.name ?? "0"}, ${args[2]?.name ?? "INFINITY"})`);
1066
1074
  case "fillStr": {
1067
1075
  const n = e.args.length - 2;
1068
1076
  const t = E.newTemp(e.type, `scr_bytes_fill_str(${r.name}, ${args[0].name}, ${args[1].name}, ${n}, ` +
@@ -1589,10 +1597,10 @@ export function emitExpr(E, e) {
1589
1597
  return E.newTemp(e.type, `scr_map_keys_js_order(${obj.name}->${OVERFLOW_MEMBER})`);
1590
1598
  }
1591
1599
  case "dynFrom": {
1592
- // Static value → fresh DOM tree (+1) through the interned per-type
1600
+ // Static value → fresh dyn tree (+1) through the interned per-type
1593
1601
  // converter; the operand stays borrowed (frame-released as usual).
1594
1602
  // Bare unit literals (an `undefined`/`null` stored under an
1595
- // `unknown` index signature) are the DOM unit values directly.
1603
+ // `unknown` index signature) are the dyn unit values directly.
1596
1604
  if (e.value.kind === "unitLit") {
1597
1605
  return E.newTemp(e.type, e.value.unit === "undefined"
1598
1606
  ? "scr_dyn_retain(scr_dyn_undefined())"
@@ -1600,7 +1608,7 @@ export function emitExpr(E, e) {
1600
1608
  }
1601
1609
  const v = E.emitExpr(e.value);
1602
1610
  if (v.type.kind === "func") {
1603
- // 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 +
1604
1612
  // the per-signature call thunk + the interned signature key. The
1605
1613
  // best-effort name rides along for inspect/error rendering (NULL
1606
1614
  // when the lowering had none).
@@ -1612,8 +1620,8 @@ export function emitExpr(E, e) {
1612
1620
  return E.newTemp(e.type, `${E.toDynHelper(v.type)}(${v.name})`);
1613
1621
  }
1614
1622
  case "dynFromJsval": {
1615
- // Island value → DOM: the by-reference wrap (scr_dyn_from_jsval
1616
- // 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
1617
1625
  // kinds at wrap time). Operand borrowed, result +1, never throws.
1618
1626
  const v = E.emitExpr(e.value);
1619
1627
  return E.newTemp(e.type, `scr_dyn_from_jsval(${v.name})`);
@@ -1627,11 +1635,11 @@ export function emitExpr(E, e) {
1627
1635
  const callee = E.emitExpr(e.callee);
1628
1636
  const what = cStringLiteral(Buffer.from(e.calleeName, "utf8"));
1629
1637
  if (e.spreads !== undefined && e.spreads.length > 0) {
1630
- // The RUNTIME-ARITY form (`f(...args)`): one fresh DOM array
1638
+ // The RUNTIME-ARITY form (`f(...args)`): one fresh dyn array
1631
1639
  // collects the arguments left-to-right — plain args move in
1632
1640
  // (push takes ownership), spread args FLATTEN (push_spread
1633
1641
  // retains elements in and throws V8's spread-call TypeError for
1634
- // non-iterable DOM kinds, checked per spread — JS's
1642
+ // non-iterable dyn kinds, checked per spread — JS's
1635
1643
  // ArgumentListEvaluation order) — then apply calls through the
1636
1644
  // array's elements (borrowed, exactly scr_dyn_call).
1637
1645
  const spreadAt = new Map(e.spreads.map((s) => [s.arg, s.what]));
@@ -1677,7 +1685,7 @@ export function emitExpr(E, e) {
1677
1685
  return E.fallibleTemp(e.type, `scr_dyn_invoke(${recv.name}, ${method}, ${argsExpr}, ${args.length}, ${what})`);
1678
1686
  }
1679
1687
  case "dynArrLit": {
1680
- // A DOM array built element-by-element: ownership of each dyn
1688
+ // A dyn array built element-by-element: ownership of each dyn
1681
1689
  // element MOVES into the array (scr_dyn_arr_push's contract).
1682
1690
  const arr = E.newTemp(e.type, "scr_dyn_new_arr()");
1683
1691
  for (const el of e.elems) {
@@ -1688,7 +1696,7 @@ export function emitExpr(E, e) {
1688
1696
  return arr;
1689
1697
  }
1690
1698
  case "dynObjLit": {
1691
- // A DOM object built member-by-member: key then value, source
1699
+ // A dyn object built member-by-member: key then value, source
1692
1700
  // order (JS's literal evaluation). scr_dyn_key_set BORROWS all
1693
1701
  // three (the member retains the value in), so key/value temps
1694
1702
  // release with the frame as usual; the receiver is a fresh OBJ,
@@ -1882,7 +1890,7 @@ export function emitExpr(E, e) {
1882
1890
  return E.newTemp(e.type, `${u.name}->tag ${e.negated ? "!=" : "=="} ${e.tag}`);
1883
1891
  }
1884
1892
  case "dynKeyGet": {
1885
- // 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
1886
1894
  // non-optional form throws JS's TypeError on an undefined/null
1887
1895
  // receiver, and HANDLE receivers can throw the loud unmodeled-
1888
1896
  // property ladder on EITHER form, so both ride a fallible temp;
@@ -1919,7 +1927,7 @@ export function emitExpr(E, e) {
1919
1927
  const r = E.emitExpr(e.right);
1920
1928
  const [d, s, st] = e.left.type.kind === "dyn" ? [l, r, e.right.type] : [r, l, e.left.type];
1921
1929
  const test = st.kind === "dyn"
1922
- ? // dyn vs dyn: whole-DOM strict equality (scalars by value,
1930
+ ? // dyn vs dyn: whole-dyn strict equality (scalars by value,
1923
1931
  // units by kind, reference kinds by node identity).
1924
1932
  `scr_dyn_strict_eq(${l.name}, ${r.name})`
1925
1933
  : st.kind === "string"
@@ -1930,7 +1938,7 @@ export function emitExpr(E, e) {
1930
1938
  return E.newTemp(e.type, e.negated ? `!${test}` : test);
1931
1939
  }
1932
1940
  case "dynTest": {
1933
- // 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
1934
1942
  // form also reads a scalar payload. ISLAND-held nodes (the jsval
1935
1943
  // kind — engine objects/arrays/functions only, scalars normalize
1936
1944
  // at wrap time) route the tests that depend on the engine's
@@ -1946,20 +1954,20 @@ export function emitExpr(E, e) {
1946
1954
  // engine's own typeof.
1947
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"))`
1948
1956
  : e.test === "truthy"
1949
- ? // ToBoolean over the DOM: bool by value; number falsy for
1957
+ ? // ToBoolean over the checked-dynamic tree: bool by value; number falsy for
1950
1958
  // 0, -0 (== 0 in C), and NaN (self-inequality); string
1951
1959
  // falsy when empty; obj/arr/bytes/func/handle always true;
1952
1960
  // JSVAL through the runtime's routed arm (the bigint 0n
1953
1961
  // edge); the remaining kinds (undefined, null) always false.
1954
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))`
1955
1963
  : e.test === "error"
1956
- ? // `u instanceof Error`: the DOM's error encoding — an
1964
+ ? // `u instanceof Error`: the checked-dynamic tree's error encoding — an
1957
1965
  // object carrying the reserved "%error" marker key
1958
1966
  // (built by caughtToDyn for Error payloads) — or a real
1959
1967
  // engine Error held by reference.
1960
1968
  `((${d.name}->kind == SCR_DYN_OBJ && scr_dyn_obj_get(${d.name}, "%error", 6) != NULL) || scr_dyn_isl_is_error(${d.name}))`
1961
1969
  : e.test === "array"
1962
- ? // 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
1963
1971
  // own answer for an engine-held value.
1964
1972
  `(${d.name}->kind == SCR_DYN_ARR || scr_dyn_isl_is_array(${d.name}))`
1965
1973
  : e.test === "function"
@@ -2022,7 +2030,7 @@ export function emitExpr(E, e) {
2022
2030
  throw new Error(`emitter bug: caughtNarrow to ${e.type.kind}`);
2023
2031
  }
2024
2032
  case "caughtToDyn": {
2025
- // The caught snapshot converting to a dyn DOM value (an unknown
2033
+ // The caught snapshot converting to a dyn value (an unknown
2026
2034
  // slot) — the interned runtime-kind dispatch. Box borrowed; the
2027
2035
  // result is a fresh tree (+1). Never throws.
2028
2036
  const c = E.emitExpr(e.value);
@@ -2083,7 +2091,7 @@ export function emitExpr(E, e) {
2083
2091
  const rc = vAdapters(t);
2084
2092
  if (t.kind === "dyn") {
2085
2093
  // The thrown-dyn representation (REF + dyn adapters): catch
2086
- // bindings and the unhandled dispatch see the DOM value
2094
+ // bindings and the unhandled dispatch see the dyn value
2087
2095
  // itself — identity preserved.
2088
2096
  E.line(`scr_throw_ref(${reason.name}, &${rc.retain}, &${rc.release}, NULL);${E.srcComment(e.loc)}`);
2089
2097
  }
@@ -2222,11 +2230,11 @@ export function emitExpr(E, e) {
2222
2230
  // abandons (releases are NULL-tolerant).
2223
2231
  return finish(`(scr_jsval_cast_fail(${arg(0)}, ${arg(1)}), NULL)`);
2224
2232
  case "json.parse":
2225
- // 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
2226
2234
  // catchable SyntaxError-shaped string (may-throw seed set).
2227
2235
  return finish(`scr_json_parse(${arg(0)})`);
2228
2236
  case "dyn.defineProps":
2229
- // Object.defineProperties over DOM values: both borrowed,
2237
+ // Object.defineProperties over dyn values: both borrowed,
2230
2238
  // result the target (+1); throws catchably (may-throw seed).
2231
2239
  return finish(`scr_dyn_define_props(${arg(0)}, ${arg(1)})`);
2232
2240
  case "dyn.keySet":
@@ -2235,12 +2243,20 @@ export function emitExpr(E, e) {
2235
2243
  // non-object receivers (may-throw seed set).
2236
2244
  return finish(`scr_dyn_key_set(${arg(0)}, ${arg(1)}, ${arg(2)})`);
2237
2245
  case "dyn.iterPack":
2238
- // Destructuring pack over a dyn source: both borrowed, fresh
2239
- // array +1; throws V8's destructuring TypeError on
2240
- // 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).
2241
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)})`);
2242
2258
  case "dyn.typeof":
2243
- // 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).
2244
2260
  return finish(`scr_dyn_typeof(${arg(0)})`);
2245
2261
  case "dyn.toString":
2246
2262
  // Receiver-kind-dispatched toString (+1); throws Node's
@@ -2477,10 +2493,14 @@ export function emitExpr(E, e) {
2477
2493
  return finish(`scr_math_max_arr(${arg(0)})`);
2478
2494
  case "math.minArr":
2479
2495
  return finish(`scr_math_min_arr(${arg(0)})`);
2480
- // Math.floor — C floor() IS the JS operation (math.h is always
2481
- // included). Borrows nothing; no throw.
2496
+ // Math.floor/trunc/ceil — the C functions ARE the JS operations
2497
+ // (math.h is always included). Borrow nothing; no throw.
2482
2498
  case "math.floor":
2483
2499
  return finish(`floor(${arg(0)})`);
2500
+ case "math.trunc":
2501
+ return finish(`trunc(${arg(0)})`);
2502
+ case "math.ceil":
2503
+ return finish(`ceil(${arg(0)})`);
2484
2504
  // Math.abs — C fabs IS the JS operation. Math.round — the JS
2485
2505
  // half-toward-+Infinity rule (scr_lib.c; C round() differs on
2486
2506
  // halves and naive floor(x+0.5) drifts at the epsilon boundary).
@@ -2519,7 +2539,7 @@ export function emitExpr(E, e) {
2519
2539
  // borrows, +1 result, never throws.
2520
2540
  case "regexp.escape":
2521
2541
  return finish(`scr_regexp_escape(${arg(0)})`);
2522
- // The WHATWG base64 globals (scr_string.c): DOM arg borrowed
2542
+ // The WHATWG base64 globals (scr_string.c): dyn arg borrowed
2523
2543
  // (WebIDL ToString in the runtime), +1 string result; malformed
2524
2544
  // input throws the catchable DOMException InvalidCharacterError
2525
2545
  // (may-throw seed set). The zero-argument form always throws
@@ -4785,7 +4805,7 @@ export function emitExpr(E, e) {
4785
4805
  // Borrowed receiver; +1 "name: message" (Node's toString rules).
4786
4806
  return finish(`scr_error_to_string(${arg(0)})`);
4787
4807
  case "error.newDom":
4788
- // new DOMException(message?, nameOrOptions?) — both DOM args
4808
+ // new DOMException(message?, nameOrOptions?) — both dyn args
4789
4809
  // borrowed (WebIDL resolution runs in the runtime); +1
4790
4810
  // %DOMException. Never throws.
4791
4811
  return finish(`scr_domex_new(${arg(0)}, ${arg(1)})`);
@@ -4796,7 +4816,7 @@ export function emitExpr(E, e) {
4796
4816
  // `'cause' in e` — the options form's own-property record.
4797
4817
  return finish(`scr_domex_has_cause(${arg(0)})`);
4798
4818
  case "error.domCause":
4799
- // +1 cause DOM value (the DOM undefined when absent).
4819
+ // +1 cause dyn value (the dyn undefined when absent).
4800
4820
  return finish(`scr_domex_cause(${arg(0)})`);
4801
4821
  case "error.domClone":
4802
4822
  // WebIDL serialization: name/message copy, code re-derives.
@@ -4806,7 +4826,7 @@ export function emitExpr(E, e) {
4806
4826
  case "dyn.objKeys":
4807
4827
  return finish(`scr_dyn_obj_keys(${arg(0)})`);
4808
4828
  case "dyn.assign":
4809
- // Object.assign over DOM values: own members copy, the target
4829
+ // Object.assign over dyn values: own members copy, the target
4810
4830
  // returns (+1); non-object receivers throw like Node.
4811
4831
  return finish(`scr_dyn_assign(${arg(0)}, ${arg(1)})`);
4812
4832
  case "dyn.packPush":
@@ -4831,7 +4851,7 @@ export function emitExpr(E, e) {
4831
4851
  // (+1). Never throws.
4832
4852
  return finish(`scr_dyn_new_obj_null_proto()`);
4833
4853
  case "dyn.hasOwn":
4834
- // Object.hasOwn over a DOM receiver (throws on nullish, like
4854
+ // Object.hasOwn over a dyn receiver (throws on nullish, like
4835
4855
  // Node's ToObject).
4836
4856
  return finish(`scr_dyn_has_own(${arg(0)}, ${arg(1)})`);
4837
4857
  case "dyn.objValues":
@@ -4839,11 +4859,11 @@ export function emitExpr(E, e) {
4839
4859
  case "dyn.objEntries":
4840
4860
  return finish(`scr_dyn_obj_entries(${arg(0)})`);
4841
4861
  case "dyn.errInstanceof":
4842
- // The from_error cache resolves the DOM value to its runtime
4862
+ // The from_error cache resolves the dyn value to its runtime
4843
4863
  // error; the class's stamped interval answers. Never throws.
4844
4864
  return finish(`scr_dyn_err_instanceof(${arg(0)}, ${arg(1)})`);
4845
4865
  case "dyn.structuredClone":
4846
- // Deep DOM clone (+1); option/DataClone/cycle errors throw
4866
+ // Deep dyn clone (+1); option/DataClone/cycle errors throw
4847
4867
  // (may-throw seed set). Both args borrowed.
4848
4868
  return finish(`scr_structured_clone(${arg(0)}, ${arg(1)})`);
4849
4869
  case "dyn.cloneMissing":
@@ -5097,6 +5117,18 @@ export function emitExpr(E, e) {
5097
5117
  const list = Array.from({ length: n }, (_, i) => `(ScrStream *)${arg(1 + i)}`).join(", ");
5098
5118
  return finish(`scr_sp_pipeline(${n}, (ScrStream *[]){ ${list} })`);
5099
5119
  }
5120
+ case "sc.text":
5121
+ // stream/consumers: +1 pending promises the accumulate-and-
5122
+ // settle machinery resolves or rejects (the stream's
5123
+ // error / premature close / json's SyntaxError).
5124
+ E.usesTimers = true;
5125
+ return finish(`scr_sc_text((ScrStream *)${arg(0)})`);
5126
+ case "sc.json":
5127
+ E.usesTimers = true;
5128
+ return finish(`scr_sc_json((ScrStream *)${arg(0)})`);
5129
+ case "sc.buffer":
5130
+ E.usesTimers = true;
5131
+ return finish(`scr_sc_buffer((ScrStream *)${arg(0)})`);
5100
5132
  case "readable.newDyn":
5101
5133
  case "writable.newDyn":
5102
5134
  case "duplex.newDyn":
@@ -5152,6 +5184,14 @@ export function emitExpr(E, e) {
5152
5184
  case "readable.pushStr":
5153
5185
  E.usesTimers = true;
5154
5186
  return finish(`scr_stream_push_str((ScrStream *)${arg(0)}, ${arg(1)})`);
5187
+ case "readable.pushStrEnc":
5188
+ // push(chunk, enc) with a literal non-utf8 encoding.
5189
+ E.usesTimers = true;
5190
+ return finish(`scr_stream_push_str_enc((ScrStream *)${arg(0)}, ${arg(1)}, ${arg(2)})`);
5191
+ case "readable.pushEncoding":
5192
+ // The defaultEncoding option's push side (chaining, +1).
5193
+ E.usesTimers = true;
5194
+ return finish(`(${cType(e.type).trim()})scr_stream_set_push_encoding((ScrStream *)${arg(0)}, ${arg(1)})`);
5155
5195
  case "readable.pushNull":
5156
5196
  E.usesTimers = true;
5157
5197
  return finish(`scr_stream_push_null((ScrStream *)${arg(0)})`);
@@ -5378,7 +5418,7 @@ export function emitExpr(E, e) {
5378
5418
  return finish(`scr_assert_eq_sym(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`);
5379
5419
  case "assert.eqDyn":
5380
5420
  // The quartet over checked-dynamic operands: SameValue /
5381
- // DOM-walk deep equality, assertion_error.js messages.
5421
+ // dyn-walk deep equality, assertion_error.js messages.
5382
5422
  return finish(`scr_assert_eq_dyn(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`);
5383
5423
  case "assert.deepResult":
5384
5424
  return finish(`scr_assert_deep_result(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)})`);
@@ -5643,14 +5683,14 @@ export function emitExpr(E, e) {
5643
5683
  }
5644
5684
  case "jsonStringify": {
5645
5685
  // Type-directed serialization: the STATIC type picks an emitted
5646
- // serializer (interned per type) — no DOM, no runtime dispatch. The
5686
+ // serializer (interned per type) — no dyn, no runtime dispatch. The
5647
5687
  // value temp is BORROWED (released with this statement's frame);
5648
5688
  // the result string is owned (+1). Throws only over CYCLE-CAPABLE
5649
5689
  // types (recursive records — the circular-structure TypeError) and
5650
5690
  // dyn roots; everything else keeps the throw-free path.
5651
5691
  const v = E.emitExpr(e.value);
5652
- // A dyn root: the runtime's DOM walker (scr_dyn_format_j — the %j
5653
- // 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/
5654
5694
  // null/array/object exact, dropped members omitted, a dropped ROOT
5655
5695
  // becomes the text "undefined", a runtime handle inside the tree
5656
5696
  // throws) — fallible, so the pending-exception check runs.
@@ -5682,7 +5722,7 @@ export function emitExpr(E, e) {
5682
5722
  return E.newTemp(e.type, `${E.jsonIndentHelper()}(${compact.name}, ${cStringLiteral(bytes)}, ${bytes.length})`);
5683
5723
  }
5684
5724
  case "dynCheck": {
5685
- // The dynamic boundary: validate the DOM against the target type
5725
+ // The dynamic boundary: validate the checked-dynamic tree against the target type
5686
5726
  // and BUILD the typed value (+1) — or throw a catchable
5687
5727
  // TypeError-shaped, path-annotated string. The dyn temp is BORROWED;
5688
5728
  // the result joins the frame BEFORE the pending check so an unwind
@@ -5834,7 +5874,7 @@ export function emitExpr(E, e) {
5834
5874
  return { name: "", type: e.type };
5835
5875
  }
5836
5876
  case "dyn":
5837
- // The DOM-crossing await: void fulfillments (a boxed
5877
+ // The checked-dynamic tree-crossing await: void fulfillments (a boxed
5838
5878
  // promise<void> that skipped its adapter) answer the
5839
5879
  // undefined VALUE, never NULL.
5840
5880
  read = `scr_await_dyn(${pr.name})`;
@@ -6039,7 +6079,7 @@ export function emitExpr(E, e) {
6039
6079
  case "string":
6040
6080
  return E.newTemp(e.type, `scr_jsval_from_str(${v.name})`);
6041
6081
  case "dyn":
6042
- // A CHECKED-DYNAMIC (DOM) value entering the island: deep
6082
+ // A CHECKED-DYNAMIC (dyn) value entering the island: deep
6043
6083
  // copy, data kinds only — boxed functions/handles/promises
6044
6084
  // throw the catchable TypeError in the runtime.
6045
6085
  return E.fallibleTemp(e.type, `scr_jsval_from_dyn(${v.name})`);
@@ -6050,6 +6090,20 @@ export function emitExpr(E, e) {
6050
6090
  case "url":
6051
6091
  // A URL crossing IN: an engine URL instance built from href.
6052
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
+ }
6053
6107
  case "func": {
6054
6108
  // A closure entering the island as a host function (the
6055
6109
  // package-callback pattern). from_closure retains the closure;
@@ -6226,10 +6280,19 @@ export function emitExpr(E, e) {
6226
6280
  // emits u8 targets (canExitIslandToType).
6227
6281
  return E.fallibleTemp(e.type, `scr_jsval_exit_bytes(${v.name})`);
6228
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
+ }
6229
6290
  // An undefined-armed union target: the engine's undefined takes
6230
6291
  // the undefined arm FIRST — JSON cannot spell it (to_json would
6231
6292
  // refuse the exit) — then null and data ride the round trip
6232
- // 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).
6233
6296
  const undefTag = e.type.kind === "union" ? E.undefinedArmTag(e.type) : -1;
6234
6297
  if (e.type.kind === "union" && undefTag >= 0) {
6235
6298
  const name = `sc_t${E.tempCounter++}`;
@@ -6241,11 +6304,23 @@ export function emitExpr(E, e) {
6241
6304
  E.line(`} else {`);
6242
6305
  E.indent++;
6243
6306
  E.frames.push([]);
6244
- const json = E.fallibleTemp(STRING, `scr_jsval_to_json(${v.name})`);
6245
- const dom = E.fallibleTemp(DYN, `scr_json_parse(${json.name})`);
6246
- const out = E.fallibleTemp(e.type, `${E.dynCheckHelper(e.type)}(${dom.name}, NULL)`);
6247
- E.moveTemp(out);
6248
- 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
+ }
6249
6324
  E.releaseFrame(E.frames.pop());
6250
6325
  E.indent--;
6251
6326
  E.line(`}`);
@@ -6267,7 +6342,9 @@ export function emitExpr(E, e) {
6267
6342
  const v = E.emitExpr(e.value);
6268
6343
  const payload = e.type.kind === "promise" && e.type.inner.kind === "void"
6269
6344
  ? "SCR_ISLP_VOID"
6270
- : "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";
6271
6348
  return E.fallibleTemp(e.type, `scr_jsval_bridge_promise(${v.name}, ${payload})`);
6272
6349
  }
6273
6350
  default: {