@scriptc/compiler 0.2.1 → 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 (315) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +158 -31
  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 +5 -2
  16. package/dist/backend/llvm/dyn.js +163 -47
  17. package/dist/backend/llvm/dyn.js.map +1 -1
  18. package/dist/backend/llvm/emitter.d.ts +37 -1
  19. package/dist/backend/llvm/emitter.js +209 -21
  20. package/dist/backend/llvm/emitter.js.map +1 -1
  21. package/dist/backend/llvm/emitter.test.js +29 -2
  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 +75 -13
  28. package/dist/backend/llvm/expr-containers.js.map +1 -1
  29. package/dist/backend/llvm/expr-dynamic.js +31 -6
  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 +75 -19
  36. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  37. package/dist/backend/llvm/expr-stream-callbacks.d.ts +2 -2
  38. package/dist/backend/llvm/expr-stream-callbacks.js +7 -57
  39. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  40. package/dist/backend/llvm/lib-dispatch.js +41 -3
  41. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  42. package/dist/backend/llvm/lib-filesystem.js +12 -9
  43. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  44. package/dist/backend/llvm/lib-shared.js +70 -2
  45. package/dist/backend/llvm/lib-shared.js.map +1 -1
  46. package/dist/backend/llvm/local-array-reads.d.ts +44 -0
  47. package/dist/backend/llvm/local-array-reads.js +313 -0
  48. package/dist/backend/llvm/local-array-reads.js.map +1 -0
  49. package/dist/backend/llvm/local-array-reads.test.d.ts +1 -0
  50. package/dist/backend/llvm/local-array-reads.test.js +446 -0
  51. package/dist/backend/llvm/local-array-reads.test.js.map +1 -0
  52. package/dist/backend/llvm/map-read-lifetimes.d.ts +36 -0
  53. package/dist/backend/llvm/map-read-lifetimes.js +128 -0
  54. package/dist/backend/llvm/map-read-lifetimes.js.map +1 -0
  55. package/dist/backend/llvm/map-read-lifetimes.test.d.ts +1 -0
  56. package/dist/backend/llvm/map-read-lifetimes.test.js +123 -0
  57. package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -0
  58. package/dist/backend/llvm/shapes.js +1 -0
  59. package/dist/backend/llvm/shapes.js.map +1 -1
  60. package/dist/backend/llvm/split.js +15 -5
  61. package/dist/backend/llvm/split.js.map +1 -1
  62. package/dist/backend/llvm/split.test.js +17 -0
  63. package/dist/backend/llvm/split.test.js.map +1 -1
  64. package/dist/backend/llvm/stack-unions.d.ts +20 -0
  65. package/dist/backend/llvm/stack-unions.js +61 -0
  66. package/dist/backend/llvm/stack-unions.js.map +1 -0
  67. package/dist/backend/llvm/stack-unions.test.d.ts +1 -0
  68. package/dist/backend/llvm/stack-unions.test.js +241 -0
  69. package/dist/backend/llvm/stack-unions.test.js.map +1 -0
  70. package/dist/backend/llvm/string-lifetimes.d.ts +12 -0
  71. package/dist/backend/llvm/string-lifetimes.js +70 -0
  72. package/dist/backend/llvm/string-lifetimes.js.map +1 -0
  73. package/dist/backend/llvm/string-lifetimes.test.d.ts +1 -0
  74. package/dist/backend/llvm/string-lifetimes.test.js +230 -0
  75. package/dist/backend/llvm/string-lifetimes.test.js.map +1 -0
  76. package/dist/backend/mangle.d.ts +2 -0
  77. package/dist/backend/mangle.js +4 -0
  78. package/dist/backend/mangle.js.map +1 -1
  79. package/dist/backend/may-throw.js +71 -29
  80. package/dist/backend/may-throw.js.map +1 -1
  81. package/dist/backend/may-throw.test.js +104 -1
  82. package/dist/backend/may-throw.test.js.map +1 -1
  83. package/dist/backend/native-codegen.d.ts +1 -1
  84. package/dist/backend/native-codegen.js +4 -3
  85. package/dist/backend/native-codegen.js.map +1 -1
  86. package/dist/backend/native-codegen.test.js +11 -0
  87. package/dist/backend/native-codegen.test.js.map +1 -1
  88. package/dist/backend/native-toolchain.d.ts +2 -2
  89. package/dist/backend/native-toolchain.js +2 -0
  90. package/dist/backend/native-toolchain.js.map +1 -1
  91. package/dist/backend/target-diagnostics.d.ts +5 -0
  92. package/dist/backend/target-diagnostics.js +72 -1
  93. package/dist/backend/target-diagnostics.js.map +1 -1
  94. package/dist/backend/target-diagnostics.test.d.ts +1 -0
  95. package/dist/backend/target-diagnostics.test.js +68 -0
  96. package/dist/backend/target-diagnostics.test.js.map +1 -0
  97. package/dist/coverage/surface-manifest.js +5 -3
  98. package/dist/coverage/surface-manifest.js.map +1 -1
  99. package/dist/executable/executable-cache.d.ts +7 -3
  100. package/dist/executable/executable-cache.js +47 -11
  101. package/dist/executable/executable-cache.js.map +1 -1
  102. package/dist/executable/executable-cache.test.js +109 -2
  103. package/dist/executable/executable-cache.test.js.map +1 -1
  104. package/dist/executable/prepare.js +2 -1
  105. package/dist/executable/prepare.js.map +1 -1
  106. package/dist/frontend/builtin-modules.d.ts +1 -1
  107. package/dist/frontend/builtin-modules.js +1 -1
  108. package/dist/frontend/builtin-modules.js.map +1 -1
  109. package/dist/frontend/function-completion.d.ts +6 -0
  110. package/dist/frontend/function-completion.js +50 -0
  111. package/dist/frontend/function-completion.js.map +1 -0
  112. package/dist/frontend/input-tracker.js +3 -3
  113. package/dist/frontend/input-tracker.js.map +1 -1
  114. package/dist/frontend/input-tracker.test.js +38 -2
  115. package/dist/frontend/input-tracker.test.js.map +1 -1
  116. package/dist/frontend/lowering/abstract-equality.js +5 -1
  117. package/dist/frontend/lowering/abstract-equality.js.map +1 -1
  118. package/dist/frontend/lowering/checked-iterable-spread.d.ts +4 -0
  119. package/dist/frontend/lowering/checked-iterable-spread.js +30 -0
  120. package/dist/frontend/lowering/checked-iterable-spread.js.map +1 -0
  121. package/dist/frontend/lowering/checked-promise-all.d.ts +5 -0
  122. package/dist/frontend/lowering/checked-promise-all.js +31 -0
  123. package/dist/frontend/lowering/checked-promise-all.js.map +1 -0
  124. package/dist/frontend/lowering/class-callbacks.d.ts +1 -1
  125. package/dist/frontend/lowering/class-callbacks.js +7 -6
  126. package/dist/frontend/lowering/class-callbacks.js.map +1 -1
  127. package/dist/frontend/lowering/class-construction.d.ts +2 -0
  128. package/dist/frontend/lowering/class-construction.js +34 -5
  129. package/dist/frontend/lowering/class-construction.js.map +1 -1
  130. package/dist/frontend/lowering/class-descriptors.d.ts +1 -1
  131. package/dist/frontend/lowering/class-descriptors.js +12 -5
  132. package/dist/frontend/lowering/class-descriptors.js.map +1 -1
  133. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +25 -0
  134. package/dist/frontend/lowering/class-dynamic-dispatch.js +597 -78
  135. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  136. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +64 -2
  137. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
  138. package/dist/frontend/lowering/class-instance-constructor.d.ts +1 -1
  139. package/dist/frontend/lowering/class-instance-constructor.js +11 -41
  140. package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
  141. package/dist/frontend/lowering/class-method-values.d.ts +16 -0
  142. package/dist/frontend/lowering/class-method-values.js +60 -29
  143. package/dist/frontend/lowering/class-method-values.js.map +1 -1
  144. package/dist/frontend/lowering/class-prototypes.d.ts +5 -1
  145. package/dist/frontend/lowering/class-prototypes.js +69 -10
  146. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  147. package/dist/frontend/lowering/class-runtime-statics.d.ts +4 -4
  148. package/dist/frontend/lowering/class-runtime-statics.js +26 -8
  149. package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
  150. package/dist/frontend/lowering/class-static-data.d.ts +1 -0
  151. package/dist/frontend/lowering/class-static-data.js +4 -2
  152. package/dist/frontend/lowering/class-static-data.js.map +1 -1
  153. package/dist/frontend/lowering/collection-ingestion.d.ts +31 -0
  154. package/dist/frontend/lowering/collection-ingestion.js +215 -0
  155. package/dist/frontend/lowering/collection-ingestion.js.map +1 -0
  156. package/dist/frontend/lowering/containers/bytes.js +19 -4
  157. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  158. package/dist/frontend/lowering/containers/string-and-regexp.js +6 -1
  159. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  160. package/dist/frontend/lowering/deferred-module-initializers.d.ts +13 -0
  161. package/dist/frontend/lowering/deferred-module-initializers.js +410 -0
  162. package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -0
  163. package/dist/frontend/lowering/deferred-module-initializers.test.d.ts +1 -0
  164. package/dist/frontend/lowering/deferred-module-initializers.test.js +92 -0
  165. package/dist/frontend/lowering/deferred-module-initializers.test.js.map +1 -0
  166. package/dist/frontend/lowering/expressions/object-literals.js +31 -1
  167. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  168. package/dist/frontend/lowering/expressions/optional-chains.js +3 -3
  169. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  170. package/dist/frontend/lowering/import-meta.d.ts +10 -0
  171. package/dist/frontend/lowering/import-meta.js +52 -0
  172. package/dist/frontend/lowering/import-meta.js.map +1 -0
  173. package/dist/frontend/lowering/lower-assert.js +105 -41
  174. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  175. package/dist/frontend/lowering/lower-builtin-values.d.ts +2 -0
  176. package/dist/frontend/lowering/lower-builtin-values.js +22 -1
  177. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  178. package/dist/frontend/lowering/lower-builtins.d.ts +7 -22
  179. package/dist/frontend/lowering/lower-builtins.js +439 -95
  180. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  181. package/dist/frontend/lowering/lower-calls.js +289 -76
  182. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  183. package/dist/frontend/lowering/lower-classes.d.ts +5 -0
  184. package/dist/frontend/lowering/lower-classes.js +443 -29
  185. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  186. package/dist/frontend/lowering/lower-containers.d.ts +6 -2
  187. package/dist/frontend/lowering/lower-containers.js +79 -20
  188. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  189. package/dist/frontend/lowering/lower-exprs.d.ts +10 -6
  190. package/dist/frontend/lowering/lower-exprs.js +329 -170
  191. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  192. package/dist/frontend/lowering/lower-generators.js +5 -1
  193. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  194. package/dist/frontend/lowering/lower-inspect.js +58 -1
  195. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  196. package/dist/frontend/lowering/lower-island.js +4 -0
  197. package/dist/frontend/lowering/lower-island.js.map +1 -1
  198. package/dist/frontend/lowering/lower-island.test.d.ts +1 -0
  199. package/dist/frontend/lowering/lower-island.test.js +51 -0
  200. package/dist/frontend/lowering/lower-island.test.js.map +1 -0
  201. package/dist/frontend/lowering/lower-modules.d.ts +1 -3
  202. package/dist/frontend/lowering/lower-modules.js +186 -82
  203. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  204. package/dist/frontend/lowering/lower-modules.test.js +69 -1
  205. package/dist/frontend/lowering/lower-modules.test.js.map +1 -1
  206. package/dist/frontend/lowering/lower-stmts.js +172 -103
  207. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  208. package/dist/frontend/lowering/lower-stmts.test.d.ts +1 -0
  209. package/dist/frontend/lowering/lower-stmts.test.js +77 -0
  210. package/dist/frontend/lowering/lower-stmts.test.js.map +1 -0
  211. package/dist/frontend/lowering/lower-stream.js +2 -0
  212. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  213. package/dist/frontend/lowering/lower-system-errors.d.ts +6 -0
  214. package/dist/frontend/lowering/lower-system-errors.js +29 -0
  215. package/dist/frontend/lowering/lower-system-errors.js.map +1 -0
  216. package/dist/frontend/lowering/lower-url.d.ts +2 -1
  217. package/dist/frontend/lowering/lower-url.js +32 -9
  218. package/dist/frontend/lowering/lower-url.js.map +1 -1
  219. package/dist/frontend/lowering/lowerer.d.ts +30 -12
  220. package/dist/frontend/lowering/lowerer.js +268 -49
  221. package/dist/frontend/lowering/lowerer.js.map +1 -1
  222. package/dist/frontend/lowering/lowerer.test.js +38 -0
  223. package/dist/frontend/lowering/lowerer.test.js.map +1 -1
  224. package/dist/frontend/lowering/module-namespace-elements.d.ts +7 -0
  225. package/dist/frontend/lowering/module-namespace-elements.js +54 -0
  226. package/dist/frontend/lowering/module-namespace-elements.js.map +1 -0
  227. package/dist/frontend/lowering/object-factory-new.d.ts +4 -3
  228. package/dist/frontend/lowering/object-factory-new.js +27 -14
  229. package/dist/frontend/lowering/object-factory-new.js.map +1 -1
  230. package/dist/frontend/lowering/surfaces.d.ts +3 -2
  231. package/dist/frontend/lowering/surfaces.js +93 -33
  232. package/dist/frontend/lowering/surfaces.js.map +1 -1
  233. package/dist/frontend/lowering/text-decoder-encoding.js +3 -0
  234. package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -1
  235. package/dist/frontend/lowering/text-decoder-encoding.test.js +2 -1
  236. package/dist/frontend/lowering/text-decoder-encoding.test.js.map +1 -1
  237. package/dist/frontend/module-syntax.d.ts +1 -1
  238. package/dist/frontend/module-syntax.js +8 -1
  239. package/dist/frontend/module-syntax.js.map +1 -1
  240. package/dist/frontend/module-syntax.test.js +10 -0
  241. package/dist/frontend/module-syntax.test.js.map +1 -1
  242. package/dist/frontend/npm.d.ts +4 -0
  243. package/dist/frontend/npm.js +86 -33
  244. package/dist/frontend/npm.js.map +1 -1
  245. package/dist/frontend/npm.test.js +103 -0
  246. package/dist/frontend/npm.test.js.map +1 -1
  247. package/dist/frontend/pipeline-native.js +2 -1
  248. package/dist/frontend/pipeline-native.js.map +1 -1
  249. package/dist/frontend/program.js +4 -2
  250. package/dist/frontend/program.js.map +1 -1
  251. package/dist/frontend/services-node.js +3 -2
  252. package/dist/frontend/services-node.js.map +1 -1
  253. package/dist/frontend/services.d.ts +5 -1
  254. package/dist/frontend/services.js +9 -1
  255. package/dist/frontend/services.js.map +1 -1
  256. package/dist/frontend/services.test.js +21 -0
  257. package/dist/frontend/services.test.js.map +1 -1
  258. package/dist/frontend/ts7/ast-node.d.ts +2 -0
  259. package/dist/frontend/ts7/ast-node.js +30 -4
  260. package/dist/frontend/ts7/ast-node.js.map +1 -1
  261. package/dist/frontend/ts7/ast-node.test.js +60 -1
  262. package/dist/frontend/ts7/ast-node.test.js.map +1 -1
  263. package/dist/frontend/type-mapper.js +89 -14
  264. package/dist/frontend/type-mapper.js.map +1 -1
  265. package/dist/frontend/union-discriminants.js +22 -7
  266. package/dist/frontend/union-discriminants.js.map +1 -1
  267. package/dist/index.js +19 -12
  268. package/dist/index.js.map +1 -1
  269. package/dist/ir/analysis.js +1 -0
  270. package/dist/ir/analysis.js.map +1 -1
  271. package/dist/ir/integer-loops.d.ts +7 -0
  272. package/dist/ir/integer-loops.js +23 -0
  273. package/dist/ir/integer-loops.js.map +1 -1
  274. package/dist/ir/integer-loops.test.d.ts +1 -0
  275. package/dist/ir/integer-loops.test.js +41 -0
  276. package/dist/ir/integer-loops.test.js.map +1 -0
  277. package/dist/ir/ir.d.ts +44 -26
  278. package/dist/ir/ir.js +69 -11
  279. package/dist/ir/ir.js.map +1 -1
  280. package/dist/ir/ir.test.js +18 -0
  281. package/dist/ir/ir.test.js.map +1 -1
  282. package/dist/ir/serialize.js +21 -1
  283. package/dist/ir/serialize.js.map +1 -1
  284. package/dist/ir/serialize.test.js +21 -0
  285. package/dist/ir/serialize.test.js.map +1 -1
  286. package/dist/ir/traverse.d.ts +0 -3
  287. package/dist/ir/traverse.js +33 -20
  288. package/dist/ir/traverse.js.map +1 -1
  289. package/dist/ir/validate.js +216 -80
  290. package/dist/ir/validate.js.map +1 -1
  291. package/dist/ir/validate.test.js +244 -1
  292. package/dist/ir/validate.test.js.map +1 -1
  293. package/dist/library/compiler-self-identity.js +1 -1
  294. package/dist/library/compiler-self-identity.test.js +2 -2
  295. package/dist/library/compiler-self-identity.test.js.map +1 -1
  296. package/dist/library/fence-eval.js +9 -2
  297. package/dist/library/fence-eval.js.map +1 -1
  298. package/dist/library/fence-eval.test.d.ts +1 -0
  299. package/dist/library/fence-eval.test.js +21 -0
  300. package/dist/library/fence-eval.test.js.map +1 -0
  301. package/dist/library/int-infer.d.ts +2 -2
  302. package/dist/library/int-infer.js +10 -7
  303. package/dist/library/int-infer.js.map +1 -1
  304. package/dist/library/int-infer.test.js +44 -0
  305. package/dist/library/int-infer.test.js.map +1 -1
  306. package/dist/library/prepare.js +2 -1
  307. package/dist/library/prepare.js.map +1 -1
  308. package/dist/native/runtime-typescript.d.ts +4 -0
  309. package/dist/native/runtime-typescript.js +61 -0
  310. package/dist/native/runtime-typescript.js.map +1 -0
  311. package/dist/native/runtime-typescript.test.d.ts +1 -0
  312. package/dist/native/runtime-typescript.test.js +41 -0
  313. package/dist/native/runtime-typescript.test.js.map +1 -0
  314. package/package.json +20 -20
  315. package/surface-manifest.json +385 -29
