@scriptc/compiler 0.2.2 → 0.2.3

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 (178) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +99 -27
  2. package/dist/backend/cycle-analysis.js +63 -50
  3. package/dist/backend/cycle-analysis.js.map +1 -1
  4. package/dist/backend/cycle-analysis.test.js +51 -0
  5. package/dist/backend/cycle-analysis.test.js.map +1 -1
  6. package/dist/backend/llvm/borrowed-receivers.d.ts +9 -0
  7. package/dist/backend/llvm/borrowed-receivers.js +58 -0
  8. package/dist/backend/llvm/borrowed-receivers.js.map +1 -0
  9. package/dist/backend/llvm/call-lifetimes.d.ts +20 -0
  10. package/dist/backend/llvm/call-lifetimes.js +179 -0
  11. package/dist/backend/llvm/call-lifetimes.js.map +1 -0
  12. package/dist/backend/llvm/call-lifetimes.test.d.ts +1 -0
  13. package/dist/backend/llvm/call-lifetimes.test.js +205 -0
  14. package/dist/backend/llvm/call-lifetimes.test.js.map +1 -0
  15. package/dist/backend/llvm/dyn.d.ts +2 -2
  16. package/dist/backend/llvm/dyn.js +79 -35
  17. package/dist/backend/llvm/dyn.js.map +1 -1
  18. package/dist/backend/llvm/emitter.d.ts +33 -0
  19. package/dist/backend/llvm/emitter.js +189 -16
  20. package/dist/backend/llvm/emitter.js.map +1 -1
  21. package/dist/backend/llvm/emitter.test.js +20 -1
  22. package/dist/backend/llvm/emitter.test.js.map +1 -1
  23. package/dist/backend/llvm/expr-async.js +1 -1
  24. package/dist/backend/llvm/expr-async.js.map +1 -1
  25. package/dist/backend/llvm/expr-calls.js +42 -5
  26. package/dist/backend/llvm/expr-calls.js.map +1 -1
  27. package/dist/backend/llvm/expr-containers.js +70 -13
  28. package/dist/backend/llvm/expr-containers.js.map +1 -1
  29. package/dist/backend/llvm/expr-dynamic.js +1 -1
  30. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  31. package/dist/backend/llvm/expr-primitives.js +6 -5
  32. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  33. package/dist/backend/llvm/expr-records.js +1 -1
  34. package/dist/backend/llvm/expr-records.js.map +1 -1
  35. package/dist/backend/llvm/expr-stream-bridges.js +5 -10
  36. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  37. package/dist/backend/llvm/lib-shared.js +35 -1
  38. package/dist/backend/llvm/lib-shared.js.map +1 -1
  39. package/dist/backend/llvm/local-array-reads.d.ts +44 -0
  40. package/dist/backend/llvm/local-array-reads.js +313 -0
  41. package/dist/backend/llvm/local-array-reads.js.map +1 -0
  42. package/dist/backend/llvm/local-array-reads.test.d.ts +1 -0
  43. package/dist/backend/llvm/local-array-reads.test.js +446 -0
  44. package/dist/backend/llvm/local-array-reads.test.js.map +1 -0
  45. package/dist/backend/llvm/map-read-lifetimes.d.ts +36 -0
  46. package/dist/backend/llvm/map-read-lifetimes.js +128 -0
  47. package/dist/backend/llvm/map-read-lifetimes.js.map +1 -0
  48. package/dist/backend/llvm/map-read-lifetimes.test.d.ts +1 -0
  49. package/dist/backend/llvm/map-read-lifetimes.test.js +123 -0
  50. package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -0
  51. package/dist/backend/llvm/shapes.js +1 -0
  52. package/dist/backend/llvm/shapes.js.map +1 -1
  53. package/dist/backend/llvm/split.js +15 -5
  54. package/dist/backend/llvm/split.js.map +1 -1
  55. package/dist/backend/llvm/split.test.js +17 -0
  56. package/dist/backend/llvm/split.test.js.map +1 -1
  57. package/dist/backend/llvm/stack-unions.d.ts +20 -0
  58. package/dist/backend/llvm/stack-unions.js +61 -0
  59. package/dist/backend/llvm/stack-unions.js.map +1 -0
  60. package/dist/backend/llvm/stack-unions.test.d.ts +1 -0
  61. package/dist/backend/llvm/stack-unions.test.js +241 -0
  62. package/dist/backend/llvm/stack-unions.test.js.map +1 -0
  63. package/dist/backend/llvm/string-lifetimes.d.ts +12 -0
  64. package/dist/backend/llvm/string-lifetimes.js +70 -0
  65. package/dist/backend/llvm/string-lifetimes.js.map +1 -0
  66. package/dist/backend/llvm/string-lifetimes.test.d.ts +1 -0
  67. package/dist/backend/llvm/string-lifetimes.test.js +230 -0
  68. package/dist/backend/llvm/string-lifetimes.test.js.map +1 -0
  69. package/dist/backend/mangle.d.ts +2 -0
  70. package/dist/backend/mangle.js +4 -0
  71. package/dist/backend/mangle.js.map +1 -1
  72. package/dist/backend/may-throw.js +67 -29
  73. package/dist/backend/may-throw.js.map +1 -1
  74. package/dist/backend/may-throw.test.js +104 -1
  75. package/dist/backend/may-throw.test.js.map +1 -1
  76. package/dist/backend/native-toolchain.d.ts +2 -2
  77. package/dist/backend/native-toolchain.js +2 -0
  78. package/dist/backend/native-toolchain.js.map +1 -1
  79. package/dist/frontend/input-tracker.js +3 -3
  80. package/dist/frontend/input-tracker.js.map +1 -1
  81. package/dist/frontend/input-tracker.test.js +38 -2
  82. package/dist/frontend/input-tracker.test.js.map +1 -1
  83. package/dist/frontend/lowering/collection-ingestion.d.ts +31 -0
  84. package/dist/frontend/lowering/collection-ingestion.js +215 -0
  85. package/dist/frontend/lowering/collection-ingestion.js.map +1 -0
  86. package/dist/frontend/lowering/containers/bytes.js +2 -0
  87. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  88. package/dist/frontend/lowering/import-meta.d.ts +10 -0
  89. package/dist/frontend/lowering/import-meta.js +52 -0
  90. package/dist/frontend/lowering/import-meta.js.map +1 -0
  91. package/dist/frontend/lowering/lower-assert.js +105 -41
  92. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  93. package/dist/frontend/lowering/lower-builtin-values.d.ts +2 -0
  94. package/dist/frontend/lowering/lower-builtin-values.js +22 -1
  95. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  96. package/dist/frontend/lowering/lower-builtins.d.ts +3 -13
  97. package/dist/frontend/lowering/lower-builtins.js +150 -46
  98. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  99. package/dist/frontend/lowering/lower-calls.js +6 -3
  100. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  101. package/dist/frontend/lowering/lower-classes.js +4 -4
  102. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  103. package/dist/frontend/lowering/lower-containers.d.ts +5 -1
  104. package/dist/frontend/lowering/lower-containers.js +40 -3
  105. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  106. package/dist/frontend/lowering/lower-exprs.js +35 -41
  107. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  108. package/dist/frontend/lowering/lower-inspect.js +43 -0
  109. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  110. package/dist/frontend/lowering/lower-stmts.js +72 -68
  111. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  112. package/dist/frontend/lowering/lower-system-errors.d.ts +6 -0
  113. package/dist/frontend/lowering/lower-system-errors.js +29 -0
  114. package/dist/frontend/lowering/lower-system-errors.js.map +1 -0
  115. package/dist/frontend/lowering/lowerer.d.ts +4 -3
  116. package/dist/frontend/lowering/lowerer.js +50 -22
  117. package/dist/frontend/lowering/lowerer.js.map +1 -1
  118. package/dist/frontend/lowering/surfaces.d.ts +2 -2
  119. package/dist/frontend/lowering/surfaces.js +69 -21
  120. package/dist/frontend/lowering/surfaces.js.map +1 -1
  121. package/dist/frontend/module-syntax.d.ts +1 -1
  122. package/dist/frontend/module-syntax.js +8 -1
  123. package/dist/frontend/module-syntax.js.map +1 -1
  124. package/dist/frontend/module-syntax.test.js +10 -0
  125. package/dist/frontend/module-syntax.test.js.map +1 -1
  126. package/dist/frontend/npm.d.ts +4 -0
  127. package/dist/frontend/npm.js +86 -33
  128. package/dist/frontend/npm.js.map +1 -1
  129. package/dist/frontend/npm.test.js +103 -0
  130. package/dist/frontend/npm.test.js.map +1 -1
  131. package/dist/frontend/pipeline-native.js +2 -1
  132. package/dist/frontend/pipeline-native.js.map +1 -1
  133. package/dist/frontend/services-node.js +3 -2
  134. package/dist/frontend/services-node.js.map +1 -1
  135. package/dist/frontend/services.d.ts +5 -1
  136. package/dist/frontend/services.js +9 -1
  137. package/dist/frontend/services.js.map +1 -1
  138. package/dist/frontend/services.test.js +21 -0
  139. package/dist/frontend/services.test.js.map +1 -1
  140. package/dist/frontend/ts7/ast-node.d.ts +2 -0
  141. package/dist/frontend/ts7/ast-node.js +30 -4
  142. package/dist/frontend/ts7/ast-node.js.map +1 -1
  143. package/dist/frontend/ts7/ast-node.test.js +60 -1
  144. package/dist/frontend/ts7/ast-node.test.js.map +1 -1
  145. package/dist/frontend/type-mapper.js +6 -0
  146. package/dist/frontend/type-mapper.js.map +1 -1
  147. package/dist/index.js +3 -2
  148. package/dist/index.js.map +1 -1
  149. package/dist/ir/analysis.js +1 -0
  150. package/dist/ir/analysis.js.map +1 -1
  151. package/dist/ir/integer-loops.d.ts +7 -0
  152. package/dist/ir/integer-loops.js +23 -0
  153. package/dist/ir/integer-loops.js.map +1 -1
  154. package/dist/ir/integer-loops.test.d.ts +1 -0
  155. package/dist/ir/integer-loops.test.js +41 -0
  156. package/dist/ir/integer-loops.test.js.map +1 -0
  157. package/dist/ir/ir.d.ts +21 -17
  158. package/dist/ir/ir.js +43 -9
  159. package/dist/ir/ir.js.map +1 -1
  160. package/dist/ir/ir.test.js +18 -0
  161. package/dist/ir/ir.test.js.map +1 -1
  162. package/dist/ir/validate.js +161 -76
  163. package/dist/ir/validate.js.map +1 -1
  164. package/dist/ir/validate.test.js +227 -0
  165. package/dist/ir/validate.test.js.map +1 -1
  166. package/dist/library/fence-eval.js +9 -2
  167. package/dist/library/fence-eval.js.map +1 -1
  168. package/dist/library/fence-eval.test.d.ts +1 -0
  169. package/dist/library/fence-eval.test.js +21 -0
  170. package/dist/library/fence-eval.test.js.map +1 -0
  171. package/dist/native/runtime-typescript.d.ts +4 -0
  172. package/dist/native/runtime-typescript.js +61 -0
  173. package/dist/native/runtime-typescript.js.map +1 -0
  174. package/dist/native/runtime-typescript.test.d.ts +1 -0
  175. package/dist/native/runtime-typescript.test.js +41 -0
  176. package/dist/native/runtime-typescript.test.js.map +1 -0
  177. package/package.json +20 -20
  178. package/surface-manifest.json +271 -17
