@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
@@ -1,4 +1,4 @@
1
- import { canMarshalFuncIntoIsland, CAUGHT, DYN, F64, islandCallbackRet, isRefCounted, isUnitType, MAY_THROW_LIB_FNS, moduleUsesDynInvoke, moduleUsesFetch, moduleUsesFsWatch, moduleUsesHttpServer, moduleUsesNet, moduleUsesProcessEvents, moduleUsesStream, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, STRING, typeEquals, typeKey, VOID } from "../../ir/nodes.js";
1
+ import { canMarshalFuncIntoIsland, CAUGHT, DYN, F64, islandCallbackRet, islandPromisePayloadTag, isRefCounted, isUnitType, MAY_THROW_LIB_FNS, moduleUsesDynInvoke, moduleUsesFetch, moduleUsesFsWatch, moduleUsesHttpServer, moduleUsesNet, moduleUsesProcessEvents, moduleUsesStream, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, STRING, typeEquals, typeKey, VOID } from "../../ir/nodes.js";
2
2
  import { computeMayThrow } from "../emission/may-throw.js";
3
3
  import { mangleArgPack, mangleAsyncSpawn, mangleClassNew, mangleClassObj, mangleClassRetain, mangleFnClosure, mangleFunction, mangleGenDrop, mangleGenResThunk, mangleGenSpawn, mangleGlobal, mangleLocal, mangleRecordNew, mangleRecordStruct, mangleResolveThunk, mangleTrampoline, mangleVtStruct, mangleWrapper } from "../mangle.js";
4
4
  import { BlockBuilder } from "./blocks.js";
