@scriptc/compiler 0.1.6 → 0.2.0

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 (1060) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +73 -25
  2. package/ambient/scriptc-overrides.d.ts +10 -6
  3. package/ambient/scriptc.d.ts +28 -5
  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 +107 -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/debug-symbols.d.ts +8 -0
  16. package/dist/backend/debug-symbols.js +52 -0
  17. package/dist/backend/debug-symbols.js.map +1 -0
  18. package/dist/backend/executable-features.d.ts +4 -0
  19. package/dist/backend/executable-features.js +42 -0
  20. package/dist/backend/executable-features.js.map +1 -0
  21. package/dist/backend/external-c.d.ts +5 -27
  22. package/dist/backend/external-c.js +5 -40
  23. package/dist/backend/external-c.js.map +1 -1
  24. package/dist/backend/ffi-callbacks.d.ts +2 -3
  25. package/dist/backend/ffi-callbacks.js +2 -3
  26. package/dist/backend/ffi-callbacks.js.map +1 -1
  27. package/dist/backend/library-identity-markers.d.ts +4 -9
  28. package/dist/backend/library-identity-markers.js +11 -49
  29. package/dist/backend/library-identity-markers.js.map +1 -1
  30. package/dist/backend/library-pack.d.ts +5 -0
  31. package/dist/backend/library-pack.js +123 -0
  32. package/dist/backend/library-pack.js.map +1 -0
  33. package/dist/backend/link-plan-core.d.ts +20 -0
  34. package/dist/backend/link-plan-core.js +18 -0
  35. package/dist/backend/link-plan-core.js.map +1 -0
  36. package/dist/backend/link-plan.d.ts +2 -1
  37. package/dist/backend/link-plan.js +18 -17
  38. package/dist/backend/link-plan.js.map +1 -1
  39. package/dist/backend/link-trace.d.ts +2 -0
  40. package/dist/backend/link-trace.js +24 -0
  41. package/dist/backend/link-trace.js.map +1 -0
  42. package/dist/backend/linker.js +9 -1
  43. package/dist/backend/linker.js.map +1 -1
  44. package/dist/backend/literals.d.ts +9 -0
  45. package/dist/backend/literals.js +35 -0
  46. package/dist/backend/literals.js.map +1 -0
  47. package/dist/backend/literals.test.d.ts +1 -0
  48. package/dist/backend/literals.test.js +53 -0
  49. package/dist/backend/literals.test.js.map +1 -0
  50. package/dist/backend/llvm/blocks.d.ts +4 -0
  51. package/dist/backend/llvm/blocks.js +25 -4
  52. package/dist/backend/llvm/blocks.js.map +1 -1
  53. package/dist/backend/llvm/blocks.test.d.ts +1 -0
  54. package/dist/backend/llvm/blocks.test.js +91 -0
  55. package/dist/backend/llvm/blocks.test.js.map +1 -0
  56. package/dist/backend/llvm/classes.d.ts +14 -8
  57. package/dist/backend/llvm/classes.js +70 -28
  58. package/dist/backend/llvm/classes.js.map +1 -1
  59. package/dist/backend/llvm/common.d.ts +5 -1
  60. package/dist/backend/llvm/common.js +45 -4
  61. package/dist/backend/llvm/common.js.map +1 -1
  62. package/dist/backend/llvm/debug-info.d.ts +32 -0
  63. package/dist/backend/llvm/debug-info.js +198 -0
  64. package/dist/backend/llvm/debug-info.js.map +1 -0
  65. package/dist/backend/llvm/debug-info.test.d.ts +1 -0
  66. package/dist/backend/llvm/debug-info.test.js +110 -0
  67. package/dist/backend/llvm/debug-info.test.js.map +1 -0
  68. package/dist/backend/llvm/dyn.d.ts +16 -2
  69. package/dist/backend/llvm/dyn.js +498 -175
  70. package/dist/backend/llvm/dyn.js.map +1 -1
  71. package/dist/backend/llvm/emitter.d.ts +598 -1
  72. package/dist/backend/llvm/emitter.js +739 -409
  73. package/dist/backend/llvm/emitter.js.map +1 -1
  74. package/dist/backend/llvm/emitter.test.d.ts +1 -0
  75. package/dist/backend/llvm/emitter.test.js +179 -0
  76. package/dist/backend/llvm/emitter.test.js.map +1 -0
  77. package/dist/backend/llvm/expr-async.js +23 -14
  78. package/dist/backend/llvm/expr-async.js.map +1 -1
  79. package/dist/backend/llvm/expr-bytes.d.ts +1 -1
  80. package/dist/backend/llvm/expr-bytes.js +32 -14
  81. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  82. package/dist/backend/llvm/expr-callbacks.d.ts +1 -1
  83. package/dist/backend/llvm/expr-callbacks.js +25 -22
  84. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  85. package/dist/backend/llvm/expr-calls.js +136 -35
  86. package/dist/backend/llvm/expr-calls.js.map +1 -1
  87. package/dist/backend/llvm/expr-containers.d.ts +1 -1
  88. package/dist/backend/llvm/expr-containers.js +43 -14
  89. package/dist/backend/llvm/expr-containers.js.map +1 -1
  90. package/dist/backend/llvm/expr-context.d.ts +5 -260
  91. package/dist/backend/llvm/expr-control.js +9 -5
  92. package/dist/backend/llvm/expr-control.js.map +1 -1
  93. package/dist/backend/llvm/expr-dispatch.d.ts +1 -1
  94. package/dist/backend/llvm/expr-dispatch.js +2 -0
  95. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  96. package/dist/backend/llvm/expr-dynamic.js +72 -74
  97. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  98. package/dist/backend/llvm/expr-island.d.ts +1 -1
  99. package/dist/backend/llvm/expr-island.js +11 -7
  100. package/dist/backend/llvm/expr-island.js.map +1 -1
  101. package/dist/backend/llvm/expr-primitives.d.ts +1 -1
  102. package/dist/backend/llvm/expr-primitives.js +51 -30
  103. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  104. package/dist/backend/llvm/expr-primitives.test.js +1 -1
  105. package/dist/backend/llvm/expr-records.d.ts +5 -1
  106. package/dist/backend/llvm/expr-records.js +43 -4
  107. package/dist/backend/llvm/expr-records.js.map +1 -1
  108. package/dist/backend/llvm/expr-stream-bridges.d.ts +4 -4
  109. package/dist/backend/llvm/expr-stream-bridges.js +102 -121
  110. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  111. package/dist/backend/llvm/expr-stream-bridges.test.d.ts +1 -0
  112. package/dist/backend/llvm/expr-stream-bridges.test.js +55 -0
  113. package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -0
  114. package/dist/backend/llvm/expr-stream-callbacks.d.ts +1 -1
  115. package/dist/backend/llvm/expr-stream-callbacks.js +12 -12
  116. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  117. package/dist/backend/llvm/layouts.d.ts +19 -0
  118. package/dist/backend/llvm/layouts.js +12 -0
  119. package/dist/backend/llvm/layouts.js.map +1 -0
  120. package/dist/backend/llvm/lib-abi.d.ts +19 -0
  121. package/dist/backend/llvm/lib-abi.js +82 -0
  122. package/dist/backend/llvm/lib-abi.js.map +1 -0
  123. package/dist/backend/llvm/lib-connect.d.ts +2 -0
  124. package/dist/backend/llvm/lib-connect.js +51 -0
  125. package/dist/backend/llvm/lib-connect.js.map +1 -0
  126. package/dist/backend/llvm/lib-datagram.d.ts +2 -0
  127. package/dist/backend/llvm/lib-datagram.js +135 -0
  128. package/dist/backend/llvm/lib-datagram.js.map +1 -0
  129. package/dist/backend/llvm/lib-dispatch.js +50 -6
  130. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  131. package/dist/backend/llvm/lib-filesystem.js +59 -18
  132. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  133. package/dist/backend/llvm/lib-http2.d.ts +2 -0
  134. package/dist/backend/llvm/lib-http2.js +215 -0
  135. package/dist/backend/llvm/lib-http2.js.map +1 -0
  136. package/dist/backend/llvm/lib-lookup.d.ts +2 -0
  137. package/dist/backend/llvm/lib-lookup.js +39 -0
  138. package/dist/backend/llvm/lib-lookup.js.map +1 -0
  139. package/dist/backend/llvm/lib-network.js +25 -2
  140. package/dist/backend/llvm/lib-network.js.map +1 -1
  141. package/dist/backend/llvm/lib-process.js +21 -16
  142. package/dist/backend/llvm/lib-process.js.map +1 -1
  143. package/dist/backend/llvm/lib-shared.js +125 -1
  144. package/dist/backend/llvm/lib-shared.js.map +1 -1
  145. package/dist/backend/llvm/lib-stream.js +3 -2
  146. package/dist/backend/llvm/lib-stream.js.map +1 -1
  147. package/dist/backend/llvm/lib-test.d.ts +2 -0
  148. package/dist/backend/llvm/lib-test.js +34 -0
  149. package/dist/backend/llvm/lib-test.js.map +1 -0
  150. package/dist/backend/llvm/lib-tls.d.ts +2 -0
  151. package/dist/backend/llvm/lib-tls.js +82 -0
  152. package/dist/backend/llvm/lib-tls.js.map +1 -0
  153. package/dist/backend/llvm/shapes.d.ts +10 -9
  154. package/dist/backend/llvm/shapes.js +35 -130
  155. package/dist/backend/llvm/shapes.js.map +1 -1
  156. package/dist/backend/llvm/split.js +4 -1
  157. package/dist/backend/llvm/split.js.map +1 -1
  158. package/dist/backend/llvm/split.test.js +26 -1
  159. package/dist/backend/llvm/split.test.js.map +1 -1
  160. package/dist/backend/llvm/unsupported.d.ts +1 -0
  161. package/dist/backend/llvm/unsupported.js +1 -2
  162. package/dist/backend/llvm/unsupported.js.map +1 -1
  163. package/dist/backend/llvm/walkers.js +1 -7
  164. package/dist/backend/llvm/walkers.js.map +1 -1
  165. package/dist/backend/mangle.d.ts +2 -2
  166. package/dist/backend/mangle.js +16 -5
  167. package/dist/backend/mangle.js.map +1 -1
  168. package/dist/backend/{c/may-throw.d.ts → may-throw.d.ts} +1 -1
  169. package/dist/backend/{c/may-throw.js → may-throw.js} +51 -46
  170. package/dist/backend/may-throw.js.map +1 -0
  171. package/dist/backend/may-throw.test.d.ts +1 -0
  172. package/dist/backend/may-throw.test.js +58 -0
  173. package/dist/backend/may-throw.test.js.map +1 -0
  174. package/dist/backend/native-codegen-core.d.ts +22 -0
  175. package/dist/backend/native-codegen-core.js +44 -0
  176. package/dist/backend/native-codegen-core.js.map +1 -0
  177. package/dist/backend/native-codegen.d.ts +3 -19
  178. package/dist/backend/native-codegen.js +5 -44
  179. package/dist/backend/native-codegen.js.map +1 -1
  180. package/dist/backend/native-codegen.test.js +2 -2
  181. package/dist/backend/native-codegen.test.js.map +1 -1
  182. package/dist/backend/native-link-info-core.d.ts +94 -0
  183. package/dist/backend/native-link-info-core.js +62 -0
  184. package/dist/backend/native-link-info-core.js.map +1 -0
  185. package/dist/backend/native-link-info.d.ts +3 -88
  186. package/dist/backend/native-link-info.js +12 -243
  187. package/dist/backend/native-link-info.js.map +1 -1
  188. package/dist/backend/native-link-info.test.js +41 -146
  189. package/dist/backend/native-link-info.test.js.map +1 -1
  190. package/dist/backend/native-toolchain.d.ts +10 -25
  191. package/dist/backend/native-toolchain.js +89 -219
  192. package/dist/backend/native-toolchain.js.map +1 -1
  193. package/dist/backend/native-toolchain.test.js +15 -5
  194. package/dist/backend/native-toolchain.test.js.map +1 -1
  195. package/dist/backend/native-tools.d.ts +24 -0
  196. package/dist/backend/native-tools.js +33 -0
  197. package/dist/backend/native-tools.js.map +1 -0
  198. package/dist/backend/object-localize.js +19 -8
  199. package/dist/backend/object-localize.js.map +1 -1
  200. package/dist/backend/object-localize.test.js +22 -0
  201. package/dist/backend/object-localize.test.js.map +1 -1
  202. package/dist/backend/runtime-abi.d.ts +2 -2
  203. package/dist/backend/runtime-abi.js +2 -2
  204. package/dist/backend/runtime-pack-core.d.ts +101 -0
  205. package/dist/backend/runtime-pack-core.js +172 -0
  206. package/dist/backend/runtime-pack-core.js.map +1 -0
  207. package/dist/backend/runtime-pack-native.d.ts +21 -0
  208. package/dist/backend/runtime-pack-native.js +70 -0
  209. package/dist/backend/runtime-pack-native.js.map +1 -0
  210. package/dist/backend/runtime-pack-targets.test.js +1 -1
  211. package/dist/backend/runtime-pack.d.ts +3 -83
  212. package/dist/backend/runtime-pack.js +8 -151
  213. package/dist/backend/runtime-pack.js.map +1 -1
  214. package/dist/backend/runtime-pack.test.js +24 -1
  215. package/dist/backend/runtime-pack.test.js.map +1 -1
  216. package/dist/backend/source-locations.d.ts +12 -0
  217. package/dist/backend/source-locations.js +32 -0
  218. package/dist/backend/source-locations.js.map +1 -0
  219. package/dist/backend/source-locations.test.d.ts +1 -0
  220. package/dist/backend/source-locations.test.js +16 -0
  221. package/dist/backend/source-locations.test.js.map +1 -0
  222. package/dist/backend/target-diagnostics.d.ts +22 -0
  223. package/dist/backend/target-diagnostics.js +108 -0
  224. package/dist/backend/target-diagnostics.js.map +1 -0
  225. package/dist/backend/target-platform.d.ts +15 -0
  226. package/dist/backend/target-platform.js +72 -0
  227. package/dist/backend/target-platform.js.map +1 -0
  228. package/dist/backend/targets.d.ts +13 -4
  229. package/dist/backend/targets.js +95 -30
  230. package/dist/backend/targets.js.map +1 -1
  231. package/dist/backend/targets.test.js +65 -4
  232. package/dist/backend/targets.test.js.map +1 -1
  233. package/dist/backend/toolchain-environment.d.ts +6 -0
  234. package/dist/backend/toolchain-environment.js +99 -0
  235. package/dist/backend/toolchain-environment.js.map +1 -0
  236. package/dist/backend/vendor-archives.d.ts +1 -9
  237. package/dist/backend/vendor-archives.js +2 -9
  238. package/dist/backend/vendor-archives.js.map +1 -1
  239. package/dist/backend/vendor-inputs.d.ts +9 -0
  240. package/dist/backend/vendor-inputs.js +10 -0
  241. package/dist/backend/vendor-inputs.js.map +1 -0
  242. package/dist/backend/warm-cache.d.ts +3 -0
  243. package/dist/backend/warm-cache.js +41 -0
  244. package/dist/backend/warm-cache.js.map +1 -0
  245. package/dist/cli/command.d.ts +3 -0
  246. package/dist/cli/command.js +328 -0
  247. package/dist/cli/command.js.map +1 -0
  248. package/dist/cli/host.d.ts +24 -0
  249. package/dist/cli/host.js +2 -0
  250. package/dist/cli/host.js.map +1 -0
  251. package/dist/cli/output-options.d.ts +26 -0
  252. package/dist/cli/output-options.js +60 -0
  253. package/dist/cli/output-options.js.map +1 -0
  254. package/dist/cli/paths.d.ts +12 -0
  255. package/dist/cli/paths.js +42 -0
  256. package/dist/cli/paths.js.map +1 -0
  257. package/dist/cli/usage.d.ts +74 -0
  258. package/dist/cli/usage.js +86 -0
  259. package/dist/cli/usage.js.map +1 -0
  260. package/dist/cli/wasi-paths.d.ts +8 -0
  261. package/dist/cli/wasi-paths.js +41 -0
  262. package/dist/cli/wasi-paths.js.map +1 -0
  263. package/dist/cli/wasi-runner.d.ts +2 -0
  264. package/dist/cli/wasi-runner.js +28 -0
  265. package/dist/cli/wasi-runner.js.map +1 -0
  266. package/dist/compat/fetch-profile.js +3 -3
  267. package/dist/compat/fetch-profile.js.map +1 -1
  268. package/dist/compile-types.d.ts +162 -0
  269. package/dist/compile-types.js +2 -0
  270. package/dist/compile-types.js.map +1 -0
  271. package/dist/coverage/report.js +11 -5
  272. package/dist/coverage/report.js.map +1 -1
  273. package/dist/coverage/surface-manifest.js +5 -2
  274. package/dist/coverage/surface-manifest.js.map +1 -1
  275. package/dist/diagnostics/diagnostic.d.ts +4 -0
  276. package/dist/diagnostics/diagnostic.js +15 -3
  277. package/dist/diagnostics/diagnostic.js.map +1 -1
  278. package/dist/executable/executable-cache.d.ts +3 -4
  279. package/dist/executable/executable-cache.js +33 -10
  280. package/dist/executable/executable-cache.js.map +1 -1
  281. package/dist/executable/executable-cache.test.js +38 -16
  282. package/dist/executable/executable-cache.test.js.map +1 -1
  283. package/dist/executable/prepare.d.ts +14 -0
  284. package/dist/executable/prepare.js +66 -0
  285. package/dist/executable/prepare.js.map +1 -0
  286. package/dist/ffi/ffi-manifest.d.ts +11 -4
  287. package/dist/ffi/ffi-manifest.js +170 -58
  288. package/dist/ffi/ffi-manifest.js.map +1 -1
  289. package/dist/ffi/ffi-manifest.test.d.ts +1 -0
  290. package/dist/ffi/ffi-manifest.test.js +111 -0
  291. package/dist/ffi/ffi-manifest.test.js.map +1 -0
  292. package/dist/format-integer.d.ts +3 -0
  293. package/dist/format-integer.js +14 -0
  294. package/dist/format-integer.js.map +1 -0
  295. package/dist/frontend/analysis.d.ts +5 -0
  296. package/dist/frontend/analysis.js +88 -0
  297. package/dist/frontend/analysis.js.map +1 -0
  298. package/dist/frontend/arguments-usage.d.ts +4 -0
  299. package/dist/frontend/arguments-usage.js +40 -0
  300. package/dist/frontend/arguments-usage.js.map +1 -0
  301. package/dist/frontend/binding-source.d.ts +4 -0
  302. package/dist/frontend/binding-source.js +18 -0
  303. package/dist/frontend/binding-source.js.map +1 -0
  304. package/dist/frontend/builtin-modules.d.ts +1 -1
  305. package/dist/frontend/builtin-modules.js +1 -1
  306. package/dist/frontend/builtin-modules.js.map +1 -1
  307. package/dist/frontend/cjs-lexer.d.ts +4 -25
  308. package/dist/frontend/cjs-lexer.js +6 -806
  309. package/dist/frontend/cjs-lexer.js.map +1 -1
  310. package/dist/frontend/cjs-resolve.d.ts +5 -0
  311. package/dist/frontend/cjs-resolve.js +429 -0
  312. package/dist/frontend/cjs-resolve.js.map +1 -0
  313. package/dist/frontend/cjs-syntax.d.ts +26 -0
  314. package/dist/frontend/cjs-syntax.js +806 -0
  315. package/dist/frontend/cjs-syntax.js.map +1 -0
  316. package/dist/frontend/comptime-node.d.ts +4 -0
  317. package/dist/frontend/comptime-node.js +16 -0
  318. package/dist/frontend/comptime-node.js.map +1 -0
  319. package/dist/frontend/comptime-node.test.d.ts +1 -0
  320. package/dist/frontend/comptime-node.test.js +37 -0
  321. package/dist/frontend/comptime-node.test.js.map +1 -0
  322. package/dist/frontend/dts-paths.d.ts +3 -4
  323. package/dist/frontend/dts-paths.js +15 -8
  324. package/dist/frontend/dts-paths.js.map +1 -1
  325. package/dist/frontend/fork-target.js +2 -2
  326. package/dist/frontend/fork-target.js.map +1 -1
  327. package/dist/frontend/helper-tokens.d.ts +1 -0
  328. package/dist/frontend/helper-tokens.js +147 -0
  329. package/dist/frontend/helper-tokens.js.map +1 -0
  330. package/dist/frontend/helper-tokens.test.d.ts +1 -0
  331. package/dist/frontend/helper-tokens.test.js +35 -0
  332. package/dist/frontend/helper-tokens.test.js.map +1 -0
  333. package/dist/frontend/inferred-js-diagnostics.d.ts +5 -0
  334. package/dist/frontend/inferred-js-diagnostics.js +69 -0
  335. package/dist/frontend/inferred-js-diagnostics.js.map +1 -0
  336. package/dist/frontend/inferred-js-diagnostics.test.d.ts +1 -0
  337. package/dist/frontend/inferred-js-diagnostics.test.js +58 -0
  338. package/dist/frontend/inferred-js-diagnostics.test.js.map +1 -0
  339. package/dist/frontend/input-tracker.d.ts +5 -2
  340. package/dist/frontend/input-tracker.js +24 -3
  341. package/dist/frontend/input-tracker.js.map +1 -1
  342. package/dist/frontend/input-tracker.test.js +23 -0
  343. package/dist/frontend/input-tracker.test.js.map +1 -1
  344. package/dist/frontend/lib-contract.js +32 -24
  345. package/dist/frontend/lib-contract.js.map +1 -1
  346. package/dist/frontend/literal-values.d.ts +4 -0
  347. package/dist/frontend/literal-values.js +21 -0
  348. package/dist/frontend/literal-values.js.map +1 -0
  349. package/dist/frontend/literal-values.test.d.ts +1 -0
  350. package/dist/frontend/literal-values.test.js +91 -0
  351. package/dist/frontend/literal-values.test.js.map +1 -0
  352. package/dist/frontend/lowering/abstract-equality.d.ts +1 -1
  353. package/dist/frontend/lowering/abstract-equality.js +3 -0
  354. package/dist/frontend/lowering/abstract-equality.js.map +1 -1
  355. package/dist/frontend/lowering/array-indexed-mutation.js +11 -6
  356. package/dist/frontend/lowering/array-indexed-mutation.js.map +1 -1
  357. package/dist/frontend/lowering/array-values.d.ts +4 -1
  358. package/dist/frontend/lowering/array-values.js +43 -1
  359. package/dist/frontend/lowering/array-values.js.map +1 -1
  360. package/dist/frontend/lowering/callback-arg.js +1 -0
  361. package/dist/frontend/lowering/callback-arg.js.map +1 -1
  362. package/dist/frontend/lowering/class-callbacks.d.ts +12 -0
  363. package/dist/frontend/lowering/class-callbacks.js +63 -0
  364. package/dist/frontend/lowering/class-callbacks.js.map +1 -0
  365. package/dist/frontend/lowering/class-descriptors.d.ts +9 -0
  366. package/dist/frontend/lowering/class-descriptors.js +73 -0
  367. package/dist/frontend/lowering/class-descriptors.js.map +1 -0
  368. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +41 -0
  369. package/dist/frontend/lowering/class-dynamic-dispatch.js +803 -0
  370. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -0
  371. package/dist/frontend/lowering/class-dynamic-dispatch.test.d.ts +1 -0
  372. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +92 -0
  373. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -0
  374. package/dist/frontend/lowering/class-instance-constructor.d.ts +7 -0
  375. package/dist/frontend/lowering/class-instance-constructor.js +64 -0
  376. package/dist/frontend/lowering/class-instance-constructor.js.map +1 -0
  377. package/dist/frontend/lowering/class-method-values.d.ts +10 -0
  378. package/dist/frontend/lowering/class-method-values.js +170 -0
  379. package/dist/frontend/lowering/class-method-values.js.map +1 -0
  380. package/dist/frontend/lowering/class-prototypes.d.ts +16 -0
  381. package/dist/frontend/lowering/class-prototypes.js +134 -0
  382. package/dist/frontend/lowering/class-prototypes.js.map +1 -0
  383. package/dist/frontend/lowering/class-static-data.d.ts +6 -0
  384. package/dist/frontend/lowering/class-static-data.js +56 -0
  385. package/dist/frontend/lowering/class-static-data.js.map +1 -0
  386. package/dist/frontend/lowering/containers/buffer-numeric-methods.d.ts +4 -0
  387. package/dist/frontend/lowering/containers/buffer-numeric-methods.js +26 -0
  388. package/dist/frontend/lowering/containers/buffer-numeric-methods.js.map +1 -0
  389. package/dist/frontend/lowering/containers/bytes.d.ts +11 -7
  390. package/dist/frontend/lowering/containers/bytes.js +164 -155
  391. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  392. package/dist/frontend/lowering/containers/string-and-regexp.d.ts +2 -2
  393. package/dist/frontend/lowering/containers/string-and-regexp.js +39 -16
  394. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  395. package/dist/frontend/lowering/containers/string-replacement.d.ts +7 -0
  396. package/dist/frontend/lowering/containers/string-replacement.js +217 -0
  397. package/dist/frontend/lowering/containers/string-replacement.js.map +1 -0
  398. package/dist/frontend/lowering/error-methods.d.ts +11 -0
  399. package/dist/frontend/lowering/error-methods.js +78 -0
  400. package/dist/frontend/lowering/error-methods.js.map +1 -0
  401. package/dist/frontend/lowering/expressions/global-symbols.d.ts +6 -0
  402. package/dist/frontend/lowering/expressions/global-symbols.js +11 -0
  403. package/dist/frontend/lowering/expressions/global-symbols.js.map +1 -0
  404. package/dist/frontend/lowering/expressions/native-proxy.d.ts +7 -0
  405. package/dist/frontend/lowering/expressions/native-proxy.js +49 -0
  406. package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -0
  407. package/dist/frontend/lowering/expressions/nullish-assignment.d.ts +6 -0
  408. package/dist/frontend/lowering/expressions/nullish-assignment.js +124 -0
  409. package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -0
  410. package/dist/frontend/lowering/expressions/object-literals.d.ts +8 -8
  411. package/dist/frontend/lowering/expressions/object-literals.js +485 -185
  412. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  413. package/dist/frontend/lowering/expressions/optional-chains.d.ts +5 -6
  414. package/dist/frontend/lowering/expressions/optional-chains.js +27 -14
  415. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  416. package/dist/frontend/lowering/expressions/try-lower-expression.js +1 -0
  417. package/dist/frontend/lowering/expressions/try-lower-expression.js.map +1 -1
  418. package/dist/frontend/lowering/expressions/union-field-write.d.ts +8 -0
  419. package/dist/frontend/lowering/expressions/union-field-write.js +71 -0
  420. package/dist/frontend/lowering/expressions/union-field-write.js.map +1 -0
  421. package/dist/frontend/lowering/function-context.d.ts +93 -0
  422. package/dist/frontend/lowering/function-context.js +103 -0
  423. package/dist/frontend/lowering/function-context.js.map +1 -0
  424. package/dist/frontend/lowering/generator-delegation.d.ts +7 -0
  425. package/dist/frontend/lowering/generator-delegation.js +85 -0
  426. package/dist/frontend/lowering/generator-delegation.js.map +1 -0
  427. package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +10 -0
  428. package/dist/frontend/lowering/generator-dynamic-dispatch.js +105 -0
  429. package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -0
  430. package/dist/frontend/lowering/lib-boundary.d.ts +2 -1
  431. package/dist/frontend/lowering/lib-boundary.js +59 -20
  432. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  433. package/dist/frontend/lowering/lib-boundary.test.d.ts +1 -0
  434. package/dist/frontend/lowering/lib-boundary.test.js +45 -0
  435. package/dist/frontend/lowering/lib-boundary.test.js.map +1 -0
  436. package/dist/frontend/lowering/lower-array-sort.d.ts +1 -1
  437. package/dist/frontend/lowering/lower-assert.d.ts +1 -1
  438. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  439. package/dist/frontend/lowering/lower-async-iteration.d.ts +1 -1
  440. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
  441. package/dist/frontend/lowering/lower-builtin-values.d.ts +12 -0
  442. package/dist/frontend/lowering/lower-builtin-values.js +139 -0
  443. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -0
  444. package/dist/frontend/lowering/lower-builtins.d.ts +27 -41
  445. package/dist/frontend/lowering/lower-builtins.js +553 -346
  446. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  447. package/dist/frontend/lowering/lower-calls.d.ts +22 -26
  448. package/dist/frontend/lowering/lower-calls.js +1373 -380
  449. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  450. package/dist/frontend/lowering/lower-classes.d.ts +83 -45
  451. package/dist/frontend/lowering/lower-classes.js +952 -339
  452. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  453. package/dist/frontend/lowering/lower-comptime.d.ts +1 -1
  454. package/dist/frontend/lowering/lower-comptime.js +23 -32
  455. package/dist/frontend/lowering/lower-comptime.js.map +1 -1
  456. package/dist/frontend/lowering/lower-containers.d.ts +27 -32
  457. package/dist/frontend/lowering/lower-containers.js +796 -151
  458. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  459. package/dist/frontend/lowering/lower-dgram.d.ts +1 -1
  460. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  461. package/dist/frontend/lowering/lower-enums.d.ts +1 -1
  462. package/dist/frontend/lowering/lower-enums.js.map +1 -1
  463. package/dist/frontend/lowering/lower-event-emitter.d.ts +30 -1
  464. package/dist/frontend/lowering/lower-event-emitter.js +58 -26
  465. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  466. package/dist/frontend/lowering/lower-expando.d.ts +7 -1
  467. package/dist/frontend/lowering/lower-expando.js +14 -6
  468. package/dist/frontend/lowering/lower-expando.js.map +1 -1
  469. package/dist/frontend/lowering/lower-exprs.d.ts +35 -11
  470. package/dist/frontend/lowering/lower-exprs.js +1785 -790
  471. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  472. package/dist/frontend/lowering/lower-generators.d.ts +2 -5
  473. package/dist/frontend/lowering/lower-generators.js +77 -46
  474. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  475. package/dist/frontend/lowering/lower-global-value.d.ts +7 -0
  476. package/dist/frontend/lowering/lower-global-value.js +17 -0
  477. package/dist/frontend/lowering/lower-global-value.js.map +1 -0
  478. package/dist/frontend/lowering/lower-inspect.d.ts +1 -1
  479. package/dist/frontend/lowering/lower-inspect.js +17 -8
  480. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  481. package/dist/frontend/lowering/lower-island.d.ts +5 -8
  482. package/dist/frontend/lowering/lower-island.js +34 -23
  483. package/dist/frontend/lowering/lower-island.js.map +1 -1
  484. package/dist/frontend/lowering/lower-mixins.d.ts +2 -2
  485. package/dist/frontend/lowering/lower-mixins.js +5 -3
  486. package/dist/frontend/lowering/lower-mixins.js.map +1 -1
  487. package/dist/frontend/lowering/lower-modules.d.ts +1 -1
  488. package/dist/frontend/lowering/lower-modules.js +252 -38
  489. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  490. package/dist/frontend/lowering/lower-namespaces.d.ts +1 -1
  491. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  492. package/dist/frontend/lowering/lower-node-module.d.ts +1 -1
  493. package/dist/frontend/lowering/lower-node-module.js +13 -10
  494. package/dist/frontend/lowering/lower-node-module.js.map +1 -1
  495. package/dist/frontend/lowering/lower-server.d.ts +1 -1
  496. package/dist/frontend/lowering/lower-server.js +6 -10
  497. package/dist/frontend/lowering/lower-server.js.map +1 -1
  498. package/dist/frontend/lowering/lower-stmts.d.ts +10 -14
  499. package/dist/frontend/lowering/lower-stmts.js +731 -532
  500. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  501. package/dist/frontend/lowering/lower-stream.d.ts +1 -1
  502. package/dist/frontend/lowering/lower-stream.js +19 -10
  503. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  504. package/dist/frontend/lowering/lower-test.d.ts +1 -1
  505. package/dist/frontend/lowering/lower-test.js.map +1 -1
  506. package/dist/frontend/lowering/lower-url.d.ts +6 -0
  507. package/dist/frontend/lowering/lower-url.js +77 -0
  508. package/dist/frontend/lowering/lower-url.js.map +1 -0
  509. package/dist/frontend/lowering/lowerer.d.ts +113 -189
  510. package/dist/frontend/lowering/lowerer.js +1033 -663
  511. package/dist/frontend/lowering/lowerer.js.map +1 -1
  512. package/dist/frontend/lowering/lowerer.test.d.ts +1 -0
  513. package/dist/frontend/lowering/lowerer.test.js +26 -0
  514. package/dist/frontend/lowering/lowerer.test.js.map +1 -0
  515. package/dist/frontend/lowering/native-ffi.d.ts +5 -0
  516. package/dist/frontend/lowering/native-ffi.js +40 -0
  517. package/dist/frontend/lowering/native-ffi.js.map +1 -0
  518. package/dist/frontend/lowering/object-enumeration-receiver.d.ts +7 -0
  519. package/dist/frontend/lowering/object-enumeration-receiver.js +33 -0
  520. package/dist/frontend/lowering/object-enumeration-receiver.js.map +1 -0
  521. package/dist/frontend/lowering/object-factory-new.d.ts +8 -0
  522. package/dist/frontend/lowering/object-factory-new.js +68 -0
  523. package/dist/frontend/lowering/object-factory-new.js.map +1 -0
  524. package/dist/frontend/lowering/optional-arguments.js +6 -1
  525. package/dist/frontend/lowering/optional-arguments.js.map +1 -1
  526. package/dist/frontend/lowering/pairs-snapshot.js +2 -1
  527. package/dist/frontend/lowering/pairs-snapshot.js.map +1 -1
  528. package/dist/frontend/lowering/runtime-optional-locals.d.ts +14 -0
  529. package/dist/frontend/lowering/runtime-optional-locals.js +41 -0
  530. package/dist/frontend/lowering/runtime-optional-locals.js.map +1 -0
  531. package/dist/frontend/lowering/runtime-optional-locals.test.d.ts +1 -0
  532. package/dist/frontend/lowering/runtime-optional-locals.test.js +85 -0
  533. package/dist/frontend/lowering/runtime-optional-locals.test.js.map +1 -0
  534. package/dist/frontend/lowering/sanitize-class-types.d.ts +8 -0
  535. package/dist/frontend/lowering/sanitize-class-types.js +79 -0
  536. package/dist/frontend/lowering/sanitize-class-types.js.map +1 -0
  537. package/dist/frontend/lowering/sanitize-class-types.test.d.ts +1 -0
  538. package/dist/frontend/lowering/sanitize-class-types.test.js +60 -0
  539. package/dist/frontend/lowering/sanitize-class-types.test.js.map +1 -0
  540. package/dist/frontend/lowering/static-this.d.ts +5 -1
  541. package/dist/frontend/lowering/static-this.js +28 -2
  542. package/dist/frontend/lowering/static-this.js.map +1 -1
  543. package/dist/frontend/lowering/string-index.d.ts +7 -0
  544. package/dist/frontend/lowering/string-index.js +39 -0
  545. package/dist/frontend/lowering/string-index.js.map +1 -0
  546. package/dist/frontend/lowering/surfaces.d.ts +9 -4
  547. package/dist/frontend/lowering/surfaces.js +98 -35
  548. package/dist/frontend/lowering/surfaces.js.map +1 -1
  549. package/dist/frontend/lowering/symbol-fields.d.ts +22 -0
  550. package/dist/frontend/lowering/symbol-fields.js +183 -0
  551. package/dist/frontend/lowering/symbol-fields.js.map +1 -0
  552. package/dist/frontend/lowering/symbol-methods.d.ts +7 -0
  553. package/dist/frontend/lowering/symbol-methods.js +30 -0
  554. package/dist/frontend/lowering/symbol-methods.js.map +1 -0
  555. package/dist/frontend/lowering/text-decoder-encoding.d.ts +10 -0
  556. package/dist/frontend/lowering/text-decoder-encoding.js +77 -0
  557. package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -0
  558. package/dist/frontend/lowering/text-decoder-encoding.test.d.ts +1 -0
  559. package/dist/frontend/lowering/text-decoder-encoding.test.js +38 -0
  560. package/dist/frontend/lowering/text-decoder-encoding.test.js.map +1 -0
  561. package/dist/frontend/lowering/union-narrow.d.ts +9 -0
  562. package/dist/frontend/lowering/union-narrow.js +59 -0
  563. package/dist/frontend/lowering/union-narrow.js.map +1 -0
  564. package/dist/frontend/lowering/union-narrow.test.d.ts +1 -0
  565. package/dist/frontend/lowering/union-narrow.test.js +72 -0
  566. package/dist/frontend/lowering/union-narrow.test.js.map +1 -0
  567. package/dist/frontend/lowering/union-retag.d.ts +43 -0
  568. package/dist/frontend/lowering/union-retag.js +259 -0
  569. package/dist/frontend/lowering/union-retag.js.map +1 -0
  570. package/dist/frontend/lowering/union-retag.test.d.ts +1 -0
  571. package/dist/frontend/lowering/union-retag.test.js +405 -0
  572. package/dist/frontend/lowering/union-retag.test.js.map +1 -0
  573. package/dist/frontend/lowering/unregistered-class-types.d.ts +14 -0
  574. package/dist/frontend/lowering/unregistered-class-types.js +94 -0
  575. package/dist/frontend/lowering/unregistered-class-types.js.map +1 -0
  576. package/dist/frontend/lowering/unregistered-class-types.test.d.ts +1 -0
  577. package/dist/frontend/lowering/unregistered-class-types.test.js +65 -0
  578. package/dist/frontend/lowering/unregistered-class-types.test.js.map +1 -0
  579. package/dist/frontend/lowering/width-lift.d.ts +40 -0
  580. package/dist/frontend/lowering/width-lift.js +2 -0
  581. package/dist/frontend/lowering/width-lift.js.map +1 -0
  582. package/dist/frontend/module-syntax.d.ts +58 -0
  583. package/dist/frontend/module-syntax.js +123 -0
  584. package/dist/frontend/module-syntax.js.map +1 -0
  585. package/dist/frontend/module-syntax.test.d.ts +1 -0
  586. package/dist/frontend/module-syntax.test.js +78 -0
  587. package/dist/frontend/module-syntax.test.js.map +1 -0
  588. package/dist/frontend/npm-fetch-analysis.d.ts +17 -0
  589. package/dist/frontend/npm-fetch-analysis.js +100 -0
  590. package/dist/frontend/npm-fetch-analysis.js.map +1 -0
  591. package/dist/frontend/npm-fetch-analysis.test.d.ts +1 -0
  592. package/dist/frontend/npm-fetch-analysis.test.js +107 -0
  593. package/dist/frontend/npm-fetch-analysis.test.js.map +1 -0
  594. package/dist/frontend/npm-fetch-node.d.ts +2 -0
  595. package/dist/frontend/npm-fetch-node.js +12 -0
  596. package/dist/frontend/npm-fetch-node.js.map +1 -0
  597. package/dist/frontend/npm-fetch-syntax.d.ts +6 -0
  598. package/dist/frontend/npm-fetch-syntax.js +207 -0
  599. package/dist/frontend/npm-fetch-syntax.js.map +1 -0
  600. package/dist/frontend/npm-node.d.ts +10 -0
  601. package/dist/frontend/npm-node.js +14 -0
  602. package/dist/frontend/npm-node.js.map +1 -0
  603. package/dist/frontend/npm-static-bundled-cjs.d.ts +8 -0
  604. package/dist/frontend/npm-static-bundled-cjs.js +236 -0
  605. package/dist/frontend/npm-static-bundled-cjs.js.map +1 -0
  606. package/dist/frontend/npm-static-bundled-cjs.test.d.ts +1 -0
  607. package/dist/frontend/npm-static-bundled-cjs.test.js +69 -0
  608. package/dist/frontend/npm-static-bundled-cjs.test.js.map +1 -0
  609. package/dist/frontend/npm-static-declaration-syntax.d.ts +57 -0
  610. package/dist/frontend/npm-static-declaration-syntax.js +944 -0
  611. package/dist/frontend/npm-static-declaration-syntax.js.map +1 -0
  612. package/dist/frontend/npm-static-declarations.d.ts +11 -39
  613. package/dist/frontend/npm-static-declarations.js +22 -561
  614. package/dist/frontend/npm-static-declarations.js.map +1 -1
  615. package/dist/frontend/npm-static-declarations.test.js +245 -6
  616. package/dist/frontend/npm-static-declarations.test.js.map +1 -1
  617. package/dist/frontend/npm-static-prune.d.ts +1 -1
  618. package/dist/frontend/npm-static-prune.js +5 -4
  619. package/dist/frontend/npm-static-prune.js.map +1 -1
  620. package/dist/frontend/npm-static-prune.test.js +1 -1
  621. package/dist/frontend/npm-static-prune.test.js.map +1 -1
  622. package/dist/frontend/npm-static-rewrite-host.d.ts +4 -0
  623. package/dist/frontend/npm-static-rewrite-host.js +179 -0
  624. package/dist/frontend/npm-static-rewrite-host.js.map +1 -0
  625. package/dist/frontend/npm-static-rewrite-syntax.d.ts +16 -0
  626. package/dist/frontend/npm-static-rewrite-syntax.js +905 -0
  627. package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -0
  628. package/dist/frontend/npm-static-rewrite.d.ts +0 -5
  629. package/dist/frontend/npm-static-rewrite.js +2 -1079
  630. package/dist/frontend/npm-static-rewrite.js.map +1 -1
  631. package/dist/frontend/npm-static-subtyping.d.ts +5 -0
  632. package/dist/frontend/npm-static-subtyping.js +55 -0
  633. package/dist/frontend/npm-static-subtyping.js.map +1 -0
  634. package/dist/frontend/npm-static-subtyping.test.d.ts +1 -0
  635. package/dist/frontend/npm-static-subtyping.test.js +58 -0
  636. package/dist/frontend/npm-static-subtyping.test.js.map +1 -0
  637. package/dist/frontend/npm-static.d.ts +7 -15
  638. package/dist/frontend/npm-static.js +19 -28
  639. package/dist/frontend/npm-static.js.map +1 -1
  640. package/dist/frontend/npm.d.ts +8 -69
  641. package/dist/frontend/npm.js +21 -361
  642. package/dist/frontend/npm.js.map +1 -1
  643. package/dist/frontend/npm.test.js +2 -2
  644. package/dist/frontend/npm.test.js.map +1 -1
  645. package/dist/frontend/pipeline-native.d.ts +6 -0
  646. package/dist/frontend/pipeline-native.js +32 -0
  647. package/dist/frontend/pipeline-native.js.map +1 -0
  648. package/dist/frontend/pipeline.d.ts +54 -0
  649. package/dist/frontend/pipeline.js +382 -0
  650. package/dist/frontend/pipeline.js.map +1 -0
  651. package/dist/frontend/pipeline.test.d.ts +1 -0
  652. package/dist/frontend/pipeline.test.js +77 -0
  653. package/dist/frontend/pipeline.test.js.map +1 -0
  654. package/dist/frontend/program-analysis.d.ts +10 -0
  655. package/dist/frontend/program-analysis.js +14 -0
  656. package/dist/frontend/program-analysis.js.map +1 -0
  657. package/dist/frontend/program-node.d.ts +9 -0
  658. package/dist/frontend/program-node.js +48 -0
  659. package/dist/frontend/program-node.js.map +1 -0
  660. package/dist/frontend/program.d.ts +43 -19
  661. package/dist/frontend/program.js +556 -197
  662. package/dist/frontend/program.js.map +1 -1
  663. package/dist/frontend/program.test.d.ts +1 -0
  664. package/dist/frontend/program.test.js +202 -0
  665. package/dist/frontend/program.test.js.map +1 -0
  666. package/dist/frontend/provenance-core.d.ts +9 -0
  667. package/dist/frontend/provenance-core.js +435 -0
  668. package/dist/frontend/provenance-core.js.map +1 -0
  669. package/dist/frontend/provenance.d.ts +0 -4
  670. package/dist/frontend/provenance.js +4 -459
  671. package/dist/frontend/provenance.js.map +1 -1
  672. package/dist/frontend/resolve.d.ts +3 -1
  673. package/dist/frontend/resolve.js +6 -3
  674. package/dist/frontend/resolve.js.map +1 -1
  675. package/dist/frontend/runtime-resolve.d.ts +4 -3
  676. package/dist/frontend/runtime-resolve.js +22 -18
  677. package/dist/frontend/runtime-resolve.js.map +1 -1
  678. package/dist/frontend/runtime-resolve.test.js +53 -0
  679. package/dist/frontend/runtime-resolve.test.js.map +1 -1
  680. package/dist/frontend/services-node.d.ts +5 -0
  681. package/dist/frontend/services-node.js +19 -0
  682. package/dist/frontend/services-node.js.map +1 -0
  683. package/dist/frontend/services-node.test.d.ts +1 -0
  684. package/dist/frontend/services-node.test.js +70 -0
  685. package/dist/frontend/services-node.test.js.map +1 -0
  686. package/dist/frontend/services.d.ts +44 -0
  687. package/dist/frontend/services.js +90 -0
  688. package/dist/frontend/services.js.map +1 -0
  689. package/dist/frontend/services.test.d.ts +1 -0
  690. package/dist/frontend/services.test.js +174 -0
  691. package/dist/frontend/services.test.js.map +1 -0
  692. package/dist/frontend/ts7/adapter.d.ts +3 -3
  693. package/dist/frontend/ts7/adapter.js +14 -31
  694. package/dist/frontend/ts7/adapter.js.map +1 -1
  695. package/dist/frontend/ts7/api.d.ts +16 -0
  696. package/dist/frontend/ts7/api.js +24 -0
  697. package/dist/frontend/ts7/api.js.map +1 -0
  698. package/dist/frontend/ts7/ast-bytes.d.ts +31 -0
  699. package/dist/frontend/ts7/ast-bytes.js +137 -0
  700. package/dist/frontend/ts7/ast-bytes.js.map +1 -0
  701. package/dist/frontend/ts7/ast-bytes.test.d.ts +1 -0
  702. package/dist/frontend/ts7/ast-bytes.test.js +73 -0
  703. package/dist/frontend/ts7/ast-bytes.test.js.map +1 -0
  704. package/dist/frontend/ts7/ast-guards.generated.d.ts +353 -0
  705. package/dist/frontend/ts7/ast-guards.generated.js +1951 -0
  706. package/dist/frontend/ts7/ast-guards.generated.js.map +1 -0
  707. package/dist/frontend/ts7/ast-guards.test.d.ts +1 -0
  708. package/dist/frontend/ts7/ast-guards.test.js +43 -0
  709. package/dist/frontend/ts7/ast-guards.test.js.map +1 -0
  710. package/dist/frontend/ts7/ast-node.d.ts +194 -0
  711. package/dist/frontend/ts7/ast-node.js +448 -0
  712. package/dist/frontend/ts7/ast-node.js.map +1 -0
  713. package/dist/frontend/ts7/ast-node.test.d.ts +1 -0
  714. package/dist/frontend/ts7/ast-node.test.js +266 -0
  715. package/dist/frontend/ts7/ast-node.test.js.map +1 -0
  716. package/dist/frontend/ts7/ast-schema.generated.d.ts +503 -0
  717. package/dist/frontend/ts7/ast-schema.generated.js +1446 -0
  718. package/dist/frontend/ts7/ast-schema.generated.js.map +1 -0
  719. package/dist/frontend/ts7/ast-text.d.ts +6 -0
  720. package/dist/frontend/ts7/ast-text.js +124 -0
  721. package/dist/frontend/ts7/ast-text.js.map +1 -0
  722. package/dist/frontend/ts7/ast-text.test.d.ts +1 -0
  723. package/dist/frontend/ts7/ast-text.test.js +38 -0
  724. package/dist/frontend/ts7/ast-text.test.js.map +1 -0
  725. package/dist/frontend/ts7/ast-tokens.generated.d.ts +2 -0
  726. package/dist/frontend/ts7/ast-tokens.generated.js +155 -0
  727. package/dist/frontend/ts7/ast-tokens.generated.js.map +1 -0
  728. package/dist/frontend/ts7/ast-types.d.ts +42 -0
  729. package/dist/frontend/ts7/ast-types.generated.d.ts +1615 -0
  730. package/dist/frontend/ts7/ast-types.generated.js +5 -0
  731. package/dist/frontend/ts7/ast-types.generated.js.map +1 -0
  732. package/dist/frontend/ts7/ast-types.js +3 -0
  733. package/dist/frontend/ts7/ast-types.js.map +1 -0
  734. package/dist/frontend/ts7/ast-wire.d.ts +58 -0
  735. package/dist/frontend/ts7/ast-wire.js +267 -0
  736. package/dist/frontend/ts7/ast-wire.js.map +1 -0
  737. package/dist/frontend/ts7/ast-wire.test.d.ts +1 -0
  738. package/dist/frontend/ts7/ast-wire.test.js +151 -0
  739. package/dist/frontend/ts7/ast-wire.test.js.map +1 -0
  740. package/dist/frontend/ts7/ast.d.ts +14 -14
  741. package/dist/frontend/ts7/ast.js +21 -15
  742. package/dist/frontend/ts7/ast.js.map +1 -1
  743. package/dist/frontend/ts7/census-check.js +1 -0
  744. package/dist/frontend/ts7/census-check.js.map +1 -1
  745. package/dist/frontend/ts7/checker-cache.d.ts +48 -0
  746. package/dist/frontend/ts7/checker-cache.js +92 -0
  747. package/dist/frontend/ts7/checker-cache.js.map +1 -0
  748. package/dist/frontend/ts7/checker.d.ts +19 -46
  749. package/dist/frontend/ts7/checker.js +231 -161
  750. package/dist/frontend/ts7/checker.js.map +1 -1
  751. package/dist/frontend/ts7/checker.test.d.ts +1 -0
  752. package/dist/frontend/ts7/checker.test.js +335 -0
  753. package/dist/frontend/ts7/checker.test.js.map +1 -0
  754. package/dist/frontend/ts7/enums.d.ts +4 -27
  755. package/dist/frontend/ts7/enums.generated.d.ts +878 -0
  756. package/dist/frontend/ts7/enums.generated.js +1313 -0
  757. package/dist/frontend/ts7/enums.generated.js.map +1 -0
  758. package/dist/frontend/ts7/enums.js +4 -45
  759. package/dist/frontend/ts7/enums.js.map +1 -1
  760. package/dist/frontend/ts7/enums.test.d.ts +1 -0
  761. package/dist/frontend/ts7/enums.test.js +48 -0
  762. package/dist/frontend/ts7/enums.test.js.map +1 -0
  763. package/dist/frontend/ts7/native-api.d.ts +10 -0
  764. package/dist/frontend/ts7/native-api.js +10 -0
  765. package/dist/frontend/ts7/native-api.js.map +1 -0
  766. package/dist/frontend/ts7/native-host.d.ts +2 -0
  767. package/dist/frontend/ts7/native-host.js +11 -0
  768. package/dist/frontend/ts7/native-host.js.map +1 -0
  769. package/dist/frontend/ts7/native-process.d.ts +14 -0
  770. package/dist/frontend/ts7/native-process.js +62 -0
  771. package/dist/frontend/ts7/native-process.js.map +1 -0
  772. package/dist/frontend/ts7/program-adapter.d.ts +10 -98
  773. package/dist/frontend/ts7/program-adapter.js +16 -310
  774. package/dist/frontend/ts7/program-adapter.js.map +1 -1
  775. package/dist/frontend/ts7/program-host.d.ts +115 -0
  776. package/dist/frontend/ts7/program-host.js +347 -0
  777. package/dist/frontend/ts7/program-host.js.map +1 -0
  778. package/dist/frontend/ts7/program-host.test.d.ts +1 -0
  779. package/dist/frontend/ts7/program-host.test.js +207 -0
  780. package/dist/frontend/ts7/program-host.test.js.map +1 -0
  781. package/dist/frontend/ts7/rpc-api.d.ts +12 -0
  782. package/dist/frontend/ts7/rpc-api.js +23 -0
  783. package/dist/frontend/ts7/rpc-api.js.map +1 -0
  784. package/dist/frontend/ts7/rpc-client.d.ts +27 -0
  785. package/dist/frontend/ts7/rpc-client.js +102 -0
  786. package/dist/frontend/ts7/rpc-client.js.map +1 -0
  787. package/dist/frontend/ts7/rpc-client.test.d.ts +1 -0
  788. package/dist/frontend/ts7/rpc-client.test.js +133 -0
  789. package/dist/frontend/ts7/rpc-client.test.js.map +1 -0
  790. package/dist/frontend/ts7/rpc-filesystem.d.ts +16 -0
  791. package/dist/frontend/ts7/rpc-filesystem.js +42 -0
  792. package/dist/frontend/ts7/rpc-filesystem.js.map +1 -0
  793. package/dist/frontend/ts7/rpc-filesystem.test.d.ts +1 -0
  794. package/dist/frontend/ts7/rpc-filesystem.test.js +89 -0
  795. package/dist/frontend/ts7/rpc-filesystem.test.js.map +1 -0
  796. package/dist/frontend/ts7/rpc-process.d.ts +2 -0
  797. package/dist/frontend/ts7/rpc-process.js +148 -0
  798. package/dist/frontend/ts7/rpc-process.js.map +1 -0
  799. package/dist/frontend/ts7/rpc-process.test.d.ts +1 -0
  800. package/dist/frontend/ts7/rpc-process.test.js +29 -0
  801. package/dist/frontend/ts7/rpc-process.test.js.map +1 -0
  802. package/dist/frontend/ts7/rpc-wire.d.ts +46 -0
  803. package/dist/frontend/ts7/rpc-wire.js +195 -0
  804. package/dist/frontend/ts7/rpc-wire.js.map +1 -0
  805. package/dist/frontend/ts7/rpc-wire.test.d.ts +1 -0
  806. package/dist/frontend/ts7/rpc-wire.test.js +168 -0
  807. package/dist/frontend/ts7/rpc-wire.test.js.map +1 -0
  808. package/dist/frontend/ts7/semantic-checker.d.ts +137 -0
  809. package/dist/frontend/ts7/semantic-checker.js +221 -0
  810. package/dist/frontend/ts7/semantic-checker.js.map +1 -0
  811. package/dist/frontend/ts7/semantic-checker.test.d.ts +1 -0
  812. package/dist/frontend/ts7/semantic-checker.test.js +119 -0
  813. package/dist/frontend/ts7/semantic-checker.test.js.map +1 -0
  814. package/dist/frontend/ts7/semantic-json.d.ts +5 -0
  815. package/dist/frontend/ts7/semantic-json.js +52 -0
  816. package/dist/frontend/ts7/semantic-json.js.map +1 -0
  817. package/dist/frontend/ts7/semantic-json.test.d.ts +1 -0
  818. package/dist/frontend/ts7/semantic-json.test.js +42 -0
  819. package/dist/frontend/ts7/semantic-json.test.js.map +1 -0
  820. package/dist/frontend/ts7/semantic-model.d.ts +222 -0
  821. package/dist/frontend/ts7/semantic-model.js +423 -0
  822. package/dist/frontend/ts7/semantic-model.js.map +1 -0
  823. package/dist/frontend/ts7/semantic-model.test.d.ts +1 -0
  824. package/dist/frontend/ts7/semantic-model.test.js +322 -0
  825. package/dist/frontend/ts7/semantic-model.test.js.map +1 -0
  826. package/dist/frontend/ts7/semantic-schema.generated.d.ts +283 -0
  827. package/dist/frontend/ts7/semantic-schema.generated.js +222 -0
  828. package/dist/frontend/ts7/semantic-schema.generated.js.map +1 -0
  829. package/dist/frontend/ts7/semantic-types.d.ts +5 -0
  830. package/dist/frontend/ts7/semantic-types.js +2 -0
  831. package/dist/frontend/ts7/semantic-types.js.map +1 -0
  832. package/dist/frontend/ts7/session-cache.d.ts +17 -0
  833. package/dist/frontend/ts7/session-cache.js +97 -0
  834. package/dist/frontend/ts7/session-cache.js.map +1 -0
  835. package/dist/frontend/ts7/session-cache.test.d.ts +1 -0
  836. package/dist/frontend/ts7/session-cache.test.js +87 -0
  837. package/dist/frontend/ts7/session-cache.test.js.map +1 -0
  838. package/dist/frontend/ts7/session-path.d.ts +18 -0
  839. package/dist/frontend/ts7/session-path.js +203 -0
  840. package/dist/frontend/ts7/session-path.js.map +1 -0
  841. package/dist/frontend/ts7/session-path.test.d.ts +1 -0
  842. package/dist/frontend/ts7/session-path.test.js +34 -0
  843. package/dist/frontend/ts7/session-path.test.js.map +1 -0
  844. package/dist/frontend/ts7/session-schema.generated.d.ts +167 -0
  845. package/dist/frontend/ts7/session-schema.generated.js +5 -0
  846. package/dist/frontend/ts7/session-schema.generated.js.map +1 -0
  847. package/dist/frontend/ts7/session-timing.d.ts +50 -0
  848. package/dist/frontend/ts7/session-timing.js +61 -0
  849. package/dist/frontend/ts7/session-timing.js.map +1 -0
  850. package/dist/frontend/ts7/session-timing.test.d.ts +1 -0
  851. package/dist/frontend/ts7/session-timing.test.js +52 -0
  852. package/dist/frontend/ts7/session-timing.test.js.map +1 -0
  853. package/dist/frontend/ts7/session.d.ts +105 -0
  854. package/dist/frontend/ts7/session.js +233 -0
  855. package/dist/frontend/ts7/session.js.map +1 -0
  856. package/dist/frontend/ts7/session.test.d.ts +1 -0
  857. package/dist/frontend/ts7/session.test.js +215 -0
  858. package/dist/frontend/ts7/session.test.js.map +1 -0
  859. package/dist/frontend/ts7/source-parser-node.d.ts +6 -0
  860. package/dist/frontend/ts7/source-parser-node.js +15 -0
  861. package/dist/frontend/ts7/source-parser-node.js.map +1 -0
  862. package/dist/frontend/ts7/source-parser.d.ts +25 -0
  863. package/dist/frontend/ts7/source-parser.js +96 -0
  864. package/dist/frontend/ts7/source-parser.js.map +1 -0
  865. package/dist/frontend/ts7/source-parser.test.d.ts +1 -0
  866. package/dist/frontend/ts7/source-parser.test.js +151 -0
  867. package/dist/frontend/ts7/source-parser.test.js.map +1 -0
  868. package/dist/frontend/ts7/syntax.d.ts +3 -0
  869. package/dist/frontend/ts7/syntax.js +4 -0
  870. package/dist/frontend/ts7/syntax.js.map +1 -0
  871. package/dist/frontend/tsc-codes.js +3 -0
  872. package/dist/frontend/tsc-codes.js.map +1 -1
  873. package/dist/frontend/type-mapper.d.ts +29 -19
  874. package/dist/frontend/type-mapper.js +713 -306
  875. package/dist/frontend/type-mapper.js.map +1 -1
  876. package/dist/frontend/type-mapper.test.d.ts +1 -0
  877. package/dist/frontend/type-mapper.test.js +207 -0
  878. package/dist/frontend/type-mapper.test.js.map +1 -0
  879. package/dist/frontend/union-discriminants.d.ts +16 -0
  880. package/dist/frontend/union-discriminants.js +98 -0
  881. package/dist/frontend/union-discriminants.js.map +1 -0
  882. package/dist/frontend/union-discriminants.test.d.ts +1 -0
  883. package/dist/frontend/union-discriminants.test.js +182 -0
  884. package/dist/frontend/union-discriminants.test.js.map +1 -0
  885. package/dist/index.d.ts +7 -197
  886. package/dist/index.js +369 -1567
  887. package/dist/index.js.map +1 -1
  888. package/dist/ir/analysis.d.ts +16 -4
  889. package/dist/ir/analysis.js +25 -6
  890. package/dist/ir/analysis.js.map +1 -1
  891. package/dist/ir/analysis.test.js +15 -2
  892. package/dist/ir/analysis.test.js.map +1 -1
  893. package/dist/ir/constant-tables.js +67 -49
  894. package/dist/ir/constant-tables.js.map +1 -1
  895. package/dist/ir/constant-tables.test.js +1 -1
  896. package/dist/ir/control-flow.d.ts +6 -0
  897. package/dist/ir/control-flow.js +142 -0
  898. package/dist/ir/control-flow.js.map +1 -0
  899. package/dist/ir/control-flow.test.d.ts +1 -0
  900. package/dist/ir/control-flow.test.js +113 -0
  901. package/dist/ir/control-flow.test.js.map +1 -0
  902. package/dist/ir/integer-loops.js +7 -18
  903. package/dist/ir/integer-loops.js.map +1 -1
  904. package/dist/ir/integer-ranges.js +53 -27
  905. package/dist/ir/integer-ranges.js.map +1 -1
  906. package/dist/ir/ir.d.ts +309 -164
  907. package/dist/ir/ir.js +588 -879
  908. package/dist/ir/ir.js.map +1 -1
  909. package/dist/ir/ir.test.js +127 -1
  910. package/dist/ir/ir.test.js.map +1 -1
  911. package/dist/ir/scalar-records.js +165 -134
  912. package/dist/ir/scalar-records.js.map +1 -1
  913. package/dist/ir/scalar-records.test.js +1 -1
  914. package/dist/ir/serialize.d.ts +4 -2
  915. package/dist/ir/serialize.js +19 -12
  916. package/dist/ir/serialize.js.map +1 -1
  917. package/dist/ir/serialize.test.d.ts +1 -0
  918. package/dist/ir/serialize.test.js +53 -0
  919. package/dist/ir/serialize.test.js.map +1 -0
  920. package/dist/ir/traverse.d.ts +41 -0
  921. package/dist/ir/traverse.js +660 -0
  922. package/dist/ir/traverse.js.map +1 -0
  923. package/dist/ir/traverse.test.d.ts +1 -0
  924. package/dist/ir/traverse.test.js +242 -0
  925. package/dist/ir/traverse.test.js.map +1 -0
  926. package/dist/ir/validate.js +1956 -1496
  927. package/dist/ir/validate.js.map +1 -1
  928. package/dist/ir/validate.test.js +476 -2
  929. package/dist/ir/validate.test.js.map +1 -1
  930. package/dist/library/cache-primitives.d.ts +2 -3
  931. package/dist/library/cache-primitives.js +4 -6
  932. package/dist/library/cache-primitives.js.map +1 -1
  933. package/dist/library/compiler-self-identity.d.ts +1 -1
  934. package/dist/library/compiler-self-identity.js +31 -15
  935. package/dist/library/compiler-self-identity.js.map +1 -1
  936. package/dist/library/compiler-self-identity.test.d.ts +1 -0
  937. package/dist/library/compiler-self-identity.test.js +93 -0
  938. package/dist/library/compiler-self-identity.test.js.map +1 -0
  939. package/dist/library/fence-eval.js +2 -2
  940. package/dist/library/fence-eval.js.map +1 -1
  941. package/dist/library/int-infer.js +7 -6
  942. package/dist/library/int-infer.js.map +1 -1
  943. package/dist/library/int-infer.test.js +4 -4
  944. package/dist/library/library-cache.d.ts +3 -2
  945. package/dist/library/library-cache.js +5 -17
  946. package/dist/library/library-cache.js.map +1 -1
  947. package/dist/library/library-cache.test.js +54 -41
  948. package/dist/library/library-cache.test.js.map +1 -1
  949. package/dist/library/library-profile.d.ts +3 -1
  950. package/dist/library/library-profile.js +15 -6
  951. package/dist/library/library-profile.js.map +1 -1
  952. package/dist/library/prepare.d.ts +15 -0
  953. package/dist/library/prepare.js +584 -0
  954. package/dist/library/prepare.js.map +1 -0
  955. package/dist/library/semantic-source.d.ts +1 -1
  956. package/dist/library/semantic-source.js +8 -6
  957. package/dist/library/semantic-source.js.map +1 -1
  958. package/dist/library/sidecar-validate.js +4 -4
  959. package/dist/library/sidecar-validate.js.map +1 -1
  960. package/dist/library/sidecar.d.ts +2 -0
  961. package/dist/library/sidecar.js +10 -3
  962. package/dist/library/sidecar.js.map +1 -1
  963. package/dist/native/cache.d.ts +11 -0
  964. package/dist/native/cache.js +113 -0
  965. package/dist/native/cache.js.map +1 -0
  966. package/dist/native/cache.test.d.ts +1 -0
  967. package/dist/native/cache.test.js +66 -0
  968. package/dist/native/cache.test.js.map +1 -0
  969. package/dist/native/cli.d.ts +1 -0
  970. package/dist/native/cli.js +112 -0
  971. package/dist/native/cli.js.map +1 -0
  972. package/dist/native/compiler.d.ts +15 -0
  973. package/dist/native/compiler.js +336 -0
  974. package/dist/native/compiler.js.map +1 -0
  975. package/dist/native/compiler.test.d.ts +1 -0
  976. package/dist/native/compiler.test.js +174 -0
  977. package/dist/native/compiler.test.js.map +1 -0
  978. package/dist/native/comptime.d.ts +5 -0
  979. package/dist/native/comptime.js +73 -0
  980. package/dist/native/comptime.js.map +1 -0
  981. package/dist/native/comptime.test.d.ts +1 -0
  982. package/dist/native/comptime.test.js +65 -0
  983. package/dist/native/comptime.test.js.map +1 -0
  984. package/dist/native/executable-cache.d.ts +26 -0
  985. package/dist/native/executable-cache.js +228 -0
  986. package/dist/native/executable-cache.js.map +1 -0
  987. package/dist/native/executable-cache.test.d.ts +1 -0
  988. package/dist/native/executable-cache.test.js +151 -0
  989. package/dist/native/executable-cache.test.js.map +1 -0
  990. package/dist/native/file-identity.d.ts +4 -0
  991. package/dist/native/file-identity.js +14 -0
  992. package/dist/native/file-identity.js.map +1 -0
  993. package/dist/native/file-identity.test.d.ts +1 -0
  994. package/dist/native/file-identity.test.js +43 -0
  995. package/dist/native/file-identity.test.js.map +1 -0
  996. package/dist/native/library.d.ts +22 -0
  997. package/dist/native/library.js +83 -0
  998. package/dist/native/library.js.map +1 -0
  999. package/dist/native/prepare.d.ts +21 -0
  1000. package/dist/native/prepare.js +174 -0
  1001. package/dist/native/prepare.js.map +1 -0
  1002. package/dist/native/prepare.test.d.ts +1 -0
  1003. package/dist/native/prepare.test.js +70 -0
  1004. package/dist/native/prepare.test.js.map +1 -0
  1005. package/dist/native/sanitizer.d.ts +11 -0
  1006. package/dist/native/sanitizer.js +135 -0
  1007. package/dist/native/sanitizer.js.map +1 -0
  1008. package/dist/native/sanitizer.test.d.ts +1 -0
  1009. package/dist/native/sanitizer.test.js +58 -0
  1010. package/dist/native/sanitizer.test.js.map +1 -0
  1011. package/dist/native/task.d.ts +4 -0
  1012. package/dist/native/task.js +16 -0
  1013. package/dist/native/task.js.map +1 -0
  1014. package/dist/native/task.test.d.ts +1 -0
  1015. package/dist/native/task.test.js +17 -0
  1016. package/dist/native/task.test.js.map +1 -0
  1017. package/dist/native/toolchain.d.ts +45 -0
  1018. package/dist/native/toolchain.js +74 -0
  1019. package/dist/native/toolchain.js.map +1 -0
  1020. package/dist/native/toolchain.test.d.ts +1 -0
  1021. package/dist/native/toolchain.test.js +33 -0
  1022. package/dist/native/toolchain.test.js.map +1 -0
  1023. package/dist/startup-cache.d.ts +1 -1
  1024. package/dist/startup-cache.js +2 -5
  1025. package/dist/startup-cache.js.map +1 -1
  1026. package/dist/timing.d.ts +4 -0
  1027. package/dist/timing.js +19 -0
  1028. package/dist/timing.js.map +1 -0
  1029. package/dist/wasi-paths.js +10 -7
  1030. package/dist/wasi-paths.js.map +1 -1
  1031. package/package.json +28 -19
  1032. package/surface-manifest.json +171 -18
  1033. package/dist/backend/c/async.d.ts +0 -171
  1034. package/dist/backend/c/async.js +0 -1317
  1035. package/dist/backend/c/async.js.map +0 -1
  1036. package/dist/backend/c/c-emitter.d.ts +0 -531
  1037. package/dist/backend/c/c-emitter.js +0 -1917
  1038. package/dist/backend/c/c-emitter.js.map +0 -1
  1039. package/dist/backend/c/exprs.d.ts +0 -15
  1040. package/dist/backend/c/exprs.js +0 -8803
  1041. package/dist/backend/c/exprs.js.map +0 -1
  1042. package/dist/backend/c/island.d.ts +0 -45
  1043. package/dist/backend/c/island.js +0 -281
  1044. package/dist/backend/c/island.js.map +0 -1
  1045. package/dist/backend/c/may-throw.js.map +0 -1
  1046. package/dist/backend/c/shapes.d.ts +0 -142
  1047. package/dist/backend/c/shapes.js +0 -603
  1048. package/dist/backend/c/shapes.js.map +0 -1
  1049. package/dist/backend/c/stmts.d.ts +0 -76
  1050. package/dist/backend/c/stmts.js +0 -1084
  1051. package/dist/backend/c/stmts.js.map +0 -1
  1052. package/dist/backend/c/types.d.ts +0 -71
  1053. package/dist/backend/c/types.js +0 -459
  1054. package/dist/backend/c/types.js.map +0 -1
  1055. package/dist/backend/c/types.test.js +0 -32
  1056. package/dist/backend/c/types.test.js.map +0 -1
  1057. package/dist/backend/c/walkers.d.ts +0 -134
  1058. package/dist/backend/c/walkers.js +0 -1773
  1059. package/dist/backend/c/walkers.js.map +0 -1
  1060. /package/dist/backend/{c/types.test.d.ts → cycle-analysis.test.d.ts} +0 -0
