@scriptc/compiler 0.4.2 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (636) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +397 -37
  2. package/dist/backend/cycle-analysis.d.ts +4 -1
  3. package/dist/backend/cycle-analysis.js +6 -4
  4. package/dist/backend/cycle-analysis.js.map +1 -1
  5. package/dist/backend/cycle-analysis.test.js +55 -0
  6. package/dist/backend/cycle-analysis.test.js.map +1 -1
  7. package/dist/backend/cycle-mutability.d.ts +7 -0
  8. package/dist/backend/cycle-mutability.js +19 -1
  9. package/dist/backend/cycle-mutability.js.map +1 -1
  10. package/dist/backend/executable-features.js +2 -0
  11. package/dist/backend/executable-features.js.map +1 -1
  12. package/dist/backend/immutability.d.ts +6 -3
  13. package/dist/backend/immutability.js +33 -29
  14. package/dist/backend/immutability.js.map +1 -1
  15. package/dist/backend/library-pack.js +1 -0
  16. package/dist/backend/library-pack.js.map +1 -1
  17. package/dist/backend/llvm/alloc.d.ts +16 -1
  18. package/dist/backend/llvm/alloc.js +54 -4
  19. package/dist/backend/llvm/alloc.js.map +1 -1
  20. package/dist/backend/llvm/appended-array-literals.d.ts +2 -1
  21. package/dist/backend/llvm/appended-array-literals.js +44 -36
  22. package/dist/backend/llvm/appended-array-literals.js.map +1 -1
  23. package/dist/backend/llvm/appended-array-literals.test.js +4 -3
  24. package/dist/backend/llvm/appended-array-literals.test.js.map +1 -1
  25. package/dist/backend/llvm/array-search.d.ts +4 -3
  26. package/dist/backend/llvm/array-search.js +21 -9
  27. package/dist/backend/llvm/array-search.js.map +1 -1
  28. package/dist/backend/llvm/blocks.d.ts +1 -1
  29. package/dist/backend/llvm/blocks.js +2 -2
  30. package/dist/backend/llvm/blocks.js.map +1 -1
  31. package/dist/backend/llvm/byte-windows.js +2 -0
  32. package/dist/backend/llvm/byte-windows.js.map +1 -1
  33. package/dist/backend/llvm/bytes-alias.d.ts +6 -1
  34. package/dist/backend/llvm/bytes-alias.js +8 -2
  35. package/dist/backend/llvm/bytes-alias.js.map +1 -1
  36. package/dist/backend/llvm/bytes-loop-versions.d.ts +47 -5
  37. package/dist/backend/llvm/bytes-loop-versions.js +473 -32
  38. package/dist/backend/llvm/bytes-loop-versions.js.map +1 -1
  39. package/dist/backend/llvm/bytes-loop-versions.test.js +258 -2
  40. package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -1
  41. package/dist/backend/llvm/checked-value-lifetimes.js +2 -0
  42. package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
  43. package/dist/backend/llvm/classes.d.ts +7 -5
  44. package/dist/backend/llvm/classes.js +44 -20
  45. package/dist/backend/llvm/classes.js.map +1 -1
  46. package/dist/backend/llvm/classes.test.js +167 -7
  47. package/dist/backend/llvm/classes.test.js.map +1 -1
  48. package/dist/backend/llvm/common.d.ts +9 -3
  49. package/dist/backend/llvm/common.js +9 -3
  50. package/dist/backend/llvm/common.js.map +1 -1
  51. package/dist/backend/llvm/constant-callbacks.d.ts +2 -1
  52. package/dist/backend/llvm/constant-callbacks.js +83 -52
  53. package/dist/backend/llvm/constant-callbacks.js.map +1 -1
  54. package/dist/backend/llvm/counted-loops.d.ts +7 -0
  55. package/dist/backend/llvm/counted-loops.js +18 -0
  56. package/dist/backend/llvm/counted-loops.js.map +1 -1
  57. package/dist/backend/llvm/dense-array-access.d.ts +39 -8
  58. package/dist/backend/llvm/dense-array-access.js +222 -52
  59. package/dist/backend/llvm/dense-array-access.js.map +1 -1
  60. package/dist/backend/llvm/dense-array-access.test.js +36 -0
  61. package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
  62. package/dist/backend/llvm/dense-array-loops.d.ts +17 -1
  63. package/dist/backend/llvm/dense-array-loops.js +194 -5
  64. package/dist/backend/llvm/dense-array-loops.js.map +1 -1
  65. package/dist/backend/llvm/dense-array-loops.test.js +90 -1
  66. package/dist/backend/llvm/dense-array-loops.test.js.map +1 -1
  67. package/dist/backend/llvm/dyn-handle-tags.test.js +6 -1
  68. package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -1
  69. package/dist/backend/llvm/dyn.d.ts +26 -0
  70. package/dist/backend/llvm/dyn.js +352 -61
  71. package/dist/backend/llvm/dyn.js.map +1 -1
  72. package/dist/backend/llvm/emit-function.js +11 -20
  73. package/dist/backend/llvm/emit-function.js.map +1 -1
  74. package/dist/backend/llvm/emit-journal.d.ts +93 -0
  75. package/dist/backend/llvm/emit-journal.js +170 -0
  76. package/dist/backend/llvm/emit-journal.js.map +1 -0
  77. package/dist/backend/llvm/emit-module.js +195 -27
  78. package/dist/backend/llvm/emit-module.js.map +1 -1
  79. package/dist/backend/llvm/emit-statements.d.ts +0 -4
  80. package/dist/backend/llvm/emit-statements.js +268 -84
  81. package/dist/backend/llvm/emit-statements.js.map +1 -1
  82. package/dist/backend/llvm/emitter-state.d.ts +7 -0
  83. package/dist/backend/llvm/emitter-state.js +14 -0
  84. package/dist/backend/llvm/emitter-state.js.map +1 -0
  85. package/dist/backend/llvm/emitter.d.ts +176 -37
  86. package/dist/backend/llvm/emitter.js +724 -85
  87. package/dist/backend/llvm/emitter.js.map +1 -1
  88. package/dist/backend/llvm/emitter.test.js +54 -5
  89. package/dist/backend/llvm/emitter.test.js.map +1 -1
  90. package/dist/backend/llvm/expr-bytes.js +34 -12
  91. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  92. package/dist/backend/llvm/expr-callbacks.js +47 -0
  93. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  94. package/dist/backend/llvm/expr-calls.js +28 -14
  95. package/dist/backend/llvm/expr-calls.js.map +1 -1
  96. package/dist/backend/llvm/expr-containers.d.ts +14 -2
  97. package/dist/backend/llvm/expr-containers.js +129 -37
  98. package/dist/backend/llvm/expr-containers.js.map +1 -1
  99. package/dist/backend/llvm/expr-context.d.ts +14 -0
  100. package/dist/backend/llvm/expr-dynamic.js +18 -11
  101. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  102. package/dist/backend/llvm/expr-primitives.js +100 -28
  103. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  104. package/dist/backend/llvm/expr-primitives.test.js +11 -6
  105. package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
  106. package/dist/backend/llvm/expr-records.d.ts +12 -0
  107. package/dist/backend/llvm/expr-records.js +106 -0
  108. package/dist/backend/llvm/expr-records.js.map +1 -1
  109. package/dist/backend/llvm/expr-stream-bridges.d.ts +2 -2
  110. package/dist/backend/llvm/expr-stream-bridges.js +194 -65
  111. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  112. package/dist/backend/llvm/expr-stream-bridges.test.js +1 -1
  113. package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -1
  114. package/dist/backend/llvm/expr-stream-callbacks.d.ts +2 -2
  115. package/dist/backend/llvm/expr-stream-callbacks.js +74 -20
  116. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  117. package/dist/backend/llvm/int32-kind-loops.d.ts +39 -0
  118. package/dist/backend/llvm/int32-kind-loops.js +106 -0
  119. package/dist/backend/llvm/int32-kind-loops.js.map +1 -0
  120. package/dist/backend/llvm/integer-or-nan-indexes.test.d.ts +1 -0
  121. package/dist/backend/llvm/integer-or-nan-indexes.test.js +118 -0
  122. package/dist/backend/llvm/integer-or-nan-indexes.test.js.map +1 -0
  123. package/dist/backend/llvm/integer-values.d.ts +20 -1
  124. package/dist/backend/llvm/integer-values.js +71 -0
  125. package/dist/backend/llvm/integer-values.js.map +1 -1
  126. package/dist/backend/llvm/js-ic.d.ts +1 -1
  127. package/dist/backend/llvm/js-ic.js +1 -1
  128. package/dist/backend/llvm/js-ic.js.map +1 -1
  129. package/dist/backend/llvm/key-orders.d.ts +7 -0
  130. package/dist/backend/llvm/key-orders.js +33 -0
  131. package/dist/backend/llvm/key-orders.js.map +1 -0
  132. package/dist/backend/llvm/lib-connect.js +4 -0
  133. package/dist/backend/llvm/lib-connect.js.map +1 -1
  134. package/dist/backend/llvm/lib-datagram.js +11 -0
  135. package/dist/backend/llvm/lib-datagram.js.map +1 -1
  136. package/dist/backend/llvm/lib-dispatch.js +80 -2
  137. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  138. package/dist/backend/llvm/lib-filesystem.js +4 -4
  139. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  140. package/dist/backend/llvm/lib-http2.js +4 -0
  141. package/dist/backend/llvm/lib-http2.js.map +1 -1
  142. package/dist/backend/llvm/lib-lookup.js +16 -6
  143. package/dist/backend/llvm/lib-lookup.js.map +1 -1
  144. package/dist/backend/llvm/lib-shared.js +73 -2
  145. package/dist/backend/llvm/lib-shared.js.map +1 -1
  146. package/dist/backend/llvm/lib-stream.js +35 -5
  147. package/dist/backend/llvm/lib-stream.js.map +1 -1
  148. package/dist/backend/llvm/local-array-reads.js +115 -19
  149. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  150. package/dist/backend/llvm/local-array-reads.test.js +14 -0
  151. package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
  152. package/dist/backend/llvm/loop-state.d.ts +33 -0
  153. package/dist/backend/llvm/loop-state.js +42 -0
  154. package/dist/backend/llvm/loop-state.js.map +1 -0
  155. package/dist/backend/llvm/map-number-lookup.d.ts +26 -8
  156. package/dist/backend/llvm/map-number-lookup.js +91 -31
  157. package/dist/backend/llvm/map-number-lookup.js.map +1 -1
  158. package/dist/backend/llvm/map-number-lookup.test.js +55 -0
  159. package/dist/backend/llvm/map-number-lookup.test.js.map +1 -1
  160. package/dist/backend/llvm/map-read-lifetimes.js +4 -2
  161. package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
  162. package/dist/backend/llvm/nullable-unions.d.ts +2 -1
  163. package/dist/backend/llvm/nullable-unions.js +15 -3
  164. package/dist/backend/llvm/nullable-unions.js.map +1 -1
  165. package/dist/backend/llvm/publish.d.ts +10 -0
  166. package/dist/backend/llvm/publish.js +12 -0
  167. package/dist/backend/llvm/publish.js.map +1 -1
  168. package/dist/backend/llvm/receivers.js +6 -1
  169. package/dist/backend/llvm/receivers.js.map +1 -1
  170. package/dist/backend/llvm/record-results.d.ts +1 -9
  171. package/dist/backend/llvm/record-results.js +2 -11
  172. package/dist/backend/llvm/record-results.js.map +1 -1
  173. package/dist/backend/llvm/reference-writes.d.ts +7 -2
  174. package/dist/backend/llvm/reference-writes.js +89 -72
  175. package/dist/backend/llvm/reference-writes.js.map +1 -1
  176. package/dist/backend/llvm/running-extrema.d.ts +11 -0
  177. package/dist/backend/llvm/running-extrema.js +115 -0
  178. package/dist/backend/llvm/running-extrema.js.map +1 -0
  179. package/dist/backend/llvm/running-extrema.test.d.ts +1 -0
  180. package/dist/backend/llvm/running-extrema.test.js +89 -0
  181. package/dist/backend/llvm/running-extrema.test.js.map +1 -0
  182. package/dist/backend/llvm/shapes.d.ts +71 -15
  183. package/dist/backend/llvm/shapes.js +222 -33
  184. package/dist/backend/llvm/shapes.js.map +1 -1
  185. package/dist/backend/llvm/shapes.test.js +53 -7
  186. package/dist/backend/llvm/shapes.test.js.map +1 -1
  187. package/dist/backend/llvm/speculative-integers.d.ts +6 -0
  188. package/dist/backend/llvm/speculative-integers.js +2 -2
  189. package/dist/backend/llvm/speculative-integers.js.map +1 -1
  190. package/dist/backend/llvm/stack-objects.d.ts +3 -2
  191. package/dist/backend/llvm/stack-objects.js +5 -2
  192. package/dist/backend/llvm/stack-objects.js.map +1 -1
  193. package/dist/backend/llvm/string-reads.d.ts +12 -0
  194. package/dist/backend/llvm/string-reads.js +44 -0
  195. package/dist/backend/llvm/string-reads.js.map +1 -1
  196. package/dist/backend/llvm/walk-borrows.d.ts +3 -0
  197. package/dist/backend/llvm/walk-borrows.js +46 -41
  198. package/dist/backend/llvm/walk-borrows.js.map +1 -1
  199. package/dist/backend/llvm/walkers.d.ts +3 -0
  200. package/dist/backend/llvm/walkers.js +88 -65
  201. package/dist/backend/llvm/walkers.js.map +1 -1
  202. package/dist/backend/llvm/wrapping-sums.d.ts +16 -1
  203. package/dist/backend/llvm/wrapping-sums.js +126 -0
  204. package/dist/backend/llvm/wrapping-sums.js.map +1 -1
  205. package/dist/backend/may-throw.d.ts +8 -10
  206. package/dist/backend/may-throw.js +14 -10
  207. package/dist/backend/may-throw.js.map +1 -1
  208. package/dist/backend/native/contracts.d.ts +5 -0
  209. package/dist/backend/native/executable.js +7 -0
  210. package/dist/backend/native/executable.js.map +1 -1
  211. package/dist/backend/native/runtime-inputs.d.ts +1 -1
  212. package/dist/backend/native/runtime-inputs.js +1 -0
  213. package/dist/backend/native/runtime-inputs.js.map +1 -1
  214. package/dist/backend/native-link-info-core.d.ts +4 -0
  215. package/dist/backend/native-link-info-core.js.map +1 -1
  216. package/dist/backend/publication.d.ts +12 -1
  217. package/dist/backend/publication.js +37 -14
  218. package/dist/backend/publication.js.map +1 -1
  219. package/dist/backend/publication.test.js +30 -0
  220. package/dist/backend/publication.test.js.map +1 -1
  221. package/dist/backend/result-slots.d.ts +16 -0
  222. package/dist/backend/result-slots.js +23 -0
  223. package/dist/backend/result-slots.js.map +1 -0
  224. package/dist/backend/runtime-abi.d.ts +2 -2
  225. package/dist/backend/runtime-abi.js +2 -2
  226. package/dist/backend/runtime-pack-core.d.ts +1 -0
  227. package/dist/backend/runtime-pack-core.js +1 -0
  228. package/dist/backend/runtime-pack-core.js.map +1 -1
  229. package/dist/backend/runtime-pack-targets.test.js +2 -1
  230. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  231. package/dist/backend/runtime-pack.test.js +2 -1
  232. package/dist/backend/runtime-pack.test.js.map +1 -1
  233. package/dist/backend/stack-observations.d.ts +2 -1
  234. package/dist/backend/stack-observations.js +67 -42
  235. package/dist/backend/stack-observations.js.map +1 -1
  236. package/dist/backend/target-diagnostics.js +5 -3
  237. package/dist/backend/target-diagnostics.js.map +1 -1
  238. package/dist/backend/warm-cache.js +1 -0
  239. package/dist/backend/warm-cache.js.map +1 -1
  240. package/dist/cli/usage.d.ts +1 -1
  241. package/dist/cli/usage.js +3 -3
  242. package/dist/compat/fetch-profile.js +1 -1
  243. package/dist/compat/fetch-profile.js.map +1 -1
  244. package/dist/contracts/check.js +4 -3
  245. package/dist/contracts/check.js.map +1 -1
  246. package/dist/contracts/int32-elements.js +10 -2
  247. package/dist/contracts/int32-elements.js.map +1 -1
  248. package/dist/coverage/report.js +12 -3
  249. package/dist/coverage/report.js.map +1 -1
  250. package/dist/diagnostics/diagnostic.d.ts +4 -0
  251. package/dist/diagnostics/diagnostic.js.map +1 -1
  252. package/dist/diagnostics/envelope.d.ts +3 -0
  253. package/dist/diagnostics/envelope.js +1 -0
  254. package/dist/diagnostics/envelope.js.map +1 -1
  255. package/dist/executable/executable-cache.d.ts +2 -0
  256. package/dist/executable/executable-cache.js +1 -0
  257. package/dist/executable/executable-cache.js.map +1 -1
  258. package/dist/executable/executable-cache.test.js +1 -0
  259. package/dist/executable/executable-cache.test.js.map +1 -1
  260. package/dist/frontend/decl-projection.d.ts +41 -0
  261. package/dist/frontend/decl-projection.js +854 -0
  262. package/dist/frontend/decl-projection.js.map +1 -0
  263. package/dist/frontend/decl-projection.test.d.ts +1 -0
  264. package/dist/frontend/decl-projection.test.js +30 -0
  265. package/dist/frontend/decl-projection.test.js.map +1 -0
  266. package/dist/frontend/dts-paths.d.ts +15 -0
  267. package/dist/frontend/dts-paths.js +25 -0
  268. package/dist/frontend/dts-paths.js.map +1 -1
  269. package/dist/frontend/input-tracker.d.ts +6 -0
  270. package/dist/frontend/input-tracker.js +51 -28
  271. package/dist/frontend/input-tracker.js.map +1 -1
  272. package/dist/frontend/input-tracker.test.js +19 -0
  273. package/dist/frontend/input-tracker.test.js.map +1 -1
  274. package/dist/frontend/lowering/array-values.js +100 -2
  275. package/dist/frontend/lowering/array-values.js.map +1 -1
  276. package/dist/frontend/lowering/builtins/child-process-methods.js +46 -15
  277. package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
  278. package/dist/frontend/lowering/builtins/child-process.js +13 -2
  279. package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
  280. package/dist/frontend/lowering/builtins/crypto.js +84 -9
  281. package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
  282. package/dist/frontend/lowering/builtins/global-namespace-keys.d.ts +3 -0
  283. package/dist/frontend/lowering/builtins/global-namespace-keys.js +122 -0
  284. package/dist/frontend/lowering/builtins/global-namespace-keys.js.map +1 -0
  285. package/dist/frontend/lowering/builtins/numbers.js +9 -1
  286. package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
  287. package/dist/frontend/lowering/builtins/promises.d.ts +6 -0
  288. package/dist/frontend/lowering/builtins/promises.js +88 -2
  289. package/dist/frontend/lowering/builtins/promises.js.map +1 -1
  290. package/dist/frontend/lowering/builtins/readline.d.ts +5 -1
  291. package/dist/frontend/lowering/builtins/readline.js +35 -3
  292. package/dist/frontend/lowering/builtins/readline.js.map +1 -1
  293. package/dist/frontend/lowering/builtins/url.js +24 -1
  294. package/dist/frontend/lowering/builtins/url.js.map +1 -1
  295. package/dist/frontend/lowering/builtins/webassembly.js +6 -3
  296. package/dist/frontend/lowering/builtins/webassembly.js.map +1 -1
  297. package/dist/frontend/lowering/class-callbacks.d.ts +5 -2
  298. package/dist/frontend/lowering/class-callbacks.js +82 -12
  299. package/dist/frontend/lowering/class-callbacks.js.map +1 -1
  300. package/dist/frontend/lowering/class-construction.d.ts +4 -1
  301. package/dist/frontend/lowering/class-construction.js +17 -3
  302. package/dist/frontend/lowering/class-construction.js.map +1 -1
  303. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +39 -2
  304. package/dist/frontend/lowering/class-dynamic-dispatch.js +766 -108
  305. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  306. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +47 -0
  307. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
  308. package/dist/frontend/lowering/class-iterables.d.ts +2 -1
  309. package/dist/frontend/lowering/class-iterables.js +9 -1
  310. package/dist/frontend/lowering/class-iterables.js.map +1 -1
  311. package/dist/frontend/lowering/class-method-mutations.js +32 -9
  312. package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
  313. package/dist/frontend/lowering/class-prototypes.js +31 -2
  314. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  315. package/dist/frontend/lowering/class-runtime-statics.d.ts +9 -3
  316. package/dist/frontend/lowering/class-runtime-statics.js +29 -4
  317. package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
  318. package/dist/frontend/lowering/coercions/structural-plans.js +48 -1
  319. package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
  320. package/dist/frontend/lowering/coercions/structural.js +91 -1
  321. package/dist/frontend/lowering/coercions/structural.js.map +1 -1
  322. package/dist/frontend/lowering/containers/array-callback-call.js +2 -2
  323. package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -1
  324. package/dist/frontend/lowering/containers/array-callbacks.js +338 -18
  325. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  326. package/dist/frontend/lowering/containers/array-concat.js +10 -0
  327. package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
  328. package/dist/frontend/lowering/containers/array-methods.js +15 -0
  329. package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
  330. package/dist/frontend/lowering/containers/array-pipelines.js +19 -8
  331. package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
  332. package/dist/frontend/lowering/containers/bytes.js +2 -1
  333. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  334. package/dist/frontend/lowering/containers/callback-arguments.js +3 -0
  335. package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
  336. package/dist/frontend/lowering/containers/collection-methods.js +7 -2
  337. package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
  338. package/dist/frontend/lowering/containers/filter-predicates.d.ts +6 -0
  339. package/dist/frontend/lowering/containers/filter-predicates.js +205 -0
  340. package/dist/frontend/lowering/containers/filter-predicates.js.map +1 -0
  341. package/dist/frontend/lowering/containers/indexed-objects.d.ts +0 -12
  342. package/dist/frontend/lowering/containers/indexed-objects.js +46 -7
  343. package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
  344. package/dist/frontend/lowering/containers/string-and-regexp.js +55 -9
  345. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  346. package/dist/frontend/lowering/containers/string-replacement.js +43 -19
  347. package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
  348. package/dist/frontend/lowering/dispatch-sites.js +15 -1
  349. package/dist/frontend/lowering/dispatch-sites.js.map +1 -1
  350. package/dist/frontend/lowering/divergences.js +9 -1
  351. package/dist/frontend/lowering/divergences.js.map +1 -1
  352. package/dist/frontend/lowering/error-methods.js +47 -2
  353. package/dist/frontend/lowering/error-methods.js.map +1 -1
  354. package/dist/frontend/lowering/expressions/array-literals.js +47 -0
  355. package/dist/frontend/lowering/expressions/array-literals.js.map +1 -1
  356. package/dist/frontend/lowering/expressions/binary.js +36 -2
  357. package/dist/frontend/lowering/expressions/binary.js.map +1 -1
  358. package/dist/frontend/lowering/expressions/element-access.js +90 -13
  359. package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
  360. package/dist/frontend/lowering/expressions/identifiers.js +33 -4
  361. package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
  362. package/dist/frontend/lowering/expressions/narrowing.js +95 -1
  363. package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
  364. package/dist/frontend/lowering/expressions/nullish-assignment.js +3 -1
  365. package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
  366. package/dist/frontend/lowering/expressions/object-literals.d.ts +10 -0
  367. package/dist/frontend/lowering/expressions/object-literals.js +138 -51
  368. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  369. package/dist/frontend/lowering/expressions/optional-chains.js +12 -0
  370. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  371. package/dist/frontend/lowering/expressions/property-access.js +113 -11
  372. package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
  373. package/dist/frontend/lowering/expressions/relational.js +212 -33
  374. package/dist/frontend/lowering/expressions/relational.js.map +1 -1
  375. package/dist/frontend/lowering/expressions/union-fields.js +4 -0
  376. package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
  377. package/dist/frontend/lowering/expressions/updates.js +22 -3
  378. package/dist/frontend/lowering/expressions/updates.js.map +1 -1
  379. package/dist/frontend/lowering/frozen-records.d.ts +28 -0
  380. package/dist/frontend/lowering/frozen-records.js +322 -0
  381. package/dist/frontend/lowering/frozen-records.js.map +1 -0
  382. package/dist/frontend/lowering/function-returns.js +49 -0
  383. package/dist/frontend/lowering/function-returns.js.map +1 -1
  384. package/dist/frontend/lowering/generic-functions.js +7 -2
  385. package/dist/frontend/lowering/generic-functions.js.map +1 -1
  386. package/dist/frontend/lowering/iterable-values.d.ts +49 -0
  387. package/dist/frontend/lowering/iterable-values.js +297 -0
  388. package/dist/frontend/lowering/iterable-values.js.map +1 -0
  389. package/dist/frontend/lowering/iterator-adapters.js +186 -1
  390. package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
  391. package/dist/frontend/lowering/js-class-fields.d.ts +8 -0
  392. package/dist/frontend/lowering/js-class-fields.js +45 -10
  393. package/dist/frontend/lowering/js-class-fields.js.map +1 -1
  394. package/dist/frontend/lowering/key-order-witness.d.ts +18 -3
  395. package/dist/frontend/lowering/key-order-witness.js +770 -22
  396. package/dist/frontend/lowering/key-order-witness.js.map +1 -1
  397. package/dist/frontend/lowering/key-order-witness.test.js +428 -8
  398. package/dist/frontend/lowering/key-order-witness.test.js.map +1 -1
  399. package/dist/frontend/lowering/lower-async-iteration.js +4 -1
  400. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
  401. package/dist/frontend/lowering/lower-calls.d.ts +7 -0
  402. package/dist/frontend/lowering/lower-calls.js +443 -41
  403. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  404. package/dist/frontend/lowering/lower-classes.d.ts +11 -2
  405. package/dist/frontend/lowering/lower-classes.js +302 -22
  406. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  407. package/dist/frontend/lowering/lower-dgram.js +3 -1
  408. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  409. package/dist/frontend/lowering/lower-exprs.js +10 -2
  410. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  411. package/dist/frontend/lowering/lower-functions.d.ts +11 -0
  412. package/dist/frontend/lowering/lower-functions.js +83 -0
  413. package/dist/frontend/lowering/lower-functions.js.map +1 -1
  414. package/dist/frontend/lowering/lower-generators.js +41 -31
  415. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  416. package/dist/frontend/lowering/lower-global-value.js +6 -3
  417. package/dist/frontend/lowering/lower-global-value.js.map +1 -1
  418. package/dist/frontend/lowering/lower-inspect.js +18 -6
  419. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  420. package/dist/frontend/lowering/lower-modules.js +32 -0
  421. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  422. package/dist/frontend/lowering/lower-namespaces.js +5 -1
  423. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  424. package/dist/frontend/lowering/lower-server.js +2 -2
  425. package/dist/frontend/lowering/lower-server.js.map +1 -1
  426. package/dist/frontend/lowering/lower-stdlib.d.ts +5 -0
  427. package/dist/frontend/lowering/lower-stdlib.js +30 -0
  428. package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
  429. package/dist/frontend/lowering/lower-stmts.d.ts +23 -0
  430. package/dist/frontend/lowering/lower-stmts.js +454 -48
  431. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  432. package/dist/frontend/lowering/lower-stream.d.ts +20 -2
  433. package/dist/frontend/lowering/lower-stream.js +1483 -156
  434. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  435. package/dist/frontend/lowering/lowerer.d.ts +77 -6
  436. package/dist/frontend/lowering/lowerer.js +313 -29
  437. package/dist/frontend/lowering/lowerer.js.map +1 -1
  438. package/dist/frontend/lowering/module-namespace-elements.d.ts +11 -1
  439. package/dist/frontend/lowering/module-namespace-elements.js +82 -5
  440. package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
  441. package/dist/frontend/lowering/new-target.d.ts +12 -0
  442. package/dist/frontend/lowering/new-target.js +280 -0
  443. package/dist/frontend/lowering/new-target.js.map +1 -0
  444. package/dist/frontend/lowering/surfaces.d.ts +3 -0
  445. package/dist/frontend/lowering/surfaces.js +18 -6
  446. package/dist/frontend/lowering/surfaces.js.map +1 -1
  447. package/dist/frontend/lowering/undefined-index.d.ts +27 -0
  448. package/dist/frontend/lowering/undefined-index.js +82 -0
  449. package/dist/frontend/lowering/undefined-index.js.map +1 -0
  450. package/dist/frontend/lowering/var-hoisting.js +29 -13
  451. package/dist/frontend/lowering/var-hoisting.js.map +1 -1
  452. package/dist/frontend/lowering/width-lift.d.ts +18 -0
  453. package/dist/frontend/npm-static-bundled-chunks.js +9 -11
  454. package/dist/frontend/npm-static-bundled-chunks.js.map +1 -1
  455. package/dist/frontend/npm-static-bundled-chunks.test.js +6 -5
  456. package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -1
  457. package/dist/frontend/npm-static-rewrite-syntax.js +9 -1
  458. package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
  459. package/dist/frontend/npm-static.js +4 -20
  460. package/dist/frontend/npm-static.js.map +1 -1
  461. package/dist/frontend/package-shims.d.ts +3 -0
  462. package/dist/frontend/package-shims.js +71 -8
  463. package/dist/frontend/package-shims.js.map +1 -1
  464. package/dist/frontend/pipeline.js +18 -10
  465. package/dist/frontend/pipeline.js.map +1 -1
  466. package/dist/frontend/process-fork.d.ts +25 -0
  467. package/dist/frontend/process-fork.js +2 -0
  468. package/dist/frontend/process-fork.js.map +1 -0
  469. package/dist/frontend/program.d.ts +8 -1
  470. package/dist/frontend/program.js +484 -69
  471. package/dist/frontend/program.js.map +1 -1
  472. package/dist/frontend/program.test.js +43 -3
  473. package/dist/frontend/program.test.js.map +1 -1
  474. package/dist/frontend/token-equivalence.d.ts +3 -0
  475. package/dist/frontend/token-equivalence.js +409 -0
  476. package/dist/frontend/token-equivalence.js.map +1 -0
  477. package/dist/frontend/token-equivalence.test.d.ts +1 -0
  478. package/dist/frontend/token-equivalence.test.js +67 -0
  479. package/dist/frontend/token-equivalence.test.js.map +1 -0
  480. package/dist/frontend/ts7/ast-node.d.ts +22 -0
  481. package/dist/frontend/ts7/ast-node.js +1048 -103
  482. package/dist/frontend/ts7/ast-node.js.map +1 -1
  483. package/dist/frontend/ts7/ast-node.test.js +24 -0
  484. package/dist/frontend/ts7/ast-node.test.js.map +1 -1
  485. package/dist/frontend/ts7/ast-wire.d.ts +4 -3
  486. package/dist/frontend/ts7/ast-wire.js +34 -24
  487. package/dist/frontend/ts7/ast-wire.js.map +1 -1
  488. package/dist/frontend/ts7/ast-wire.test.js +23 -0
  489. package/dist/frontend/ts7/ast-wire.test.js.map +1 -1
  490. package/dist/frontend/ts7/checker-backend.d.ts +3 -4
  491. package/dist/frontend/ts7/checker-backend.js +2 -2
  492. package/dist/frontend/ts7/checker-backend.js.map +1 -1
  493. package/dist/frontend/ts7/checker-backend.test.js +5 -9
  494. package/dist/frontend/ts7/checker-backend.test.js.map +1 -1
  495. package/dist/frontend/ts7/checker.d.ts +4 -0
  496. package/dist/frontend/ts7/checker.js +7 -0
  497. package/dist/frontend/ts7/checker.js.map +1 -1
  498. package/dist/frontend/ts7/lib-diagnostics.d.ts +24 -0
  499. package/dist/frontend/ts7/lib-diagnostics.js +307 -0
  500. package/dist/frontend/ts7/lib-diagnostics.js.map +1 -0
  501. package/dist/frontend/ts7/lib-diagnostics.test.d.ts +1 -0
  502. package/dist/frontend/ts7/lib-diagnostics.test.js +199 -0
  503. package/dist/frontend/ts7/lib-diagnostics.test.js.map +1 -0
  504. package/dist/frontend/ts7/program-host.d.ts +7 -0
  505. package/dist/frontend/ts7/program-host.js +25 -2
  506. package/dist/frontend/ts7/program-host.js.map +1 -1
  507. package/dist/frontend/ts7/session.d.ts +14 -1
  508. package/dist/frontend/ts7/session.js +22 -0
  509. package/dist/frontend/ts7/session.js.map +1 -1
  510. package/dist/frontend/type-mapper.d.ts +13 -1
  511. package/dist/frontend/type-mapper.js +191 -11
  512. package/dist/frontend/type-mapper.js.map +1 -1
  513. package/dist/index.d.ts +0 -5
  514. package/dist/index.js +34 -4
  515. package/dist/index.js.map +1 -1
  516. package/dist/ir/analysis.js +5 -3
  517. package/dist/ir/analysis.js.map +1 -1
  518. package/dist/ir/array-length-stability.d.ts +4 -0
  519. package/dist/ir/array-length-stability.js +19 -6
  520. package/dist/ir/array-length-stability.js.map +1 -1
  521. package/dist/ir/array-length-stability.test.js +24 -0
  522. package/dist/ir/array-length-stability.test.js.map +1 -1
  523. package/dist/ir/builtin-effects.d.ts +7 -0
  524. package/dist/ir/builtin-effects.js +52 -0
  525. package/dist/ir/builtin-effects.js.map +1 -1
  526. package/dist/ir/builtin-signatures.d.ts +6 -4
  527. package/dist/ir/builtin-signatures.js +166 -13
  528. package/dist/ir/builtin-signatures.js.map +1 -1
  529. package/dist/ir/callback-specialization.d.ts +2 -1
  530. package/dist/ir/callback-specialization.js +23 -18
  531. package/dist/ir/callback-specialization.js.map +1 -1
  532. package/dist/ir/char-unit-locals.d.ts +19 -0
  533. package/dist/ir/char-unit-locals.js +185 -0
  534. package/dist/ir/char-unit-locals.js.map +1 -0
  535. package/dist/ir/char-unit-locals.test.d.ts +1 -0
  536. package/dist/ir/char-unit-locals.test.js +94 -0
  537. package/dist/ir/char-unit-locals.test.js.map +1 -0
  538. package/dist/ir/final-fields.d.ts +2 -1
  539. package/dist/ir/final-fields.js +14 -16
  540. package/dist/ir/final-fields.js.map +1 -1
  541. package/dist/ir/function-references.d.ts +2 -0
  542. package/dist/ir/function-references.js +2 -0
  543. package/dist/ir/function-references.js.map +1 -1
  544. package/dist/ir/function-references.test.js +3 -0
  545. package/dist/ir/function-references.test.js.map +1 -1
  546. package/dist/ir/initializer-bindings.d.ts +2 -1
  547. package/dist/ir/initializer-bindings.js +27 -20
  548. package/dist/ir/initializer-bindings.js.map +1 -1
  549. package/dist/ir/int32-arrays.d.ts +108 -0
  550. package/dist/ir/int32-arrays.js +831 -0
  551. package/dist/ir/int32-arrays.js.map +1 -0
  552. package/dist/ir/int32-slots.d.ts +24 -2
  553. package/dist/ir/int32-slots.js +259 -57
  554. package/dist/ir/int32-slots.js.map +1 -1
  555. package/dist/ir/integer-loops.d.ts +3 -3
  556. package/dist/ir/integer-loops.js +14 -6
  557. package/dist/ir/integer-loops.js.map +1 -1
  558. package/dist/ir/integer-loops.test.js +10 -0
  559. package/dist/ir/integer-loops.test.js.map +1 -1
  560. package/dist/ir/integer-ranges.d.ts +5 -0
  561. package/dist/ir/integer-ranges.js +125 -12
  562. package/dist/ir/integer-ranges.js.map +1 -1
  563. package/dist/ir/integer-ranges.test.js +30 -0
  564. package/dist/ir/integer-ranges.test.js.map +1 -1
  565. package/dist/ir/ir.d.ts +70 -7
  566. package/dist/ir/ir.js +58 -1
  567. package/dist/ir/ir.js.map +1 -1
  568. package/dist/ir/ir.test.js +21 -1
  569. package/dist/ir/ir.test.js.map +1 -1
  570. package/dist/ir/js-ic.d.ts +19 -2
  571. package/dist/ir/js-ic.js +95 -11
  572. package/dist/ir/js-ic.js.map +1 -1
  573. package/dist/ir/js-ic.test.js +188 -0
  574. package/dist/ir/js-ic.test.js.map +1 -1
  575. package/dist/ir/node-index.d.ts +57 -0
  576. package/dist/ir/node-index.js +215 -0
  577. package/dist/ir/node-index.js.map +1 -0
  578. package/dist/ir/paired-while-loops.d.ts +25 -0
  579. package/dist/ir/paired-while-loops.js +335 -0
  580. package/dist/ir/paired-while-loops.js.map +1 -0
  581. package/dist/ir/paired-while-loops.test.d.ts +1 -0
  582. package/dist/ir/paired-while-loops.test.js +163 -0
  583. package/dist/ir/paired-while-loops.test.js.map +1 -0
  584. package/dist/ir/parameter-versions.d.ts +25 -0
  585. package/dist/ir/parameter-versions.js +300 -0
  586. package/dist/ir/parameter-versions.js.map +1 -0
  587. package/dist/ir/runtime-features.d.ts +34 -13
  588. package/dist/ir/runtime-features.js +152 -38
  589. package/dist/ir/runtime-features.js.map +1 -1
  590. package/dist/ir/serialize.d.ts +12 -2
  591. package/dist/ir/serialize.js +16 -3
  592. package/dist/ir/serialize.js.map +1 -1
  593. package/dist/ir/serialize.test.js +17 -0
  594. package/dist/ir/serialize.test.js.map +1 -1
  595. package/dist/ir/traverse.js +18 -6
  596. package/dist/ir/traverse.js.map +1 -1
  597. package/dist/ir/validate.js +122 -36
  598. package/dist/ir/validate.js.map +1 -1
  599. package/dist/library/ir-policy.js +2 -0
  600. package/dist/library/ir-policy.js.map +1 -1
  601. package/dist/native/cache.d.ts +6 -1
  602. package/dist/native/cache.js +28 -5
  603. package/dist/native/cache.js.map +1 -1
  604. package/dist/native/cache.test.js +16 -2
  605. package/dist/native/cache.test.js.map +1 -1
  606. package/dist/native/cli.js +21 -1
  607. package/dist/native/cli.js.map +1 -1
  608. package/dist/native/compiler.js +8 -6
  609. package/dist/native/compiler.js.map +1 -1
  610. package/dist/native/executable-cache.d.ts +1 -1
  611. package/dist/native/executable-cache.js +2 -2
  612. package/dist/native/executable-cache.js.map +1 -1
  613. package/dist/native/prepare.d.ts +3 -1
  614. package/dist/native/prepare.js +119 -31
  615. package/dist/native/prepare.js.map +1 -1
  616. package/dist/native/prepare.test.js +78 -18
  617. package/dist/native/prepare.test.js.map +1 -1
  618. package/dist/native/sanitizer.test.js +2 -0
  619. package/dist/native/sanitizer.test.js.map +1 -1
  620. package/dist/native/text-file.d.ts +13 -3
  621. package/dist/native/text-file.js +63 -9
  622. package/dist/native/text-file.js.map +1 -1
  623. package/dist/native/text-file.test.d.ts +1 -0
  624. package/dist/native/text-file.test.js +49 -0
  625. package/dist/native/text-file.test.js.map +1 -0
  626. package/dist/native/toolchain.js +4 -4
  627. package/dist/native/toolchain.js.map +1 -1
  628. package/dist/native/toolchain.test.js +3 -3
  629. package/dist/native/toolchain.test.js.map +1 -1
  630. package/package.json +21 -21
  631. package/shims/chalk/v5.ts +688 -0
  632. package/shims/hono-node-server/v2.ts +645 -0
  633. package/shims/hot-shots/client.ts +1126 -0
  634. package/shims/hot-shots/v8-unix-dgram.ts +8 -0
  635. package/shims/hot-shots/v8.ts +8 -0
  636. package/surface-manifest.json +26 -4