@@ -60,7 +60,7 @@ export class LlDyn {
60
60
  }
61
61
  /** Branch to a variant only after its literal discriminator and complete
62
62
  * structure match. Use the same path for predicates and builders. */
63
- unionArmMatch(B, def, tag, yes, no) {
63
+ unionArmMatch(B, def, tag, yes, no, preserveRefs = false) {
64
64
  const guard = def.discriminant?.cases.find((candidate) => candidate.tag === tag);
65
65
  if (guard && def.discriminant) {
66
66
  const structure = B.newLabel("du.shape");
@@ -81,7 +81,7 @@ export class LlDyn {
81
81
  B.startBlock(structure);
82
82
  }
83
83
  const matches = B.tmp();
84
- B.line(`${matches} = call zeroext i1 @${this.dynMatchHelper(def.arms[tag])}(ptr %d)`);
84
+ B.line(`${matches} = call zeroext i1 @${this.dynMatchHelper(def.arms[tag], preserveRefs)}(ptr %d)`);
85
85
  B.condBr(matches, yes, no);
86
86
  }
87
87
  get S() { return this.host.sizeType; }
@@ -93,7 +93,7 @@ export class LlDyn {
93
93
  }
94
94
  /** The value LLVM type of a dynCheck result / toDyn operand for `t`. */
95
95
  valTy(t) {
96
- return t.kind === "f64" || t.kind === "date" ? "double" : t.kind === "bool" ? "i1" : "ptr";
96
+ return t.kind === "f64" || t.kind === "date" || t.kind === "procStream" ? "double" : t.kind === "bool" ? "i1" : "ptr";
97
97
  }
98
98
  collectionDynOps(t) {
99
99
  const key = typeKey(t);
@@ -342,13 +342,14 @@ export class LlDyn {
342
342
  return matched;
343
343
  }
344
344
  /** `sc_dm_<n>(ptr d) -> i1` — does this dyn fit T? Never throws. */
345
- dynMatchHelper(t) {
345
+ dynMatchHelper(t, preserveRefs = false) {
346
346
  const key = typeKey(t);
347
- const existing = this.dynMatchers.get(key);
347
+ const matcherKey = preserveRefs ? `identity:${key}` : key;
348
+ const existing = this.dynMatchers.get(matcherKey);
348
349
  if (existing)
349
350
  return existing;
350
351
  const name = `sc_dm_${this.dynMatchers.size}`;
351
- this.dynMatchers.set(key, name);
352
+ this.dynMatchers.set(matcherKey, name);
352
353
  const B = new BlockBuilder();
353
354
  if (isRefCounted(t) && t.kind !== "dyn") {
354
355
  const matched = this.typedRefMatches(B, t);
@@ -369,12 +370,17 @@ export class LlDyn {
369
370
  const lPlain = B.newLabel("dm.tr.plain");
370
371
  B.condBr(capsule, lCapsule, lPlain);
371
372
  B.startBlock(lCapsule);
372
- const materialized = B.tmp();
373
- const matched = B.tmp();
374
- B.line(`${materialized} = call ptr @scr_dyn_typed_ref_materialize(ptr %d)`);
375
- B.line(`${matched} = call zeroext i1 @${name}(ptr ${materialized})`);
376
- B.line(`call void @scr_dyn_release_v(ptr ${materialized})`);
377
- B.terminate(`ret i1 ${matched}`);
373
+ if (preserveRefs) {
374
+ B.terminate(`ret i1 false`);
375
+ }
376
+ else {
377
+ const materialized = B.tmp();
378
+ const matched = B.tmp();
379
+ B.line(`${materialized} = call ptr @scr_dyn_typed_ref_materialize(ptr %d)`);
380
+ B.line(`${matched} = call zeroext i1 @${name}(ptr ${materialized})`);
381
+ B.line(`call void @scr_dyn_release_v(ptr ${materialized})`);
382
+ B.terminate(`ret i1 ${matched}`);
383
+ }
378
384
  B.startBlock(lPlain);
379
385
  }
380
386
  const kindIs = (k) => {
@@ -422,6 +428,13 @@ export class LlDyn {
422
428
  case "promise":
423
429
  kindIs(DYN_KIND.PROMISE);
424
430
  break;
431
+ case "procStream": {
432
+ this.host.declare(`declare zeroext i1 @scr_dyn_process_stdio_is(ptr)`);
433
+ const matched = B.tmp();
434
+ B.line(`${matched} = call zeroext i1 @scr_dyn_process_stdio_is(ptr %d)`);
435
+ B.terminate(`ret i1 ${matched}`);
436
+ break;
437
+ }
425
438
  case "symbol":
426
439
  kindIs(DYN_KIND.SYMBOL);
427
440
  break;
@@ -516,7 +529,7 @@ export class LlDyn {
516
529
  for (const [i, f] of byIndex.entries()) {
517
530
  const e = this.itemAt(B, items, `${i}`);
518
531
  const m = B.tmp();
519
- B.line(`${m} = call zeroext i1 @${this.dynMatchHelper(f.type)}(ptr ${e})`);
532
+ B.line(`${m} = call zeroext i1 @${this.dynMatchHelper(f.type, preserveRefs)}(ptr ${e})`);
520
533
  const ln = B.newLabel("dm.i");
521
534
  B.condBr(m, ln, fail);
522
535
  B.startBlock(ln);
@@ -547,7 +560,7 @@ export class LlDyn {
547
560
  this.host.declare(`declare void @scr_dyn_release(ptr)`);
548
561
  this.pendingBail(B, "dm.read", () => B.line(`call void @scr_dyn_release(ptr ${m})`), "i1 false");
549
562
  const ok = B.tmp();
550
- B.line(`${ok} = call zeroext i1 @${this.dynMatchHelper(f.type)}(ptr ${m})`);
563
+ B.line(`${ok} = call zeroext i1 @${this.dynMatchHelper(f.type, preserveRefs)}(ptr ${m})`);
551
564
  B.line(`call void @scr_dyn_release(ptr ${m})`);
552
565
  B.condBr(ok, lNext, fail);
553
566
  B.startBlock(lNext);
@@ -583,7 +596,7 @@ export class LlDyn {
583
596
  B.startBlock(lNo);
584
597
  }
585
598
  const ok = B.tmp();
586
- B.line(`${ok} = call zeroext i1 @${this.dynMatchHelper(shape.indexValue)}(ptr ${ent.value})`);
599
+ B.line(`${ok} = call zeroext i1 @${this.dynMatchHelper(shape.indexValue, preserveRefs)}(ptr ${ent.value})`);
587
600
  const lOk = B.newLabel("dm.vo");
588
601
  B.condBr(ok, lOk, fail);
589
602
  B.startBlock(lOk);
@@ -595,7 +608,7 @@ export class LlDyn {
595
608
  break;
596
609
  }
597
610
  case "array": {
598
- const m = this.dynMatchHelper(t.elem);
611
+ const m = this.dynMatchHelper(t.elem, preserveRefs);
599
612
  const fail = B.newLabel("dm.f");
600
613
  const kd = this.kindOf(B, "%d");
601
614
  const isArr = B.tmp();
@@ -635,7 +648,7 @@ export class LlDyn {
635
648
  const yes = B.newLabel("dm.y");
636
649
  for (let tag = 0; tag < def.arms.length; tag++) {
637
650
  const ln = B.newLabel("dm.n");
638
- this.unionArmMatch(B, def, tag, yes, ln);
651
+ this.unionArmMatch(B, def, tag, yes, ln, preserveRefs);
639
652
  B.startBlock(ln);
640
653
  }
641
654
  B.terminate(`ret i1 false`);
@@ -673,13 +686,14 @@ export class LlDyn {
673
686
  /** `sc_dc_<n>(ptr d, ptr path) -> T` — validate the checked-dynamic tree against T and
674
687
  * BUILD the typed value (+1), or throw the catchable path-annotated
675
688
  * TypeError and return a dummy with the pending flag set. */
676
- dynCheckHelper(t) {
689
+ dynCheckHelper(t, preserveRefs = false) {
677
690
  const key = typeKey(t);
678
- const existing = this.dynBuilders.get(key);
691
+ const builderKey = preserveRefs ? `identity:${key}` : key;
692
+ const existing = this.dynBuilders.get(builderKey);
679
693
  if (existing)
680
694
  return existing;
681
695
  const name = `sc_dc_${this.dynBuilders.size}`;
682
- this.dynBuilders.set(key, name);
696
+ this.dynBuilders.set(builderKey, name);
683
697
  const host = this.host;
684
698
  const retTy = this.valTy(t);
685
699
  const dummy = retTy === "double" ? `double ${f64Lit(0)}` : retTy === "i1" ? "i1 false" : "ptr null";
@@ -716,7 +730,19 @@ export class LlDyn {
716
730
  B.line(`${ref} = call ptr @scr_dyn_typed_ref_unbox(ptr %d)`);
717
731
  B.terminate(`ret ptr ${ref}`);
718
732
  B.startBlock(lNext);
719
- if (t.kind !== "union") {
733
+ if (t.kind !== "union" && preserveRefs) {
734
+ const kind = this.kindOf(B, "%d");
735
+ const capsule = B.tmp();
736
+ B.line(`${capsule} = icmp eq i32 ${kind}, ${DYN_KIND.TYPED_REF}`);
737
+ const reject = B.newLabel("dc.identity.reject");
738
+ const plain = B.newLabel("dc.identity.plain");
739
+ B.condBr(capsule, reject, plain);
740
+ B.startBlock(reject);
741
+ B.line(`call void @scr_dyn_check_fail(ptr %path, ptr ${host.cstr("reference with its original layout")}, ptr %d)`);
742
+ B.terminate(`ret ${dummy}`);
743
+ B.startBlock(plain);
744
+ }
745
+ else if (t.kind !== "union") {
720
746
  host.declare(`declare ptr @scr_dyn_typed_ref_materialize(ptr)`);
721
747
  host.declare(`declare ptr @scr_dyn_typed_ref_cached_cast(ptr, ptr, ${host.sizeType})`);
722
748
  host.declare(`declare void @scr_dyn_typed_ref_cache_cast(ptr, ptr, ${host.sizeType}, ptr, ptr, ptr, i1)`);
@@ -926,6 +952,13 @@ export class LlDyn {
926
952
  B.terminate(`ret ptr ${retained}`);
927
953
  break;
928
954
  }
955
+ case "procStream": {
956
+ host.declare(`declare double @scr_dyn_process_stdio_fd(ptr, ptr)`);
957
+ const r = B.tmp();
958
+ B.line(`${r} = call double @scr_dyn_process_stdio_fd(ptr %d, ptr %path)`);
959
+ B.terminate(`ret double ${r}`);
960
+ break;
961
+ }
929
962
  case "bytes": {
930
963
  host.declare(`declare zeroext i1 @scr_dyn_bytes_is(ptr, i32)`);
931
964
  const matched = B.tmp();
@@ -1072,7 +1105,7 @@ export class LlDyn {
1072
1105
  setPath(null, `${i}`);
1073
1106
  const e = this.itemAt(B, items, `${i}`);
1074
1107
  const v = B.tmp();
1075
- B.line(`${v} = call ${this.valTy(f.type)} @${this.dynCheckHelper(f.type)}(ptr ${e}, ptr ${pathSlot})`);
1108
+ B.line(`${v} = call ${this.valTy(f.type)} @${this.dynCheckHelper(f.type, preserveRefs)}(ptr ${e}, ptr ${pathSlot})`);
1076
1109
  storeInto(f.name, f.type, v);
1077
1110
  this.pendingBail(B, "dct", releaseR, "ptr null");
1078
1111
  });
@@ -1115,7 +1148,7 @@ export class LlDyn {
1115
1148
  this.pendingBail(B, "dcr.read", () => { B.line(`call void @scr_dyn_release(ptr ${m})`); releaseR(); }, "ptr null");
1116
1149
  setPath(f.name, "0");
1117
1150
  const value = B.tmp();
1118
- B.line(`${value} = call ${this.valTy(f.type)} @${this.dynCheckHelper(f.type)}(ptr ${m}, ptr ${pathSlot})`);
1151
+ B.line(`${value} = call ${this.valTy(f.type)} @${this.dynCheckHelper(f.type, preserveRefs)}(ptr ${m}, ptr ${pathSlot})`);
1119
1152
  B.line(`call void @scr_dyn_release(ptr ${m})`);
1120
1153
  storeInto(f.name, f.type, value);
1121
1154
  this.pendingBail(B, "dcr", releaseR, "ptr null");
@@ -1163,7 +1196,7 @@ export class LlDyn {
1163
1196
  else {
1164
1197
  setPathKeyPtr(ent.key);
1165
1198
  ev = B.tmp();
1166
- B.line(`${ev} = call ${this.valTy(iv)} @${this.dynCheckHelper(iv)}(ptr ${ent.value}, ptr ${pathSlot})`);
1199
+ B.line(`${ev} = call ${this.valTy(iv)} @${this.dynCheckHelper(iv, preserveRefs)}(ptr ${ent.value}, ptr ${pathSlot})`);
1167
1200
  this.pendingBail(B, "dcv", releaseR, "ptr null");
1168
1201
  }
1169
1202
  const ek = B.tmp();
@@ -1188,7 +1221,7 @@ export class LlDyn {
1188
1221
  }
1189
1222
  case "array": {
1190
1223
  const elem = t.elem;
1191
- const c = this.dynCheckHelper(elem);
1224
+ const c = this.dynCheckHelper(elem, preserveRefs);
1192
1225
  requireKind(DYN_KIND.ARR, "dca");
1193
1226
  const n = this.lenOf(B, "%d");
1194
1227
  const a = B.tmp();
@@ -1249,18 +1282,18 @@ export class LlDyn {
1249
1282
  def.arms.forEach((arm, i) => {
1250
1283
  const lHit = B.newLabel("dcu.h");
1251
1284
  const lNext = B.newLabel("dcu.n");
1252
- this.unionArmMatch(B, def, i, lHit, lNext);
1285
+ this.unionArmMatch(B, def, i, lHit, lNext, preserveRefs);
1253
1286
  B.startBlock(lHit);
1254
1287
  if (arm.kind === "undefinedT" || arm.kind === "nullT") {
1255
1288
  // A matched unit arm builds nothing: THE interned immortal
1256
1289
  // instance (rc == SIZE_MAX — no retain owed).
1257
1290
  B.terminate(`ret ptr ${host.unitInstanceRef(t.unionId, i)}`);
1258
1291
  }
1259
- else if (arm.kind === "f64") {
1292
+ else if (arm.kind === "f64" || arm.kind === "procStream") {
1260
1293
  host.declare(`declare ptr @scr_union_new_f64(i32, double)`);
1261
1294
  const x = B.tmp();
1262
1295
  const u = B.tmp();
1263
- B.line(`${x} = call double @${this.dynCheckHelper(arm)}(ptr %d, ptr %path)`);
1296
+ B.line(`${x} = call double @${this.dynCheckHelper(arm, preserveRefs)}(ptr %d, ptr %path)`);
1264
1297
  B.line(`${u} = call ptr @scr_union_new_f64(i32 ${i}, double ${x})`);
1265
1298
  B.terminate(`ret ptr ${u}`);
1266
1299
  }
@@ -1268,7 +1301,7 @@ export class LlDyn {
1268
1301
  host.declare(`declare ptr @scr_union_new_bool(i32, i1 zeroext)`);
1269
1302
  const x = B.tmp();
1270
1303
  const u = B.tmp();
1271
- B.line(`${x} = call zeroext i1 @${this.dynCheckHelper(arm)}(ptr %d, ptr %path)`);
1304
+ B.line(`${x} = call zeroext i1 @${this.dynCheckHelper(arm, preserveRefs)}(ptr %d, ptr %path)`);
1272
1305
  B.line(`${u} = call ptr @scr_union_new_bool(i32 ${i}, i1 ${x})`);
1273
1306
  B.terminate(`ret ptr ${u}`);
1274
1307
  }
@@ -1277,12 +1310,17 @@ export class LlDyn {
1277
1310
  host.declare(`declare ptr @scr_union_new_ref(i32, ptr, ptr, ptr, ptr)`);
1278
1311
  const x = B.tmp();
1279
1312
  const u = B.tmp();
1280
- B.line(`${x} = call ptr @${this.dynCheckHelper(arm)}(ptr %d, ptr %path)`);
1313
+ B.line(`${x} = call ptr @${this.dynCheckHelper(arm, preserveRefs)}(ptr %d, ptr %path)`);
1281
1314
  B.line(`${u} = call ptr @scr_union_new_ref(i32 ${i}, ptr ${x}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(host, arm)})`);
1282
1315
  B.terminate(`ret ptr ${u}`);
1283
1316
  }
1284
1317
  B.startBlock(lNext);
1285
1318
  });
1319
+ if (preserveRefs) {
1320
+ B.line(`call void @scr_dyn_check_fail(ptr %path, ptr ${host.cstr("reference with its original layout")}, ptr %d)`);
1321
+ B.terminate(`ret ptr null`);
1322
+ break;
1323
+ }
1286
1324
  // Preserve an exact typed-ref arm above. If no producer tag matched,
1287
1325
  // retry the union against the ordinary copy-based structural
1288
1326
  // snapshot (the compiler's width-coercion stance, rather than a
@@ -1516,6 +1554,13 @@ export class LlDyn {
1516
1554
  B.terminate(`ret ptr ${r}`);
1517
1555
  break;
1518
1556
  }
1557
+ case "procStream": {
1558
+ host.declare(`declare ptr @scr_process_stdio(double)`);
1559
+ const r = B.tmp();
1560
+ B.line(`${r} = call ptr @scr_process_stdio(double %v)`);
1561
+ B.terminate(`ret ptr ${r}`);
1562
+ break;
1563
+ }
1519
1564
  case "string": {
1520
1565
  host.declare(`declare ptr @scr_dyn_new_str(ptr)`);
1521
1566
  const r = B.tmp();
@@ -1834,13 +1879,12 @@ export class LlDyn {
1834
1879
  B.line(`${r} = call ptr @scr_dyn_new_null()`);
1835
1880
  B.terminate(`ret ptr ${r}`);
1836
1881
  }
1837
- else if (arm.kind === "f64") {
1882
+ else if (arm.kind === "f64" || arm.kind === "procStream") {
1838
1883
  host.declare(`declare double @scr_union_get_f64(ptr)`);
1839
- host.declare(`declare ptr @scr_dyn_new_num(double)`);
1840
1884
  const x = B.tmp();
1841
1885
  const r = B.tmp();
1842
1886
  B.line(`${x} = call double @scr_union_get_f64(ptr %v)`);
1843
- B.line(`${r} = call ptr @scr_dyn_new_num(double ${x})`);
1887
+ B.line(`${r} = call ptr @${this.toDynHelper(arm)}(double ${x})`);
1844
1888
  B.terminate(`ret ptr ${r}`);
1845
1889
  }
1846
1890
  else if (arm.kind === "bool") {
@@ -1957,13 +2001,13 @@ export class LlDyn {
1957
2001
  fulfill(dv);
1958
2002
  break;
1959
2003
  }
2004
+ case "procStream":
1960
2005
  case "f64": {
1961
2006
  host.declare(`declare double @scr_promise_payload_f64(ptr)`);
1962
- host.declare(`declare ptr @scr_dyn_new_num(double)`);
1963
2007
  const x = B.tmp();
1964
2008
  const dv = B.tmp();
1965
2009
  B.line(`${x} = call double @scr_promise_payload_f64(ptr %src)`);
1966
- B.line(`${dv} = call ptr @scr_dyn_new_num(double ${x})`);
2010
+ B.line(`${dv} = call ptr @${this.toDynHelper(inner)}(double ${x})`);
1967
2011
  fulfill(dv);
1968
2012
  break;
1969
2013
  }