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