@@ -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 } from "../../ir/analysis.js";
5
+ import { dynDesc, streamTypedRefEligible } 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";
@@ -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);
@@ -108,9 +108,25 @@ export class LlDyn {
108
108
  const ty = this.valTy(type);
109
109
  const unpack = ty === "double" ? "bitcast i64 %slot to double" : ty === "i1" ? "trunc i64 %slot to i1" : "inttoptr i64 %slot to ptr";
110
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);
111
+ // Collection reads expose the original mutable element, including
112
+ // records/arrays inside unions, rather than a detached dyn snapshot.
113
+ const B = new BlockBuilder();
114
+ B.line(`%value = ${unpack}`);
115
+ if (type.kind === "union" && this.host.unionsById.get(type.unionId)?.arms.some(streamTypedRefEligible)) {
116
+ B.line(`%result = call ptr @${this.host.liveDynUnionRefAdapter(type)}(ptr %value)`);
117
+ }
118
+ else if (type.kind === "record" || type.kind === "array") {
119
+ const adapter = this.host.liveDynRefAdapter(type);
120
+ const rc = vAdapters(this.host, type);
121
+ const typeId = typeKey(type);
122
+ B.line(`%result = call ptr ${typedRefConstructor(this.host, type)}(ptr %value, ptr ${rc.retain}, ptr ${rc.release}, ptr ${this.host.cstr(typeId)}, ${this.S} ${Buffer.byteLength(typeId, "utf8")}, ptr @${adapter.snapshot}, ptr ${adapter.commit})`);
123
+ }
124
+ else {
125
+ B.line(`%result = call ptr @${this.toDynHelper(type)}(${ty} %value)`);
126
+ }
127
+ B.terminate("ret ptr %result");
112
128
  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`, `}`, "");
129
+ this.defs.push(`define internal ptr @${name}_${role}_box(i64 %slot) ${FN_ATTRS} {`, B.render(), `}`, "", `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
130
  };
