@scriptc/compiler 0.1.7 → 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 (1043) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +98 -39
  2. package/ambient/scriptc-overrides.d.ts +10 -6
  3. package/ambient/scriptc.d.ts +15 -0
  4. package/dist/backend/build-cache.d.ts +1 -3
  5. package/dist/backend/build-cache.js +3 -22
  6. package/dist/backend/build-cache.js.map +1 -1
  7. package/dist/backend/cache-root.d.ts +3 -0
  8. package/dist/backend/cache-root.js +23 -0
  9. package/dist/backend/cache-root.js.map +1 -0
  10. package/dist/backend/cycle-analysis.d.ts +15 -0
  11. package/dist/backend/cycle-analysis.js +108 -0
  12. package/dist/backend/cycle-analysis.js.map +1 -0
  13. package/dist/backend/cycle-analysis.test.js +124 -0
  14. package/dist/backend/cycle-analysis.test.js.map +1 -0
  15. package/dist/backend/executable-features.d.ts +4 -0
  16. package/dist/backend/executable-features.js +42 -0
  17. package/dist/backend/executable-features.js.map +1 -0
  18. package/dist/backend/external-c.d.ts +5 -27
  19. package/dist/backend/external-c.js +5 -40
  20. package/dist/backend/external-c.js.map +1 -1
  21. package/dist/backend/ffi-callbacks.d.ts +2 -3
  22. package/dist/backend/ffi-callbacks.js +2 -3
  23. package/dist/backend/ffi-callbacks.js.map +1 -1
  24. package/dist/backend/library-identity-markers.d.ts +4 -9
  25. package/dist/backend/library-identity-markers.js +11 -49
  26. package/dist/backend/library-identity-markers.js.map +1 -1
  27. package/dist/backend/library-pack.d.ts +5 -0
  28. package/dist/backend/library-pack.js +123 -0
  29. package/dist/backend/library-pack.js.map +1 -0
  30. package/dist/backend/link-plan-core.d.ts +20 -0
  31. package/dist/backend/link-plan-core.js +18 -0
  32. package/dist/backend/link-plan-core.js.map +1 -0
  33. package/dist/backend/link-plan.d.ts +1 -1
  34. package/dist/backend/link-plan.js +16 -17
  35. package/dist/backend/link-plan.js.map +1 -1
  36. package/dist/backend/link-trace.d.ts +2 -0
  37. package/dist/backend/link-trace.js +24 -0
  38. package/dist/backend/link-trace.js.map +1 -0
  39. package/dist/backend/linker.js +1 -1
  40. package/dist/backend/linker.js.map +1 -1
  41. package/dist/backend/literals.d.ts +9 -0
  42. package/dist/backend/literals.js +35 -0
  43. package/dist/backend/literals.js.map +1 -0
  44. package/dist/backend/literals.test.d.ts +1 -0
  45. package/dist/backend/literals.test.js +53 -0
  46. package/dist/backend/literals.test.js.map +1 -0
  47. package/dist/backend/llvm/blocks.d.ts +2 -0
  48. package/dist/backend/llvm/blocks.js +9 -4
  49. package/dist/backend/llvm/blocks.js.map +1 -1
  50. package/dist/backend/llvm/blocks.test.d.ts +1 -0
  51. package/dist/backend/llvm/blocks.test.js +91 -0
  52. package/dist/backend/llvm/blocks.test.js.map +1 -0
  53. package/dist/backend/llvm/classes.d.ts +14 -8
  54. package/dist/backend/llvm/classes.js +88 -30
  55. package/dist/backend/llvm/classes.js.map +1 -1
  56. package/dist/backend/llvm/common.d.ts +5 -1
  57. package/dist/backend/llvm/common.js +45 -4
  58. package/dist/backend/llvm/common.js.map +1 -1
  59. package/dist/backend/llvm/debug-info.js +2 -7
  60. package/dist/backend/llvm/debug-info.js.map +1 -1
  61. package/dist/backend/llvm/debug-info.test.d.ts +1 -0
  62. package/dist/backend/llvm/debug-info.test.js +110 -0
  63. package/dist/backend/llvm/debug-info.test.js.map +1 -0
  64. package/dist/backend/llvm/dyn.d.ts +21 -2
  65. package/dist/backend/llvm/dyn.js +647 -251
  66. package/dist/backend/llvm/dyn.js.map +1 -1
  67. package/dist/backend/llvm/emitter.d.ts +596 -1
  68. package/dist/backend/llvm/emitter.js +769 -425
  69. package/dist/backend/llvm/emitter.js.map +1 -1
  70. package/dist/backend/llvm/emitter.test.d.ts +1 -0
  71. package/dist/backend/llvm/emitter.test.js +179 -0
  72. package/dist/backend/llvm/emitter.test.js.map +1 -0
  73. package/dist/backend/llvm/expr-async.js +23 -14
  74. package/dist/backend/llvm/expr-async.js.map +1 -1
  75. package/dist/backend/llvm/expr-bytes.d.ts +2 -2
  76. package/dist/backend/llvm/expr-bytes.js +60 -31
  77. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  78. package/dist/backend/llvm/expr-callbacks.d.ts +1 -1
  79. package/dist/backend/llvm/expr-callbacks.js +25 -22
  80. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  81. package/dist/backend/llvm/expr-calls.js +136 -35
  82. package/dist/backend/llvm/expr-calls.js.map +1 -1
  83. package/dist/backend/llvm/expr-containers.d.ts +1 -1
  84. package/dist/backend/llvm/expr-containers.js +43 -14
  85. package/dist/backend/llvm/expr-containers.js.map +1 -1
  86. package/dist/backend/llvm/expr-context.d.ts +5 -260
  87. package/dist/backend/llvm/expr-control.js +10 -6
  88. package/dist/backend/llvm/expr-control.js.map +1 -1
  89. package/dist/backend/llvm/expr-dispatch.d.ts +1 -1
  90. package/dist/backend/llvm/expr-dispatch.js +2 -0
  91. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  92. package/dist/backend/llvm/expr-dynamic.js +78 -81
  93. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  94. package/dist/backend/llvm/expr-island.d.ts +1 -1
  95. package/dist/backend/llvm/expr-island.js +11 -7
  96. package/dist/backend/llvm/expr-island.js.map +1 -1
  97. package/dist/backend/llvm/expr-primitives.d.ts +1 -1
  98. package/dist/backend/llvm/expr-primitives.js +62 -31
  99. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  100. package/dist/backend/llvm/expr-primitives.test.js +1 -1
  101. package/dist/backend/llvm/expr-records.d.ts +5 -1
  102. package/dist/backend/llvm/expr-records.js +54 -7
  103. package/dist/backend/llvm/expr-records.js.map +1 -1
  104. package/dist/backend/llvm/expr-stream-bridges.d.ts +4 -4
  105. package/dist/backend/llvm/expr-stream-bridges.js +220 -131
  106. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  107. package/dist/backend/llvm/expr-stream-bridges.test.d.ts +1 -0
  108. package/dist/backend/llvm/expr-stream-bridges.test.js +55 -0
  109. package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -0
  110. package/dist/backend/llvm/expr-stream-callbacks.d.ts +1 -1
  111. package/dist/backend/llvm/expr-stream-callbacks.js +12 -12
  112. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  113. package/dist/backend/llvm/layouts.d.ts +19 -0
  114. package/dist/backend/llvm/layouts.js +12 -0
  115. package/dist/backend/llvm/layouts.js.map +1 -0
  116. package/dist/backend/llvm/lib-abi.d.ts +19 -0
  117. package/dist/backend/llvm/lib-abi.js +82 -0
  118. package/dist/backend/llvm/lib-abi.js.map +1 -0
  119. package/dist/backend/llvm/lib-connect.d.ts +2 -0
  120. package/dist/backend/llvm/lib-connect.js +51 -0
  121. package/dist/backend/llvm/lib-connect.js.map +1 -0
  122. package/dist/backend/llvm/lib-datagram.d.ts +2 -0
  123. package/dist/backend/llvm/lib-datagram.js +135 -0
  124. package/dist/backend/llvm/lib-datagram.js.map +1 -0
  125. package/dist/backend/llvm/lib-dispatch.js +50 -6
  126. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  127. package/dist/backend/llvm/lib-filesystem.js +30 -18
  128. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  129. package/dist/backend/llvm/lib-http2.d.ts +2 -0
  130. package/dist/backend/llvm/lib-http2.js +215 -0
  131. package/dist/backend/llvm/lib-http2.js.map +1 -0
  132. package/dist/backend/llvm/lib-lookup.d.ts +2 -0
  133. package/dist/backend/llvm/lib-lookup.js +39 -0
  134. package/dist/backend/llvm/lib-lookup.js.map +1 -0
  135. package/dist/backend/llvm/lib-network.js +25 -2
  136. package/dist/backend/llvm/lib-network.js.map +1 -1
  137. package/dist/backend/llvm/lib-process.js +44 -19
  138. package/dist/backend/llvm/lib-process.js.map +1 -1
  139. package/dist/backend/llvm/lib-shared.js +162 -3
  140. package/dist/backend/llvm/lib-shared.js.map +1 -1
  141. package/dist/backend/llvm/lib-stream.js +3 -2
  142. package/dist/backend/llvm/lib-stream.js.map +1 -1
  143. package/dist/backend/llvm/lib-test.d.ts +2 -0
  144. package/dist/backend/llvm/lib-test.js +34 -0
  145. package/dist/backend/llvm/lib-test.js.map +1 -0
  146. package/dist/backend/llvm/lib-tls.d.ts +2 -0
  147. package/dist/backend/llvm/lib-tls.js +82 -0
  148. package/dist/backend/llvm/lib-tls.js.map +1 -0
  149. package/dist/backend/llvm/shapes.d.ts +10 -9
  150. package/dist/backend/llvm/shapes.js +42 -131
  151. package/dist/backend/llvm/shapes.js.map +1 -1
  152. package/dist/backend/llvm/unsupported.d.ts +1 -0
  153. package/dist/backend/llvm/unsupported.js +1 -2
  154. package/dist/backend/llvm/unsupported.js.map +1 -1
  155. package/dist/backend/llvm/walkers.js +1 -7
  156. package/dist/backend/llvm/walkers.js.map +1 -1
  157. package/dist/backend/mangle.d.ts +2 -2
  158. package/dist/backend/mangle.js +16 -5
  159. package/dist/backend/mangle.js.map +1 -1
  160. package/dist/backend/{c/may-throw.d.ts → may-throw.d.ts} +1 -1
  161. package/dist/backend/{c/may-throw.js → may-throw.js} +51 -46
  162. package/dist/backend/may-throw.js.map +1 -0
  163. package/dist/backend/may-throw.test.d.ts +1 -0
  164. package/dist/backend/may-throw.test.js +58 -0
  165. package/dist/backend/may-throw.test.js.map +1 -0
  166. package/dist/backend/native-codegen-core.d.ts +22 -0
  167. package/dist/backend/native-codegen-core.js +44 -0
  168. package/dist/backend/native-codegen-core.js.map +1 -0
  169. package/dist/backend/native-codegen.d.ts +3 -19
  170. package/dist/backend/native-codegen.js +5 -44
  171. package/dist/backend/native-codegen.js.map +1 -1
  172. package/dist/backend/native-codegen.test.js +2 -2
  173. package/dist/backend/native-codegen.test.js.map +1 -1
  174. package/dist/backend/native-link-info-core.d.ts +94 -0
  175. package/dist/backend/native-link-info-core.js +62 -0
  176. package/dist/backend/native-link-info-core.js.map +1 -0
  177. package/dist/backend/native-link-info.d.ts +3 -88
  178. package/dist/backend/native-link-info.js +12 -243
  179. package/dist/backend/native-link-info.js.map +1 -1
  180. package/dist/backend/native-link-info.test.js +41 -146
  181. package/dist/backend/native-link-info.test.js.map +1 -1
  182. package/dist/backend/native-toolchain.d.ts +12 -30
  183. package/dist/backend/native-toolchain.js +83 -233
  184. package/dist/backend/native-toolchain.js.map +1 -1
  185. package/dist/backend/native-toolchain.test.js +77 -5
  186. package/dist/backend/native-toolchain.test.js.map +1 -1
  187. package/dist/backend/native-tools.d.ts +24 -0
  188. package/dist/backend/native-tools.js +33 -0
  189. package/dist/backend/native-tools.js.map +1 -0
  190. package/dist/backend/object-localize.js +19 -8
  191. package/dist/backend/object-localize.js.map +1 -1
  192. package/dist/backend/object-localize.test.js +22 -0
  193. package/dist/backend/object-localize.test.js.map +1 -1
  194. package/dist/backend/runtime-abi.d.ts +2 -2
  195. package/dist/backend/runtime-abi.js +2 -2
  196. package/dist/backend/runtime-pack-core.d.ts +101 -0
  197. package/dist/backend/runtime-pack-core.js +172 -0
  198. package/dist/backend/runtime-pack-core.js.map +1 -0
  199. package/dist/backend/runtime-pack-native.d.ts +21 -0
  200. package/dist/backend/runtime-pack-native.js +73 -0
  201. package/dist/backend/runtime-pack-native.js.map +1 -0
  202. package/dist/backend/runtime-pack-targets.test.js +1 -1
  203. package/dist/backend/runtime-pack.d.ts +3 -83
  204. package/dist/backend/runtime-pack.js +8 -151
  205. package/dist/backend/runtime-pack.js.map +1 -1
  206. package/dist/backend/runtime-pack.test.js +24 -1
  207. package/dist/backend/runtime-pack.test.js.map +1 -1
  208. package/dist/backend/target-diagnostics.d.ts +22 -0
  209. package/dist/backend/target-diagnostics.js +108 -0
  210. package/dist/backend/target-diagnostics.js.map +1 -0
  211. package/dist/backend/target-platform.d.ts +15 -0
  212. package/dist/backend/target-platform.js +72 -0
  213. package/dist/backend/target-platform.js.map +1 -0
  214. package/dist/backend/targets.d.ts +13 -4
  215. package/dist/backend/targets.js +103 -34
  216. package/dist/backend/targets.js.map +1 -1
  217. package/dist/backend/targets.test.js +72 -4
  218. package/dist/backend/targets.test.js.map +1 -1
  219. package/dist/backend/toolchain-environment.d.ts +6 -0
  220. package/dist/backend/toolchain-environment.js +99 -0
  221. package/dist/backend/toolchain-environment.js.map +1 -0
  222. package/dist/backend/vendor-archives.d.ts +1 -9
  223. package/dist/backend/vendor-archives.js +2 -9
  224. package/dist/backend/vendor-archives.js.map +1 -1
  225. package/dist/backend/vendor-inputs.d.ts +9 -0
  226. package/dist/backend/vendor-inputs.js +10 -0
  227. package/dist/backend/vendor-inputs.js.map +1 -0
  228. package/dist/backend/warm-cache.d.ts +3 -0
  229. package/dist/backend/warm-cache.js +41 -0
  230. package/dist/backend/warm-cache.js.map +1 -0
  231. package/dist/cli/command.d.ts +3 -0
  232. package/dist/cli/command.js +328 -0
  233. package/dist/cli/command.js.map +1 -0
  234. package/dist/cli/host.d.ts +24 -0
  235. package/dist/cli/host.js +2 -0
  236. package/dist/cli/host.js.map +1 -0
  237. package/dist/cli/output-options.d.ts +26 -0
  238. package/dist/cli/output-options.js +60 -0
  239. package/dist/cli/output-options.js.map +1 -0
  240. package/dist/cli/paths.d.ts +12 -0
  241. package/dist/cli/paths.js +42 -0
  242. package/dist/cli/paths.js.map +1 -0
  243. package/dist/cli/usage.d.ts +74 -0
  244. package/dist/cli/usage.js +86 -0
  245. package/dist/cli/usage.js.map +1 -0
  246. package/dist/cli/wasi-paths.d.ts +8 -0
  247. package/dist/cli/wasi-paths.js +41 -0
  248. package/dist/cli/wasi-paths.js.map +1 -0
  249. package/dist/cli/wasi-runner.d.ts +2 -0
  250. package/dist/cli/wasi-runner.js +28 -0
  251. package/dist/cli/wasi-runner.js.map +1 -0
  252. package/dist/compat/fetch-profile.js +37 -7
  253. package/dist/compat/fetch-profile.js.map +1 -1
  254. package/dist/compile-types.d.ts +162 -0
  255. package/dist/compile-types.js +2 -0
  256. package/dist/compile-types.js.map +1 -0
  257. package/dist/coverage/report.js +11 -5
  258. package/dist/coverage/report.js.map +1 -1
  259. package/dist/coverage/surface-manifest.js +5 -2
  260. package/dist/coverage/surface-manifest.js.map +1 -1
  261. package/dist/diagnostics/diagnostic.js +5 -10
  262. package/dist/diagnostics/diagnostic.js.map +1 -1
  263. package/dist/executable/executable-cache.d.ts +3 -4
  264. package/dist/executable/executable-cache.js +5 -6
  265. package/dist/executable/executable-cache.js.map +1 -1
  266. package/dist/executable/executable-cache.test.js +16 -17
  267. package/dist/executable/executable-cache.test.js.map +1 -1
  268. package/dist/executable/prepare.d.ts +14 -0
  269. package/dist/executable/prepare.js +66 -0
  270. package/dist/executable/prepare.js.map +1 -0
  271. package/dist/ffi/ffi-manifest.d.ts +11 -4
  272. package/dist/ffi/ffi-manifest.js +170 -58
  273. package/dist/ffi/ffi-manifest.js.map +1 -1
  274. package/dist/ffi/ffi-manifest.test.d.ts +1 -0
  275. package/dist/ffi/ffi-manifest.test.js +111 -0
  276. package/dist/ffi/ffi-manifest.test.js.map +1 -0
  277. package/dist/format-integer.d.ts +3 -0
  278. package/dist/format-integer.js +14 -0
  279. package/dist/format-integer.js.map +1 -0
  280. package/dist/frontend/analysis.d.ts +5 -0
  281. package/dist/frontend/analysis.js +88 -0
  282. package/dist/frontend/analysis.js.map +1 -0
  283. package/dist/frontend/arguments-usage.d.ts +1 -3
  284. package/dist/frontend/arguments-usage.js.map +1 -1
  285. package/dist/frontend/builtin-modules.d.ts +1 -1
  286. package/dist/frontend/builtin-modules.js +1 -1
  287. package/dist/frontend/builtin-modules.js.map +1 -1
  288. package/dist/frontend/cjs-lexer.d.ts +4 -25
  289. package/dist/frontend/cjs-lexer.js +6 -806
  290. package/dist/frontend/cjs-lexer.js.map +1 -1
  291. package/dist/frontend/cjs-resolve.d.ts +5 -0
  292. package/dist/frontend/cjs-resolve.js +429 -0
  293. package/dist/frontend/cjs-resolve.js.map +1 -0
  294. package/dist/frontend/cjs-syntax.d.ts +26 -0
  295. package/dist/frontend/cjs-syntax.js +806 -0
  296. package/dist/frontend/cjs-syntax.js.map +1 -0
  297. package/dist/frontend/comptime-node.d.ts +4 -0
  298. package/dist/frontend/comptime-node.js +16 -0
  299. package/dist/frontend/comptime-node.js.map +1 -0
  300. package/dist/frontend/comptime-node.test.d.ts +1 -0
  301. package/dist/frontend/comptime-node.test.js +37 -0
  302. package/dist/frontend/comptime-node.test.js.map +1 -0
  303. package/dist/frontend/dts-paths.d.ts +3 -4
  304. package/dist/frontend/dts-paths.js +15 -8
  305. package/dist/frontend/dts-paths.js.map +1 -1
  306. package/dist/frontend/fork-target.js +2 -2
  307. package/dist/frontend/fork-target.js.map +1 -1
  308. package/dist/frontend/helper-tokens.d.ts +1 -0
  309. package/dist/frontend/helper-tokens.js +147 -0
  310. package/dist/frontend/helper-tokens.js.map +1 -0
  311. package/dist/frontend/helper-tokens.test.d.ts +1 -0
  312. package/dist/frontend/helper-tokens.test.js +35 -0
  313. package/dist/frontend/helper-tokens.test.js.map +1 -0
  314. package/dist/frontend/inferred-js-diagnostics.d.ts +5 -0
  315. package/dist/frontend/inferred-js-diagnostics.js +69 -0
  316. package/dist/frontend/inferred-js-diagnostics.js.map +1 -0
  317. package/dist/frontend/inferred-js-diagnostics.test.d.ts +1 -0
  318. package/dist/frontend/inferred-js-diagnostics.test.js +58 -0
  319. package/dist/frontend/inferred-js-diagnostics.test.js.map +1 -0
  320. package/dist/frontend/input-tracker.d.ts +5 -2
  321. package/dist/frontend/input-tracker.js +24 -3
  322. package/dist/frontend/input-tracker.js.map +1 -1
  323. package/dist/frontend/input-tracker.test.js +23 -0
  324. package/dist/frontend/input-tracker.test.js.map +1 -1
  325. package/dist/frontend/lib-contract.js +32 -24
  326. package/dist/frontend/lib-contract.js.map +1 -1
  327. package/dist/frontend/literal-values.d.ts +4 -0
  328. package/dist/frontend/literal-values.js +21 -0
  329. package/dist/frontend/literal-values.js.map +1 -0
  330. package/dist/frontend/literal-values.test.d.ts +1 -0
  331. package/dist/frontend/literal-values.test.js +91 -0
  332. package/dist/frontend/literal-values.test.js.map +1 -0
  333. package/dist/frontend/lowering/abstract-equality.d.ts +1 -1
  334. package/dist/frontend/lowering/abstract-equality.js +3 -0
  335. package/dist/frontend/lowering/abstract-equality.js.map +1 -1
  336. package/dist/frontend/lowering/array-indexed-mutation.js +11 -6
  337. package/dist/frontend/lowering/array-indexed-mutation.js.map +1 -1
  338. package/dist/frontend/lowering/array-values.d.ts +4 -1
  339. package/dist/frontend/lowering/array-values.js +43 -1
  340. package/dist/frontend/lowering/array-values.js.map +1 -1
  341. package/dist/frontend/lowering/callback-arg.js +1 -0
  342. package/dist/frontend/lowering/callback-arg.js.map +1 -1
  343. package/dist/frontend/lowering/class-callbacks.d.ts +12 -0
  344. package/dist/frontend/lowering/class-callbacks.js +74 -0
  345. package/dist/frontend/lowering/class-callbacks.js.map +1 -0
  346. package/dist/frontend/lowering/class-construction.d.ts +12 -0
  347. package/dist/frontend/lowering/class-construction.js +156 -0
  348. package/dist/frontend/lowering/class-construction.js.map +1 -0
  349. package/dist/frontend/lowering/class-descriptors.d.ts +10 -0
  350. package/dist/frontend/lowering/class-descriptors.js +114 -0
  351. package/dist/frontend/lowering/class-descriptors.js.map +1 -0
  352. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +51 -0
  353. package/dist/frontend/lowering/class-dynamic-dispatch.js +1158 -0
  354. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -0
  355. package/dist/frontend/lowering/class-dynamic-dispatch.test.d.ts +1 -0
  356. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +93 -0
  357. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -0
  358. package/dist/frontend/lowering/class-instance-constructor.d.ts +7 -0
  359. package/dist/frontend/lowering/class-instance-constructor.js +67 -0
  360. package/dist/frontend/lowering/class-instance-constructor.js.map +1 -0
  361. package/dist/frontend/lowering/class-method-values.d.ts +13 -0
  362. package/dist/frontend/lowering/class-method-values.js +235 -0
  363. package/dist/frontend/lowering/class-method-values.js.map +1 -0
  364. package/dist/frontend/lowering/class-prototypes.d.ts +19 -0
  365. package/dist/frontend/lowering/class-prototypes.js +242 -0
  366. package/dist/frontend/lowering/class-prototypes.js.map +1 -0
  367. package/dist/frontend/lowering/class-runtime-statics.d.ts +8 -0
  368. package/dist/frontend/lowering/class-runtime-statics.js +66 -0
  369. package/dist/frontend/lowering/class-runtime-statics.js.map +1 -0
  370. package/dist/frontend/lowering/class-static-data.d.ts +6 -0
  371. package/dist/frontend/lowering/class-static-data.js +56 -0
  372. package/dist/frontend/lowering/class-static-data.js.map +1 -0
  373. package/dist/frontend/lowering/containers/buffer-numeric-methods.d.ts +4 -0
  374. package/dist/frontend/lowering/containers/buffer-numeric-methods.js +26 -0
  375. package/dist/frontend/lowering/containers/buffer-numeric-methods.js.map +1 -0
  376. package/dist/frontend/lowering/containers/bytes.d.ts +11 -7
  377. package/dist/frontend/lowering/containers/bytes.js +208 -163
  378. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  379. package/dist/frontend/lowering/containers/string-and-regexp.d.ts +2 -2
  380. package/dist/frontend/lowering/containers/string-and-regexp.js +58 -63
  381. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  382. package/dist/frontend/lowering/containers/string-replacement.d.ts +7 -0
  383. package/dist/frontend/lowering/containers/string-replacement.js +217 -0
  384. package/dist/frontend/lowering/containers/string-replacement.js.map +1 -0
  385. package/dist/frontend/lowering/error-methods.d.ts +14 -0
  386. package/dist/frontend/lowering/error-methods.js +177 -0
  387. package/dist/frontend/lowering/error-methods.js.map +1 -0
  388. package/dist/frontend/lowering/expressions/global-symbols.d.ts +6 -0
  389. package/dist/frontend/lowering/expressions/global-symbols.js +11 -0
  390. package/dist/frontend/lowering/expressions/global-symbols.js.map +1 -0
  391. package/dist/frontend/lowering/expressions/native-proxy.d.ts +7 -0
  392. package/dist/frontend/lowering/expressions/native-proxy.js +51 -0
  393. package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -0
  394. package/dist/frontend/lowering/expressions/nullish-assignment.d.ts +6 -0
  395. package/dist/frontend/lowering/expressions/nullish-assignment.js +132 -0
  396. package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -0
  397. package/dist/frontend/lowering/expressions/object-literals.d.ts +8 -8
  398. package/dist/frontend/lowering/expressions/object-literals.js +509 -183
  399. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  400. package/dist/frontend/lowering/expressions/optional-chains.d.ts +3 -4
  401. package/dist/frontend/lowering/expressions/optional-chains.js +88 -24
  402. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  403. package/dist/frontend/lowering/expressions/try-lower-expression.js +1 -0
  404. package/dist/frontend/lowering/expressions/try-lower-expression.js.map +1 -1
  405. package/dist/frontend/lowering/expressions/union-field-write.d.ts +8 -0
  406. package/dist/frontend/lowering/expressions/union-field-write.js +71 -0
  407. package/dist/frontend/lowering/expressions/union-field-write.js.map +1 -0
  408. package/dist/frontend/lowering/function-context.d.ts +101 -0
  409. package/dist/frontend/lowering/function-context.js +109 -0
  410. package/dist/frontend/lowering/function-context.js.map +1 -0
  411. package/dist/frontend/lowering/generator-delegation.d.ts +7 -0
  412. package/dist/frontend/lowering/generator-delegation.js +85 -0
  413. package/dist/frontend/lowering/generator-delegation.js.map +1 -0
  414. package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +11 -0
  415. package/dist/frontend/lowering/generator-dynamic-dispatch.js +143 -0
  416. package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -0
  417. package/dist/frontend/lowering/lib-boundary.d.ts +4 -1
  418. package/dist/frontend/lowering/lib-boundary.js +112 -20
  419. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  420. package/dist/frontend/lowering/lib-boundary.test.d.ts +1 -0
  421. package/dist/frontend/lowering/lib-boundary.test.js +45 -0
  422. package/dist/frontend/lowering/lib-boundary.test.js.map +1 -0
  423. package/dist/frontend/lowering/lower-array-sort.d.ts +1 -1
  424. package/dist/frontend/lowering/lower-assert.d.ts +1 -1
  425. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  426. package/dist/frontend/lowering/lower-async-iteration.d.ts +1 -1
  427. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
  428. package/dist/frontend/lowering/lower-builtin-values.d.ts +18 -0
  429. package/dist/frontend/lowering/lower-builtin-values.js +249 -0
  430. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -0
  431. package/dist/frontend/lowering/lower-builtins.d.ts +33 -46
  432. package/dist/frontend/lowering/lower-builtins.js +676 -365
  433. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  434. package/dist/frontend/lowering/lower-calls.d.ts +28 -22
  435. package/dist/frontend/lowering/lower-calls.js +1660 -412
  436. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  437. package/dist/frontend/lowering/lower-classes.d.ts +95 -57
  438. package/dist/frontend/lowering/lower-classes.js +1491 -404
  439. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  440. package/dist/frontend/lowering/lower-comptime.d.ts +1 -1
  441. package/dist/frontend/lowering/lower-comptime.js +23 -32
  442. package/dist/frontend/lowering/lower-comptime.js.map +1 -1
  443. package/dist/frontend/lowering/lower-containers.d.ts +36 -32
  444. package/dist/frontend/lowering/lower-containers.js +925 -181
  445. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  446. package/dist/frontend/lowering/lower-dgram.d.ts +1 -1
  447. package/dist/frontend/lowering/lower-dgram.js +3 -2
  448. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  449. package/dist/frontend/lowering/lower-enums.d.ts +1 -1
  450. package/dist/frontend/lowering/lower-enums.js.map +1 -1
  451. package/dist/frontend/lowering/lower-event-emitter.d.ts +30 -1
  452. package/dist/frontend/lowering/lower-event-emitter.js +58 -26
  453. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  454. package/dist/frontend/lowering/lower-expando.d.ts +7 -1
  455. package/dist/frontend/lowering/lower-expando.js +14 -6
  456. package/dist/frontend/lowering/lower-expando.js.map +1 -1
  457. package/dist/frontend/lowering/lower-exprs.d.ts +37 -13
  458. package/dist/frontend/lowering/lower-exprs.js +2163 -863
  459. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  460. package/dist/frontend/lowering/lower-generators.d.ts +2 -5
  461. package/dist/frontend/lowering/lower-generators.js +88 -46
  462. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  463. package/dist/frontend/lowering/lower-global-value.d.ts +7 -0
  464. package/dist/frontend/lowering/lower-global-value.js +17 -0
  465. package/dist/frontend/lowering/lower-global-value.js.map +1 -0
  466. package/dist/frontend/lowering/lower-inspect.d.ts +1 -1
  467. package/dist/frontend/lowering/lower-inspect.js +17 -8
  468. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  469. package/dist/frontend/lowering/lower-island.d.ts +7 -8
  470. package/dist/frontend/lowering/lower-island.js +66 -33
  471. package/dist/frontend/lowering/lower-island.js.map +1 -1
  472. package/dist/frontend/lowering/lower-mixins.d.ts +2 -2
  473. package/dist/frontend/lowering/lower-mixins.js +5 -3
  474. package/dist/frontend/lowering/lower-mixins.js.map +1 -1
  475. package/dist/frontend/lowering/lower-modules.d.ts +1 -1
  476. package/dist/frontend/lowering/lower-modules.js +445 -39
  477. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  478. package/dist/frontend/lowering/lower-modules.test.d.ts +1 -0
  479. package/dist/frontend/lowering/lower-modules.test.js +39 -0
  480. package/dist/frontend/lowering/lower-modules.test.js.map +1 -0
  481. package/dist/frontend/lowering/lower-namespaces.d.ts +1 -1
  482. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  483. package/dist/frontend/lowering/lower-node-module.d.ts +1 -1
  484. package/dist/frontend/lowering/lower-node-module.js +13 -10
  485. package/dist/frontend/lowering/lower-node-module.js.map +1 -1
  486. package/dist/frontend/lowering/lower-server.d.ts +1 -1
  487. package/dist/frontend/lowering/lower-server.js +6 -10
  488. package/dist/frontend/lowering/lower-server.js.map +1 -1
  489. package/dist/frontend/lowering/lower-stmts.d.ts +17 -17
  490. package/dist/frontend/lowering/lower-stmts.js +855 -514
  491. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  492. package/dist/frontend/lowering/lower-stream.d.ts +1 -1
  493. package/dist/frontend/lowering/lower-stream.js +20 -11
  494. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  495. package/dist/frontend/lowering/lower-test.d.ts +1 -1
  496. package/dist/frontend/lowering/lower-test.js.map +1 -1
  497. package/dist/frontend/lowering/lower-url.d.ts +6 -0
  498. package/dist/frontend/lowering/lower-url.js +77 -0
  499. package/dist/frontend/lowering/lower-url.js.map +1 -0
  500. package/dist/frontend/lowering/lowerer.d.ts +140 -190
  501. package/dist/frontend/lowering/lowerer.js +1193 -712
  502. package/dist/frontend/lowering/lowerer.js.map +1 -1
  503. package/dist/frontend/lowering/lowerer.test.d.ts +1 -0
  504. package/dist/frontend/lowering/lowerer.test.js +172 -0
  505. package/dist/frontend/lowering/lowerer.test.js.map +1 -0
  506. package/dist/frontend/lowering/native-ffi.d.ts +5 -0
  507. package/dist/frontend/lowering/native-ffi.js +40 -0
  508. package/dist/frontend/lowering/native-ffi.js.map +1 -0
  509. package/dist/frontend/lowering/object-enumeration-receiver.d.ts +7 -0
  510. package/dist/frontend/lowering/object-enumeration-receiver.js +33 -0
  511. package/dist/frontend/lowering/object-enumeration-receiver.js.map +1 -0
  512. package/dist/frontend/lowering/object-factory-new.d.ts +8 -0
  513. package/dist/frontend/lowering/object-factory-new.js +68 -0
  514. package/dist/frontend/lowering/object-factory-new.js.map +1 -0
  515. package/dist/frontend/lowering/optional-arguments.js +6 -1
  516. package/dist/frontend/lowering/optional-arguments.js.map +1 -1
  517. package/dist/frontend/lowering/pairs-snapshot.js +2 -1
  518. package/dist/frontend/lowering/pairs-snapshot.js.map +1 -1
  519. package/dist/frontend/lowering/runtime-optional-locals.d.ts +14 -0
  520. package/dist/frontend/lowering/runtime-optional-locals.js +41 -0
  521. package/dist/frontend/lowering/runtime-optional-locals.js.map +1 -0
  522. package/dist/frontend/lowering/runtime-optional-locals.test.d.ts +1 -0
  523. package/dist/frontend/lowering/runtime-optional-locals.test.js +85 -0
  524. package/dist/frontend/lowering/runtime-optional-locals.test.js.map +1 -0
  525. package/dist/frontend/lowering/sanitize-class-types.d.ts +8 -0
  526. package/dist/frontend/lowering/sanitize-class-types.js +79 -0
  527. package/dist/frontend/lowering/sanitize-class-types.js.map +1 -0
  528. package/dist/frontend/lowering/sanitize-class-types.test.d.ts +1 -0
  529. package/dist/frontend/lowering/sanitize-class-types.test.js +60 -0
  530. package/dist/frontend/lowering/sanitize-class-types.test.js.map +1 -0
  531. package/dist/frontend/lowering/static-this.d.ts +5 -1
  532. package/dist/frontend/lowering/static-this.js +28 -2
  533. package/dist/frontend/lowering/static-this.js.map +1 -1
  534. package/dist/frontend/lowering/string-index.d.ts +7 -0
  535. package/dist/frontend/lowering/string-index.js +39 -0
  536. package/dist/frontend/lowering/string-index.js.map +1 -0
  537. package/dist/frontend/lowering/surfaces.d.ts +10 -3
  538. package/dist/frontend/lowering/surfaces.js +86 -37
  539. package/dist/frontend/lowering/surfaces.js.map +1 -1
  540. package/dist/frontend/lowering/symbol-fields.d.ts +22 -0
  541. package/dist/frontend/lowering/symbol-fields.js +183 -0
  542. package/dist/frontend/lowering/symbol-fields.js.map +1 -0
  543. package/dist/frontend/lowering/symbol-methods.d.ts +7 -0
  544. package/dist/frontend/lowering/symbol-methods.js +30 -0
  545. package/dist/frontend/lowering/symbol-methods.js.map +1 -0
  546. package/dist/frontend/lowering/text-decoder-encoding.d.ts +12 -0
  547. package/dist/frontend/lowering/text-decoder-encoding.js +82 -0
  548. package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -0
  549. package/dist/frontend/lowering/text-decoder-encoding.test.d.ts +1 -0
  550. package/dist/frontend/lowering/text-decoder-encoding.test.js +38 -0
  551. package/dist/frontend/lowering/text-decoder-encoding.test.js.map +1 -0
  552. package/dist/frontend/lowering/union-narrow.d.ts +9 -0
  553. package/dist/frontend/lowering/union-narrow.js +59 -0
  554. package/dist/frontend/lowering/union-narrow.js.map +1 -0
  555. package/dist/frontend/lowering/union-narrow.test.d.ts +1 -0
  556. package/dist/frontend/lowering/union-narrow.test.js +72 -0
  557. package/dist/frontend/lowering/union-narrow.test.js.map +1 -0
  558. package/dist/frontend/lowering/union-retag.d.ts +43 -0
  559. package/dist/frontend/lowering/union-retag.js +259 -0
  560. package/dist/frontend/lowering/union-retag.js.map +1 -0
  561. package/dist/frontend/lowering/union-retag.test.d.ts +1 -0
  562. package/dist/frontend/lowering/union-retag.test.js +405 -0
  563. package/dist/frontend/lowering/union-retag.test.js.map +1 -0
  564. package/dist/frontend/lowering/unregistered-class-types.d.ts +14 -0
  565. package/dist/frontend/lowering/unregistered-class-types.js +94 -0
  566. package/dist/frontend/lowering/unregistered-class-types.js.map +1 -0
  567. package/dist/frontend/lowering/unregistered-class-types.test.d.ts +1 -0
  568. package/dist/frontend/lowering/unregistered-class-types.test.js +65 -0
  569. package/dist/frontend/lowering/unregistered-class-types.test.js.map +1 -0
  570. package/dist/frontend/lowering/width-lift.d.ts +40 -0
  571. package/dist/frontend/lowering/width-lift.js +2 -0
  572. package/dist/frontend/lowering/width-lift.js.map +1 -0
  573. package/dist/frontend/module-syntax.d.ts +58 -0
  574. package/dist/frontend/module-syntax.js +123 -0
  575. package/dist/frontend/module-syntax.js.map +1 -0
  576. package/dist/frontend/module-syntax.test.d.ts +1 -0
  577. package/dist/frontend/module-syntax.test.js +78 -0
  578. package/dist/frontend/module-syntax.test.js.map +1 -0
  579. package/dist/frontend/npm-fetch-analysis.d.ts +17 -0
  580. package/dist/frontend/npm-fetch-analysis.js +100 -0
  581. package/dist/frontend/npm-fetch-analysis.js.map +1 -0
  582. package/dist/frontend/npm-fetch-analysis.test.d.ts +1 -0
  583. package/dist/frontend/npm-fetch-analysis.test.js +107 -0
  584. package/dist/frontend/npm-fetch-analysis.test.js.map +1 -0
  585. package/dist/frontend/npm-fetch-node.d.ts +2 -0
  586. package/dist/frontend/npm-fetch-node.js +12 -0
  587. package/dist/frontend/npm-fetch-node.js.map +1 -0
  588. package/dist/frontend/npm-fetch-syntax.d.ts +6 -0
  589. package/dist/frontend/npm-fetch-syntax.js +207 -0
  590. package/dist/frontend/npm-fetch-syntax.js.map +1 -0
  591. package/dist/frontend/npm-node.d.ts +10 -0
  592. package/dist/frontend/npm-node.js +14 -0
  593. package/dist/frontend/npm-node.js.map +1 -0
  594. package/dist/frontend/npm-static-bundled-cjs.d.ts +8 -0
  595. package/dist/frontend/npm-static-bundled-cjs.js +236 -0
  596. package/dist/frontend/npm-static-bundled-cjs.js.map +1 -0
  597. package/dist/frontend/npm-static-bundled-cjs.test.d.ts +1 -0
  598. package/dist/frontend/npm-static-bundled-cjs.test.js +69 -0
  599. package/dist/frontend/npm-static-bundled-cjs.test.js.map +1 -0
  600. package/dist/frontend/npm-static-declaration-syntax.d.ts +57 -0
  601. package/dist/frontend/npm-static-declaration-syntax.js +944 -0
  602. package/dist/frontend/npm-static-declaration-syntax.js.map +1 -0
  603. package/dist/frontend/npm-static-declarations.d.ts +11 -39
  604. package/dist/frontend/npm-static-declarations.js +22 -561
  605. package/dist/frontend/npm-static-declarations.js.map +1 -1
  606. package/dist/frontend/npm-static-declarations.test.js +245 -6
  607. package/dist/frontend/npm-static-declarations.test.js.map +1 -1
  608. package/dist/frontend/npm-static-prune.d.ts +1 -1
  609. package/dist/frontend/npm-static-prune.js +121 -38
  610. package/dist/frontend/npm-static-prune.js.map +1 -1
  611. package/dist/frontend/npm-static-prune.test.js +9 -1
  612. package/dist/frontend/npm-static-prune.test.js.map +1 -1
  613. package/dist/frontend/npm-static-rewrite-host.d.ts +4 -0
  614. package/dist/frontend/npm-static-rewrite-host.js +179 -0
  615. package/dist/frontend/npm-static-rewrite-host.js.map +1 -0
  616. package/dist/frontend/npm-static-rewrite-syntax.d.ts +16 -0
  617. package/dist/frontend/npm-static-rewrite-syntax.js +905 -0
  618. package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -0
  619. package/dist/frontend/npm-static-rewrite.d.ts +0 -5
  620. package/dist/frontend/npm-static-rewrite.js +2 -1079
  621. package/dist/frontend/npm-static-rewrite.js.map +1 -1
  622. package/dist/frontend/npm-static-subtyping.d.ts +5 -0
  623. package/dist/frontend/npm-static-subtyping.js +55 -0
  624. package/dist/frontend/npm-static-subtyping.js.map +1 -0
  625. package/dist/frontend/npm-static-subtyping.test.d.ts +1 -0
  626. package/dist/frontend/npm-static-subtyping.test.js +58 -0
  627. package/dist/frontend/npm-static-subtyping.test.js.map +1 -0
  628. package/dist/frontend/npm-static.d.ts +7 -15
  629. package/dist/frontend/npm-static.js +19 -28
  630. package/dist/frontend/npm-static.js.map +1 -1
  631. package/dist/frontend/npm.d.ts +8 -69
  632. package/dist/frontend/npm.js +21 -361
  633. package/dist/frontend/npm.js.map +1 -1
  634. package/dist/frontend/npm.test.js +2 -2
  635. package/dist/frontend/npm.test.js.map +1 -1
  636. package/dist/frontend/pipeline-native.d.ts +6 -0
  637. package/dist/frontend/pipeline-native.js +32 -0
  638. package/dist/frontend/pipeline-native.js.map +1 -0
  639. package/dist/frontend/pipeline.d.ts +54 -0
  640. package/dist/frontend/pipeline.js +382 -0
  641. package/dist/frontend/pipeline.js.map +1 -0
  642. package/dist/frontend/pipeline.test.d.ts +1 -0
  643. package/dist/frontend/pipeline.test.js +77 -0
  644. package/dist/frontend/pipeline.test.js.map +1 -0
  645. package/dist/frontend/program-analysis.d.ts +10 -0
  646. package/dist/frontend/program-analysis.js +14 -0
  647. package/dist/frontend/program-analysis.js.map +1 -0
  648. package/dist/frontend/program-node.d.ts +9 -0
  649. package/dist/frontend/program-node.js +48 -0
  650. package/dist/frontend/program-node.js.map +1 -0
  651. package/dist/frontend/program.d.ts +39 -20
  652. package/dist/frontend/program.js +393 -189
  653. package/dist/frontend/program.js.map +1 -1
  654. package/dist/frontend/program.test.js +105 -2
  655. package/dist/frontend/program.test.js.map +1 -1
  656. package/dist/frontend/provenance-core.d.ts +9 -0
  657. package/dist/frontend/provenance-core.js +435 -0
  658. package/dist/frontend/provenance-core.js.map +1 -0
  659. package/dist/frontend/provenance.d.ts +0 -4
  660. package/dist/frontend/provenance.js +4 -459
  661. package/dist/frontend/provenance.js.map +1 -1
  662. package/dist/frontend/resolve.d.ts +3 -1
  663. package/dist/frontend/resolve.js +6 -3
  664. package/dist/frontend/resolve.js.map +1 -1
  665. package/dist/frontend/runtime-resolve.d.ts +4 -3
  666. package/dist/frontend/runtime-resolve.js +22 -18
  667. package/dist/frontend/runtime-resolve.js.map +1 -1
  668. package/dist/frontend/runtime-resolve.test.js +53 -0
  669. package/dist/frontend/runtime-resolve.test.js.map +1 -1
  670. package/dist/frontend/services-node.d.ts +5 -0
  671. package/dist/frontend/services-node.js +19 -0
  672. package/dist/frontend/services-node.js.map +1 -0
  673. package/dist/frontend/services-node.test.d.ts +1 -0
  674. package/dist/frontend/services-node.test.js +70 -0
  675. package/dist/frontend/services-node.test.js.map +1 -0
  676. package/dist/frontend/services.d.ts +44 -0
  677. package/dist/frontend/services.js +90 -0
  678. package/dist/frontend/services.js.map +1 -0
  679. package/dist/frontend/services.test.d.ts +1 -0
  680. package/dist/frontend/services.test.js +174 -0
  681. package/dist/frontend/services.test.js.map +1 -0
  682. package/dist/frontend/ts7/adapter.d.ts +3 -3
  683. package/dist/frontend/ts7/adapter.js +14 -31
  684. package/dist/frontend/ts7/adapter.js.map +1 -1
  685. package/dist/frontend/ts7/api.d.ts +16 -0
  686. package/dist/frontend/ts7/api.js +24 -0
  687. package/dist/frontend/ts7/api.js.map +1 -0
  688. package/dist/frontend/ts7/ast-bytes.d.ts +31 -0
  689. package/dist/frontend/ts7/ast-bytes.js +137 -0
  690. package/dist/frontend/ts7/ast-bytes.js.map +1 -0
  691. package/dist/frontend/ts7/ast-bytes.test.d.ts +1 -0
  692. package/dist/frontend/ts7/ast-bytes.test.js +73 -0
  693. package/dist/frontend/ts7/ast-bytes.test.js.map +1 -0
  694. package/dist/frontend/ts7/ast-guards.generated.d.ts +353 -0
  695. package/dist/frontend/ts7/ast-guards.generated.js +1951 -0
  696. package/dist/frontend/ts7/ast-guards.generated.js.map +1 -0
  697. package/dist/frontend/ts7/ast-guards.test.d.ts +1 -0
  698. package/dist/frontend/ts7/ast-guards.test.js +43 -0
  699. package/dist/frontend/ts7/ast-guards.test.js.map +1 -0
  700. package/dist/frontend/ts7/ast-node.d.ts +194 -0
  701. package/dist/frontend/ts7/ast-node.js +448 -0
  702. package/dist/frontend/ts7/ast-node.js.map +1 -0
  703. package/dist/frontend/ts7/ast-node.test.d.ts +1 -0
  704. package/dist/frontend/ts7/ast-node.test.js +266 -0
  705. package/dist/frontend/ts7/ast-node.test.js.map +1 -0
  706. package/dist/frontend/ts7/ast-schema.generated.d.ts +503 -0
  707. package/dist/frontend/ts7/ast-schema.generated.js +1446 -0
  708. package/dist/frontend/ts7/ast-schema.generated.js.map +1 -0
  709. package/dist/frontend/ts7/ast-text.d.ts +6 -0
  710. package/dist/frontend/ts7/ast-text.js +124 -0
  711. package/dist/frontend/ts7/ast-text.js.map +1 -0
  712. package/dist/frontend/ts7/ast-text.test.d.ts +1 -0
  713. package/dist/frontend/ts7/ast-text.test.js +38 -0
  714. package/dist/frontend/ts7/ast-text.test.js.map +1 -0
  715. package/dist/frontend/ts7/ast-tokens.generated.d.ts +2 -0
  716. package/dist/frontend/ts7/ast-tokens.generated.js +155 -0
  717. package/dist/frontend/ts7/ast-tokens.generated.js.map +1 -0
  718. package/dist/frontend/ts7/ast-types.d.ts +42 -0
  719. package/dist/frontend/ts7/ast-types.generated.d.ts +1615 -0
  720. package/dist/frontend/ts7/ast-types.generated.js +5 -0
  721. package/dist/frontend/ts7/ast-types.generated.js.map +1 -0
  722. package/dist/frontend/ts7/ast-types.js +3 -0
  723. package/dist/frontend/ts7/ast-types.js.map +1 -0
  724. package/dist/frontend/ts7/ast-wire.d.ts +58 -0
  725. package/dist/frontend/ts7/ast-wire.js +267 -0
  726. package/dist/frontend/ts7/ast-wire.js.map +1 -0
  727. package/dist/frontend/ts7/ast-wire.test.d.ts +1 -0
  728. package/dist/frontend/ts7/ast-wire.test.js +151 -0
  729. package/dist/frontend/ts7/ast-wire.test.js.map +1 -0
  730. package/dist/frontend/ts7/ast.d.ts +14 -14
  731. package/dist/frontend/ts7/ast.js +25 -18
  732. package/dist/frontend/ts7/ast.js.map +1 -1
  733. package/dist/frontend/ts7/census-check.js +1 -0
  734. package/dist/frontend/ts7/census-check.js.map +1 -1
  735. package/dist/frontend/ts7/checker-cache.d.ts +48 -0
  736. package/dist/frontend/ts7/checker-cache.js +92 -0
  737. package/dist/frontend/ts7/checker-cache.js.map +1 -0
  738. package/dist/frontend/ts7/checker.d.ts +19 -46
  739. package/dist/frontend/ts7/checker.js +231 -161
  740. package/dist/frontend/ts7/checker.js.map +1 -1
  741. package/dist/frontend/ts7/checker.test.d.ts +1 -0
  742. package/dist/frontend/ts7/checker.test.js +335 -0
  743. package/dist/frontend/ts7/checker.test.js.map +1 -0
  744. package/dist/frontend/ts7/enums.d.ts +4 -27
  745. package/dist/frontend/ts7/enums.generated.d.ts +878 -0
  746. package/dist/frontend/ts7/enums.generated.js +1313 -0
  747. package/dist/frontend/ts7/enums.generated.js.map +1 -0
  748. package/dist/frontend/ts7/enums.js +4 -45
  749. package/dist/frontend/ts7/enums.js.map +1 -1
  750. package/dist/frontend/ts7/enums.test.d.ts +1 -0
  751. package/dist/frontend/ts7/enums.test.js +48 -0
  752. package/dist/frontend/ts7/enums.test.js.map +1 -0
  753. package/dist/frontend/ts7/native-api.d.ts +10 -0
  754. package/dist/frontend/ts7/native-api.js +10 -0
  755. package/dist/frontend/ts7/native-api.js.map +1 -0
  756. package/dist/frontend/ts7/native-host.d.ts +2 -0
  757. package/dist/frontend/ts7/native-host.js +11 -0
  758. package/dist/frontend/ts7/native-host.js.map +1 -0
  759. package/dist/frontend/ts7/native-process.d.ts +14 -0
  760. package/dist/frontend/ts7/native-process.js +62 -0
  761. package/dist/frontend/ts7/native-process.js.map +1 -0
  762. package/dist/frontend/ts7/program-adapter.d.ts +10 -98
  763. package/dist/frontend/ts7/program-adapter.js +16 -310
  764. package/dist/frontend/ts7/program-adapter.js.map +1 -1
  765. package/dist/frontend/ts7/program-host.d.ts +115 -0
  766. package/dist/frontend/ts7/program-host.js +347 -0
  767. package/dist/frontend/ts7/program-host.js.map +1 -0
  768. package/dist/frontend/ts7/program-host.test.d.ts +1 -0
  769. package/dist/frontend/ts7/program-host.test.js +207 -0
  770. package/dist/frontend/ts7/program-host.test.js.map +1 -0
  771. package/dist/frontend/ts7/rpc-api.d.ts +12 -0
  772. package/dist/frontend/ts7/rpc-api.js +23 -0
  773. package/dist/frontend/ts7/rpc-api.js.map +1 -0
  774. package/dist/frontend/ts7/rpc-client.d.ts +27 -0
  775. package/dist/frontend/ts7/rpc-client.js +102 -0
  776. package/dist/frontend/ts7/rpc-client.js.map +1 -0
  777. package/dist/frontend/ts7/rpc-client.test.d.ts +1 -0
  778. package/dist/frontend/ts7/rpc-client.test.js +133 -0
  779. package/dist/frontend/ts7/rpc-client.test.js.map +1 -0
  780. package/dist/frontend/ts7/rpc-filesystem.d.ts +16 -0
  781. package/dist/frontend/ts7/rpc-filesystem.js +42 -0
  782. package/dist/frontend/ts7/rpc-filesystem.js.map +1 -0
  783. package/dist/frontend/ts7/rpc-filesystem.test.d.ts +1 -0
  784. package/dist/frontend/ts7/rpc-filesystem.test.js +89 -0
  785. package/dist/frontend/ts7/rpc-filesystem.test.js.map +1 -0
  786. package/dist/frontend/ts7/rpc-process.d.ts +2 -0
  787. package/dist/frontend/ts7/rpc-process.js +148 -0
  788. package/dist/frontend/ts7/rpc-process.js.map +1 -0
  789. package/dist/frontend/ts7/rpc-process.test.d.ts +1 -0
  790. package/dist/frontend/ts7/rpc-process.test.js +29 -0
  791. package/dist/frontend/ts7/rpc-process.test.js.map +1 -0
  792. package/dist/frontend/ts7/rpc-wire.d.ts +46 -0
  793. package/dist/frontend/ts7/rpc-wire.js +195 -0
  794. package/dist/frontend/ts7/rpc-wire.js.map +1 -0
  795. package/dist/frontend/ts7/rpc-wire.test.d.ts +1 -0
  796. package/dist/frontend/ts7/rpc-wire.test.js +168 -0
  797. package/dist/frontend/ts7/rpc-wire.test.js.map +1 -0
  798. package/dist/frontend/ts7/semantic-checker.d.ts +137 -0
  799. package/dist/frontend/ts7/semantic-checker.js +221 -0
  800. package/dist/frontend/ts7/semantic-checker.js.map +1 -0
  801. package/dist/frontend/ts7/semantic-checker.test.d.ts +1 -0
  802. package/dist/frontend/ts7/semantic-checker.test.js +119 -0
  803. package/dist/frontend/ts7/semantic-checker.test.js.map +1 -0
  804. package/dist/frontend/ts7/semantic-json.d.ts +5 -0
  805. package/dist/frontend/ts7/semantic-json.js +47 -0
  806. package/dist/frontend/ts7/semantic-json.js.map +1 -0
  807. package/dist/frontend/ts7/semantic-json.test.d.ts +1 -0
  808. package/dist/frontend/ts7/semantic-json.test.js +42 -0
  809. package/dist/frontend/ts7/semantic-json.test.js.map +1 -0
  810. package/dist/frontend/ts7/semantic-model.d.ts +222 -0
  811. package/dist/frontend/ts7/semantic-model.js +423 -0
  812. package/dist/frontend/ts7/semantic-model.js.map +1 -0
  813. package/dist/frontend/ts7/semantic-model.test.d.ts +1 -0
  814. package/dist/frontend/ts7/semantic-model.test.js +322 -0
  815. package/dist/frontend/ts7/semantic-model.test.js.map +1 -0
  816. package/dist/frontend/ts7/semantic-schema.generated.d.ts +283 -0
  817. package/dist/frontend/ts7/semantic-schema.generated.js +222 -0
  818. package/dist/frontend/ts7/semantic-schema.generated.js.map +1 -0
  819. package/dist/frontend/ts7/semantic-types.d.ts +5 -0
  820. package/dist/frontend/ts7/semantic-types.js +2 -0
  821. package/dist/frontend/ts7/semantic-types.js.map +1 -0
  822. package/dist/frontend/ts7/session-cache.d.ts +17 -0
  823. package/dist/frontend/ts7/session-cache.js +97 -0
  824. package/dist/frontend/ts7/session-cache.js.map +1 -0
  825. package/dist/frontend/ts7/session-cache.test.d.ts +1 -0
  826. package/dist/frontend/ts7/session-cache.test.js +87 -0
  827. package/dist/frontend/ts7/session-cache.test.js.map +1 -0
  828. package/dist/frontend/ts7/session-path.d.ts +18 -0
  829. package/dist/frontend/ts7/session-path.js +203 -0
  830. package/dist/frontend/ts7/session-path.js.map +1 -0
  831. package/dist/frontend/ts7/session-path.test.d.ts +1 -0
  832. package/dist/frontend/ts7/session-path.test.js +34 -0
  833. package/dist/frontend/ts7/session-path.test.js.map +1 -0
  834. package/dist/frontend/ts7/session-schema.generated.d.ts +167 -0
  835. package/dist/frontend/ts7/session-schema.generated.js +5 -0
  836. package/dist/frontend/ts7/session-schema.generated.js.map +1 -0
  837. package/dist/frontend/ts7/session-timing.d.ts +50 -0
  838. package/dist/frontend/ts7/session-timing.js +61 -0
  839. package/dist/frontend/ts7/session-timing.js.map +1 -0
  840. package/dist/frontend/ts7/session-timing.test.d.ts +1 -0
  841. package/dist/frontend/ts7/session-timing.test.js +52 -0
  842. package/dist/frontend/ts7/session-timing.test.js.map +1 -0
  843. package/dist/frontend/ts7/session.d.ts +105 -0
  844. package/dist/frontend/ts7/session.js +233 -0
  845. package/dist/frontend/ts7/session.js.map +1 -0
  846. package/dist/frontend/ts7/session.test.d.ts +1 -0
  847. package/dist/frontend/ts7/session.test.js +215 -0
  848. package/dist/frontend/ts7/session.test.js.map +1 -0
  849. package/dist/frontend/ts7/source-parser-node.d.ts +6 -0
  850. package/dist/frontend/ts7/source-parser-node.js +15 -0
  851. package/dist/frontend/ts7/source-parser-node.js.map +1 -0
  852. package/dist/frontend/ts7/source-parser.d.ts +25 -0
  853. package/dist/frontend/ts7/source-parser.js +96 -0
  854. package/dist/frontend/ts7/source-parser.js.map +1 -0
  855. package/dist/frontend/ts7/source-parser.test.d.ts +1 -0
  856. package/dist/frontend/ts7/source-parser.test.js +151 -0
  857. package/dist/frontend/ts7/source-parser.test.js.map +1 -0
  858. package/dist/frontend/ts7/syntax.d.ts +3 -0
  859. package/dist/frontend/ts7/syntax.js +4 -0
  860. package/dist/frontend/ts7/syntax.js.map +1 -0
  861. package/dist/frontend/tsc-codes.js +3 -0
  862. package/dist/frontend/tsc-codes.js.map +1 -1
  863. package/dist/frontend/type-mapper.d.ts +34 -18
  864. package/dist/frontend/type-mapper.js +552 -131
  865. package/dist/frontend/type-mapper.js.map +1 -1
  866. package/dist/frontend/type-mapper.test.js +146 -2
  867. package/dist/frontend/type-mapper.test.js.map +1 -1
  868. package/dist/frontend/union-discriminants.d.ts +16 -0
  869. package/dist/frontend/union-discriminants.js +98 -0
  870. package/dist/frontend/union-discriminants.js.map +1 -0
  871. package/dist/frontend/union-discriminants.test.d.ts +1 -0
  872. package/dist/frontend/union-discriminants.test.js +182 -0
  873. package/dist/frontend/union-discriminants.test.js.map +1 -0
  874. package/dist/index.d.ts +7 -198
  875. package/dist/index.js +369 -1572
  876. package/dist/index.js.map +1 -1
  877. package/dist/ir/analysis.d.ts +16 -4
  878. package/dist/ir/analysis.js +23 -4
  879. package/dist/ir/analysis.js.map +1 -1
  880. package/dist/ir/analysis.test.js +15 -2
  881. package/dist/ir/analysis.test.js.map +1 -1
  882. package/dist/ir/constant-tables.js +67 -49
  883. package/dist/ir/constant-tables.js.map +1 -1
  884. package/dist/ir/constant-tables.test.js +1 -1
  885. package/dist/ir/control-flow.d.ts +6 -0
  886. package/dist/ir/control-flow.js +142 -0
  887. package/dist/ir/control-flow.js.map +1 -0
  888. package/dist/ir/control-flow.test.d.ts +1 -0
  889. package/dist/ir/control-flow.test.js +113 -0
  890. package/dist/ir/control-flow.test.js.map +1 -0
  891. package/dist/ir/integer-loops.js +7 -18
  892. package/dist/ir/integer-loops.js.map +1 -1
  893. package/dist/ir/integer-ranges.js +53 -27
  894. package/dist/ir/integer-ranges.js.map +1 -1
  895. package/dist/ir/ir.d.ts +334 -176
  896. package/dist/ir/ir.js +710 -903
  897. package/dist/ir/ir.js.map +1 -1
  898. package/dist/ir/ir.test.js +162 -1
  899. package/dist/ir/ir.test.js.map +1 -1
  900. package/dist/ir/scalar-records.js +165 -134
  901. package/dist/ir/scalar-records.js.map +1 -1
  902. package/dist/ir/scalar-records.test.js +1 -1
  903. package/dist/ir/serialize.d.ts +4 -2
  904. package/dist/ir/serialize.js +33 -14
  905. package/dist/ir/serialize.js.map +1 -1
  906. package/dist/ir/serialize.test.d.ts +1 -0
  907. package/dist/ir/serialize.test.js +57 -0
  908. package/dist/ir/serialize.test.js.map +1 -0
  909. package/dist/ir/traverse.d.ts +41 -0
  910. package/dist/ir/traverse.js +660 -0
  911. package/dist/ir/traverse.js.map +1 -0
  912. package/dist/ir/traverse.test.d.ts +1 -0
  913. package/dist/ir/traverse.test.js +242 -0
  914. package/dist/ir/traverse.test.js.map +1 -0
  915. package/dist/ir/validate.js +2018 -1498
  916. package/dist/ir/validate.js.map +1 -1
  917. package/dist/ir/validate.test.js +536 -2
  918. package/dist/ir/validate.test.js.map +1 -1
  919. package/dist/library/cache-primitives.d.ts +2 -3
  920. package/dist/library/cache-primitives.js +4 -6
  921. package/dist/library/cache-primitives.js.map +1 -1
  922. package/dist/library/fence-eval.js +2 -2
  923. package/dist/library/fence-eval.js.map +1 -1
  924. package/dist/library/int-infer.js +7 -6
  925. package/dist/library/int-infer.js.map +1 -1
  926. package/dist/library/int-infer.test.js +4 -4
  927. package/dist/library/library-cache.d.ts +3 -2
  928. package/dist/library/library-cache.js +5 -17
  929. package/dist/library/library-cache.js.map +1 -1
  930. package/dist/library/library-cache.test.js +54 -41
  931. package/dist/library/library-cache.test.js.map +1 -1
  932. package/dist/library/library-profile.d.ts +3 -1
  933. package/dist/library/library-profile.js +15 -6
  934. package/dist/library/library-profile.js.map +1 -1
  935. package/dist/library/prepare.d.ts +15 -0
  936. package/dist/library/prepare.js +584 -0
  937. package/dist/library/prepare.js.map +1 -0
  938. package/dist/library/semantic-source.d.ts +1 -1
  939. package/dist/library/semantic-source.js +8 -6
  940. package/dist/library/semantic-source.js.map +1 -1
  941. package/dist/library/sidecar-validate.js +4 -4
  942. package/dist/library/sidecar-validate.js.map +1 -1
  943. package/dist/library/sidecar.d.ts +2 -0
  944. package/dist/library/sidecar.js +10 -3
  945. package/dist/library/sidecar.js.map +1 -1
  946. package/dist/native/cache.d.ts +11 -0
  947. package/dist/native/cache.js +113 -0
  948. package/dist/native/cache.js.map +1 -0
  949. package/dist/native/cache.test.d.ts +1 -0
  950. package/dist/native/cache.test.js +66 -0
  951. package/dist/native/cache.test.js.map +1 -0
  952. package/dist/native/cli.d.ts +1 -0
  953. package/dist/native/cli.js +112 -0
  954. package/dist/native/cli.js.map +1 -0
  955. package/dist/native/compiler.d.ts +15 -0
  956. package/dist/native/compiler.js +336 -0
  957. package/dist/native/compiler.js.map +1 -0
  958. package/dist/native/compiler.test.d.ts +1 -0
  959. package/dist/native/compiler.test.js +174 -0
  960. package/dist/native/compiler.test.js.map +1 -0
  961. package/dist/native/comptime.d.ts +5 -0
  962. package/dist/native/comptime.js +73 -0
  963. package/dist/native/comptime.js.map +1 -0
  964. package/dist/native/comptime.test.d.ts +1 -0
  965. package/dist/native/comptime.test.js +65 -0
  966. package/dist/native/comptime.test.js.map +1 -0
  967. package/dist/native/executable-cache.d.ts +26 -0
  968. package/dist/native/executable-cache.js +228 -0
  969. package/dist/native/executable-cache.js.map +1 -0
  970. package/dist/native/executable-cache.test.d.ts +1 -0
  971. package/dist/native/executable-cache.test.js +151 -0
  972. package/dist/native/executable-cache.test.js.map +1 -0
  973. package/dist/native/file-identity.d.ts +4 -0
  974. package/dist/native/file-identity.js +14 -0
  975. package/dist/native/file-identity.js.map +1 -0
  976. package/dist/native/file-identity.test.d.ts +1 -0
  977. package/dist/native/file-identity.test.js +43 -0
  978. package/dist/native/file-identity.test.js.map +1 -0
  979. package/dist/native/library.d.ts +22 -0
  980. package/dist/native/library.js +83 -0
  981. package/dist/native/library.js.map +1 -0
  982. package/dist/native/prepare.d.ts +21 -0
  983. package/dist/native/prepare.js +174 -0
  984. package/dist/native/prepare.js.map +1 -0
  985. package/dist/native/prepare.test.d.ts +1 -0
  986. package/dist/native/prepare.test.js +70 -0
  987. package/dist/native/prepare.test.js.map +1 -0
  988. package/dist/native/sanitizer.d.ts +11 -0
  989. package/dist/native/sanitizer.js +137 -0
  990. package/dist/native/sanitizer.js.map +1 -0
  991. package/dist/native/sanitizer.test.d.ts +1 -0
  992. package/dist/native/sanitizer.test.js +58 -0
  993. package/dist/native/sanitizer.test.js.map +1 -0
  994. package/dist/native/task.d.ts +4 -0
  995. package/dist/native/task.js +16 -0
  996. package/dist/native/task.js.map +1 -0
  997. package/dist/native/task.test.d.ts +1 -0
  998. package/dist/native/task.test.js +17 -0
  999. package/dist/native/task.test.js.map +1 -0
  1000. package/dist/native/toolchain.d.ts +45 -0
  1001. package/dist/native/toolchain.js +94 -0
  1002. package/dist/native/toolchain.js.map +1 -0
  1003. package/dist/native/toolchain.test.d.ts +1 -0
  1004. package/dist/native/toolchain.test.js +85 -0
  1005. package/dist/native/toolchain.test.js.map +1 -0
  1006. package/dist/startup-cache.d.ts +1 -1
  1007. package/dist/startup-cache.js +2 -5
  1008. package/dist/startup-cache.js.map +1 -1
  1009. package/dist/timing.d.ts +4 -0
  1010. package/dist/timing.js +19 -0
  1011. package/dist/timing.js.map +1 -0
  1012. package/dist/wasi-paths.js +10 -7
  1013. package/dist/wasi-paths.js.map +1 -1
  1014. package/package.json +28 -19
  1015. package/surface-manifest.json +107 -98
  1016. package/dist/backend/c/async.d.ts +0 -171
  1017. package/dist/backend/c/async.js +0 -1317
  1018. package/dist/backend/c/async.js.map +0 -1
  1019. package/dist/backend/c/c-emitter.d.ts +0 -536
  1020. package/dist/backend/c/c-emitter.js +0 -1932
  1021. package/dist/backend/c/c-emitter.js.map +0 -1
  1022. package/dist/backend/c/exprs.d.ts +0 -15
  1023. package/dist/backend/c/exprs.js +0 -8847
  1024. package/dist/backend/c/exprs.js.map +0 -1
  1025. package/dist/backend/c/island.d.ts +0 -45
  1026. package/dist/backend/c/island.js +0 -281
  1027. package/dist/backend/c/island.js.map +0 -1
  1028. package/dist/backend/c/may-throw.js.map +0 -1
  1029. package/dist/backend/c/shapes.d.ts +0 -142
  1030. package/dist/backend/c/shapes.js +0 -603
  1031. package/dist/backend/c/shapes.js.map +0 -1
  1032. package/dist/backend/c/stmts.d.ts +0 -76
  1033. package/dist/backend/c/stmts.js +0 -1108
  1034. package/dist/backend/c/stmts.js.map +0 -1
  1035. package/dist/backend/c/types.d.ts +0 -71
  1036. package/dist/backend/c/types.js +0 -459
  1037. package/dist/backend/c/types.js.map +0 -1
  1038. package/dist/backend/c/types.test.js +0 -32
  1039. package/dist/backend/c/types.test.js.map +0 -1
  1040. package/dist/backend/c/walkers.d.ts +0 -134
  1041. package/dist/backend/c/walkers.js +0 -1772
  1042. package/dist/backend/c/walkers.js.map +0 -1
  1043. /package/dist/backend/{c/types.test.d.ts → cycle-analysis.test.d.ts} +0 -0
