@scriptc/compiler 0.2.0 → 0.2.1

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 (194) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +25 -15
  2. package/dist/backend/cycle-analysis.js +1 -0
  3. package/dist/backend/cycle-analysis.js.map +1 -1
  4. package/dist/backend/llvm/classes.js +21 -5
  5. package/dist/backend/llvm/classes.js.map +1 -1
  6. package/dist/backend/llvm/dyn.d.ts +5 -0
  7. package/dist/backend/llvm/dyn.js +166 -99
  8. package/dist/backend/llvm/dyn.js.map +1 -1
  9. package/dist/backend/llvm/emitter.d.ts +2 -2
  10. package/dist/backend/llvm/emitter.js +79 -20
  11. package/dist/backend/llvm/emitter.js.map +1 -1
  12. package/dist/backend/llvm/expr-bytes.d.ts +1 -1
  13. package/dist/backend/llvm/expr-bytes.js +28 -17
  14. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  15. package/dist/backend/llvm/expr-control.js +1 -1
  16. package/dist/backend/llvm/expr-control.js.map +1 -1
  17. package/dist/backend/llvm/expr-dynamic.js +18 -9
  18. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  19. package/dist/backend/llvm/expr-primitives.js +11 -1
  20. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  21. package/dist/backend/llvm/expr-records.js +11 -3
  22. package/dist/backend/llvm/expr-records.js.map +1 -1
  23. package/dist/backend/llvm/expr-stream-bridges.js +125 -17
  24. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  25. package/dist/backend/llvm/lib-process.js +23 -3
  26. package/dist/backend/llvm/lib-process.js.map +1 -1
  27. package/dist/backend/llvm/lib-shared.js +45 -2
  28. package/dist/backend/llvm/lib-shared.js.map +1 -1
  29. package/dist/backend/llvm/shapes.js +8 -2
  30. package/dist/backend/llvm/shapes.js.map +1 -1
  31. package/dist/backend/native-toolchain.d.ts +3 -6
  32. package/dist/backend/native-toolchain.js +53 -23
  33. package/dist/backend/native-toolchain.js.map +1 -1
  34. package/dist/backend/native-toolchain.test.js +72 -0
  35. package/dist/backend/native-toolchain.test.js.map +1 -1
  36. package/dist/backend/runtime-abi.d.ts +2 -2
  37. package/dist/backend/runtime-abi.js +2 -2
  38. package/dist/backend/runtime-pack-native.js +4 -1
  39. package/dist/backend/runtime-pack-native.js.map +1 -1
  40. package/dist/backend/runtime-pack-targets.test.js +1 -1
  41. package/dist/backend/runtime-pack.test.js +1 -1
  42. package/dist/backend/targets.js +10 -6
  43. package/dist/backend/targets.js.map +1 -1
  44. package/dist/backend/targets.test.js +7 -0
  45. package/dist/backend/targets.test.js.map +1 -1
  46. package/dist/compat/fetch-profile.js +34 -4
  47. package/dist/compat/fetch-profile.js.map +1 -1
  48. package/dist/diagnostics/diagnostic.js +2 -7
  49. package/dist/diagnostics/diagnostic.js.map +1 -1
  50. package/dist/frontend/lowering/class-callbacks.d.ts +3 -3
  51. package/dist/frontend/lowering/class-callbacks.js +26 -15
  52. package/dist/frontend/lowering/class-callbacks.js.map +1 -1
  53. package/dist/frontend/lowering/class-construction.d.ts +12 -0
  54. package/dist/frontend/lowering/class-construction.js +156 -0
  55. package/dist/frontend/lowering/class-construction.js.map +1 -0
  56. package/dist/frontend/lowering/class-descriptors.d.ts +1 -0
  57. package/dist/frontend/lowering/class-descriptors.js +46 -5
  58. package/dist/frontend/lowering/class-descriptors.js.map +1 -1
  59. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +11 -1
  60. package/dist/frontend/lowering/class-dynamic-dispatch.js +403 -48
  61. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  62. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +2 -1
  63. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
  64. package/dist/frontend/lowering/class-instance-constructor.js +4 -1
  65. package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
  66. package/dist/frontend/lowering/class-method-values.d.ts +4 -1
  67. package/dist/frontend/lowering/class-method-values.js +72 -7
  68. package/dist/frontend/lowering/class-method-values.js.map +1 -1
  69. package/dist/frontend/lowering/class-prototypes.d.ts +5 -2
  70. package/dist/frontend/lowering/class-prototypes.js +121 -13
  71. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  72. package/dist/frontend/lowering/class-runtime-statics.d.ts +8 -0
  73. package/dist/frontend/lowering/class-runtime-statics.js +66 -0
  74. package/dist/frontend/lowering/class-runtime-statics.js.map +1 -0
  75. package/dist/frontend/lowering/class-static-data.js +2 -2
  76. package/dist/frontend/lowering/class-static-data.js.map +1 -1
  77. package/dist/frontend/lowering/containers/bytes.js +49 -13
  78. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  79. package/dist/frontend/lowering/containers/string-and-regexp.js +19 -47
  80. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  81. package/dist/frontend/lowering/error-methods.d.ts +4 -1
  82. package/dist/frontend/lowering/error-methods.js +100 -1
  83. package/dist/frontend/lowering/error-methods.js.map +1 -1
  84. package/dist/frontend/lowering/expressions/native-proxy.js +3 -1
  85. package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
  86. package/dist/frontend/lowering/expressions/nullish-assignment.js +19 -11
  87. package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
  88. package/dist/frontend/lowering/expressions/object-literals.js +38 -7
  89. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  90. package/dist/frontend/lowering/expressions/optional-chains.d.ts +3 -4
  91. package/dist/frontend/lowering/expressions/optional-chains.js +69 -17
  92. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  93. package/dist/frontend/lowering/function-context.d.ts +11 -3
  94. package/dist/frontend/lowering/function-context.js +11 -5
  95. package/dist/frontend/lowering/function-context.js.map +1 -1
  96. package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +1 -0
  97. package/dist/frontend/lowering/generator-dynamic-dispatch.js +39 -1
  98. package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
  99. package/dist/frontend/lowering/lib-boundary.d.ts +2 -0
  100. package/dist/frontend/lowering/lib-boundary.js +54 -1
  101. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  102. package/dist/frontend/lowering/lower-builtin-values.d.ts +7 -1
  103. package/dist/frontend/lowering/lower-builtin-values.js +113 -3
  104. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  105. package/dist/frontend/lowering/lower-builtins.d.ts +6 -5
  106. package/dist/frontend/lowering/lower-builtins.js +156 -41
  107. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  108. package/dist/frontend/lowering/lower-calls.d.ts +8 -5
  109. package/dist/frontend/lowering/lower-calls.js +448 -83
  110. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  111. package/dist/frontend/lowering/lower-classes.d.ts +13 -13
  112. package/dist/frontend/lowering/lower-classes.js +650 -176
  113. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  114. package/dist/frontend/lowering/lower-containers.d.ts +9 -0
  115. package/dist/frontend/lowering/lower-containers.js +135 -36
  116. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  117. package/dist/frontend/lowering/lower-dgram.js +3 -2
  118. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  119. package/dist/frontend/lowering/lower-exprs.d.ts +2 -2
  120. package/dist/frontend/lowering/lower-exprs.js +531 -126
  121. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  122. package/dist/frontend/lowering/lower-generators.js +12 -1
  123. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  124. package/dist/frontend/lowering/lower-island.d.ts +2 -0
  125. package/dist/frontend/lowering/lower-island.js +32 -10
  126. package/dist/frontend/lowering/lower-island.js.map +1 -1
  127. package/dist/frontend/lowering/lower-modules.js +220 -17
  128. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  129. package/dist/frontend/lowering/lower-modules.test.d.ts +1 -0
  130. package/dist/frontend/lowering/lower-modules.test.js +39 -0
  131. package/dist/frontend/lowering/lower-modules.test.js.map +1 -0
  132. package/dist/frontend/lowering/lower-stmts.d.ts +7 -3
  133. package/dist/frontend/lowering/lower-stmts.js +135 -26
  134. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  135. package/dist/frontend/lowering/lower-stream.js +1 -1
  136. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  137. package/dist/frontend/lowering/lowerer.d.ts +27 -1
  138. package/dist/frontend/lowering/lowerer.js +172 -50
  139. package/dist/frontend/lowering/lowerer.js.map +1 -1
  140. package/dist/frontend/lowering/lowerer.test.js +149 -3
  141. package/dist/frontend/lowering/lowerer.test.js.map +1 -1
  142. package/dist/frontend/lowering/surfaces.d.ts +2 -0
  143. package/dist/frontend/lowering/surfaces.js +25 -8
  144. package/dist/frontend/lowering/surfaces.js.map +1 -1
  145. package/dist/frontend/lowering/text-decoder-encoding.d.ts +2 -0
  146. package/dist/frontend/lowering/text-decoder-encoding.js +5 -0
  147. package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -1
  148. package/dist/frontend/lowering/unregistered-class-types.test.js +3 -3
  149. package/dist/frontend/lowering/unregistered-class-types.test.js.map +1 -1
  150. package/dist/frontend/npm-static-prune.js +116 -34
  151. package/dist/frontend/npm-static-prune.js.map +1 -1
  152. package/dist/frontend/npm-static-prune.test.js +8 -0
  153. package/dist/frontend/npm-static-prune.test.js.map +1 -1
  154. package/dist/frontend/program.d.ts +1 -1
  155. package/dist/frontend/program.js +53 -24
  156. package/dist/frontend/program.js.map +1 -1
  157. package/dist/frontend/program.test.js +18 -0
  158. package/dist/frontend/program.test.js.map +1 -1
  159. package/dist/frontend/ts7/ast.js +4 -3
  160. package/dist/frontend/ts7/ast.js.map +1 -1
  161. package/dist/frontend/ts7/semantic-json.js +5 -10
  162. package/dist/frontend/ts7/semantic-json.js.map +1 -1
  163. package/dist/frontend/type-mapper.d.ts +9 -1
  164. package/dist/frontend/type-mapper.js +90 -13
  165. package/dist/frontend/type-mapper.js.map +1 -1
  166. package/dist/frontend/type-mapper.test.js +23 -0
  167. package/dist/frontend/type-mapper.test.js.map +1 -1
  168. package/dist/frontend/union-discriminants.d.ts +1 -1
  169. package/dist/frontend/union-discriminants.js +2 -2
  170. package/dist/frontend/union-discriminants.js.map +1 -1
  171. package/dist/ir/analysis.js +2 -0
  172. package/dist/ir/analysis.js.map +1 -1
  173. package/dist/ir/ir.d.ts +52 -33
  174. package/dist/ir/ir.js +142 -42
  175. package/dist/ir/ir.js.map +1 -1
  176. package/dist/ir/ir.test.js +35 -0
  177. package/dist/ir/ir.test.js.map +1 -1
  178. package/dist/ir/serialize.js +15 -3
  179. package/dist/ir/serialize.js.map +1 -1
  180. package/dist/ir/serialize.test.js +5 -1
  181. package/dist/ir/serialize.test.js.map +1 -1
  182. package/dist/ir/validate.js +80 -11
  183. package/dist/ir/validate.js.map +1 -1
  184. package/dist/ir/validate.test.js +61 -1
  185. package/dist/ir/validate.test.js.map +1 -1
  186. package/dist/native/sanitizer.js +3 -1
  187. package/dist/native/sanitizer.js.map +1 -1
  188. package/dist/native/toolchain.d.ts +1 -1
  189. package/dist/native/toolchain.js +26 -6
  190. package/dist/native/toolchain.js.map +1 -1
  191. package/dist/native/toolchain.test.js +53 -1
  192. package/dist/native/toolchain.test.js.map +1 -1
  193. package/package.json +20 -20
  194. package/surface-manifest.json +56 -81
