@scriptc/compiler 0.2.6 → 0.2.8

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 (588) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +7 -18
  2. package/dist/backend/cycle-analysis.d.ts +21 -9
  3. package/dist/backend/cycle-analysis.js +139 -67
  4. package/dist/backend/cycle-analysis.js.map +1 -1
  5. package/dist/backend/cycle-analysis.test.js +283 -3
  6. package/dist/backend/cycle-analysis.test.js.map +1 -1
  7. package/dist/backend/cycle-mutability.d.ts +39 -0
  8. package/dist/backend/cycle-mutability.js +205 -0
  9. package/dist/backend/cycle-mutability.js.map +1 -0
  10. package/dist/backend/link-plan-core.d.ts +2 -1
  11. package/dist/backend/link-plan-core.js +15 -3
  12. package/dist/backend/link-plan-core.js.map +1 -1
  13. package/dist/backend/link-plan.d.ts +2 -1
  14. package/dist/backend/link-plan.js.map +1 -1
  15. package/dist/backend/llvm/alloc.d.ts +43 -0
  16. package/dist/backend/llvm/alloc.js +246 -0
  17. package/dist/backend/llvm/alloc.js.map +1 -0
  18. package/dist/backend/llvm/alloc.test.d.ts +1 -0
  19. package/dist/backend/llvm/alloc.test.js +102 -0
  20. package/dist/backend/llvm/alloc.test.js.map +1 -0
  21. package/dist/backend/llvm/blocks.d.ts +9 -0
  22. package/dist/backend/llvm/blocks.js +9 -0
  23. package/dist/backend/llvm/blocks.js.map +1 -1
  24. package/dist/backend/llvm/borrowed-receivers.d.ts +7 -0
  25. package/dist/backend/llvm/borrowed-receivers.js +39 -0
  26. package/dist/backend/llvm/borrowed-receivers.js.map +1 -1
  27. package/dist/backend/llvm/call-lifetimes.d.ts +18 -3
  28. package/dist/backend/llvm/call-lifetimes.js +54 -19
  29. package/dist/backend/llvm/call-lifetimes.js.map +1 -1
  30. package/dist/backend/llvm/call-lifetimes.test.js +178 -3
  31. package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
  32. package/dist/backend/llvm/checked-narrows.d.ts +24 -0
  33. package/dist/backend/llvm/checked-narrows.js +108 -0
  34. package/dist/backend/llvm/checked-narrows.js.map +1 -0
  35. package/dist/backend/llvm/checked-narrows.test.d.ts +1 -0
  36. package/dist/backend/llvm/checked-narrows.test.js +208 -0
  37. package/dist/backend/llvm/checked-narrows.test.js.map +1 -0
  38. package/dist/backend/llvm/classes.d.ts +16 -1
  39. package/dist/backend/llvm/classes.js +60 -49
  40. package/dist/backend/llvm/classes.js.map +1 -1
  41. package/dist/backend/llvm/classes.test.js +68 -6
  42. package/dist/backend/llvm/classes.test.js.map +1 -1
  43. package/dist/backend/llvm/common.d.ts +13 -0
  44. package/dist/backend/llvm/common.js +30 -0
  45. package/dist/backend/llvm/common.js.map +1 -1
  46. package/dist/backend/llvm/constant-callbacks.d.ts +19 -3
  47. package/dist/backend/llvm/constant-callbacks.js +289 -52
  48. package/dist/backend/llvm/constant-callbacks.js.map +1 -1
  49. package/dist/backend/llvm/constant-callbacks.test.js +140 -3
  50. package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
  51. package/dist/backend/llvm/debug-info.d.ts +6 -2
  52. package/dist/backend/llvm/debug-info.js +11 -1
  53. package/dist/backend/llvm/debug-info.js.map +1 -1
  54. package/dist/backend/llvm/dense-array-access.d.ts +29 -0
  55. package/dist/backend/llvm/dense-array-access.js +335 -0
  56. package/dist/backend/llvm/dense-array-access.js.map +1 -0
  57. package/dist/backend/llvm/dense-array-access.test.d.ts +1 -0
  58. package/dist/backend/llvm/dense-array-access.test.js +238 -0
  59. package/dist/backend/llvm/dense-array-access.test.js.map +1 -0
  60. package/dist/backend/llvm/dyn.d.ts +38 -0
  61. package/dist/backend/llvm/dyn.js +213 -14
  62. package/dist/backend/llvm/dyn.js.map +1 -1
  63. package/dist/backend/llvm/emitter.d.ts +308 -15
  64. package/dist/backend/llvm/emitter.js +1788 -206
  65. package/dist/backend/llvm/emitter.js.map +1 -1
  66. package/dist/backend/llvm/emitter.test.js +89 -7
  67. package/dist/backend/llvm/emitter.test.js.map +1 -1
  68. package/dist/backend/llvm/expr-async.js +62 -8
  69. package/dist/backend/llvm/expr-async.js.map +1 -1
  70. package/dist/backend/llvm/expr-async.test.d.ts +1 -0
  71. package/dist/backend/llvm/expr-async.test.js +62 -0
  72. package/dist/backend/llvm/expr-async.test.js.map +1 -0
  73. package/dist/backend/llvm/expr-bytes.d.ts +1 -1
  74. package/dist/backend/llvm/expr-bytes.js +85 -8
  75. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  76. package/dist/backend/llvm/expr-callbacks.js +29 -21
  77. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  78. package/dist/backend/llvm/expr-calls.d.ts +5 -0
  79. package/dist/backend/llvm/expr-calls.js +118 -15
  80. package/dist/backend/llvm/expr-calls.js.map +1 -1
  81. package/dist/backend/llvm/expr-containers.d.ts +7 -1
  82. package/dist/backend/llvm/expr-containers.js +246 -32
  83. package/dist/backend/llvm/expr-containers.js.map +1 -1
  84. package/dist/backend/llvm/expr-control.js +113 -8
  85. package/dist/backend/llvm/expr-control.js.map +1 -1
  86. package/dist/backend/llvm/expr-dispatch.js +2 -0
  87. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  88. package/dist/backend/llvm/expr-dynamic.js +244 -44
  89. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  90. package/dist/backend/llvm/expr-island.js +3 -8
  91. package/dist/backend/llvm/expr-island.js.map +1 -1
  92. package/dist/backend/llvm/expr-primitives.d.ts +1 -1
  93. package/dist/backend/llvm/expr-primitives.js +93 -36
  94. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  95. package/dist/backend/llvm/expr-primitives.test.js +51 -3
  96. package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
  97. package/dist/backend/llvm/expr-records.js +31 -17
  98. package/dist/backend/llvm/expr-records.js.map +1 -1
  99. package/dist/backend/llvm/expr-stream-bridges.js +96 -29
  100. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  101. package/dist/backend/llvm/expr-stream-bridges.test.js +1 -1
  102. package/dist/backend/llvm/expr-stream-callbacks.js +6 -3
  103. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  104. package/dist/backend/llvm/integer-remainder.d.ts +11 -0
  105. package/dist/backend/llvm/integer-remainder.js +91 -0
  106. package/dist/backend/llvm/integer-remainder.js.map +1 -1
  107. package/dist/backend/llvm/layouts.d.ts +3 -1
  108. package/dist/backend/llvm/layouts.js +3 -2
  109. package/dist/backend/llvm/layouts.js.map +1 -1
  110. package/dist/backend/llvm/lazy-captures.d.ts +16 -0
  111. package/dist/backend/llvm/lazy-captures.js +96 -0
  112. package/dist/backend/llvm/lazy-captures.js.map +1 -0
  113. package/dist/backend/llvm/lazy-captures.test.d.ts +1 -0
  114. package/dist/backend/llvm/lazy-captures.test.js +78 -0
  115. package/dist/backend/llvm/lazy-captures.test.js.map +1 -0
  116. package/dist/backend/llvm/lib-abi.js +10 -0
  117. package/dist/backend/llvm/lib-abi.js.map +1 -1
  118. package/dist/backend/llvm/lib-filesystem.js +10 -15
  119. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  120. package/dist/backend/llvm/lib-process.js +8 -8
  121. package/dist/backend/llvm/lib-process.js.map +1 -1
  122. package/dist/backend/llvm/lib-shared.js +1 -0
  123. package/dist/backend/llvm/lib-shared.js.map +1 -1
  124. package/dist/backend/llvm/local-array-reads.d.ts +5 -1
  125. package/dist/backend/llvm/local-array-reads.js +147 -26
  126. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  127. package/dist/backend/llvm/local-array-reads.test.js +85 -4
  128. package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
  129. package/dist/backend/llvm/local-union-storage.d.ts +5 -1
  130. package/dist/backend/llvm/local-union-storage.js +54 -8
  131. package/dist/backend/llvm/local-union-storage.js.map +1 -1
  132. package/dist/backend/llvm/local-union-storage.test.js +94 -6
  133. package/dist/backend/llvm/local-union-storage.test.js.map +1 -1
  134. package/dist/backend/llvm/map-number-lookup.d.ts +18 -0
  135. package/dist/backend/llvm/map-number-lookup.js +62 -0
  136. package/dist/backend/llvm/map-number-lookup.js.map +1 -0
  137. package/dist/backend/llvm/map-read-lifetimes.d.ts +6 -0
  138. package/dist/backend/llvm/map-read-lifetimes.js +24 -3
  139. package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
  140. package/dist/backend/llvm/map-read-lifetimes.test.js +39 -20
  141. package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -1
  142. package/dist/backend/llvm/nullable-fields.d.ts +28 -0
  143. package/dist/backend/llvm/nullable-fields.js +45 -0
  144. package/dist/backend/llvm/nullable-fields.js.map +1 -0
  145. package/dist/backend/llvm/nullable-fields.test.d.ts +1 -0
  146. package/dist/backend/llvm/nullable-fields.test.js +48 -0
  147. package/dist/backend/llvm/nullable-fields.test.js.map +1 -0
  148. package/dist/backend/llvm/nullable-unions.d.ts +68 -0
  149. package/dist/backend/llvm/nullable-unions.js +132 -0
  150. package/dist/backend/llvm/nullable-unions.js.map +1 -0
  151. package/dist/backend/llvm/publish.d.ts +58 -0
  152. package/dist/backend/llvm/publish.js +286 -0
  153. package/dist/backend/llvm/publish.js.map +1 -0
  154. package/dist/backend/llvm/rebound-parameters.d.ts +12 -0
  155. package/dist/backend/llvm/rebound-parameters.js +72 -0
  156. package/dist/backend/llvm/rebound-parameters.js.map +1 -0
  157. package/dist/backend/llvm/rebound-parameters.test.d.ts +1 -0
  158. package/dist/backend/llvm/rebound-parameters.test.js +67 -0
  159. package/dist/backend/llvm/rebound-parameters.test.js.map +1 -0
  160. package/dist/backend/llvm/reference-effects.d.ts +18 -2
  161. package/dist/backend/llvm/reference-effects.js +106 -16
  162. package/dist/backend/llvm/reference-effects.js.map +1 -1
  163. package/dist/backend/llvm/reference-effects.test.js +52 -1
  164. package/dist/backend/llvm/reference-effects.test.js.map +1 -1
  165. package/dist/backend/llvm/serialized-ir-emission.test.d.ts +1 -0
  166. package/dist/backend/llvm/serialized-ir-emission.test.js +52 -0
  167. package/dist/backend/llvm/serialized-ir-emission.test.js.map +1 -0
  168. package/dist/backend/llvm/shapes.d.ts +104 -9
  169. package/dist/backend/llvm/shapes.js +356 -46
  170. package/dist/backend/llvm/shapes.js.map +1 -1
  171. package/dist/backend/llvm/shapes.test.js +139 -5
  172. package/dist/backend/llvm/shapes.test.js.map +1 -1
  173. package/dist/backend/llvm/stack-callbacks.js +2 -3
  174. package/dist/backend/llvm/stack-callbacks.js.map +1 -1
  175. package/dist/backend/llvm/stack-captures.d.ts +3 -1
  176. package/dist/backend/llvm/stack-captures.js +5 -3
  177. package/dist/backend/llvm/stack-captures.js.map +1 -1
  178. package/dist/backend/llvm/stack-unions.test.js +43 -3
  179. package/dist/backend/llvm/stack-unions.test.js.map +1 -1
  180. package/dist/backend/llvm/string-construction.d.ts +10 -0
  181. package/dist/backend/llvm/string-construction.js +42 -0
  182. package/dist/backend/llvm/string-construction.js.map +1 -1
  183. package/dist/backend/llvm/string-construction.test.js +1 -1
  184. package/dist/backend/llvm/string-key-hash.d.ts +15 -0
  185. package/dist/backend/llvm/string-key-hash.js +76 -0
  186. package/dist/backend/llvm/string-key-hash.js.map +1 -0
  187. package/dist/backend/llvm/string-key-hash.test.d.ts +1 -0
  188. package/dist/backend/llvm/string-key-hash.test.js +45 -0
  189. package/dist/backend/llvm/string-key-hash.test.js.map +1 -0
  190. package/dist/backend/llvm/string-lifetimes.test.js +65 -15
  191. package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
  192. package/dist/backend/llvm/string-reads.d.ts +7 -0
  193. package/dist/backend/llvm/string-reads.js +76 -0
  194. package/dist/backend/llvm/string-reads.js.map +1 -0
  195. package/dist/backend/llvm/switch-dispatch.js +1 -1
  196. package/dist/backend/llvm/switch-dispatch.js.map +1 -1
  197. package/dist/backend/llvm/switch-dispatch.test.js +3 -3
  198. package/dist/backend/llvm/switch-dispatch.test.js.map +1 -1
  199. package/dist/backend/llvm/test-boxed-unions.d.ts +5 -0
  200. package/dist/backend/llvm/test-boxed-unions.js +13 -0
  201. package/dist/backend/llvm/test-boxed-unions.js.map +1 -0
  202. package/dist/backend/llvm/union-repr.d.ts +15 -0
  203. package/dist/backend/llvm/union-repr.js +89 -0
  204. package/dist/backend/llvm/union-repr.js.map +1 -0
  205. package/dist/backend/llvm/virtual-borrows.d.ts +31 -0
  206. package/dist/backend/llvm/virtual-borrows.js +82 -0
  207. package/dist/backend/llvm/virtual-borrows.js.map +1 -0
  208. package/dist/backend/llvm/walk-borrows.d.ts +43 -0
  209. package/dist/backend/llvm/walk-borrows.js +150 -0
  210. package/dist/backend/llvm/walk-borrows.js.map +1 -0
  211. package/dist/backend/llvm/walk-borrows.test.d.ts +1 -0
  212. package/dist/backend/llvm/walk-borrows.test.js +119 -0
  213. package/dist/backend/llvm/walk-borrows.test.js.map +1 -0
  214. package/dist/backend/llvm/walkers.d.ts +5 -1
  215. package/dist/backend/llvm/walkers.js +24 -21
  216. package/dist/backend/llvm/walkers.js.map +1 -1
  217. package/dist/backend/may-throw.d.ts +29 -1
  218. package/dist/backend/may-throw.js +349 -3
  219. package/dist/backend/may-throw.js.map +1 -1
  220. package/dist/backend/may-throw.test.js +114 -2
  221. package/dist/backend/may-throw.test.js.map +1 -1
  222. package/dist/backend/native/cache-warm.d.ts +2 -1
  223. package/dist/backend/native/cache-warm.js.map +1 -1
  224. package/dist/backend/native/contracts.d.ts +3 -2
  225. package/dist/backend/native/contracts.js.map +1 -1
  226. package/dist/backend/native/runtime-inputs.d.ts +1 -1
  227. package/dist/backend/native/runtime-inputs.js +2 -0
  228. package/dist/backend/native/runtime-inputs.js.map +1 -1
  229. package/dist/backend/native-codegen-core.d.ts +7 -4
  230. package/dist/backend/native-codegen-core.js +14 -9
  231. package/dist/backend/native-codegen-core.js.map +1 -1
  232. package/dist/backend/native-codegen.d.ts +9 -0
  233. package/dist/backend/native-codegen.js +53 -2
  234. package/dist/backend/native-codegen.js.map +1 -1
  235. package/dist/backend/native-codegen.test.js +64 -10
  236. package/dist/backend/native-codegen.test.js.map +1 -1
  237. package/dist/backend/native-link-info-core.d.ts +3 -2
  238. package/dist/backend/native-link-info-core.js.map +1 -1
  239. package/dist/backend/native-link-info.d.ts +2 -1
  240. package/dist/backend/native-link-info.js.map +1 -1
  241. package/dist/backend/native-link-info.test.js +2 -2
  242. package/dist/backend/native-link-info.test.js.map +1 -1
  243. package/dist/backend/native-tools.d.ts +5 -1
  244. package/dist/backend/native-tools.js +3 -1
  245. package/dist/backend/native-tools.js.map +1 -1
  246. package/dist/backend/optimization.d.ts +25 -0
  247. package/dist/backend/optimization.js +21 -0
  248. package/dist/backend/optimization.js.map +1 -0
  249. package/dist/backend/optimization.test.d.ts +1 -0
  250. package/dist/backend/optimization.test.js +24 -0
  251. package/dist/backend/optimization.test.js.map +1 -0
  252. package/dist/backend/publication.d.ts +28 -0
  253. package/dist/backend/publication.js +155 -0
  254. package/dist/backend/publication.js.map +1 -0
  255. package/dist/backend/publication.test.d.ts +1 -0
  256. package/dist/backend/publication.test.js +72 -0
  257. package/dist/backend/publication.test.js.map +1 -0
  258. package/dist/backend/runtime-abi.d.ts +2 -2
  259. package/dist/backend/runtime-abi.js +2 -2
  260. package/dist/backend/runtime-pack-core.d.ts +15 -4
  261. package/dist/backend/runtime-pack-core.js +23 -12
  262. package/dist/backend/runtime-pack-core.js.map +1 -1
  263. package/dist/backend/runtime-pack-native.d.ts +7 -3
  264. package/dist/backend/runtime-pack-native.js +0 -3
  265. package/dist/backend/runtime-pack-native.js.map +1 -1
  266. package/dist/backend/runtime-pack-targets.test.js +1 -1
  267. package/dist/backend/runtime-pack.d.ts +20 -2
  268. package/dist/backend/runtime-pack.js +23 -0
  269. package/dist/backend/runtime-pack.js.map +1 -1
  270. package/dist/backend/runtime-pack.test.js +115 -2
  271. package/dist/backend/runtime-pack.test.js.map +1 -1
  272. package/dist/backend/target-diagnostics.test.js +1 -1
  273. package/dist/backend/targets.d.ts +2 -1
  274. package/dist/backend/targets.js +1 -1
  275. package/dist/backend/targets.js.map +1 -1
  276. package/dist/cli/command.js +75 -11
  277. package/dist/cli/command.js.map +1 -1
  278. package/dist/cli/host.d.ts +2 -1
  279. package/dist/cli/usage.d.ts +4 -1
  280. package/dist/cli/usage.js +13 -3
  281. package/dist/cli/usage.js.map +1 -1
  282. package/dist/compile-types.d.ts +17 -5
  283. package/dist/coverage/report.d.ts +25 -2
  284. package/dist/coverage/report.js +161 -33
  285. package/dist/coverage/report.js.map +1 -1
  286. package/dist/coverage/verdict-cache.d.ts +63 -0
  287. package/dist/coverage/verdict-cache.js +193 -0
  288. package/dist/coverage/verdict-cache.js.map +1 -0
  289. package/dist/coverage/verdict-cache.test.d.ts +1 -0
  290. package/dist/coverage/verdict-cache.test.js +52 -0
  291. package/dist/coverage/verdict-cache.test.js.map +1 -0
  292. package/dist/coverage/verdict-semantic.d.ts +2 -0
  293. package/dist/coverage/verdict-semantic.js +24 -0
  294. package/dist/coverage/verdict-semantic.js.map +1 -0
  295. package/dist/coverage/verdict-startup.d.ts +15 -0
  296. package/dist/coverage/verdict-startup.js +66 -0
  297. package/dist/coverage/verdict-startup.js.map +1 -0
  298. package/dist/diagnostics/diagnostic.d.ts +29 -1
  299. package/dist/diagnostics/diagnostic.js +84 -12
  300. package/dist/diagnostics/diagnostic.js.map +1 -1
  301. package/dist/diagnostics/envelope.d.ts +130 -0
  302. package/dist/diagnostics/envelope.js +257 -0
  303. package/dist/diagnostics/envelope.js.map +1 -0
  304. package/dist/diagnostics/envelope.test.d.ts +1 -0
  305. package/dist/diagnostics/envelope.test.js +91 -0
  306. package/dist/diagnostics/envelope.test.js.map +1 -0
  307. package/dist/diagnostics/render.d.ts +3 -0
  308. package/dist/diagnostics/render.js +13 -2
  309. package/dist/diagnostics/render.js.map +1 -1
  310. package/dist/executable/executable-cache.d.ts +2 -2
  311. package/dist/executable/executable-cache.js +7 -4
  312. package/dist/executable/executable-cache.js.map +1 -1
  313. package/dist/executable/executable-cache.test.js +20 -0
  314. package/dist/executable/executable-cache.test.js.map +1 -1
  315. package/dist/executable/prepare.d.ts +4 -0
  316. package/dist/executable/prepare.js +7 -1
  317. package/dist/executable/prepare.js.map +1 -1
  318. package/dist/frontend/analysis.js +1 -0
  319. package/dist/frontend/analysis.js.map +1 -1
  320. package/dist/frontend/lowering/abstract-equality.js +5 -49
  321. package/dist/frontend/lowering/abstract-equality.js.map +1 -1
  322. package/dist/frontend/lowering/array-values.d.ts +30 -0
  323. package/dist/frontend/lowering/array-values.js +246 -1
  324. package/dist/frontend/lowering/array-values.js.map +1 -1
  325. package/dist/frontend/lowering/builtins/errors.js +17 -2
  326. package/dist/frontend/lowering/builtins/errors.js.map +1 -1
  327. package/dist/frontend/lowering/builtins/numbers.js +29 -1
  328. package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
  329. package/dist/frontend/lowering/builtins/process.d.ts +10 -17
  330. package/dist/frontend/lowering/builtins/process.js +66 -29
  331. package/dist/frontend/lowering/builtins/process.js.map +1 -1
  332. package/dist/frontend/lowering/builtins/workers.js +4 -2
  333. package/dist/frontend/lowering/builtins/workers.js.map +1 -1
  334. package/dist/frontend/lowering/caught-value-dispatch.d.ts +11 -0
  335. package/dist/frontend/lowering/caught-value-dispatch.js +87 -0
  336. package/dist/frontend/lowering/caught-value-dispatch.js.map +1 -0
  337. package/dist/frontend/lowering/class-assertions.d.ts +12 -0
  338. package/dist/frontend/lowering/class-assertions.js +229 -5
  339. package/dist/frontend/lowering/class-assertions.js.map +1 -1
  340. package/dist/frontend/lowering/class-callbacks.d.ts +3 -3
  341. package/dist/frontend/lowering/class-callbacks.js +18 -5
  342. package/dist/frontend/lowering/class-callbacks.js.map +1 -1
  343. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +1 -0
  344. package/dist/frontend/lowering/class-dynamic-dispatch.js +12 -6
  345. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  346. package/dist/frontend/lowering/class-method-mutations.d.ts +5 -0
  347. package/dist/frontend/lowering/class-method-mutations.js +472 -0
  348. package/dist/frontend/lowering/class-method-mutations.js.map +1 -0
  349. package/dist/frontend/lowering/class-method-values.js +25 -5
  350. package/dist/frontend/lowering/class-method-values.js.map +1 -1
  351. package/dist/frontend/lowering/class-prototypes.js +8 -2
  352. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  353. package/dist/frontend/lowering/class-unions.d.ts +16 -0
  354. package/dist/frontend/lowering/class-unions.js +127 -0
  355. package/dist/frontend/lowering/class-unions.js.map +1 -0
  356. package/dist/frontend/lowering/coercions/builders.js +8 -1
  357. package/dist/frontend/lowering/coercions/builders.js.map +1 -1
  358. package/dist/frontend/lowering/coercions/function-adapters.js +2 -0
  359. package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
  360. package/dist/frontend/lowering/coercions/identity.d.ts +7 -0
  361. package/dist/frontend/lowering/coercions/identity.js +26 -0
  362. package/dist/frontend/lowering/coercions/identity.js.map +1 -0
  363. package/dist/frontend/lowering/coercions/state.d.ts +6 -0
  364. package/dist/frontend/lowering/coercions/state.js +2 -0
  365. package/dist/frontend/lowering/coercions/state.js.map +1 -1
  366. package/dist/frontend/lowering/coercions/structural.js +9 -6
  367. package/dist/frontend/lowering/coercions/structural.js.map +1 -1
  368. package/dist/frontend/lowering/coercions/unions.d.ts +8 -0
  369. package/dist/frontend/lowering/coercions/unions.js +67 -2
  370. package/dist/frontend/lowering/coercions/unions.js.map +1 -1
  371. package/dist/frontend/lowering/collation-repertoire.d.ts +1 -0
  372. package/dist/frontend/lowering/collation-repertoire.js +19 -0
  373. package/dist/frontend/lowering/collation-repertoire.js.map +1 -0
  374. package/dist/frontend/lowering/collection-narrowing.d.ts +6 -0
  375. package/dist/frontend/lowering/collection-narrowing.js +31 -0
  376. package/dist/frontend/lowering/collection-narrowing.js.map +1 -0
  377. package/dist/frontend/lowering/construction-escapes.d.ts +38 -0
  378. package/dist/frontend/lowering/construction-escapes.js +146 -0
  379. package/dist/frontend/lowering/construction-escapes.js.map +1 -0
  380. package/dist/frontend/lowering/construction-escapes.test.d.ts +1 -0
  381. package/dist/frontend/lowering/construction-escapes.test.js +150 -0
  382. package/dist/frontend/lowering/construction-escapes.test.js.map +1 -0
  383. package/dist/frontend/lowering/containers/array-callback-call.d.ts +7 -0
  384. package/dist/frontend/lowering/containers/array-callback-call.js +52 -0
  385. package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -0
  386. package/dist/frontend/lowering/containers/array-callbacks.d.ts +1 -1
  387. package/dist/frontend/lowering/containers/array-callbacks.js +416 -65
  388. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  389. package/dist/frontend/lowering/containers/array-concat.d.ts +7 -0
  390. package/dist/frontend/lowering/containers/array-concat.js +130 -0
  391. package/dist/frontend/lowering/containers/array-concat.js.map +1 -0
  392. package/dist/frontend/lowering/containers/array-construction.d.ts +2 -0
  393. package/dist/frontend/lowering/containers/array-construction.js +110 -5
  394. package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
  395. package/dist/frontend/lowering/containers/array-methods.d.ts +1 -11
  396. package/dist/frontend/lowering/containers/array-methods.js +274 -144
  397. package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
  398. package/dist/frontend/lowering/containers/callback-arguments.js +43 -1
  399. package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
  400. package/dist/frontend/lowering/containers/collection-methods.js +10 -1
  401. package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
  402. package/dist/frontend/lowering/containers/indexed-objects.js +56 -70
  403. package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
  404. package/dist/frontend/lowering/containers/string-and-regexp.js +7 -63
  405. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  406. package/dist/frontend/lowering/cycle-initialization.d.ts +46 -0
  407. package/dist/frontend/lowering/cycle-initialization.js +303 -0
  408. package/dist/frontend/lowering/cycle-initialization.js.map +1 -0
  409. package/dist/frontend/lowering/divergences.d.ts +9 -0
  410. package/dist/frontend/lowering/divergences.js +630 -0
  411. package/dist/frontend/lowering/divergences.js.map +1 -0
  412. package/dist/frontend/lowering/expressions/evaluation-safety.js +4 -0
  413. package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
  414. package/dist/frontend/lowering/expressions/object-literals.js +178 -34
  415. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  416. package/dist/frontend/lowering/expressions/union-field-write.d.ts +4 -4
  417. package/dist/frontend/lowering/expressions/union-field-write.js +54 -44
  418. package/dist/frontend/lowering/expressions/union-field-write.js.map +1 -1
  419. package/dist/frontend/lowering/iterator-adapters.d.ts +20 -0
  420. package/dist/frontend/lowering/iterator-adapters.js +605 -0
  421. package/dist/frontend/lowering/iterator-adapters.js.map +1 -0
  422. package/dist/frontend/lowering/lower-array-sort.d.ts +1 -1
  423. package/dist/frontend/lowering/lower-array-sort.js +44 -5
  424. package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
  425. package/dist/frontend/lowering/lower-array-sort.test.d.ts +1 -0
  426. package/dist/frontend/lowering/lower-array-sort.test.js +31 -0
  427. package/dist/frontend/lowering/lower-array-sort.test.js.map +1 -0
  428. package/dist/frontend/lowering/lower-assert.js +7 -0
  429. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  430. package/dist/frontend/lowering/lower-builtin-values.js +1 -0
  431. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  432. package/dist/frontend/lowering/lower-calls.d.ts +8 -3
  433. package/dist/frontend/lowering/lower-calls.js +388 -278
  434. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  435. package/dist/frontend/lowering/lower-classes.d.ts +6 -0
  436. package/dist/frontend/lowering/lower-classes.js +117 -65
  437. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  438. package/dist/frontend/lowering/lower-exprs.d.ts +22 -2
  439. package/dist/frontend/lowering/lower-exprs.js +811 -254
  440. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  441. package/dist/frontend/lowering/lower-functions.js +32 -19
  442. package/dist/frontend/lowering/lower-functions.js.map +1 -1
  443. package/dist/frontend/lowering/lower-generators.d.ts +19 -13
  444. package/dist/frontend/lowering/lower-generators.js +67 -44
  445. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  446. package/dist/frontend/lowering/lower-inspect.js +29 -4
  447. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  448. package/dist/frontend/lowering/lower-island.d.ts +1 -1
  449. package/dist/frontend/lowering/lower-island.js +24 -7
  450. package/dist/frontend/lowering/lower-island.js.map +1 -1
  451. package/dist/frontend/lowering/lower-modules.js +100 -3
  452. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  453. package/dist/frontend/lowering/lower-stmts.js +82 -64
  454. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  455. package/dist/frontend/lowering/lowerer.d.ts +115 -2
  456. package/dist/frontend/lowering/lowerer.js +1266 -88
  457. package/dist/frontend/lowering/lowerer.js.map +1 -1
  458. package/dist/frontend/lowering/native-ffi.js +3 -1
  459. package/dist/frontend/lowering/native-ffi.js.map +1 -1
  460. package/dist/frontend/lowering/runtime-optional-bounds.d.ts +19 -0
  461. package/dist/frontend/lowering/runtime-optional-bounds.js +354 -0
  462. package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -0
  463. package/dist/frontend/lowering/runtime-optional-bounds.test.d.ts +1 -0
  464. package/dist/frontend/lowering/runtime-optional-bounds.test.js +66 -0
  465. package/dist/frontend/lowering/runtime-optional-bounds.test.js.map +1 -0
  466. package/dist/frontend/lowering/runtime-optional-elements.d.ts +117 -0
  467. package/dist/frontend/lowering/runtime-optional-elements.js +738 -0
  468. package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -0
  469. package/dist/frontend/lowering/runtime-optional-guards.d.ts +36 -0
  470. package/dist/frontend/lowering/runtime-optional-guards.js +375 -0
  471. package/dist/frontend/lowering/runtime-optional-guards.js.map +1 -0
  472. package/dist/frontend/lowering/runtime-optional-guards.test.d.ts +1 -0
  473. package/dist/frontend/lowering/runtime-optional-guards.test.js +92 -0
  474. package/dist/frontend/lowering/runtime-optional-guards.test.js.map +1 -0
  475. package/dist/frontend/lowering/runtime-optional-ownership.d.ts +63 -0
  476. package/dist/frontend/lowering/runtime-optional-ownership.js +382 -0
  477. package/dist/frontend/lowering/runtime-optional-ownership.js.map +1 -0
  478. package/dist/frontend/lowering/runtime-optional-provenance.d.ts +16 -0
  479. package/dist/frontend/lowering/runtime-optional-provenance.js +41 -0
  480. package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -0
  481. package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
  482. package/dist/frontend/lowering/strict-equality.d.ts +9 -0
  483. package/dist/frontend/lowering/strict-equality.js +116 -0
  484. package/dist/frontend/lowering/strict-equality.js.map +1 -0
  485. package/dist/frontend/lowering/string-index-bounds.d.ts +36 -0
  486. package/dist/frontend/lowering/string-index-bounds.js +537 -0
  487. package/dist/frontend/lowering/string-index-bounds.js.map +1 -0
  488. package/dist/frontend/lowering/string-index-bounds.test.d.ts +1 -0
  489. package/dist/frontend/lowering/string-index-bounds.test.js +223 -0
  490. package/dist/frontend/lowering/string-index-bounds.test.js.map +1 -0
  491. package/dist/frontend/lowering/surfaces.js +3 -0
  492. package/dist/frontend/lowering/surfaces.js.map +1 -1
  493. package/dist/frontend/lowering/union-comparison.d.ts +5 -0
  494. package/dist/frontend/lowering/union-comparison.js +47 -0
  495. package/dist/frontend/lowering/union-comparison.js.map +1 -0
  496. package/dist/frontend/lowering/union-narrow.d.ts +2 -0
  497. package/dist/frontend/lowering/union-narrow.js +10 -6
  498. package/dist/frontend/lowering/union-narrow.js.map +1 -1
  499. package/dist/frontend/program-analysis.d.ts +10 -0
  500. package/dist/frontend/program-analysis.js +7 -0
  501. package/dist/frontend/program-analysis.js.map +1 -1
  502. package/dist/frontend/program.d.ts +63 -2
  503. package/dist/frontend/program.js +1038 -61
  504. package/dist/frontend/program.js.map +1 -1
  505. package/dist/frontend/program.test.js +122 -6
  506. package/dist/frontend/program.test.js.map +1 -1
  507. package/dist/frontend/resolve.d.ts +6 -0
  508. package/dist/frontend/resolve.js +14 -0
  509. package/dist/frontend/resolve.js.map +1 -1
  510. package/dist/frontend/threads-import.d.ts +5 -0
  511. package/dist/frontend/threads-import.js +21 -0
  512. package/dist/frontend/threads-import.js.map +1 -0
  513. package/dist/frontend/type-mapper.d.ts +4 -1
  514. package/dist/frontend/type-mapper.js +161 -20
  515. package/dist/frontend/type-mapper.js.map +1 -1
  516. package/dist/frontend/type-mapper.test.js +15 -3
  517. package/dist/frontend/type-mapper.test.js.map +1 -1
  518. package/dist/frontend/worker-target.d.ts +4 -0
  519. package/dist/frontend/worker-target.js +8 -1
  520. package/dist/frontend/worker-target.js.map +1 -1
  521. package/dist/index.d.ts +6 -1
  522. package/dist/index.js +70 -16
  523. package/dist/index.js.map +1 -1
  524. package/dist/ir/analysis.d.ts +3 -1
  525. package/dist/ir/analysis.js +4 -0
  526. package/dist/ir/analysis.js.map +1 -1
  527. package/dist/ir/build.d.ts +5 -0
  528. package/dist/ir/build.js +7 -0
  529. package/dist/ir/build.js.map +1 -1
  530. package/dist/ir/builtin-signatures.d.ts +1 -1
  531. package/dist/ir/builtin-signatures.js +5 -3
  532. package/dist/ir/builtin-signatures.js.map +1 -1
  533. package/dist/ir/constant-tables.test.js +1 -1
  534. package/dist/ir/initializer-bindings.test.js +1 -1
  535. package/dist/ir/int32-slots.d.ts +72 -0
  536. package/dist/ir/int32-slots.js +837 -0
  537. package/dist/ir/int32-slots.js.map +1 -0
  538. package/dist/ir/int32-slots.test.d.ts +1 -0
  539. package/dist/ir/int32-slots.test.js +222 -0
  540. package/dist/ir/int32-slots.test.js.map +1 -0
  541. package/dist/ir/integer-ranges.d.ts +19 -3
  542. package/dist/ir/integer-ranges.js +168 -23
  543. package/dist/ir/integer-ranges.js.map +1 -1
  544. package/dist/ir/integer-ranges.test.js +74 -2
  545. package/dist/ir/integer-ranges.test.js.map +1 -1
  546. package/dist/ir/ir.d.ts +101 -20
  547. package/dist/ir/ir.js +20 -6
  548. package/dist/ir/ir.js.map +1 -1
  549. package/dist/ir/scalar-records.test.js +1 -1
  550. package/dist/ir/serialize.d.ts +1 -1
  551. package/dist/ir/serialize.js +3 -3
  552. package/dist/ir/serialize.js.map +1 -1
  553. package/dist/ir/traverse.js +8 -0
  554. package/dist/ir/traverse.js.map +1 -1
  555. package/dist/ir/validate.js +139 -22
  556. package/dist/ir/validate.js.map +1 -1
  557. package/dist/ir/validate.test.js +308 -8
  558. package/dist/ir/validate.test.js.map +1 -1
  559. package/dist/library/fence-eval.test.js +1 -1
  560. package/dist/library/int-infer.test.js +4 -4
  561. package/dist/library/library-cache.test.js +5 -5
  562. package/dist/library/library-profile.d.ts +2 -1
  563. package/dist/library/library-profile.js +4 -3
  564. package/dist/library/library-profile.js.map +1 -1
  565. package/dist/native/cache.d.ts +3 -0
  566. package/dist/native/cache.js +49 -1
  567. package/dist/native/cache.js.map +1 -1
  568. package/dist/native/cache.test.js +21 -1
  569. package/dist/native/cache.test.js.map +1 -1
  570. package/dist/native/cli.js +1 -1
  571. package/dist/native/cli.js.map +1 -1
  572. package/dist/native/compiler.d.ts +5 -0
  573. package/dist/native/compiler.js +51 -4
  574. package/dist/native/compiler.js.map +1 -1
  575. package/dist/native/compiler.test.js +2 -2
  576. package/dist/native/library.d.ts +2 -1
  577. package/dist/native/library.js.map +1 -1
  578. package/dist/native/prepare.d.ts +4 -0
  579. package/dist/native/prepare.js +28 -3
  580. package/dist/native/prepare.js.map +1 -1
  581. package/dist/native/sanitizer.d.ts +3 -2
  582. package/dist/native/sanitizer.js +3 -13
  583. package/dist/native/sanitizer.js.map +1 -1
  584. package/dist/startup-cache.d.ts +2 -0
  585. package/dist/startup-cache.js +2 -0
  586. package/dist/startup-cache.js.map +1 -1
  587. package/package.json +20 -20
  588. package/surface-manifest.json +8 -2