@@ -0,0 +1,831 @@
1
+ import { exprFunctionReference, moduleFunctionReferences } from "./function-references.js";
2
+ import { F64 } from "./ir.js";
3
+ import { reparseExpr } from "./serialize.js";
4
+ import { everyExprChild, everyStmtChild, everyStmtList, mapExprChildren, mapStmtChildren, transformExpr, transformStmt, transformStmtList, } from "./traverse.js";
5
+ /** Number arrays the backend may store as int32 slots.
6
+ *
7
+ * A candidate is a `number[]` binding that only compiled element
8
+ * operations reach: a local of a synchronous function, a module global, or
9
+ * a parameter. Every write of a local or a global stores a fresh array (an
10
+ * array literal, or `new Array(n).fill(v)`); a parameter is never written.
11
+ * Every read of a candidate is the receiver of an element read, write,
12
+ * state test, `length`, `push` or `pop` (a discarded `pop` included), the
13
+ * array of an element-reader helper call, or the argument of a direct call
14
+ * whose parameter at that position is a candidate itself. A parameter is a
15
+ * candidate only when its function is reached by direct calls alone and
16
+ * every call passes a candidate there, so every binding that can hold one
17
+ * of these arrays is a candidate: the array never reaches a runtime
18
+ * function that reads its slots, a library call, a closure, a return or
19
+ * untyped code.
20
+ *
21
+ * Candidates are only proposed here. The int32 slot analysis
22
+ * (int32-slots.ts) keeps the ones whose every stored element is a proven
23
+ * int32 (never -0), assuming the candidates' own elements are int32s, at
24
+ * a fixpoint, and the LLVM backend stores those as SCR_ELEM_I32. It keeps
25
+ * the ones whose stores are exact integers but not all proven int32s as
26
+ * int32 arrays with checked stores: SCR_ELEM_I32 until a store that is not
27
+ * an int32 widens them to doubles in place. Their element-reader helper
28
+ * calls are inlined first (rewriteCandidates), so no shared helper ever
29
+ * receives an int32 array. */
30
+ /** The candidate key of the binding `localId` as `fnName` reads it:
31
+ * `function\0local` for a local or parameter, `\0global` for a module
32
+ * global (`%g.` ids), which every function reads alike. */
33
+ export function int32ArrayKey(fnName, localId) {
34
+ return localId.startsWith("%g.") ? `\0${localId}` : `${fnName}\0${localId}`;
35
+ }
36
+ /** The int32 element slot (int32-slots.ts) of a candidate key. */
37
+ export function int32ArraySlot(key) {
38
+ return key.startsWith("\0") ? `g:${key.slice(1)}` : `l:${key}`;
39
+ }
40
+ /** Array methods a candidate may be the receiver of: the runtime paths
41
+ * behind them read and write int32 slots through the double-valued slot
42
+ * accessors. */
43
+ export const INT32_ARRAY_METHODS = new Set([
44
+ "length",
45
+ "push",
46
+ "pop",
47
+ "getNumber",
48
+ ]);
49
+ /** An element-reader helper (`%arr.idxOr.*`): `(a, i) => a's state at i is
50
+ * a value ? the element : undefined`, as one returned ternary. */
51
+ export function isElementReader(fn) {
52
+ if (fn.params.length !== 2 || fn.body.length !== 1)
53
+ return false;
54
+ const [array, index] = fn.params;
55
+ const ret = fn.body[0];
56
+ if (array.type.kind !== "array" || array.type.elem.kind !== "f64")
57
+ return false;
58
+ if (index.type.kind !== "f64" || ret.kind !== "return" || ret.value?.kind !== "ternary")
59
+ return false;
60
+ const isParam = (e, id) => e.kind === "varRef" && e.localId === id;
61
+ const { cond, then, else_ } = ret.value;
62
+ return (cond.kind === "bin" &&
63
+ cond.op === "===" &&
64
+ cond.left.kind === "arrayState" &&
65
+ isParam(cond.left.arr, array.localId) &&
66
+ isParam(cond.left.index, index.localId) &&
67
+ cond.right.kind === "numLit" &&
68
+ cond.right.value === 1 &&
69
+ then.kind === "unionWrap" &&
70
+ then.value.kind === "arrayGet" &&
71
+ isParam(then.value.arr, array.localId) &&
72
+ isParam(then.value.index, index.localId) &&
73
+ else_.kind === "unionWrap" &&
74
+ else_.value.kind === "unitLit");
75
+ }
76
+ /** `new Array(n).fill(v)` as lowering spells it: `fill` over a sequence
77
+ * that declares a temporary empty array, sets its length and yields it. */
78
+ function fillAllocation(e) {
79
+ if (e.kind !== "arrIntrinsic" || e.method !== "fill" || e.receiver.kind !== "seqExpr")
80
+ return null;
81
+ const seq = e.receiver;
82
+ const [decl, length] = seq.stmts;
83
+ if (seq.stmts.length !== 2 ||
84
+ decl?.kind !== "varDecl" ||
85
+ decl.init?.kind !== "arrayLit" ||
86
+ decl.init.elems.length !== 0 ||
87
+ length?.kind !== "arraySetLength" ||
88
+ length.arr.kind !== "varRef" ||
89
+ length.arr.localId !== decl.localId ||
90
+ seq.result.kind !== "varRef" ||
91
+ seq.result.localId !== decl.localId)
92
+ return null;
93
+ return e;
94
+ }
95
+ /** Fill-form arrays shorter than this hold doubles even when they are int32
96
+ * arrays with checked stores: their doubles fit a typical 32 KiB L1 data
97
+ * cache, so 4-byte slots save no memory traffic. */
98
+ export const CHECKED_INT32_MIN_LENGTH = 4096;
99
+ /** The length `n` of `new Array(n).fill(v)`, or null for any other
100
+ * allocation. */
101
+ export function fillAllocationLength(e) {
102
+ const fill = fillAllocation(e);
103
+ if (!fill || fill.receiver.kind !== "seqExpr")
104
+ return null;
105
+ const set = fill.receiver.stmts[1];
106
+ return set.kind === "arraySetLength" ? set.length : null;
107
+ }
108
+ /** A number expression whose evaluation has no effect: locals, literals and
109
+ * arithmetic. */
110
+ function isPureLength(e) {
111
+ if (e.type.kind !== "f64")
112
+ return false;
113
+ switch (e.kind) {
114
+ case "numLit":
115
+ case "varRef":
116
+ return true;
117
+ case "bin":
118
+ return e.left.type.kind === "f64" && isPureLength(e.left) && isPureLength(e.right);
119
+ case "unary":
120
+ return isPureLength(e.operand);
121
+ default:
122
+ return false;
123
+ }
124
+ }
125
+ /** Whether the candidate `id` of `fn` may hold int32 slots with checked
126
+ * stores: every array it is assigned is the fill form, with a length that
127
+ * may reach CHECKED_INT32_MIN_LENGTH and evaluates without effects (the
128
+ * backend evaluates it once more to pick the new array's kind). */
129
+ export function checkableInt32Allocations(fn, id) {
130
+ let ok = true;
131
+ everyStmtList(fn.body, {
132
+ stmt: (s) => {
133
+ if ((s.kind === "varDecl" || s.kind === "assign") && s.localId === id) {
134
+ const value = s.kind === "varDecl" ? s.init : s.value;
135
+ const length = value ? fillAllocationLength(value) : null;
136
+ if (length === null ||
137
+ !isPureLength(length) ||
138
+ (length.kind === "numLit" && length.value < CHECKED_INT32_MIN_LENGTH))
139
+ ok = false;
140
+ }
141
+ return ok;
142
+ },
143
+ expr: () => ok,
144
+ });
145
+ return ok;
146
+ }
147
+ /** A fresh number array: a literal without spreads, or the fill form. */
148
+ export function int32ArrayAllocation(e) {
149
+ return (e.kind === "arrayLit" && (e.spreads?.length ?? 0) === 0) || fillAllocation(e) !== null;
150
+ }
151
+ /** The array literal a candidate's allocation builds (the literal itself,
152
+ * or the fill form's temporary's), and the fill form's temporary. */
153
+ export function allocatedLiteral(e) {
154
+ if (e.kind === "arrayLit")
155
+ return { literal: e, temporary: null };
156
+ const fill = fillAllocation(e);
157
+ if (!fill || fill.receiver.kind !== "seqExpr")
158
+ return null;
159
+ const decl = fill.receiver.stmts[0];
160
+ return decl.kind === "varDecl" && decl.init?.kind === "arrayLit"
161
+ ? { literal: decl.init, temporary: decl.localId }
162
+ : null;
163
+ }
164
+ /** `xs.pop()` whose value is unused, as lowering spells it: a sequence
165
+ * that binds the array to a hidden local, then only reads that local's
166
+ * length and truncates it with pop stores. Returns the hidden local and the
167
+ * array read it binds. */
168
+ function discardedPop(e) {
169
+ if (e.kind !== "seqExpr")
170
+ return null;
171
+ const [bind, ...rest] = e.stmts;
172
+ if (bind?.kind !== "varDecl" || bind.init?.kind !== "varRef")
173
+ return null;
174
+ const local = bind.localId;
175
+ const isLocal = (x) => x.kind === "varRef" && x.localId === local;
176
+ const expr = (x) => {
177
+ if (x.kind === "arrIntrinsic" && x.method === "length" && isLocal(x.receiver))
178
+ return true;
179
+ return !isLocal(x) && everyExprChild(x, expr, stmt);
180
+ };
181
+ const stmt = (x) => {
182
+ if (x.kind === "arraySetLength" && x.pop === true && isLocal(x.arr))
183
+ return expr(x.length);
184
+ return (!((x.kind === "varDecl" || x.kind === "assign") && x.localId === local) &&
185
+ everyStmtChild(x, expr, stmt));
186
+ };
187
+ return rest.every(stmt) && expr(e.result) ? { local, array: bind.init } : null;
188
+ }
189
+ /** Whether evaluating `e` may assign the local `id`. */
190
+ function writesLocal(e, id) {
191
+ const expr = (x) => !(x.kind === "assignExpr" && x.localId === id) && everyExprChild(x, expr, stmt);
192
+ const stmt = (x) => !((x.kind === "varDecl" || x.kind === "assign") && x.localId === id) &&
193
+ everyStmtChild(x, expr, stmt);
194
+ return !expr(e);
195
+ }
196
+ /** Expression kinds an index can be built from without running any code. */
197
+ const PURE_INDEX_KINDS = new Set([
198
+ "varRef",
199
+ "numLit",
200
+ "boolLit",
201
+ "bin",
202
+ "unary",
203
+ "ternary",
204
+ "logical",
205
+ "arrayGet",
206
+ "arrayState",
207
+ ]);
208
+ /** Whether evaluating an index runs no code (no call, accessor or
209
+ * conversion): plain reads, literals and their operators only. */
210
+ function pureIndex(e) {
211
+ return PURE_INDEX_KINDS.has(e.kind) && everyExprChild(e, pureIndex, () => false);
212
+ }
213
+ const NO_SHARED = {
214
+ params: new Set(),
215
+ globals: new Set(),
216
+ paramAt: () => false,
217
+ };
218
+ /** The candidates of `fn` (see the module comment): its own locals, its
219
+ * parameters in `shared.params`, and the globals of `shared.globals` that
220
+ * it reads only in candidate positions. `written` receives the globals it
221
+ * assigns fresh arrays. */
222
+ export function int32ArrayCandidates(fn, readers, shared = NO_SHARED, written = new Set()) {
223
+ const result = new Set();
224
+ if (fn.async || fn.generator) {
225
+ // Globals read here leave the candidates.
226
+ for (const id of shared.globals)
227
+ result.add(id);
228
+ everyStmtList(fn.body, {
229
+ expr: (e) => {
230
+ if ((e.kind === "varRef" || e.kind === "assignExpr") && result.has(e.localId))
231
+ result.delete(e.localId);
232
+ return true;
233
+ },
234
+ stmt: (s) => {
235
+ if ((s.kind === "varDecl" || s.kind === "assign") && result.has(s.localId))
236
+ result.delete(s.localId);
237
+ return true;
238
+ },
239
+ });
240
+ return result;
241
+ }
242
+ const captured = new Set([...(fn.captures ?? []), ...(fn.classCaptures ?? [])].map((c) => c.localId));
243
+ const params = new Set(fn.params.map((p) => p.localId));
244
+ for (const local of fn.locals)
245
+ if (local.type.kind === "array" &&
246
+ local.type.elem.kind === "f64" &&
247
+ !local.boxed &&
248
+ !local.tdz &&
249
+ !captured.has(local.id) &&
250
+ (!params.has(local.id) || shared.params.has(`${fn.name}\0${local.id}`)))
251
+ result.add(local.id);
252
+ for (const id of shared.globals)
253
+ result.add(id);
254
+ if (result.size === 0)
255
+ return result;
256
+ const allocated = new Set();
257
+ // A receiver position: the candidate is read there without escaping.
258
+ const receiver = (e) => {
259
+ if (e.kind !== "varRef")
260
+ expr(e);
261
+ };
262
+ const expr = (e) => {
263
+ switch (e.kind) {
264
+ case "varRef":
265
+ result.delete(e.localId);
266
+ return true;
267
+ case "assignExpr":
268
+ result.delete(e.localId);
269
+ break;
270
+ case "arrayGet":
271
+ case "arrayState":
272
+ case "arrayHas":
273
+ receiver(e.arr);
274
+ expr(e.index);
275
+ return true;
276
+ case "arrIntrinsic":
277
+ if (!INT32_ARRAY_METHODS.has(e.method))
278
+ break;
279
+ receiver(e.receiver);
280
+ e.args.forEach(expr);
281
+ return true;
282
+ case "seqExpr": {
283
+ // The pop's hidden local is the array itself; every use of it is a
284
+ // length read or a pop store.
285
+ const pop = discardedPop(e);
286
+ if (!pop)
287
+ break;
288
+ e.stmts.slice(1).every(stmt);
289
+ expr(e.result);
290
+ return true;
291
+ }
292
+ case "call": {
293
+ if (readers.has(e.callee) && e.args.length === 2) {
294
+ const [array, index] = e.args;
295
+ // Inlining evaluates the index before the array read: an index
296
+ // that rebinds the array keeps it out, and so does one that can run
297
+ // code when the array is a module global (a call can reassign it).
298
+ if (array.kind === "varRef" &&
299
+ (writesLocal(index, array.localId) ||
300
+ (array.localId.startsWith("%g.") && !pureIndex(index))))
301
+ result.delete(array.localId);
302
+ receiver(array);
303
+ expr(index);
304
+ return true;
305
+ }
306
+ // An argument at a candidate parameter position passes the array
307
+ // to another candidate binding (moduleInt32ArrayCandidates checks
308
+ // every such call).
309
+ e.args.forEach((arg, index) => {
310
+ if (shared.paramAt(e.callee, index))
311
+ receiver(arg);
312
+ else
313
+ expr(arg);
314
+ });
315
+ return true;
316
+ }
317
+ }
318
+ return everyExprChild(e, expr, stmt);
319
+ };
320
+ const stmt = (s) => {
321
+ switch (s.kind) {
322
+ case "varDecl":
323
+ case "assign": {
324
+ const value = s.kind === "varDecl" ? s.init : s.value;
325
+ if (params.has(s.localId))
326
+ result.delete(s.localId);
327
+ else if (value && int32ArrayAllocation(value))
328
+ allocated.add(s.localId);
329
+ else if (value)
330
+ result.delete(s.localId);
331
+ if (value)
332
+ expr(value);
333
+ return true;
334
+ }
335
+ case "arraySet":
336
+ receiver(s.arr);
337
+ expr(s.index);
338
+ expr(s.value);
339
+ return true;
340
+ case "arraySetUndefined":
341
+ // Stores a present undefined: a state, and a cleared (+0) slot.
342
+ receiver(s.arr);
343
+ expr(s.index);
344
+ return true;
345
+ case "forOf":
346
+ result.delete(s.localId);
347
+ break;
348
+ case "tryCatch":
349
+ if (s.catchLocalId)
350
+ result.delete(s.catchLocalId);
351
+ break;
352
+ }
353
+ return everyStmtChild(s, expr, stmt);
354
+ };
355
+ fn.body.every(stmt);
356
+ for (const id of result) {
357
+ if (shared.globals.has(id)) {
358
+ if (allocated.has(id))
359
+ written.add(id);
360
+ }
361
+ else if (!params.has(id) && !allocated.has(id))
362
+ result.delete(id);
363
+ }
364
+ return result;
365
+ }
366
+ /** The members of `ids` (none when absent) that are in `live`. */
367
+ function liveIn(ids, live) {
368
+ const result = new Set();
369
+ if (ids)
370
+ for (const id of ids)
371
+ if (live.has(id))
372
+ result.add(id);
373
+ return result;
374
+ }
375
+ /** The candidates of every function of `mod` that has any, only those
376
+ * whose keys are in `keep` when given. Parameters and globals are shared:
377
+ * starting from every one that may qualify, each pass drops the ones a
378
+ * function reads outside candidate positions, the parameters some call
379
+ * passes anything but a candidate, and the globals never assigned a fresh
380
+ * array, until a pass drops nothing. Functions in `redirected` keep their
381
+ * parameters: some of their calls reach another function. */
382
+ export function moduleInt32ArrayCandidates(mod, readers, keep = null, redirected = new Set()) {
383
+ const kept = (key) => keep === null || keep.has(key);
384
+ const arrayParams = new Map();
385
+ for (const fn of mod.functions) {
386
+ // Class methods, constructors and runtime helpers (`%` names) keep
387
+ // their parameters.
388
+ if (fn.name.startsWith("%") || fn.async || fn.generator || redirected.has(fn.name))
389
+ continue;
390
+ const indexes = [];
391
+ fn.params.forEach((p, i) => {
392
+ if (p.type.kind === "array" && p.type.elem.kind === "f64")
393
+ indexes.push(i);
394
+ });
395
+ if (indexes.length > 0)
396
+ arrayParams.set(fn.name, indexes);
397
+ }
398
+ let globals = new Set();
399
+ for (const g of mod.globals ?? [])
400
+ if (g.type.kind === "array" &&
401
+ g.type.elem.kind === "f64" &&
402
+ g.initFlag === undefined &&
403
+ kept(`\0${g.id}`))
404
+ globals.add(g.id);
405
+ const result = new Map();
406
+ if (arrayParams.size === 0 && globals.size === 0) {
407
+ for (const fn of mod.functions) {
408
+ const candidates = int32ArrayCandidates(fn, readers);
409
+ for (const id of candidates)
410
+ if (!kept(`${fn.name}\0${id}`))
411
+ candidates.delete(id);
412
+ if (candidates.size > 0)
413
+ result.set(fn.name, candidates);
414
+ }
415
+ return result;
416
+ }
417
+ // One walk: the functions reached other than by direct calls, the direct
418
+ // calls of functions with number[] parameters, the globals each function
419
+ // reads or writes, and whether a module namespace object exists (its
420
+ // member reads can reach any global by name).
421
+ const reached = new Set(moduleFunctionReferences(mod));
422
+ const calls = [];
423
+ const globalsIn = new Map();
424
+ let namespaces = false;
425
+ for (const fn of mod.functions) {
426
+ const used = new Set();
427
+ const note = (id) => {
428
+ if (globals.has(id))
429
+ used.add(id);
430
+ };
431
+ everyStmtList(fn.body, {
432
+ expr: (e) => {
433
+ const name = exprFunctionReference(e);
434
+ if (name !== undefined)
435
+ reached.add(name);
436
+ if (e.kind === "moduleNsRef")
437
+ namespaces = true;
438
+ if (e.kind === "call" && arrayParams.has(e.callee))
439
+ calls.push({ caller: fn.name, call: e });
440
+ if (e.kind === "varRef" || e.kind === "assignExpr")
441
+ note(e.localId);
442
+ return true;
443
+ },
444
+ stmt: (s) => {
445
+ if (s.kind === "varDecl" || s.kind === "assign")
446
+ note(s.localId);
447
+ return true;
448
+ },
449
+ });
450
+ if (used.size > 0)
451
+ globalsIn.set(fn.name, used);
452
+ }
453
+ if (namespaces) {
454
+ globals = new Set();
455
+ globalsIn.clear();
456
+ }
457
+ const paramIds = new Map();
458
+ let params = new Set();
459
+ for (const fn of mod.functions) {
460
+ const indexes = arrayParams.get(fn.name);
461
+ if (!indexes || reached.has(fn.name))
462
+ continue;
463
+ paramIds.set(fn.name, fn.params.map((p) => p.localId));
464
+ for (const i of indexes) {
465
+ const key = `${fn.name}\0${fn.params[i].localId}`;
466
+ if (kept(key))
467
+ params.add(key);
468
+ }
469
+ }
470
+ for (;;) {
471
+ const current = params;
472
+ const written = new Set();
473
+ const liveGlobals = new Set(globals);
474
+ result.clear();
475
+ for (const fn of mod.functions) {
476
+ const shared = {
477
+ params: current,
478
+ globals: liveIn(globalsIn.get(fn.name), globals),
479
+ paramAt: (callee, index) => {
480
+ const id = paramIds.get(callee)?.[index];
481
+ return id !== undefined && current.has(`${callee}\0${id}`);
482
+ },
483
+ };
484
+ const candidates = int32ArrayCandidates(fn, readers, shared, written);
485
+ for (const id of shared.globals)
486
+ if (!candidates.has(id))
487
+ liveGlobals.delete(id);
488
+ for (const id of candidates)
489
+ if (!shared.globals.has(id) && !kept(`${fn.name}\0${id}`))
490
+ candidates.delete(id);
491
+ if (candidates.size > 0)
492
+ result.set(fn.name, candidates);
493
+ }
494
+ for (const id of liveGlobals)
495
+ if (!written.has(id))
496
+ liveGlobals.delete(id);
497
+ const live = new Set([...current].filter((key) => {
498
+ const cut = key.indexOf("\0");
499
+ return result.get(key.slice(0, cut))?.has(key.slice(cut + 1)) === true;
500
+ }));
501
+ // A parameter needs a candidate at that position of every call; a call
502
+ // with fewer arguments passes undefined.
503
+ for (const { caller, call } of calls) {
504
+ const ids = paramIds.get(call.callee);
505
+ if (!ids)
506
+ continue;
507
+ ids.forEach((id, i) => {
508
+ const key = `${call.callee}\0${id}`;
509
+ if (!live.has(key))
510
+ return;
511
+ const arg = call.args[i];
512
+ const ok = arg?.kind === "varRef" &&
513
+ (arg.localId.startsWith("%g.")
514
+ ? liveGlobals.has(arg.localId)
515
+ : result.get(caller)?.has(arg.localId) === true);
516
+ if (!ok)
517
+ live.delete(key);
518
+ });
519
+ }
520
+ if (live.size === current.size && liveGlobals.size === globals.size)
521
+ break;
522
+ params = live;
523
+ globals = liveGlobals;
524
+ }
525
+ return result;
526
+ }
527
+ /** The candidates one array can reach together: a direct call's argument
528
+ * and the parameter it binds hold the same array, so their element facts
529
+ * stand or fall together. `group` maps each of `keys` to its group's keys
530
+ * (itself alone for most), and `globalReaders` each candidate global's
531
+ * key to the functions that read or write it. */
532
+ export function int32ArrayGroups(mod, keys) {
533
+ const parent = new Map();
534
+ const root = (key) => {
535
+ let r = key;
536
+ while (parent.has(r))
537
+ r = parent.get(r);
538
+ if (r !== key)
539
+ parent.set(key, r);
540
+ return r;
541
+ };
542
+ const globalReaders = new Map();
543
+ const params = new Map(mod.functions.map((fn) => [fn.name, fn.params]));
544
+ const paramKeys = new Set(mod.functions.flatMap((fn) => fn.params.map((p) => `${fn.name}\0${p.localId}`)));
545
+ if ([...keys].some((key) => key.startsWith("\0") || paramKeys.has(key))) {
546
+ for (const fn of mod.functions) {
547
+ const touch = (id) => {
548
+ const key = int32ArrayKey(fn.name, id);
549
+ if (!key.startsWith("\0") || !keys.has(key))
550
+ return;
551
+ const set = globalReaders.get(key) ?? new Set();
552
+ set.add(fn.name);
553
+ globalReaders.set(key, set);
554
+ };
555
+ everyStmtList(fn.body, {
556
+ expr: (e) => {
557
+ if (e.kind === "varRef" || e.kind === "assignExpr")
558
+ touch(e.localId);
559
+ if (e.kind === "call")
560
+ e.args.forEach((arg, i) => {
561
+ const param = params.get(e.callee)?.[i];
562
+ if (arg.kind !== "varRef" || !param)
563
+ return;
564
+ const a = int32ArrayKey(fn.name, arg.localId), p = `${e.callee}\0${param.localId}`;
565
+ if (!keys.has(a) || !keys.has(p))
566
+ return;
567
+ const ra = root(a), rp = root(p);
568
+ if (ra !== rp)
569
+ parent.set(ra, rp);
570
+ });
571
+ return true;
572
+ },
573
+ stmt: (s) => {
574
+ if (s.kind === "varDecl" || s.kind === "assign")
575
+ touch(s.localId);
576
+ return true;
577
+ },
578
+ });
579
+ }
580
+ }
581
+ const members = new Map();
582
+ for (const key of keys) {
583
+ const r = root(key);
584
+ const list = members.get(r);
585
+ if (list)
586
+ list.push(key);
587
+ else
588
+ members.set(r, [key]);
589
+ }
590
+ const group = new Map();
591
+ for (const key of keys)
592
+ group.set(key, members.get(root(key)));
593
+ return { group, globalReaders };
594
+ }
595
+ /** The element values stored into each candidate: element writes, pushed
596
+ * values, literal elements and fill values. */
597
+ export function int32ArrayStores(fn, candidates) {
598
+ const stores = new Map();
599
+ const add = (id, value) => {
600
+ const list = stores.get(id);
601
+ if (list)
602
+ list.push(value);
603
+ else
604
+ stores.set(id, [value]);
605
+ };
606
+ const target = (e) => e.kind === "varRef" && candidates.has(e.localId) ? e.localId : null;
607
+ const expr = (e) => {
608
+ if (e.kind === "arrIntrinsic" && e.method === "push") {
609
+ const id = target(e.receiver);
610
+ if (id !== null)
611
+ for (const arg of e.args)
612
+ add(id, arg);
613
+ }
614
+ return everyExprChild(e, expr, stmt);
615
+ };
616
+ const stmt = (s) => {
617
+ if ((s.kind === "varDecl" || s.kind === "assign") && candidates.has(s.localId)) {
618
+ const value = s.kind === "varDecl" ? s.init : s.value;
619
+ if (value?.kind === "arrayLit")
620
+ for (const el of value.elems)
621
+ add(s.localId, el);
622
+ else if (value) {
623
+ const fill = fillAllocation(value);
624
+ if (fill)
625
+ add(s.localId, fill.args[0]);
626
+ }
627
+ }
628
+ if (s.kind === "arraySet") {
629
+ const id = target(s.arr);
630
+ if (id !== null)
631
+ add(id, s.value);
632
+ }
633
+ return everyStmtChild(s, expr, stmt);
634
+ };
635
+ fn.body.every(stmt);
636
+ return stores;
637
+ }
638
+ const REPEATED_INDEX_OPS = new Set(["+", "-", "*", "&", "|", "^", "<<", ">>", ">>>"]);
639
+ /** An index the inlined read may evaluate at each of its uses: a plain read,
640
+ * a literal, or integer arithmetic over them. Repeating it keeps the forms
641
+ * the backend derives from its operands at every use, such as the exact i64
642
+ * of an int32 product, where a bound local holds only the double. */
643
+ function repeatableIndex(e) {
644
+ if (e.kind === "varRef" || e.kind === "numLit")
645
+ return true;
646
+ if (e.kind === "unary")
647
+ return e.op === "-" && repeatableIndex(e.operand);
648
+ return (e.kind === "bin" &&
649
+ REPEATED_INDEX_OPS.has(e.op) &&
650
+ repeatableIndex(e.left) &&
651
+ repeatableIndex(e.right));
652
+ }
653
+ /** Rewrite a function's candidates for the backend. A discarded pop uses
654
+ * the candidate in place of its hidden local. An element-reader helper call
655
+ * whose array is a candidate is inlined: the helper's returned ternary, with
656
+ * the candidate for its array and the index for its index, so the read means
657
+ * the same. An index that is not repeatable (repeatableIndex) is bound to a
658
+ * fresh local first: in its own declaration just before the statement when
659
+ * the call is the whole value of a declaration or assignment (the form
660
+ * lowering gives `a[i]!`, and the one the backend reads without a box),
661
+ * otherwise in a sequence around the ternary. Selection keeps out indexes
662
+ * that write the array, so evaluating the index before the array read is
663
+ * unobservable. */
664
+ function rewriteCandidates(fn, candidates, readers) {
665
+ const locals = [...fn.locals];
666
+ let fresh = 0;
667
+ const bind = (index) => {
668
+ const id = `%int32.read.${fresh++}`;
669
+ locals.push({ id, name: id, type: F64, mutable: false });
670
+ return {
671
+ decl: { kind: "varDecl", localId: id, init: index, loc: index.loc },
672
+ ref: { kind: "varRef", localId: id, type: F64, loc: index.loc },
673
+ };
674
+ };
675
+ const readerCall = (e) => e?.kind === "call" &&
676
+ e.args.length === 2 &&
677
+ readers.has(e.callee) &&
678
+ e.args[0].kind === "varRef" &&
679
+ candidates.has(e.args[0].localId)
680
+ ? e
681
+ : null;
682
+ // The statements of a list, with complex read indexes declared first.
683
+ const hoist = (list) => list.flatMap((s) => {
684
+ if (s.kind !== "varDecl" && s.kind !== "assign")
685
+ return [s];
686
+ const value = s.kind === "varDecl" ? s.init : s.value;
687
+ const call = readerCall(value);
688
+ if (!call || repeatableIndex(call.args[1]))
689
+ return [s];
690
+ const { decl, ref } = bind(call.args[1]);
691
+ const read = { ...call, args: [call.args[0], ref] };
692
+ if (s.kind === "varDecl")
693
+ return [decl, { ...s, init: read }];
694
+ return [decl, { ...s, value: read }];
695
+ });
696
+ const hoistCase = (c) => ({ ...c, body: hoist(c.body) });
697
+ const lists = (s) => {
698
+ switch (s.kind) {
699
+ case "if":
700
+ return { ...s, then: hoist(s.then), else_: s.else_ === null ? null : hoist(s.else_) };
701
+ case "block":
702
+ return { ...s, body: hoist(s.body) };
703
+ case "while":
704
+ return { ...s, body: hoist(s.body) };
705
+ case "doWhile":
706
+ return { ...s, body: hoist(s.body) };
707
+ case "for":
708
+ return { ...s, body: hoist(s.body) };
709
+ case "forOf":
710
+ return { ...s, body: hoist(s.body) };
711
+ case "switch":
712
+ return { ...s, cases: s.cases.map((c) => hoistCase(c)) };
713
+ case "tryCatch":
714
+ return {
715
+ ...s,
716
+ tryBody: hoist(s.tryBody),
717
+ catchBody: s.catchBody === null ? null : hoist(s.catchBody),
718
+ finallyBody: s.finallyBody === null ? null : hoist(s.finallyBody),
719
+ };
720
+ }
721
+ return s;
722
+ };
723
+ // Hidden pop locals replaced by their candidate array.
724
+ const popLocals = new Set();
725
+ const rewrite = (e) => {
726
+ const pop = discardedPop(e);
727
+ if (e.kind === "seqExpr" && pop && candidates.has(pop.array.localId)) {
728
+ popLocals.add(pop.local);
729
+ const array = pop.array;
730
+ const substitute = {
731
+ expr: (x) => x.kind === "varRef" && x.localId === pop.local ? { ...array, loc: x.loc } : x,
732
+ stmt: (x) => x,
733
+ };
734
+ return {
735
+ ...e,
736
+ stmts: e.stmts.slice(1).map((x) => transformStmt(x, substitute)),
737
+ result: transformExpr(e.result, substitute),
738
+ };
739
+ }
740
+ const call = readerCall(e);
741
+ if (!call) {
742
+ if (e.kind === "seqExpr")
743
+ return { ...e, stmts: hoist(e.stmts) };
744
+ return e;
745
+ }
746
+ const helper = readers.get(call.callee);
747
+ const array = call.args[0];
748
+ const [arrayParam, indexParam] = helper.params;
749
+ const ret = helper.body[0];
750
+ if (ret.kind !== "return" || !ret.value)
751
+ return e;
752
+ let index = call.args[1];
753
+ const stmts = [];
754
+ if (!repeatableIndex(index)) {
755
+ const { decl, ref } = bind(index);
756
+ stmts.push(decl);
757
+ index = ref;
758
+ }
759
+ const operand = index;
760
+ // The arguments' copies are not searched again: an index may read a
761
+ // local that has the id of one of the helper's parameters.
762
+ const substituteExpr = (x) => {
763
+ if (x.kind !== "varRef")
764
+ return mapExprChildren(x, substituteExpr, substituteStmt);
765
+ if (x.localId === arrayParam.localId)
766
+ return reparseExpr(array);
767
+ if (x.localId === indexParam.localId)
768
+ return reparseExpr(operand);
769
+ return x;
770
+ };
771
+ const substituteStmt = (x) => mapStmtChildren(x, substituteExpr, substituteStmt);
772
+ const body = substituteExpr(reparseExpr(ret.value));
773
+ // The ternary is a fresh copy (reparseExpr): it takes the call's location.
774
+ const typed = body;
775
+ typed.loc = e.loc;
776
+ return stmts.length === 0
777
+ ? typed
778
+ : { kind: "seqExpr", stmts, result: typed, type: typed.type, loc: e.loc };
779
+ };
780
+ const body = transformStmtList(hoist(fn.body), { expr: rewrite, stmt: lists });
781
+ if (fresh === 0 && popLocals.size === 0)
782
+ return { ...fn, body };
783
+ return { ...fn, body, locals: locals.filter((local) => !popLocals.has(local.id)) };
784
+ }
785
+ /** Propose the module's int32 array candidates (int32ArrayKey keys in
786
+ * `int32ArrayCandidates`), only those in `keep` when given, and rewrite
787
+ * their functions. */
788
+ export function markInt32ArrayCandidates(mod, keep = null, redirected = new Set()) {
789
+ if (mod.lib !== undefined)
790
+ return mod;
791
+ const readers = new Map();
792
+ for (const fn of mod.functions)
793
+ if (isElementReader(fn))
794
+ readers.set(fn.name, fn);
795
+ const all = moduleInt32ArrayCandidates(mod, new Set(readers.keys()), keep, redirected);
796
+ if (all.size === 0)
797
+ return mod;
798
+ const keys = new Set();
799
+ const functions = mod.functions.map((fn) => {
800
+ const candidates = all.get(fn.name);
801
+ if (!candidates)
802
+ return fn;
803
+ for (const id of candidates)
804
+ keys.add(int32ArrayKey(fn.name, id));
805
+ return rewriteCandidates(fn, candidates, readers);
806
+ });
807
+ return { ...mod, functions, int32ArrayCandidates: [...keys] };
808
+ }
809
+ /** The module the backend emits: rewritten for exactly the candidates the
810
+ * int32 slot analysis (`prove`, returning its int32Arrays) keeps, so a
811
+ * module without int32 arrays is `mod` itself. A dropped candidate's
812
+ * rewrite is undone by marking again without it, until every candidate
813
+ * marked is kept. `redirected` names the functions some of whose calls the
814
+ * backend emits as calls of another function (a result-slot entry): their
815
+ * parameters keep doubles. */
816
+ export function selectInt32Arrays(mod, prove, redirected = () => new Set()) {
817
+ let keep = null;
818
+ const others = redirected(mod);
819
+ for (let round = 0; round < 4; round++) {
820
+ const marked = markInt32ArrayCandidates(mod, keep, others);
821
+ if (marked === mod)
822
+ return mod;
823
+ const kept = prove(marked);
824
+ const proposed = marked.int32ArrayCandidates ?? [];
825
+ if (proposed.every((key) => kept.has(key)))
826
+ return marked;
827
+ keep = new Set(proposed.filter((key) => kept.has(key)));
828
+ }
829
+ return mod;
830
+ }
831
+ //# sourceMappingURL=int32-arrays.js.map