@@ -1,80 +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 } from "../mangle.js";
76
34
  import { BlockBuilder } from "./blocks.js";
77
- import { f64Lit, ffiNativeTypeLl, llvmCommentText } from "./common.js";
35
+ import { LlvmDebugInfo } from "./debug-info.js";
36
+ import { f64Lit, ffiNativeTypeLl, ffiNativeParamLl, ffiNativeReturnLl, llvmCommentText } from "./common.js";
37
+ import { ffiExtendsNarrowIntegers } from "../targets.js";
78
38
  import { emitLiteralExpr, emitOperatorExpr, emitStringExpr, emitContainerExpr, emitRecordExpr } from "./expr-primitives.js";
79
39
  import { emitControlExpr } from "./expr-control.js";
80
40
  import { emitCallExpr } from "./expr-calls.js";
@@ -93,57 +53,60 @@ import { emitChildProcessLibCall, emitAsyncContextLibCall, emitProcessLibCall, e
93
53
  import { emitStreamLibCall } from "./lib-stream.js";
94
54
  import { emitNetworkHttpLibCall } from "./lib-network.js";
95
55
  import { emitAssertInspectLibCall, emitIoLibCall, emitGenericLibCall, emitLibCall } from "./lib-dispatch.js";
96
- import { buildClassGraph, classFieldIndex, classStructSym, emitClassObjDefs, emitClassShapes, } from "./classes.js";
56
+ import { buildClassGraph, classEnvironmentIndex, classFieldIndex, classStructSym, } from "./classes.js";
97
57
  import { LlDyn } from "./dyn.js";
98
58
  import { LlvmUnsupportedError } from "./unsupported.js";
99
59
  import { LlWalkers } from "./walkers.js";
100
- 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, vAdapters, } from "./shapes.js";
101
61
  export { LlvmUnsupportedError } from "./unsupported.js";