@@ -0,0 +1,238 @@
1
+ import { expect, test } from "vitest";
2
+ import { BOOL, F64, STRING, VOID, arrayOf, } from "../../ir/ir.js";
3
+ import { emitLlvmModule } from "./emitter.js";
4
+ const loc = { file: "dense-array-access.ts", start: 0, end: 0 };
5
+ const nums = arrayOf(F64);
6
+ const flags = arrayOf(BOOL);
7
+ const words = arrayOf(STRING);
8
+ const ref = (localId, type) => ({
9
+ kind: "varRef",
10
+ localId,
11
+ type,
12
+ loc,
13
+ });
14
+ const index = ref("i", F64);
15
+ function module(name, returnType, body) {
16
+ return {
17
+ irVersion: 15,
18
+ sourceFile: loc.file,
19
+ entry: "__main",
20
+ functions: [
21
+ { name: "__main", params: [], returnType: VOID, locals: [], body: [], loc },
22
+ {
23
+ name,
24
+ params: [
25
+ { name: "a", localId: "a", type: nums },
26
+ { name: "b", localId: "b", type: flags },
27
+ { name: "s", localId: "s", type: words },
28
+ { name: "i", localId: "i", type: F64 },
29
+ ],
30
+ returnType,
31
+ locals: [
32
+ { id: "a", name: "a", type: nums, mutable: false },
33
+ { id: "b", name: "b", type: flags, mutable: false },
34
+ { id: "s", name: "s", type: words, mutable: false },
35
+ { id: "i", name: "i", type: F64, mutable: false },
36
+ ],
37
+ body,
38
+ loc,
39
+ },
40
+ ],
41
+ };
42
+ }
43
+ function body(llvm, name) {
44
+ return new RegExp(`^define internal [^\\n]*@sc_bf_${name}\\([^]*?^}`, "m").exec(llvm)[0];
45
+ }
46
+ test.each([32, 64])("strict scalar reads check dense storage inline (%i-bit)", (bits) => {
47
+ const read = { kind: "arrayGet", arr: ref("a", nums), index, type: F64, loc };
48
+ const llvm = emitLlvmModule(module("get", F64, [{ kind: "return", value: read, loc }]), {
49
+ pointerBits: bits,
50
+ });
51
+ const fn = body(llvm, "get");
52
+ // A double index must round-trip exactly; NaN/out-of-range conversions are frozen.
53
+ expect(fn).toContain("fptosi double");
54
+ expect(fn).toContain("freeze i64");
55
+ expect(fn).toMatch(/icmp ult i64 .*/);
56
+ expect(fn).toMatch(/load i8, ptr /);
57
+ expect(fn).toMatch(/icmp eq i8 .*, 1$/m);
58
+ expect(fn).toMatch(/load double, ptr /);
59
+ expect(fn).toMatch(/call double @scr_arr_get_f64\(.*\) cold memory\(read, inaccessiblemem: readwrite\)/);
60
+ if (bits === 32)
61
+ expect(fn).toContain("trunc i64");
62
+ });
63
+ test("reference reads retain inline and keep a cold +1 runtime fallback", () => {
64
+ const read = { kind: "arrayGet", arr: ref("s", words), index, type: STRING, loc };
65
+ const llvm = emitLlvmModule(module("word", STRING, [{ kind: "return", value: read, loc }]));
66
+ const fn = body(llvm, "word");
67
+ expect(fn).toMatch(/icmp ne ptr .*, null/);
68
+ expect(fn).toContain("@scr_str_retain_v(");
69
+ // The retaining getter writes reference counts, so it gets no read-only effect.
70
+ expect(fn).toMatch(/call ptr @scr_arr_get_ref\(.*\) cold$/m);
71
+ });
72
+ test("element writes store inline, extend the length, and release replaced references", () => {
73
+ const set = (arr, value) => ({
74
+ kind: "arraySet",
75
+ arr,
76
+ index,
77
+ value,
78
+ loc,
79
+ });
80
+ const llvm = emitLlvmModule(module("store", VOID, [
81
+ set(ref("a", nums), { kind: "numLit", value: 2.5, type: F64, loc }),
82
+ set(ref("b", flags), { kind: "boolLit", value: true, type: BOOL, loc }),
83
+ set(ref("s", words), { kind: "strLit", value: "x", type: STRING, loc }),
84
+ ]));
85
+ const fn = body(llvm, "store");
86
+ expect(fn).toMatch(/store double 0x4004000000000000, ptr /);
87
+ expect(fn).toMatch(/zext i1 .* to i64/);
88
+ expect(fn).toMatch(/store i8 1, ptr /);
89
+ expect(fn).toMatch(/icmp uge i64 .*/);
90
+ expect(fn).toContain("call void @scr_str_release(");
91
+ for (const acc of ["f64", "bool", "ref"]) {
92
+ expect(fn).toMatch(new RegExp(`call void @scr_arr_set_${acc}\\(.*\\) cold$`, "m"));
93
+ }
94
+ });
95
+ test.each([32, 64])("push appends inline below the capacity and keeps a cold runtime append (%i-bit)", (bits) => {
96
+ const push = (receiver, value) => ({
97
+ kind: "exprStmt",
98
+ expr: { kind: "arrIntrinsic", method: "push", receiver, args: [value], type: F64, loc },
99
+ loc,
100
+ });
101
+ const llvm = emitLlvmModule(module("append", VOID, [
102
+ push(ref("a", nums), { kind: "numLit", value: 2.5, type: F64, loc }),
103
+ push(ref("b", flags), { kind: "boolLit", value: true, type: BOOL, loc }),
104
+ push(ref("s", words), { kind: "strLit", value: "x", type: STRING, loc }),
105
+ ]), { pointerBits: bits });
106
+ const fn = body(llvm, "append");
107
+ const size = bits === 32 ? "i32" : "i64";
108
+ expect(fn.match(new RegExp(`icmp ult ${size} `, "g"))).toHaveLength(3);
109
+ expect(fn).toMatch(/store double 0x4004000000000000, ptr /);
110
+ expect(fn).toMatch(/zext i1 .* to i64/);
111
+ expect(fn.match(/store i8 1, ptr /g)).toHaveLength(3);
112
+ expect(fn.match(new RegExp(`add nuw ${size} .*, 1$`, "gm"))).toHaveLength(3);
113
+ // Appends never release: the slot past the length holds no value.
114
+ expect(fn).not.toContain("_release(");
115
+ for (const acc of ["f64", "bool", "ref"]) {
116
+ expect(fn).toMatch(new RegExp(`call double @scr_arr_push_${acc}\\(.*\\) cold$`, "m"));
117
+ }
118
+ });
119
+ test("state and presence queries answer dense slots inline", () => {
120
+ const state = { kind: "arrayState", arr: ref("b", flags), index, type: F64, loc };
121
+ const has = { kind: "arrayHas", arr: ref("s", words), index, type: BOOL, loc };
122
+ const llvm = emitLlvmModule(module("query", BOOL, [
123
+ {
124
+ kind: "return",
125
+ value: {
126
+ kind: "logical",
127
+ op: "&&",
128
+ left: {
129
+ kind: "bin",
130
+ op: "===",
131
+ left: state,
132
+ right: { kind: "numLit", value: 1, type: F64, loc },
133
+ type: BOOL,
134
+ loc,
135
+ },
136
+ right: has,
137
+ type: BOOL,
138
+ loc,
139
+ },
140
+ loc,
141
+ },
142
+ ]));
143
+ const fn = body(llvm, "query");
144
+ expect(fn).toMatch(/uitofp i8 .* to double/);
145
+ expect(fn).toMatch(/icmp ne i8 .*, 0/);
146
+ expect(fn).toMatch(/call double @scr_arr_state\(.*\) cold memory\(read/);
147
+ expect(fn).toMatch(/call i1 @scr_arr_has\(.*\) cold memory\(read/);
148
+ });
149
+ test("statement-position splices insert values without result or item arrays", () => {
150
+ const num = (value) => ({ kind: "numLit", value, type: F64, loc });
151
+ const splice = (items) => ({
152
+ kind: "exprStmt",
153
+ expr: {
154
+ kind: "arrIntrinsic",
155
+ method: items ? "spliceInsert" : "splice",
156
+ receiver: ref("s", words),
157
+ args: [
158
+ index,
159
+ num(0),
160
+ ...(items ? [{ kind: "arrayLit", elems: items, type: words, loc }] : []),
161
+ ],
162
+ type: words,
163
+ loc,
164
+ },
165
+ loc,
166
+ });
167
+ const llvm = emitLlvmModule(module("insert", VOID, [
168
+ splice([{ kind: "strLit", value: "x", type: STRING, loc }]),
169
+ splice(null),
170
+ ]));
171
+ const fn = body(llvm, "insert");
172
+ expect(fn.match(/call void @scr_arr_splice_drop\(/g)).toHaveLength(2);
173
+ expect(fn).toMatch(/call void @scr_arr_splice_drop\(.*, i64 1, ptr %t\d+\)/);
174
+ expect(fn).toMatch(/call void @scr_arr_splice_drop\(.*, i64 0, ptr null\)/);
175
+ expect(fn).not.toContain("@scr_arr_new");
176
+ expect(fn).not.toContain("@scr_arr_splice_insert");
177
+ expect(fn).not.toContain("@scr_arr_release");
178
+ });
179
+ test("length assignments skip the runtime when the length is unchanged", () => {
180
+ const llvm = emitLlvmModule(module("reset", VOID, [{ kind: "arraySetLength", arr: ref("s", words), length: index, loc }]));
181
+ const fn = body(llvm, "reset");
182
+ expect(fn).toMatch(/uitofp i64 .* to double/);
183
+ expect(fn).toMatch(/fcmp oeq double %p?\S*, %t\d+/);
184
+ expect(fn.match(/call void @scr_arr_set_len\(/g)).toHaveLength(1);
185
+ expect(fn).toMatch(/br i1 %t\d+, label %arr\.len\.done\d*, label %arr\.len\.set\d*/);
186
+ });
187
+ test("a discarded conditional splice drops the result of its literal arm", () => {
188
+ const insert = (items) => ({
189
+ kind: "arrIntrinsic",
190
+ method: "spliceInsert",
191
+ receiver: ref("s", words),
192
+ args: [index, { kind: "numLit", value: 0, type: F64, loc }, items],
193
+ type: words,
194
+ loc,
195
+ });
196
+ const word = { kind: "strLit", value: "x", type: STRING, loc };
197
+ const llvm = emitLlvmModule(module("pick", VOID, [
198
+ {
199
+ kind: "exprStmt",
200
+ expr: {
201
+ kind: "seqExpr",
202
+ stmts: [],
203
+ result: {
204
+ kind: "ternary",
205
+ cond: { kind: "boolLit", value: true, type: BOOL, loc },
206
+ then: insert({
207
+ kind: "seqExpr",
208
+ stmts: [],
209
+ result: { kind: "arrayLit", elems: [word], type: words, loc },
210
+ type: words,
211
+ loc,
212
+ }),
213
+ else_: insert({ kind: "arrayLit", elems: [word], type: words, loc }),
214
+ type: words,
215
+ loc,
216
+ },
217
+ type: words,
218
+ loc,
219
+ },
220
+ loc,
221
+ },
222
+ ]));
223
+ const fn = body(llvm, "pick");
224
+ expect(fn.match(/call void @scr_arr_splice_drop\(/g)).toHaveLength(1);
225
+ expect(fn.match(/call ptr @scr_arr_splice_insert\(/g)).toHaveLength(1);
226
+ expect(fn).toMatch(/drop\.t\d*:/);
227
+ });
228
+ test("an empty literal's capacity hint sizes its first dense storage", () => {
229
+ const llvm = emitLlvmModule(module("fresh", words, [
230
+ {
231
+ kind: "return",
232
+ value: { kind: "arrayLit", elems: [], capacity: 3, type: words, loc },
233
+ loc,
234
+ },
235
+ ]));
236
+ expect(body(llvm, "fresh")).toMatch(/call ptr @scr_arr_new\(.*, i64 3\)/);
237
+ });
238
+ //# sourceMappingURL=dense-array-access.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dense-array-access.test.js","sourceRoot":"","sources":["../../../src/backend/llvm/dense-array-access.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EACL,IAAI,EACJ,GAAG,EACH,MAAM,EACN,IAAI,EACJ,OAAO,GAIR,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,uBAAuB,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;AAChE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;AAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAC9B,MAAM,GAAG,GAAG,CAAC,OAAe,EAAE,IAAoB,EAAU,EAAE,CAAC,CAAC;IAC9D,IAAI,EAAE,QAAQ;IACd,OAAO;IACP,IAAI;IACJ,GAAG;CACJ,CAAC,CAAC;AACH,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAE5B,SAAS,MAAM,CAAC,IAAY,EAAE,UAA0B,EAAE,IAAc;IACtE,OAAO;QACL,SAAS,EAAE,EAAE;QACb,UAAU,EAAE,GAAG,CAAC,IAAI;QACpB,KAAK,EAAE,QAAQ;QACf,SAAS,EAAE;YACT,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE;YAC3E;gBACE,IAAI;gBACJ,MAAM,EAAE;oBACN,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE;oBACvC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE;oBACxC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE;oBACxC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE;iBACvC;gBACD,UAAU;gBACV,MAAM,EAAE;oBACN,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE;oBAClD,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE;oBACnD,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE;oBACnD,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE;iBAClD;gBACD,IAAI;gBACJ,GAAG;aACJ;SACF;KACF,CAAC;AACJ,CAAC;AAED,SAAS,IAAI,CAAC,IAAY,EAAE,IAAY;IACtC,OAAO,IAAI,MAAM,CAAC,kCAAkC,IAAI,YAAY,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAE,CAAC,CAAC,CAAC,CAAC;AAC5F,CAAC;AAED,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAU,CAAC,CAAC,yDAAyD,EAAE,CAAC,IAAI,EAAE,EAAE;IAC/F,MAAM,IAAI,GAAW,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACtF,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE;QACtF,WAAW,EAAE,IAAI;KAClB,CAAC,CAAC;IACH,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC7B,mFAAmF;IACnF,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IACtC,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IACnC,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACtC,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IACpC,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACzC,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACxC,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAChB,oFAAoF,CACrF,CAAC;IACF,IAAI,IAAI,KAAK,EAAE;QAAE,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;AACrD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,mEAAmE,EAAE,GAAG,EAAE;IAC7E,MAAM,IAAI,GAAW,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IAC1F,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5F,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC9B,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC3C,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;IAC3C,gFAAgF;IAChF,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,wCAAwC,CAAC,CAAC;AAC/D,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iFAAiF,EAAE,GAAG,EAAE;IAC3F,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,KAAa,EAAU,EAAE,CAAC,CAAC;QACnD,IAAI,EAAE,UAAU;QAChB,GAAG;QACH,KAAK;QACL,KAAK;QACL,GAAG;KACJ,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,cAAc,CACzB,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE;QACpB,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;QACnE,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;QACvE,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;KACxE,CAAC,CACH,CAAC;IACF,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC;IAC5D,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACxC,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACvC,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACtC,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC;IACpD,KAAK,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;QACzC,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,0BAA0B,GAAG,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAC;IACrF,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAU,CAAC,CAC1B,iFAAiF,EACjF,CAAC,IAAI,EAAE,EAAE;IACP,MAAM,IAAI,GAAG,CAAC,QAAgB,EAAE,KAAa,EAAU,EAAE,CAAC,CAAC;QACzD,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE;QACvF,GAAG;KACJ,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,cAAc,CACzB,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE;QACrB,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;QACpE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;QACxE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;KACzE,CAAC,EACF,EAAE,WAAW,EAAE,IAAI,EAAE,CACtB,CAAC;IACF,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;IACzC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,YAAY,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACvE,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC;IAC5D,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACxC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACtD,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,WAAW,IAAI,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC7E,kEAAkE;IAClE,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACtC,KAAK,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;QACzC,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,6BAA6B,GAAG,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAC;IACxF,CAAC;AACH,CAAC,CACF,CAAC;AAEF,IAAI,CAAC,sDAAsD,EAAE,GAAG,EAAE;IAChE,MAAM,KAAK,GAAW,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IAC1F,MAAM,GAAG,GAAW,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IACvF,MAAM,IAAI,GAAG,cAAc,CACzB,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE;QACpB;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE;gBACL,IAAI,EAAE,SAAS;gBACf,EAAE,EAAE,IAAI;gBACR,IAAI,EAAE;oBACJ,IAAI,EAAE,KAAK;oBACX,EAAE,EAAE,KAAK;oBACT,IAAI,EAAE,KAAK;oBACX,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE;oBACnD,IAAI,EAAE,IAAI;oBACV,GAAG;iBACJ;gBACD,KAAK,EAAE,GAAG;gBACV,IAAI,EAAE,IAAI;gBACV,GAAG;aACJ;YACD,GAAG;SACJ;KACF,CAAC,CACH,CAAC;IACF,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAC7C,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACvC,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,oDAAoD,CAAC,CAAC;IACzE,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,8CAA8C,CAAC,CAAC;AACrE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,wEAAwE,EAAE,GAAG,EAAE;IAClF,MAAM,GAAG,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IACnF,MAAM,MAAM,GAAG,CAAC,KAAsB,EAAU,EAAE,CAAC,CAAC;QAClD,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE;YACJ,IAAI,EAAE,cAAc;YACpB,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ;YACzC,QAAQ,EAAE,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC;YACzB,IAAI,EAAE;gBACJ,KAAK;gBACL,GAAG,CAAC,CAAC,CAAC;gBACN,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAmB,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;aAClF;YACD,IAAI,EAAE,KAAK;YACX,GAAG;SACJ;QACD,GAAG;KACJ,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,cAAc,CACzB,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE;QACrB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3D,MAAM,CAAC,IAAI,CAAC;KACb,CAAC,CACH,CAAC;IACF,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,wDAAwD,CAAC,CAAC;IAC7E,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,uDAAuD,CAAC,CAAC;IAC5E,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IACzC,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;IACnD,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;AAC/C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kEAAkE,EAAE,GAAG,EAAE;IAC5E,MAAM,IAAI,GAAG,cAAc,CACzB,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAC9F,CAAC;IACF,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAC9C,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC;IACpD,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAClE,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,gEAAgE,CAAC,CAAC;AACvF,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,oEAAoE,EAAE,GAAG,EAAE;IAC9E,MAAM,MAAM,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,CAAC;QACzC,IAAI,EAAE,cAAc;QACpB,MAAM,EAAE,cAAc;QACtB,QAAQ,EAAE,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC;QACzB,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,CAAC;QAClE,IAAI,EAAE,KAAK;QACX,GAAG;KACJ,CAAC,CAAC;IACH,MAAM,IAAI,GAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IACvE,MAAM,IAAI,GAAG,cAAc,CACzB,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE;QACnB;YACE,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE;gBACJ,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,EAAE;gBACT,MAAM,EAAE;oBACN,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;oBACvD,IAAI,EAAE,MAAM,CAAC;wBACX,IAAI,EAAE,SAAS;wBACf,KAAK,EAAE,EAAE;wBACT,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE;wBAC7D,IAAI,EAAE,KAAK;wBACX,GAAG;qBACJ,CAAC;oBACF,KAAK,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;oBACpE,IAAI,EAAE,KAAK;oBACX,GAAG;iBACJ;gBACD,IAAI,EAAE,KAAK;gBACX,GAAG;aACJ;YACD,GAAG;SACJ;KACF,CAAC,CACH,CAAC;IACF,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC9B,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACvE,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;AACpC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gEAAgE,EAAE,GAAG,EAAE;IAC1E,MAAM,IAAI,GAAG,cAAc,CACzB,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE;QACrB;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE;YACrE,GAAG;SACJ;KACF,CAAC,CACH,CAAC;IACF,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC;AAC5E,CAAC,CAAC,CAAC"}
@@ -22,6 +22,10 @@ export declare const DYN_KIND: {
22
22
  * unit instances (undefined-armed dynCheck targets build them). */
23
23
  export interface DynHost extends WalkerHost {
24
24
  unitInstanceRef(unionId: string, tag: number): string;
25
+ /** See ClassHost.virtualEntry. */
26
+ virtualEntry?(implFn: string): string;
27
+ /** The immortal ABSENT field-slot state of an undefined-armed union. */
28
+ absentInstanceRef(unionId: string): string;
25
29
  liveDynRefAdapter(t: IrType): {
26
30
  snapshot: string;
27
31
  commit: string;
@@ -32,6 +36,8 @@ export interface DynHost extends WalkerHost {
32
36
  dynPromiseAdapter(t: IrType): string;
33
37
  isErrorClass(className: string): boolean;
34
38
  classSubtypes(className: string): readonly string[];
39
+ /** emitter.ts's pendingTestLines: the inline pending-exception test. */
40
+ pendingTestLines(dest: string): string[];
35
41
  }
36
42
  export declare class LlDyn {
37
43
  private readonly host;
@@ -82,6 +88,19 @@ export declare class LlDyn {
82
88
  private undef;
83
89
  /** scr_dyn_obj_get with a compile-time key: borrowed member or null. */
84
90
  private objGetLit;
91
+ /** Branches past the caller's next emission when an undefined-armed
92
+ * field value is the ABSENT state. Returns the label the caller must branch
93
+ * to and start after its emission, or null when the type has no
94
+ * undefined arm. */
95
+ private skipIfAbsent;
96
+ /** A checked undefined-armed field value, or the field's ABSENT state
97
+ * when the value is undefined because the source object has no own
98
+ * property of that name (a missing JSON key stays missing; an explicit
99
+ * undefined stays present). Proxy sources answer through their reads, so
100
+ * they count as present. The checked value is a +1 union; replacing it
101
+ * with the immortal absent instance releases nothing (unit instances are
102
+ * immortal too). */
103
+ private presenceOf;
85
104
  /** Ordinary property lookup, including inherited data and accessors (+1). */
86
105
  private objReadLit;
87
106
  /** Appends a borrowed string, preserving its full byte length. */
@@ -99,6 +118,25 @@ export declare class LlDyn {
99
118
  private typedRefMatches;
100
119
  /** `sc_dm_<n>(ptr d) -> i1` — does this dyn fit T? Never throws. */
101
120
  dynMatchHelper(t: IrType, preserveRefs?: boolean): string;
121
+ private readonly jsonSchemas;
122
+ private readonly jsonParsers;
123
+ /** Targets the one-pass parser (scr_json_parse_schema) can build
124
+ * directly: number, boolean and string leaves inside arrays and plain
125
+ * records (no tuple, index signature, internal '%' slot or `__proto__`
126
+ * member; 1..64 fields). Everything else keeps the checked-dynamic
127
+ * route alone. */
128
+ private jsonSchemaSupported;
129
+ /** The ScrJsonSchema constant for t (scr_runtime.h layout). Records list
130
+ * fields in declaration order — the order JSON.stringify writes — so the
131
+ * runtime's next-field guess usually matches without a scan. */
132
+ private jsonSchema;
133
+ /** `sc_jp_<n>(ptr text) -> T` for `JSON.parse(text) as T`, or null when T
134
+ * is not a schema target. Tries the one-pass schema parser; when it
135
+ * declines (any input the checked route might reject or read
136
+ * differently), runs the checked-dynamic route — scr_json_parse plus the
137
+ * dynCheck builder — which reports the exact error. Returns +1, or null
138
+ * with the pending flag set. */
139
+ jsonParseHelper(t: IrType): string | null;
102
140
  /** `sc_dc_<n>(ptr d, ptr path) -> T` — validate the checked-dynamic tree against T and
103
141
  * BUILD the typed value (+1), or throw the catchable path-annotated
104
142
  * TypeError and return a dummy with the pending flag set. */
@@ -1,5 +1,6 @@
1
1
  import { typedRefConstructor } from "./shapes.js";
2
2
  import { BYTES_ELEM_NUM, f64Lit } from "./common.js";
3
+ import { emitUnionPeek, emitUnionTag } from "./union-repr.js";
3
4
  import { InternalCompilerError } from "../../errors.js";
4
5
  import { DYN_HANDLE_KINDS, isDynTypedRefType, isRefCounted, typeKey } from "../../ir/ir.js";
5
6
  import { dynDesc, streamTypedRefEligible } from "../../ir/analysis.js";
@@ -254,6 +255,61 @@ export class LlDyn {
254
255
  B.line(`${t} = call ptr @scr_dyn_obj_get(ptr ${d}, ptr ${this.host.cstr(key)}, ${this.S} ${len}) ; .${llvmCommentText(key)}`);
255
256
  return t;
256
257
  }
258
+ /** Branches past the caller's next emission when an undefined-armed
259
+ * field value is the ABSENT state. Returns the label the caller must branch
260
+ * to and start after its emission, or null when the type has no
261
+ * undefined arm. */
262
+ skipIfAbsent(B, value, t) {
263
+ const def = this.host.unionsById.get(t.unionId);
264
+ const utag = def ? def.arms.findIndex((arm) => arm.kind === "undefinedT") : -1;
265
+ if (utag < 0)
266
+ return null;
267
+ const absent = this.host.fieldAbsentTestIn(B, value, t.unionId);
268
+ const lSkip = B.newLabel("tdr.absent");
269
+ const lSet = B.newLabel("tdr.set");
270
+ B.condBr(absent, lSkip, lSet);
271
+ B.startBlock(lSet);
272
+ return lSkip;
273
+ }
274
+ /** A checked undefined-armed field value, or the field's ABSENT state
275
+ * when the value is undefined because the source object has no own
276
+ * property of that name (a missing JSON key stays missing; an explicit
277
+ * undefined stays present). Proxy sources answer through their reads, so
278
+ * they count as present. The checked value is a +1 union; replacing it
279
+ * with the immortal absent instance releases nothing (unit instances are
280
+ * immortal too). */
281
+ presenceOf(B, d, key, t, value) {
282
+ const def = this.host.unionsById.get(t.unionId);
283
+ const utag = def ? def.arms.findIndex((arm) => arm.kind === "undefinedT") : -1;
284
+ if (utag < 0)
285
+ return value;
286
+ const tag = emitUnionTag(B, this.host.nullableUnions.get(t.unionId), value);
287
+ const isUndef = B.tmp();
288
+ B.line(`${isUndef} = icmp eq i32 ${tag}, ${utag}`);
289
+ const kind = this.kindOf(B, d);
290
+ const isObj = B.tmp();
291
+ B.line(`${isObj} = icmp eq i32 ${kind}, ${DYN_KIND.OBJ}`);
292
+ const probe = B.tmp();
293
+ B.line(`${probe} = and i1 ${isUndef}, ${isObj}`);
294
+ const slot = B.slot();
295
+ B.entryAllocas.push(`${slot} = alloca ptr`);
296
+ B.line(`store ptr ${value}, ptr ${slot}`);
297
+ const lProbe = B.newLabel("dcr.has");
298
+ const lJoin = B.newLabel("dcr.hasj");
299
+ B.condBr(probe, lProbe, lJoin);
300
+ B.startBlock(lProbe);
301
+ const own = this.objGetLit(B, d, key);
302
+ const missing = B.tmp();
303
+ const chosen = B.tmp();
304
+ B.line(`${missing} = icmp eq ptr ${own}, null`);
305
+ B.line(`${chosen} = select i1 ${missing}, ptr ${this.host.absentInstanceRef(t.unionId)}, ptr ${value}`);
306
+ B.line(`store ptr ${chosen}, ptr ${slot}`);
307
+ B.br(lJoin);
308
+ B.startBlock(lJoin);
309
+ const out = B.tmp();
310
+ B.line(`${out} = load ptr, ptr ${slot}`);
311
+ return out;
312
+ }
257
313
  /** Ordinary property lookup, including inherited data and accessors (+1). */
258
314
  objReadLit(B, d, key) {
259
315
  this.host.declare(`declare ptr @scr_dyn_obj_read(ptr, ptr, ${this.S})`);
@@ -300,9 +356,9 @@ export class LlDyn {
300
356
  /** Emit the standard in-helper pending check: on a pending exception
301
357
  * run `cleanup` and return `dummy`. */
302
358
  pendingBail(B, hint, cleanup, dummy) {
303
- this.host.declare(`declare zeroext i1 @scr_exc_pending()`);
304
359
  const p = B.tmp();
305
- B.line(`${p} = call zeroext i1 @scr_exc_pending()`);
360
+ for (const line of this.host.pendingTestLines(p))
361
+ B.line(line.trimStart());
306
362
  const lu = B.newLabel(`${hint}.u`);
307
363
  const lk = B.newLabel(`${hint}.k`);
308
364
  B.condBr(p, lu, lk);
@@ -676,6 +732,121 @@ export class LlDyn {
676
732
  this.defs.push(`define internal zeroext i1 @${name}(ptr %d) ${FN_ATTRS} { ; matches ${key}`, B.render(), `}`, ``);
677
733
  return name;
678
734
  }
735
+ /* ── schema-directed JSON.parse ───────────────────────────────── */
736
+ jsonSchemas = new Map();
737
+ jsonParsers = new Map();
738
+ /** Targets the one-pass parser (scr_json_parse_schema) can build
739
+ * directly: number, boolean and string leaves inside arrays and plain
740
+ * records (no tuple, index signature, internal '%' slot or `__proto__`
741
+ * member; 1..64 fields). Everything else keeps the checked-dynamic
742
+ * route alone. */
743
+ jsonSchemaSupported(t, visiting) {
744
+ switch (t.kind) {
745
+ case "f64":
746
+ case "bool":
747
+ case "string":
748
+ return true;
749
+ case "array":
750
+ return this.jsonSchemaSupported(t.elem, visiting);
751
+ case "record": {
752
+ if (visiting.has(t.shapeId))
753
+ return true;
754
+ const shape = this.host.recordsById.get(t.shapeId);
755
+ if (!shape || shape.tuple || shape.indexValue)
756
+ return false;
757
+ if (shape.fields.length === 0 || shape.fields.length > 64)
758
+ return false;
759
+ visiting.add(t.shapeId);
760
+ return shape.fields.every((f) => !f.name.startsWith("%") &&
761
+ f.name !== "__proto__" &&
762
+ this.jsonSchemaSupported(f.type, visiting));
763
+ }
764
+ default:
765
+ return false;
766
+ }
767
+ }
768
+ /** The ScrJsonSchema constant for t (scr_runtime.h layout). Records list
769
+ * fields in declaration order — the order JSON.stringify writes — so the
770
+ * runtime's next-field guess usually matches without a scan. */
771
+ jsonSchema(t) {
772
+ const key = typeKey(t);
773
+ const existing = this.jsonSchemas.get(key);
774
+ if (existing)
775
+ return existing;
776
+ const host = this.host;
777
+ const S = host.sizeType;
778
+ const name = `sc_jsch_${this.jsonSchemas.size}`;
779
+ this.jsonSchemas.set(key, name);
780
+ let body;
781
+ switch (t.kind) {
782
+ case "f64":
783
+ case "bool":
784
+ case "string": {
785
+ const kind = t.kind === "f64" ? 0 : t.kind === "bool" ? 1 : 2;
786
+ body = `${S} ${kind}, ${S} 0, ptr null, ptr null, ptr null, ptr null, ptr null`;
787
+ break;
788
+ }
789
+ case "array": {
790
+ const elem = this.jsonSchema(t.elem);
791
+ const ctor = `${name}_new`;
792
+ this.defs.push(`define internal ptr @${ctor}(${S} %cap) ${FN_ATTRS} {`, `entry:`, ` %a = ${arrNewCall(host, t.elem, "%cap")}`, ` ret ptr %a`, `}`, ``);
793
+ body = `${S} 4, ${S} 0, ptr null, ptr @${elem}, ptr null, ptr @${ctor}, ptr ${vAdapters(host, t).release}`;
794
+ break;
795
+ }
796
+ case "record": {
797
+ const shape = host.recordsById.get(t.shapeId);
798
+ if (!shape)
799
+ throw new InternalCompilerError(`llvm emitter bug: JSON schema of unknown shape ${t.shapeId}`);
800
+ const struct = mangleRecordStruct(t.shapeId);
801
+ const index = new Map(shape.fields.map((f, i) => [f.name, i + 1]));
802
+ const order = [...(shape.declaredOrder ?? []).filter((n) => index.has(n))];
803
+ for (const f of shape.fields)
804
+ if (!order.includes(f.name))
805
+ order.push(f.name);
806
+ const fieldTy = `{ ptr, ${S}, ${S}, ptr }`;
807
+ const entries = order.map((fieldName) => {
808
+ const field = shape.fields[index.get(fieldName) - 1];
809
+ const sub = this.jsonSchema(field.type);
810
+ const offset = `ptrtoint (ptr getelementptr (%${struct}, ptr null, i64 0, i32 ${index.get(fieldName)}) to ${S})`;
811
+ return `${fieldTy} { ptr ${host.cstr(fieldName)}, ${S} ${Buffer.byteLength(fieldName, "utf8")}, ${S} ${offset}, ptr @${sub} }`;
812
+ });
813
+ const fields = `${name}_fields`;
814
+ this.defs.push(`@${fields} = internal constant [${entries.length} x ${fieldTy}] [${entries.join(", ")}]`, ``);
815
+ body = `${S} 3, ${S} ${entries.length}, ptr @${fields}, ptr null, ptr @${mangleRecordNew(t.shapeId)}, ptr null, ptr ${vAdapters(host, t).release}`;
816
+ break;
817
+ }
818
+ default:
819
+ throw new InternalCompilerError(`llvm emitter bug: JSON schema of ${t.kind}`);
820
+ }
821
+ this.defs.push(`@${name} = internal constant { ${S}, ${S}, ptr, ptr, ptr, ptr, ptr } { ${body} }`, ``);
822
+ return name;
823
+ }
824
+ /** `sc_jp_<n>(ptr text) -> T` for `JSON.parse(text) as T`, or null when T
825
+ * is not a schema target. Tries the one-pass schema parser; when it
826
+ * declines (any input the checked route might reject or read
827
+ * differently), runs the checked-dynamic route — scr_json_parse plus the
828
+ * dynCheck builder — which reports the exact error. Returns +1, or null
829
+ * with the pending flag set. */
830
+ jsonParseHelper(t) {
831
+ if (t.kind !== "record" && t.kind !== "array")
832
+ return null;
833
+ const key = typeKey(t);
834
+ const existing = this.jsonParsers.get(key);
835
+ if (existing)
836
+ return existing;
837
+ if (!this.jsonSchemaSupported(t, new Set()))
838
+ return null;
839
+ const host = this.host;
840
+ const name = `sc_jp_${this.jsonParsers.size}`;
841
+ this.jsonParsers.set(key, name);
842
+ const schema = this.jsonSchema(t);
843
+ const check = this.dynCheckHelper(t);
844
+ host.declare(`declare ptr @scr_json_parse_schema(ptr, ptr)`);
845
+ host.declare(`declare ptr @scr_json_parse(ptr)`);
846
+ host.declare(`declare void @scr_dyn_release(ptr)`);
847
+ this.defs.push(`define internal ptr @${name}(ptr %text) ${FN_ATTRS} { ; JSON.parse as ${llvmCommentText(key)}`, `entry:`, ` %fast = call ptr @scr_json_parse_schema(ptr %text, ptr @${schema})`, ` %hit = icmp ne ptr %fast, null`, ` br i1 %hit, label %done, label %slow`, `done:`, ` ret ptr %fast`, `slow:`, ` %d = call ptr @scr_json_parse(ptr %text)`, ` %bad = icmp eq ptr %d, null`, ` br i1 %bad, label %fail, label %check`, `fail:`, ` ret ptr null`, `check:`, ` %v = call ptr @${check}(ptr %d, ptr null)`, ` call void @scr_dyn_release(ptr %d)`, ` ret ptr %v`, `}`, ``);
848
+ return name;
849
+ }
679
850
  /* ── dynCheckHelper (walkers.ts, ported) ──────────────────────── */
680
851
  /** `sc_dc_<n>(ptr d, ptr path) -> T` — validate the checked-dynamic tree against T and
681
852
  * BUILD the typed value (+1), or throw the catchable path-annotated
@@ -1147,6 +1318,11 @@ export class LlDyn {
1147
1318
  B.line(`call void @scr_dyn_release(ptr ${m})`);
1148
1319
  storeInto(f.name, f.type, value);
1149
1320
  this.pendingBail(B, "dcr", releaseR, "ptr null");
1321
+ if (f.type.kind === "union") {
1322
+ const stored = this.presenceOf(B, "%d", f.name, f.type, value);
1323
+ if (stored !== value)
1324
+ storeInto(f.name, f.type, stored);
1325
+ }
1150
1326
  }
1151
1327
  // Index-signature shapes CAPTURE undeclared keys into the
1152
1328
  // overflow map.
@@ -1300,6 +1476,12 @@ export class LlDyn {
1300
1476
  B.line(`${u} = call ptr @scr_union_new_bool(i32 ${i}, i1 ${x})`);
1301
1477
  B.terminate(`ret ptr ${u}`);
1302
1478
  }
1479
+ else if (host.nullableUnions.has(t.unionId)) {
1480
+ // A nullable union is its (+1) reference payload.
1481
+ const x = B.tmp();
1482
+ B.line(`${x} = call ptr @${this.dynCheckHelper(arm, preserveRefs)}(ptr %d, ptr %path)`);
1483
+ B.terminate(`ret ptr ${x}`);
1484
+ }
1303
1485
  else {
1304
1486
  const rc = vAdapters(host, arm);
1305
1487
  host.declare(`declare ptr @scr_union_new_ref(i32, ptr, ptr, ptr, ptr)`);
@@ -1333,6 +1515,21 @@ export class LlDyn {
1333
1515
  const lFail = B.newLabel("dcu.fail");
1334
1516
  B.condBr(capsule, lCapsule, lFail);
1335
1517
  B.startBlock(lCapsule);
1518
+ if (host.nullableUnions.has(t.unionId)) {
1519
+ // No box identity to cache: the structural snapshot's payload is
1520
+ // the value, and NULL is the undefined arm, so failure is the
1521
+ // pending exception rather than a NULL result.
1522
+ const materialized = B.tmp();
1523
+ const checked = B.tmp();
1524
+ B.line(`${materialized} = call ptr @scr_dyn_typed_ref_materialize(ptr %d)`);
1525
+ B.line(`${checked} = call ptr @${name}(ptr ${materialized}, ptr %path)`);
1526
+ B.line(`call void @scr_dyn_release_v(ptr ${materialized})`);
1527
+ B.terminate(`ret ptr ${checked}`);
1528
+ B.startBlock(lFail);
1529
+ B.line(`call void @scr_dyn_check_fail(ptr %path, ptr ${want}, ptr %d)`);
1530
+ B.terminate(`ret ptr null`);
1531
+ break;
1532
+ }
1336
1533
  const cached = B.tmp();
1337
1534
  B.line(`${cached} = call ptr @scr_dyn_typed_ref_cached_cast(ptr %d, ptr ${host.cstr(key)}, ${host.sizeType} ${Buffer.byteLength(key, "utf8")})`);
1338
1535
  const hasCached = B.tmp();
@@ -1457,6 +1654,10 @@ export class LlDyn {
1457
1654
  B.line(`store ptr ${box}, ptr ${capp}`);
1458
1655
  const rd = this.retainDyn(B, "%d");
1459
1656
  B.line(`call void @scr_box_set_ref(ptr ${box}, ptr ${rd})`);
1657
+ // The shim is the same JS function under another signature: it
1658
+ // takes the boxed closure's identity (kept alive through caps[0]).
1659
+ host.declare(`declare void @scr_dyn_adopt_identity(ptr, ptr)`);
1660
+ B.line(`call void @scr_dyn_adopt_identity(ptr ${a}, ptr %d)`);
1460
1661
  B.terminate(`ret ptr ${a}`);
1461
1662
  break;
1462
1663
  }
@@ -1695,9 +1896,15 @@ export class LlDyn {
1695
1896
  for (const f of dynFields) {
1696
1897
  const klen = Buffer.byteLength(f.name, "utf8");
1697
1898
  const fv = loadFieldOf(f.name, f.type);
1899
+ // An ABSENT optional field contributes no key.
1900
+ const lSkip = f.type.kind === "union" ? this.skipIfAbsent(B, fv, f.type) : null;
1698
1901
  const conv = B.tmp();
1699
1902
  B.line(`${conv} = call ptr @${this.toDynHelper(f.type)}(${this.valTy(f.type)} ${fv})`);
1700
1903
  B.line(`call void @scr_dyn_obj_set(ptr ${d}, ptr ${host.cstr(f.name)}, ${host.sizeType} ${klen}, ptr ${conv}) ; ${llvmCommentText(f.name)}`);
1904
+ if (lSkip !== null) {
1905
+ B.br(lSkip);
1906
+ B.startBlock(lSkip);
1907
+ }
1701
1908
  }
1702
1909
  if (shape.indexValue) {
1703
1910
  const iv = shape.indexValue;
@@ -1854,10 +2061,8 @@ export class LlDyn {
1854
2061
  const def = host.unionsById.get(t.unionId);
1855
2062
  if (!def)
1856
2063
  throw new InternalCompilerError(`llvm emitter bug: to-dyn of unknown union ${t.unionId}`);
1857
- const tagp = B.tmp();
1858
- const tag = B.tmp();
1859
- B.line(`${tagp} = getelementptr inbounds %ScrUnion, ptr %v, i64 0, i32 1`);
1860
- B.line(`${tag} = load i32, ptr ${tagp}`);
2064
+ const nullable = host.nullableUnions.get(t.unionId);
2065
+ const tag = emitUnionTag(B, nullable, "%v");
1861
2066
  const bad = B.newLabel("tdu.bad");
1862
2067
  const labels = def.arms.map(() => B.newLabel("tdu.a"));
1863
2068
  B.terminate(`switch i32 ${tag}, label %${bad} [ ${def.arms.map((_, i) => `i32 ${i}, label %${labels[i]}`).join(" ")} ]`);
@@ -1894,19 +2099,13 @@ export class LlDyn {
1894
2099
  else if (arm.kind === "func") {
1895
2100
  // A boxable function arm crosses through the checked-dynamic
1896
2101
  // function boundary (the dynFrom func special case, sans name).
1897
- const pp = B.tmp();
1898
- const p = B.tmp();
1899
- B.line(`${pp} = getelementptr inbounds %ScrUnion, ptr %v, i64 0, i32 5`);
1900
- B.line(`${p} = load ptr, ptr ${pp}`);
2102
+ const p = emitUnionPeek(B, nullable, "%v");
1901
2103
  const r = B.tmp();
1902
2104
  B.line(`${r} = call ptr @${this.dynFuncBoxHelper(arm)}(ptr ${p}, ptr null)`);
1903
2105
  B.terminate(`ret ptr ${r}`);
1904
2106
  }
1905
2107
  else {
1906
- const pp = B.tmp();
1907
- const p = B.tmp();
1908
- B.line(`${pp} = getelementptr inbounds %ScrUnion, ptr %v, i64 0, i32 5`);
1909
- B.line(`${p} = load ptr, ptr ${pp}`);
2108
+ const p = emitUnionPeek(B, nullable, "%v");
1910
2109
  const r = B.tmp();
1911
2110
  B.line(`${r} = call ptr @${this.toDynHelper(arm)}(ptr ${p}) ; ${arm.kind}`);
1912
2111
  B.terminate(`ret ptr ${r}`);