115
131
  emitSlot(keyType, "key");
116
132
  emitSlot(valueType, "value");
@@ -326,13 +342,14 @@ export class LlDyn {
326
342
  return matched;
327
343
  }
328
344
  /** `sc_dm_<n>(ptr d) -> i1` — does this dyn fit T? Never throws. */
329
- dynMatchHelper(t) {
345
+ dynMatchHelper(t, preserveRefs = false) {
330
346
  const key = typeKey(t);
331
- const existing = this.dynMatchers.get(key);
347
+ const matcherKey = preserveRefs ? `identity:${key}` : key;
348
+ const existing = this.dynMatchers.get(matcherKey);
332
349
  if (existing)
333
350
  return existing;
334
351
  const name = `sc_dm_${this.dynMatchers.size}`;
335
- this.dynMatchers.set(key, name);
352
+ this.dynMatchers.set(matcherKey, name);
336
353
  const B = new BlockBuilder();
337
354
  if (isRefCounted(t) && t.kind !== "dyn") {
338
355
  const matched = this.typedRefMatches(B, t);
@@ -353,12 +370,17 @@ export class LlDyn {
353
370
  const lPlain = B.newLabel("dm.tr.plain");
354
371
  B.condBr(capsule, lCapsule, lPlain);
355
372
  B.startBlock(lCapsule);
356
- const materialized = B.tmp();
357
- const matched = B.tmp();
358
- B.line(`${materialized} = call ptr @scr_dyn_typed_ref_materialize(ptr %d)`);
359
- B.line(`${matched} = call zeroext i1 @${name}(ptr ${materialized})`);
360
- B.line(`call void @scr_dyn_release_v(ptr ${materialized})`);
361
- 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
+ }
362
384
  B.startBlock(lPlain);
363
385
  }
364
386
  const kindIs = (k) => {
@@ -406,6 +428,13 @@ export class LlDyn {
406
428
  case "promise":
407
429
  kindIs(DYN_KIND.PROMISE);
408
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
+ }
409
438
  case "symbol":
410
439
  kindIs(DYN_KIND.SYMBOL);
411
440
  break;
@@ -436,7 +465,12 @@ export class LlDyn {
436
465
  break;
437
466
  }
438
467
  case "func":
439
- kindIs(DYN_KIND.FUNC);
468
+ this.host.declare(`declare zeroext i1 @scr_dyn_is_callable(ptr)`);
469
+ {
470
+ const matched = B.tmp();
471
+ B.line(`${matched} = call zeroext i1 @scr_dyn_is_callable(ptr %d)`);
472
+ B.terminate(`ret i1 ${matched}`);
473
+ }
440
474
  break;
441
475
  case "classval": {
442
476
  this.host.declare(`declare zeroext i1 @scr_dyn_class_is(ptr, ptr)`);
@@ -495,7 +529,7 @@ export class LlDyn {
495
529
  for (const [i, f] of byIndex.entries()) {
496
530
  const e = this.itemAt(B, items, `${i}`);
497
531
  const m = B.tmp();
498
- 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})`);
499
533
  const ln = B.newLabel("dm.i");
500
534
  B.condBr(m, ln, fail);
501
535
  B.startBlock(ln);
@@ -526,7 +560,7 @@ export class LlDyn {
526
560
  this.host.declare(`declare void @scr_dyn_release(ptr)`);
527
561
  this.pendingBail(B, "dm.read", () => B.line(`call void @scr_dyn_release(ptr ${m})`), "i1 false");
528
562
  const ok = B.tmp();
529
- 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})`);
530
564
  B.line(`call void @scr_dyn_release(ptr ${m})`);
531
565
  B.condBr(ok, lNext, fail);
532
566
  B.startBlock(lNext);
@@ -562,7 +596,7 @@ export class LlDyn {
562
596
  B.startBlock(lNo);
563
597
  }
564
598
  const ok = B.tmp();
565
- 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})`);
566
600
  const lOk = B.newLabel("dm.vo");
567
601
  B.condBr(ok, lOk, fail);
568
602
  B.startBlock(lOk);
@@ -574,7 +608,7 @@ export class LlDyn {
574
608
  break;
575
609
  }
576
610
  case "array": {
577
- const m = this.dynMatchHelper(t.elem);
611
+ const m = this.dynMatchHelper(t.elem, preserveRefs);
578
612
  const fail = B.newLabel("dm.f");
579
613
  const kd = this.kindOf(B, "%d");
580
614
  const isArr = B.tmp();
@@ -584,7 +618,16 @@ export class LlDyn {
584
618
  B.startBlock(l0);
585
619
  const n = this.lenOf(B, "%d");
586
620
  const items = this.itemsOf(B, "%d");
587
- this.i64Loop(B, "dm.el", n, (i) => {
621
+ this.i64Loop(B, "dm.el", n, (i, brNext) => {
622
+ this.host.declare(`declare zeroext i1 @scr_dyn_arr_has_index(ptr, ${this.S})`);
623
+ const present = B.tmp();
624
+ B.line(`${present} = call zeroext i1 @scr_dyn_arr_has_index(ptr %d, ${this.S} ${i})`);
625
+ const valueLabel = B.newLabel("dm.present");
626
+ const holeLabel = B.newLabel("dm.hole");
627
+ B.condBr(present, valueLabel, holeLabel);
628
+ B.startBlock(holeLabel);
629
+ brNext();
630
+ B.startBlock(valueLabel);
588
631
  const e = this.itemAt(B, items, i);
589
632
  const ok = B.tmp();
590
633
  B.line(`${ok} = call zeroext i1 @${m}(ptr ${e})`);
@@ -605,7 +648,7 @@ export class LlDyn {
605
648
  const yes = B.newLabel("dm.y");
606
649
  for (let tag = 0; tag < def.arms.length; tag++) {
607
650
  const ln = B.newLabel("dm.n");
608
- this.unionArmMatch(B, def, tag, yes, ln);
651
+ this.unionArmMatch(B, def, tag, yes, ln, preserveRefs);
609
652
  B.startBlock(ln);
610
653
  }
611
654
  B.terminate(`ret i1 false`);
@@ -643,13 +686,14 @@ export class LlDyn {
643
686
  /** `sc_dc_<n>(ptr d, ptr path) -> T` — validate the checked-dynamic tree against T and
644
687
  * BUILD the typed value (+1), or throw the catchable path-annotated
645
688
  * TypeError and return a dummy with the pending flag set. */
646
- dynCheckHelper(t) {
689
+ dynCheckHelper(t, preserveRefs = false) {
647
690
  const key = typeKey(t);
648
- const existing = this.dynBuilders.get(key);
691
+ const builderKey = preserveRefs ? `identity:${key}` : key;
692
+ const existing = this.dynBuilders.get(builderKey);
649
693
  if (existing)
650
694
  return existing;
651
695
  const name = `sc_dc_${this.dynBuilders.size}`;
652
- this.dynBuilders.set(key, name);
696
+ this.dynBuilders.set(builderKey, name);
653
697
  const host = this.host;
654
698
  const retTy = this.valTy(t);
655
699
  const dummy = retTy === "double" ? `double ${f64Lit(0)}` : retTy === "i1" ? "i1 false" : "ptr null";
@@ -686,7 +730,19 @@ export class LlDyn {
686
730
  B.line(`${ref} = call ptr @scr_dyn_typed_ref_unbox(ptr %d)`);
687
731
  B.terminate(`ret ptr ${ref}`);
688
732
  B.startBlock(lNext);
689
- 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") {
690
746
  host.declare(`declare ptr @scr_dyn_typed_ref_materialize(ptr)`);
691
747
  host.declare(`declare ptr @scr_dyn_typed_ref_cached_cast(ptr, ptr, ${host.sizeType})`);
692
748
  host.declare(`declare void @scr_dyn_typed_ref_cache_cast(ptr, ptr, ${host.sizeType}, ptr, ptr, ptr, i1)`);
@@ -896,6 +952,13 @@ export class LlDyn {
896
952
  B.terminate(`ret ptr ${retained}`);
897
953
  break;
898
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
+ }
899
962
  case "bytes": {
900
963
  host.declare(`declare zeroext i1 @scr_dyn_bytes_is(ptr, i32)`);
901
964
  const matched = B.tmp();
@@ -1042,7 +1105,7 @@ export class LlDyn {
1042
1105
  setPath(null, `${i}`);
1043
1106
  const e = this.itemAt(B, items, `${i}`);
1044
1107
  const v = B.tmp();
1045
- 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})`);
1046
1109
  storeInto(f.name, f.type, v);