102
62
  function ffiCallbackDummyLl(callback) {
103
63
  switch (callback.returns) {
64
+ case "i64":
65
+ case "u64":
66
+ return "i64 0";
67
+ case "pointer":
68
+ return "ptr null";
104
69
  case "void":
105
70
  return "void";
106
71
  case "f64":
107
72
  return "double 0.0";
73
+ case "f32":
74
+ return "float 0.0";
108
75
  case "bool":
109
76
  case "u8":
77
+ case "i8":
110
78
  return "i8 0";
79
+ case "u16":
80
+ case "i16":
81
+ return "i16 0";
111
82
  case "u32":
112
83
  case "i32":
113
84
  return "i32 0";
114
85
  }
115
86
  }
116
87
  export function emitLlvmModule(mod, options = {}) {
117
- return new LlEmitter(scalarizeNumericRecords(mod), options).emit();
118
- }
119
- /** LLVM c"..." payload for a UTF-8 literal, NUL-terminated like the C
120
- * emitter's flexible-array-member initializer. */
121
- function llBytes(bytes) {
122
- let s = "";
123
- for (const b of bytes) {
124
- s +=
125
- b >= 0x20 && b < 0x7f && b !== 0x22 && b !== 0x5c
126
- ? String.fromCharCode(b)
127
- : `\\${b.toString(16).padStart(2, "0").toUpperCase()}`;
128
- }
129
- return `${s}\\00`;
88
+ // Keep source storage intact for debugger inspection in dev builds.
89
+ return new LlEmitter(options.debugSources === undefined ? scalarizeNumericRecords(mod) : mod, options).emit();
130
90
  }
131
91
  function llStrBytes(text) {
132
92
  return llBytes(Buffer.from(text, "utf8"));
133
93
  }