@@ -1,81 +1,40 @@
1
+ import { emitLlvmLayouts } from "./layouts.js";
2
+ import { llvmBytes as llBytes } from "../literals.js";
1
3
  import { InternalCompilerError } from "../../errors.js";
2
- /* IR → LLVM IR text (.ll). The LLVM backend consumes the SAME in-memory
3
- * IrModule the C backend does (never the JSON dump — see the -0 lesson in
4
- * the survey). Its textual module is either lowered by scriptc's native
5
- * helper and linked with a runtime pack or occupies the legacy compiler
6
- * driver's program-TU seat. Both paths use the same scr_* C ABI.
4
+ /** Lower typed IR to LLVM, using the runtime's C ABI.
7
5
  *
8
- * Phase 1 was the TRIVIAL TIER: f64/bool/string locals and params, the
9
- * scalar operator set, structured control flow, direct calls, interned
10
- * string literals, and the console protocol. Phase 2 adds the VOLUME
11
- * TIER: module globals and locals of every in-tier ref kind (arrays,
12
- * record shapes, unions, function values/closures), the full array and
13
- * string intrinsic surfaces, per-record-shape RC helpers (cycle headers
14
- * included — the C emitter's fixpoint, ported in shapes.ts), tagged-union
15
- * construction/narrowing/equality with interned immortal unit instances,
16
- * capture boxes and the closure calling convention, switch/for-of
17
- * lowering, and the non-throwing slice of the libCall table. EVERYTHING
18
- * ELSE REFUSES loudly at the first unhandled node (LlvmUnsupportedError
19
- * naming the kind) — this backend never guesses and never emits wrong
20
- * code for a construct it does not model. compile() surfaces the refusal
21
- * as diagnostic SC3001.
6
+ * Reference-counted temporaries own one reference. Declarations, assignments,
7
+ * returns and arguments move that ownership; frame and scope exits release
8
+ * everything remaining. Slot-backed entries release the slot's current value.
22
9
  *
23
- * RC ownership discipline: the frame/scope release-point machinery is
24
- * ported from CEmitter (docs/ir.md) — every refcounted temp holds an owned
25
- * +1 reference; varDecl/assign/return/call-argument MOVE that ownership;
26
- * each statement releases its remaining refcounted temps when it ends;
27
- * each scope releases the refcounted locals declared in it when it exits;
28
- * callees own their params; return/break/continue release everything the
29
- * jump bypasses (releaseForJump). Releases are type-directed through
30
- * shapes.ts (the releaseCallC table's LLVM twin); frame entries can be
31
- * SLOT-based (the entry names a pointer whose CURRENT value releases —
32
- * conditional results like optional chains need that indirection).
10
+ * Exceptions use a pending flag and explicit cleanup edges. Throwing calls
11
+ * test scr_exc_pending before consuming results, release the scopes crossed,
12
+ * and branch to the innermost handler or return to the caller. Catch bindings
13
+ * hold ScrCaught snapshots; finally runs on normal, throwing and returning
14
+ * paths. This keeps ownership cleanup intact without nonlocal jumps.
33
15
  *
34
- * Exceptions (phase 4): the pending-flag unwind protocol, ported from the
35
- * C emitter. `throw` moves its payload into the runtime's exception cell
36
- * (scr_throw_*) and unwinds; after every call that can raise (per the
37
- * SAME computeMayThrow analysis the C backend runs) a pending check tests
38
- * scr_exc_pending() and unwinds — releasing frames/scopes down to the
39
- * innermost try handler's depths and branching to its label, or releasing
40
- * everything and returning a dummy value (never read: callers of a
41
- * may-throw function test the flag before using the result). No
42
- * setjmp/longjmp: longjmp would skip the emitted RC releases. try/catch
43
- * follows stmts.ts's shape exactly — a compile-time tryStack entry
44
- * per region, the catch block taking the exception (scr_exc_take into the
45
- * binding's snapshot box, or scr_exc_clear for the bindingless form), the
46
- * finally body emitted once per path (normal, exception-with-stash,
47
- * pending-return) with fresh temps each time. Catch bindings ride
48
- * ScrCaught snapshot boxes (caughtTest/caughtNarrow/caughtCheck read
49
- * them); TDZ reads test the box's payload slot and throw Node's
50
- * ReferenceError. main() gains the uncaught epilogue when the entry
51
- * function may throw.
52
- *
53
- * The dyn surface (phase 5): ScrDyn dyn values are in the tier — dyn.ts
54
- * ports walkers.ts's dyn slice (match/check/toDyn walkers, the
55
- * String(unknown)/caught→dyn/keyed-read singletons, the checked-dynamic
56
- * function boundary's thunk/box/adapter triple) and the emitter lowers
57
- * the dyn expression kinds (dynFrom/dynCall/dynInvoke/dynTest/dynKeyGet/
58
- * dynCheck/destructuring), the JSON.parse family, dyn record fields and
59
- * overflow maps, dyn capture boxes, and generator unknown channels.
60
- * The island surface (jsval/jsExit and embedded npm tables) is in the
61
- * tier too; the module text and resolution tables use the same compressed,
62
- * lazy-inflate representation as the C debugging backend.
16
+ * Program objects are emitted by the packaged LLVM helper and linked with
17
+ * runtime packs. Sanitizer development builds use an external LLVM driver.
18
+ * Dynamic values and islands share the runtime ABI; embedded npm modules use
19
+ * compressed source tables that the runtime inflates on demand.
63
20
  */