@@ -340,7 +340,7 @@ const LIB_FN_SYMS = {
340
340
  "sym.toString": "scr_sym_to_string",
341
341
  "error.toString": "scr_error_to_string",
342
342
  "class.name": "scr_classobj_name",
343
- // The dyn (ScrDyn DOM) surface (scr_json.c / scr_dyn_invoke.c):
343
+ // The dyn (ScrDyn dyn) surface (scr_json.c / scr_dyn_invoke.c):
344
344
  // json.parse throws the catchable SyntaxError; keySet/toString/
345
345
  // defineProps throw Node's TypeErrors (all in the may-throw seed set —
346
346
  // the generic path emits the standard pending check). typeof and the
@@ -348,6 +348,8 @@ const LIB_FN_SYMS = {
348
348
  "json.parse": "scr_json_parse",
349
349
  "dyn.keySet": "scr_dyn_key_set",
350
350
  "dyn.iterPack": "scr_dyn_iter_pack",
351
+ "dyn.arrLen": "scr_dyn_arr_len",
352
+ "dyn.arrAt": "scr_dyn_arr_at",
351
353
  "dyn.defineProps": "scr_dyn_define_props",
352
354
  "dyn.typeof": "scr_dyn_typeof",
353
355
  "dyn.toString": "scr_dyn_to_string_method",
@@ -535,7 +537,7 @@ const LIB_FN_SYMS = {
535
537
  "dc.tcTraceCallback": "scr_dc_tc_trace_callback",
536
538
  "dc.tcTracePromise": "scr_dc_tc_trace_promise",
537
539
  // AsyncLocalStorage (scr_async_dyn.c): store ids are doubles, values
538
- // ride the DOM; run/exitRun dispatch user callbacks (may-throw).
540
+ // ride the checked-dynamic tree; run/exitRun dispatch user callbacks (may-throw).
539
541
  // The dc bind-store trio shares the als id space.
540
542
  "als.new": "scr_als_new",
541
543
  "als.get": "scr_als_get",
@@ -547,7 +549,7 @@ const LIB_FN_SYMS = {
547
549
  "dc.chanUnbindStore": "scr_dc_chan_unbind_store",
548
550
  "dc.chanRunStores": "scr_dc_chan_run_stores",
549
551
  // process warning/rejection events (scr_lib.c / scr_async_dyn.c):
550
- // DOM listeners are borrowed (the runtime retains its copy);
552
+ // dyn listeners are borrowed (the runtime retains its copy);
551
553
  // onUnhandledRejection marks the loop live (the loop-end report
552
554
  // dispatches the listeners).
553
555
  "process.onWarning": "scr_process_on_warning",
@@ -568,7 +570,7 @@ const LIB_FN_SYMS = {
568
570
  "regexp.escape": "scr_regexp_escape",
569
571
  // The dyn Object walks (throw on nullish receivers), structuredClone
570
572
  // (option/DataClone/cycle errors), and new RegExp's eager compile
571
- // (catchable SyntaxError) — all may-throw generics over the DOM.
573
+ // (catchable SyntaxError) — all may-throw generics over the checked-dynamic tree.
572
574
  "dyn.objKeys": "scr_dyn_obj_keys",
573
575
  "dyn.hasOwn": "scr_dyn_has_own",
574
576
  "dyn.assign": "scr_dyn_assign",
@@ -719,7 +721,7 @@ class LlEmitter {
719
721
  * rewriter, union ToString/join) — interned per typeKey/unionId, defs
720
722
  * flushed with the shape helpers. */
721
723
  walkers = new LlWalkers(this);
722
- /** The dyn (ScrDyn DOM) helper registry — dyn.ts's interned ports of
724
+ /** The dyn (ScrDyn dyn) helper registry — dyn.ts's interned ports of
723
725
  * emit-walkers.ts's dyn slice. */
724
726
  dyn = new LlDyn(this);
725
727
  /** External declarations, in first-use order. */
@@ -2036,7 +2038,7 @@ class LlEmitter {
2036
2038
  return t;
2037
2039
  }
2038
2040
  case "dyn": {
2039
- // ToBoolean over the DOM kind (scr_dyn_truthy — JS-exact for
2041
+ // ToBoolean over the dyn kind (scr_dyn_truthy — JS-exact for
2040
2042
  // every kind; borrowed, never throws): `v || dflt` and condition
2041
2043
  // descent on checked-dynamic values.
2042
2044
  this.declare(`declare zeroext i1 @scr_dyn_truthy(ptr)`);
@@ -3714,7 +3716,7 @@ class LlEmitter {
3714
3716
  return this.own({ name: t, type: e.type });
3715
3717
  }
3716
3718
  if (v.type.kind === "dyn") {
3717
- // String(unknown): dispatch over the DOM kind (dyn.ts's sc_ds —
3719
+ // String(unknown): dispatch over the dyn kind (dyn.ts's sc_ds —
3718
3720
  // Node's String() incl. arrays-join and "[object Object]").
3719
3721
  const helper = this.dyn.dynToStrHelper();
3720
3722
  const t = B.tmp();
@@ -4015,7 +4017,7 @@ class LlEmitter {
4015
4017
  this.unionTagSwitch(u.name, def, (arm) => {
4016
4018
  if (isUnitType(arm)) {
4017
4019
  if (e.type.kind === "dyn") {
4018
- // A dyn-typed chain: the unit path is the undefined DOM
4020
+ // A dyn-typed chain: the unit path is the undefined dyn
4019
4021
  // value — dyn represents undefined directly.
4020
4022
  this.declare(`declare ptr @scr_dyn_undefined()`);
4021
4023
  this.declare(`declare ptr @scr_dyn_retain_v(ptr)`);
@@ -4311,9 +4313,9 @@ class LlEmitter {
4311
4313
  // the frame's release is a no-op) and the body reads it through
4312
4314
  // chainRecv.
4313
4315
  if (e.receiver.type.kind === "dyn") {
4314
- // A dyn (DOM) receiver — the `rawName?.match(re)` step: the
4316
+ // A dyn (dyn) receiver — the `rawName?.match(re)` step: the
4315
4317
  // nullish test reads the node's kind tag; the unit path is the
4316
- // undefined DOM singleton (dyn results) or nothing (void
4318
+ // undefined dyn singleton (dyn results) or nothing (void
4317
4319
  // bodies), the body runs over the bound receiver otherwise.
4318
4320
  const r = this.emitExpr(e.receiver);
4319
4321
  const kd = this.dynKind(r.name);
@@ -4465,7 +4467,7 @@ class LlEmitter {
4465
4467
  }
4466
4468
  if (e.type.kind === "dyn") {
4467
4469
  // A dyn-typed chain (`pricing?.[key]` over an unknown-valued
4468
- // index signature): the unit path is the undefined DOM value —
4470
+ // index signature): the unit path is the undefined dyn value —
4469
4471
  // dyn represents undefined directly, no union wrapper exists.
4470
4472
  const slotD = B.slot();
4471
4473
  B.entryAllocas.push(`${slotD} = alloca ptr`);
@@ -4912,14 +4914,14 @@ class LlEmitter {
4912
4914
  }
4913
4915
  case "jsonStringify": {
4914
4916
  // Type-directed serialization: the STATIC type picks an emitted
4915
- // serializer (interned per typeKey) — no DOM, no runtime dispatch.
4917
+ // serializer (interned per typeKey) — no dyn, no runtime dispatch.
4916
4918
  // The value temp is BORROWED (released with this statement's
4917
4919
  // frame); the result string is owned (+1). Never throws — except
4918
4920
  // the dyn root below.
4919
4921
  const v = this.emitExpr(e.value);
4920
4922
  let compact;
4921
4923
  if (e.value.type.kind === "dyn") {
4922
- // A dyn root: the runtime's DOM walker (scr_dyn_format_j — the
4924
+ // A dyn root: the runtime's dyn walker (scr_dyn_format_j — the
4923
4925
  // C backend's dispatch exactly): number/string/bool/null/array/
4924
4926
  // object exact, dropped members omitted, and a dropped ROOT
4925
4927
  // becomes the TEXT "undefined" (JSON.stringify(undefined) is
@@ -5084,7 +5086,7 @@ class LlEmitter {
5084
5086
  if (e.arg === null) {
5085
5087
  if (genT.nextT.kind === "dyn") {
5086
5088
  // Valueless resume on a dyn channel: JS's undefined — the
5087
- // DOM singleton rides the IN slot (+1 moves in).
5089
+ // dyn singleton rides the IN slot (+1 moves in).
5088
5090
  this.declare(`declare ptr @scr_dyn_undefined()`);
5089
5091
  this.declare(`declare ptr @scr_dyn_retain_v(ptr)`);
5090
5092
  this.declare(`declare void @scr_dyn_release_v(ptr)`);
@@ -5552,10 +5554,10 @@ class LlEmitter {
5552
5554
  return { name: "", type: e.type };
5553
5555
  }
5554
5556
  case "dynFrom": {
5555
- // Static value → fresh DOM tree (+1) through the interned per-type
5557
+ // Static value → fresh dyn tree (+1) through the interned per-type
5556
5558
  // converter; the operand stays borrowed (frame-released as usual).
5557
5559
  // Bare unit literals (an `undefined`/`null` stored under an
5558
- // `unknown` index signature) are the DOM unit values directly.
5560
+ // `unknown` index signature) are the dyn unit values directly.
5559
5561
  if (e.value.kind === "unitLit") {
5560
5562
  const t = B.tmp();
5561
5563
  if (e.value.unit === "undefined") {
@@ -5573,7 +5575,7 @@ class LlEmitter {
5573
5575
  }
5574
5576
  const v = this.emitExpr(e.value);
5575
5577
  if (v.type.kind === "func") {
5576
- // A closure boxes as the DOM's function kind: retained closure +
5578
+ // A closure boxes as the checked-dynamic tree's function kind: retained closure +
5577
5579
  // the per-signature call thunk + the interned signature key. The
5578
5580
  // best-effort name rides along (null when the lowering had none).
5579
5581
  const name = e.fnName !== undefined && e.fnName !== "" ? this.cstr(e.fnName) : "null";
@@ -5589,8 +5591,8 @@ class LlEmitter {
5589
5591
  return this.own({ name: t, type: e.type });
5590
5592
  }
5591
5593
  case "dynFromJsval": {
5592
- // Island value → DOM: the by-reference wrap (scr_dyn_from_jsval
5593
- // retains the cell in; engine scalars normalize to native DOM
5594
+ // Island value → dyn: the by-reference wrap (scr_dyn_from_jsval
5595
+ // retains the cell in; engine scalars normalize to native dyn
5594
5596
  // kinds at wrap time). Operand borrowed, result +1, never throws.
5595
5597
  const v = this.emitExpr(e.value);
5596
5598
  this.declare(`declare ptr @scr_dyn_from_jsval(ptr)`);
@@ -5609,7 +5611,7 @@ class LlEmitter {
5609
5611
  return this.own({ name: t, type: e.type });
5610
5612
  }
5611
5613
  case "dynCheck": {
5612
- // The dynamic boundary: validate the DOM against the target type
5614
+ // The dynamic boundary: validate the checked-dynamic tree against the target type
5613
5615
  // and BUILD the typed value (+1) — or throw the catchable
5614
5616
  // path-annotated TypeError. The dyn temp is BORROWED; the result
5615
5617
  // joins the frame BEFORE the pending check so an unwind releases
@@ -5630,11 +5632,11 @@ class LlEmitter {
5630
5632
  // spelling rides along for Node's "<name> is not a function".
5631
5633
  const callee = this.emitExpr(e.callee);
5632
5634
  if (e.spreads !== undefined && e.spreads.length > 0) {
5633
- // The RUNTIME-ARITY form (`f(...args)`): one fresh DOM array
5635
+ // The RUNTIME-ARITY form (`f(...args)`): one fresh dyn array
5634
5636
  // collects the arguments left-to-right — plain args move in
5635
5637
  // (push takes ownership), spread args FLATTEN (push_spread
5636
5638
  // retains elements in and throws V8's spread-call TypeError for
5637
- // non-iterable DOM kinds, checked per spread — JS's
5639
+ // non-iterable dyn kinds, checked per spread — JS's
5638
5640
  // ArgumentListEvaluation order) — then apply calls through the
5639
5641
  // array's elements (borrowed, exactly scr_dyn_call).
5640
5642
  this.declare(`declare ptr @scr_dyn_new_arr()`);
@@ -5707,7 +5709,7 @@ class LlEmitter {
5707
5709
  return out;
5708
5710
  }
5709
5711
  case "dynArrLit": {
5710
- // A DOM array built element-by-element: ownership of each dyn
5712
+ // A dyn array built element-by-element: ownership of each dyn
5711
5713
  // element MOVES into the array (scr_dyn_arr_push's contract).
5712
5714
  this.declare(`declare ptr @scr_dyn_new_arr()`);
5713
5715
  this.declare(`declare void @scr_dyn_arr_push(ptr, ptr)`);
@@ -5722,7 +5724,7 @@ class LlEmitter {
5722
5724
  return out;
5723
5725
  }
5724
5726
  case "dynObjLit": {
5725
- // A DOM object built member-by-member: key then value, source
5727
+ // A dyn object built member-by-member: key then value, source
5726
5728
  // order. scr_dyn_key_set BORROWS all three (the member retains the
5727
5729
  // value in); the receiver is a fresh OBJ, so the non-object throw
5728
5730
  // paths are unreachable here.
@@ -5739,7 +5741,7 @@ class LlEmitter {
5739
5741
  return out;
5740
5742
  }
5741
5743
  case "dynKeyGet": {
5742
- // Keyed read on the DOM through the one interned helper — the
5744
+ // Keyed read on the checked-dynamic tree through the one interned helper — the
5743
5745
  // non-optional form throws JS's TypeError on an undefined/null
5744
5746
  // receiver, and HANDLE receivers can throw the loud unmodeled-
5745
5747
  // property ladder on EITHER form; the result is owned (+1).
@@ -5824,7 +5826,7 @@ class LlEmitter {
5824
5826
  const [d, s, st] = e.left.type.kind === "dyn" ? [l, r, e.right.type] : [r, l, e.left.type];
5825
5827
  let test;
5826
5828
  if (st.kind === "dyn") {
5827
- // dyn vs dyn: whole-DOM strict equality.
5829
+ // dyn vs dyn: whole-dyn strict equality.
5828
5830
  this.declare(`declare zeroext i1 @scr_dyn_strict_eq(ptr, ptr)`);
5829
5831
  test = B.tmp();
5830
5832
  B.line(`${test} = call zeroext i1 @scr_dyn_strict_eq(ptr ${l.name}, ptr ${r.name})`);
@@ -5877,7 +5879,7 @@ class LlEmitter {
5877
5879
  return { name: neg, type: e.type };
5878
5880
  }
5879
5881
  case "dynTest": {
5880
- // A pure kind compare on the DOM node — borrowed; only the truthy
5882
+ // A pure kind compare on the dyn node — borrowed; only the truthy
5881
5883
  // form also reads a scalar payload (the runtime's ToBoolean).
5882
5884
  const d = this.emitExpr(e.value);
5883
5885
  let test;
@@ -5887,7 +5889,7 @@ class LlEmitter {
5887
5889
  B.line(`${test} = call zeroext i1 @scr_dyn_truthy(ptr ${d.name})`);
5888
5890
  }
5889
5891
  else if (e.test === "error") {
5890
- // `u instanceof Error`: the DOM's error encoding — an object
5892
+ // `u instanceof Error`: the checked-dynamic tree's error encoding — an object
5891
5893
  // carrying the reserved "%error" marker key — or a real engine
5892
5894
  // Error held by reference (the isl helper answers false for
5893
5895
  // every non-JSVAL kind, so the call is unconditional).
@@ -5954,7 +5956,7 @@ class LlEmitter {
5954
5956
  test = orIsl(oneOf([DK.OBJ, DK.ARR, DK.BYTES, DK.HANDLE, DK.PROMISE, DK.NULL]), "scr_dyn_isl_typeof_is", this.cstr("object"));
5955
5957
  }
5956
5958
  else if (e.test === "array") {
5957
- // Array.isArray: the DOM's array kind, or the engine's own
5959
+ // Array.isArray: the checked-dynamic tree's array kind, or the engine's own
5958
5960
  // answer for an engine-held value.
5959
5961
  test = orIsl(oneOf([DK.ARR]), "scr_dyn_isl_is_array");
5960
5962
  }
@@ -5980,7 +5982,7 @@ class LlEmitter {
5980
5982
  return { name: neg, type: e.type };
5981
5983
  }
5982
5984
  case "dynDestrCheck": {
5983
- // RequireObjectCoercible with V8's destructuring TypeError. DOM
5985
+ // RequireObjectCoercible with V8's destructuring TypeError. dyn
5984
5986
  // values check in the runtime helper and pass through unchanged
5985
5987
  // (same temp, same ownership); island values check in the engine
5986
5988
  // (a fresh +1 cell for the same value comes back).
@@ -6001,7 +6003,7 @@ class LlEmitter {
6001
6003
  }
6002
6004
  case "dynIterN": {
6003
6005
  // GetIterator + first-N steps as a fresh array (V8's exact
6004
- // not-iterable TypeError on non-iterables): the DOM helper for
6006
+ // not-iterable TypeError on non-iterables): the dyn helper for
6005
6007
  // dyn operands, the engine's real iterator protocol for island
6006
6008
  // ones.
6007
6009
  const v = this.emitExpr(e.value);
@@ -6033,7 +6035,9 @@ class LlEmitter {
6033
6035
  const v = this.emitExpr(e.value);
6034
6036
  const payload = e.type.kind === "promise" && e.type.inner.kind === "void"
6035
6037
  ? 0 // SCR_ISLP_VOID
6036
- : 4; // SCR_ISLP_JSVAL
6038
+ : e.type.kind === "promise" && e.type.inner.kind === "array" && e.type.inner.elem.kind === "jsval"
6039
+ ? 5 // SCR_ISLP_JSVAL_ARR: the Array.isArray-gated by-reference exit at settle
6040
+ : 4; // SCR_ISLP_JSVAL
6037
6041
  this.declare(`declare ptr @scr_jsval_bridge_promise(ptr, i32)`);
6038
6042
  const t = B.tmp();
6039
6043
  B.line(`${t} = call ptr @scr_jsval_bridge_promise(ptr ${v.name}, i32 ${payload})`);
@@ -6081,7 +6085,7 @@ class LlEmitter {
6081
6085
  case "string":
6082
6086
  return simple("scr_jsval_from_str", "ptr", false);
6083
6087
  case "dyn":
6084
- // A CHECKED-DYNAMIC (DOM) value entering the island: deep copy,
6088
+ // A CHECKED-DYNAMIC (dyn) value entering the island: deep copy,
6085
6089
  // data kinds only — boxed functions/handles/promises throw the
6086
6090
  // catchable TypeError in the runtime, and a wrapped island value
6087
6091
  // unwraps to the SAME engine value (the identity round trip).
@@ -6093,6 +6097,25 @@ class LlEmitter {
6093
6097
  case "url":
6094
6098
  // A URL crossing IN: an engine URL instance built from href.
6095
6099
  return simple("scr_jsval_from_url", "ptr", true);
6100
+ case "promise": {
6101
+ // A STATIC promise crossing IN: a real engine thenable settled
6102
+ // when the scriptc promise settles (the async-callback return
6103
+ // bridge). from_promise takes ownership of a +1 — retain past
6104
+ // the borrowed frame temp. The C emitter's rule, mirrored.
6105
+ const tag = islandPromisePayloadTag(e.value.type.inner);
6106
+ if (!tag)
6107
+ throw new Error("llvm emitter bug: jsMarshal of a promise outside the bridge payload domain");
6108
+ const tagN = { void: 0, f64: 1, bool: 2, string: 3, jsval: 4, jsvalArr: 5 }[tag];
6109
+ this.declare(`declare ptr @scr_promise_retain(ptr)`);
6110
+ this.declare(`declare ptr @scr_jsval_from_promise(ptr, i32)`);
6111
+ const pr = B.tmp();
6112
+ B.line(`${pr} = call ptr @scr_promise_retain(ptr ${v.name})`);
6113
+ const t = B.tmp();
6114
+ B.line(`${t} = call ptr @scr_jsval_from_promise(ptr ${pr}, i32 ${tagN})`);
6115
+ const out = this.own({ name: t, type: e.type });
6116
+ this.emitPendingCheck();
6117
+ return out;
6118
+ }
6096
6119
  case "func": {
6097
6120
  // A closure entering the island as a host function: from_closure
6098
6121
  // retains it; the engine's finalizer releases it at teardown. The
@@ -6424,6 +6447,17 @@ class LlEmitter {
6424
6447
  return out;
6425
6448
  }
6426
6449
  default: {
6450
+ // `any[]`-declared slot: Array.isArray-gated, elements BY
6451
+ // REFERENCE (identity crosses; the spine is a snapshot copy).
6452
+ // JSON-safe element types keep the round trip below.
6453
+ if (e.type.kind === "array" && e.type.elem.kind === "jsval") {
6454
+ this.declare(`declare ptr @scr_jsval_exit_jsval_arr(ptr)`);
6455
+ const t = B.tmp();
6456
+ B.line(`${t} = call ptr @scr_jsval_exit_jsval_arr(ptr ${v.name})`);
6457
+ const out = this.own({ name: t, type: e.type });
6458
+ this.emitPendingCheck();
6459
+ return out;
6460
+ }
6427
6461
  // An undefined-armed union target: the engine's undefined takes
6428
6462
  // the undefined arm FIRST (JSON cannot spell it); then null and
6429
6463
  // data ride the round trip into the union's dynCheck like any
@@ -6460,11 +6494,31 @@ class LlEmitter {
6460
6494
  B.br(lj);
6461
6495
  B.startBlock(ld);
6462
6496
  this.frames.push([]);
6463
- const t = roundTrip();
6464
- this.own({ name: t, type: e.type });
6465
- this.emitPendingCheck();
6466
- this.moveTemp({ name: t, type: e.type });
6467
- B.line(`store ptr ${t}, ptr ${slot}`);
6497
+ const unionDef = this.unionsById.get(e.type.unionId);
6498
+ const dataArms = unionDef ? unionDef.arms.flatMap((a, i) => (isUnitType(a) ? [] : [{ a, i }])) : [];
6499
+ const jsvalArr = dataArms.length === 1 && dataArms[0].a.kind === "array" && dataArms[0].a.elem.kind === "jsval" ? dataArms[0] : null;
6500
+ let t;
6501
+ if (jsvalArr) {
6502
+ // The `any[] | undefined` defaulted-parameter spelling: the
6503
+ // engine array exits BY REFERENCE into the data arm.
6504
+ this.declare(`declare ptr @scr_jsval_exit_jsval_arr(ptr)`);
6505
+ this.declare(`declare ptr @scr_union_new_ref(i32, ptr, ptr, ptr, ptr)`);
6506
+ this.declare(`declare ptr @scr_arr_retain_v(ptr)`);
6507
+ this.declare(`declare void @scr_arr_release_v(ptr)`);
6508
+ const arr = B.tmp();
6509
+ B.line(`${arr} = call ptr @scr_jsval_exit_jsval_arr(ptr ${v.name})`);
6510
+ this.emitPendingCheck();
6511
+ t = B.tmp();
6512
+ B.line(`${t} = call ptr @scr_union_new_ref(i32 ${jsvalArr.i}, ptr ${arr}, ptr @scr_arr_retain_v, ptr @scr_arr_release_v, ptr null)`);
6513
+ B.line(`store ptr ${t}, ptr ${slot}`);
6514
+ }
6515
+ else {
6516
+ t = roundTrip();
6517
+ this.own({ name: t, type: e.type });
6518
+ this.emitPendingCheck();
6519
+ this.moveTemp({ name: t, type: e.type });
6520
+ B.line(`store ptr ${t}, ptr ${slot}`);
6521
+ }
6468
6522
  this.releaseFrame(this.frames.pop());
6469
6523
  B.br(lj);
6470
6524
  B.startBlock(lj);
@@ -6677,7 +6731,7 @@ class LlEmitter {
6677
6731
  d.push(` %r = call ptr %fn(${passed.join(", ")})`, ` %rn = icmp eq ptr %r, null`, ` br i1 %rn, label %snull, label %sok`, `snull:`, ` ret ptr null`, `sok:`, ` %j = call ptr @scr_jsval_from_str(ptr %r)`, ` call void @scr_str_release(ptr %r)`, ` ret ptr %j`);
6678
6732
  break;
6679
6733
  case "dyn":
6680
- // A checked-dynamic (+1 DOM) result: deep copy into the engine
6734
+ // A checked-dynamic (+1 dyn) result: deep copy into the engine
6681
6735
  // (the jsMarshal dyn rule); NULL is the throw-path dummy.
6682
6736
  this.declare(`declare ptr @scr_jsval_from_dyn(ptr)`);
6683
6737
  this.declare(`declare void @scr_dyn_release(ptr)`);
@@ -6708,7 +6762,7 @@ class LlEmitter {
6708
6762
  this.resolveThunkDefs.push(...d);
6709
6763
  return sym;
6710
6764
  }
6711
- /** Loads a DOM node's kind tag (i32 at +8) — the dyn expression tests'
6765
+ /** Loads a dyn node's kind tag (i32 at +8) — the dyn expression tests'
6712
6766
  * shared read. */
6713
6767
  dynKind(d) {
6714
6768
  const B = this.B;
@@ -8537,7 +8591,7 @@ class LlEmitter {
8537
8591
  // A dyn JOIN (the C helper's `surface` dyn arm): declared hits
8538
8592
  // convert through the per-type toDyn walker (borrowed read → fresh
8539
8593
  // +1 tree), a dyn-valued overflow hit passes through (+1 from the
8540
- // map get), and a miss is JS's undefined — the DOM singleton.
8594
+ // map get), and a miss is JS's undefined — the dyn singleton.
8541
8595
  this.declare(`declare zeroext i1 @scr_str_eq(ptr, ptr)`);
8542
8596
  for (const f of overflowOnly ? [] : shape.fields) {
8543
8597
  const lit = this.internLiteral(f.name);
@@ -8615,7 +8669,7 @@ class LlEmitter {
8615
8669
  B.br(join);
8616
8670
  B.startBlock(ln);
8617
8671
  }
8618
- // The miss path: JS's undefined — the DOM singleton, retained.
8672
+ // The miss path: JS's undefined — the dyn singleton, retained.
8619
8673
  this.declare(`declare ptr @scr_dyn_undefined()`);
8620
8674
  this.declare(`declare ptr @scr_dyn_retain_v(ptr)`);
8621
8675
  const u = B.tmp();