134
- class LlEmitter {
94
+ export class LlEmitter {
135
95
  mod;
96
+ debug;
97
+ debugScope = null;
136
98
  sizeType;
99
+ ffiExtendNarrowIntegers;
137
100
  cycleColorOffset;
138
101
  wasi;
139
102
  emitLibraryIdentity;
140
103
  runtimeAbiMarker;
141
104
  /** Interned string literals: UTF-8 text → { symbol, byte length } —
142
- * first-use order, the C emitter's determinism discipline. */
105
+ * first-use order, the runtime ABI’s determinism discipline. */
143
106
  literals = new Map();
144
107
  /** Interned unit-armed union instances: "unionId:tag" → symbol — one
145
- * immortal (rc == SIZE_MAX) static per (union, unit tag), exactly the
146
- * 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. */
147
110
  unitInstances = new Map();
148
111
  /** Interned regex literals: "<flags>/<pattern>" → { symbol, interned
149
112
  * source/flags literal refs } — one immortal ScrRegex per distinct
@@ -162,10 +125,12 @@ class LlEmitter {
162
125
  /** Type-directed walker functions (JSON serializers, the indent
163
126
  * rewriter, union ToString/join) — interned per typeKey/unionId, defs
164
127
  * flushed with the shape helpers. */
165
- walkers = new LlWalkers(this);
128
+ walkers;
166
129
  /** The dyn (ScrDyn dyn) helper registry — dyn.ts's interned ports of
167
130
  * walkers.ts's dyn slice. */
168
- dyn = new LlDyn(this);
131
+ dyn;
132
+ /** Explicit callback boundary for standalone layout and walker stages. */
133
+ shapeHost;
169
134
  /** External declarations, in first-use order. */
170
135
  decls = new Set();
171
136
  /** Declared functions referenced as values: each needs an env-signature
@@ -188,19 +153,20 @@ class LlEmitter {
188
153
  ffiHasRetainedCallback;
189
154
  ffiHasForeignCallback;
190
155
  globalTypes = new Map();
156
+ tdzGlobals = new Map();
191
157
  constantNumericTables;
192
- /** May-throw analysis (the C emitter's computeMayThrow, shared): pending
158
+ /** May-throw analysis (computeMayThrow): pending
193
159
  * checks are emitted only after calls that can actually raise. */
194
160
  mayThrow;
195
161
  indirectMayThrow;
196
162
  /** Method names with at least one may-throw implementation — the
197
- * virtualCall pending check's key (CEmitter.mayThrowMethods). */
163
+ * virtualCall pending check's key. */
198
164
  mayThrowMethods = new Set();
199
165
  /** setTimeout and friends appeared somewhere: main must run the event
200
- * loop even in programs with no async functions (CEmitter.usesTimers). */
166
+ * loop even in programs with no async functions. */
201
167
  usesTimers = false;
202
168
  /** Emitted ref-kind resolve thunks for new Promise, interned per inner
203
- * typeKey → thunk symbol (CEmitter.resolveThunks). */
169
+ * typeKey → thunk symbol. */
204
170
  resolveThunks = new Map();
205
171
  resolveThunkDefs = [];
206
172
  /** ReadableStream.from adapters keep typed arrays by reference and box
@@ -218,15 +184,16 @@ class LlEmitter {
218
184
  tracedShapes;
219
185
  tracedUnions;
220
186
  /** The class graph (buildClassGraph): preorder numbering, hierarchy
221
- * membership, virtual slot lists — the CEmitter classMeta, ported. */
187
+ * membership, virtual slot lists. */
222
188
  classMeta;
223
189
  /** Class objects (classes as first-class values): className → the
224
190
  * interned .name literal ref — registered during body emission, the
225
191
  * statics and construct thunks assemble around the bodies. */
226
192
  classObjs = new Map();
193
+ unionFieldReadGroups = new Map();
227
194
  /** Preorder intervals of the runtime error classes under THIS module's
228
195
  * class-forest numbering (main() stamps scr_error_vts with them, exactly
229
- * like the C emitter's errorVtStampLines). */
196
+ * like the runtime ABI’s errorVtStampLines). */
230
197
  errorIntervals = [];
231
198
  /** The runtime emitter vtable's preorder interval, when the program
232
199
  * touches node:events (the class def rides the module exactly then) —
@@ -241,6 +208,10 @@ class LlEmitter {
241
208
  B = new BlockBuilder();
242
209
  frames = [];
243
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();
244
215
  /** Enclosing break/continue targets. `kind` separates loops from
245
216
  * switches and labeled blocks: an unlabeled break binds to the innermost
246
217
  * NON-BLOCK entry (loop or switch — blocks only enter the stack when
@@ -256,7 +227,7 @@ class LlEmitter {
256
227
  integerRanges = new Map();
257
228
  /** Enclosing try-with-FINALLY regions, innermost last: a `return`
258
229
  * inside one runs every crossed finally (innermost first) before the
259
- * 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
260
231
  * bodies emitted inline at the return site instead of behind a goto.
261
232
  * `tryDepth` snapshots tryStack.length at region entry: a throw inside
262
233
  * a pending-return finally copy propagates OUT of the completing try
@@ -265,7 +236,7 @@ class LlEmitter {
265
236
  * emitFinallysForJump. */
266
237
  finallyStack = [];
267
238
  /** Enclosing try contexts, innermost last — the compile-time unwind
268
- * targets (CEmitter.tryStack): a pending check or `throw` inside a try
239
+ * targets: a pending check or `throw` inside a try
269
240
  * releases frames/scopes down to the recorded depths and branches to
270
241
  * `label` (the catch, or the exception-path finally) instead of
271
242
  * returning out of the function. Entering a try emits no code. */
@@ -283,16 +254,22 @@ class LlEmitter {
283
254
  /** Active optional-chain bind slots, by chain id (chainRecv reads). */
284
255
  chainSlots = new Map();
285
256
  logArgSlots = 0;
257
+ stackTraces;
286
258
  constructor(mod, options) {
287
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
+ }));
263
+ this.debug = options.debugSources === undefined ? null : new LlvmDebugInfo(mod.sourceFile, options.debugSources, options.pointerBits, mod.unions);
288
264
  this.constantNumericTables = findConstantNumericTables(mod);
289
265
  this.sizeType = options.pointerBits === 32 ? "i32" : "i64";
266
+ this.ffiExtendNarrowIntegers = options.wasi === true || ffiExtendsNarrowIntegers(options.targetTriple);
290
267
  this.wasi = options.wasi === true;
291
268
  this.emitLibraryIdentity = options.emitLibraryIdentity !== false;
292
269
  this.runtimeAbiMarker = options.runtimeAbiMarker === true;
293
- // ScrCycHdr is { ptr trace; ptr free; i32 color; i16 buffered;
294
- // i16 gen; size_t buf_index }. The object follows it, so color is 12
295
- // 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.
296
273
  this.cycleColorOffset = options.pointerBits === 32 ? 12 : 16;
297
274
  this.ffiCallbackAdapters = allocateFfiCallbackAdapters(mod.ffiImports ?? []);
298
275
  this.ffiHasRetainedCallback = hasRetainedFfiCallback(mod.ffiImports ?? []);