64
21
  import { deflateRawSync } from "node:zlib";
65
22
  import { endsWithJump, matchStringSelfConcat, streamTypedRefEligible } from "../../ir/analysis.js";
66
23
  import { emitLibraryIdentityLines } from "../library-identity-markers.js";
67
- import { CAUGHT, ffiCallbackType, isDynTypedRefType, isFfiContextParam, isRefCounted, isUnitType, moduleEmbedsBuiltin, moduleEmbedsCompressedNpm, moduleUsesChildProcess, moduleUsesDynInvoke, moduleUsesFetch, moduleUsesFsWatch, moduleUsesHttpServer, moduleUsesNet, moduleUsesNodeTest, moduleUsesProcessEvents, moduleUsesStream, moduleUsesTls, moduleUsesTlsCa, NPM_COMPRESS_MIN, POINTER_KINDS, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, typeKey, VOID } from "../../ir/ir.js";
24
+ import { CAUGHT, ffiCallbackType, isDynTypedRefType, isFfiContextParam, isRefCounted, isUnitType, moduleRuntimeFeatures, moduleEmbedsBuiltin, moduleEmbedsCompressedNpm, NPM_COMPRESS_MIN, POINTER_KINDS, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, typeKey, VOID } from "../../ir/ir.js";
68
25
  import { matchIntegerBytesForLoop } from "../../ir/integer-loops.js";
69
26
  import { scalarizeNumericRecords } from "../../ir/scalar-records.js";
27
+ import { everyStmtList } from "../../ir/traverse.js";
70
28
  import { analyzeIntegerRanges } from "../../ir/integer-ranges.js";
71
29
  import { findConstantNumericTables } from "../../ir/constant-tables.js";
72
30
  import { allocateFfiCallbackAdapters, hasForeignFfiCallback, hasRetainedFfiCallback } from "../ffi-callbacks.js";
73
31
  import { RUNTIME_ABI_MARKER } from "../runtime-abi.js";
74
- import { computeMayThrow } from "../c/may-throw.js";
75
- import { mangleArgPack, mangleAsyncSpawn, mangleClassObj, mangleFnClosure, mangleFunction, mangleGenDrop, mangleGenSpawn, mangleGlobal, mangleLocal, mangleRecordStruct, mangleTrampoline, mangleWrapper } from "../mangle.js";
32
+ import { computeMayThrow } from "../may-throw.js";
33
+ import { mangleArgPack, mangleAsyncSpawn, mangleClassObj, mangleClassStruct, mangleFnClosure, mangleFunction, mangleGenDrop, mangleGenSpawn, mangleGlobal, mangleLocal, mangleRecordStruct, mangleTrampoline, mangleWrapper, mangleVtInstance } from "../mangle.js";
76
34
  import { BlockBuilder } from "./blocks.js";
77
35
  import { LlvmDebugInfo } from "./debug-info.js";
78
- import { f64Lit, ffiNativeTypeLl, llvmCommentText } from "./common.js";
36
+ import { f64Lit, ffiNativeTypeLl, ffiNativeParamLl, ffiNativeReturnLl, llvmCommentText } from "./common.js";
37
+ import { ffiExtendsNarrowIntegers } from "../targets.js";
79
38
  import { emitLiteralExpr, emitOperatorExpr, emitStringExpr, emitContainerExpr, emitRecordExpr } from "./expr-primitives.js";
80
39
  import { emitControlExpr } from "./expr-control.js";
81
40
  import { emitCallExpr } from "./expr-calls.js";