@@ -2,7 +2,7 @@ import { typedRefConstructor } from "./shapes.js";
2
2
  import { BYTES_ELEM_NUM, f64Lit } from "./common.js";
3
3
  import { InternalCompilerError } from "../../errors.js";
4
4
  import { DYN_HANDLE_KINDS, isDynTypedRefType, isRefCounted, typeKey } from "../../ir/ir.js";
5
- import { dynDesc, undefinedArmTag } from "../../ir/analysis.js";
5
+ import { dynDesc } from "../../ir/analysis.js";
6
6
  import { mangleRecordNew, mangleRecordStruct } from "../mangle.js";
7
7
  import { BlockBuilder } from "./blocks.js";
8
8
  import { llvmCommentText } from "./common.js";
@@ -49,6 +49,7 @@ export class LlDyn {
49
49
  dynFuncBoxes = new Map();
50
50
  dynFuncAdapters = new Map();
51
51
  promiseDynAdapters = new Map();
52
+ mapDynOps = new Map();
52
53
  dynToStrFn = null;
53
54
  caughtToDynFn = null;
54
55
  helperMemo = new Map();
@@ -92,7 +93,29 @@ export class LlDyn {
92
93
  }
93
94
  /** The value LLVM type of a dynCheck result / toDyn operand for `t`. */
94
95
  valTy(t) {
95
- return t.kind === "f64" ? "double" : t.kind === "bool" ? "i1" : "ptr";
96
+ return t.kind === "f64" || t.kind === "date" ? "double" : t.kind === "bool" ? "i1" : "ptr";
97
+ }
98
+ collectionDynOps(t) {
99
+ const key = typeKey(t);
100
+ const prior = this.mapDynOps.get(key);
101
+ if (prior)
102
+ return prior;
103
+ const name = `sc_map_dyn_${this.mapDynOps.size}`;
104
+ this.mapDynOps.set(key, name);
105
+ const keyType = t.kind === "map" ? t.key : t.elem;
106
+ const valueType = t.kind === "map" ? t.value : { kind: "f64" };
107
+ const emitSlot = (type, role) => {
108
+ const ty = this.valTy(type);
109
+ const unpack = ty === "double" ? "bitcast i64 %slot to double" : ty === "i1" ? "trunc i64 %slot to i1" : "inttoptr i64 %slot to ptr";
110
+ const pack = ty === "double" ? "bitcast double %value to i64" : ty === "i1" ? "zext i1 %value to i64" : "ptrtoint ptr %value to i64";
111
+ const box = this.toDynHelper(type);
112
+ const unbox = this.dynCheckHelper(type);
113
+ this.defs.push(`define internal ptr @${name}_${role}_box(i64 %slot) ${FN_ATTRS} {`, ` %value = ${unpack}`, ` %result = call ptr @${box}(${ty} %value)`, ` ret ptr %result`, `}`, "", `define internal i64 @${name}_${role}_unbox(ptr %d) ${FN_ATTRS} {`, ` %value = call ${ty === "i1" ? "zeroext i1" : ty} @${unbox}(ptr %d, ptr null)`, ` %result = ${pack}`, ` ret i64 %result`, `}`, "");
114
+ };
115
+ emitSlot(keyType, "key");
116
+ emitSlot(valueType, "value");
117
+ this.defs.push(`@${name} = internal constant { ptr, ptr, ptr, ptr, ptr, ptr } { ptr ${this.host.cstr(key)}, ptr @${name}_key_box, ptr @${name}_key_unbox, ptr @${this.dynMatchHelper(keyType)}, ptr @${name}_value_box, ptr @${name}_value_unbox }`, "");
118
+ return name;
96
119
  }
97
120
  /* ── dyn node plumbing ─────────────────────────────────────────────── */
98
121
  /** Loads a dyn node's kind tag (after the size_t rc word). */
@@ -197,6 +220,13 @@ export class LlDyn {
197
220
  B.line(`${t} = call ptr @scr_dyn_obj_get(ptr ${d}, ptr ${this.host.cstr(key)}, ${this.S} ${len}) ; .${llvmCommentText(key)}`);
198
221
  return t;
199
222
  }
223
+ /** Ordinary property lookup, including inherited data and accessors (+1). */
224
+ objReadLit(B, d, key) {
225
+ this.host.declare(`declare ptr @scr_dyn_obj_read(ptr, ptr, ${this.S})`);
226
+ const value = B.tmp();
227
+ B.line(`${value} = call ptr @scr_dyn_obj_read(ptr ${d}, ptr ${this.host.cstr(key)}, ${this.S} ${Buffer.byteLength(key, "utf8")})`);
228
+ return value;
229
+ }
200
230
  /** Appends an ScrStr's bytes into a ScrJsonBuf (walkers' putScrStr). */
201
231
  putScrStr(B, buf, s) {
202
232
  this.host.declare(`declare void @scr_jb_putc(ptr, i8)`);
@@ -338,10 +368,19 @@ export class LlDyn {
338
368
  B.terminate(`ret i1 ${r}`);
339
369
  };
340
370
  switch (t.kind) {
341
- case "url": {
342
- this.host.declare(`declare zeroext i1 @scr_dyn_native_url_is(ptr)`);
371
+ case "date": {
372
+ this.host.declare(`declare zeroext i1 @scr_dyn_native_date_is(ptr)`);
343
373
  const r = B.tmp();
344
- B.line(`${r} = call zeroext i1 @scr_dyn_native_url_is(ptr %d)`);
374
+ B.line(`${r} = call zeroext i1 @scr_dyn_native_date_is(ptr %d)`);
375
+ B.terminate(`ret i1 ${r}`);
376
+ break;
377
+ }
378
+ case "url":
379
+ case "searchParams": {
380
+ const native = t.kind === "url" ? "url" : "search_params";
381
+ this.host.declare(`declare zeroext i1 @scr_dyn_native_${native}_is(ptr)`);
382
+ const r = B.tmp();
383
+ B.line(`${r} = call zeroext i1 @scr_dyn_native_${native}_is(ptr %d)`);
345
384
  B.terminate(`ret i1 ${r}`);
346
385
  break;
347
386
  }
@@ -354,15 +393,19 @@ export class LlDyn {
354
393
  }
355
394
  case "map":
356
395
  case "set": {
357
- this.host.declare(`declare zeroext i1 @scr_dyn_native_${t.kind}_is(ptr)`);
396
+ this.host.declare(`declare zeroext i1 @scr_dyn_native_collection_is(ptr, i32, ptr)`);
358
397
  const r = B.tmp();
359
- B.line(`${r} = call zeroext i1 @scr_dyn_native_${t.kind}_is(ptr %d)`);
398
+ const typed = t.kind === "map" ? t.key.kind !== "dyn" || t.value.kind !== "dyn" : t.elem.kind !== "dyn";
399
+ B.line(`${r} = call zeroext i1 @scr_dyn_native_collection_is(ptr %d, i32 ${t.kind === "map" ? 1 : 0}, ptr ${typed ? this.host.cstr(typeKey(t)) : "null"})`);
360
400
  B.terminate(`ret i1 ${r}`);
361
401
  break;
362
402
  }
363
403
  case "bigint":
364
404
  kindIs(DYN_KIND.BIGINT);
365
405
  break;
406
+ case "promise":
407
+ kindIs(DYN_KIND.PROMISE);
408
+ break;
366
409
  case "symbol":
367
410
  kindIs(DYN_KIND.SYMBOL);
368
411
  break;
@@ -465,28 +508,26 @@ export class LlDyn {
465
508
  const isObj = B.tmp();
466
509
  B.line(`${isObj} = icmp eq i32 ${kd}, ${DYN_KIND.OBJ}`);
467
510
  const l0 = B.newLabel("dm.o");
468
- B.condBr(isObj, l0, fail);
511
+ let readable = isObj;
512
+ if (!shape.indexValue) {
513
+ const proxy = B.tmp();
514
+ readable = B.tmp();
515
+ B.line(`${proxy} = icmp eq i32 ${kd}, ${DYN_KIND.PROXY}`);
516
+ B.line(`${readable} = or i1 ${isObj}, ${proxy}`);
517
+ }
518
+ B.condBr(readable, l0, fail);
469
519
  B.startBlock(l0);
470
520
  // dyn ('unknown') fields match ANY value, present or missing.
471
521
  for (const f of shape.fields) {
472
522
  if (f.type.kind === "dyn")
473
523
  continue;
474
- const m = this.objGetLit(B, "%d", f.name);
475
- const has = B.tmp();
476
- B.line(`${has} = icmp ne ptr ${m}, null`);
477
- const lTest = B.newLabel("dm.t");
524
+ const m = this.objReadLit(B, "%d", f.name);
478
525
  const lNext = B.newLabel("dm.n");
479
- if (undefinedArmTag(f.type, this.host.unionsById) >= 0) {
480
- // Optional-flavored field: a MISSING key is the undefined arm
481
- // (a match); a PRESENT key must fit the union as usual.
482
- B.condBr(has, lTest, lNext);
483
- }
484
- else {
485
- B.condBr(has, lTest, fail);
486
- }
487
- B.startBlock(lTest);
526
+ this.host.declare(`declare void @scr_dyn_release(ptr)`);
527
+ this.pendingBail(B, "dm.read", () => B.line(`call void @scr_dyn_release(ptr ${m})`), "i1 false");
488
528
  const ok = B.tmp();
489
529
  B.line(`${ok} = call zeroext i1 @${this.dynMatchHelper(f.type)}(ptr ${m})`);
530
+ B.line(`call void @scr_dyn_release(ptr ${m})`);
490
531
  B.condBr(ok, lNext, fail);
491
532
  B.startBlock(lNext);
492
533
  }
@@ -625,6 +666,17 @@ export class LlDyn {
625
666
  }
626
667
  if (isRefCounted(t) && t.kind !== "dyn") {
627
668
  host.declare(`declare ptr @scr_dyn_typed_ref_unbox(ptr)`);
669
+ if (t.kind === "object" && t.className === "%Error") {
670
+ host.declare(`declare ptr @scr_errdyn_err_of(ptr)`);
671
+ const error = B.tmp(), found = B.tmp();
672
+ B.line(`${error} = call ptr @scr_errdyn_err_of(ptr %d)`);
673
+ B.line(`${found} = icmp ne ptr ${error}, null`);
674
+ const yes = B.newLabel("dc.error"), next = B.newLabel("dc.noterror");
675
+ B.condBr(found, yes, next);
676
+ B.startBlock(yes);
677
+ B.terminate(`ret ptr ${error}`);
678
+ B.startBlock(next);
679
+ }
628
680
  const matched = this.typedRefMatches(B, t);
629
681
  const lRef = B.newLabel("dc.tr");
630
682
  const lNext = B.newLabel("dc.nt");
@@ -637,7 +689,7 @@ export class LlDyn {
637
689
  if (t.kind !== "union") {
638
690
  host.declare(`declare ptr @scr_dyn_typed_ref_materialize(ptr)`);
639
691
  host.declare(`declare ptr @scr_dyn_typed_ref_cached_cast(ptr, ptr, ${host.sizeType})`);
640
- host.declare(`declare void @scr_dyn_typed_ref_cache_cast(ptr, ptr, ${host.sizeType}, ptr, ptr, ptr)`);
692
+ host.declare(`declare void @scr_dyn_typed_ref_cache_cast(ptr, ptr, ${host.sizeType}, ptr, ptr, ptr, i1)`);
641
693
  host.declare(`declare void @scr_dyn_release_v(ptr)`);
642
694
  const rc = vAdapters(host, t);
643
695
  const kind = this.kindOf(B, "%d");
@@ -735,7 +787,7 @@ export class LlDyn {
735
787
  B.line(`call void ${releaseSym(host, t)}(ptr ${checked})`);
736
788
  B.terminate(`ret ptr ${cached}`);
737
789
  B.startBlock(lCache);
738
- B.line(`call void @scr_dyn_typed_ref_cache_cast(ptr %d, ptr ${host.cstr(key)}, ${host.sizeType} ${Buffer.byteLength(key, "utf8")}, ptr ${checked}, ptr ${rc.retain}, ptr ${rc.release})`);
790
+ B.line(`call void @scr_dyn_typed_ref_cache_cast(ptr %d, ptr ${host.cstr(key)}, ${host.sizeType} ${Buffer.byteLength(key, "utf8")}, ptr ${checked}, ptr ${rc.retain}, ptr ${rc.release}, i1 ${traceAdapter(host, t) !== null ? "true" : "false"})`);
739
791
  B.terminate(`ret ptr ${checked}`);
740
792
  }
741
793
  else {
@@ -743,7 +795,7 @@ export class LlDyn {
743
795
  const lReturn = B.newLabel("dc.tr.ret");
744
796
  B.condBr(ok, lCache, lReturn);
745
797
  B.startBlock(lCache);
746
- B.line(`call void @scr_dyn_typed_ref_cache_cast(ptr %d, ptr ${host.cstr(key)}, ${host.sizeType} ${Buffer.byteLength(key, "utf8")}, ptr ${checked}, ptr ${rc.retain}, ptr ${rc.release})`);
798
+ B.line(`call void @scr_dyn_typed_ref_cache_cast(ptr %d, ptr ${host.cstr(key)}, ${host.sizeType} ${Buffer.byteLength(key, "utf8")}, ptr ${checked}, ptr ${rc.retain}, ptr ${rc.release}, i1 ${traceAdapter(host, t) !== null ? "true" : "false"})`);
747
799
  B.br(lReturn);
748
800
  B.startBlock(lReturn);
749
801
  B.terminate(`ret ptr ${checked}`);
@@ -765,10 +817,19 @@ export class LlDyn {
765
817
  B.startBlock(lo);
766
818
  };
767
819
  switch (t.kind) {
768
- case "url": {
769
- host.declare(`declare ptr @scr_dyn_native_url_check(ptr, ptr)`);
820
+ case "date": {
821
+ host.declare(`declare double @scr_dyn_native_date_value(ptr)`);
822
+ const r = B.tmp();
823
+ B.line(`${r} = call double @scr_dyn_native_date_value(ptr %d)`);
824
+ B.terminate(`ret double ${r}`);
825
+ break;
826
+ }
827
+ case "url":
828
+ case "searchParams": {
829
+ const native = t.kind === "url" ? "url" : "search_params";
830
+ host.declare(`declare ptr @scr_dyn_native_${native}_check(ptr, ptr)`);
770
831
  const r = B.tmp();
771
- B.line(`${r} = call ptr @scr_dyn_native_url_check(ptr %d, ptr %path)`);
832
+ B.line(`${r} = call ptr @scr_dyn_native_${native}_check(ptr %d, ptr %path)`);
772
833
  B.terminate(`ret ptr ${r}`);
773
834
  break;
774
835
  }
@@ -781,9 +842,10 @@ export class LlDyn {
781
842
  }
782
843
  case "map":
783
844
  case "set": {
784
- host.declare(`declare ptr @scr_dyn_native_${t.kind}_check(ptr, ptr)`);
845
+ host.declare(`declare ptr @scr_dyn_native_collection_check(ptr, i32, ptr, ptr)`);
785
846
  const r = B.tmp();
786
- B.line(`${r} = call ptr @scr_dyn_native_${t.kind}_check(ptr %d, ptr %path)`);
847
+ const typed = t.kind === "map" ? t.key.kind !== "dyn" || t.value.kind !== "dyn" : t.elem.kind !== "dyn";
848
+ B.line(`${r} = call ptr @scr_dyn_native_collection_check(ptr %d, i32 ${t.kind === "map" ? 1 : 0}, ptr ${typed ? host.cstr(typeKey(t)) : "null"}, ptr %path)`);
787
849
  B.terminate(`ret ptr ${r}`);
788
850
  break;
789
851
  }
@@ -855,6 +917,24 @@ export class LlDyn {
855
917
  B.line(`call void @scr_dyn_check_fail(ptr %path, ptr ${want}, ptr %d)`);
856
918
  B.terminate(`ret ptr null`);
857
919
  break;
920
+ case "promise": {
921
+ requireKind(DYN_KIND.PROMISE, "dc");
922
+ host.declare(`declare ptr @scr_promise_retain(ptr)`);
923
+ const promise = this.payloadOf(B, "%d", "ptr"), retained = B.tmp();
924
+ if (t.inner.kind !== "dyn") {
925
+ host.declare(`declare ptr @scr_promise_new()`);
926
+ host.declare(`declare void @scr_promise_race_add(ptr, ptr, ptr)`);
927
+ B.line(`${retained} = call ptr @scr_promise_new()`);
928
+ host.declare(`declare void @scr_promise_share_identity(ptr, ptr)`);
929
+ B.line(`call void @scr_promise_share_identity(ptr ${retained}, ptr ${promise})`);
930
+ B.line(`call void @scr_promise_race_add(ptr ${retained}, ptr ${promise}, ptr @${host.dynPromiseAdapter(t.inner)})`);
931
+ B.terminate(`ret ptr ${retained}`);
932
+ break;
933
+ }
934
+ B.line(`${retained} = call ptr @scr_promise_retain(ptr ${promise})`);
935
+ B.terminate(`ret ptr ${retained}`);
936
+ break;
937
+ }
858
938
  case "object": {
859
939
  // The %Error extraction (an instanceof-Error narrow on unknown):
860
940
  // validate the checked-dynamic tree's error encoding — the reserved "%error" marker
@@ -969,7 +1049,20 @@ export class LlDyn {
969
1049
  B.terminate(`ret ptr %r0`);
970
1050
  break;
971
1051
  }
972
- requireKind(DYN_KIND.OBJ, "dcr");
1052
+ if (shape.indexValue)
1053
+ requireKind(DYN_KIND.OBJ, "dcr");
1054
+ else {
1055
+ const kind = this.kindOf(B, "%d"), object = B.tmp(), proxy = B.tmp(), readable = B.tmp();
1056
+ B.line(`${object} = icmp eq i32 ${kind}, ${DYN_KIND.OBJ}`);
1057
+ B.line(`${proxy} = icmp eq i32 ${kind}, ${DYN_KIND.PROXY}`);
1058
+ B.line(`${readable} = or i1 ${object}, ${proxy}`);
1059
+ const ok = B.newLabel("dcr.object"), fail = B.newLabel("dcr.fail");
1060
+ B.condBr(readable, ok, fail);
1061
+ B.startBlock(fail);
1062
+ B.line(`call void @scr_dyn_check_fail(ptr %path, ptr ${want}, ptr %d)`);
1063
+ B.terminate(`ret ptr null`);
1064
+ B.startBlock(ok);
1065
+ }
973
1066
  if (shape.fields.length === 0 && !shape.indexValue) {
974
1067
  const sourceAccessor = `${this.toDynHelper(t)}_source_access`;
975
1068
  const rc = vAdapters(host, t);
@@ -987,61 +1080,15 @@ export class LlDyn {
987
1080
  }
988
1081
  B.line(`%r0 = call ptr @${mangleRecordNew(t.shapeId)}()`);
989
1082
  for (const f of shape.fields) {
990
- const fieldWant = host.cstr(dynDesc(f.type, this.host.recordsById, this.host.unionsById));
991
- const utag = f.type.kind === "union" ? undefinedArmTag(f.type, host.unionsById) : -1;
992
- const m = this.objGetLit(B, "%d", f.name);
993
- if (f.type.kind === "dyn") {
994
- // An `unknown` field: a present key passes through, a missing
995
- // one IS the undefined dyn value. Go through the dyn builder so
996
- // a Web-stream typed-ref capsule cannot escape inside a checked
997
- // record field.
998
- const has = B.tmp();
999
- B.line(`${has} = icmp ne ptr ${m}, null`);
1000
- const sel = B.tmp();
1001
- const u = this.undef(B);
1002
- B.line(`${sel} = select i1 ${has}, ptr ${m}, ptr ${u}`);
1003
- const value = B.tmp();
1004
- B.line(`${value} = call ptr @${this.dynCheckHelper(f.type)}(ptr ${sel}, ptr ${pathSlot})`);
1005
- storeInto(f.name, f.type, value);
1006
- }
1007
- else if (utag >= 0 && f.type.kind === "union") {
1008
- const unit = host.unitInstanceRef(f.type.unionId, utag);
1009
- const has = B.tmp();
1010
- B.line(`${has} = icmp ne ptr ${m}, null`);
1011
- const lp = B.newLabel("dcr.p");
1012
- const la = B.newLabel("dcr.a");
1013
- const lj = B.newLabel("dcr.j");
1014
- B.condBr(has, lp, la);
1015
- B.startBlock(la);
1016
- storeInto(f.name, f.type, unit); // absent key -> the undefined arm
1017
- B.br(lj);
1018
- B.startBlock(lp);
1019
- setPath(f.name, "0");
1020
- const v = B.tmp();
1021
- B.line(`${v} = call ptr @${this.dynCheckHelper(f.type)}(ptr ${m}, ptr ${pathSlot})`);
1022
- storeInto(f.name, f.type, v);
1023
- this.pendingBail(B, "dcr", releaseR, "ptr null");
1024
- B.br(lj);
1025
- B.startBlock(lj);
1026
- }
1027
- else {
1028
- const has = B.tmp();
1029
- B.line(`${has} = icmp ne ptr ${m}, null`);
1030
- const lp = B.newLabel("dcr.p");
1031
- const la = B.newLabel("dcr.a");
1032
- B.condBr(has, lp, la);
1033
- B.startBlock(la);
1034
- setPath(f.name, "0");
1035
- B.line(`call void @scr_dyn_check_fail(ptr ${pathSlot}, ptr ${fieldWant}, ptr null)`);
1036
- releaseR();
1037
- B.terminate(`ret ptr null`);
1038
- B.startBlock(lp);
1039
- setPath(f.name, "0");
1040
- const v = B.tmp();
1041
- B.line(`${v} = call ${this.valTy(f.type)} @${this.dynCheckHelper(f.type)}(ptr ${m}, ptr ${pathSlot})`);
1042
- storeInto(f.name, f.type, v);
1043
- this.pendingBail(B, "dcr", releaseR, "ptr null");
1044
- }
1083
+ const m = this.objReadLit(B, "%d", f.name);
1084
+ host.declare(`declare void @scr_dyn_release(ptr)`);
1085
+ this.pendingBail(B, "dcr.read", () => { B.line(`call void @scr_dyn_release(ptr ${m})`); releaseR(); }, "ptr null");
1086
+ setPath(f.name, "0");
1087
+ const value = B.tmp();
1088
+ B.line(`${value} = call ${this.valTy(f.type)} @${this.dynCheckHelper(f.type)}(ptr ${m}, ptr ${pathSlot})`);
1089
+ B.line(`call void @scr_dyn_release(ptr ${m})`);
1090
+ storeInto(f.name, f.type, value);
1091
+ this.pendingBail(B, "dcr", releaseR, "ptr null");
1045
1092
  }
1046
1093
  // Index-signature shapes CAPTURE undeclared keys into the
1047
1094
  // overflow map.
@@ -1194,7 +1241,7 @@ export class LlDyn {
1194
1241
  // live narrowed alias).
1195
1242
  host.declare(`declare ptr @scr_dyn_typed_ref_materialize(ptr)`);
1196
1243
  host.declare(`declare ptr @scr_dyn_typed_ref_cached_cast(ptr, ptr, ${host.sizeType})`);
1197
- host.declare(`declare void @scr_dyn_typed_ref_cache_cast(ptr, ptr, ${host.sizeType}, ptr, ptr, ptr)`);
1244
+ host.declare(`declare void @scr_dyn_typed_ref_cache_cast(ptr, ptr, ${host.sizeType}, ptr, ptr, ptr, i1)`);
1198
1245
  host.declare(`declare void @scr_dyn_release_v(ptr)`);
1199
1246
  host.declare(`declare void @scr_union_release(ptr)`);
1200
1247
  const rc = vAdapters(host, t);
@@ -1255,7 +1302,7 @@ export class LlDyn {
1255
1302
  B.line(`call void @scr_union_release(ptr ${checked})`);
1256
1303
  B.terminate(`ret ptr ${cached}`);
1257
1304
  B.startBlock(lCache);
1258
- B.line(`call void @scr_dyn_typed_ref_cache_cast(ptr %d, ptr ${host.cstr(key)}, ${host.sizeType} ${Buffer.byteLength(key, "utf8")}, ptr ${checked}, ptr ${rc.retain}, ptr ${rc.release})`);
1305
+ B.line(`call void @scr_dyn_typed_ref_cache_cast(ptr %d, ptr ${host.cstr(key)}, ${host.sizeType} ${Buffer.byteLength(key, "utf8")}, ptr ${checked}, ptr ${rc.retain}, ptr ${rc.release}, i1 ${traceAdapter(host, t) !== null ? "true" : "false"})`);
1259
1306
  B.terminate(`ret ptr ${checked}`);
1260
1307
  B.startBlock(lFail);
1261
1308
  B.line(`call void @scr_dyn_check_fail(ptr %path, ptr ${want}, ptr %d)`);
@@ -1351,10 +1398,12 @@ export class LlDyn {
1351
1398
  const B = new BlockBuilder();
1352
1399
  let sourceAccessor = null;
1353
1400
  switch (t.kind) {
1354
- case "url": {
1355
- host.declare(`declare ptr @scr_dyn_native_url(ptr)`);
1401
+ case "url":
1402
+ case "searchParams": {
1403
+ const native = t.kind === "url" ? "url" : "search_params";
1404
+ host.declare(`declare ptr @scr_dyn_native_${native}(ptr)`);
1356
1405
  const r = B.tmp();
1357
- B.line(`${r} = call ptr @scr_dyn_native_url(ptr %v)`);
1406
+ B.line(`${r} = call ptr @scr_dyn_native_${native}(ptr %v)`);
1358
1407
  B.terminate(`ret ptr ${r}`);
1359
1408
  break;
1360
1409
  }
@@ -1368,6 +1417,10 @@ export class LlDyn {
1368
1417
  case "map":
1369
1418
  case "set": {
1370
1419
  host.declare(`declare ptr @scr_dyn_native_${t.kind}(ptr)`);
1420
+ if (t.kind === "map" ? t.key.kind !== "dyn" || t.value.kind !== "dyn" : t.elem.kind !== "dyn") {
1421
+ host.declare(`declare void @scr_map_dyn_attach(ptr, ptr)`);
1422
+ B.line(`call void @scr_map_dyn_attach(ptr %v, ptr @${this.collectionDynOps(t)})`);
1423
+ }
1371
1424
  const r = B.tmp();
1372
1425
  B.line(`${r} = call ptr @scr_dyn_native_${t.kind}(ptr %v)`);
1373
1426
  B.terminate(`ret ptr ${r}`);
@@ -1676,6 +1729,8 @@ export class LlDyn {
1676
1729
  B.terminate(`br label %${doneLabel}`);
1677
1730
  B.startBlock(doneLabel);
1678
1731
  });
1732
+ host.declare(`declare void @scr_arr_copy_metadata(ptr, ptr)`);
1733
+ B.line(`call void @scr_arr_copy_metadata(ptr %v, ptr ${d})`);
1679
1734
  if (cyclicArr)
1680
1735
  B.line(`call void @scr_dyn_from_leave()`);
1681
1736
  host.declare(`declare ptr @scr_dyn_mark_snapshot(ptr)`);
@@ -2818,14 +2873,13 @@ export class LlDyn {
2818
2873
  const materialized = B.tmp();
2819
2874
  const out = B.tmp();
2820
2875
  B.line(`${materialized} = call ptr @scr_dyn_typed_ref_materialize(ptr %d)`);
2821
- B.line(`${out} = call ptr @${name}(ptr ${materialized}, ${host.sizeType} %n)`);
2876
+ B.line(`${out} = call ptr @${name}(ptr ${materialized}, ${host.sizeType} %n, ptr %spelling)`);
2822
2877
  B.line(`call void @scr_dyn_release_v(ptr ${materialized})`);
2823
2878
  B.terminate(`ret ptr ${out}`);
2824
2879
  B.startBlock(lNext);
2825
2880
  }
2826
- // ISLAND-held sources: an engine array IS iterable — the not-iterable
2827
- // TypeError below would be a wrong claim. Loud fence (lane
2828
- // dyn-routing-ops).
2881
+ // Island-held sources keep the engine's iterator and IteratorClose
2882
+ // behavior while returning checked values for the destructuring slots.
2829
2883
  {
2830
2884
  const isJv = B.tmp();
2831
2885
  B.line(`${isJv} = icmp eq i32 ${kd}, ${DYN_KIND.JSVAL}`);
@@ -2833,10 +2887,12 @@ export class LlDyn {
2833
2887
  const lNotJv = B.newLabel("din.njv");
2834
2888
  B.condBr(isJv, lJv, lNotJv);
2835
2889
  B.startBlock(lJv);
2836
- host.declare(`declare zeroext i1 @scr_dyn_isl_fence(ptr, ptr)`);
2837
- const f = B.tmp();
2838
- B.line(`${f} = call zeroext i1 @scr_dyn_isl_fence(ptr %d, ptr ${host.cstr("iteration")})`);
2839
- B.terminate(`ret ptr null`);
2890
+ host.declare(`declare ptr @scr_dyn_jsval_iter_n(ptr, double)`);
2891
+ const count = B.tmp();
2892
+ const out = B.tmp();
2893
+ B.line(`${count} = uitofp ${host.sizeType} %n to double`);
2894
+ B.line(`${out} = call ptr @scr_dyn_jsval_iter_n(ptr %d, double ${count})`);
2895
+ B.terminate(`ret ptr ${out}`);
2840
2896
  B.startBlock(lNotJv);
2841
2897
  }
2842
2898
  const okA = B.tmp();
@@ -2857,6 +2913,17 @@ export class LlDyn {
2857
2913
  const buf = "%dib";
2858
2914
  B.entryAllocas.push(`${buf} = alloca %ScrJsonBuf`);
2859
2915
  B.line(`call void @scr_jb_init(ptr ${buf})`);
2916
+ const hasSpelling = B.tmp();
2917
+ B.line(`${hasSpelling} = icmp ne ptr %spelling, null`);
2918
+ const named = B.newLabel("din.named"), unnamed = B.newLabel("din.unnamed");
2919
+ B.condBr(hasSpelling, named, unnamed);
2920
+ B.startBlock(named);
2921
+ B.line(`call void @scr_jb_puts(ptr ${buf}, ptr %spelling)`);
2922
+ const namedMessage = B.tmp();
2923
+ B.line(`${namedMessage} = call ptr @scr_jb_finish(ptr ${buf})`);
2924
+ B.line(`call void @scr_throw_error(i32 1, ptr ${namedMessage})`);
2925
+ B.terminate(`ret ptr null`);
2926
+ B.startBlock(unnamed);
2860
2927
  const lU = B.newLabel("din.u");
2861
2928
  const lN = B.newLabel("din.n");
2862
2929
  const lB2 = B.newLabel("din.b");
@@ -3036,7 +3103,7 @@ export class LlDyn {
3036
3103
  B.line(`call void @scr_dyn_arr_push(ptr ${out}, ptr ${item}) ; push takes ownership`);
3037
3104
  });
3038
3105
  B.terminate(`ret ptr ${out}`);
3039
- this.defs.push(`define internal ptr @${name}(ptr %d, ${host.sizeType} %n) ${FN_ATTRS} { ; destructuring GetIterator + N steps`, B.render(), `}`, ``);
3106
+ this.defs.push(`define internal ptr @${name}(ptr %d, ${host.sizeType} %n, ptr %spelling) ${FN_ATTRS} { ; destructuring GetIterator + N steps`, B.render(), `}`, ``);
3040
3107
  return name;
3041
3108
  }
3042
3109
  /* ── the checked-dynamic function boundary (ported) ────────────────── */