@@ -318,11 +295,34 @@ class LlEmitter {
318
295
  const traced = computeTraced(mod);
319
296
  this.tracedShapes = traced.shapes;
320
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
+ isErrorClass: (name) => this.classMeta.get(name)?.root.def.name === "%Error",
314
+ classSubtypes: (name) => {
315
+ const target = this.classMetaOf(name);
316
+ return [...this.classMeta.values()].filter((meta) => target.pre <= meta.pre && meta.pre <= target.post).map((meta) => meta.def.name);
317
+ },
318
+ };
319
+ this.walkers = new LlWalkers(this.shapeHost);
320
+ this.dyn = new LlDyn(this.shapeHost);
321
321
  for (const g of mod.globals ?? []) {
322
322
  // Module globals: scalar (f64/bool) storage is a zero-initialized
323
323
  // LLVM global, ref-kind storage a null-initialized ptr — load/store
324
324
  // like a local, assigned by the %init functions. Refcounted globals
325
- // are released at the end of main (the C emitter's
325
+ // are released at the end of main (the runtime ABI’s
326
326
  // sc_release_globals), before the RC audit would run.
327
327
  try {
328
328
  this.llType(g.type); // refuses out-of-tier kinds
@@ -333,12 +333,11 @@ class LlEmitter {
333
333
  throw err;
334
334
  }
335
335
  this.globalTypes.set(g.id, g.type);
336
+ if (g.tdz)
337
+ this.tdzGlobals.set(g.id, g.name);
336
338
  }
337
- // User classes are IN the tier (phase 3), and so are the runtime
338
- // error classes and the runtime EventEmitter/stream classes (phase 6
339
- // — subclasses embed the ScrEmitter/ScrStream prefixes, classes.ts).
340
- // Anything else runtime-flagged refuses by name, exactly the
341
- // classDef:* histogram key.
339
+ // Runtime error, EventEmitter, and stream classes have known layouts.
340
+ // Subclasses embed the ScrEmitter/ScrStream prefixes from classes.ts.
342
341
  const classes = mod.classes ?? [];
343
342
  for (const cls of classes) {
344
343
  if (cls.runtime &&
@@ -349,9 +348,8 @@ class LlEmitter {
349
348
  }
350
349
  }
351
350
  // The class graph: base/children links, hierarchy membership, the
352
- // whole-program preorder numbering (identical to CEmitter's, so
353
- // runtime-made and compiled error objects agree on instanceof through
354
- // either backend), and the per-hierarchy virtual slot lists.
351
+ // whole-program preorder numbering for instanceof over runtime and
352
+ // compiled error objects, and the per-hierarchy virtual slot lists.
355
353
  this.classMeta = buildClassGraph(mod, this.fnByName);
356
354
  for (const [name, rec] of RUNTIME_ERROR_CLASSES) {
357
355
  const meta = this.classMeta.get(name);
@@ -379,7 +377,7 @@ class LlEmitter {
379
377
  }
380
378
  // ── types ───────────────────────────────────────────────────────────────
381
379
  llType(t) {
382
- if (POINTER_KINDS.has(t.kind) && t.kind !== "http2Session" && t.kind !== "http2Stream")
380
+ if (POINTER_KINDS.has(t.kind))
383
381
  return "ptr";
384
382
  switch (t.kind) {
385
383
  case "f64":
@@ -422,7 +420,7 @@ class LlEmitter {
422
420
  if (adapter.tls !== null)
423
421
  globals.push(`@${adapter.tls} = internal thread_local global ptr null`);
424
422
  if (adapter.global !== null)
425
- globals.push(`@${adapter.global} = internal global ptr null`);
423
+ globals.push(`@${adapter.global} = internal thread_local global ptr null`);
426
424
  if (adapter.table !== null) {
427
425
  globals.push(`@${adapter.table} = internal global %ScrFfiTable zeroinitializer`);
428
426
  }
@@ -432,11 +430,11 @@ class LlEmitter {
432
430
  if (param === "string" || param === "bytes") {
433
431
  return [`ptr %a${i}`, `${this.sizeType} %a${i}_len`];
434
432
  }
435
- return [`${ffiNativeTypeLl(param)} %a${i}`];
433
+ return [`${ffiNativeParamLl(param, this.ffiExtendNarrowIntegers)} %a${i}`];
436
434
  });
437
- const ret = ffiNativeTypeLl(cb.returns);
438
435
  if (cb.invoke === "foreign") {
439
- if (adapter.table === null || !cb.params.some(isFfiContextParam) || cb.returns !== "void") {
436
+ if (adapter.table === null || !cb.params.some(isFfiContextParam) || cb.returns !== "void" ||
437
+ cb.params.some(param => param === "i64" || param === "u64" || param === "pointer")) {
440
438
  throw new InternalCompilerError("llvm emitter bug: invalid foreign FFI callback descriptor");
441
439
  }
442
440
  const dispatch = `${adapter.symbol}_dispatch`;
@@ -453,6 +451,10 @@ class LlEmitter {
453
451
  continue;
454
452
  switch (param) {
455
453
  case "f64":
454
+ case "f32":
455
+ case "i8":
456
+ case "u16":
457
+ case "i16":
456
458
  this.declare(`declare double @scr_ffi_call_get_f64(ptr, ${this.sizeType})`);
457
459
  dispatchBody.push(` %s${i} = call double @scr_ffi_call_get_f64(ptr %call, ${this.sizeType} ${i})`);
458
460
  scriptArgs.push(`double %s${i}`);
@@ -489,7 +491,8 @@ class LlEmitter {
489
491
  }
490
492
  }
491
493
  dispatchBody.push(` call void %fn(${[`ptr %cb`, ...scriptArgs].join(", ")})`, ` ret void`, `}`, ``);
492
- defs.push(...dispatchBody);
494
+ for (const line of dispatchBody)
495
+ defs.push(line);
493
496
  this.declare(`declare ptr @scr_ffi_call_new(ptr, ptr, ptr, ${this.sizeType})`);
494
497
  this.declare(`declare void @scr_ffi_post(ptr)`);
495
498
  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})`);
@@ -505,6 +508,12 @@ class LlEmitter {
505
508
  this.declare(`declare void @scr_ffi_call_copy_${param}(ptr, ${this.sizeType}, ptr, ${this.sizeType})`);
506
509
  defs.push(` call void @scr_ffi_call_copy_${param}(ptr %call, ${this.sizeType} ${i}, ptr %a${i}, ${this.sizeType} %a${i}_len)`);
507
510
  }
511
+ else if (param === "f32" || param === "i8" || param === "u16" || param === "i16") {
512
+ const nativeTy = ffiNativeTypeLl(param);
513
+ const op = param === "f32" ? "fpext" : param === "u16" ? "uitofp" : "sitofp";
514
+ this.declare(`declare void @scr_ffi_call_set_f64(ptr, ${this.sizeType}, double)`);
515
+ 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})`);
516
+ }
508
517
  else {
509
518
  const nativeTy = ffiNativeTypeLl(param);
510
519
  this.declare(`declare void @scr_ffi_call_set_${param}(ptr, ${this.sizeType}, ${nativeTy})`);
@@ -514,7 +523,7 @@ class LlEmitter {
514
523
  defs.push(` call void @scr_ffi_post(ptr %call)`, ` ret void`, `}`, ``);
515
524
  continue;
516
525
  }
517
- defs.push(`define internal ${ret} @${adapter.symbol}(${params.join(", ")}) ${FN_ATTRS} {`, `entry:`, adapter.tls !== null
526
+ defs.push(`define internal ${ffiNativeReturnLl(cb.returns, this.ffiExtendNarrowIntegers)} @${adapter.symbol}(${params.join(", ")}) ${FN_ATTRS} {`, `entry:`, adapter.tls !== null
518
527
  ? ` %cb = load ptr, ptr @${adapter.tls}`
519
528
  : adapter.global !== null
520
529
  ? ` %cb = load ptr, ptr @${adapter.global}`
@@ -545,9 +554,28 @@ class LlEmitter {
545
554
  if (isFfiContextParam(param))
546
555
  continue;
547
556
  switch (param) {
557
+ case "i64":
558
+ case "u64":
559
+ case "pointer": {
560
+ const ty = ffiNativeTypeLl(param);
561
+ this.declare(`declare ptr @scr_bigint_from_${param}(${ty})`);
562
+ defs.push(` %s${i} = call ptr @scr_bigint_from_${param}(${ty} %a${i})`);
563
+ scriptArgs.push(`ptr %s${i}`);
564
+ break;
565
+ }
548
566
  case "f64":
549
567
  scriptArgs.push(`double %a${i}`);
550
568
  break;
569
+ case "f32":
570
+ case "i8":
571
+ case "u16":
572
+ case "i16": {
573
+ const nativeTy = ffiNativeTypeLl(param);
574
+ const op = param === "f32" ? "fpext" : param === "u16" ? "uitofp" : "sitofp";
575
+ defs.push(` %s${i} = ${op} ${nativeTy} %a${i} to double`);
576
+ scriptArgs.push(`double %s${i}`);
577
+ break;
578
+ }
551
579
  case "bool":
552
580
  defs.push(` %s${i} = icmp ne i8 %a${i}, 0`);
553
581
  scriptArgs.push(`i1 %s${i}`);
@@ -599,18 +627,34 @@ class LlEmitter {
599
627
  defs.push(` call void @scr_closure_release_v(ptr %invoke_pin)`);
600
628
  }
601
629
  switch (cb.returns) {
630
+ case "i64":
631
+ case "u64":
632
+ case "pointer": {
633
+ const ty = ffiNativeTypeLl(cb.returns);
634
+ this.declare(`declare ${ty} @scr_bigint_to_${cb.returns}(ptr)`);
635
+ this.declare(`declare void @scr_bigint_release(ptr)`);
636
+ defs.push(` %out = call ${ty} @scr_bigint_to_${cb.returns}(ptr %result)`, ` call void @scr_bigint_release(ptr %result)`, ` ret ${ty} %out`);
637
+ break;
638
+ }
602
639
  case "f64":
603
640
  defs.push(` ret double %result`);
604
641
  break;
642
+ case "f32":
643
+ defs.push(` %out = fptrunc double %result to float`, ` ret float %out`);
644
+ break;
605
645
  case "bool":
606
646
  defs.push(` %out = zext i1 %result to i8`, ` ret i8 %out`);
607
647
  break;
608
648
  case "u8":
649
+ case "i8":
650
+ case "u16":
651
+ case "i16":
609
652
  case "u32":
610
653
  this.declare(`declare double @scr_bit_ushr(double, double)`);
611
654
  defs.push(` %coerced = call double @scr_bit_ushr(double %result, double ${f64Lit(0)})`, ` %wide = fptoui double %coerced to i32`);
612
- if (cb.returns === "u8") {
613
- defs.push(` %out = trunc i32 %wide to i8`, ` ret i8 %out`);
655
+ if (cb.returns !== "u32") {
656
+ const nativeTy = ffiNativeTypeLl(cb.returns);
657
+ defs.push(` %out = trunc i32 %wide to ${nativeTy}`, ` ret ${nativeTy} %out`);
614
658
  }
615
659
  else {
616
660
  defs.push(` ret i32 %wide`);
@@ -627,13 +671,14 @@ class LlEmitter {
627
671
  }
628
672
  emit() {
629
673
  // Function bodies first (the literal/unit/fn-value tables fill as they
630
- // emit), then the file assembles around them — the C emitter's order.
674
+ // emit), then the file assembles around them — the runtime ABI’s order.
631
675
  const fnDefs = [];
632
676
  for (const fn of this.mod.functions)
633
677
  fnDefs.push(this.emitFunction(fn));
634
- const shapes = emitRecordShapes(this, this.mod);
635
- const classShapes = emitClassShapes(this, this.mod, this.classMeta);
636
- const classObjDefs = emitClassObjDefs(this, this.classMeta, this.classObjs, this.fnByName, (t) => this.llType(t));
678
+ const layouts = emitLlvmLayouts(this.shapeHost, this.mod, this.classMeta, this.classObjs, this.fnByName, (t) => this.llType(t));
679
+ const shapes = layouts.records;
680
+ const classShapes = layouts.classes;
681
+ const classObjDefs = layouts.classObjects;
637
682
  const wrappers = this.emitFnValueDefs();
638
683
  const asyncDefs = this.emitAsyncScaffolding();
639
684
  const ffiCallbacks = this.emitFfiCallbackDefs();
@@ -667,17 +712,18 @@ class LlEmitter {
667
712
  seenGlobalIds.add(g.id);
668
713
  return true;
669
714
  });
670
- // Refcounted globals release before main returns — the C emitter's
715
+ // Refcounted globals release before main returns — the runtime ABI’s
671
716
  // sc_release_globals, keeping the RC audit's live count exact. Built
672
717
  // before the declaration table flushes (it adds the release symbols).
673
718
  // Two spellings with distinct temp names: the normal exit and the
674
719
  // uncaught-exception exit are separate blocks of the same function.
675
720
  // Interned function-value closures are IMMORTAL (rc == SIZE_MAX), so
676
721
  // an own-property table Object.defineProperties hung on one would
677
- // outlive the RC audit — release it with the globals (the C emitter's
722
+ // outlive the RC audit — release it with the globals (the runtime ABI’s
678
723
  // sc_release_globals tail). Only when the dispatch unit is even
679
724
  // linked (defineProps is the only writer).
680
- const fnValueProps = moduleUsesDynInvoke(this.mod) ? [...this.fnValues] : [];
725
+ const runtimeFeatures = moduleRuntimeFeatures(this.mod);
726
+ const fnValueProps = runtimeFeatures.dynInvoke ? [...this.fnValues] : [];
681
727
  if (fnValueProps.length > 0)
682
728
  this.declare(`declare void @scr_box_release(ptr)`);
683
729
  const globalReleaseLines = (prefix) => {
@@ -685,7 +731,7 @@ class LlEmitter {
685
731
  globals.forEach((g, i) => {
686
732
  if (!isRefCounted(g.type))
687
733
  return;
688
- lines.push(` %${prefix}${i} = load ptr, ptr @${mangleGlobal(g.id)}`, ` call void ${releaseSym(this, g.type)}(ptr %${prefix}${i}) ; ${g.name}`);
734
+ lines.push(` %${prefix}${i} = load ptr, ptr @${mangleGlobal(g.id)}`, ` call void ${releaseSym(this.shapeHost, g.type)}(ptr %${prefix}${i}) ; ${g.name}`);
689
735
  });
690
736
  fnValueProps.forEach((name, i) => {
691
737
  // props sits at %ScrClosure field 3; release is NULL-tolerant —
@@ -695,38 +741,40 @@ class LlEmitter {
695
741
  return lines;
696
742
  };
697
743
  // Exit listeners can read MODULE GLOBALS directly, so they must run
698
- // BEFORE the global releases (the C emitter's runExitListeners
744
+ // BEFORE the global releases (the runtime ABI’s runExitListeners
699
745
  // ordering — the atexit half becomes an idempotent no-op).
700
- const usesEvents = moduleUsesProcessEvents(this.mod);
701
- const usesChildProcess = moduleUsesChildProcess(this.mod);
702
- const usesFsWatch = moduleUsesFsWatch(this.mod);
746
+ const usesEvents = runtimeFeatures.processEvents;
747
+ const usesChildProcess = runtimeFeatures.childProcess;
748
+ const usesFsWatch = runtimeFeatures.fsWatch;
703
749
  // Stream-surface programs fill the loop's stream hook (the deferred
704
750
  // next-tick emissions) and the emitter's post-registration flow kick
705
751
  // before %main — scr_stream.c links only when the line is emitted
706
752
  // (native-toolchain.ts gates on the same predicate).
707
- const usesStream = moduleUsesStream(this.mod);
753
+ const usesStream = runtimeFeatures.stream;
708
754
  // Net-surface programs fill the loop's net hooks (and the netSocket
709
755
  // handle-dispatch ops for the checked-dynamic boundary); http-surface
710
756
  // programs additionally stamp the httpReq/httpRes ops — the C main's
711
757
  // install lines, gated on the same predicates native-toolchain.ts links by.
712
- const usesNet = moduleUsesNet(this.mod);
713
- const usesHttp = moduleUsesHttpServer(this.mod);
758
+ const usesNet = runtimeFeatures.net;
759
+ const usesDgram = runtimeFeatures.dgram;
760
+ const usesHttp2 = runtimeFeatures.http2;
761
+ const usesHttp = runtimeFeatures.http;
714
762
  // Fetch-referencing programs register the native fetch bridge before
715
763
  // any island entry (the engine's lazy boot consults it) — native-toolchain.ts
716
764
  // compiles scr_fetch.c on the same predicate.
717
- const usesFetch = moduleUsesFetch(this.mod);
765
+ const usesFetch = runtimeFeatures.fetch;
718
766
  const embedsZlib = moduleEmbedsBuiltin(this.mod, "node:zlib");
719
767
  const embedsNet = moduleEmbedsBuiltin(this.mod, "node:http") ||
720
768
  moduleEmbedsBuiltin(this.mod, "node:https") ||
721
769
  moduleEmbedsBuiltin(this.mod, "node:net") ||
722
770
  moduleEmbedsBuiltin(this.mod, "node:tls");
723
- const snapshotsTlsCa = moduleUsesTls(this.mod) || moduleUsesTlsCa(this.mod) ||
771
+ const snapshotsTlsCa = runtimeFeatures.tls || runtimeFeatures.tlsCa ||
724
772
  moduleEmbedsBuiltin(this.mod, "node:https") ||
725
773
  moduleEmbedsBuiltin(this.mod, "node:tls");
726
774
  // The process verdict has the same precedence as the C reference
727
775
  // emitter: node:test owns the final status when present; otherwise an
728
776
  // embedded process.exitCode owns it; ordinary programs return zero.
729
- const usesNodeTest = moduleUsesNodeTest(this.mod);
777
+ const usesNodeTest = runtimeFeatures.nodeTest;
730
778
  const programExitUsesIsland = !usesNodeTest && usesIsland;
731
779
  // Declared NOW — the extern block flushes before main assembles.
732
780
  if (usesEvents)
@@ -743,6 +791,10 @@ class LlEmitter {
743
791
  this.declare(`declare void @scr_net_install()`);
744
792
  this.declare(`declare void @scr_net_dyn_install()`);
745
793
  }
794
+ if (usesDgram)
795
+ this.declare(`declare void @scr_dgram_install()`);
796
+ if (usesHttp2)
797
+ this.declare(`declare void @scr_http2_dyn_install()`);
746
798
  if (usesHttp)
747
799
  this.declare(`declare void @scr_http_dyn_install()`);
748
800
  if (usesFetch)
@@ -768,13 +820,12 @@ class LlEmitter {
768
820
  // the refcounted-global releases, or the retained-FFI atexit ledger
769
821
  // sweep (a listener may legitimately release or pump a registration,
770
822
  // and only the inline call orders ahead of every atexit handler —
771
- // the C emitter's runExitListeners stance). Plain event programs
823
+ // the runtime ABI’s runExitListeners stance). Plain event programs
772
824
  // with neither keep the atexit path, so their listener timing is
773
825
  // unchanged.
774
826
  const hasRefGlobals = globals.some((g) => isRefCounted(g.type)) || fnValueProps.length > 0;
775
827
  const inlineExitListeners = usesEvents && (hasRefGlobals || this.ffiHasRetainedCallback);
776
- if (!usesNodeTest && !usesIsland)
777
- this.declare(`declare i32 @scr_exit_code_hint_get()`);
828
+ this.declare(`declare i32 @scr_exit_code_hint_get()`);
778
829
  if (inlineExitListeners) {
779
830
  this.declare(`declare void @scr_run_exit_listeners(double)`);
780
831
  this.declare(`declare i32 @scr_exit_code_hint_get()`);
@@ -847,17 +898,23 @@ class LlEmitter {
847
898
  // finish_top_level initially notes 13. Replace that hint before exit
848
899
  // listeners run when a higher-priority verdict was already selected.
849
900
  lines.push(` call void @scr_exit_code_note(i32 ${exitStatus})`);
850
- lines.push(...exitListenerLines("xp"));
901
+ for (const line of exitListenerLines("xp"))
902
+ lines.push(line);
851
903
  if (tracksIslandExit) {
852
904
  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 ]`);
853
905
  }
854
- lines.push(...topPendingReleases);
906
+ for (const line of topPendingReleases)
907
+ lines.push(line);
855
908
  lines.push(` ret i32 ${tracksIslandExit ? "%tla_final_exit" : exitStatus}`);
856
909
  return lines;
857
910
  };
858
911
  // LIBRARY mode: the runtime entry points the generated library
859
912
  // symbols delegate to — declared before the extern block flushes.
860
913
  if (this.mod.lib !== undefined) {
914
+ if (this.wasi) {
915
+ this.declare(`declare ptr @malloc(${this.sizeType})`);
916
+ this.declare(`declare void @free(ptr)`);
917
+ }
861
918
  this.declare(`declare void @scr_library_entry(i1 zeroext, ptr)`);
862
919
  this.declare(`declare void @scr_library_reset()`);
863
920
  this.declare(`declare void @scr_library_check_exc()`);
@@ -911,18 +968,18 @@ class LlEmitter {
911
968
  `%ScrLogArg = type { i32, i64 }`,
912
969
  `%ScrVt = type { ${this.sizeType}, ${this.sizeType}, ptr }`,
913
970
  `%ScrUnion = type { ${this.sizeType}, i32, ptr, ptr, ptr, i64 }`,
914
- `%ScrClosure = type { ${this.sizeType}, ptr, ${this.sizeType}, ptr }`,
971
+ `%ScrClosure = type { ${this.sizeType}, ptr, ${this.sizeType}, ptr, i32 }`,
915
972
  `%ScrFfiTable = type { ptr, ${this.sizeType}, ${this.sizeType}, ptr, i8, ptr, ptr, ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, ptr, ptr }`,
916
973
  `%ScrRegex = type { ${this.sizeType}, ptr, ptr, ptr }`,
917
974
  // ScrArr mirrors scr_runtime.h field-for-field. Live dynamic stream
918
975
  // commits swap its mutable dense, sparse, presence, and property
919
976
  // storage while preserving the target object's identity.
920
977
  `%ScrArr = type { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, i32, ptr, ptr, ptr, ptr, ptr, ptr, ${this.sizeType}, ${this.sizeType}, ptr, ${this.sizeType}, ${this.sizeType} }`,
921
- // The runtime error prefix { rc, vt, name, message, code } and the
978
+ // The runtime error prefix { rc, vt, name, message, code, cause } and the
922
979
  // class-object shape { rc, pre, post, ctor, name } — field reads on
923
980
  // builtin errors and classval loads GEP through these.
924
- `%ScrError = type { ${this.sizeType}, ptr, ptr, ptr, ptr }`,
925
- `%ScrClassObj = type { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, ptr, ptr }`,
981
+ `%ScrError = type { ${this.sizeType}, ptr, ptr, ptr, ptr, ptr }`,
982
+ `%ScrClassObj = type { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, ptr, ptr, ${this.sizeType}, ${this.sizeType}, ptr }`,
926
983
  // The runtime emitter prefix { rc, vt, reg, cls } — user subclasses
927
984
  // embed it (classes.ts), and bare-emitter GEPs address through it.
928
985
  `%ScrEmitter = type { ${this.sizeType}, ptr, ptr, ptr }`,
@@ -939,7 +996,7 @@ class LlEmitter {
939
996
  // typed-array access GEPs through this directly: the IR type already
940
997
  // fixes elem, so the hot path needs neither a runtime kind load nor
941
998
  // the generic scr_bytes_get/set call.
942
- `%ScrBytes = type { ${this.sizeType}, ${this.sizeType}, i32, ptr, ptr }`,
999
+ `%ScrBytes = type { ${this.sizeType}, ${this.sizeType}, i32, ptr, ptr, i8 }`,
943
1000
  // The capture box { rc, kind, obj_retain, obj_release, obj_trace,
944
1001
  // slot } — TDZ reads peek the payload slot (offset 40) directly.
945
1002
  `%ScrBox = type { ${this.sizeType}, i32, ptr, ptr, ptr, i64 }`,
@@ -951,8 +1008,10 @@ class LlEmitter {
951
1008
  `%ScrIslandModule = type { ptr, ptr, ${this.sizeType}, ${this.sizeType}, i32, ptr, ${this.sizeType}, ${this.sizeType} }`,
952
1009
  `%ScrIslandEdge = type { ptr, ptr, ptr, i32 }`,
953
1010
  ];
954
- out.push(...shapes.typeDefs);
955
- out.push(...classShapes.typeDefs);
1011
+ for (const line of shapes.typeDefs)
1012
+ out.push(line);
1013
+ for (const line of classShapes.typeDefs)
1014
+ out.push(line);
956
1015
  // Thread-instanced library state (abi.instance_per_thread): the
957
1016
  // program TU's mutable globals — module globals, run-once guards, the
958
1017
  // lazily-compiled regex literal caches — and the runtime globals its
@@ -961,7 +1020,7 @@ class LlEmitter {
961
1020
  // data (string literals, unit arms, template arrays, vtables) stays
962
1021
  // shared.
963
1022
  const tl = this.mod.lib?.threadInstances === true ? "thread_local " : "";
964
- 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
1023
+ 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
965
1024
  ? [`declare void @${RUNTIME_ABI_MARKER}()`]
966
1025
  : []));
967
1026
  for (const d of this.decls)
@@ -976,7 +1035,7 @@ class LlEmitter {
976
1035
  }
977
1036
  for (const [text, lit] of this.literals) {
978
1037
  // Immortal interned ScrStr: { rc = SIZE_MAX, len, cap = len, bytes\0 } —
979
- // the C emitter's static table, retain/release skip rc == SIZE_MAX.
1038
+ // the runtime ABI’s static table, retain/release skip rc == SIZE_MAX.
980
1039
  out.push(`@${lit.sym} = internal global { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, [${lit.len + 1} x i8] } ` +
981
1040
  `{ ${this.sizeType} -1, ${this.sizeType} ${lit.len}, ${this.sizeType} ${lit.len}, [${lit.len + 1} x i8] c"${llStrBytes(text)}" }`);
982
1041
  }
@@ -1014,8 +1073,7 @@ class LlEmitter {
1014
1073
  if (this.templateStringsInstances.size > 0)
1015
1074
  out.push(``);
1016
1075
  for (const [text, c] of this.cstrs) {
1017
- // NUL-terminated byte-array constants: the scr_jb_puts / indent-text
1018
- // currency (the C emitter passes string literals; these are theirs).
1076
+ // NUL-terminated byte-array constants for scr_jb_puts and indentation.
1019
1077
  out.push(`@${c.sym} = internal constant [${c.len + 1} x i8] c"${llStrBytes(text)}"`);
1020
1078
  }
1021
1079
  if (this.cstrs.size > 0)
@@ -1042,7 +1100,8 @@ class LlEmitter {
1042
1100
  });
1043
1101
  out.push(`@sc_npm_modules = internal constant [${moduleRows.length} x %ScrIslandModule] [ ${moduleRows.join(", ")} ]`);
1044
1102
  embedded.edges.forEach((edge, i) => {
1045
- for (const [part, text] of [["from", edge.from], ["spec", edge.specifier], ["to", edge.to]]) {
1103
+ const parts = [["from", edge.from], ["spec", edge.specifier], ["to", edge.to]];
1104
+ for (const [part, text] of parts) {
1046
1105
  const bytes = Buffer.from(text, "utf8");
1047
1106
  out.push(`@sc_npm_edge_${i}_${part} = internal constant [${bytes.length + 1} x i8] c"${llBytes(bytes)}"`);
1048
1107
  }
@@ -1054,36 +1113,48 @@ class LlEmitter {
1054
1113
  }
1055
1114
  out.push(``);
1056
1115
  }
1057
- out.push(...ffiCallbacks.globals);
1116
+ for (const line of ffiCallbacks.globals)
1117
+ out.push(line);
1058
1118
  if (ffiCallbacks.globals.length > 0)
1059
1119
  out.push(``);
1060
1120
  for (const g of globals) {
1061
1121
  const ty = this.llType(g.type);
1062
1122
  const zero = ty === "double" ? f64Lit(0) : ty === "ptr" ? "null" : "false";
1063
- out.push(`@${mangleGlobal(g.id)} = internal ${tl}global ${ty} ${zero} ; ${g.name}`);
1123
+ const debug = this.debug?.global(g);
1124
+ out.push(`@${mangleGlobal(g.id)} = internal ${tl}global ${ty} ${zero}${debug ? `, !dbg ${debug}` : ""} ; ${g.name}`);
1064
1125
  }
1065
1126
  if (globals.length > 0)
1066
1127
  out.push(``);
1067
- out.push(...helpers);
1068
- out.push(...ffiCallbacks.defs);
1069
- out.push(...shapes.defs);
1070
- out.push(...classShapes.defs);
1071
- out.push(...classObjDefs);
1072
- out.push(...this.walkers.defs);
1073
- out.push(...this.dyn.defs);
1074
- out.push(...wrappers);
1075
- out.push(...asyncDefs);
1076
- out.push(...this.resolveThunkDefs);
1128
+ for (const line of helpers)
1129
+ out.push(line);
1130
+ for (const line of ffiCallbacks.defs)
1131
+ out.push(line);
1132
+ for (const line of shapes.defs)
1133
+ out.push(line);
1134
+ for (const line of classShapes.defs)
1135
+ out.push(line);
1136
+ for (const line of classObjDefs)
1137
+ out.push(line);
1138
+ for (const line of this.walkers.defs)
1139
+ out.push(line);
1140
+ for (const line of this.dyn.defs)
1141
+ out.push(line);
1142
+ for (const line of wrappers)
1143
+ out.push(line);
1144
+ for (const line of asyncDefs)
1145
+ out.push(line);
1146
+ for (const line of this.resolveThunkDefs)
1147
+ out.push(line);
1077
1148
  out.push(fnDefs.join("\n\n"), ``);
1078
1149
  // main(): scr_init, the program-dependent error-vt interval stamps,
1079
1150
  // scr_lib_init(argc, argv), then the entry function. An uncaught
1080
- // exception escaping top-level code prints and exits 1 (Node) — the
1081
- // C emitter's epilogue, emitted exactly when the entry may throw.
1082
- // No event loop yet: timers/async still refuse (phase 5).
1151
+ // exception escaping top-level code prints and exits 1 (Node).
1152
+ // The exception epilogue is emitted when the entry may throw.
1083
1153
  const stamps = [];
1084
1154
  for (const iv of this.errorIntervals) {
1085
- for (const [field, value] of [[0, iv.pre], [1, iv.post]]) {
1086
- 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}` : ""}`);
1155
+ const fields = [[0, iv.pre], [1, iv.post]];
1156
+ for (const [field, value] of fields) {
1157
+ 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}` : ""}`);
1087
1158
  }
1088
1159
  }
1089
1160
  if (this.emitterInterval !== null) {
@@ -1116,18 +1187,21 @@ class LlEmitter {
1116
1187
  // order-free — the scr_error_set_traced precedent). Only the
1117
1188
  // printer emits here (nothing else declares it); scr_exc_pending
1118
1189
  // and the loop entry points rode the Set before the flush.
1119
- out.push(`declare void @scr_exc_print_uncaught()`, ``);
1190
+ out.push(`declare void @scr_exc_print_uncaught()`, `declare zeroext i1 @scr_exc_handle_uncaught(i1 zeroext)`, ``);
1120
1191
  }
1121
1192
  if (this.mod.lib !== undefined) {
1122
1193
  // LIBRARY mode: no @main — the profile-declared external
1123
- // symbols instead, from the same IR facts the C emission consumes.
1124
- out.push(...this.emitLibDefs(globals, globalReleaseLines, stamps));
1194
+ // symbols specified by the library IR instead.
1195
+ for (const line of this.emitLibDefs(globals, globalReleaseLines, stamps))
1196
+ out.push(line);
1125
1197
  out.push(`attributes #0 = { sanitize_address }`);
1126
1198
  if (this.wasi)
1127
1199
  out.push(`attributes #1 = { sanitize_address presplitcoroutine }`);
1128
1200
  if (hasNoInlineRecordClone)
1129
1201
  out.push(`attributes #2 = { noinline sanitize_address }`);
1130
1202
  out.push(``);
1203
+ if (this.debug !== null)
1204
+ out.push(this.debug.render());
1131
1205
  return out.join("\n");
1132
1206
  }
1133
1207
  out.push(`define i32 @${this.wasi ? "__main_argc_argv" : "main"}(i32 %argc, ptr %argv) ${FN_ATTRS} {`, `entry:`, ...(this.runtimeAbiMarker ? [` call void @${RUNTIME_ABI_MARKER}()`] : []), ` call void @scr_init()`, ...stamps,
@@ -1137,7 +1211,7 @@ class LlEmitter {
1137
1211
  ...(usesEvents ? [` call void @scr_events_install()`] : []), ...(usesChildProcess ? [` call void @scr_child_dyn_install()`] : []),
1138
1212
  // fs.watch programs fill the loop's watch hooks the same way —
1139
1213
  // scr_watch.c links only when this line is emitted.
1140
- ...(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
1214
+ ...(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
1141
1215
  ? [
1142
1216
  ...(moduleEmbedsCompressedNpm(this.mod)
1143
1217
  ? [` call void @scr_island_set_inflate(ptr @scr_zlib_inflate_exact)`]
@@ -1154,10 +1228,14 @@ class LlEmitter {
1154
1228
  ` %exc = call zeroext i1 @scr_exc_pending()`,
1155
1229
  ` br i1 %exc, label %uncaught, label %ok`,
1156
1230
  `uncaught:`,
1231
+ ` %handled = call zeroext i1 @scr_exc_handle_uncaught(i1 false)`,
1232
+ ` br i1 %handled, label %ok, label %fatal`,
1233
+ `fatal:`,
1157
1234
  ` call void @scr_exc_print_uncaught()`,
1158
1235
  ...exitListenerLines("xu"),
1159
1236
  ...uncaughtReleases,
1160
- ` ret i32 1`,
1237
+ ` %failure_code_0 = call i32 @scr_exit_code_hint_get()`,
1238
+ ` ret i32 %failure_code_0`,
1161
1239
  `ok:`,
1162
1240
  ]
1163
1241
  : []),
@@ -1174,7 +1252,8 @@ class LlEmitter {
1174
1252
  ...(asyncEntry ? [` call void @scr_promise_release(ptr %top)`] : []),
1175
1253
  ...exitListenerLines("xl"),
1176
1254
  ...loopReleasesU,
1177
- ` ret i32 1`,
1255
+ ` %failure_code_1 = call i32 @scr_exit_code_hint_get()`,
1256
+ ` ret i32 %failure_code_1`,
1178
1257
  `lok:`,
1179
1258
  ` br i1 %loop_rejection, label %lreported, label %lclean`,
1180
1259
  `lreported:`,
@@ -1182,7 +1261,8 @@ class LlEmitter {
1182
1261
  ...(asyncEntry ? [` call void @scr_promise_release(ptr %top)`] : []),
1183
1262
  ...exitListenerLines("xq"),
1184
1263
  ...loopReportedReleases,
1185
- ` ret i32 1`,
1264
+ ` %failure_code_2 = call i32 @scr_exit_code_hint_get()`,
1265
+ ` ret i32 %failure_code_2`,
1186
1266
  `lclean:`,
1187
1267
  ...(asyncEntry
1188
1268
  ? [
@@ -1199,7 +1279,8 @@ class LlEmitter {
1199
1279
  ` call void @scr_exc_print_uncaught()`,
1200
1280
  ...exitListenerLines("xt"),
1201
1281
  ...topRejectReleases,
1202
- ` ret i32 1`,
1282
+ ` %failure_code_3 = call i32 @scr_exit_code_hint_get()`,
1283
+ ` ret i32 %failure_code_3`,
1203
1284
  `tla_not_rejected:`,
1204
1285
  ` call void @scr_promise_release(ptr %top)`,
1205
1286
  ]
@@ -1209,7 +1290,8 @@ class LlEmitter {
1209
1290
  `lrej:`,
1210
1291
  ...exitListenerLines("xr"),
1211
1292
  ...loopReleasesR,
1212
- ` ret i32 1`,
1293
+ ` %failure_code_4 = call i32 @scr_exit_code_hint_get()`,
1294
+ ` ret i32 %failure_code_4`,
1213
1295
  `lrok:`,
1214
1296
  ...(asyncEntry
1215
1297
  ? [
@@ -1230,6 +1312,8 @@ class LlEmitter {
1230
1312
  // lane's -fsanitize=address link activates instrumentation over the
1231
1313
  // emitted functions too (the runtime TUs get theirs from clang).
1232
1314
  `attributes #0 = { sanitize_address }`, ...(this.wasi ? [`attributes #1 = { sanitize_address presplitcoroutine }`] : []), ...(hasNoInlineRecordClone ? [`attributes #2 = { noinline sanitize_address }`] : []), ``);
1315
+ if (this.debug !== null)
1316
+ out.push(this.debug.render());
1233
1317
  return out.join("\n");
1234
1318
  }
1235
1319
  /** LIBRARY mode: the profile-declared external definitions — the
@@ -1261,11 +1345,15 @@ class LlEmitter {
1261
1345
  for (const e of lib.exports)
1262
1346
  emitSymConst(e.symbol);
1263
1347
  out.push(``);
1348
+ if (this.wasi) {
1349
+ for (const symbol of ["scriptc_alloc", "scriptc_free"])
1350
+ emitSymConst(symbol);
1351
+ 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`, `}`, ``);
1352
+ }
1264
1353
  // The runtime detected-trap overlay table (scr_runtime.h declares it,
1265
1354
  // the library trap funnel consults it): flat code/teaching/remediation
1266
1355
  // triples, one per runtime trap code (SC4013–SC4019) the profile
1267
- // declares text for — the same data the C emission defines, so the
1268
- // funnel-assembled sink message is emission-invariant by construction.
1356
+ // declares text for. The funnel assembles the structured sink message.
1269
1357
  // The empty table still defines the symbols the funnel links against.
1270
1358
  const ovlCells = [];
1271
1359
  lib.trapOverlays.forEach((o, i) => {
@@ -1299,8 +1387,8 @@ class LlEmitter {
1299
1387
  // Host-callback channels: the per-channel name constants (the
1300
1388
  // registration dispatch's strcmp operands), the per-channel
1301
1389
  // unregistered-call trap constants (the ffiCall sites'
1302
- // scr_library_cb_require operands — same bytes as the C emission by
1303
- // construction), and the registration define: a pure store dispatch
1390
+ // scr_library_cb_require operands), and the registration function:
1391
+ // a pure store dispatch
1304
1392
  // (the sink registration's rule — no entry prologue, no poison
1305
1393
  // guard) whose first operation rejects callback-time re-entry
1306
1394
  // (SC4026). An unknown or NULL name is a defined -1, never a store.
@@ -1320,7 +1408,8 @@ class LlEmitter {
1320
1408
  // from the poisoned guard and every runtime touch (ratified), so a
1321
1409
  // host can read them before init and after a trap. The u64 rides
1322
1410
  // i64 two's-complement (LLVM integer constants are signed).
1323
- out.push(...emitLibraryIdentityLines("llvm", lib.identity, FN_ATTRS));
1411
+ for (const line of emitLibraryIdentityLines(lib.identity, FN_ATTRS))
1412
+ out.push(line);
1324
1413
  }
1325
1414
  if (lib.resultResetSymbol !== null) {
1326
1415
  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`, `}`, ``);
@@ -1335,8 +1424,7 @@ class LlEmitter {
1335
1424
  if (e.inboundBytesTrap !== undefined) {
1336
1425
  // The bytes-in helper's trap message: the compiler-assembled
1337
1426
  // structured trap-teaching form (0x01 text 0x1F SC4012 0x1F symbol
1338
- // [0x1F remediation]) — the same bytes the C emission passes, so
1339
- // the sink message is emission-invariant by construction.
1427
+ // [0x1F remediation]) consumed by the runtime sink.
1340
1428
  const trapBytes = Buffer.byteLength(e.inboundBytesTrap, "utf8");
1341
1429
  out.push(`@sc_lib_bytes_trap_${e.symbol} = internal constant [${trapBytes + 1} x i8] c"${llStrBytes(e.inboundBytesTrap)}"`, ``);
1342
1430
  }
@@ -1440,7 +1528,7 @@ class LlEmitter {
1440
1528
  }
1441
1529
  /** The shared abort helpers (emitted only when referenced): the OOM
1442
1530
  * abort of untraced shape allocation and the invalid-union-tag abort —
1443
- * both print the C emitter's exact message on fd 2 and abort. */
1531
+ * both print the runtime ABI’s exact message on fd 2 and abort. */
1444
1532
  helperDefs() {
1445
1533
  const defs = [];
1446
1534
  const msgHelper = (fnName, msgSym, msg) => {
@@ -1475,7 +1563,7 @@ class LlEmitter {
1475
1563
  return defs.length > 0 ? [...defs] : defs;
1476
1564
  }
1477
1565
  /** Env-signature wrappers + interned immortal closures for declared
1478
- * functions used as values (the C emitter's sc_w_/sc_fc_ pair): every
1566
+ * functions used as values (the runtime ABI’s sc_w_/sc_fc_ pair): every
1479
1567
  * mention of `f` yields the same pointer, so `f === f` holds. */
1480
1568
  emitFnValueDefs() {
1481
1569
  const out = [];
@@ -1488,7 +1576,7 @@ class LlEmitter {
1488
1576
  // never the inner return type.
1489
1577
  const ret = fn.async === true || fn.generator !== undefined ? "ptr" : this.llType(fn.returnType);
1490
1578
  const call = `call ${ret} @${this.callTarget(name)}(${args})`;
1491
- 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 }`, ``);
1579
+ 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)} }`, ``);
1492
1580
  }
1493
1581
  return out;
1494
1582
  }
@@ -1560,7 +1648,8 @@ class LlEmitter {
1560
1648
  if (fn.async !== true || fn.generator !== undefined)
1561
1649
  continue;
1562
1650
  const { definitions, ret, tr, spawnParams, argPackLines } = this.emitArgPackAndTrampolinePrologue(fn);
1563
- out.push(...definitions);
1651
+ for (const line of definitions)
1652
+ out.push(line);
1564
1653
  this.declare(`declare ptr @scr_fiber_promise(ptr)`);
1565
1654
  this.declare(`declare ptr @scr_async_spawn(ptr, ptr)`);
1566
1655
  this.needOom();
@@ -1594,19 +1683,20 @@ class LlEmitter {
1594
1683
  tr.push(` call void @scr_promise_fulfill_str(ptr %pr, ptr %r) ; moves in`);
1595
1684
  break;
1596
1685
  default: {
1597
- const v = vAdapters(this, ret);
1686
+ const v = vAdapters(this.shapeHost, ret);
1598
1687
  this.declare(`declare void @scr_promise_fulfill_ref(ptr, ptr, ptr, ptr, ptr)`);
1599
- tr.push(` call void @scr_promise_fulfill_ref(ptr %pr, ptr %r, ptr ${v.retain}, ptr ${v.release}, ptr ${traceArg(this, ret)})`);
1688
+ tr.push(` call void @scr_promise_fulfill_ref(ptr %pr, ptr %r, ptr ${v.retain}, ptr ${v.release}, ptr ${traceArg(this.shapeHost, ret)})`);
1600
1689
  }
1601
1690
  }
1602
1691
  tr.push(` ret void`, `thrown:`);
1603
1692
  if (ret.kind !== "void" && isRefCounted(ret)) {
1604
1693
  // An escaping throw means %r is the never-read dummy (NULL).
1605
- tr.push(` call void ${releaseSym(this, ret)}(ptr %r)`);
1694
+ tr.push(` call void ${releaseSym(this.shapeHost, ret)}(ptr %r)`);
1606
1695
  }
1607
1696
  tr.push(` ret void`, `}`, ``);
1608
1697
  }
1609
- out.push(...tr);
1698
+ for (const line of tr)
1699
+ out.push(line);
1610
1700
  // Spawn wrapper: pack the args (+1 moves in), spawn the fiber.
1611
1701
  const cache = fn.asyncCacheGlobal !== undefined ? mangleGlobal(fn.asyncCacheGlobal) : null;
1612
1702
  const cycleCache = fn.asyncCycleCacheGlobal !== undefined ? mangleGlobal(fn.asyncCycleCacheGlobal) : null;
@@ -1666,9 +1756,11 @@ class LlEmitter {
1666
1756
  ` store ptr %cycle_cache_owned, ptr @${cycleCache}`,
1667
1757
  ]
1668
1758
  : []), ` ret ptr %p`, `}`, ``);
1669
- out.push(...sp);
1759
+ for (const line of sp)
1760
+ out.push(line);
1670
1761
  }
1671
- out.push(...this.emitGenScaffolding());
1762
+ for (const line of this.emitGenScaffolding())
1763
+ out.push(line);
1672
1764
  return out;
1673
1765
  }
1674
1766
  /** Per-generator-function machinery — the async scaffolding's lazy
@@ -1683,7 +1775,8 @@ class LlEmitter {
1683
1775
  if (fn.generator === undefined)
1684
1776
  continue;
1685
1777
  const { definitions, pack, lifted, fieldTys, ret, tr, spawnParams, argPackLines, } = this.emitArgPackAndTrampolinePrologue(fn);
1686
- out.push(...definitions);
1778
+ for (const line of definitions)
1779
+ out.push(line);
1687
1780
  this.declare(`declare zeroext i1 @scr_exc_genret_pending()`);
1688
1781
  this.declare(`declare void @scr_exc_clear()`);
1689
1782
  this.declare(`declare ptr @scr_gen_of_fiber(ptr)`);
@@ -1716,18 +1809,19 @@ class LlEmitter {
1716
1809
  tr.push(` call void @scr_gen_out_bool(ptr %g, i1 %r)`, ` br label %done`);
1717
1810
  break;
1718
1811
  default: {
1719
- const v = vAdapters(this, ret);
1812
+ const v = vAdapters(this.shapeHost, ret);
1720
1813
  this.declare(`declare void @scr_gen_out_ref(ptr, ptr, ptr)`);
1721
1814
  tr.push(` call void @scr_gen_out_ref(ptr %g, ptr %r, ptr ${v.release})`, ` br label %done`);
1722
1815
  }
1723
1816
  }
1724
1817
  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:`);
1725
1818
  if (ret.kind !== "void" && isRefCounted(ret)) {
1726
- tr.push(` call void ${releaseSym(this, ret)}(ptr %r) ; unwound: the never-read dummy`);
1819
+ tr.push(` call void ${releaseSym(this.shapeHost, ret)}(ptr %r) ; unwound: the never-read dummy`);
1727
1820
  }
1728
1821
  tr.push(` br label %done`, `done:`, ` ret void`, `}`, ``);
1729
1822
  }
1730
- out.push(...tr);
1823
+ for (const line of tr)
1824
+ out.push(line);
1731
1825
  let settleAsync = null;
1732
1826
  if (fn.async) {
1733
1827
  this.declare(`declare ptr @scr_async_gen_new(ptr, ptr, ptr, ptr)`);
@@ -1744,8 +1838,8 @@ class LlEmitter {
1744
1838
  const settleKey = `ags:${typeKey(genT)}`;
1745
1839
  if (!this.resolveThunks.has(settleKey)) {
1746
1840
  this.resolveThunks.set(settleKey, settleAsync);
1747
- const adapters = vAdapters(this, resultT);
1748
- 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`, `}`, ``);
1841
+ const adapters = vAdapters(this.shapeHost, resultT);
1842
+ 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`, `}`, ``);
1749
1843
  }
1750
1844
  this.declare(`declare void @scr_promise_fulfill_ref(ptr, ptr, ptr, ptr, ptr)`);
1751
1845
  }
@@ -1765,11 +1859,12 @@ class LlEmitter {
1765
1859
  dr.push(` call void @scr_closure_release(ptr %dv${i})`);
1766
1860
  }
1767
1861
  else {
1768
- dr.push(` call void ${releaseSym(this, pType)}(ptr %dv${i})`);
1862
+ dr.push(` call void ${releaseSym(this.shapeHost, pType)}(ptr %dv${i})`);
1769
1863
  }
1770
1864
  });
1771
1865
  dr.push(` call void @free(ptr %ap)`, ` ret void`, `}`, ``);
1772
- out.push(...dr);
1866
+ for (const line of dr)
1867
+ out.push(line);
1773
1868
  // Spawn wrapper: pack the args (+1 moves in), allocate the
1774
1869
  // SUSPENDED fiber — nothing runs until the first .next().
1775
1870
  if (lifted) {
@@ -1783,11 +1878,12 @@ class LlEmitter {
1783
1878
  sp.push(settleAsync === null
1784
1879
  ? ` %gg = call ptr @scr_gen_new(ptr @${mangleTrampoline(fn.name)}, ptr %ap, ptr @${mangleGenDrop(fn.name)})`
1785
1880
  : ` %gg = call ptr @scr_async_gen_new(ptr @${mangleTrampoline(fn.name)}, ptr %ap, ptr @${mangleGenDrop(fn.name)}, ptr @${settleAsync})`, ` ret ptr %gg`, `}`, ``);
1786
- out.push(...sp);
1881
+ for (const line of sp)
1882
+ out.push(line);
1787
1883
  }
1788
1884
  return out;
1789
1885
  }
1790
- // ── plumbing (the CEmitter frame/scope machinery, alloca-flavored) ──────
1886
+ // ── plumbing (frame and scope ownership) ──────
1791
1887
  internLiteral(text) {
1792
1888
  let lit = this.literals.get(text);
1793
1889
  if (!lit) {
@@ -1867,20 +1963,26 @@ class LlEmitter {
1867
1963
  * the `_v` table (immortals skip, exactly the C retain calls). */
1868
1964
  retainValue(name, type) {
1869
1965
  const t = this.B.tmp();
1870
- this.B.line(`${t} = call ptr ${retainSym(this, type)}(ptr ${name})`);
1966
+ this.B.line(`${t} = call ptr ${retainSym(this.shapeHost, type)}(ptr ${name})`);
1871
1967
  return t;
1872
1968
  }
1873
1969
  /** The release call for one owned refcounted value — type-directed like
1874
1970
  * releaseCallC (all runtime releases are NULL-tolerant). */
1875
1971
  releaseValue(name, type) {
1876
- this.B.line(`call void ${releaseSym(this, type)}(ptr ${name})`);
1972
+ this.B.line(`call void ${releaseSym(this.shapeHost, type)}(ptr ${name})`);
1877
1973
  }
1878
1974
  releaseFrame(frame) {
1879
1975
  for (const v of frame) {
1880
1976
  if (v.slot) {
1881
1977
  const t = this.B.tmp();
1882
1978
  this.B.line(`${t} = load ptr, ptr ${v.name}`);
1883
- this.releaseValue(t, v.type);
1979
+ if (v.boxed) {
1980
+ this.declare(`declare void @scr_box_release(ptr)`);
1981
+ this.B.line(`call void @scr_box_release(ptr ${t})`);
1982
+ }
1983
+ else {
1984
+ this.releaseValue(t, v.type);
1985
+ }
1884
1986
  }
1885
1987
  else {
1886
1988
  this.releaseValue(v.name, v.type);
@@ -1903,7 +2005,7 @@ class LlEmitter {
1903
2005
  /** THE release-on-jump path (break/continue/return): pending statement
1904
2006
  * frames and entered scopes down to the given depths, innermost first —
1905
2007
  * everything whose normal fall-through releases the jump bypasses.
1906
- * Ported verbatim from CEmitter.releaseForJump. */
2008
+ * Release every scope crossed by the control-flow edge. */
1907
2009
  releaseForJump(frameDepth, scopeDepth) {
1908
2010
  for (let i = this.frames.length - 1; i >= frameDepth; i--)
1909
2011
  this.releaseFrame(this.frames[i]);
@@ -1943,29 +2045,47 @@ class LlEmitter {
1943
2045
  * function — and branch to the handler / return a dummy value (never
1944
2046
  * read: callers of a may-throw function test the pending flag before
1945
2047
  * using the result). Callers own the surrounding pending branch; a
1946
- * `throw` unwinds unconditionally. CEmitter.emitUnwind, block-flavored. */
2048
+ * `throw` unwinds unconditionally. */
1947
2049
  emitUnwind() {
1948
2050
  const target = this.tryStack[this.tryStack.length - 1];
2051
+ const frameDepth = target?.frameDepth ?? 0;
2052
+ const scopeDepth = target?.scopeDepth ?? 0;
2053
+ for (let i = this.frames.length - 1; i >= frameDepth; i--)
2054
+ this.releaseFrame(this.frames[i]);
2055
+ let terminator;
1949
2056
  if (target) {
1950
- this.releaseForJump(target.frameDepth, target.scopeDepth);
1951
2057
  target.used = true;
1952
- this.B.terminate(`br label %${target.label}`);
1953
- return;
2058
+ terminator = `br label %${target.label}`;
1954
2059
  }
1955
- this.releaseForJump(0, 0);
1956
- if (this.currentWasiCoro !== null) {
1957
- this.B.terminate(`br label %${this.currentWasiCoro.finalLabel}`);
2060
+ else if (this.currentWasiCoro !== null) {
2061
+ terminator = `br label %${this.currentWasiCoro.finalLabel}`;
2062
+ }
2063
+ else {
2064
+ const t = this.currentReturnType;
2065
+ terminator = t.kind === "void" ? "ret void"
2066
+ : t.kind === "f64" || t.kind === "date" ? `ret double ${f64Lit(0)}`
2067
+ : t.kind === "bool" ? "ret i1 false" : "ret ptr null";
2068
+ }
2069
+ // Copy the entries now: later declarations extend these lexical scopes.
2070
+ // Release order and the handler are part of the shared block's identity.
2071
+ const entries = [];
2072
+ let key = terminator;
2073
+ for (let i = this.scopes.length - 1; i >= scopeDepth; i--) {
2074
+ for (const entry of this.scopes[i]) {
2075
+ entries.push(entry);
2076
+ key += `\0${entry.slot}\0${entry.boxed ? "@scr_box_release" : releaseSym(this.shapeHost, entry.type)}`;
2077
+ }
2078
+ }
2079
+ if (entries.length === 0) {
2080
+ this.B.terminate(terminator);
1958
2081
  return;
1959
2082
  }
1960
- const t = this.currentReturnType;
1961
- if (t.kind === "void")
1962
- this.B.terminate("ret void");
1963
- else if (t.kind === "f64" || t.kind === "date")
1964
- this.B.terminate(`ret double ${f64Lit(0)}`);
1965
- else if (t.kind === "bool")
1966
- this.B.terminate("ret i1 false");
1967
- else
1968
- this.B.terminate("ret ptr null");
2083
+ let cleanup = this.unwindCleanups.get(key);
2084
+ if (!cleanup) {
2085
+ cleanup = { label: this.B.newLabel("exc.cleanup"), entries, terminator };
2086
+ this.unwindCleanups.set(key, cleanup);
2087
+ }
2088
+ this.B.br(cleanup.label);
1969
2089
  }
1970
2090
  /** The emitter contract for exceptions: after EVERY call that can throw
1971
2091
  * (per the may-throw analysis), test the pending flag and unwind. The
@@ -2011,14 +2131,32 @@ class LlEmitter {
2011
2131
  // Hierarchy instances carry a vtable word: the OBJ kind keeps the
2012
2132
  // dynamic class inspectable (catch-binding instanceof, the uncaught
2013
2133
  // printer's "name: message" for Error instances).
2014
- const rc = vAdapters(this, t);
2134
+ const rc = vAdapters(this.shapeHost, t);
2015
2135
  this.declare(`declare void @scr_throw_obj(ptr, ptr, ptr, ptr)`);
2016
- B.line(`call void @scr_throw_obj(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this, t)})`);
2136
+ B.line(`call void @scr_throw_obj(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this.shapeHost, t)})`);
2137
+ }
2138
+ else if (t.kind === "symbol" || t.kind === "bigint" || t.kind === "func" || t.kind === "classval") {
2139
+ const rc = vAdapters(this.shapeHost, t);
2140
+ this.declare(`declare void @scr_throw_primitive_ref(ptr, ptr, ptr, ptr)`);
2141
+ B.line(`call void @scr_throw_primitive_ref(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr null)`);
2142
+ }
2143
+ else if (t.kind === "dyn") {
2144
+ this.declare(`declare void @scr_dyn_throw(ptr)`);
2145
+ B.line(`call void @scr_dyn_throw(ptr ${v.name})`);
2146
+ }
2147
+ else if (t.kind === "jsval") {
2148
+ const rc = vAdapters(this.shapeHost, t);
2149
+ const test = "scr_jsval_is_object";
2150
+ this.declare(`declare zeroext i1 @${test}(ptr)`);
2151
+ this.declare(`declare void @scr_throw_ref_classified(ptr, ptr, ptr, ptr, i1 zeroext)`);
2152
+ const object = B.tmp();
2153
+ B.line(`${object} = call zeroext i1 @${test}(ptr ${v.name})`);
2154
+ 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})`);
2017
2155
  }
2018
2156
  else {
2019
- const rc = vAdapters(this, t);
2157
+ const rc = vAdapters(this.shapeHost, t);
2020
2158
  this.declare(`declare void @scr_throw_ref(ptr, ptr, ptr, ptr)`);
2021
- B.line(`call void @scr_throw_ref(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this, t)})`);
2159
+ B.line(`call void @scr_throw_ref(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this.shapeHost, t)})`);
2022
2160
  }
2023
2161
  }
2024
2162
  /** JS truthiness of a value (falsy: false, 0, -0, NaN, "", nullish
@@ -2028,7 +2166,7 @@ class LlEmitter {
2028
2166
  truthy(v) {
2029
2167
  const B = this.B;
2030
2168
  if (v.type.kind === "union") {
2031
- // The ARM value's ToBoolean: an inline tag switch (the C emitter's
2169
+ // The ARM value's ToBoolean: an inline tag switch (the runtime ABI’s
2032
2170
  // per-union interned helper, emitted at the use site instead).
2033
2171
  const def = this.unionsById.get(v.type.unionId);
2034
2172
  if (!def)
@@ -2038,7 +2176,7 @@ class LlEmitter {
2038
2176
  const join = B.newLabel("ut.j");
2039
2177
  this.unionTagSwitch(v.name, def, (arm) => {
2040
2178
  let valueName = "false";
2041
- if (arm.kind === "f64") {
2179
+ if (arm.kind === "f64" || arm.kind === "procStream") {
2042
2180
  valueName = B.tmp();
2043
2181
  this.declare(`declare double @scr_union_get_f64(ptr)`);
2044
2182
  B.line(`${valueName} = call double @scr_union_get_f64(ptr ${v.name})`);
@@ -2051,7 +2189,7 @@ class LlEmitter {
2051
2189
  else if (arm.kind === "string") {
2052
2190
  valueName = this.unionPeek(v.name);
2053
2191
  }
2054
- else if (arm.kind === "bigint") {
2192
+ else if (arm.kind === "bigint" || arm.kind === "dyn" || arm.kind === "jsval") {
2055
2193
  valueName = this.unionPeek(v.name);
2056
2194
  }
2057
2195
  const truthy = this.truthyOf(arm.kind, valueName, true);
@@ -2072,15 +2210,10 @@ class LlEmitter {
2072
2210
  switch (kind) {
2073
2211
  case "undefinedT":
2074
2212
  case "nullT":
2075
- if (!unionArm)
2076
- throw new LlvmUnsupportedError(`truthy:${kind}`);
2077
2213
  return "false";
2078
2214
  case "bool":
2079
2215
  return valueName;
2080
- case "f64":
2081
- case "procStream": {
2082
- if (unionArm && kind === "procStream")
2083
- throw new LlvmUnsupportedError(`truthy:union:${kind}`);
2216
+ case "f64": {
2084
2217
  const truthy = B.tmp();
2085
2218
  B.line(`${truthy} = fcmp one double ${valueName}, ${f64Lit(0)}`);
2086
2219
  return truthy;
@@ -2101,6 +2234,9 @@ class LlEmitter {
2101
2234
  return truthy;
2102
2235
  }
2103
2236
  case "date":
2237
+ // Process streams use a numeric descriptor internally, including zero
2238
+ // for stdin. They remain JavaScript objects in boolean contexts.
2239
+ case "procStream":
2104
2240
  return "true";
2105
2241
  case "array":
2106
2242
  case "record":
@@ -2124,7 +2260,17 @@ class LlEmitter {
2124
2260
  case "generator":
2125
2261
  case "fsWatcher":
2126
2262
  case "cryptoHash":
2127
- case "cryptoHmac": {
2263
+ case "cryptoHmac":
2264
+ case "netSocket":
2265
+ case "netServer":
2266
+ case "httpReq":
2267
+ case "httpRes":
2268
+ case "httpClientReq":
2269
+ case "http2Session":
2270
+ case "http2Stream":
2271
+ case "dgramSocket":
2272
+ case "secureCtx":
2273
+ case "testCtx": {
2128
2274
  if (unionArm)
2129
2275
  return "true";
2130
2276
  const truthy = B.tmp();
@@ -2132,16 +2278,12 @@ class LlEmitter {
2132
2278
  return truthy;
2133
2279
  }
2134
2280
  case "dyn": {
2135
- if (unionArm)
2136
- throw new LlvmUnsupportedError(`truthy:union:${kind}`);
2137
2281
  this.declare(`declare zeroext i1 @scr_dyn_truthy(ptr)`);
2138
2282
  const truthy = B.tmp();
2139
2283
  B.line(`${truthy} = call zeroext i1 @scr_dyn_truthy(ptr ${valueName})`);
2140
2284
  return truthy;
2141
2285
  }
2142
2286
  case "jsval": {
2143
- if (unionArm)
2144
- throw new LlvmUnsupportedError(`truthy:union:${kind}`);
2145
2287
  this.declare(`declare i32 @scr_jsval_truthy(ptr)`);
2146
2288
  const raw = B.tmp();
2147
2289
  const truthy = B.tmp();
@@ -2173,17 +2315,48 @@ class LlEmitter {
2173
2315
  }
2174
2316
  /** Emits `switch` over a union's tag with one block per arm; each arm
2175
2317
  * body must TERMINATE its block (the callers branch to a join). The
2176
- * default block is the C emitter's invalid-tag abort. */
2177
- unionTagSwitch(uName, def, arm) {
2318
+ * default block is the runtime ABI’s invalid-tag abort. Shared field
2319
+ * reads can group equivalent storage prefixes and emit one representative. */
2320
+ unionTagSwitch(uName, def, arm, fieldGroups) {
2178
2321
  const B = this.B;
2179
2322
  const tag = this.unionTag(uName);
2180
2323
  const bad = B.newLabel("u.bad");
2181
- const labels = def.arms.map(() => B.newLabel("u.a"));
2182
- B.terminate(`switch i32 ${tag}, label %${bad} [ ${def.arms.map((_, i) => `i32 ${i}, label %${labels[i]}`).join(" ")} ]`);
2183
- def.arms.forEach((a, i) => {
2184
- B.startBlock(labels[i]);
2185
- arm(a, i);
2186
- });
2324
+ const labels = [];
2325
+ if (fieldGroups) {
2326
+ for (const group of fieldGroups) {
2327
+ const label = B.newLabel("u.a");
2328
+ for (const member of group) {
2329
+ if (member === undefined)
2330
+ throw new InternalCompilerError("llvm emitter bug: missing union field tag");
2331
+ labels[member] = label;
2332
+ }
2333
+ }
2334
+ }
2335
+ else {
2336
+ for (let i = 0; i < def.arms.length; i++)
2337
+ labels.push(B.newLabel("u.a"));
2338
+ }
2339
+ if (fieldGroups?.length === 1) {
2340
+ const valid = B.tmp();
2341
+ B.line(`${valid} = icmp ult i32 ${tag}, ${def.arms.length}`);
2342
+ B.condBr(valid, labels[0], bad);
2343
+ }
2344
+ else {
2345
+ B.terminate(`switch i32 ${tag}, label %${bad} [ ${def.arms.map((_, i) => `i32 ${i}, label %${labels[i]}`).join(" ")} ]`);
2346
+ }
2347
+ if (fieldGroups) {
2348
+ for (const group of fieldGroups) {
2349
+ const representative = group[0];
2350
+ B.startBlock(labels[representative]);
2351
+ arm(def.arms[representative], representative);
2352
+ }
2353
+ }
2354
+ else {
2355
+ def.arms.forEach((a, i) => {
2356
+ B.startBlock(labels[i]);
2357
+ arm(a, i);
2358
+ });
2359
+ }
2187
2360
  B.startBlock(bad);
2188
2361
  this.needsBadTag = true;
2189
2362
  B.line(`call void @sc_bad_tag()`);
@@ -2224,9 +2397,9 @@ class LlEmitter {
2224
2397
  B.line(`${t} = call ptr @scr_union_new_bool(i32 ${tag}, i1 ${v.name})`);
2225
2398
  return t;
2226
2399
  }
2227
- const rc = vAdapters(this, v.type);
2400
+ const rc = vAdapters(this.shapeHost, v.type);
2228
2401
  this.declare(`declare ptr @scr_union_new_ref(i32, ptr, ptr, ptr, ptr)`);
2229
- 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)})`);
2402
+ 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)})`);
2230
2403
  return t;
2231
2404
  }
2232
2405
  // ── class plumbing ──────────────────────────────────────────────────────
@@ -2239,7 +2412,7 @@ class LlEmitter {
2239
2412
  /** The field-slot pointer of a class member: rc at 0, the vtable word at
2240
2413
  * 1 on hierarchy members, then the flattened field list. Runtime error
2241
2414
  * classes GEP through %ScrError (their structs live in the runtime; the
2242
- * def's [name, message, %code] order matches the layout). */
2415
+ * def's [name, message, %code, %cause] order matches the layout). */
2243
2416
  classFieldPtr(objName, className, field) {
2244
2417
  const meta = this.classMetaOf(className);
2245
2418
  const { index, type } = classFieldIndex(meta, field);
@@ -2278,6 +2451,37 @@ class LlEmitter {
2278
2451
  throw new InternalCompilerError(`llvm emitter bug: unknown record shape ${shapeId}`);
2279
2452
  return shape;
2280
2453
  }
2454
+ /** Record prefixes with the same LLVM storage types put a field at the
2455
+ * same offset on every target. Share one field-read block per matching
2456
+ * prefix; class variants retain their own concrete layout dispatch. */
2457
+ unionFieldGroups(def, field) {
2458
+ const key = `${def.id}\0${field}`;
2459
+ const cached = this.unionFieldReadGroups.get(key);
2460
+ if (cached !== undefined)
2461
+ return cached;
2462
+ const groups = new Map();
2463
+ for (let tag = 0; tag < def.arms.length; tag++) {
2464
+ const arm = def.arms[tag];
2465
+ let layout = `variant:${tag}`;
2466
+ if (arm.kind === "record") {
2467
+ const shape = this.recordShape(arm.shapeId);
2468
+ const index = shape.fields.findIndex((entry) => entry.name === field);
2469
+ if (index < 0)
2470
+ throw new InternalCompilerError(`llvm emitter bug: missing union field ${field}`);
2471
+ layout = "record:";
2472
+ for (let i = 0; i <= index; i++)
2473
+ layout += `${llFieldType(shape.fields[i].type)};`;
2474
+ }
2475
+ const group = groups.get(layout);
2476
+ if (group)
2477
+ group.push(tag);
2478
+ else
2479
+ groups.set(layout, [tag]);
2480
+ }
2481
+ const result = [...groups.values()];
2482
+ this.unionFieldReadGroups.set(key, result);
2483
+ return result;
2484
+ }
2281
2485
  /** The field-slot pointer of a record member (rc header at index 0). */
2282
2486
  recordFieldPtr(objName, shapeId, field) {
2283
2487
  const shape = this.recordShape(shapeId);
@@ -2341,6 +2545,13 @@ class LlEmitter {
2341
2545
  throw new InternalCompilerError(`llvm emitter bug: unknown binding ${id}`);
2342
2546
  return { kind: "global", slot: `@${mangleGlobal(id)}`, type: g };
2343
2547
  }
2548
+ emitDebugLocal(local, slot, arg = 0, captured = false) {
2549
+ const debug = this.debug?.local(local, this.debugScope, arg, captured);
2550
+ if (!debug)
2551
+ return;
2552
+ this.declare("declare void @llvm.dbg.declare(metadata, metadata, metadata)");
2553
+ this.B.entryAllocas.push(`call void @llvm.dbg.declare(metadata ptr ${slot}, metadata ${debug.variable}, metadata ${debug.expression}), !dbg ${debug.location}`);
2554
+ }
2344
2555
  /** Loads a boxed binding's box pointer out of its slot. */
2345
2556
  loadBox(slot) {
2346
2557
  const b = this.B.tmp();
@@ -2395,7 +2606,7 @@ class LlEmitter {
2395
2606
  const B = this.B;
2396
2607
  const acc = boxAccess(t);
2397
2608
  const cell = B.tmp();
2398
- B.line(`${cell} = ${arrNewCall(this, t, "1")} ; TDZ cell`);
2609
+ B.line(`${cell} = ${arrNewCall(this.shapeHost, t, "1")} ; TDZ cell`);
2399
2610
  this.arrPush(cell, acc === "bool" ? "bool" : "f64", value);
2400
2611
  this.declare(`declare void @scr_box_set_ref(ptr, ptr)`);
2401
2612
  B.line(`call void @scr_box_set_ref(ptr ${box}, ptr ${cell})`);
@@ -2404,7 +2615,7 @@ class LlEmitter {
2404
2615
  * the temporal dead zone — throw Node's exact catchable ReferenceError
2405
2616
  * (exprs.ts's varRef guard). Scalars then peek the one-element
2406
2617
  * array cell; ref kinds read the box normally (+1). */
2407
- tdzBoxRead(box, t, name) {
2618
+ checkTdz(box, name) {
2408
2619
  const B = this.B;
2409
2620
  const slotp = B.tmp();
2410
2621
  const slotv = B.tmp();
@@ -2412,6 +2623,22 @@ class LlEmitter {
2412
2623
  B.line(`${slotp} = getelementptr inbounds %ScrBox, ptr ${box}, i64 0, i32 5`);
2413
2624
  B.line(`${slotv} = load i64, ptr ${slotp}`);
2414
2625
  B.line(`${empty} = icmp eq i64 ${slotv}, 0`);
2626
+ this.throwIfUninitialized(empty, name);
2627
+ return slotv;
2628
+ }
2629
+ checkGlobalTdz(id) {
2630
+ const name = this.tdzGlobals.get(id);
2631
+ if (name === undefined)
2632
+ return;
2633
+ const B = this.B;
2634
+ const value = B.tmp();
2635
+ const empty = B.tmp();
2636
+ B.line(`${value} = load ptr, ptr @${mangleGlobal(id)}`);
2637
+ B.line(`${empty} = icmp eq ptr ${value}, null`);
2638
+ this.throwIfUninitialized(empty, name);
2639
+ }
2640
+ throwIfUninitialized(empty, name) {
2641
+ const B = this.B;
2415
2642
  const lt = B.newLabel("tdz.t");
2416
2643
  const lk = B.newLabel("tdz.k");
2417
2644
  B.condBr(empty, lt, lk);
@@ -2424,6 +2651,10 @@ class LlEmitter {
2424
2651
  B.line(`call void @scr_throw_error_named(ptr ${errName}, ptr ${msg})`);
2425
2652
  this.emitUnwind();
2426
2653
  B.startBlock(lk);
2654
+ }
2655
+ tdzBoxRead(box, t, name) {
2656
+ const slotv = this.checkTdz(box, name);
2657
+ const B = this.B;
2427
2658
  const acc = boxAccess(t);
2428
2659
  if (acc === "ref")
2429
2660
  return this.boxGet(box, t);
@@ -2437,12 +2668,34 @@ class LlEmitter {
2437
2668
  B.line(`${v} = call ${accTy} @scr_arr_get_${acc}(ptr ${cell}, double ${f64Lit(0)})`);
2438
2669
  return v;
2439
2670
  }
2671
+ /** Declaration stores initialize an empty TDZ box. Later stores check
2672
+ * it after the RHS and update scalar cells in place. References move in. */
2673
+ writeBindingBox(box, local, value, initializes = false, borrowed = false) {
2674
+ if (local.tdz) {
2675
+ const first = initializes || !local.mutable;
2676
+ const slotv = first ? null : this.checkTdz(box, local.name);
2677
+ const acc = boxAccess(local.type);
2678
+ if (acc !== "ref") {
2679
+ if (first)
2680
+ this.tdzScalarInit(box, local.type, value);
2681
+ else {
2682
+ const cell = this.B.tmp();
2683
+ this.B.line(`${cell} = inttoptr i64 ${slotv} to ptr`);
2684
+ const ty = acc === "bool" ? "i1" : "double";
2685
+ this.declare(`declare void @scr_arr_set_${acc}(ptr, double, ${acc === "bool" ? "i1 zeroext" : ty})`);
2686
+ this.B.line(`call void @scr_arr_set_${acc}(ptr ${cell}, double ${f64Lit(0)}, ${ty} ${value})`);
2687
+ }
2688
+ return;
2689
+ }
2690
+ }
2691
+ this.boxSet(box, local.type, borrowed && isRefCounted(local.type) ? this.retainValue(value, local.type) : value);
2692
+ }
2440
2693
  // ── functions ───────────────────────────────────────────────────────────
2441
2694
  /** The LLVM symbol a direct call or closure enters a function through:
2442
2695
  * async bodies are entered via their emitted spawn wrapper (which runs
2443
2696
  * the fiber eagerly to its first suspension and returns the promise);
2444
2697
  * generator bodies via theirs (which only ALLOCATES the suspended
2445
- * fiber and returns the generator object) — CEmitter.callTargetC. */
2698
+ * fiber and returns the generator object). */
2446
2699
  callTarget(fnName) {
2447
2700
  const fn = this.fnByName.get(fnName);
2448
2701
  if (fn?.generator !== undefined)
@@ -2506,7 +2759,7 @@ class LlEmitter {
2506
2759
  return;
2507
2760
  default:
2508
2761
  this.declare(`declare void @scr_gen_out_ref(ptr, ptr, ptr)`);
2509
- this.B.line(`call void @scr_gen_out_ref(ptr ${gen}, ptr ${v.name}, ptr ${vAdapters(this, ret).release})`);
2762
+ this.B.line(`call void @scr_gen_out_ref(ptr ${gen}, ptr ${v.name}, ptr ${vAdapters(this.shapeHost, ret).release})`);
2510
2763
  return;
2511
2764
  }
2512
2765
  }
@@ -2532,20 +2785,23 @@ class LlEmitter {
2532
2785
  this.B.line(`call void @scr_promise_fulfill_str(ptr ${pr}, ptr ${v.name}) ; moves in`);
2533
2786
  break;
2534
2787
  default: {
2535
- const rc = vAdapters(this, ret);
2788
+ const rc = vAdapters(this.shapeHost, ret);
2536
2789
  this.declare(`declare void @scr_promise_fulfill_ref(ptr, ptr, ptr, ptr, ptr)`);
2537
- this.B.line(`call void @scr_promise_fulfill_ref(ptr ${pr}, ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this, ret)})`);
2790
+ 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)})`);
2538
2791
  }
2539
2792
  }
2540
2793
  }
2541
2794
  emitFunction(fn) {
2542
2795
  const B = new BlockBuilder();
2543
2796
  this.B = B;
2797
+ this.debugScope = this.debug?.function(fn) ?? null;
2798
+ B.debugLocation = this.debug?.location(fn.loc, this.debugScope) ?? null;
2544
2799
  this.frames = [];
2545
2800
  this.scopes = [];
2801
+ this.unwindCleanups.clear();
2546
2802
  this.jumpTargets = [];
2547
2803
  this.currentLocals = new Map(fn.locals.map((l) => [l.id, l]));
2548
- this.captureIds = new Set((fn.captures ?? []).map((c) => c.localId));
2804
+ this.captureIds = new Set([...(fn.captures ?? []), ...(fn.classCaptures ?? [])].map((c) => c.localId));
2549
2805
  this.integerLoopBindings.clear();
2550
2806
  this.integerRanges = analyzeIntegerRanges(fn);
2551
2807
  this.chainSlots.clear();
@@ -2562,7 +2818,7 @@ class LlEmitter {
2562
2818
  this.declare(`declare token @llvm.coro.save(ptr)`);
2563
2819
  this.declare(`declare i8 @llvm.coro.suspend(token, i1)`);
2564
2820
  this.declare(`declare ptr @llvm.coro.free(token, ptr)`);
2565
- this.declare(`declare i1 @llvm.coro.end(ptr, i1, token)`);
2821
+ this.declare(`declare void @llvm.coro.end(ptr, i1, token)`);
2566
2822
  this.declare(`declare ptr @malloc(${this.sizeType})`);
2567
2823
  this.declare(`declare void @free(ptr)`);
2568
2824
  this.declare(`declare void @scr_wasi_coro_started(ptr)`);
@@ -2598,6 +2854,7 @@ class LlEmitter {
2598
2854
  ? "ptr"
2599
2855
  : this.llType(local.type);
2600
2856
  B.entryAllocas.push(`%${mangleLocal(local.id)} = alloca ${slotTy} ; ${local.name}`);
2857
+ this.emitDebugLocal(local, `%${mangleLocal(local.id)}`, fn.params.findIndex((p) => p.localId === local.id) + 1, this.captureIds.has(local.id));
2601
2858
  // Refcounted/boxed locals start NULL (the C prologue's `= NULL`):
2602
2859
  // scope-exit releases run whether or not an assign ever did.
2603
2860
  if (paramIds.has(local.id) || this.captureIds.has(local.id))
@@ -2617,6 +2874,22 @@ class LlEmitter {
2617
2874
  B.line(`${box} = load ptr, ptr ${p}`);
2618
2875
  B.line(`store ptr ${box}, ptr %${mangleLocal(c.localId)} ; captured ${c.name}`);
2619
2876
  });
2877
+ (fn.classCaptures ?? []).forEach((c) => {
2878
+ const self = fn.params[0];
2879
+ if (self.type.kind !== "object")
2880
+ throw new InternalCompilerError("class captures require an instance receiver");
2881
+ const classSlot = B.tmp();
2882
+ const classValue = B.tmp();
2883
+ const caps = B.tmp();
2884
+ const slot = B.tmp();
2885
+ const box = B.tmp();
2886
+ B.line(`${classSlot} = getelementptr inbounds %${mangleClassStruct(self.type.className)}, ptr %p_${mangleLocal(self.localId)}, i64 0, i32 ${classEnvironmentIndex(this.classMeta.get(self.type.className))}`);
2887
+ B.line(`${classValue} = load ptr, ptr ${classSlot}`);
2888
+ B.line(`${caps} = getelementptr inbounds %ScrClassObj, ptr ${classValue}, i64 1`);
2889
+ B.line(`${slot} = getelementptr inbounds ptr, ptr ${caps}, ${this.sizeType} ${c.slot}`);
2890
+ B.line(`${box} = load ptr, ptr ${slot}`);
2891
+ B.line(`store ptr ${box}, ptr %${mangleLocal(c.localId)} ; class capture ${c.name}`);
2892
+ });
2620
2893
  // Params spill into their slots; the function scope owns refcounted
2621
2894
  // params (callees own their params — callers passed +1). Boxed params
2622
2895
  // allocate the shared binding and move the raw value in.
@@ -2626,7 +2899,7 @@ class LlEmitter {
2626
2899
  const slot = `%${mangleLocal(p.localId)}`;
2627
2900
  if (local.boxed) {
2628
2901
  const box = B.tmp();
2629
- B.line(`${box} = ${boxNewCall(this, p.type)} ; ${p.name} (boxed param)`);
2902
+ B.line(`${box} = ${boxNewCall(this.shapeHost, p.type)} ; ${p.name} (boxed param)`);
2630
2903
  this.boxSet(box, p.type, `%p_${mangleLocal(p.localId)}`);
2631
2904
  B.line(`store ptr ${box}, ptr ${slot}`);
2632
2905
  fnScope.push({ slot, type: p.type, boxed: true });
@@ -2637,6 +2910,16 @@ class LlEmitter {
2637
2910
  fnScope.push({ slot, type: p.type });
2638
2911
  }
2639
2912
  this.scopes.push(fnScope);
2913
+ // Stackful native fibers retain these frames while suspended. The
2914
+ // active exception context owns the chain, so concurrent fibers isolate it.
2915
+ if (this.stackTraces && !this.wasi && fn.sourceName !== undefined) {
2916
+ this.declare(`declare void @scr_stack_enter(ptr, ptr)`);
2917
+ this.declare(`declare void @scr_stack_leave(ptr)`);
2918
+ B.entryAllocas.push(`%source_frame = alloca { ptr, ptr }`);
2919
+ const frame = ` at ${fn.sourceName} (${fn.loc.file})`;
2920
+ B.line(`call void @scr_stack_enter(ptr %source_frame, ptr ${this.cstr(frame)})`);
2921
+ B.returnEpilogue = `call void @scr_stack_leave(ptr %source_frame)`;
2922
+ }
2640
2923
  this.emitStmts(fn.body);
2641
2924
  // Implicit exit of a void function: release the function scope unless
2642
2925
  // the body already terminated its final block (return, or a throw
@@ -2676,8 +2959,7 @@ class LlEmitter {
2676
2959
  B.line(`call void @free(ptr ${frame})`);
2677
2960
  B.br(coro.suspendLabel);
2678
2961
  B.startBlock(coro.suspendLabel);
2679
- const ended = B.tmp();
2680
- B.line(`${ended} = call i1 @llvm.coro.end(ptr ${coro.handle}, i1 false, token none)`);
2962
+ B.line(`call void @llvm.coro.end(ptr ${coro.handle}, i1 false, token none)`);
2681
2963
  const ret = this.llType(fn.returnType);
2682
2964
  if (ret === "void")
2683
2965
  B.terminate(`ret void`);
@@ -2688,6 +2970,14 @@ class LlEmitter {
2688
2970
  else
2689
2971
  B.terminate(`ret ptr null`);
2690
2972
  }
2973
+ // Shared blocks have multiple source locations. Keep the location on
2974
+ // each incoming exception check instead of assigning one to the cleanup.
2975
+ B.debugLocation = null;
2976
+ for (const cleanup of this.unwindCleanups.values()) {
2977
+ B.startBlock(cleanup.label);
2978
+ this.releaseScope(cleanup.entries);
2979
+ B.terminate(cleanup.terminator);
2980
+ }
2691
2981
  if (this.logArgSlots > 0) {
2692
2982
  B.entryAllocas.push(`%logargs = alloca [${this.logArgSlots} x %ScrLogArg]`);
2693
2983
  }
@@ -2697,21 +2987,22 @@ class LlEmitter {
2697
2987
  params.unshift("ptr %sc_env");
2698
2988
  const ret = this.llType(fn.returnType);
2699
2989
  const attrs = coro !== null ? "#1" : FN_ATTRS;
2700
- return `define internal ${ret} @${mangleFunction(fn.name)}(${params.join(", ")}) ${attrs} { ; ${fn.name}\n${B.render()}\n}`;
2990
+ const debug = this.debugScope === null ? "" : ` !dbg ${this.debugScope}`;
2991
+ return `define internal ${ret} @${mangleFunction(fn.name)}(${params.join(", ")}) ${attrs}${debug} { ; ${fn.name}\n${B.render()}\n}`;
2701
2992
  }
2702
2993
  // ── statements ──────────────────────────────────────────────────────────
2703
2994
  emitStmts(stmts) {
2704
2995
  for (const s of stmts) {
2705
2996
  // Statements after a terminator are unreachable (dead code after
2706
- // return/break/continue) — the C emitter emits them as dead C; here
2707
- // they are skipped so no dropped SSA definition can leak forward.
2997
+ // return/break/continue). Skip them so no dropped SSA definition
2998
+ // can leak forward.
2708
2999
  if (this.B.isTerminated())
2709
3000
  return;
2710
3001
  this.emitStmt(s);
2711
3002
  }
2712
3003
  }
2713
3004
  /** Emits a block in its own lexical scope (refcounted locals released at
2714
- * end) — CEmitter.emitBlock without the braces. `setup` runs after the
3005
+ * end). `setup` runs after the
2715
3006
  * scope opens, before the statements — the catch-binding hook: it may
2716
3007
  * emit prelude lines and register entries the scope owns (released on
2717
3008
  * every exit, jumps and unwinds included). */
@@ -2726,6 +3017,16 @@ class LlEmitter {
2726
3017
  this.releaseScope(scope);
2727
3018
  }
2728
3019
  emitStmt(s) {
3020
+ const previous = this.B.debugLocation;
3021
+ this.B.debugLocation = this.debug?.location(s.loc, this.debugScope) ?? null;
3022
+ try {
3023
+ this.emitStmtBody(s);
3024
+ }
3025
+ finally {
3026
+ this.B.debugLocation = previous;
3027
+ }
3028
+ }
3029
+ emitStmtBody(s) {
2729
3030
  const B = this.B;
2730
3031
  this.frames.push([]);
2731
3032
  switch (s.kind) {
@@ -2740,7 +3041,7 @@ class LlEmitter {
2740
3041
  // bit pattern to spend on it (stmts.ts's varDecl).
2741
3042
  const boxNew = b.local.tdz === true && boxAccess(b.type) !== "ref"
2742
3043
  ? (this.declare(`declare ptr @scr_box_new(i32)`), `call ptr @scr_box_new(i32 3)`)
2743
- : boxNewCall(this, b.type);
3044
+ : boxNewCall(this.shapeHost, b.type);
2744
3045
  const box = B.tmp();
2745
3046
  B.line(`${box} = ${boxNew} ; let ${b.local.name} (boxed)`);
2746
3047
  B.line(`store ptr ${box}, ptr ${b.slot}`);
@@ -2785,17 +3086,13 @@ class LlEmitter {
2785
3086
  }
2786
3087
  const b = this.binding(s.localId);
2787
3088
  const v = this.emitExpr(s.value);
3089
+ if (b.kind === "global" && !s.initializes)
3090
+ this.checkGlobalTdz(s.localId);
2788
3091
  if (b.kind === "boxed") {
3092
+ this.writeBindingBox(this.loadBox(b.slot), b.local, v.name, s.initializes);
3093
+ // The RHS remains frame-owned until a possible TDZ throw passes.
2789
3094
  if (isRefCounted(v.type))
2790
- this.moveTemp(v); // set_ref releases the old value
2791
- // A scalar TDZ box (forward-captured const): the initializing
2792
- // write mints the one-element array cell — set_ref moves it in
2793
- // (and the empty-slot sentinel ends here).
2794
- if (b.local.tdz === true && boxAccess(b.type) !== "ref") {
2795
- this.tdzScalarInit(this.loadBox(b.slot), b.type, v.name);
2796
- break;
2797
- }
2798
- this.boxSet(this.loadBox(b.slot), b.type, v.name);
3095
+ this.moveTemp(v);
2799
3096
  break;
2800
3097
  }
2801
3098
  this.moveTemp(v);
@@ -3085,7 +3382,7 @@ class LlEmitter {
3085
3382
  kind: "loop",
3086
3383
  brkLabel: le,
3087
3384
  contLabel: lc,
3088
- ...(s.labels !== undefined && { labels: s.labels }),
3385
+ labels: s.labels,
3089
3386
  frameDepth: this.frames.length,
3090
3387
  scopeDepth: this.scopes.length,
3091
3388
  finallyDepth: this.finallyStack.length,
@@ -3107,7 +3404,7 @@ class LlEmitter {
3107
3404
  kind: "loop",
3108
3405
  brkLabel: le,
3109
3406
  contLabel: lc,
3110
- ...(s.labels !== undefined && { labels: s.labels }),
3407
+ labels: s.labels,
3111
3408
  frameDepth: this.frames.length,
3112
3409
  scopeDepth: this.scopes.length,
3113
3410
  finallyDepth: this.finallyStack.length,
@@ -3123,7 +3420,7 @@ class LlEmitter {
3123
3420
  case "for": {
3124
3421
  // The init's scope wraps the whole loop (break/continue must NOT
3125
3422
  // release it — scopeDepth captured after the push, C parity).
3126
- const integerLoop = matchIntegerBytesForLoop(s, this.currentLocals);
3423
+ const integerLoop = this.debug === null ? matchIntegerBytesForLoop(s, this.currentLocals) : null;
3127
3424
  this.scopes.push([]);
3128
3425
  let integerSlot = null;
3129
3426
  if (integerLoop) {
@@ -3133,7 +3430,12 @@ class LlEmitter {
3133
3430
  this.integerLoopBindings.set(integerLoop.localId, integerSlot);
3134
3431
  }
3135
3432
  else if (s.init) {
3136
- this.emitStmt(s.init);
3433
+ // A multi-declarator head shares the loop's scope. Emitting its
3434
+ // IR block as an ordinary block would release captured/ref locals
3435
+ // before the first condition.
3436
+ const initializers = s.init.kind === "block" ? s.init.body : [s.init];
3437
+ for (const initializer of initializers)
3438
+ this.emitStmt(initializer);
3137
3439
  }
3138
3440
  const lc = B.newLabel("loop.c");
3139
3441
  const lb = B.newLabel("loop.b");
@@ -3141,11 +3443,29 @@ class LlEmitter {
3141
3443
  // JS `for (let i ...)`: each iteration gets a FRESH binding holding
3142
3444
  // a copy of the previous one (closures made in iteration k keep
3143
3445
  // seeing iteration k's value) — only observable, and only emitted,
3144
- // when the init variable is captured (boxed). The freshening (and
3145
- // the update) live in the continue-target block.
3146
- const initLocal = s.init?.kind === "varDecl" ? this.currentLocals.get(s.init.localId) : undefined;
3147
- const freshens = initLocal?.boxed === true;
3148
- const lu = s.update || freshens ? B.newLabel("loop.u") : lc;
3446
+ // when a let variable is captured (boxed). Freshen before the first
3447
+ // condition and again in the continue-target block before updating.
3448
+ const initializers = s.init?.kind === "block" ? s.init.body : s.init ? [s.init] : [];
3449
+ const capturedLets = initializers.flatMap((init) => {
3450
+ const local = init.kind === "varDecl" ? this.currentLocals.get(init.localId) : undefined;
3451
+ return local?.boxed && local.mutable ? [local] : [];
3452
+ });
3453
+ const freshenBindings = () => {
3454
+ for (const local of capturedLets) {
3455
+ const slot = `%${mangleLocal(local.id)}`;
3456
+ const fresh = B.tmp();
3457
+ const old = B.tmp();
3458
+ B.line(`${fresh} = ${boxNewCall(this.shapeHost, local.type)} ; per-iteration ${local.name}`);
3459
+ B.line(`${old} = load ptr, ptr ${slot}`);
3460
+ const val = this.boxGet(old, local.type);
3461
+ this.boxSet(fresh, local.type, val);
3462
+ this.declare(`declare void @scr_box_release(ptr)`);
3463
+ B.line(`call void @scr_box_release(ptr ${old})`);
3464
+ B.line(`store ptr ${fresh}, ptr ${slot}`);
3465
+ }
3466
+ };
3467
+ const lu = s.update || capturedLets.length > 0 ? B.newLabel("loop.u") : lc;
3468
+ freshenBindings();
3149
3469
  B.br(lc);
3150
3470
  B.startBlock(lc);
3151
3471
  if (integerLoop && integerSlot) {
@@ -3169,7 +3489,7 @@ class LlEmitter {
3169
3489
  kind: "loop",
3170
3490
  brkLabel: le,
3171
3491
  contLabel: lu,
3172
- ...(s.labels !== undefined && { labels: s.labels }),
3492
+ labels: s.labels,
3173
3493
  frameDepth: this.frames.length,
3174
3494
  scopeDepth: this.scopes.length,
3175
3495
  finallyDepth: this.finallyStack.length,
@@ -3179,20 +3499,7 @@ class LlEmitter {
3179
3499
  B.br(lu);
3180
3500
  if (lu !== lc) {
3181
3501
  B.startBlock(lu);
3182
- if (freshens && initLocal) {
3183
- const slot = `%${mangleLocal(initLocal.id)}`;
3184
- const fresh = B.tmp();
3185
- const old = B.tmp();
3186
- B.line(`${fresh} = ${boxNewCall(this, initLocal.type)} ; per-iteration ${initLocal.name}`);
3187
- B.line(`${old} = load ptr, ptr ${slot}`);
3188
- const val = this.boxGet(old, initLocal.type); // ref: +1 out
3189
- this.boxSet(fresh, initLocal.type, val); // takes ownership
3190
- this.declare(`declare void @scr_box_release(ptr)`);
3191
- B.line(`call void @scr_box_release(ptr ${old})`);
3192
- B.line(`store ptr ${fresh}, ptr ${slot}`);
3193
- // The wrapper scope's entry releases whatever the slot points
3194
- // to at loop exit — now the freshest binding. Nothing to fix.
3195
- }
3502
+ freshenBindings();
3196
3503
  if (integerLoop && integerSlot) {
3197
3504
  const old = B.tmp();
3198
3505
  const next = B.tmp();
@@ -3241,7 +3548,7 @@ class LlEmitter {
3241
3548
  kind: "loop",
3242
3549
  brkLabel: le,
3243
3550
  contLabel: lu,
3244
- ...(s.labels !== undefined && { labels: s.labels }),
3551
+ labels: s.labels,
3245
3552
  frameDepth: this.frames.length,
3246
3553
  scopeDepth: this.scopes.length,
3247
3554
  finallyDepth: this.finallyStack.length,
@@ -3262,7 +3569,7 @@ class LlEmitter {
3262
3569
  // fresh const binding. The box takes ownership of a ref element's
3263
3570
  // +1 and is released with the iteration's scope.
3264
3571
  const box = B.tmp();
3265
- B.line(`${box} = ${boxNewCall(this, elem)} ; per-iteration ${localInfo.name}`);
3572
+ B.line(`${box} = ${boxNewCall(this.shapeHost, elem)} ; per-iteration ${localInfo.name}`);
3266
3573
  this.boxSet(box, elem, cur);
3267
3574
  B.line(`store ptr ${box}, ptr ${slot}`);
3268
3575
  this.scopes[this.scopes.length - 1].push({ slot, type: elem, boxed: true });
@@ -3335,10 +3642,7 @@ class LlEmitter {
3335
3642
  // tryStack it sees truncated to its region (its releases already
3336
3643
  // ran; a throw inside a copy propagates OUT of the completing
3337
3644
  // try, past its own catch), then the function-level releases and
3338
- // the actual ret. The C emitter routes this through per-region
3339
- // finally copies behind gotos with the value parked in sc_pret;
3340
- // the inline copies here are the same code at the same depths,
3341
- // with the parked value's ownership riding a synthetic slot-based
3645
+ // the actual ret. The parked value owns a synthetic slot-backed
3342
3646
  // scope entry during each copy so a throwing finally releases it.
3343
3647
  let v = null;
3344
3648
  if (s.value !== null) {
@@ -3593,7 +3897,7 @@ class LlEmitter {
3593
3897
  }
3594
3898
  /** JS-exact switch: lazily evaluated, arbitrary-expression case tests in
3595
3899
  * source order, bodies falling through in source order until a break —
3596
- * CEmitter.emitSwitch's goto chain, block-flavored. All case bodies
3900
+ * A chain of conditional branches. All case bodies
3597
3901
  * share ONE scope; because dispatch can jump PAST a varDecl into a later
3598
3902
  * case, refcounted/boxed case-body locals are NULL-reset up front and
3599
3903
  * the scope-exit releases rely on NULL tolerance. */
@@ -3651,7 +3955,7 @@ class LlEmitter {
3651
3955
  kind: "switch",
3652
3956
  brkLabel: end,
3653
3957
  contLabel: null,
3654
- ...(s.labels !== undefined && { labels: s.labels }),
3958
+ labels: s.labels,
3655
3959
  frameDepth: this.frames.length,
3656
3960
  scopeDepth: this.scopes.length,
3657
3961
  finallyDepth: this.finallyStack.length,
@@ -3676,7 +3980,7 @@ class LlEmitter {
3676
3980
  /** Evaluates a condition (IR conds are bool-typed) and releases its
3677
3981
  * temps BEFORE the branch — safe because the result is a scalar i1, and
3678
3982
  * required in loop-condition blocks (their temps must not survive into
3679
- * later blocks across the back edge). CEmitter.emitCondition. */
3983
+ * later blocks across the back edge). */
3680
3984
  emitCondition(cond) {
3681
3985
  const v = this.emitExpr(cond);
3682
3986
  const frame = this.currentFrame();
@@ -3687,7 +3991,7 @@ class LlEmitter {
3687
3991
  /** Evaluates `expr` in its own statement frame inside an already-open
3688
3992
  * branch and moves the result into `slot`: the chosen value's ownership
3689
3993
  * transfers, every other temp the arm allocated releases inside the
3690
- * branch. The shared core of ternary/logical. CEmitter.emitBranchInto. */
3994
+ * branch. The shared core of ternary/logical. */
3691
3995
  emitBranchInto(slot, expr) {
3692
3996
  this.frames.push([]);
3693
3997
  const v = this.emitExpr(expr);
@@ -3696,24 +4000,28 @@ class LlEmitter {
3696
4000
  this.releaseFrame(this.frames.pop());
3697
4001
  }
3698
4002
  // ── expressions ─────────────────────────────────────────────────────────
3699
- /** One audited escape hatch for the type-only boundary used by the
3700
- * extracted expression modules. LlEmitter remains the sole owner of the
3701
- * mutable emission state; the context exposes only the operations those
3702
- * modules require. */
3703
- expressionContext() {
3704
- return this;
3705
- }
3706
4003
  emitLiteralExpr(e) {
3707
- return emitLiteralExpr(this.expressionContext(), e);
4004
+ return emitLiteralExpr(this, e);
3708
4005
  }
3709
4006
  emitOperatorExpr(e) {
3710
- return emitOperatorExpr(this.expressionContext(), e);
4007
+ if (e.kind === "seqExpr") {
4008
+ // Saved operands can feed later call arguments. Transfer ownership
4009
+ // to this expression's frame so they survive those reads and still
4010
+ // die on the path that created them, including inside lazy branches.
4011
+ this.scopes.push([]);
4012
+ const result = emitOperatorExpr(this, e);
4013
+ for (const local of this.scopes.pop()) {
4014
+ this.currentFrame().push({ name: local.slot, type: local.type, slot: true, ...(local.boxed ? { boxed: true } : {}) });
4015
+ }
4016
+ return result;
4017
+ }
4018
+ return emitOperatorExpr(this, e);
3711
4019
  }
3712
4020
  emitControlExpr(e) {
3713
- return emitControlExpr(this.expressionContext(), e);
4021
+ return emitControlExpr(this, e);
3714
4022
  }
3715
4023
  emitStringExpr(e) {
3716
- return emitStringExpr(this.expressionContext(), e);
4024
+ return emitStringExpr(this, e);
3717
4025
  }
3718
4026
  /**
3719
4027
  * Lower canonical `target = target + suffix` after evaluating the old
@@ -3757,251 +4065,273 @@ class LlEmitter {
3757
4065
  return result;
3758
4066
  }
3759
4067
  emitContainerExpr(e) {
3760
- return emitContainerExpr(this.expressionContext(), e);
4068
+ return emitContainerExpr(this, e);
3761
4069
  }
3762
4070
  emitCallExpr(e) {
3763
- return emitCallExpr(this.expressionContext(), e);
4071
+ return emitCallExpr(this, e);
3764
4072
  }
3765
4073
  emitRecordExpr(e) {
3766
- return emitRecordExpr(this.expressionContext(), e);
4074
+ return emitRecordExpr(this, e);
3767
4075
  }
3768
4076
  emitDynamicExpr(e) {
3769
- return emitDynamicExpr(this.expressionContext(), e);
4077
+ return emitDynamicExpr(this, e);
3770
4078
  }
3771
4079
  emitIntrinsicExpr(e) {
3772
- return emitIntrinsicExpr(this.expressionContext(), e);
4080
+ return emitIntrinsicExpr(this, e);
3773
4081
  }
3774
4082
  emitSerializationExpr(e) {
3775
- return emitSerializationExpr(this.expressionContext(), e);
4083
+ return emitSerializationExpr(this, e);
3776
4084
  }
3777
4085
  emitAsyncExpr(e) {
3778
- return emitAsyncExpr(this.expressionContext(), e);
4086
+ return emitAsyncExpr(this, e);
3779
4087
  }
3780
4088
  emitJsInteropExpr(e) {
3781
- return emitJsInteropExpr(this.expressionContext(), e);
4089
+ return emitJsInteropExpr(this, e);
4090
+ }
4091
+ /** Read a receiver whose value is consumed immediately by a field or tag
4092
+ * load. No user code may run between this read and its consumer. Locals
4093
+ * and their projections already have an owner; other expressions keep
4094
+ * their ordinary statement-frame ownership. The caller must retain any
4095
+ * reference result before evaluating another expression. */
4096
+ emitReadReceiver(e) {
4097
+ if (!isRefCounted(e.type))
4098
+ return this.emitExpr(e);
4099
+ if (e.kind === "varRef") {
4100
+ const binding = this.binding(e.localId);
4101
+ // Capture boxes can carry TDZ and caught-value conversion semantics.
4102
+ if (binding.kind === "boxed")
4103
+ return this.emitExpr(e);
4104
+ if (binding.kind === "global")
4105
+ this.checkGlobalTdz(e.localId);
4106
+ const value = this.B.tmp();
4107
+ this.B.line(`${value} = load ptr, ptr ${binding.slot}`);
4108
+ return { name: value, type: e.type };
4109
+ }
4110
+ if (e.kind === "unionNarrow") {
4111
+ const union = this.emitReadReceiver(e.value);
4112
+ return { name: this.unionPeek(union.name), type: e.type };
4113
+ }
4114
+ if (e.kind === "recordGet" || e.kind === "fieldGet") {
4115
+ const receiver = this.emitReadReceiver(e.obj);
4116
+ const { ptr, type } = e.kind === "recordGet"
4117
+ ? this.recordFieldPtr(receiver.name, e.shapeId, e.field)
4118
+ : this.classFieldPtr(receiver.name, e.className, e.field);
4119
+ return { name: this.loadField(ptr, type), type: e.type };
4120
+ }
4121
+ return this.emitExpr(e);
3782
4122
  }
3783
4123
  emitExpr(e) {
3784
- return emitExpr(this.expressionContext(), e);
4124
+ return emitExpr(this, e);
3785
4125
  }
3786
4126
  emitJsMarshal(e) {
3787
- return emitJsMarshal(this.expressionContext(), e);
4127
+ return emitJsMarshal(this, e);
3788
4128
  }
3789
4129
  emitJsOp(e) {
3790
- return emitJsOp(this.expressionContext(), e);
4130
+ return emitJsOp(this, e);
3791
4131
  }
3792
4132
  emitJsExit(e) {
3793
- return emitJsExit(this.expressionContext(), e);
4133
+ return emitJsExit(this, e);
3794
4134
  }
3795
4135
  islandAdapter(arity, retKind) {
3796
- return islandAdapter(this.expressionContext(), arity, retKind);
4136
+ return islandAdapter(this, arity, retKind);
3797
4137
  }
3798
4138
  islandTypedAdapter(fn) {
3799
- return islandTypedAdapter(this.expressionContext(), fn);
4139
+ return islandTypedAdapter(this, fn);
3800
4140
  }
3801
4141
  dynKind(d) {
3802
- return dynKind(this.expressionContext(), d);
4142
+ return dynKind(this, d);
3803
4143
  }
3804
4144
  raceAdapterFor(from, to) {
3805
- return raceAdapterFor(this.expressionContext(), from, to);
4145
+ return raceAdapterFor(this, from, to);
3806
4146
  }
3807
4147
  genResultThunkFor(genT, recT) {
3808
- return genResultThunkFor(this.expressionContext(), genT, recT);
4148
+ return genResultThunkFor(this, genT, recT);
3809
4149
  }
3810
4150
  childExitThunkFor(param) {
3811
- return childExitThunkFor(this.expressionContext(), param);
4151
+ return childExitThunkFor(this, param);
3812
4152
  }
3813
4153
  execFileThunkFor(cbT) {
3814
- return execFileThunkFor(this.expressionContext(), cbT);
4154
+ return execFileThunkFor(this, cbT);
3815
4155
  }
3816
4156
  ipcMessageThunkFor(cbT) {
3817
- return ipcMessageThunkFor(this.expressionContext(), cbT);
4157
+ return ipcMessageThunkFor(this, cbT);
3818
4158
  }
3819
4159
  ipcSendThunkFor(cbT) {
3820
- return ipcSendThunkFor(this.expressionContext(), cbT);
4160
+ return ipcSendThunkFor(this, cbT);
3821
4161
  }
3822
4162
  childExitSignalThunkFor(codeParam, sigParam) {
3823
- return childExitSignalThunkFor(this.expressionContext(), codeParam, sigParam);
4163
+ return childExitSignalThunkFor(this, codeParam, sigParam);
3824
4164
  }
3825
4165
  childDataThunkFor(param) {
3826
- return childDataThunkFor(this.expressionContext(), param);
4166
+ return childDataThunkFor(this, param);
3827
4167
  }
3828
4168
  emitterFixedAdapter(cbT) {
3829
- return emitterFixedAdapter(this.expressionContext(), cbT);
4169
+ return emitterFixedAdapter(this, cbT);
3830
4170
  }
3831
4171
  wrapEmitterListener(target, adapterFn) {
3832
- return wrapEmitterListener(this.expressionContext(), target, adapterFn);
4172
+ return wrapEmitterListener(this, target, adapterFn);
3833
4173
  }
3834
4174
  unwrapNullableClosure(u, funcTag) {
3835
- return unwrapNullableClosure(this.expressionContext(), u, funcTag);
4175
+ return unwrapNullableClosure(this, u, funcTag);
3836
4176
  }
3837
4177
  closeBindThunkFor(cbUnion, retServer) {
3838
- return closeBindThunkFor(this.expressionContext(), cbUnion, retServer);
4178
+ return closeBindThunkFor(this, cbUnion, retServer);
3839
4179
  }
3840
4180
  closeOverrideWrapFor(cbUnion, retServer) {
3841
- return closeOverrideWrapFor(this.expressionContext(), cbUnion, retServer);
4181
+ return closeOverrideWrapFor(this, cbUnion, retServer);
3842
4182
  }
3843
4183
  streamDataAdapter(cbT) {
3844
- return streamDataAdapter(this.expressionContext(), cbT);
4184
+ return streamDataAdapter(this, cbT);
3845
4185
  }
3846
4186
  streamDoneFnFor(kind, doneT) {
3847
- return streamDoneFnFor(this.expressionContext(), kind, doneT);
4187
+ return streamDoneFnFor(this, kind, doneT);
3848
4188
  }
3849
4189
  fsRenameThunkFor(cbT) {
3850
- return fsRenameThunkFor(this.expressionContext(), cbT);
4190
+ return fsRenameThunkFor(this, cbT);
3851
4191
  }
3852
4192
  cryptoBytesThunkFor(cbT) {
3853
- return cryptoBytesThunkFor(this.expressionContext(), cbT);
4193
+ return cryptoBytesThunkFor(this, cbT);
3854
4194
  }
3855
4195
  zlibBytesThunkFor(cbT) {
3856
- return zlibBytesThunkFor(this.expressionContext(), cbT);
4196
+ return zlibBytesThunkFor(this, cbT);
3857
4197
  }
3858
4198
  streamCbThunkFor(kind, cbT) {
3859
- return streamCbThunkFor(this.expressionContext(), kind, cbT);
4199
+ return streamCbThunkFor(this, kind, cbT);
3860
4200
  }
3861
4201
  resolveThunkFor(inner) {
3862
- return resolveThunkFor(this.expressionContext(), inner);
4202
+ return resolveThunkFor(this, inner);
3863
4203
  }
3864
4204
  tagInSet(uName, tags) {
3865
- return tagInSet(this.expressionContext(), uName, tags);
4205
+ return tagInSet(this, uName, tags);
3866
4206
  }
3867
4207
  arrPush(arr, acc, value) {
3868
- return arrPush(this.expressionContext(), arr, acc, value);
4208
+ return arrPush(this, arr, acc, value);
3869
4209
  }
3870
4210
  emitArrayCopyLoop(dst, src, acc) {
3871
- return emitArrayCopyLoop(this.expressionContext(), dst, src, acc);
4211
+ return emitArrayCopyLoop(this, dst, src, acc);
3872
4212
  }
3873
4213
  emitStrIntrinsic(e) {
3874
- return emitStrIntrinsic(this.expressionContext(), e);
4214
+ return emitStrIntrinsic(this, e);
3875
4215
  }
3876
4216
  emitArrIntrinsic(e) {
3877
- return emitArrIntrinsic(this.expressionContext(), e);
4217
+ return emitArrIntrinsic(this, e);
3878
4218
  }
3879
4219
  wrapNullable(raw, present, valueType, valueTag, resultType, absentTag) {
3880
- return wrapNullable(this.expressionContext(), raw, present, valueType, valueTag, resultType, absentTag);
4220
+ return wrapNullable(this, raw, present, valueType, valueTag, resultType, absentTag);
3881
4221
  }
3882
4222
  emitMapNew(e) {
3883
- return emitMapNew(this.expressionContext(), e);
4223
+ return emitMapNew(this, e);
3884
4224
  }
3885
4225
  mapSet(m, kAcc, vAcc, key, value) {
3886
- return mapSet(this.expressionContext(), m, kAcc, vAcc, key, value);
4226
+ return mapSet(this, m, kAcc, vAcc, key, value);
3887
4227
  }
3888
4228
  emitMapLikeIntrinsic(e) {
3889
- return emitMapLikeIntrinsic(this.expressionContext(), e);
4229
+ return emitMapLikeIntrinsic(this, e);
3890
4230
  }
3891
4231
  emitSetNew(e) {
3892
- return emitSetNew(this.expressionContext(), e);
4232
+ return emitSetNew(this, e);
3893
4233
  }
3894
4234
  emitStableReceiver(receiver, following) {
3895
- return emitStableReceiver(this.expressionContext(), receiver, following);
4235
+ return emitStableReceiver(this, receiver, following);
3896
4236
  }
3897
4237
  emitIntegerLoopIndex(expr) {
3898
- return emitIntegerLoopIndex(this.expressionContext(), expr);
4238
+ return emitIntegerLoopIndex(this, expr);
3899
4239
  }
3900
4240
  emitBytesIndex(receiver, index, integerIndex = false) {
3901
- return emitBytesIndex(this.expressionContext(), receiver, index, integerIndex);
4241
+ return emitBytesIndex(this, receiver, index, integerIndex);
3902
4242
  }
3903
4243
  emitBytesData(receiver) {
3904
- return emitBytesData(this.expressionContext(), receiver);
4244
+ return emitBytesData(this, receiver);
3905
4245
  }
3906
4246
  emitBytesLength(elem, receiver, bytes) {
3907
- return emitBytesLength(this.expressionContext(), elem, receiver, bytes);
4247
+ return emitBytesLength(this, elem, receiver, bytes);
3908
4248
  }
3909
4249
  emitBytesGet(elem, receiver, index, integerIndex = false) {
3910
- return emitBytesGet(this.expressionContext(), elem, receiver, index, integerIndex);
4250
+ return emitBytesGet(this, elem, receiver, index, integerIndex);
3911
4251
  }
3912
4252
  emitToUint32(value, expr) {
3913
- return emitToUint32(this.expressionContext(), value, expr);
4253
+ return emitToUint32(this, value, expr);
3914
4254
  }
3915
4255
  emitBytesSet(elem, receiver, index, value, integerIndex = false) {
3916
- return emitBytesSet(this.expressionContext(), elem, receiver, index, value, integerIndex);
4256
+ return emitBytesSet(this, elem, receiver, index, value, integerIndex);
3917
4257
  }
3918
4258
  emitBytesIntrinsic(e) {
3919
- return emitBytesIntrinsic(this.expressionContext(), e);
4259
+ return emitBytesIntrinsic(this, e);
3920
4260
  }
3921
4261
  emitRegexIntrinsic(e) {
3922
- return emitRegexIntrinsic(this.expressionContext(), e);
4262
+ return emitRegexIntrinsic(this, e);
3923
4263
  }
3924
4264
  emitRecordKeyGet(e) {
3925
- return emitRecordKeyGet(this.expressionContext(), e);
4265
+ return emitRecordKeyGet(this, e);
3926
4266
  }
3927
4267
  keyedRecordReadInto(slot, join, objName, keyName, shapeId, resultType, overflowOnly, loc) {
3928
- return keyedRecordReadInto(this.expressionContext(), slot, join, objName, keyName, shapeId, resultType, overflowOnly, loc);
4268
+ return keyedRecordReadInto(this, slot, join, objName, keyName, shapeId, resultType, overflowOnly, loc);
3929
4269
  }
3930
4270
  dynPromiseAdapter(inner) {
3931
- return dynPromiseAdapter(this.expressionContext(), inner);
4271
+ return dynPromiseAdapter(this, inner);
3932
4272
  }
3933
4273
  streamTypedRefCommitAdapter(t, snapshot) {
3934
- return streamTypedRefCommitAdapter(this.expressionContext(), t, snapshot);
4274
+ return streamTypedRefCommitAdapter(this, t, snapshot);
3935
4275
  }
3936
4276
  liveDynRefAdapter(t) {
3937
- const key = typeKey(t);
3938
- const existing = this.liveDynRefAdapters.get(key);
3939
- if (existing)
3940
- return existing;
3941
4277
  if (!streamTypedRefEligible(t) && !isDynTypedRefType(t)) {
3942
- throw new InternalCompilerError(`llvm emitter bug: live dyn ref of ${key}`);
4278
+ throw new InternalCompilerError(`llvm emitter bug: live dyn ref of ${typeKey(t)}`);
3943
4279
  }
3944
- const prefix = `sc_ldr_${this.liveDynRefAdapters.size}`;
3945
- const adapter = streamTypedRefMaterializeAdapter(this.expressionContext(), t, { prefix, adapters: new Map() }, `${prefix}_materialize`);
3946
- this.liveDynRefAdapters.set(key, adapter);
3947
- return adapter;
4280
+ return streamTypedRefMaterializeAdapter(this, t);
3948
4281
  }
3949
4282
  liveDynUnionRefAdapter(t) {
3950
- return liveDynUnionRefAdapter(this.expressionContext(), t);
3951
- }
3952
- streamTypedRefBoxValue(B, t, value, ctx) {
3953
- return streamTypedRefBoxValue(this.expressionContext(), B, t, value, ctx);
4283
+ return liveDynUnionRefAdapter(this, t);
3954
4284
  }
3955
- streamTypedRefMaterializeAdapter(t, ctx, preferredSnapshot) {
3956
- return streamTypedRefMaterializeAdapter(this.expressionContext(), t, ctx, preferredSnapshot);
4285
+ streamTypedRefBoxValue(B, t, value) {
4286
+ return streamTypedRefBoxValue(this, B, t, value);
3957
4287
  }
3958
4288
  streamFromArrayAdapter(t) {
3959
- return streamFromArrayAdapter(this.expressionContext(), t);
4289
+ return streamFromArrayAdapter(this, t);
3960
4290
  }
3961
4291
  emitWebLibCall(e) {
3962
- return emitWebLibCall(this.expressionContext(), e);
4292
+ return emitWebLibCall(this, e);
3963
4293
  }
3964
4294
  emitDynamicLibCall(e) {
3965
- return emitDynamicLibCall(this.expressionContext(), e);
4295
+ return emitDynamicLibCall(this, e);
3966
4296
  }
3967
4297
  emitFilesystemLibCall(e) {
3968
- return emitFilesystemLibCall(this.expressionContext(), e);
4298
+ return emitFilesystemLibCall(this, e);
3969
4299
  }
3970
4300
  emitPathUrlLibCall(e) {
3971
- return emitPathUrlLibCall(this.expressionContext(), e);
4301
+ return emitPathUrlLibCall(this, e);
3972
4302
  }
3973
4303
  emitPrimitiveLibCall(e) {
3974
- return emitPrimitiveLibCall(this.expressionContext(), e);
4304
+ return emitPrimitiveLibCall(this, e);
3975
4305
  }
3976
4306
  emitChildProcessLibCall(e) {
3977
- return emitChildProcessLibCall(this.expressionContext(), e);
4307
+ return emitChildProcessLibCall(this, e);
3978
4308
  }
3979
4309
  emitAsyncContextLibCall(e) {
3980
- return emitAsyncContextLibCall(this.expressionContext(), e);
4310
+ return emitAsyncContextLibCall(this, e);
3981
4311
  }
3982
4312
  emitProcessLibCall(e) {
3983
- return emitProcessLibCall(this.expressionContext(), e);
4313
+ return emitProcessLibCall(this, e);
3984
4314
  }
3985
4315
  emitErrorsEventsLibCall(e) {
3986
- return emitErrorsEventsLibCall(this.expressionContext(), e);
4316
+ return emitErrorsEventsLibCall(this, e);
3987
4317
  }
3988
4318
  emitStreamLibCall(e) {
3989
- return emitStreamLibCall(this.expressionContext(), e);
4319
+ return emitStreamLibCall(this, e);
3990
4320
  }
3991
4321
  emitNetworkHttpLibCall(e) {
3992
- return emitNetworkHttpLibCall(this.expressionContext(), e);
4322
+ return emitNetworkHttpLibCall(this, e);
3993
4323
  }
3994
4324
  emitAssertInspectLibCall(e) {
3995
- return emitAssertInspectLibCall(this.expressionContext(), e);
4325
+ return emitAssertInspectLibCall(this, e);
3996
4326
  }
3997
4327
  emitIoLibCall(e) {
3998
- return emitIoLibCall(this.expressionContext(), e);
4328
+ return emitIoLibCall(this, e);
3999
4329
  }
4000
4330
  emitGenericLibCall(e) {
4001
- return emitGenericLibCall(this.expressionContext(), e);
4331
+ return emitGenericLibCall(this, e);
4002
4332
  }
4003
4333
  emitLibCall(e) {
4004
- return emitLibCall(this.expressionContext(), e);
4334
+ return emitLibCall(this, e);
4005
4335
  }
4006
4336
  }
4007
4337
  //# sourceMappingURL=emitter.js.map