@@ -94,21 +53,32 @@ import { emitChildProcessLibCall, emitAsyncContextLibCall, emitProcessLibCall, e
94
53
  import { emitStreamLibCall } from "./lib-stream.js";
95
54
  import { emitNetworkHttpLibCall } from "./lib-network.js";
96
55
  import { emitAssertInspectLibCall, emitIoLibCall, emitGenericLibCall, emitLibCall } from "./lib-dispatch.js";
97
- import { buildClassGraph, classFieldIndex, classStructSym, emitClassObjDefs, emitClassShapes, } from "./classes.js";
56
+ import { buildClassGraph, classEnvironmentIndex, classFieldIndex, classStructSym, } from "./classes.js";
98
57
  import { LlDyn } from "./dyn.js";
99
58
  import { LlvmUnsupportedError } from "./unsupported.js";
100
59
  import { LlWalkers } from "./walkers.js";
101
- import { arrNewCall, boxAccess, boxNewCall, computeTraced, elemAccess, emitRecordShapes, FN_ATTRS, llFieldType, releaseSym, retainSym, traceArg, vAdapters, } from "./shapes.js";
60
+ import { arrNewCall, boxAccess, boxNewCall, computeTraced, elemAccess, FN_ATTRS, llFieldType, releaseSym, retainSym, traceArg, typedRefConstructor, vAdapters, } from "./shapes.js";
102
61
  export { LlvmUnsupportedError } from "./unsupported.js";
103
62
  function ffiCallbackDummyLl(callback) {
104
63
  switch (callback.returns) {
64
+ case "i64":
65
+ case "u64":
66
+ return "i64 0";
67
+ case "pointer":
68
+ return "ptr null";
105
69
  case "void":
106
70
  return "void";
107
71
  case "f64":
108
72
  return "double 0.0";
73
+ case "f32":
74
+ return "float 0.0";
109
75
  case "bool":
110
76
  case "u8":
77
+ case "i8":
111
78
  return "i8 0";
79
+ case "u16":
80
+ case "i16":
81
+ return "i16 0";
112
82
  case "u32":
113
83
  case "i32":
114
84
  return "i32 0";
@@ -118,39 +88,28 @@ export function emitLlvmModule(mod, options = {}) {
118
88
  // Keep source storage intact for debugger inspection in dev builds.
119
89
  return new LlEmitter(options.debugSources === undefined ? scalarizeNumericRecords(mod) : mod, options).emit();
120
90
  }
121
- /** LLVM c"..." payload for a UTF-8 literal, NUL-terminated like the C
122
- * emitter's flexible-array-member initializer. */
123
- function llBytes(bytes) {
124
- let s = "";
125
- for (const b of bytes) {
126
- s +=
127
- b >= 0x20 && b < 0x7f && b !== 0x22 && b !== 0x5c
128
- ? String.fromCharCode(b)
129
- : `\\${b.toString(16).padStart(2, "0").toUpperCase()}`;
130
- }
131
- return `${s}\\00`;
132
- }
133
91
  function llStrBytes(text) {
134
92
  return llBytes(Buffer.from(text, "utf8"));
135
93
  }
136
- class LlEmitter {
94
+ export class LlEmitter {
137
95
  mod;
138
96
  debug;
139
97
  debugScope = null;
140
98
  sizeType;
99
+ ffiExtendNarrowIntegers;
141
100
  cycleColorOffset;
142
101
  wasi;
143
102
  emitLibraryIdentity;
144
103
  runtimeAbiMarker;
145
104
  /** Interned string literals: UTF-8 text → { symbol, byte length } —
146
- * first-use order, the C emitter's determinism discipline. */
105
+ * first-use order, the runtime ABI’s determinism discipline. */
147
106
  literals = new Map();
148
107
  /** Interned unit-armed union instances: "unionId:tag" → symbol — one
149
- * immortal (rc == SIZE_MAX) static per (union, unit tag), exactly the
150
- * C emitter's table. RC entry points and the collector skip immortals. */
108
+ * immortal (rc == SIZE_MAX) static per (union, unit tag).
109
+ * RC entry points and the collector skip immortals. */
151
110
  unitInstances = new Map();
152
- /** Interned regex literals: "<flags>/<pattern>" → { symbol, interned
153
- * source/flags literal refs } — one immortal ScrRegex per distinct
111
+ /** Regex literal templates: "<flags>/<pattern>" → { symbol, interned
112
+ * source/flags literal refs } — one immortal ScrRegex template per distinct
154
113
  * (pattern, flags) pair; the bytecode slot starts null and the runtime
155
114
  * compiles it lazily on first use. The source/flags strings intern at
156
115
  * REGISTRATION (bodies emit before the literal table flushes). */
@@ -166,10 +125,12 @@ class LlEmitter {
166
125
  /** Type-directed walker functions (JSON serializers, the indent
167
126
  * rewriter, union ToString/join) — interned per typeKey/unionId, defs
168
127
  * flushed with the shape helpers. */
169
- walkers = new LlWalkers(this);
128
+ walkers;
170
129
  /** The dyn (ScrDyn dyn) helper registry — dyn.ts's interned ports of
171
130
  * walkers.ts's dyn slice. */
172
- dyn = new LlDyn(this);
131
+ dyn;
132
+ /** Explicit callback boundary for standalone layout and walker stages. */
133
+ shapeHost;
173
134
  /** External declarations, in first-use order. */
174
135
  decls = new Set();
175
136
  /** Declared functions referenced as values: each needs an env-signature
@@ -192,19 +153,20 @@ class LlEmitter {
192
153
  ffiHasRetainedCallback;
193
154
  ffiHasForeignCallback;
194
155
  globalTypes = new Map();
156
+ tdzGlobals = new Map();
195
157
  constantNumericTables;
196
- /** May-throw analysis (the C emitter's computeMayThrow, shared): pending
158
+ /** May-throw analysis (computeMayThrow): pending
197
159
  * checks are emitted only after calls that can actually raise. */
198
160
  mayThrow;
199
161
  indirectMayThrow;
200
162
  /** Method names with at least one may-throw implementation — the
201
- * virtualCall pending check's key (CEmitter.mayThrowMethods). */
163
+ * virtualCall pending check's key. */
202
164
  mayThrowMethods = new Set();
203
165
  /** setTimeout and friends appeared somewhere: main must run the event
204
- * loop even in programs with no async functions (CEmitter.usesTimers). */
166
+ * loop even in programs with no async functions. */
205
167
  usesTimers = false;
206
168
  /** Emitted ref-kind resolve thunks for new Promise, interned per inner
207
- * typeKey → thunk symbol (CEmitter.resolveThunks). */
169
+ * typeKey → thunk symbol. */
208
170
  resolveThunks = new Map();
209
171
  resolveThunkDefs = [];
210
172
  /** ReadableStream.from adapters keep typed arrays by reference and box
@@ -222,15 +184,16 @@ class LlEmitter {
222
184
  tracedShapes;
223
185
  tracedUnions;
224
186
  /** The class graph (buildClassGraph): preorder numbering, hierarchy
225
- * membership, virtual slot lists — the CEmitter classMeta, ported. */
187
+ * membership, virtual slot lists. */
226
188
  classMeta;
227
189
  /** Class objects (classes as first-class values): className → the
228
190
  * interned .name literal ref — registered during body emission, the
229
191
  * statics and construct thunks assemble around the bodies. */
230
192
  classObjs = new Map();
193
+ unionFieldReadGroups = new Map();
231
194
  /** Preorder intervals of the runtime error classes under THIS module's
232
195
  * class-forest numbering (main() stamps scr_error_vts with them, exactly
233
- * like the C emitter's errorVtStampLines). */
196
+ * like the runtime ABI’s errorVtStampLines). */
234
197
  errorIntervals = [];
235
198
  /** The runtime emitter vtable's preorder interval, when the program
236
199
  * touches node:events (the class def rides the module exactly then) —
@@ -245,6 +208,10 @@ class LlEmitter {
245
208
  B = new BlockBuilder();
246
209
  frames = [];
247
210
  scopes = [];
211
+ /** Scope slots dominate every throw site. Share their exceptional cleanup
212
+ * for identical live bindings and handlers; statement temporaries stay at
213
+ * their own throw sites because their SSA values are path-dependent. */
214
+ unwindCleanups = new Map();
248
215
  /** Enclosing break/continue targets. `kind` separates loops from
249
216
  * switches and labeled blocks: an unlabeled break binds to the innermost
250
217
  * NON-BLOCK entry (loop or switch — blocks only enter the stack when
@@ -260,7 +227,7 @@ class LlEmitter {
260
227
  integerRanges = new Map();
261
228
  /** Enclosing try-with-FINALLY regions, innermost last: a `return`
262
229
  * inside one runs every crossed finally (innermost first) before the
263
- * actual ret — the C emitter's pending-return path, with the finally
230
+ * actual ret — the runtime ABI’s pending-return path, with the finally
264
231
  * bodies emitted inline at the return site instead of behind a goto.
265
232
  * `tryDepth` snapshots tryStack.length at region entry: a throw inside
266
233
  * a pending-return finally copy propagates OUT of the completing try
@@ -269,7 +236,7 @@ class LlEmitter {
269
236
  * emitFinallysForJump. */
270
237
  finallyStack = [];
271
238
  /** Enclosing try contexts, innermost last — the compile-time unwind
272
- * targets (CEmitter.tryStack): a pending check or `throw` inside a try
239
+ * targets: a pending check or `throw` inside a try
273
240
  * releases frames/scopes down to the recorded depths and branches to
274
241
  * `label` (the catch, or the exception-path finally) instead of
275
242
  * returning out of the function. Entering a try emits no code. */
@@ -287,17 +254,22 @@ class LlEmitter {
287
254
  /** Active optional-chain bind slots, by chain id (chainRecv reads). */
288
255
  chainSlots = new Map();
289
256
  logArgSlots = 0;
257
+ stackTraces;
290
258
  constructor(mod, options) {
291
259
  this.mod = mod;
260
+ this.stackTraces = mod.functions.some((fn) => !everyStmtList(fn.body, {
261
+ stmt: () => true, expr: (expr) => !(expr.kind === "libCall" && expr.fn === "error.stack"),
262
+ }));
292
263
  this.debug = options.debugSources === undefined ? null : new LlvmDebugInfo(mod.sourceFile, options.debugSources, options.pointerBits, mod.unions);
293
264
  this.constantNumericTables = findConstantNumericTables(mod);
294
265
  this.sizeType = options.pointerBits === 32 ? "i32" : "i64";
266
+ this.ffiExtendNarrowIntegers = options.wasi === true || ffiExtendsNarrowIntegers(options.targetTriple);
295
267
  this.wasi = options.wasi === true;
296
268
  this.emitLibraryIdentity = options.emitLibraryIdentity !== false;
297
269
  this.runtimeAbiMarker = options.runtimeAbiMarker === true;
298
- // ScrCycHdr is { ptr trace; ptr free; i32 color; i16 buffered;
299
- // i16 gen; size_t buf_index }. The object follows it, so color is 12
300
- // bytes behind a wasm32 object and 16 bytes behind a 64-bit object.
270
+ // ScrCycHdr.color stays 12 bytes behind a wasm32 object and 16 bytes
271
+ // behind a 64-bit object. The wasm32 header pads before color so its
272
+ // payload remains double-aligned without changing this ABI offset.
301
273
  this.cycleColorOffset = options.pointerBits === 32 ? 12 : 16;
302
274
  this.ffiCallbackAdapters = allocateFfiCallbackAdapters(mod.ffiImports ?? []);
303
275
  this.ffiHasRetainedCallback = hasRetainedFfiCallback(mod.ffiImports ?? []);
@@ -323,11 +295,35 @@ class LlEmitter {
323
295
  const traced = computeTraced(mod);
324
296
  this.tracedShapes = traced.shapes;
325
297
  this.tracedUnions = traced.unions;
298
+ this.shapeHost = {
299
+ sizeType: this.sizeType,
300
+ cycleColorOffset: this.cycleColorOffset,
301
+ tracedShapes: this.tracedShapes,
302
+ tracedUnions: this.tracedUnions,
303
+ recordsById: this.recordsById,
304
+ recordCloneShapes: this.recordCloneShapes,
305
+ unionsById: this.unionsById,
306
+ declare: (decl) => this.declare(decl),
307
+ needOom: () => this.needOom(),
308
+ needBadTag: () => this.needBadTag(),
309
+ internLiteral: (text) => this.internLiteral(text),
310
+ cstr: (text) => this.cstr(text),
311
+ unitInstanceRef: (unionId, tag) => this.unitInstanceRef(unionId, tag),
312
+ liveDynRefAdapter: (type) => this.liveDynRefAdapter(type),
313
+ dynPromiseAdapter: (type) => this.dynPromiseAdapter(type),
314
+ isErrorClass: (name) => this.classMeta.get(name)?.root.def.name === "%Error",
315
+ classSubtypes: (name) => {
316
+ const target = this.classMetaOf(name);
317
+ return [...this.classMeta.values()].filter((meta) => target.pre <= meta.pre && meta.pre <= target.post).map((meta) => meta.def.name);
318
+ },
319
+ };
320
+ this.walkers = new LlWalkers(this.shapeHost);
321
+ this.dyn = new LlDyn(this.shapeHost);
326
322
  for (const g of mod.globals ?? []) {
327
323
  // Module globals: scalar (f64/bool) storage is a zero-initialized
328
324
  // LLVM global, ref-kind storage a null-initialized ptr — load/store
329
325
  // like a local, assigned by the %init functions. Refcounted globals
330
- // are released at the end of main (the C emitter's
326
+ // are released at the end of main (the runtime ABI’s
331
327
  // sc_release_globals), before the RC audit would run.
332
328
  try {
333
329
  this.llType(g.type); // refuses out-of-tier kinds
@@ -338,12 +334,11 @@ class LlEmitter {
338
334
  throw err;
339
335
  }
340
336
  this.globalTypes.set(g.id, g.type);
337
+ if (g.tdz)
338
+ this.tdzGlobals.set(g.id, g.name);
341
339
  }
342
- // User classes are IN the tier (phase 3), and so are the runtime
343
- // error classes and the runtime EventEmitter/stream classes (phase 6
344
- // — subclasses embed the ScrEmitter/ScrStream prefixes, classes.ts).
345
- // Anything else runtime-flagged refuses by name, exactly the
346
- // classDef:* histogram key.
340
+ // Runtime error, EventEmitter, and stream classes have known layouts.
341
+ // Subclasses embed the ScrEmitter/ScrStream prefixes from classes.ts.
347
342
  const classes = mod.classes ?? [];
348
343
  for (const cls of classes) {
349
344
  if (cls.runtime &&
@@ -354,9 +349,8 @@ class LlEmitter {
354
349
  }
355
350
  }
356
351
  // The class graph: base/children links, hierarchy membership, the
357
- // whole-program preorder numbering (identical to CEmitter's, so
358
- // runtime-made and compiled error objects agree on instanceof through
359
- // either backend), and the per-hierarchy virtual slot lists.
352
+ // whole-program preorder numbering for instanceof over runtime and
353
+ // compiled error objects, and the per-hierarchy virtual slot lists.
360
354
  this.classMeta = buildClassGraph(mod, this.fnByName);
361
355
  for (const [name, rec] of RUNTIME_ERROR_CLASSES) {
362
356
  const meta = this.classMeta.get(name);
@@ -384,7 +378,7 @@ class LlEmitter {
384
378
  }
385
379
  // ── types ───────────────────────────────────────────────────────────────
386
380
  llType(t) {
387
- if (POINTER_KINDS.has(t.kind) && t.kind !== "http2Session" && t.kind !== "http2Stream")
381
+ if (POINTER_KINDS.has(t.kind))
388
382
  return "ptr";
389
383
  switch (t.kind) {
390
384
  case "f64":
@@ -427,7 +421,7 @@ class LlEmitter {
427
421
  if (adapter.tls !== null)
428
422
  globals.push(`@${adapter.tls} = internal thread_local global ptr null`);
429
423
  if (adapter.global !== null)
430
- globals.push(`@${adapter.global} = internal global ptr null`);
424
+ globals.push(`@${adapter.global} = internal thread_local global ptr null`);
431
425
  if (adapter.table !== null) {
432
426
  globals.push(`@${adapter.table} = internal global %ScrFfiTable zeroinitializer`);
433
427
  }
@@ -437,11 +431,11 @@ class LlEmitter {
437
431
  if (param === "string" || param === "bytes") {
438
432
  return [`ptr %a${i}`, `${this.sizeType} %a${i}_len`];
439
433
  }
440
- return [`${ffiNativeTypeLl(param)} %a${i}`];
434
+ return [`${ffiNativeParamLl(param, this.ffiExtendNarrowIntegers)} %a${i}`];
441
435
  });
442
- const ret = ffiNativeTypeLl(cb.returns);
443
436
  if (cb.invoke === "foreign") {
444
- if (adapter.table === null || !cb.params.some(isFfiContextParam) || cb.returns !== "void") {
437
+ if (adapter.table === null || !cb.params.some(isFfiContextParam) || cb.returns !== "void" ||
438
+ cb.params.some(param => param === "i64" || param === "u64" || param === "pointer")) {
445
439
  throw new InternalCompilerError("llvm emitter bug: invalid foreign FFI callback descriptor");
446
440
  }
447
441
  const dispatch = `${adapter.symbol}_dispatch`;
@@ -458,6 +452,10 @@ class LlEmitter {
458
452
  continue;
459
453
  switch (param) {
460
454
  case "f64":
455
+ case "f32":
456
+ case "i8":
457
+ case "u16":
458
+ case "i16":
461
459
  this.declare(`declare double @scr_ffi_call_get_f64(ptr, ${this.sizeType})`);
462
460
  dispatchBody.push(` %s${i} = call double @scr_ffi_call_get_f64(ptr %call, ${this.sizeType} ${i})`);
463
461
  scriptArgs.push(`double %s${i}`);
@@ -494,7 +492,8 @@ class LlEmitter {
494
492
  }
495
493
  }
496
494
  dispatchBody.push(` call void %fn(${[`ptr %cb`, ...scriptArgs].join(", ")})`, ` ret void`, `}`, ``);
497
- defs.push(...dispatchBody);
495
+ for (const line of dispatchBody)
496
+ defs.push(line);
498
497
  this.declare(`declare ptr @scr_ffi_call_new(ptr, ptr, ptr, ${this.sizeType})`);
499
498
  this.declare(`declare void @scr_ffi_post(ptr)`);
500
499
  defs.push(`define internal void @${adapter.symbol}(${params.join(", ")}) ${FN_ATTRS} {`, `entry:`, ` %cb = getelementptr inbounds i8, ptr %ctx, i64 0`, ` %call = call ptr @scr_ffi_call_new(ptr @${adapter.table}, ptr %cb, ptr @${dispatch}, ${this.sizeType} ${cb.params.length})`);
@@ -510,6 +509,12 @@ class LlEmitter {
510
509
  this.declare(`declare void @scr_ffi_call_copy_${param}(ptr, ${this.sizeType}, ptr, ${this.sizeType})`);
511
510
  defs.push(` call void @scr_ffi_call_copy_${param}(ptr %call, ${this.sizeType} ${i}, ptr %a${i}, ${this.sizeType} %a${i}_len)`);
512
511
  }
512
+ else if (param === "f32" || param === "i8" || param === "u16" || param === "i16") {
513
+ const nativeTy = ffiNativeTypeLl(param);
514
+ const op = param === "f32" ? "fpext" : param === "u16" ? "uitofp" : "sitofp";
515
+ this.declare(`declare void @scr_ffi_call_set_f64(ptr, ${this.sizeType}, double)`);
516
+ defs.push(` %wide${i} = ${op} ${nativeTy} %a${i} to double`, ` call void @scr_ffi_call_set_f64(ptr %call, ${this.sizeType} ${i}, double %wide${i})`);
517
+ }
513
518
  else {
514
519
  const nativeTy = ffiNativeTypeLl(param);
515
520
  this.declare(`declare void @scr_ffi_call_set_${param}(ptr, ${this.sizeType}, ${nativeTy})`);
@@ -519,7 +524,7 @@ class LlEmitter {
519
524
  defs.push(` call void @scr_ffi_post(ptr %call)`, ` ret void`, `}`, ``);
520
525
  continue;
521
526
  }
522
- defs.push(`define internal ${ret} @${adapter.symbol}(${params.join(", ")}) ${FN_ATTRS} {`, `entry:`, adapter.tls !== null
527
+ defs.push(`define internal ${ffiNativeReturnLl(cb.returns, this.ffiExtendNarrowIntegers)} @${adapter.symbol}(${params.join(", ")}) ${FN_ATTRS} {`, `entry:`, adapter.tls !== null
523
528
  ? ` %cb = load ptr, ptr @${adapter.tls}`
524
529
  : adapter.global !== null
525
530
  ? ` %cb = load ptr, ptr @${adapter.global}`
@@ -550,9 +555,28 @@ class LlEmitter {
550
555
  if (isFfiContextParam(param))
551
556
  continue;
552
557
  switch (param) {
558
+ case "i64":
559
+ case "u64":
560
+ case "pointer": {
561
+ const ty = ffiNativeTypeLl(param);
562
+ this.declare(`declare ptr @scr_bigint_from_${param}(${ty})`);
563
+ defs.push(` %s${i} = call ptr @scr_bigint_from_${param}(${ty} %a${i})`);
564
+ scriptArgs.push(`ptr %s${i}`);
565
+ break;
566
+ }
553
567
  case "f64":
554
568
  scriptArgs.push(`double %a${i}`);
555
569
  break;
570
+ case "f32":
571
+ case "i8":
572
+ case "u16":
573
+ case "i16": {
574
+ const nativeTy = ffiNativeTypeLl(param);
575
+ const op = param === "f32" ? "fpext" : param === "u16" ? "uitofp" : "sitofp";
576
+ defs.push(` %s${i} = ${op} ${nativeTy} %a${i} to double`);
577
+ scriptArgs.push(`double %s${i}`);
578
+ break;
579
+ }
556
580
  case "bool":
557
581
  defs.push(` %s${i} = icmp ne i8 %a${i}, 0`);
558
582
  scriptArgs.push(`i1 %s${i}`);
@@ -604,18 +628,34 @@ class LlEmitter {
604
628
  defs.push(` call void @scr_closure_release_v(ptr %invoke_pin)`);
605
629
  }
606
630
  switch (cb.returns) {
631
+ case "i64":
632
+ case "u64":
633
+ case "pointer": {
634
+ const ty = ffiNativeTypeLl(cb.returns);
635
+ this.declare(`declare ${ty} @scr_bigint_to_${cb.returns}(ptr)`);
636
+ this.declare(`declare void @scr_bigint_release(ptr)`);
637
+ defs.push(` %out = call ${ty} @scr_bigint_to_${cb.returns}(ptr %result)`, ` call void @scr_bigint_release(ptr %result)`, ` ret ${ty} %out`);
638
+ break;
639
+ }
607
640
  case "f64":
608
641
  defs.push(` ret double %result`);
609
642
  break;
643
+ case "f32":
644
+ defs.push(` %out = fptrunc double %result to float`, ` ret float %out`);
645
+ break;
610
646
  case "bool":
611
647
  defs.push(` %out = zext i1 %result to i8`, ` ret i8 %out`);
612
648
  break;
613
649
  case "u8":
650
+ case "i8":
651
+ case "u16":
652
+ case "i16":
614
653
  case "u32":
615
654
  this.declare(`declare double @scr_bit_ushr(double, double)`);
616
655
  defs.push(` %coerced = call double @scr_bit_ushr(double %result, double ${f64Lit(0)})`, ` %wide = fptoui double %coerced to i32`);
617
- if (cb.returns === "u8") {
618
- defs.push(` %out = trunc i32 %wide to i8`, ` ret i8 %out`);
656
+ if (cb.returns !== "u32") {
657
+ const nativeTy = ffiNativeTypeLl(cb.returns);
658
+ defs.push(` %out = trunc i32 %wide to ${nativeTy}`, ` ret ${nativeTy} %out`);
619
659
  }
620
660
  else {
621
661
  defs.push(` ret i32 %wide`);
@@ -632,13 +672,32 @@ class LlEmitter {
632
672
  }
633
673
  emit() {
634
674
  // Function bodies first (the literal/unit/fn-value tables fill as they
635
- // emit), then the file assembles around them — the C emitter's order.
675
+ // emit), then the file assembles around them — the runtime ABI’s order.
636
676
  const fnDefs = [];
637
677
  for (const fn of this.mod.functions)
638
678
  fnDefs.push(this.emitFunction(fn));
639
- const shapes = emitRecordShapes(this, this.mod);
640
- const classShapes = emitClassShapes(this, this.mod, this.classMeta);
641
- const classObjDefs = emitClassObjDefs(this, this.classMeta, this.classObjs, this.fnByName, (t) => this.llType(t));
679
+ const errorViews = [];
680
+ for (const property of ["name", "message"])
681
+ if (this.mod.functions.some((fn) => fn.name === `%error.${property}.read`)) {
682
+ this.declare(`declare void @scr_error_install_${property}_reader(ptr)`);
683
+ errorViews.push(` call void @scr_error_install_${property}_reader(ptr @${mangleFunction(`%error.${property}.read`)})`);
684
+ }
685
+ for (const meta of this.classMeta.values()) {
686
+ if (meta.def.runtime || meta.root.def.name !== "%Error")
687
+ continue;
688
+ const type = { kind: "object", className: meta.def.name };
689
+ const adapter = this.liveDynRefAdapter(type);
690
+ const rc = vAdapters(this.shapeHost, type);
691
+ const key = typeKey(type);
692
+ const name = `sc_error_view_${errorViews.length}`;
693
+ this.resolveThunkDefs.push(`define internal ptr @${name}(ptr %v) ${FN_ATTRS} {`, `entry:`, ` %d = call ptr ${typedRefConstructor(this.shapeHost, type)}(ptr %v, ptr ${rc.retain}, ptr ${rc.release}, ptr ${this.cstr(key)}, ${this.sizeType} ${Buffer.byteLength(key, "utf8")}, ptr @${adapter.snapshot}, ptr ${adapter.commit})`, ` ret ptr %d`, `}`, ``);
694
+ this.declare(`declare void @scr_error_register_dyn(ptr, ptr)`);
695
+ errorViews.push(` call void @scr_error_register_dyn(ptr @${mangleVtInstance(meta.def.name)}, ptr @${name})`);
696
+ }
697
+ const layouts = emitLlvmLayouts(this.shapeHost, this.mod, this.classMeta, this.classObjs, this.fnByName, (t) => this.llType(t));
698
+ const shapes = layouts.records;
699
+ const classShapes = layouts.classes;
700
+ const classObjDefs = layouts.classObjects;
642
701
  const wrappers = this.emitFnValueDefs();
643
702
  const asyncDefs = this.emitAsyncScaffolding();
644
703
  const ffiCallbacks = this.emitFfiCallbackDefs();
@@ -672,72 +731,88 @@ class LlEmitter {
672
731
  seenGlobalIds.add(g.id);
673
732
  return true;
674
733
  });
675
- // Refcounted globals release before main returns — the C emitter's
734
+ // Refcounted globals release before main returns — the runtime ABI’s
676
735
  // sc_release_globals, keeping the RC audit's live count exact. Built
677
736
  // before the declaration table flushes (it adds the release symbols).
678
737
  // Two spellings with distinct temp names: the normal exit and the
679
738
  // uncaught-exception exit are separate blocks of the same function.
680
739
  // Interned function-value closures are IMMORTAL (rc == SIZE_MAX), so
681
740
  // an own-property table Object.defineProperties hung on one would
682
- // outlive the RC audit — release it with the globals (the C emitter's
741
+ // outlive the RC audit — release it with the globals (the runtime ABI’s
683
742
  // sc_release_globals tail). Only when the dispatch unit is even
684
743
  // linked (defineProps is the only writer).
685
- const fnValueProps = moduleUsesDynInvoke(this.mod) ? [...this.fnValues] : [];
744
+ const runtimeFeatures = moduleRuntimeFeatures(this.mod);
745
+ const fnValueProps = [...this.fnValues];
686
746
  if (fnValueProps.length > 0)
687
747
  this.declare(`declare void @scr_box_release(ptr)`);
748
+ if (this.classObjs.size > 0)
749
+ this.declare(`declare void @scr_classobj_clear_properties(ptr)`);
688
750
  const globalReleaseLines = (prefix) => {
689
751
  const lines = [];
690
752
  globals.forEach((g, i) => {
691
753
  if (!isRefCounted(g.type))
692
754
  return;
693
- lines.push(` %${prefix}${i} = load ptr, ptr @${mangleGlobal(g.id)}`, ` call void ${releaseSym(this, g.type)}(ptr %${prefix}${i}) ; ${g.name}`);
755
+ lines.push(` %${prefix}${i} = load ptr, ptr @${mangleGlobal(g.id)}`, ` call void ${releaseSym(this.shapeHost, g.type)}(ptr %${prefix}${i}) ; ${g.name}`);
694
756
  });
695
757
  fnValueProps.forEach((name, i) => {
696
758
  // props sits at %ScrClosure field 3; release is NULL-tolerant —
697
759
  // cleared so a second release path stays idempotent.
698
760
  lines.push(` %${prefix}fp${i} = load ptr, ptr getelementptr inbounds (%ScrClosure, ptr @${mangleFnClosure(name)}, i64 0, i32 3)`, ` call void @scr_box_release(ptr %${prefix}fp${i}) ; ${name}.props`, ` store ptr null, ptr getelementptr inbounds (%ScrClosure, ptr @${mangleFnClosure(name)}, i64 0, i32 3)`);
699
761
  });
762
+ for (const name of this.classObjs.keys())
763
+ lines.push(` call void @scr_classobj_clear_properties(ptr @${mangleClassObj(name)})`);
700
764
  return lines;
701
765
  };
702
766
  // Exit listeners can read MODULE GLOBALS directly, so they must run
703
- // BEFORE the global releases (the C emitter's runExitListeners
767
+ // BEFORE the global releases (the runtime ABI’s runExitListeners
704
768
  // ordering — the atexit half becomes an idempotent no-op).
705
- const usesEvents = moduleUsesProcessEvents(this.mod);
706
- const usesChildProcess = moduleUsesChildProcess(this.mod);
707
- const usesFsWatch = moduleUsesFsWatch(this.mod);
769
+ const usesEvents = runtimeFeatures.processEvents;
770
+ const usesChildProcess = runtimeFeatures.childProcess;
771
+ const usesFsWatch = runtimeFeatures.fsWatch;
708
772
  // Stream-surface programs fill the loop's stream hook (the deferred
709
773
  // next-tick emissions) and the emitter's post-registration flow kick
710
774
  // before %main — scr_stream.c links only when the line is emitted
711
775
  // (native-toolchain.ts gates on the same predicate).
712
- const usesStream = moduleUsesStream(this.mod);
776
+ const usesStream = runtimeFeatures.stream;
713
777
  // Net-surface programs fill the loop's net hooks (and the netSocket
714
778
  // handle-dispatch ops for the checked-dynamic boundary); http-surface
715
779
  // programs additionally stamp the httpReq/httpRes ops — the C main's
716
780
  // install lines, gated on the same predicates native-toolchain.ts links by.
717
- const usesNet = moduleUsesNet(this.mod);
718
- const usesHttp = moduleUsesHttpServer(this.mod);
781
+ const usesNet = runtimeFeatures.net;
782
+ const usesDgram = runtimeFeatures.dgram;
783
+ const usesHttp2 = runtimeFeatures.http2;
784
+ const usesHttp = runtimeFeatures.http;
719
785
  // Fetch-referencing programs register the native fetch bridge before
720
786
  // any island entry (the engine's lazy boot consults it) — native-toolchain.ts
721
787
  // compiles scr_fetch.c on the same predicate.
722
- const usesFetch = moduleUsesFetch(this.mod);
788
+ const usesFetch = runtimeFeatures.fetch;
723
789
  const embedsZlib = moduleEmbedsBuiltin(this.mod, "node:zlib");
724
790
  const embedsNet = moduleEmbedsBuiltin(this.mod, "node:http") ||
725
791
  moduleEmbedsBuiltin(this.mod, "node:https") ||
726
792
  moduleEmbedsBuiltin(this.mod, "node:net") ||
727
793
  moduleEmbedsBuiltin(this.mod, "node:tls");
728
- const snapshotsTlsCa = moduleUsesTls(this.mod) || moduleUsesTlsCa(this.mod) ||
794
+ const snapshotsTlsCa = runtimeFeatures.tls || runtimeFeatures.tlsCa ||
729
795
  moduleEmbedsBuiltin(this.mod, "node:https") ||
730
796
  moduleEmbedsBuiltin(this.mod, "node:tls");
731
797
  // The process verdict has the same precedence as the C reference
732
798
  // emitter: node:test owns the final status when present; otherwise an
733
799
  // embedded process.exitCode owns it; ordinary programs return zero.
734
- const usesNodeTest = moduleUsesNodeTest(this.mod);
800
+ const usesNodeTest = runtimeFeatures.nodeTest;
735
801
  const programExitUsesIsland = !usesNodeTest && usesIsland;
736
802
  // Declared NOW — the extern block flushes before main assembles.
737
803
  if (usesEvents)
738
804
  this.declare(`declare void @scr_events_install()`);
739
805
  if (usesChildProcess)
740
806
  this.declare(`declare void @scr_child_dyn_install()`);
807
+ const childStreamBoxes = usesChildProcess && usesStream &&
808
+ this.classMeta.has("%Readable") && this.classMeta.has("%Writable")
809
+ ? [this.dyn.toDynHelper({ kind: "object", className: "%Readable" }),
810
+ this.dyn.toDynHelper({ kind: "object", className: "%Writable" })]
811
+ : null;
812
+ if (childStreamBoxes) {
813
+ this.declare(`@scr_stream_child_ops = external constant { ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }`);
814
+ this.declare(`declare void @scr_child_dyn_streams_install(ptr, ptr, ptr)`);
815
+ }
741
816
  if (usesFsWatch)
742
817
  this.declare(`declare void @scr_watch_install()`);
743
818
  if (this.ffiHasForeignCallback)
@@ -748,6 +823,10 @@ class LlEmitter {
748
823
  this.declare(`declare void @scr_net_install()`);
749
824
  this.declare(`declare void @scr_net_dyn_install()`);
750
825
  }
826
+ if (usesDgram)
827
+ this.declare(`declare void @scr_dgram_install()`);
828
+ if (usesHttp2)
829
+ this.declare(`declare void @scr_http2_dyn_install()`);
751
830
  if (usesHttp)
752
831
  this.declare(`declare void @scr_http_dyn_install()`);
753
832
  if (usesFetch)
@@ -773,13 +852,12 @@ class LlEmitter {
773
852
  // the refcounted-global releases, or the retained-FFI atexit ledger
774
853
  // sweep (a listener may legitimately release or pump a registration,
775
854
  // and only the inline call orders ahead of every atexit handler —
776
- // the C emitter's runExitListeners stance). Plain event programs
855
+ // the runtime ABI’s runExitListeners stance). Plain event programs
777
856
  // with neither keep the atexit path, so their listener timing is
778
857
  // unchanged.
779
858
  const hasRefGlobals = globals.some((g) => isRefCounted(g.type)) || fnValueProps.length > 0;
780
859
  const inlineExitListeners = usesEvents && (hasRefGlobals || this.ffiHasRetainedCallback);
781
- if (!usesNodeTest && !usesIsland)
782
- this.declare(`declare i32 @scr_exit_code_hint_get()`);
860
+ this.declare(`declare i32 @scr_exit_code_hint_get()`);
783
861
  if (inlineExitListeners) {
784
862
  this.declare(`declare void @scr_run_exit_listeners(double)`);
785
863
  this.declare(`declare i32 @scr_exit_code_hint_get()`);
@@ -852,17 +930,23 @@ class LlEmitter {
852
930
  // finish_top_level initially notes 13. Replace that hint before exit
853
931
  // listeners run when a higher-priority verdict was already selected.
854
932
  lines.push(` call void @scr_exit_code_note(i32 ${exitStatus})`);
855
- lines.push(...exitListenerLines("xp"));
933
+ for (const line of exitListenerLines("xp"))
934
+ lines.push(line);
856
935
  if (tracksIslandExit) {
857
936
  lines.push(` %tla_exit_version_after = call ${this.sizeType} @scr_island_exit_code_version()`, ` %tla_exit_changed = icmp ne ${this.sizeType} %tla_exit_version_after, %tla_exit_version`, ` br i1 %tla_exit_changed, label %tla_exit_updated, label %tla_exit_unchanged`, `tla_exit_updated:`, ` %tla_listener_exit = call i32 @scr_island_exit_code()`, ` call void @scr_exit_code_note(i32 %tla_listener_exit)`, ` br label %tla_exit_done`, `tla_exit_unchanged:`, ` br label %tla_exit_done`, `tla_exit_done:`, ` %tla_final_exit = phi i32 [ %tla_listener_exit, %tla_exit_updated ], [ ${exitStatus}, %tla_exit_unchanged ]`);
858
937
  }
859
- lines.push(...topPendingReleases);
938
+ for (const line of topPendingReleases)
939
+ lines.push(line);
860
940
  lines.push(` ret i32 ${tracksIslandExit ? "%tla_final_exit" : exitStatus}`);
861
941
  return lines;
862
942
  };
863
943
  // LIBRARY mode: the runtime entry points the generated library
864
944
  // symbols delegate to — declared before the extern block flushes.
865
945
  if (this.mod.lib !== undefined) {
946
+ if (this.wasi) {
947
+ this.declare(`declare ptr @malloc(${this.sizeType})`);
948
+ this.declare(`declare void @free(ptr)`);
949
+ }
866
950
  this.declare(`declare void @scr_library_entry(i1 zeroext, ptr)`);
867
951
  this.declare(`declare void @scr_library_reset()`);
868
952
  this.declare(`declare void @scr_library_check_exc()`);
@@ -916,18 +1000,18 @@ class LlEmitter {
916
1000
  `%ScrLogArg = type { i32, i64 }`,
917
1001
  `%ScrVt = type { ${this.sizeType}, ${this.sizeType}, ptr }`,
918
1002
  `%ScrUnion = type { ${this.sizeType}, i32, ptr, ptr, ptr, i64 }`,
919
- `%ScrClosure = type { ${this.sizeType}, ptr, ${this.sizeType}, ptr }`,
1003
+ `%ScrClosure = type { ${this.sizeType}, ptr, ${this.sizeType}, ptr, i32 }`,
920
1004
  `%ScrFfiTable = type { ptr, ${this.sizeType}, ${this.sizeType}, ptr, i8, ptr, ptr, ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, ptr, ptr }`,
921
- `%ScrRegex = type { ${this.sizeType}, ptr, ptr, ptr }`,
1005
+ `%ScrRegex = type { ${this.sizeType}, ptr, ptr, ptr, double, ptr }`,
922
1006
  // ScrArr mirrors scr_runtime.h field-for-field. Live dynamic stream
923
1007
  // commits swap its mutable dense, sparse, presence, and property
924
1008
  // storage while preserving the target object's identity.
925
- `%ScrArr = type { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, i32, ptr, ptr, ptr, ptr, ptr, ptr, ${this.sizeType}, ${this.sizeType}, ptr, ${this.sizeType}, ${this.sizeType} }`,
926
- // The runtime error prefix { rc, vt, name, message, code } and the
1009
+ `%ScrArr = type { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, i32, ptr, ptr, ptr, ptr, ptr, ptr, ${this.sizeType}, ${this.sizeType}, ptr, ${this.sizeType}, ${this.sizeType}, ptr }`,
1010
+ // The runtime error prefix { rc, vt, name, message, code, cause } and the
927
1011
  // class-object shape { rc, pre, post, ctor, name } — field reads on
928
1012
  // builtin errors and classval loads GEP through these.
929
- `%ScrError = type { ${this.sizeType}, ptr, ptr, ptr, ptr }`,
930
- `%ScrClassObj = type { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, ptr, ptr }`,
1013
+ `%ScrError = type { ${this.sizeType}, ptr, ptr, ptr, ptr, ptr, i8, i8, i8, i8, i8, ptr, ptr }`,
1014
+ `%ScrClassObj = type { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, ptr, ptr, ${this.sizeType}, ${this.sizeType}, ptr, ptr }`,
931
1015
  // The runtime emitter prefix { rc, vt, reg, cls } — user subclasses
932
1016
  // embed it (classes.ts), and bare-emitter GEPs address through it.
933
1017
  `%ScrEmitter = type { ${this.sizeType}, ptr, ptr, ptr }`,
@@ -944,7 +1028,7 @@ class LlEmitter {
944
1028
  // typed-array access GEPs through this directly: the IR type already
945
1029
  // fixes elem, so the hot path needs neither a runtime kind load nor
946
1030
  // the generic scr_bytes_get/set call.
947
- `%ScrBytes = type { ${this.sizeType}, ${this.sizeType}, i32, ptr, ptr }`,
1031
+ `%ScrBytes = type { ${this.sizeType}, ${this.sizeType}, i32, ptr, ptr, i8 }`,
948
1032
  // The capture box { rc, kind, obj_retain, obj_release, obj_trace,
949
1033
  // slot } — TDZ reads peek the payload slot (offset 40) directly.
950
1034
  `%ScrBox = type { ${this.sizeType}, i32, ptr, ptr, ptr, i64 }`,
@@ -956,8 +1040,10 @@ class LlEmitter {
956
1040
  `%ScrIslandModule = type { ptr, ptr, ${this.sizeType}, ${this.sizeType}, i32, ptr, ${this.sizeType}, ${this.sizeType} }`,
957
1041
  `%ScrIslandEdge = type { ptr, ptr, ptr, i32 }`,
958
1042
  ];
959
- out.push(...shapes.typeDefs);
960
- out.push(...classShapes.typeDefs);
1043
+ for (const line of shapes.typeDefs)
1044
+ out.push(line);
1045
+ for (const line of classShapes.typeDefs)
1046
+ out.push(line);
961
1047
  // Thread-instanced library state (abi.instance_per_thread): the
962
1048
  // program TU's mutable globals — module globals, run-once guards, the
963
1049
  // lazily-compiled regex literal caches — and the runtime globals its
@@ -966,7 +1052,7 @@ class LlEmitter {
966
1052
  // data (string literals, unit arms, template arrays, vtables) stays
967
1053
  // shared.
968
1054
  const tl = this.mod.lib?.threadInstances === true ? "thread_local " : "";
969
- out.push(``, `@scr_error_vts = external ${tl}global [5 x %ScrVt]`, `declare void @scr_init()`, `declare void @scr_lib_init(i32, ptr)`, ...(this.runtimeAbiMarker && this.mod.lib === undefined
1055
+ out.push(``, `@scr_error_vts = external ${tl}global [${RUNTIME_ERROR_CLASSES.size} x %ScrVt]`, `declare void @scr_init()`, `declare void @scr_lib_init(i32, ptr)`, ...(this.runtimeAbiMarker && this.mod.lib === undefined
970
1056
  ? [`declare void @${RUNTIME_ABI_MARKER}()`]
971
1057
  : []));
972
1058
  for (const d of this.decls)
@@ -981,7 +1067,7 @@ class LlEmitter {
981
1067
  }
982
1068
  for (const [text, lit] of this.literals) {
983
1069
  // Immortal interned ScrStr: { rc = SIZE_MAX, len, cap = len, bytes\0 } —
984
- // the C emitter's static table, retain/release skip rc == SIZE_MAX.
1070
+ // the runtime ABI’s static table, retain/release skip rc == SIZE_MAX.
985
1071
  out.push(`@${lit.sym} = internal global { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, [${lit.len + 1} x i8] } ` +
986
1072
  `{ ${this.sizeType} -1, ${this.sizeType} ${lit.len}, ${this.sizeType} ${lit.len}, [${lit.len + 1} x i8] c"${llStrBytes(text)}" }`);
987
1073
  }
@@ -1000,7 +1086,7 @@ class LlEmitter {
1000
1086
  // One immortal ScrRegex per (pattern, flags) literal, pointing at
1001
1087
  // the interned source/flags strings. The bc slot starts null (lazy
1002
1088
  // compile, cached by the runtime) — a mutable global, not constant.
1003
- out.push(`@${re.sym} = internal ${tl}global %ScrRegex { ${this.sizeType} -1, ptr ${re.src}, ptr ${re.fl}, ptr null } ; ${key.replace(/\n/g, "\\n")}`);
1089
+ out.push(`@${re.sym} = internal ${tl}global %ScrRegex { ${this.sizeType} -1, ptr ${re.src}, ptr ${re.fl}, ptr null, double 0.0, ptr null } ; ${key.replace(/\n/g, "\\n")}`);
1004
1090
  }
1005
1091
  if (this.regexInstances.size > 0)
1006
1092
  out.push(``);
@@ -1014,13 +1100,12 @@ class LlEmitter {
1014
1100
  const present = n === 0
1015
1101
  ? "zeroinitializer"
1016
1102
  : `[ ${inst.slots.map(() => "i8 1").join(", ")} ]`;
1017
- out.push(`@${inst.sym}_data = internal constant [${n} x ptr] [ ${inst.slots.map((s) => `ptr ${s}`).join(", ")} ]`, `@${inst.sym}_present = internal constant [${n} x i8] ${present}`, `@${inst.sym} = internal global %ScrArr { ${this.sizeType} -1, ${this.sizeType} ${n}, ${this.sizeType} ${n}, i32 2, ptr null, ptr null, ptr null, ptr @${inst.sym}_data, ptr @${inst.sym}_present, ptr null, ${this.sizeType} 0, ${this.sizeType} 0, ptr null, ${this.sizeType} 0, ${this.sizeType} 0 }`);
1103
+ out.push(`@${inst.sym}_data = internal constant [${n} x ptr] [ ${inst.slots.map((s) => `ptr ${s}`).join(", ")} ]`, `@${inst.sym}_present = internal constant [${n} x i8] ${present}`, `@${inst.sym} = internal global %ScrArr { ${this.sizeType} -1, ${this.sizeType} ${n}, ${this.sizeType} ${n}, i32 2, ptr null, ptr null, ptr null, ptr @${inst.sym}_data, ptr @${inst.sym}_present, ptr null, ${this.sizeType} 0, ${this.sizeType} 0, ptr null, ${this.sizeType} 0, ${this.sizeType} 0, ptr null }`);
1018
1104
  }
1019
1105
  if (this.templateStringsInstances.size > 0)
1020
1106
  out.push(``);
1021
1107
  for (const [text, c] of this.cstrs) {
1022
- // NUL-terminated byte-array constants: the scr_jb_puts / indent-text
1023
- // currency (the C emitter passes string literals; these are theirs).
1108
+ // NUL-terminated byte-array constants for scr_jb_puts and indentation.
1024
1109
  out.push(`@${c.sym} = internal constant [${c.len + 1} x i8] c"${llStrBytes(text)}"`);
1025
1110
  }
1026
1111
  if (this.cstrs.size > 0)
@@ -1047,7 +1132,8 @@ class LlEmitter {
1047
1132
  });
1048
1133
  out.push(`@sc_npm_modules = internal constant [${moduleRows.length} x %ScrIslandModule] [ ${moduleRows.join(", ")} ]`);
1049
1134
  embedded.edges.forEach((edge, i) => {
1050
- for (const [part, text] of [["from", edge.from], ["spec", edge.specifier], ["to", edge.to]]) {
1135
+ const parts = [["from", edge.from], ["spec", edge.specifier], ["to", edge.to]];
1136
+ for (const [part, text] of parts) {
1051
1137
  const bytes = Buffer.from(text, "utf8");
1052
1138
  out.push(`@sc_npm_edge_${i}_${part} = internal constant [${bytes.length + 1} x i8] c"${llBytes(bytes)}"`);
1053
1139
  }
@@ -1059,7 +1145,8 @@ class LlEmitter {
1059
1145
  }
1060
1146
  out.push(``);
1061
1147
  }
1062
- out.push(...ffiCallbacks.globals);
1148
+ for (const line of ffiCallbacks.globals)
1149
+ out.push(line);
1063
1150
  if (ffiCallbacks.globals.length > 0)
1064
1151
  out.push(``);
1065
1152
  for (const g of globals) {
@@ -1070,26 +1157,36 @@ class LlEmitter {
1070
1157
  }
1071
1158
  if (globals.length > 0)
1072
1159
  out.push(``);
1073
- out.push(...helpers);
1074
- out.push(...ffiCallbacks.defs);
1075
- out.push(...shapes.defs);
1076
- out.push(...classShapes.defs);
1077
- out.push(...classObjDefs);
1078
- out.push(...this.walkers.defs);
1079
- out.push(...this.dyn.defs);
1080
- out.push(...wrappers);
1081
- out.push(...asyncDefs);
1082
- out.push(...this.resolveThunkDefs);
1160
+ for (const line of helpers)
1161
+ out.push(line);
1162
+ for (const line of ffiCallbacks.defs)
1163
+ out.push(line);
1164
+ for (const line of shapes.defs)
1165
+ out.push(line);
1166
+ for (const line of classShapes.defs)
1167
+ out.push(line);
1168
+ for (const line of classObjDefs)
1169
+ out.push(line);
1170
+ for (const line of this.walkers.defs)
1171
+ out.push(line);
1172
+ for (const line of this.dyn.defs)
1173
+ out.push(line);
1174
+ for (const line of wrappers)
1175
+ out.push(line);
1176
+ for (const line of asyncDefs)
1177
+ out.push(line);
1178
+ for (const line of this.resolveThunkDefs)
1179
+ out.push(line);
1083
1180
  out.push(fnDefs.join("\n\n"), ``);
1084
1181
  // main(): scr_init, the program-dependent error-vt interval stamps,
1085
1182
  // scr_lib_init(argc, argv), then the entry function. An uncaught
1086
- // exception escaping top-level code prints and exits 1 (Node) — the
1087
- // C emitter's epilogue, emitted exactly when the entry may throw.
1088
- // No event loop yet: timers/async still refuse (phase 5).
1089
- const stamps = [];
1183
+ // exception escaping top-level code prints and exits 1 (Node).
1184
+ // The exception epilogue is emitted when the entry may throw.
1185
+ const stamps = [...errorViews];
1090
1186
  for (const iv of this.errorIntervals) {
1091
- for (const [field, value] of [[0, iv.pre], [1, iv.post]]) {
1092
- stamps.push(` store ${this.sizeType} ${value}, ptr getelementptr inbounds ([5 x %ScrVt], ptr @scr_error_vts, i64 0, i64 ${iv.kind}, i32 ${field})${field === 1 ? ` ; ${iv.lib}` : ""}`);
1187
+ const fields = [[0, iv.pre], [1, iv.post]];
1188
+ for (const [field, value] of fields) {
1189
+ stamps.push(` store ${this.sizeType} ${value}, ptr getelementptr inbounds ([${RUNTIME_ERROR_CLASSES.size} x %ScrVt], ptr @scr_error_vts, i64 0, i64 ${iv.kind}, i32 ${field})${field === 1 ? ` ; ${iv.lib}` : ""}`);
1093
1190
  }
1094
1191
  }
1095
1192
  if (this.emitterInterval !== null) {
@@ -1122,12 +1219,13 @@ class LlEmitter {
1122
1219
  // order-free — the scr_error_set_traced precedent). Only the
1123
1220
  // printer emits here (nothing else declares it); scr_exc_pending
1124
1221
  // and the loop entry points rode the Set before the flush.
1125
- out.push(`declare void @scr_exc_print_uncaught()`, ``);
1222
+ out.push(`declare void @scr_exc_print_uncaught()`, `declare zeroext i1 @scr_exc_handle_uncaught(i1 zeroext)`, ``);
1126
1223
  }
1127
1224
  if (this.mod.lib !== undefined) {
1128
1225
  // LIBRARY mode: no @main — the profile-declared external
1129
- // symbols instead, from the same IR facts the C emission consumes.
1130
- out.push(...this.emitLibDefs(globals, globalReleaseLines, stamps));
1226
+ // symbols specified by the library IR instead.
1227
+ for (const line of this.emitLibDefs(globals, globalReleaseLines, stamps))
1228
+ out.push(line);
1131
1229
  out.push(`attributes #0 = { sanitize_address }`);
1132
1230
  if (this.wasi)
1133
1231
  out.push(`attributes #1 = { sanitize_address presplitcoroutine }`);
@@ -1142,10 +1240,10 @@ class LlEmitter {
1142
1240
  // Event-surface programs (signal/exit listeners) fill the loop's
1143
1241
  // nullable event hooks before %main — scr_events.c links only when
1144
1242
  // this line is emitted (native-toolchain.ts gates on the same predicate).
1145
- ...(usesEvents ? [` call void @scr_events_install()`] : []), ...(usesChildProcess ? [` call void @scr_child_dyn_install()`] : []),
1243
+ ...(usesEvents ? [` call void @scr_events_install()`] : []), ...(usesChildProcess ? [` call void @scr_child_dyn_install()`] : []), ...(childStreamBoxes ? [` call void @scr_child_dyn_streams_install(ptr @scr_stream_child_ops, ptr @${childStreamBoxes[0]}, ptr @${childStreamBoxes[1]})`] : []),
1146
1244
  // fs.watch programs fill the loop's watch hooks the same way —
1147
1245
  // scr_watch.c links only when this line is emitted.
1148
- ...(usesFsWatch ? [` call void @scr_watch_install()`] : []), ...(this.ffiHasForeignCallback ? [` call void @scr_ffi_install()`] : []), ...(snapshotsTlsCa ? [` call void @scr_tls_ca_install()`] : []), ...(usesFetch ? [` call void @scr_fetch_install()`] : []), ...(embedsZlib ? [` call void @scr_zlib_island_install()`] : []), ...(embedsNet ? [` call void @scr_net_island_install()`] : []), ...(usesNet ? [` call void @scr_net_install()`, ` call void @scr_net_dyn_install()`] : []), ...(usesHttp ? [` call void @scr_http_dyn_install()`] : []), ...(usesStream ? [` call void @scr_stream_install()`] : []), ` call void @scr_lib_init(i32 %argc, ptr %argv)`, ...(usesIsland
1246
+ ...(usesFsWatch ? [` call void @scr_watch_install()`] : []), ...(this.ffiHasForeignCallback ? [` call void @scr_ffi_install()`] : []), ...(snapshotsTlsCa ? [` call void @scr_tls_ca_install()`] : []), ...(usesFetch ? [` call void @scr_fetch_install()`] : []), ...(embedsZlib ? [` call void @scr_zlib_island_install()`] : []), ...(embedsNet ? [` call void @scr_net_island_install()`] : []), ...(usesNet ? [` call void @scr_net_install()`, ` call void @scr_net_dyn_install()`] : []), ...(usesHttp ? [` call void @scr_http_dyn_install()`] : []), ...(usesDgram ? [` call void @scr_dgram_install()`] : []), ...(usesHttp2 ? [` call void @scr_http2_dyn_install()`] : []), ...(usesStream ? [` call void @scr_stream_install()`] : []), ` call void @scr_lib_init(i32 %argc, ptr %argv)`, ...(usesIsland
1149
1247
  ? [
1150
1248
  ...(moduleEmbedsCompressedNpm(this.mod)
1151
1249
  ? [` call void @scr_island_set_inflate(ptr @scr_zlib_inflate_exact)`]
@@ -1162,10 +1260,14 @@ class LlEmitter {
1162
1260
  ` %exc = call zeroext i1 @scr_exc_pending()`,
1163
1261
  ` br i1 %exc, label %uncaught, label %ok`,
1164
1262
  `uncaught:`,
1263
+ ` %handled = call zeroext i1 @scr_exc_handle_uncaught(i1 false)`,
1264
+ ` br i1 %handled, label %ok, label %fatal`,
1265
+ `fatal:`,
1165
1266
  ` call void @scr_exc_print_uncaught()`,
1166
1267
  ...exitListenerLines("xu"),
1167
1268
  ...uncaughtReleases,
1168
- ` ret i32 1`,
1269
+ ` %failure_code_0 = call i32 @scr_exit_code_hint_get()`,
1270
+ ` ret i32 %failure_code_0`,
1169
1271
  `ok:`,
1170
1272
  ]
1171
1273
  : []),
@@ -1182,7 +1284,8 @@ class LlEmitter {
1182
1284
  ...(asyncEntry ? [` call void @scr_promise_release(ptr %top)`] : []),
1183
1285
  ...exitListenerLines("xl"),
1184
1286
  ...loopReleasesU,
1185
- ` ret i32 1`,
1287
+ ` %failure_code_1 = call i32 @scr_exit_code_hint_get()`,
1288
+ ` ret i32 %failure_code_1`,
1186
1289
  `lok:`,
1187
1290
  ` br i1 %loop_rejection, label %lreported, label %lclean`,
1188
1291
  `lreported:`,
@@ -1190,7 +1293,8 @@ class LlEmitter {
1190
1293
  ...(asyncEntry ? [` call void @scr_promise_release(ptr %top)`] : []),
1191
1294
  ...exitListenerLines("xq"),
1192
1295
  ...loopReportedReleases,
1193
- ` ret i32 1`,
1296
+ ` %failure_code_2 = call i32 @scr_exit_code_hint_get()`,
1297
+ ` ret i32 %failure_code_2`,
1194
1298
  `lclean:`,
1195
1299
  ...(asyncEntry
1196
1300
  ? [
@@ -1207,7 +1311,8 @@ class LlEmitter {
1207
1311
  ` call void @scr_exc_print_uncaught()`,
1208
1312
  ...exitListenerLines("xt"),
1209
1313
  ...topRejectReleases,
1210
- ` ret i32 1`,
1314
+ ` %failure_code_3 = call i32 @scr_exit_code_hint_get()`,
1315
+ ` ret i32 %failure_code_3`,
1211
1316
  `tla_not_rejected:`,
1212
1317
  ` call void @scr_promise_release(ptr %top)`,
1213
1318
  ]
@@ -1217,7 +1322,8 @@ class LlEmitter {
1217
1322
  `lrej:`,
1218
1323
  ...exitListenerLines("xr"),
1219
1324
  ...loopReleasesR,
1220
- ` ret i32 1`,
1325
+ ` %failure_code_4 = call i32 @scr_exit_code_hint_get()`,
1326
+ ` ret i32 %failure_code_4`,
1221
1327
  `lrok:`,
1222
1328
  ...(asyncEntry
1223
1329
  ? [
@@ -1271,11 +1377,15 @@ class LlEmitter {
1271
1377
  for (const e of lib.exports)
1272
1378
  emitSymConst(e.symbol);
1273
1379
  out.push(``);
1380
+ if (this.wasi) {
1381
+ for (const symbol of ["scriptc_alloc", "scriptc_free"])
1382
+ emitSymConst(symbol);
1383
+ out.push(`define ptr @scriptc_alloc(i32 %size) ${FN_ATTRS} {`, `entry:`, ` call void @scr_library_entry(i1 zeroext false, ptr ${symConst("scriptc_alloc")})`, ` %p = call ptr @malloc(i32 %size)`, ` ret ptr %p`, `}`, ``, `define void @scriptc_free(ptr %p) ${FN_ATTRS} {`, `entry:`, ` call void @scr_library_entry(i1 zeroext false, ptr ${symConst("scriptc_free")})`, ` call void @free(ptr %p)`, ` ret void`, `}`, ``);
1384
+ }
1274
1385
  // The runtime detected-trap overlay table (scr_runtime.h declares it,
1275
1386
  // the library trap funnel consults it): flat code/teaching/remediation
1276
1387
  // triples, one per runtime trap code (SC4013–SC4019) the profile
1277
- // declares text for — the same data the C emission defines, so the
1278
- // funnel-assembled sink message is emission-invariant by construction.
1388
+ // declares text for. The funnel assembles the structured sink message.
1279
1389
  // The empty table still defines the symbols the funnel links against.
1280
1390
  const ovlCells = [];
1281
1391
  lib.trapOverlays.forEach((o, i) => {
@@ -1309,8 +1419,8 @@ class LlEmitter {
1309
1419
  // Host-callback channels: the per-channel name constants (the
1310
1420
  // registration dispatch's strcmp operands), the per-channel
1311
1421
  // unregistered-call trap constants (the ffiCall sites'
1312
- // scr_library_cb_require operands — same bytes as the C emission by
1313
- // construction), and the registration define: a pure store dispatch
1422
+ // scr_library_cb_require operands), and the registration function:
1423
+ // a pure store dispatch
1314
1424
  // (the sink registration's rule — no entry prologue, no poison
1315
1425
  // guard) whose first operation rejects callback-time re-entry
1316
1426
  // (SC4026). An unknown or NULL name is a defined -1, never a store.
@@ -1330,7 +1440,8 @@ class LlEmitter {
1330
1440
  // from the poisoned guard and every runtime touch (ratified), so a
1331
1441
  // host can read them before init and after a trap. The u64 rides
1332
1442
  // i64 two's-complement (LLVM integer constants are signed).
1333
- out.push(...emitLibraryIdentityLines("llvm", lib.identity, FN_ATTRS));
1443
+ for (const line of emitLibraryIdentityLines(lib.identity, FN_ATTRS))
1444
+ out.push(line);
1334
1445
  }
1335
1446
  if (lib.resultResetSymbol !== null) {
1336
1447
  out.push(`define void @${lib.resultResetSymbol}() ${FN_ATTRS} {`, `entry:`, ` call void @scr_library_entry(i1 zeroext false, ptr ${symConst(lib.resultResetSymbol)})`, ` call void @scr_library_arena_reset()`, ` ret void`, `}`, ``);
@@ -1345,8 +1456,7 @@ class LlEmitter {
1345
1456
  if (e.inboundBytesTrap !== undefined) {
1346
1457
  // The bytes-in helper's trap message: the compiler-assembled
1347
1458
  // structured trap-teaching form (0x01 text 0x1F SC4012 0x1F symbol
1348
- // [0x1F remediation]) — the same bytes the C emission passes, so
1349
- // the sink message is emission-invariant by construction.
1459
+ // [0x1F remediation]) consumed by the runtime sink.
1350
1460
  const trapBytes = Buffer.byteLength(e.inboundBytesTrap, "utf8");
1351
1461
  out.push(`@sc_lib_bytes_trap_${e.symbol} = internal constant [${trapBytes + 1} x i8] c"${llStrBytes(e.inboundBytesTrap)}"`, ``);
1352
1462
  }
@@ -1450,7 +1560,7 @@ class LlEmitter {
1450
1560
  }
1451
1561
  /** The shared abort helpers (emitted only when referenced): the OOM
1452
1562
  * abort of untraced shape allocation and the invalid-union-tag abort —
1453
- * both print the C emitter's exact message on fd 2 and abort. */
1563
+ * both print the runtime ABI’s exact message on fd 2 and abort. */
1454
1564
  helperDefs() {
1455
1565
  const defs = [];
1456
1566
  const msgHelper = (fnName, msgSym, msg) => {
@@ -1485,7 +1595,7 @@ class LlEmitter {
1485
1595
  return defs.length > 0 ? [...defs] : defs;
1486
1596
  }
1487
1597
  /** Env-signature wrappers + interned immortal closures for declared
1488
- * functions used as values (the C emitter's sc_w_/sc_fc_ pair): every
1598
+ * functions used as values (the runtime ABI’s sc_w_/sc_fc_ pair): every
1489
1599
  * mention of `f` yields the same pointer, so `f === f` holds. */
1490
1600
  emitFnValueDefs() {
1491
1601
  const out = [];
@@ -1498,7 +1608,7 @@ class LlEmitter {
1498
1608
  // never the inner return type.
1499
1609
  const ret = fn.async === true || fn.generator !== undefined ? "ptr" : this.llType(fn.returnType);
1500
1610
  const call = `call ${ret} @${this.callTarget(name)}(${args})`;
1501
- out.push(`define internal ${ret} @${mangleWrapper(name)}(ptr %env${params.length ? ", " + params.join(", ") : ""}) ${FN_ATTRS} { ; ${name} as a value`, `entry:`, ret === "void" ? ` ${call}` : ` %r = ${call}`, ret === "void" ? ` ret void` : ` ret ${ret} %r`, `}`, `@${mangleFnClosure(name)} = internal global %ScrClosure { ${this.sizeType} -1, ptr @${mangleWrapper(name)}, ${this.sizeType} 0, ptr null }`, ``);
1611
+ out.push(`define internal ${ret} @${mangleWrapper(name)}(ptr %env${params.length ? ", " + params.join(", ") : ""}) ${FN_ATTRS} { ; ${name} as a value`, `entry:`, ret === "void" ? ` ${call}` : ` %r = ${call}`, ret === "void" ? ` ret void` : ` ret ${ret} %r`, `}`, `@${mangleFnClosure(name)} = internal global %ScrClosure { ${this.sizeType} -1, ptr @${mangleWrapper(name)}, ${this.sizeType} 0, ptr null, i32 ${(fn.generator ? 1 : 0) + (fn.async ? 2 : 0) + (fn.ownsPrototype ? 4 : 0)} }`, ``);
1502
1612
  }
1503
1613
  return out;
1504
1614
  }
@@ -1570,7 +1680,8 @@ class LlEmitter {
1570
1680
  if (fn.async !== true || fn.generator !== undefined)
1571
1681
  continue;
1572
1682
  const { definitions, ret, tr, spawnParams, argPackLines } = this.emitArgPackAndTrampolinePrologue(fn);
1573
- out.push(...definitions);
1683
+ for (const line of definitions)
1684
+ out.push(line);
1574
1685
  this.declare(`declare ptr @scr_fiber_promise(ptr)`);
1575
1686
  this.declare(`declare ptr @scr_async_spawn(ptr, ptr)`);
1576
1687
  this.needOom();
@@ -1603,20 +1714,25 @@ class LlEmitter {
1603
1714
  this.declare(`declare void @scr_promise_fulfill_str(ptr, ptr)`);
1604
1715
  tr.push(` call void @scr_promise_fulfill_str(ptr %pr, ptr %r) ; moves in`);
1605
1716
  break;
1717
+ case "dyn":
1718
+ this.declare(`declare void @scr_promise_resolve_dyn(ptr, ptr)`);
1719
+ tr.push(` call void @scr_promise_resolve_dyn(ptr %pr, ptr %r) ; moves in`);
1720
+ break;
1606
1721
  default: {
1607
- const v = vAdapters(this, ret);
1722
+ const v = vAdapters(this.shapeHost, ret);
1608
1723
  this.declare(`declare void @scr_promise_fulfill_ref(ptr, ptr, ptr, ptr, ptr)`);
1609
- tr.push(` call void @scr_promise_fulfill_ref(ptr %pr, ptr %r, ptr ${v.retain}, ptr ${v.release}, ptr ${traceArg(this, ret)})`);
1724
+ tr.push(` call void @scr_promise_fulfill_ref(ptr %pr, ptr %r, ptr ${v.retain}, ptr ${v.release}, ptr ${traceArg(this.shapeHost, ret)})`);
1610
1725
  }
1611
1726
  }
1612
1727
  tr.push(` ret void`, `thrown:`);
1613
1728
  if (ret.kind !== "void" && isRefCounted(ret)) {
1614
1729
  // An escaping throw means %r is the never-read dummy (NULL).
1615
- tr.push(` call void ${releaseSym(this, ret)}(ptr %r)`);
1730
+ tr.push(` call void ${releaseSym(this.shapeHost, ret)}(ptr %r)`);
1616
1731
  }
1617
1732
  tr.push(` ret void`, `}`, ``);
1618
1733
  }
1619
- out.push(...tr);
1734
+ for (const line of tr)
1735
+ out.push(line);
1620
1736
  // Spawn wrapper: pack the args (+1 moves in), spawn the fiber.
1621
1737
  const cache = fn.asyncCacheGlobal !== undefined ? mangleGlobal(fn.asyncCacheGlobal) : null;
1622
1738
  const cycleCache = fn.asyncCycleCacheGlobal !== undefined ? mangleGlobal(fn.asyncCycleCacheGlobal) : null;
@@ -1676,9 +1792,11 @@ class LlEmitter {
1676
1792
  ` store ptr %cycle_cache_owned, ptr @${cycleCache}`,
1677
1793
  ]
1678
1794
  : []), ` ret ptr %p`, `}`, ``);
1679
- out.push(...sp);
1795
+ for (const line of sp)
1796
+ out.push(line);
1680
1797
  }
1681
- out.push(...this.emitGenScaffolding());
1798
+ for (const line of this.emitGenScaffolding())
1799
+ out.push(line);
1682
1800
  return out;
1683
1801
  }
1684
1802
  /** Per-generator-function machinery — the async scaffolding's lazy
@@ -1693,7 +1811,8 @@ class LlEmitter {
1693
1811
  if (fn.generator === undefined)
1694
1812
  continue;
1695
1813
  const { definitions, pack, lifted, fieldTys, ret, tr, spawnParams, argPackLines, } = this.emitArgPackAndTrampolinePrologue(fn);
1696
- out.push(...definitions);
1814
+ for (const line of definitions)
1815
+ out.push(line);
1697
1816
  this.declare(`declare zeroext i1 @scr_exc_genret_pending()`);
1698
1817
  this.declare(`declare void @scr_exc_clear()`);
1699
1818
  this.declare(`declare ptr @scr_gen_of_fiber(ptr)`);
@@ -1726,18 +1845,19 @@ class LlEmitter {
1726
1845
  tr.push(` call void @scr_gen_out_bool(ptr %g, i1 %r)`, ` br label %done`);
1727
1846
  break;
1728
1847
  default: {
1729
- const v = vAdapters(this, ret);
1848
+ const v = vAdapters(this.shapeHost, ret);
1730
1849
  this.declare(`declare void @scr_gen_out_ref(ptr, ptr, ptr)`);
1731
1850
  tr.push(` call void @scr_gen_out_ref(ptr %g, ptr %r, ptr ${v.release})`, ` br label %done`);
1732
1851
  }
1733
1852
  }
1734
1853
  tr.push(`thrown:`, ` %genret = call zeroext i1 @scr_exc_genret_pending()`, ` br i1 %genret, label %promote, label %dropdummy`, `promote:`, ` call void @scr_exc_clear()`, ` call void @scr_gen_ret_to_out(ptr %g)`, ` br label %dropdummy`, `dropdummy:`);
1735
1854
  if (ret.kind !== "void" && isRefCounted(ret)) {
1736
- tr.push(` call void ${releaseSym(this, ret)}(ptr %r) ; unwound: the never-read dummy`);
1855
+ tr.push(` call void ${releaseSym(this.shapeHost, ret)}(ptr %r) ; unwound: the never-read dummy`);
1737
1856
  }
1738
1857
  tr.push(` br label %done`, `done:`, ` ret void`, `}`, ``);
1739
1858
  }
1740
- out.push(...tr);
1859
+ for (const line of tr)
1860
+ out.push(line);
1741
1861
  let settleAsync = null;
1742
1862
  if (fn.async) {
1743
1863
  this.declare(`declare ptr @scr_async_gen_new(ptr, ptr, ptr, ptr)`);
@@ -1754,8 +1874,8 @@ class LlEmitter {
1754
1874
  const settleKey = `ags:${typeKey(genT)}`;
1755
1875
  if (!this.resolveThunks.has(settleKey)) {
1756
1876
  this.resolveThunks.set(settleKey, settleAsync);
1757
- const adapters = vAdapters(this, resultT);
1758
- this.resolveThunkDefs.push(`define internal void @${settleAsync}(ptr %g, ptr %p) ${FN_ATTRS} {`, `entry:`, ` %r = call ptr @${build}(ptr %g)`, ` call void @scr_promise_fulfill_ref(ptr %p, ptr %r, ptr ${adapters.retain}, ptr ${adapters.release}, ptr ${traceArg(this, resultT)})`, ` ret void`, `}`, ``);
1877
+ const adapters = vAdapters(this.shapeHost, resultT);
1878
+ this.resolveThunkDefs.push(`define internal void @${settleAsync}(ptr %g, ptr %p) ${FN_ATTRS} {`, `entry:`, ` %r = call ptr @${build}(ptr %g)`, ` call void @scr_promise_fulfill_ref(ptr %p, ptr %r, ptr ${adapters.retain}, ptr ${adapters.release}, ptr ${traceArg(this.shapeHost, resultT)})`, ` ret void`, `}`, ``);
1759
1879
  }
1760
1880
  this.declare(`declare void @scr_promise_fulfill_ref(ptr, ptr, ptr, ptr, ptr)`);
1761
1881
  }
@@ -1775,11 +1895,12 @@ class LlEmitter {
1775
1895
  dr.push(` call void @scr_closure_release(ptr %dv${i})`);
1776
1896
  }
1777
1897
  else {
1778
- dr.push(` call void ${releaseSym(this, pType)}(ptr %dv${i})`);
1898
+ dr.push(` call void ${releaseSym(this.shapeHost, pType)}(ptr %dv${i})`);
1779
1899
  }
1780
1900
  });
1781
1901
  dr.push(` call void @free(ptr %ap)`, ` ret void`, `}`, ``);
1782
- out.push(...dr);
1902
+ for (const line of dr)
1903
+ out.push(line);
1783
1904
  // Spawn wrapper: pack the args (+1 moves in), allocate the
1784
1905
  // SUSPENDED fiber — nothing runs until the first .next().
1785
1906
  if (lifted) {
@@ -1793,11 +1914,12 @@ class LlEmitter {
1793
1914
  sp.push(settleAsync === null
1794
1915
  ? ` %gg = call ptr @scr_gen_new(ptr @${mangleTrampoline(fn.name)}, ptr %ap, ptr @${mangleGenDrop(fn.name)})`
1795
1916
  : ` %gg = call ptr @scr_async_gen_new(ptr @${mangleTrampoline(fn.name)}, ptr %ap, ptr @${mangleGenDrop(fn.name)}, ptr @${settleAsync})`, ` ret ptr %gg`, `}`, ``);
1796
- out.push(...sp);
1917
+ for (const line of sp)
1918
+ out.push(line);
1797
1919
  }
1798
1920
  return out;
1799
1921
  }
1800
- // ── plumbing (the CEmitter frame/scope machinery, alloca-flavored) ──────
1922
+ // ── plumbing (frame and scope ownership) ──────
1801
1923
  internLiteral(text) {
1802
1924
  let lit = this.literals.get(text);
1803
1925
  if (!lit) {
@@ -1877,20 +1999,26 @@ class LlEmitter {
1877
1999
  * the `_v` table (immortals skip, exactly the C retain calls). */
1878
2000
  retainValue(name, type) {
1879
2001
  const t = this.B.tmp();
1880
- this.B.line(`${t} = call ptr ${retainSym(this, type)}(ptr ${name})`);
2002
+ this.B.line(`${t} = call ptr ${retainSym(this.shapeHost, type)}(ptr ${name})`);
1881
2003
  return t;
1882
2004
  }
1883
2005
  /** The release call for one owned refcounted value — type-directed like
1884
2006
  * releaseCallC (all runtime releases are NULL-tolerant). */
1885
2007
  releaseValue(name, type) {
1886
- this.B.line(`call void ${releaseSym(this, type)}(ptr ${name})`);
2008
+ this.B.line(`call void ${releaseSym(this.shapeHost, type)}(ptr ${name})`);
1887
2009
  }
1888
2010
  releaseFrame(frame) {
1889
2011
  for (const v of frame) {
1890
2012
  if (v.slot) {
1891
2013
  const t = this.B.tmp();
1892
2014
  this.B.line(`${t} = load ptr, ptr ${v.name}`);
1893
- this.releaseValue(t, v.type);
2015
+ if (v.boxed) {
2016
+ this.declare(`declare void @scr_box_release(ptr)`);
2017
+ this.B.line(`call void @scr_box_release(ptr ${t})`);
2018
+ }
2019
+ else {
2020
+ this.releaseValue(t, v.type);
2021
+ }
1894
2022
  }
1895
2023
  else {
1896
2024
  this.releaseValue(v.name, v.type);
@@ -1913,7 +2041,7 @@ class LlEmitter {
1913
2041
  /** THE release-on-jump path (break/continue/return): pending statement
1914
2042
  * frames and entered scopes down to the given depths, innermost first —
1915
2043
  * everything whose normal fall-through releases the jump bypasses.
1916
- * Ported verbatim from CEmitter.releaseForJump. */
2044
+ * Release every scope crossed by the control-flow edge. */
1917
2045
  releaseForJump(frameDepth, scopeDepth) {
1918
2046
  for (let i = this.frames.length - 1; i >= frameDepth; i--)
1919
2047
  this.releaseFrame(this.frames[i]);
@@ -1953,29 +2081,47 @@ class LlEmitter {
1953
2081
  * function — and branch to the handler / return a dummy value (never
1954
2082
  * read: callers of a may-throw function test the pending flag before
1955
2083
  * using the result). Callers own the surrounding pending branch; a
1956
- * `throw` unwinds unconditionally. CEmitter.emitUnwind, block-flavored. */
2084
+ * `throw` unwinds unconditionally. */
1957
2085
  emitUnwind() {
1958
2086
  const target = this.tryStack[this.tryStack.length - 1];
2087
+ const frameDepth = target?.frameDepth ?? 0;
2088
+ const scopeDepth = target?.scopeDepth ?? 0;
2089
+ for (let i = this.frames.length - 1; i >= frameDepth; i--)
2090
+ this.releaseFrame(this.frames[i]);
2091
+ let terminator;
1959
2092
  if (target) {
1960
- this.releaseForJump(target.frameDepth, target.scopeDepth);
1961
2093
  target.used = true;
1962
- this.B.terminate(`br label %${target.label}`);
1963
- return;
2094
+ terminator = `br label %${target.label}`;
1964
2095
  }
1965
- this.releaseForJump(0, 0);
1966
- if (this.currentWasiCoro !== null) {
1967
- this.B.terminate(`br label %${this.currentWasiCoro.finalLabel}`);
2096
+ else if (this.currentWasiCoro !== null) {
2097
+ terminator = `br label %${this.currentWasiCoro.finalLabel}`;
2098
+ }
2099
+ else {
2100
+ const t = this.currentReturnType;
2101
+ terminator = t.kind === "void" ? "ret void"
2102
+ : t.kind === "f64" || t.kind === "date" ? `ret double ${f64Lit(0)}`
2103
+ : t.kind === "bool" ? "ret i1 false" : "ret ptr null";
2104
+ }
2105
+ // Copy the entries now: later declarations extend these lexical scopes.
2106
+ // Release order and the handler are part of the shared block's identity.
2107
+ const entries = [];
2108
+ let key = terminator;
2109
+ for (let i = this.scopes.length - 1; i >= scopeDepth; i--) {
2110
+ for (const entry of this.scopes[i]) {
2111
+ entries.push(entry);
2112
+ key += `\0${entry.slot}\0${entry.boxed ? "@scr_box_release" : releaseSym(this.shapeHost, entry.type)}`;
2113
+ }
2114
+ }
2115
+ if (entries.length === 0) {
2116
+ this.B.terminate(terminator);
1968
2117
  return;
1969
2118
  }
1970
- const t = this.currentReturnType;
1971
- if (t.kind === "void")
1972
- this.B.terminate("ret void");
1973
- else if (t.kind === "f64" || t.kind === "date")
1974
- this.B.terminate(`ret double ${f64Lit(0)}`);
1975
- else if (t.kind === "bool")
1976
- this.B.terminate("ret i1 false");
1977
- else
1978
- this.B.terminate("ret ptr null");
2119
+ let cleanup = this.unwindCleanups.get(key);
2120
+ if (!cleanup) {
2121
+ cleanup = { label: this.B.newLabel("exc.cleanup"), entries, terminator };
2122
+ this.unwindCleanups.set(key, cleanup);
2123
+ }
2124
+ this.B.br(cleanup.label);
1979
2125
  }
1980
2126
  /** The emitter contract for exceptions: after EVERY call that can throw
1981
2127
  * (per the may-throw analysis), test the pending flag and unwind. The
@@ -2021,28 +2167,32 @@ class LlEmitter {
2021
2167
  // Hierarchy instances carry a vtable word: the OBJ kind keeps the
2022
2168
  // dynamic class inspectable (catch-binding instanceof, the uncaught
2023
2169
  // printer's "name: message" for Error instances).
2024
- const rc = vAdapters(this, t);
2170
+ const rc = vAdapters(this.shapeHost, t);
2025
2171
  this.declare(`declare void @scr_throw_obj(ptr, ptr, ptr, ptr)`);
2026
- B.line(`call void @scr_throw_obj(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this, t)})`);
2172
+ B.line(`call void @scr_throw_obj(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this.shapeHost, t)})`);
2027
2173
  }
2028
2174
  else if (t.kind === "symbol" || t.kind === "bigint" || t.kind === "func" || t.kind === "classval") {
2029
- const rc = vAdapters(this, t);
2175
+ const rc = vAdapters(this.shapeHost, t);
2030
2176
  this.declare(`declare void @scr_throw_primitive_ref(ptr, ptr, ptr, ptr)`);
2031
2177
  B.line(`call void @scr_throw_primitive_ref(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr null)`);
2032
2178
  }
2033
- else if (t.kind === "dyn" || t.kind === "jsval") {
2034
- const rc = vAdapters(this, t);
2035
- const test = t.kind === "dyn" ? "scr_dyn_is_object" : "scr_jsval_is_object";
2179
+ else if (t.kind === "dyn") {
2180
+ this.declare(`declare void @scr_dyn_throw(ptr)`);
2181
+ B.line(`call void @scr_dyn_throw(ptr ${v.name})`);
2182
+ }
2183
+ else if (t.kind === "jsval") {
2184
+ const rc = vAdapters(this.shapeHost, t);
2185
+ const test = "scr_jsval_is_object";
2036
2186
  this.declare(`declare zeroext i1 @${test}(ptr)`);
2037
2187
  this.declare(`declare void @scr_throw_ref_classified(ptr, ptr, ptr, ptr, i1 zeroext)`);
2038
2188
  const object = B.tmp();
2039
2189
  B.line(`${object} = call zeroext i1 @${test}(ptr ${v.name})`);
2040
- B.line(`call void @scr_throw_ref_classified(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this, t)}, i1 zeroext ${object})`);
2190
+ B.line(`call void @scr_throw_ref_classified(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this.shapeHost, t)}, i1 zeroext ${object})`);
2041
2191
  }
2042
2192
  else {
2043
- const rc = vAdapters(this, t);
2193
+ const rc = vAdapters(this.shapeHost, t);
2044
2194
  this.declare(`declare void @scr_throw_ref(ptr, ptr, ptr, ptr)`);
2045
- B.line(`call void @scr_throw_ref(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this, t)})`);
2195
+ B.line(`call void @scr_throw_ref(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this.shapeHost, t)})`);
2046
2196
  }
2047
2197
  }
2048
2198
  /** JS truthiness of a value (falsy: false, 0, -0, NaN, "", nullish
@@ -2052,7 +2202,7 @@ class LlEmitter {
2052
2202
  truthy(v) {
2053
2203
  const B = this.B;
2054
2204
  if (v.type.kind === "union") {
2055
- // The ARM value's ToBoolean: an inline tag switch (the C emitter's
2205
+ // The ARM value's ToBoolean: an inline tag switch (the runtime ABI’s
2056
2206
  // per-union interned helper, emitted at the use site instead).
2057
2207
  const def = this.unionsById.get(v.type.unionId);
2058
2208
  if (!def)
@@ -2062,7 +2212,7 @@ class LlEmitter {
2062
2212
  const join = B.newLabel("ut.j");
2063
2213
  this.unionTagSwitch(v.name, def, (arm) => {
2064
2214
  let valueName = "false";
2065
- if (arm.kind === "f64") {
2215
+ if (arm.kind === "f64" || arm.kind === "procStream") {
2066
2216
  valueName = B.tmp();
2067
2217
  this.declare(`declare double @scr_union_get_f64(ptr)`);
2068
2218
  B.line(`${valueName} = call double @scr_union_get_f64(ptr ${v.name})`);
@@ -2075,7 +2225,7 @@ class LlEmitter {
2075
2225
  else if (arm.kind === "string") {
2076
2226
  valueName = this.unionPeek(v.name);
2077
2227
  }
2078
- else if (arm.kind === "bigint") {
2228
+ else if (arm.kind === "bigint" || arm.kind === "dyn" || arm.kind === "jsval") {
2079
2229
  valueName = this.unionPeek(v.name);
2080
2230
  }
2081
2231
  const truthy = this.truthyOf(arm.kind, valueName, true);
@@ -2096,15 +2246,10 @@ class LlEmitter {
2096
2246
  switch (kind) {
2097
2247
  case "undefinedT":
2098
2248
  case "nullT":
2099
- if (!unionArm)
2100
- throw new LlvmUnsupportedError(`truthy:${kind}`);
2101
2249
  return "false";
2102
2250
  case "bool":
2103
2251
  return valueName;
2104
- case "f64":
2105
- case "procStream": {
2106
- if (unionArm && kind === "procStream")
2107
- throw new LlvmUnsupportedError(`truthy:union:${kind}`);
2252
+ case "f64": {
2108
2253
  const truthy = B.tmp();
2109
2254
  B.line(`${truthy} = fcmp one double ${valueName}, ${f64Lit(0)}`);
2110
2255
  return truthy;
@@ -2125,6 +2270,9 @@ class LlEmitter {
2125
2270
  return truthy;
2126
2271
  }
2127
2272
  case "date":
2273
+ // Process streams use a numeric descriptor internally, including zero
2274
+ // for stdin. They remain JavaScript objects in boolean contexts.
2275
+ case "procStream":
2128
2276
  return "true";
2129
2277
  case "array":
2130
2278
  case "record":
@@ -2148,7 +2296,17 @@ class LlEmitter {
2148
2296
  case "generator":
2149
2297
  case "fsWatcher":
2150
2298
  case "cryptoHash":
2151
- case "cryptoHmac": {
2299
+ case "cryptoHmac":
2300
+ case "netSocket":
2301
+ case "netServer":
2302
+ case "httpReq":
2303
+ case "httpRes":
2304
+ case "httpClientReq":
2305
+ case "http2Session":
2306
+ case "http2Stream":
2307
+ case "dgramSocket":
2308
+ case "secureCtx":
2309
+ case "testCtx": {
2152
2310
  if (unionArm)
2153
2311
  return "true";
2154
2312
  const truthy = B.tmp();
@@ -2156,16 +2314,12 @@ class LlEmitter {
2156
2314
  return truthy;
2157
2315
  }
2158
2316
  case "dyn": {
2159
- if (unionArm)
2160
- throw new LlvmUnsupportedError(`truthy:union:${kind}`);
2161
2317
  this.declare(`declare zeroext i1 @scr_dyn_truthy(ptr)`);
2162
2318
  const truthy = B.tmp();
2163
2319
  B.line(`${truthy} = call zeroext i1 @scr_dyn_truthy(ptr ${valueName})`);
2164
2320
  return truthy;
2165
2321
  }
2166
2322
  case "jsval": {
2167
- if (unionArm)
2168
- throw new LlvmUnsupportedError(`truthy:union:${kind}`);
2169
2323
  this.declare(`declare i32 @scr_jsval_truthy(ptr)`);
2170
2324
  const raw = B.tmp();
2171
2325
  const truthy = B.tmp();
@@ -2197,17 +2351,48 @@ class LlEmitter {
2197
2351
  }
2198
2352
  /** Emits `switch` over a union's tag with one block per arm; each arm
2199
2353
  * body must TERMINATE its block (the callers branch to a join). The
2200
- * default block is the C emitter's invalid-tag abort. */
2201
- unionTagSwitch(uName, def, arm) {
2354
+ * default block is the runtime ABI’s invalid-tag abort. Shared field
2355
+ * reads can group equivalent storage prefixes and emit one representative. */
2356
+ unionTagSwitch(uName, def, arm, fieldGroups) {
2202
2357
  const B = this.B;
2203
2358
  const tag = this.unionTag(uName);
2204
2359
  const bad = B.newLabel("u.bad");
2205
- const labels = def.arms.map(() => B.newLabel("u.a"));
2206
- B.terminate(`switch i32 ${tag}, label %${bad} [ ${def.arms.map((_, i) => `i32 ${i}, label %${labels[i]}`).join(" ")} ]`);
2207
- def.arms.forEach((a, i) => {
2208
- B.startBlock(labels[i]);
2209
- arm(a, i);
2210
- });
2360
+ const labels = [];
2361
+ if (fieldGroups) {
2362
+ for (const group of fieldGroups) {
2363
+ const label = B.newLabel("u.a");
2364
+ for (const member of group) {
2365
+ if (member === undefined)
2366
+ throw new InternalCompilerError("llvm emitter bug: missing union field tag");
2367
+ labels[member] = label;
2368
+ }
2369
+ }
2370
+ }
2371
+ else {
2372
+ for (let i = 0; i < def.arms.length; i++)
2373
+ labels.push(B.newLabel("u.a"));
2374
+ }
2375
+ if (fieldGroups?.length === 1) {
2376
+ const valid = B.tmp();
2377
+ B.line(`${valid} = icmp ult i32 ${tag}, ${def.arms.length}`);
2378
+ B.condBr(valid, labels[0], bad);
2379
+ }
2380
+ else {
2381
+ B.terminate(`switch i32 ${tag}, label %${bad} [ ${def.arms.map((_, i) => `i32 ${i}, label %${labels[i]}`).join(" ")} ]`);
2382
+ }
2383
+ if (fieldGroups) {
2384
+ for (const group of fieldGroups) {
2385
+ const representative = group[0];
2386
+ B.startBlock(labels[representative]);
2387
+ arm(def.arms[representative], representative);
2388
+ }
2389
+ }
2390
+ else {
2391
+ def.arms.forEach((a, i) => {
2392
+ B.startBlock(labels[i]);
2393
+ arm(a, i);
2394
+ });
2395
+ }
2211
2396
  B.startBlock(bad);
2212
2397
  this.needsBadTag = true;
2213
2398
  B.line(`call void @sc_bad_tag()`);
@@ -2248,9 +2433,9 @@ class LlEmitter {
2248
2433
  B.line(`${t} = call ptr @scr_union_new_bool(i32 ${tag}, i1 ${v.name})`);
2249
2434
  return t;
2250
2435
  }
2251
- const rc = vAdapters(this, v.type);
2436
+ const rc = vAdapters(this.shapeHost, v.type);
2252
2437
  this.declare(`declare ptr @scr_union_new_ref(i32, ptr, ptr, ptr, ptr)`);
2253
- B.line(`${t} = call ptr @scr_union_new_ref(i32 ${tag}, ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this, v.type)})`);
2438
+ B.line(`${t} = call ptr @scr_union_new_ref(i32 ${tag}, ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this.shapeHost, v.type)})`);
2254
2439
  return t;
2255
2440
  }
2256
2441
  // ── class plumbing ──────────────────────────────────────────────────────
@@ -2263,7 +2448,7 @@ class LlEmitter {
2263
2448
  /** The field-slot pointer of a class member: rc at 0, the vtable word at
2264
2449
  * 1 on hierarchy members, then the flattened field list. Runtime error
2265
2450
  * classes GEP through %ScrError (their structs live in the runtime; the
2266
- * def's [name, message, %code] order matches the layout). */
2451
+ * def's [name, message, %code, %cause] order matches the layout). */
2267
2452
  classFieldPtr(objName, className, field) {
2268
2453
  const meta = this.classMetaOf(className);
2269
2454
  const { index, type } = classFieldIndex(meta, field);
@@ -2302,6 +2487,37 @@ class LlEmitter {
2302
2487
  throw new InternalCompilerError(`llvm emitter bug: unknown record shape ${shapeId}`);
2303
2488
  return shape;
2304
2489
  }
2490
+ /** Record prefixes with the same LLVM storage types put a field at the
2491
+ * same offset on every target. Share one field-read block per matching
2492
+ * prefix; class variants retain their own concrete layout dispatch. */
2493
+ unionFieldGroups(def, field) {
2494
+ const key = `${def.id}\0${field}`;
2495
+ const cached = this.unionFieldReadGroups.get(key);
2496
+ if (cached !== undefined)
2497
+ return cached;
2498
+ const groups = new Map();
2499
+ for (let tag = 0; tag < def.arms.length; tag++) {
2500
+ const arm = def.arms[tag];
2501
+ let layout = `variant:${tag}`;
2502
+ if (arm.kind === "record") {
2503
+ const shape = this.recordShape(arm.shapeId);
2504
+ const index = shape.fields.findIndex((entry) => entry.name === field);
2505
+ if (index < 0)
2506
+ throw new InternalCompilerError(`llvm emitter bug: missing union field ${field}`);
2507
+ layout = "record:";
2508
+ for (let i = 0; i <= index; i++)
2509
+ layout += `${llFieldType(shape.fields[i].type)};`;
2510
+ }
2511
+ const group = groups.get(layout);
2512
+ if (group)
2513
+ group.push(tag);
2514
+ else
2515
+ groups.set(layout, [tag]);
2516
+ }
2517
+ const result = [...groups.values()];
2518
+ this.unionFieldReadGroups.set(key, result);
2519
+ return result;
2520
+ }
2305
2521
  /** The field-slot pointer of a record member (rc header at index 0). */
2306
2522
  recordFieldPtr(objName, shapeId, field) {
2307
2523
  const shape = this.recordShape(shapeId);
@@ -2426,7 +2642,7 @@ class LlEmitter {
2426
2642
  const B = this.B;
2427
2643
  const acc = boxAccess(t);
2428
2644
  const cell = B.tmp();
2429
- B.line(`${cell} = ${arrNewCall(this, t, "1")} ; TDZ cell`);
2645
+ B.line(`${cell} = ${arrNewCall(this.shapeHost, t, "1")} ; TDZ cell`);
2430
2646
  this.arrPush(cell, acc === "bool" ? "bool" : "f64", value);
2431
2647
  this.declare(`declare void @scr_box_set_ref(ptr, ptr)`);
2432
2648
  B.line(`call void @scr_box_set_ref(ptr ${box}, ptr ${cell})`);
@@ -2435,7 +2651,7 @@ class LlEmitter {
2435
2651
  * the temporal dead zone — throw Node's exact catchable ReferenceError
2436
2652
  * (exprs.ts's varRef guard). Scalars then peek the one-element
2437
2653
  * array cell; ref kinds read the box normally (+1). */
2438
- tdzBoxRead(box, t, name) {
2654
+ checkTdz(box, name) {
2439
2655
  const B = this.B;
2440
2656
  const slotp = B.tmp();
2441
2657
  const slotv = B.tmp();
@@ -2443,6 +2659,22 @@ class LlEmitter {
2443
2659
  B.line(`${slotp} = getelementptr inbounds %ScrBox, ptr ${box}, i64 0, i32 5`);
2444
2660
  B.line(`${slotv} = load i64, ptr ${slotp}`);
2445
2661
  B.line(`${empty} = icmp eq i64 ${slotv}, 0`);
2662
+ this.throwIfUninitialized(empty, name);
2663
+ return slotv;
2664
+ }
2665
+ checkGlobalTdz(id) {
2666
+ const name = this.tdzGlobals.get(id);
2667
+ if (name === undefined)
2668
+ return;
2669
+ const B = this.B;
2670
+ const value = B.tmp();
2671
+ const empty = B.tmp();
2672
+ B.line(`${value} = load ptr, ptr @${mangleGlobal(id)}`);
2673
+ B.line(`${empty} = icmp eq ptr ${value}, null`);
2674
+ this.throwIfUninitialized(empty, name);
2675
+ }
2676
+ throwIfUninitialized(empty, name) {
2677
+ const B = this.B;
2446
2678
  const lt = B.newLabel("tdz.t");
2447
2679
  const lk = B.newLabel("tdz.k");
2448
2680
  B.condBr(empty, lt, lk);
@@ -2455,6 +2687,10 @@ class LlEmitter {
2455
2687
  B.line(`call void @scr_throw_error_named(ptr ${errName}, ptr ${msg})`);
2456
2688
  this.emitUnwind();
2457
2689
  B.startBlock(lk);
2690
+ }
2691
+ tdzBoxRead(box, t, name) {
2692
+ const slotv = this.checkTdz(box, name);
2693
+ const B = this.B;
2458
2694
  const acc = boxAccess(t);
2459
2695
  if (acc === "ref")
2460
2696
  return this.boxGet(box, t);
@@ -2468,12 +2704,34 @@ class LlEmitter {
2468
2704
  B.line(`${v} = call ${accTy} @scr_arr_get_${acc}(ptr ${cell}, double ${f64Lit(0)})`);
2469
2705
  return v;
2470
2706
  }
2707
+ /** Declaration stores initialize an empty TDZ box. Later stores check
2708
+ * it after the RHS and update scalar cells in place. References move in. */
2709
+ writeBindingBox(box, local, value, initializes = false, borrowed = false) {
2710
+ if (local.tdz) {
2711
+ const first = initializes || !local.mutable;
2712
+ const slotv = first ? null : this.checkTdz(box, local.name);
2713
+ const acc = boxAccess(local.type);
2714
+ if (acc !== "ref") {
2715
+ if (first)
2716
+ this.tdzScalarInit(box, local.type, value);
2717
+ else {
2718
+ const cell = this.B.tmp();
2719
+ this.B.line(`${cell} = inttoptr i64 ${slotv} to ptr`);
2720
+ const ty = acc === "bool" ? "i1" : "double";
2721
+ this.declare(`declare void @scr_arr_set_${acc}(ptr, double, ${acc === "bool" ? "i1 zeroext" : ty})`);
2722
+ this.B.line(`call void @scr_arr_set_${acc}(ptr ${cell}, double ${f64Lit(0)}, ${ty} ${value})`);
2723
+ }
2724
+ return;
2725
+ }
2726
+ }
2727
+ this.boxSet(box, local.type, borrowed && isRefCounted(local.type) ? this.retainValue(value, local.type) : value);
2728
+ }
2471
2729
  // ── functions ───────────────────────────────────────────────────────────
2472
2730
  /** The LLVM symbol a direct call or closure enters a function through:
2473
2731
  * async bodies are entered via their emitted spawn wrapper (which runs
2474
2732
  * the fiber eagerly to its first suspension and returns the promise);
2475
2733
  * generator bodies via theirs (which only ALLOCATES the suspended
2476
- * fiber and returns the generator object) — CEmitter.callTargetC. */
2734
+ * fiber and returns the generator object). */
2477
2735
  callTarget(fnName) {
2478
2736
  const fn = this.fnByName.get(fnName);
2479
2737
  if (fn?.generator !== undefined)
@@ -2537,7 +2795,7 @@ class LlEmitter {
2537
2795
  return;
2538
2796
  default:
2539
2797
  this.declare(`declare void @scr_gen_out_ref(ptr, ptr, ptr)`);
2540
- this.B.line(`call void @scr_gen_out_ref(ptr ${gen}, ptr ${v.name}, ptr ${vAdapters(this, ret).release})`);
2798
+ this.B.line(`call void @scr_gen_out_ref(ptr ${gen}, ptr ${v.name}, ptr ${vAdapters(this.shapeHost, ret).release})`);
2541
2799
  return;
2542
2800
  }
2543
2801
  }
@@ -2562,10 +2820,14 @@ class LlEmitter {
2562
2820
  this.declare(`declare void @scr_promise_fulfill_str(ptr, ptr)`);
2563
2821
  this.B.line(`call void @scr_promise_fulfill_str(ptr ${pr}, ptr ${v.name}) ; moves in`);
2564
2822
  break;
2823
+ case "dyn":
2824
+ this.declare(`declare void @scr_promise_resolve_dyn(ptr, ptr)`);
2825
+ this.B.line(`call void @scr_promise_resolve_dyn(ptr ${pr}, ptr ${v.name}) ; moves in`);
2826
+ break;
2565
2827
  default: {
2566
- const rc = vAdapters(this, ret);
2828
+ const rc = vAdapters(this.shapeHost, ret);
2567
2829
  this.declare(`declare void @scr_promise_fulfill_ref(ptr, ptr, ptr, ptr, ptr)`);
2568
- this.B.line(`call void @scr_promise_fulfill_ref(ptr ${pr}, ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this, ret)})`);
2830
+ this.B.line(`call void @scr_promise_fulfill_ref(ptr ${pr}, ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this.shapeHost, ret)})`);
2569
2831
  }
2570
2832
  }
2571
2833
  }
@@ -2576,9 +2838,10 @@ class LlEmitter {
2576
2838
  B.debugLocation = this.debug?.location(fn.loc, this.debugScope) ?? null;
2577
2839
  this.frames = [];
2578
2840
  this.scopes = [];
2841
+ this.unwindCleanups.clear();
2579
2842
  this.jumpTargets = [];
2580
2843
  this.currentLocals = new Map(fn.locals.map((l) => [l.id, l]));
2581
- this.captureIds = new Set((fn.captures ?? []).map((c) => c.localId));
2844
+ this.captureIds = new Set([...(fn.captures ?? []), ...(fn.classCaptures ?? [])].map((c) => c.localId));
2582
2845
  this.integerLoopBindings.clear();
2583
2846
  this.integerRanges = analyzeIntegerRanges(fn);
2584
2847
  this.chainSlots.clear();
@@ -2595,7 +2858,7 @@ class LlEmitter {
2595
2858
  this.declare(`declare token @llvm.coro.save(ptr)`);
2596
2859
  this.declare(`declare i8 @llvm.coro.suspend(token, i1)`);
2597
2860
  this.declare(`declare ptr @llvm.coro.free(token, ptr)`);
2598
- this.declare(`declare i1 @llvm.coro.end(ptr, i1, token)`);
2861
+ this.declare(`declare void @llvm.coro.end(ptr, i1, token)`);
2599
2862
  this.declare(`declare ptr @malloc(${this.sizeType})`);
2600
2863
  this.declare(`declare void @free(ptr)`);
2601
2864
  this.declare(`declare void @scr_wasi_coro_started(ptr)`);
@@ -2651,6 +2914,22 @@ class LlEmitter {
2651
2914
  B.line(`${box} = load ptr, ptr ${p}`);
2652
2915
  B.line(`store ptr ${box}, ptr %${mangleLocal(c.localId)} ; captured ${c.name}`);
2653
2916
  });
2917
+ (fn.classCaptures ?? []).forEach((c) => {
2918
+ const self = fn.params[0];
2919
+ if (self.type.kind !== "object")
2920
+ throw new InternalCompilerError("class captures require an instance receiver");
2921
+ const classSlot = B.tmp();
2922
+ const classValue = B.tmp();
2923
+ const caps = B.tmp();
2924
+ const slot = B.tmp();
2925
+ const box = B.tmp();
2926
+ B.line(`${classSlot} = getelementptr inbounds %${mangleClassStruct(self.type.className)}, ptr %p_${mangleLocal(self.localId)}, i64 0, i32 ${classEnvironmentIndex(this.classMeta.get(self.type.className))}`);
2927
+ B.line(`${classValue} = load ptr, ptr ${classSlot}`);
2928
+ B.line(`${caps} = getelementptr inbounds %ScrClassObj, ptr ${classValue}, i64 1`);
2929
+ B.line(`${slot} = getelementptr inbounds ptr, ptr ${caps}, ${this.sizeType} ${c.slot}`);
2930
+ B.line(`${box} = load ptr, ptr ${slot}`);
2931
+ B.line(`store ptr ${box}, ptr %${mangleLocal(c.localId)} ; class capture ${c.name}`);
2932
+ });
2654
2933
  // Params spill into their slots; the function scope owns refcounted
2655
2934
  // params (callees own their params — callers passed +1). Boxed params
2656
2935
  // allocate the shared binding and move the raw value in.
@@ -2660,7 +2939,7 @@ class LlEmitter {
2660
2939
  const slot = `%${mangleLocal(p.localId)}`;
2661
2940
  if (local.boxed) {
2662
2941
  const box = B.tmp();
2663
- B.line(`${box} = ${boxNewCall(this, p.type)} ; ${p.name} (boxed param)`);
2942
+ B.line(`${box} = ${boxNewCall(this.shapeHost, p.type)} ; ${p.name} (boxed param)`);
2664
2943
  this.boxSet(box, p.type, `%p_${mangleLocal(p.localId)}`);
2665
2944
  B.line(`store ptr ${box}, ptr ${slot}`);
2666
2945
  fnScope.push({ slot, type: p.type, boxed: true });
@@ -2671,6 +2950,16 @@ class LlEmitter {
2671
2950
  fnScope.push({ slot, type: p.type });
2672
2951
  }
2673
2952
  this.scopes.push(fnScope);
2953
+ // Stackful native fibers retain these frames while suspended. The
2954
+ // active exception context owns the chain, so concurrent fibers isolate it.
2955
+ if (this.stackTraces && !this.wasi && fn.sourceName !== undefined) {
2956
+ this.declare(`declare void @scr_stack_enter(ptr, ptr)`);
2957
+ this.declare(`declare void @scr_stack_leave(ptr)`);
2958
+ B.entryAllocas.push(`%source_frame = alloca { ptr, ptr }`);
2959
+ const frame = ` at ${fn.sourceName} (${fn.loc.file})`;
2960
+ B.line(`call void @scr_stack_enter(ptr %source_frame, ptr ${this.cstr(frame)})`);
2961
+ B.returnEpilogue = `call void @scr_stack_leave(ptr %source_frame)`;
2962
+ }
2674
2963
  this.emitStmts(fn.body);
2675
2964
  // Implicit exit of a void function: release the function scope unless
2676
2965
  // the body already terminated its final block (return, or a throw
@@ -2710,8 +2999,7 @@ class LlEmitter {
2710
2999
  B.line(`call void @free(ptr ${frame})`);
2711
3000
  B.br(coro.suspendLabel);
2712
3001
  B.startBlock(coro.suspendLabel);
2713
- const ended = B.tmp();
2714
- B.line(`${ended} = call i1 @llvm.coro.end(ptr ${coro.handle}, i1 false, token none)`);
3002
+ B.line(`call void @llvm.coro.end(ptr ${coro.handle}, i1 false, token none)`);
2715
3003
  const ret = this.llType(fn.returnType);
2716
3004
  if (ret === "void")
2717
3005
  B.terminate(`ret void`);
@@ -2722,6 +3010,14 @@ class LlEmitter {
2722
3010
  else
2723
3011
  B.terminate(`ret ptr null`);
2724
3012
  }
3013
+ // Shared blocks have multiple source locations. Keep the location on
3014
+ // each incoming exception check instead of assigning one to the cleanup.
3015
+ B.debugLocation = null;
3016
+ for (const cleanup of this.unwindCleanups.values()) {
3017
+ B.startBlock(cleanup.label);
3018
+ this.releaseScope(cleanup.entries);
3019
+ B.terminate(cleanup.terminator);
3020
+ }
2725
3021
  if (this.logArgSlots > 0) {
2726
3022
  B.entryAllocas.push(`%logargs = alloca [${this.logArgSlots} x %ScrLogArg]`);
2727
3023
  }
@@ -2738,15 +3034,15 @@ class LlEmitter {
2738
3034
  emitStmts(stmts) {
2739
3035
  for (const s of stmts) {
2740
3036
  // Statements after a terminator are unreachable (dead code after
2741
- // return/break/continue) — the C emitter emits them as dead C; here
2742
- // they are skipped so no dropped SSA definition can leak forward.
3037
+ // return/break/continue). Skip them so no dropped SSA definition
3038
+ // can leak forward.
2743
3039
  if (this.B.isTerminated())
2744
3040
  return;
2745
3041
  this.emitStmt(s);
2746
3042
  }
2747
3043
  }
2748
3044
  /** Emits a block in its own lexical scope (refcounted locals released at
2749
- * end) — CEmitter.emitBlock without the braces. `setup` runs after the
3045
+ * end). `setup` runs after the
2750
3046
  * scope opens, before the statements — the catch-binding hook: it may
2751
3047
  * emit prelude lines and register entries the scope owns (released on
2752
3048
  * every exit, jumps and unwinds included). */
@@ -2785,7 +3081,7 @@ class LlEmitter {
2785
3081
  // bit pattern to spend on it (stmts.ts's varDecl).
2786
3082
  const boxNew = b.local.tdz === true && boxAccess(b.type) !== "ref"
2787
3083
  ? (this.declare(`declare ptr @scr_box_new(i32)`), `call ptr @scr_box_new(i32 3)`)
2788
- : boxNewCall(this, b.type);
3084
+ : boxNewCall(this.shapeHost, b.type);
2789
3085
  const box = B.tmp();
2790
3086
  B.line(`${box} = ${boxNew} ; let ${b.local.name} (boxed)`);
2791
3087
  B.line(`store ptr ${box}, ptr ${b.slot}`);
@@ -2830,17 +3126,13 @@ class LlEmitter {
2830
3126
  }
2831
3127
  const b = this.binding(s.localId);
2832
3128
  const v = this.emitExpr(s.value);
3129
+ if (b.kind === "global" && !s.initializes)
3130
+ this.checkGlobalTdz(s.localId);
2833
3131
  if (b.kind === "boxed") {
3132
+ this.writeBindingBox(this.loadBox(b.slot), b.local, v.name, s.initializes);
3133
+ // The RHS remains frame-owned until a possible TDZ throw passes.
2834
3134
  if (isRefCounted(v.type))
2835
- this.moveTemp(v); // set_ref releases the old value
2836
- // A scalar TDZ box (forward-captured const): the initializing
2837
- // write mints the one-element array cell — set_ref moves it in
2838
- // (and the empty-slot sentinel ends here).
2839
- if (b.local.tdz === true && boxAccess(b.type) !== "ref") {
2840
- this.tdzScalarInit(this.loadBox(b.slot), b.type, v.name);
2841
- break;
2842
- }
2843
- this.boxSet(this.loadBox(b.slot), b.type, v.name);
3135
+ this.moveTemp(v);
2844
3136
  break;
2845
3137
  }
2846
3138
  this.moveTemp(v);
@@ -2899,8 +3191,8 @@ class LlEmitter {
2899
3191
  case "bytesSet": {
2900
3192
  // Typed-array element write: same evaluation order as arraySet;
2901
3193
  // the value is a scalar (the kind-specific inline path coerces
2902
- // JS-exactly), so no ownership moves. Any invalid index traps — no
2903
- // append. IrBytesElem is static, so never rediscover it through the
3194
+ // JS-exactly), so no ownership moves. Invalid writes are ignored.
3195
+ // IrBytesElem is static, so never rediscover it through the
2904
3196
  // generic runtime switch in a hot loop.
2905
3197
  const arr = this.emitStableReceiver(s.arr, [s.index, s.value]);
2906
3198
  const integerIndex = this.emitIntegerLoopIndex(s.index);
@@ -2933,6 +3225,17 @@ class LlEmitter {
2933
3225
  else {
2934
3226
  this.storeField(ptr, type, v.name);
2935
3227
  }
3228
+ if (s.kind === "fieldSet" && s.field === "name" && this.classMeta.get(s.className)?.root.def.name === "%Error") {
3229
+ const present = this.classFieldPtr(obj.name, s.className, "%namePresent").ptr;
3230
+ const enumerable = this.classFieldPtr(obj.name, s.className, "%nameEnumerable").ptr;
3231
+ const wasPresent = B.tmp(), wasEnumerable = B.tmp(), isPresent = B.tmp(), nextEnumerable = B.tmp();
3232
+ B.line(`${wasPresent} = load i8, ptr ${present}`);
3233
+ B.line(`${wasEnumerable} = load i8, ptr ${enumerable}`);
3234
+ B.line(`${isPresent} = icmp ne i8 ${wasPresent}, 0`);
3235
+ B.line(`${nextEnumerable} = select i1 ${isPresent}, i8 ${wasEnumerable}, i8 1`);
3236
+ B.line(`store i8 1, ptr ${present}`);
3237
+ B.line(`store i8 ${nextEnumerable}, ptr ${enumerable}`);
3238
+ }
2936
3239
  break;
2937
3240
  }
2938
3241
  case "recordKeyDelete": {
@@ -3130,7 +3433,7 @@ class LlEmitter {
3130
3433
  kind: "loop",
3131
3434
  brkLabel: le,
3132
3435
  contLabel: lc,
3133
- ...(s.labels !== undefined && { labels: s.labels }),
3436
+ labels: s.labels,
3134
3437
  frameDepth: this.frames.length,
3135
3438
  scopeDepth: this.scopes.length,
3136
3439
  finallyDepth: this.finallyStack.length,
@@ -3152,7 +3455,7 @@ class LlEmitter {
3152
3455
  kind: "loop",
3153
3456
  brkLabel: le,
3154
3457
  contLabel: lc,
3155
- ...(s.labels !== undefined && { labels: s.labels }),
3458
+ labels: s.labels,
3156
3459
  frameDepth: this.frames.length,
3157
3460
  scopeDepth: this.scopes.length,
3158
3461
  finallyDepth: this.finallyStack.length,
@@ -3178,7 +3481,12 @@ class LlEmitter {
3178
3481
  this.integerLoopBindings.set(integerLoop.localId, integerSlot);
3179
3482
  }
3180
3483
  else if (s.init) {
3181
- this.emitStmt(s.init);
3484
+ // A multi-declarator head shares the loop's scope. Emitting its
3485
+ // IR block as an ordinary block would release captured/ref locals
3486
+ // before the first condition.
3487
+ const initializers = s.init.kind === "block" ? s.init.body : [s.init];
3488
+ for (const initializer of initializers)
3489
+ this.emitStmt(initializer);
3182
3490
  }
3183
3491
  const lc = B.newLabel("loop.c");
3184
3492
  const lb = B.newLabel("loop.b");
@@ -3186,11 +3494,29 @@ class LlEmitter {
3186
3494
  // JS `for (let i ...)`: each iteration gets a FRESH binding holding
3187
3495
  // a copy of the previous one (closures made in iteration k keep
3188
3496
  // seeing iteration k's value) — only observable, and only emitted,
3189
- // when the init variable is captured (boxed). The freshening (and
3190
- // the update) live in the continue-target block.
3191
- const initLocal = s.init?.kind === "varDecl" ? this.currentLocals.get(s.init.localId) : undefined;
3192
- const freshens = initLocal?.boxed === true;
3193
- const lu = s.update || freshens ? B.newLabel("loop.u") : lc;
3497
+ // when a let variable is captured (boxed). Freshen before the first
3498
+ // condition and again in the continue-target block before updating.
3499
+ const initializers = s.init?.kind === "block" ? s.init.body : s.init ? [s.init] : [];
3500
+ const capturedLets = initializers.flatMap((init) => {
3501
+ const local = init.kind === "varDecl" ? this.currentLocals.get(init.localId) : undefined;
3502
+ return local?.boxed && local.mutable ? [local] : [];
3503
+ });
3504
+ const freshenBindings = () => {
3505
+ for (const local of capturedLets) {
3506
+ const slot = `%${mangleLocal(local.id)}`;
3507
+ const fresh = B.tmp();
3508
+ const old = B.tmp();
3509
+ B.line(`${fresh} = ${boxNewCall(this.shapeHost, local.type)} ; per-iteration ${local.name}`);
3510
+ B.line(`${old} = load ptr, ptr ${slot}`);
3511
+ const val = this.boxGet(old, local.type);
3512
+ this.boxSet(fresh, local.type, val);
3513
+ this.declare(`declare void @scr_box_release(ptr)`);
3514
+ B.line(`call void @scr_box_release(ptr ${old})`);
3515
+ B.line(`store ptr ${fresh}, ptr ${slot}`);
3516
+ }
3517
+ };
3518
+ const lu = s.update || capturedLets.length > 0 ? B.newLabel("loop.u") : lc;
3519
+ freshenBindings();
3194
3520
  B.br(lc);
3195
3521
  B.startBlock(lc);
3196
3522
  if (integerLoop && integerSlot) {
@@ -3214,7 +3540,7 @@ class LlEmitter {
3214
3540
  kind: "loop",
3215
3541
  brkLabel: le,
3216
3542
  contLabel: lu,
3217
- ...(s.labels !== undefined && { labels: s.labels }),
3543
+ labels: s.labels,
3218
3544
  frameDepth: this.frames.length,
3219
3545
  scopeDepth: this.scopes.length,
3220
3546
  finallyDepth: this.finallyStack.length,
@@ -3224,20 +3550,7 @@ class LlEmitter {
3224
3550
  B.br(lu);
3225
3551
  if (lu !== lc) {
3226
3552
  B.startBlock(lu);
3227
- if (freshens && initLocal) {
3228
- const slot = `%${mangleLocal(initLocal.id)}`;
3229
- const fresh = B.tmp();
3230
- const old = B.tmp();
3231
- B.line(`${fresh} = ${boxNewCall(this, initLocal.type)} ; per-iteration ${initLocal.name}`);
3232
- B.line(`${old} = load ptr, ptr ${slot}`);
3233
- const val = this.boxGet(old, initLocal.type); // ref: +1 out
3234
- this.boxSet(fresh, initLocal.type, val); // takes ownership
3235
- this.declare(`declare void @scr_box_release(ptr)`);
3236
- B.line(`call void @scr_box_release(ptr ${old})`);
3237
- B.line(`store ptr ${fresh}, ptr ${slot}`);
3238
- // The wrapper scope's entry releases whatever the slot points
3239
- // to at loop exit — now the freshest binding. Nothing to fix.
3240
- }
3553
+ freshenBindings();
3241
3554
  if (integerLoop && integerSlot) {
3242
3555
  const old = B.tmp();
3243
3556
  const next = B.tmp();
@@ -3286,7 +3599,7 @@ class LlEmitter {
3286
3599
  kind: "loop",
3287
3600
  brkLabel: le,
3288
3601
  contLabel: lu,
3289
- ...(s.labels !== undefined && { labels: s.labels }),
3602
+ labels: s.labels,
3290
3603
  frameDepth: this.frames.length,
3291
3604
  scopeDepth: this.scopes.length,
3292
3605
  finallyDepth: this.finallyStack.length,
@@ -3307,7 +3620,7 @@ class LlEmitter {
3307
3620
  // fresh const binding. The box takes ownership of a ref element's
3308
3621
  // +1 and is released with the iteration's scope.
3309
3622
  const box = B.tmp();
3310
- B.line(`${box} = ${boxNewCall(this, elem)} ; per-iteration ${localInfo.name}`);
3623
+ B.line(`${box} = ${boxNewCall(this.shapeHost, elem)} ; per-iteration ${localInfo.name}`);
3311
3624
  this.boxSet(box, elem, cur);
3312
3625
  B.line(`store ptr ${box}, ptr ${slot}`);
3313
3626
  this.scopes[this.scopes.length - 1].push({ slot, type: elem, boxed: true });
@@ -3380,10 +3693,7 @@ class LlEmitter {
3380
3693
  // tryStack it sees truncated to its region (its releases already
3381
3694
  // ran; a throw inside a copy propagates OUT of the completing
3382
3695
  // try, past its own catch), then the function-level releases and
3383
- // the actual ret. The C emitter routes this through per-region
3384
- // finally copies behind gotos with the value parked in sc_pret;
3385
- // the inline copies here are the same code at the same depths,
3386
- // with the parked value's ownership riding a synthetic slot-based
3696
+ // the actual ret. The parked value owns a synthetic slot-backed
3387
3697
  // scope entry during each copy so a throwing finally releases it.
3388
3698
  let v = null;
3389
3699
  if (s.value !== null) {
@@ -3450,10 +3760,9 @@ class LlEmitter {
3450
3760
  case "rethrow": {
3451
3761
  // Re-raise the saved snapshot (payload retained — the binding
3452
3762
  // local releases with its scope) and unwind like `throw`.
3453
- const c = B.tmp();
3454
- B.line(`${c} = load ptr, ptr %${mangleLocal(s.localId)}`);
3763
+ const c = this.emitExpr({ kind: "varRef", localId: s.localId, type: CAUGHT, loc: s.loc });
3455
3764
  this.declare(`declare void @scr_rethrow(ptr)`);
3456
- B.line(`call void @scr_rethrow(ptr ${c})`);
3765
+ B.line(`call void @scr_rethrow(ptr ${c.name})`);
3457
3766
  this.emitUnwind();
3458
3767
  break;
3459
3768
  }
@@ -3571,8 +3880,17 @@ class LlEmitter {
3571
3880
  this.emitBlock(s.catchBody, (scope) => {
3572
3881
  const c = B.tmp();
3573
3882
  B.line(`${c} = call ptr @scr_exc_take() ; catch binding`);
3574
- B.line(`store ptr ${c}, ptr ${slot}`);
3575
- scope.push({ slot, type: CAUGHT });
3883
+ if (this.currentLocals.get(s.catchLocalId)?.boxed) {
3884
+ const box = B.tmp();
3885
+ B.line(`${box} = ${boxNewCall(this.shapeHost, CAUGHT)} ; captured exception`);
3886
+ this.boxSet(box, CAUGHT, c);
3887
+ B.line(`store ptr ${box}, ptr ${slot}`);
3888
+ scope.push({ slot, type: CAUGHT, boxed: true });
3889
+ }
3890
+ else {
3891
+ B.line(`store ptr ${c}, ptr ${slot}`);
3892
+ scope.push({ slot, type: CAUGHT });
3893
+ }
3576
3894
  });
3577
3895
  }
3578
3896
  else {
@@ -3638,7 +3956,7 @@ class LlEmitter {
3638
3956
  }
3639
3957
  /** JS-exact switch: lazily evaluated, arbitrary-expression case tests in
3640
3958
  * source order, bodies falling through in source order until a break —
3641
- * CEmitter.emitSwitch's goto chain, block-flavored. All case bodies
3959
+ * A chain of conditional branches. All case bodies
3642
3960
  * share ONE scope; because dispatch can jump PAST a varDecl into a later
3643
3961
  * case, refcounted/boxed case-body locals are NULL-reset up front and
3644
3962
  * the scope-exit releases rely on NULL tolerance. */
@@ -3696,7 +4014,7 @@ class LlEmitter {
3696
4014
  kind: "switch",
3697
4015
  brkLabel: end,
3698
4016
  contLabel: null,
3699
- ...(s.labels !== undefined && { labels: s.labels }),
4017
+ labels: s.labels,
3700
4018
  frameDepth: this.frames.length,
3701
4019
  scopeDepth: this.scopes.length,
3702
4020
  finallyDepth: this.finallyStack.length,
@@ -3721,7 +4039,7 @@ class LlEmitter {
3721
4039
  /** Evaluates a condition (IR conds are bool-typed) and releases its
3722
4040
  * temps BEFORE the branch — safe because the result is a scalar i1, and
3723
4041
  * required in loop-condition blocks (their temps must not survive into
3724
- * later blocks across the back edge). CEmitter.emitCondition. */
4042
+ * later blocks across the back edge). */
3725
4043
  emitCondition(cond) {
3726
4044
  const v = this.emitExpr(cond);
3727
4045
  const frame = this.currentFrame();
@@ -3732,7 +4050,7 @@ class LlEmitter {
3732
4050
  /** Evaluates `expr` in its own statement frame inside an already-open
3733
4051
  * branch and moves the result into `slot`: the chosen value's ownership
3734
4052
  * transfers, every other temp the arm allocated releases inside the
3735
- * branch. The shared core of ternary/logical. CEmitter.emitBranchInto. */
4053
+ * branch. The shared core of ternary/logical. */
3736
4054
  emitBranchInto(slot, expr) {
3737
4055
  this.frames.push([]);
3738
4056
  const v = this.emitExpr(expr);
@@ -3741,24 +4059,28 @@ class LlEmitter {
3741
4059
  this.releaseFrame(this.frames.pop());
3742
4060
  }
3743
4061
  // ── expressions ─────────────────────────────────────────────────────────
3744
- /** One audited escape hatch for the type-only boundary used by the
3745
- * extracted expression modules. LlEmitter remains the sole owner of the
3746
- * mutable emission state; the context exposes only the operations those
3747
- * modules require. */
3748
- expressionContext() {
3749
- return this;
3750
- }
3751
4062
  emitLiteralExpr(e) {
3752
- return emitLiteralExpr(this.expressionContext(), e);
4063
+ return emitLiteralExpr(this, e);
3753
4064
  }
3754
4065
  emitOperatorExpr(e) {
3755
- return emitOperatorExpr(this.expressionContext(), e);
4066
+ if (e.kind === "seqExpr") {
4067
+ // Saved operands can feed later call arguments. Transfer ownership
4068
+ // to this expression's frame so they survive those reads and still
4069
+ // die on the path that created them, including inside lazy branches.
4070
+ this.scopes.push([]);
4071
+ const result = emitOperatorExpr(this, e);
4072
+ for (const local of this.scopes.pop()) {
4073
+ this.currentFrame().push({ name: local.slot, type: local.type, slot: true, ...(local.boxed ? { boxed: true } : {}) });
4074
+ }
4075
+ return result;
4076
+ }
4077
+ return emitOperatorExpr(this, e);
3756
4078
  }
3757
4079
  emitControlExpr(e) {
3758
- return emitControlExpr(this.expressionContext(), e);
4080
+ return emitControlExpr(this, e);
3759
4081
  }
3760
4082
  emitStringExpr(e) {
3761
- return emitStringExpr(this.expressionContext(), e);
4083
+ return emitStringExpr(this, e);
3762
4084
  }
3763
4085
  /**
3764
4086
  * Lower canonical `target = target + suffix` after evaluating the old
@@ -3802,251 +4124,273 @@ class LlEmitter {
3802
4124
  return result;
3803
4125
  }
3804
4126
  emitContainerExpr(e) {
3805
- return emitContainerExpr(this.expressionContext(), e);
4127
+ return emitContainerExpr(this, e);
3806
4128
  }
3807
4129
  emitCallExpr(e) {
3808
- return emitCallExpr(this.expressionContext(), e);
4130
+ return emitCallExpr(this, e);
3809
4131
  }
3810
4132
  emitRecordExpr(e) {
3811
- return emitRecordExpr(this.expressionContext(), e);
4133
+ return emitRecordExpr(this, e);
3812
4134
  }
3813
4135
  emitDynamicExpr(e) {
3814
- return emitDynamicExpr(this.expressionContext(), e);
4136
+ return emitDynamicExpr(this, e);
3815
4137
  }
3816
4138
  emitIntrinsicExpr(e) {
3817
- return emitIntrinsicExpr(this.expressionContext(), e);
4139
+ return emitIntrinsicExpr(this, e);
3818
4140
  }
3819
4141
  emitSerializationExpr(e) {
3820
- return emitSerializationExpr(this.expressionContext(), e);
4142
+ return emitSerializationExpr(this, e);
3821
4143
  }
3822
4144
  emitAsyncExpr(e) {
3823
- return emitAsyncExpr(this.expressionContext(), e);
4145
+ return emitAsyncExpr(this, e);
3824
4146
  }
3825
4147
  emitJsInteropExpr(e) {
3826
- return emitJsInteropExpr(this.expressionContext(), e);
4148
+ return emitJsInteropExpr(this, e);
4149
+ }
4150
+ /** Read a receiver whose value is consumed immediately by a field or tag
4151
+ * load. No user code may run between this read and its consumer. Locals
4152
+ * and their projections already have an owner; other expressions keep
4153
+ * their ordinary statement-frame ownership. The caller must retain any
4154
+ * reference result before evaluating another expression. */
4155
+ emitReadReceiver(e) {
4156
+ if (!isRefCounted(e.type))
4157
+ return this.emitExpr(e);
4158
+ if (e.kind === "varRef") {
4159
+ const binding = this.binding(e.localId);
4160
+ // Capture boxes can carry TDZ and caught-value conversion semantics.
4161
+ if (binding.kind === "boxed")
4162
+ return this.emitExpr(e);
4163
+ if (binding.kind === "global")
4164
+ this.checkGlobalTdz(e.localId);
4165
+ const value = this.B.tmp();
4166
+ this.B.line(`${value} = load ptr, ptr ${binding.slot}`);
4167
+ return { name: value, type: e.type };
4168
+ }
4169
+ if (e.kind === "unionNarrow") {
4170
+ const union = this.emitReadReceiver(e.value);
4171
+ return { name: this.unionPeek(union.name), type: e.type };
4172
+ }
4173
+ if (e.kind === "recordGet" || e.kind === "fieldGet") {
4174
+ const receiver = this.emitReadReceiver(e.obj);
4175
+ const { ptr, type } = e.kind === "recordGet"
4176
+ ? this.recordFieldPtr(receiver.name, e.shapeId, e.field)
4177
+ : this.classFieldPtr(receiver.name, e.className, e.field);
4178
+ return { name: this.loadField(ptr, type), type: e.type };
4179
+ }
4180
+ return this.emitExpr(e);
3827
4181
  }
3828
4182
  emitExpr(e) {
3829
- return emitExpr(this.expressionContext(), e);
4183
+ return emitExpr(this, e);
3830
4184
  }
3831
4185
  emitJsMarshal(e) {
3832
- return emitJsMarshal(this.expressionContext(), e);
4186
+ return emitJsMarshal(this, e);
3833
4187
  }
3834
4188
  emitJsOp(e) {
3835
- return emitJsOp(this.expressionContext(), e);
4189
+ return emitJsOp(this, e);
3836
4190
  }
3837
4191
  emitJsExit(e) {
3838
- return emitJsExit(this.expressionContext(), e);
4192
+ return emitJsExit(this, e);
3839
4193
  }
3840
4194
  islandAdapter(arity, retKind) {
3841
- return islandAdapter(this.expressionContext(), arity, retKind);
4195
+ return islandAdapter(this, arity, retKind);
3842
4196
  }
3843
4197
  islandTypedAdapter(fn) {
3844
- return islandTypedAdapter(this.expressionContext(), fn);
4198
+ return islandTypedAdapter(this, fn);
3845
4199
  }
3846
4200
  dynKind(d) {
3847
- return dynKind(this.expressionContext(), d);
4201
+ return dynKind(this, d);
3848
4202
  }
3849
4203
  raceAdapterFor(from, to) {
3850
- return raceAdapterFor(this.expressionContext(), from, to);
4204
+ return raceAdapterFor(this, from, to);
3851
4205
  }
3852
4206
  genResultThunkFor(genT, recT) {
3853
- return genResultThunkFor(this.expressionContext(), genT, recT);
4207
+ return genResultThunkFor(this, genT, recT);
3854
4208
  }
3855
4209
  childExitThunkFor(param) {
3856
- return childExitThunkFor(this.expressionContext(), param);
4210
+ return childExitThunkFor(this, param);
3857
4211
  }
3858
4212
  execFileThunkFor(cbT) {
3859
- return execFileThunkFor(this.expressionContext(), cbT);
4213
+ return execFileThunkFor(this, cbT);
3860
4214
  }
3861
4215
  ipcMessageThunkFor(cbT) {
3862
- return ipcMessageThunkFor(this.expressionContext(), cbT);
4216
+ return ipcMessageThunkFor(this, cbT);
3863
4217
  }
3864
4218
  ipcSendThunkFor(cbT) {
3865
- return ipcSendThunkFor(this.expressionContext(), cbT);
4219
+ return ipcSendThunkFor(this, cbT);
3866
4220
  }
3867
4221
  childExitSignalThunkFor(codeParam, sigParam) {
3868
- return childExitSignalThunkFor(this.expressionContext(), codeParam, sigParam);
4222
+ return childExitSignalThunkFor(this, codeParam, sigParam);
3869
4223
  }
3870
4224
  childDataThunkFor(param) {
3871
- return childDataThunkFor(this.expressionContext(), param);
4225
+ return childDataThunkFor(this, param);
3872
4226
  }
3873
4227
  emitterFixedAdapter(cbT) {
3874
- return emitterFixedAdapter(this.expressionContext(), cbT);
4228
+ return emitterFixedAdapter(this, cbT);
3875
4229
  }
3876
4230
  wrapEmitterListener(target, adapterFn) {
3877
- return wrapEmitterListener(this.expressionContext(), target, adapterFn);
4231
+ return wrapEmitterListener(this, target, adapterFn);
3878
4232
  }
3879
4233
  unwrapNullableClosure(u, funcTag) {
3880
- return unwrapNullableClosure(this.expressionContext(), u, funcTag);
4234
+ return unwrapNullableClosure(this, u, funcTag);
3881
4235
  }
3882
4236
  closeBindThunkFor(cbUnion, retServer) {
3883
- return closeBindThunkFor(this.expressionContext(), cbUnion, retServer);
4237
+ return closeBindThunkFor(this, cbUnion, retServer);
3884
4238
  }
3885
4239
  closeOverrideWrapFor(cbUnion, retServer) {
3886
- return closeOverrideWrapFor(this.expressionContext(), cbUnion, retServer);
4240
+ return closeOverrideWrapFor(this, cbUnion, retServer);
3887
4241
  }
3888
4242
  streamDataAdapter(cbT) {
3889
- return streamDataAdapter(this.expressionContext(), cbT);
4243
+ return streamDataAdapter(this, cbT);
3890
4244
  }
3891
4245
  streamDoneFnFor(kind, doneT) {
3892
- return streamDoneFnFor(this.expressionContext(), kind, doneT);
4246
+ return streamDoneFnFor(this, kind, doneT);
3893
4247
  }
3894
4248
  fsRenameThunkFor(cbT) {
3895
- return fsRenameThunkFor(this.expressionContext(), cbT);
4249
+ return fsRenameThunkFor(this, cbT);
3896
4250
  }
3897
4251
  cryptoBytesThunkFor(cbT) {
3898
- return cryptoBytesThunkFor(this.expressionContext(), cbT);
4252
+ return cryptoBytesThunkFor(this, cbT);
3899
4253
  }
3900
4254
  zlibBytesThunkFor(cbT) {
3901
- return zlibBytesThunkFor(this.expressionContext(), cbT);
4255
+ return zlibBytesThunkFor(this, cbT);
3902
4256
  }
3903
4257
  streamCbThunkFor(kind, cbT) {
3904
- return streamCbThunkFor(this.expressionContext(), kind, cbT);
4258
+ return streamCbThunkFor(this, kind, cbT);
3905
4259
  }
3906
4260
  resolveThunkFor(inner) {
3907
- return resolveThunkFor(this.expressionContext(), inner);
4261
+ return resolveThunkFor(this, inner);
3908
4262
  }
3909
4263
  tagInSet(uName, tags) {
3910
- return tagInSet(this.expressionContext(), uName, tags);
4264
+ return tagInSet(this, uName, tags);
3911
4265
  }
3912
4266
  arrPush(arr, acc, value) {
3913
- return arrPush(this.expressionContext(), arr, acc, value);
4267
+ return arrPush(this, arr, acc, value);
3914
4268
  }
3915
4269
  emitArrayCopyLoop(dst, src, acc) {
3916
- return emitArrayCopyLoop(this.expressionContext(), dst, src, acc);
4270
+ return emitArrayCopyLoop(this, dst, src, acc);
3917
4271
  }
3918
4272
  emitStrIntrinsic(e) {
3919
- return emitStrIntrinsic(this.expressionContext(), e);
4273
+ return emitStrIntrinsic(this, e);
3920
4274
  }
3921
4275
  emitArrIntrinsic(e) {
3922
- return emitArrIntrinsic(this.expressionContext(), e);
4276
+ return emitArrIntrinsic(this, e);
3923
4277
  }
3924
4278
  wrapNullable(raw, present, valueType, valueTag, resultType, absentTag) {
3925
- return wrapNullable(this.expressionContext(), raw, present, valueType, valueTag, resultType, absentTag);
4279
+ return wrapNullable(this, raw, present, valueType, valueTag, resultType, absentTag);
3926
4280
  }
3927
4281
  emitMapNew(e) {
3928
- return emitMapNew(this.expressionContext(), e);
4282
+ return emitMapNew(this, e);
3929
4283
  }
3930
4284
  mapSet(m, kAcc, vAcc, key, value) {
3931
- return mapSet(this.expressionContext(), m, kAcc, vAcc, key, value);
4285
+ return mapSet(this, m, kAcc, vAcc, key, value);
3932
4286
  }
3933
4287
  emitMapLikeIntrinsic(e) {
3934
- return emitMapLikeIntrinsic(this.expressionContext(), e);
4288
+ return emitMapLikeIntrinsic(this, e);
3935
4289
  }
3936
4290
  emitSetNew(e) {
3937
- return emitSetNew(this.expressionContext(), e);
4291
+ return emitSetNew(this, e);
3938
4292
  }
3939
4293
  emitStableReceiver(receiver, following) {
3940
- return emitStableReceiver(this.expressionContext(), receiver, following);
4294
+ return emitStableReceiver(this, receiver, following);
3941
4295
  }
3942
4296
  emitIntegerLoopIndex(expr) {
3943
- return emitIntegerLoopIndex(this.expressionContext(), expr);
4297
+ return emitIntegerLoopIndex(this, expr);
3944
4298
  }
3945
4299
  emitBytesIndex(receiver, index, integerIndex = false) {
3946
- return emitBytesIndex(this.expressionContext(), receiver, index, integerIndex);
4300
+ return emitBytesIndex(this, receiver, index, integerIndex);
3947
4301
  }
3948
4302
  emitBytesData(receiver) {
3949
- return emitBytesData(this.expressionContext(), receiver);
4303
+ return emitBytesData(this, receiver);
3950
4304
  }
3951
4305
  emitBytesLength(elem, receiver, bytes) {
3952
- return emitBytesLength(this.expressionContext(), elem, receiver, bytes);
4306
+ return emitBytesLength(this, elem, receiver, bytes);
3953
4307
  }
3954
4308
  emitBytesGet(elem, receiver, index, integerIndex = false) {
3955
- return emitBytesGet(this.expressionContext(), elem, receiver, index, integerIndex);
4309
+ return emitBytesGet(this, elem, receiver, index, integerIndex);
3956
4310
  }
3957
4311
  emitToUint32(value, expr) {
3958
- return emitToUint32(this.expressionContext(), value, expr);
4312
+ return emitToUint32(this, value, expr);
3959
4313
  }
3960
4314
  emitBytesSet(elem, receiver, index, value, integerIndex = false) {
3961
- return emitBytesSet(this.expressionContext(), elem, receiver, index, value, integerIndex);
4315
+ return emitBytesSet(this, elem, receiver, index, value, integerIndex);
3962
4316
  }
3963
4317
  emitBytesIntrinsic(e) {
3964
- return emitBytesIntrinsic(this.expressionContext(), e);
4318
+ return emitBytesIntrinsic(this, e);
3965
4319
  }
3966
4320
  emitRegexIntrinsic(e) {
3967
- return emitRegexIntrinsic(this.expressionContext(), e);
4321
+ return emitRegexIntrinsic(this, e);
3968
4322
  }
3969
4323
  emitRecordKeyGet(e) {
3970
- return emitRecordKeyGet(this.expressionContext(), e);
4324
+ return emitRecordKeyGet(this, e);
3971
4325
  }
3972
4326
  keyedRecordReadInto(slot, join, objName, keyName, shapeId, resultType, overflowOnly, loc) {
3973
- return keyedRecordReadInto(this.expressionContext(), slot, join, objName, keyName, shapeId, resultType, overflowOnly, loc);
4327
+ return keyedRecordReadInto(this, slot, join, objName, keyName, shapeId, resultType, overflowOnly, loc);
3974
4328
  }
3975
4329
  dynPromiseAdapter(inner) {
3976
- return dynPromiseAdapter(this.expressionContext(), inner);
4330
+ return dynPromiseAdapter(this, inner);
3977
4331
  }
3978
4332
  streamTypedRefCommitAdapter(t, snapshot) {
3979
- return streamTypedRefCommitAdapter(this.expressionContext(), t, snapshot);
4333
+ return streamTypedRefCommitAdapter(this, t, snapshot);
3980
4334
  }
3981
4335
  liveDynRefAdapter(t) {
3982
- const key = typeKey(t);
3983
- const existing = this.liveDynRefAdapters.get(key);
3984
- if (existing)
3985
- return existing;
3986
4336
  if (!streamTypedRefEligible(t) && !isDynTypedRefType(t)) {
3987
- throw new InternalCompilerError(`llvm emitter bug: live dyn ref of ${key}`);
4337
+ throw new InternalCompilerError(`llvm emitter bug: live dyn ref of ${typeKey(t)}`);
3988
4338
  }
3989
- const prefix = `sc_ldr_${this.liveDynRefAdapters.size}`;
3990
- const adapter = streamTypedRefMaterializeAdapter(this.expressionContext(), t, { prefix, adapters: new Map() }, `${prefix}_materialize`);
3991
- this.liveDynRefAdapters.set(key, adapter);
3992
- return adapter;
4339
+ return streamTypedRefMaterializeAdapter(this, t);
3993
4340
  }
3994
4341
  liveDynUnionRefAdapter(t) {
3995
- return liveDynUnionRefAdapter(this.expressionContext(), t);
3996
- }
3997
- streamTypedRefBoxValue(B, t, value, ctx) {
3998
- return streamTypedRefBoxValue(this.expressionContext(), B, t, value, ctx);
4342
+ return liveDynUnionRefAdapter(this, t);
3999
4343
  }
4000
- streamTypedRefMaterializeAdapter(t, ctx, preferredSnapshot) {
4001
- return streamTypedRefMaterializeAdapter(this.expressionContext(), t, ctx, preferredSnapshot);
4344
+ streamTypedRefBoxValue(B, t, value) {
4345
+ return streamTypedRefBoxValue(this, B, t, value);
4002
4346
  }
4003
4347
  streamFromArrayAdapter(t) {
4004
- return streamFromArrayAdapter(this.expressionContext(), t);
4348
+ return streamFromArrayAdapter(this, t);
4005
4349
  }
4006
4350
  emitWebLibCall(e) {
4007
- return emitWebLibCall(this.expressionContext(), e);
4351
+ return emitWebLibCall(this, e);
4008
4352
  }
4009
4353
  emitDynamicLibCall(e) {
4010
- return emitDynamicLibCall(this.expressionContext(), e);
4354
+ return emitDynamicLibCall(this, e);
4011
4355
  }
4012
4356
  emitFilesystemLibCall(e) {
4013
- return emitFilesystemLibCall(this.expressionContext(), e);
4357
+ return emitFilesystemLibCall(this, e);
4014
4358
  }
4015
4359
  emitPathUrlLibCall(e) {
4016
- return emitPathUrlLibCall(this.expressionContext(), e);
4360
+ return emitPathUrlLibCall(this, e);
4017
4361
  }
4018
4362
  emitPrimitiveLibCall(e) {
4019
- return emitPrimitiveLibCall(this.expressionContext(), e);
4363
+ return emitPrimitiveLibCall(this, e);
4020
4364
  }
4021
4365
  emitChildProcessLibCall(e) {
4022
- return emitChildProcessLibCall(this.expressionContext(), e);
4366
+ return emitChildProcessLibCall(this, e);
4023
4367
  }
4024
4368
  emitAsyncContextLibCall(e) {
4025
- return emitAsyncContextLibCall(this.expressionContext(), e);
4369
+ return emitAsyncContextLibCall(this, e);
4026
4370
  }
4027
4371
  emitProcessLibCall(e) {
4028
- return emitProcessLibCall(this.expressionContext(), e);
4372
+ return emitProcessLibCall(this, e);
4029
4373
  }
4030
4374
  emitErrorsEventsLibCall(e) {
4031
- return emitErrorsEventsLibCall(this.expressionContext(), e);
4375
+ return emitErrorsEventsLibCall(this, e);
4032
4376
  }
4033
4377
  emitStreamLibCall(e) {
4034
- return emitStreamLibCall(this.expressionContext(), e);
4378
+ return emitStreamLibCall(this, e);
4035
4379
  }
4036
4380
  emitNetworkHttpLibCall(e) {
4037
- return emitNetworkHttpLibCall(this.expressionContext(), e);
4381
+ return emitNetworkHttpLibCall(this, e);
4038
4382
  }
4039
4383
  emitAssertInspectLibCall(e) {
4040
- return emitAssertInspectLibCall(this.expressionContext(), e);
4384
+ return emitAssertInspectLibCall(this, e);
4041
4385
  }
4042
4386
  emitIoLibCall(e) {
4043
- return emitIoLibCall(this.expressionContext(), e);
4387
+ return emitIoLibCall(this, e);
4044
4388
  }
4045
4389
  emitGenericLibCall(e) {
4046
- return emitGenericLibCall(this.expressionContext(), e);
4390
+ return emitGenericLibCall(this, e);
4047
4391
  }
4048
4392
  emitLibCall(e) {
4049
- return emitLibCall(this.expressionContext(), e);
4393
+ return emitLibCall(this, e);
4050
4394
  }
4051
4395
  }
4052
4396
  //# sourceMappingURL=emitter.js.map