1047
1110
  this.pendingBail(B, "dct", releaseR, "ptr null");
1048
1111
  });
@@ -1085,7 +1148,7 @@ export class LlDyn {
1085
1148
  this.pendingBail(B, "dcr.read", () => { B.line(`call void @scr_dyn_release(ptr ${m})`); releaseR(); }, "ptr null");
1086
1149
  setPath(f.name, "0");
1087
1150
  const value = B.tmp();
1088
- 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})`);
1089
1152
  B.line(`call void @scr_dyn_release(ptr ${m})`);
1090
1153
  storeInto(f.name, f.type, value);
1091
1154
  this.pendingBail(B, "dcr", releaseR, "ptr null");
@@ -1133,7 +1196,7 @@ export class LlDyn {
1133
1196
  else {
1134
1197
  setPathKeyPtr(ent.key);
1135
1198
  ev = B.tmp();
1136
- 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})`);
1137
1200
  this.pendingBail(B, "dcv", releaseR, "ptr null");
1138
1201
  }
1139
1202
  const ek = B.tmp();
@@ -1158,7 +1221,7 @@ export class LlDyn {
1158
1221
  }
1159
1222
  case "array": {
1160
1223
  const elem = t.elem;
1161
- const c = this.dynCheckHelper(elem);
1224
+ const c = this.dynCheckHelper(elem, preserveRefs);
1162
1225
  requireKind(DYN_KIND.ARR, "dca");
1163
1226
  const n = this.lenOf(B, "%d");
1164
1227
  const a = B.tmp();
@@ -1170,6 +1233,22 @@ export class LlDyn {
1170
1233
  const accTy = acc === "f64" ? "double" : acc === "bool" ? "i1" : "ptr";
1171
1234
  host.declare(`declare double @scr_arr_push_${acc}(ptr, ${acc === "bool" ? "i1 zeroext" : accTy})`);
1172
1235
  this.i64Loop(B, "dca", n, (i) => {
1236
+ host.declare(`declare zeroext i1 @scr_dyn_arr_has_index(ptr, ${this.S})`);
1237
+ const present = B.tmp();
1238
+ B.line(`${present} = call zeroext i1 @scr_dyn_arr_has_index(ptr %d, ${this.S} ${i})`);
1239
+ const valueLabel = B.newLabel("dca.present");
1240
+ const holeLabel = B.newLabel("dca.hole");
1241
+ const doneLabel = B.newLabel("dca.done");
1242
+ B.condBr(present, valueLabel, holeLabel);
1243
+ B.startBlock(holeLabel);
1244
+ host.declare(`declare void @scr_arr_set_len(ptr, double)`);
1245
+ const index = B.tmp();
1246
+ const length = B.tmp();
1247
+ B.line(`${index} = uitofp ${this.S} ${i} to double`);
1248
+ B.line(`${length} = fadd double ${index}, 1.0`);
1249
+ B.line(`call void @scr_arr_set_len(ptr ${a}, double ${length})`);
1250
+ B.br(doneLabel);
1251
+ B.startBlock(valueLabel);
1173
1252
  const pp = B.tmp();
1174
1253
  const kp = B.tmp();
1175
1254
  const ip = B.tmp();
@@ -1188,6 +1267,8 @@ export class LlDyn {
1188
1267
  }, "ptr null");
1189
1268
  const pushed = B.tmp();
1190
1269
  B.line(`${pushed} = call double @scr_arr_push_${acc}(ptr ${a}, ${accTy} ${v})`);
1270
+ B.br(doneLabel);
1271
+ B.startBlock(doneLabel);
1191
1272
  });
1192
1273
  B.terminate(`ret ptr ${a}`);
1193
1274
  break;
@@ -1201,18 +1282,18 @@ export class LlDyn {
1201
1282
  def.arms.forEach((arm, i) => {
1202
1283
  const lHit = B.newLabel("dcu.h");
1203
1284
  const lNext = B.newLabel("dcu.n");
1204
- this.unionArmMatch(B, def, i, lHit, lNext);
1285
+ this.unionArmMatch(B, def, i, lHit, lNext, preserveRefs);
1205
1286
  B.startBlock(lHit);
1206
1287
  if (arm.kind === "undefinedT" || arm.kind === "nullT") {
1207
1288
  // A matched unit arm builds nothing: THE interned immortal
1208
1289
  // instance (rc == SIZE_MAX — no retain owed).
1209
1290
  B.terminate(`ret ptr ${host.unitInstanceRef(t.unionId, i)}`);
1210
1291
  }
1211
- else if (arm.kind === "f64") {
1292
+ else if (arm.kind === "f64" || arm.kind === "procStream") {
1212
1293
  host.declare(`declare ptr @scr_union_new_f64(i32, double)`);
1213
1294
  const x = B.tmp();
1214
1295
  const u = B.tmp();
1215
- 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)`);
1216
1297
  B.line(`${u} = call ptr @scr_union_new_f64(i32 ${i}, double ${x})`);
1217
1298
  B.terminate(`ret ptr ${u}`);
1218
1299
  }
@@ -1220,7 +1301,7 @@ export class LlDyn {
1220
1301
  host.declare(`declare ptr @scr_union_new_bool(i32, i1 zeroext)`);
1221
1302
  const x = B.tmp();
1222
1303
  const u = B.tmp();
1223
- 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)`);
1224
1305
  B.line(`${u} = call ptr @scr_union_new_bool(i32 ${i}, i1 ${x})`);
1225
1306
  B.terminate(`ret ptr ${u}`);
1226
1307
  }
@@ -1229,12 +1310,17 @@ export class LlDyn {
1229
1310
  host.declare(`declare ptr @scr_union_new_ref(i32, ptr, ptr, ptr, ptr)`);
1230
1311
  const x = B.tmp();
1231
1312
  const u = B.tmp();
1232
- 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)`);
1233
1314
  B.line(`${u} = call ptr @scr_union_new_ref(i32 ${i}, ptr ${x}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(host, arm)})`);
1234
1315
  B.terminate(`ret ptr ${u}`);
1235
1316
  }
1236
1317
  B.startBlock(lNext);
1237
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
+ }
1238
1324
  // Preserve an exact typed-ref arm above. If no producer tag matched,
1239
1325
  // retry the union against the ordinary copy-based structural
1240
1326
  // snapshot (the compiler's width-coercion stance, rather than a
@@ -1316,7 +1402,22 @@ export class LlDyn {
1316
1402
  // caps[0] obj-box owns the dyn value (untraced).
1317
1403
  const adapter = this.dynFuncAdapterHelper(t);
1318
1404
  const sigLit = host.cstr(key);
1319
- requireKind(DYN_KIND.FUNC, "dcf");
1405
+ const lWrap = B.newLabel("dcf.w");
1406
+ host.declare(`declare zeroext i1 @scr_dyn_is_callable(ptr)`);
1407
+ const callable = B.tmp();
1408
+ const valid = B.newLabel("dcf.k");
1409
+ const invalid = B.newLabel("dcf.f");
1410
+ B.line(`${callable} = call zeroext i1 @scr_dyn_is_callable(ptr %d)`);
1411
+ B.condBr(callable, valid, invalid);
1412
+ B.startBlock(invalid);
1413
+ B.line(`call void @scr_dyn_check_fail(ptr %path, ptr ${want}, ptr %d)`);
1414
+ B.terminate(`ret ${dummy}`);
1415
+ B.startBlock(valid);
1416
+ const direct = B.tmp();
1417
+ const lSignature = B.newLabel("dcf.signature");
1418
+ B.line(`${direct} = icmp eq i32 ${this.kindOf(B, "%d")}, ${DYN_KIND.FUNC}`);
1419
+ B.condBr(direct, lSignature, lWrap);
1420
+ B.startBlock(lSignature);
1320
1421
  host.declare(`declare i32 @strcmp(ptr, ptr)`);
1321
1422
  const sigp = B.tmp();
1322
1423
  const sig = B.tmp();
@@ -1327,7 +1428,6 @@ export class LlDyn {
1327
1428
  B.line(`${cmp} = call i32 @strcmp(ptr ${sig}, ptr ${sigLit})`);
1328
1429
  B.line(`${same} = icmp eq i32 ${cmp}, 0`);
1329
1430
  const lSame = B.newLabel("dcf.s");
1330
- const lWrap = B.newLabel("dcf.w");
1331
1431
  B.condBr(same, lSame, lWrap);
1332
1432
  B.startBlock(lSame);
1333
1433
  host.declare(`declare ptr @scr_closure_retain_v(ptr)`);
@@ -1347,14 +1447,14 @@ export class LlDyn {
1347
1447
  host.declare(`declare void @scr_dyn_release_v(ptr)`);
1348
1448
  const a = B.tmp();
1349
1449
  B.line(`${a} = call ptr @scr_closure_new(ptr @${adapter}, ${host.sizeType} 1)`);
1350
- const sourceClosure = this.payloadOf(B, "%d", "ptr");
1351
- const sourceKind = B.tmp();
1450
+ host.declare(`declare i32 @scr_dyn_function_kind(ptr)`);
1352
1451
  const functionKind = B.tmp();
1353
1452
  const targetKind = B.tmp();
1354
- B.line(`${sourceKind} = getelementptr inbounds %ScrClosure, ptr ${sourceClosure}, i64 0, i32 4`);
1355
- B.line(`${functionKind} = load i32, ptr ${sourceKind}`);
1453
+ B.line(`${functionKind} = call i32 @scr_dyn_function_kind(ptr %d)`);
1356
1454
  B.line(`${targetKind} = getelementptr inbounds %ScrClosure, ptr ${a}, i64 0, i32 4`);
1357
- B.line(`store i32 ${functionKind}, ptr ${targetKind}`);
1455
+ const adapterKind = B.tmp();
1456
+ B.line(`${adapterKind} = or i32 ${functionKind}, 8 ; preserves the checked callable in caps[0]`);
1457
+ B.line(`store i32 ${adapterKind}, ptr ${targetKind}`);
1358
1458
  const box = B.tmp();
1359
1459
  B.line(`${box} = call ptr @scr_box_new_obj(ptr @scr_dyn_retain_v, ptr @scr_dyn_release_v, ptr @scr_dyn_trace_v)`);
1360
1460
  const capp = B.tmp();
@@ -1454,6 +1554,13 @@ export class LlDyn {
1454
1554
  B.terminate(`ret ptr ${r}`);
1455
1555
  break;
1456
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
+ }
1457
1564
  case "string": {
1458
1565
  host.declare(`declare ptr @scr_dyn_new_str(ptr)`);
1459
1566
  const r = B.tmp();
@@ -1690,9 +1797,19 @@ export class LlDyn {
1690
1797
  const state = B.tmp();
1691
1798
  const undefinedState = B.tmp();
1692
1799
  const undefinedLabel = B.newLabel("tda.undefined");
1800
+ const holeLabel = B.newLabel("tda.hole");
1801
+ const presentLabel = B.newLabel("tda.present");
1693
1802
  const valueLabel = B.newLabel("tda.value");
1694
1803
  const doneLabel = B.newLabel("tda.done");
1695
1804
  B.line(`${state} = call double @scr_arr_state(ptr %v, double ${i})`);
1805
+ const hole = B.tmp();
1806
+ B.line(`${hole} = fcmp oeq double ${state}, 0.0`); // SCR_ARR_HOLE
1807
+ B.condBr(hole, holeLabel, presentLabel);
1808
+ B.startBlock(holeLabel);
1809
+ host.declare(`declare void @scr_dyn_arr_push_hole(ptr)`);
1810
+ B.line(`call void @scr_dyn_arr_push_hole(ptr ${d})`);
1811
+ B.br(doneLabel);
1812
+ B.startBlock(presentLabel);
1696
1813
  B.line(`${undefinedState} = fcmp oeq double ${state}, 2.0`); // SCR_ARR_UNDEFINED
1697
1814
  B.terminate(`br i1 ${undefinedState}, label %${undefinedLabel}, label %${valueLabel}`);
1698
1815
  B.startBlock(undefinedLabel);
@@ -1762,13 +1879,12 @@ export class LlDyn {
1762
1879
  B.line(`${r} = call ptr @scr_dyn_new_null()`);
1763
1880
  B.terminate(`ret ptr ${r}`);
1764
1881
  }
1765
- else if (arm.kind === "f64") {
1882
+ else if (arm.kind === "f64" || arm.kind === "procStream") {
1766
1883
  host.declare(`declare double @scr_union_get_f64(ptr)`);
1767
- host.declare(`declare ptr @scr_dyn_new_num(double)`);
1768
1884
  const x = B.tmp();
1769
1885
  const r = B.tmp();
1770
1886
  B.line(`${x} = call double @scr_union_get_f64(ptr %v)`);
1771
- B.line(`${r} = call ptr @scr_dyn_new_num(double ${x})`);
1887
+ B.line(`${r} = call ptr @${this.toDynHelper(arm)}(double ${x})`);
1772
1888
  B.terminate(`ret ptr ${r}`);
1773
1889
  }
1774
1890
  else if (arm.kind === "bool") {
@@ -1885,13 +2001,13 @@ export class LlDyn {
1885
2001
  fulfill(dv);
1886
2002
  break;
1887
2003
  }
2004
+ case "procStream":
1888
2005
  case "f64": {
1889
2006
  host.declare(`declare double @scr_promise_payload_f64(ptr)`);
1890
- host.declare(`declare ptr @scr_dyn_new_num(double)`);
1891
2007
  const x = B.tmp();
1892
2008
  const dv = B.tmp();
1893
2009
  B.line(`${x} = call double @scr_promise_payload_f64(ptr %src)`);
1894
- B.line(`${dv} = call ptr @scr_dyn_new_num(double ${x})`);
2010
+ B.line(`${dv} = call ptr @${this.toDynHelper(inner)}(double ${x})`);
1895
2011
  fulfill(dv);
1896
2012
  break;
1897
2013
  }