@scriptc/compiler 0.4.2 → 0.4.4

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 (726) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +470 -66
  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 +479 -32
  38. package/dist/backend/llvm/bytes-loop-versions.js.map +1 -1
  39. package/dist/backend/llvm/bytes-loop-versions.test.js +263 -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/debug-info.js +2 -5
  58. package/dist/backend/llvm/debug-info.js.map +1 -1
  59. package/dist/backend/llvm/dense-array-access.d.ts +39 -8
  60. package/dist/backend/llvm/dense-array-access.js +222 -52
  61. package/dist/backend/llvm/dense-array-access.js.map +1 -1
  62. package/dist/backend/llvm/dense-array-access.test.js +36 -0
  63. package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
  64. package/dist/backend/llvm/dense-array-loops.d.ts +17 -1
  65. package/dist/backend/llvm/dense-array-loops.js +194 -5
  66. package/dist/backend/llvm/dense-array-loops.js.map +1 -1
  67. package/dist/backend/llvm/dense-array-loops.test.js +90 -1
  68. package/dist/backend/llvm/dense-array-loops.test.js.map +1 -1
  69. package/dist/backend/llvm/dyn-handle-tags.test.js +6 -1
  70. package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -1
  71. package/dist/backend/llvm/dyn.d.ts +30 -0
  72. package/dist/backend/llvm/dyn.js +373 -70
  73. package/dist/backend/llvm/dyn.js.map +1 -1
  74. package/dist/backend/llvm/emit-function.js +13 -28
  75. package/dist/backend/llvm/emit-function.js.map +1 -1
  76. package/dist/backend/llvm/emit-journal.d.ts +93 -0
  77. package/dist/backend/llvm/emit-journal.js +170 -0
  78. package/dist/backend/llvm/emit-journal.js.map +1 -0
  79. package/dist/backend/llvm/emit-module.js +211 -33
  80. package/dist/backend/llvm/emit-module.js.map +1 -1
  81. package/dist/backend/llvm/emit-statements.d.ts +0 -4
  82. package/dist/backend/llvm/emit-statements.js +268 -84
  83. package/dist/backend/llvm/emit-statements.js.map +1 -1
  84. package/dist/backend/llvm/emitter-state.d.ts +7 -0
  85. package/dist/backend/llvm/emitter-state.js +14 -0
  86. package/dist/backend/llvm/emitter-state.js.map +1 -0
  87. package/dist/backend/llvm/emitter.d.ts +186 -37
  88. package/dist/backend/llvm/emitter.js +733 -90
  89. package/dist/backend/llvm/emitter.js.map +1 -1
  90. package/dist/backend/llvm/emitter.test.js +65 -7
  91. package/dist/backend/llvm/emitter.test.js.map +1 -1
  92. package/dist/backend/llvm/expr-async.js +11 -13
  93. package/dist/backend/llvm/expr-async.js.map +1 -1
  94. package/dist/backend/llvm/expr-bytes.js +48 -20
  95. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  96. package/dist/backend/llvm/expr-callbacks.js +47 -0
  97. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  98. package/dist/backend/llvm/expr-calls.js +28 -14
  99. package/dist/backend/llvm/expr-calls.js.map +1 -1
  100. package/dist/backend/llvm/expr-containers.d.ts +14 -2
  101. package/dist/backend/llvm/expr-containers.js +143 -37
  102. package/dist/backend/llvm/expr-containers.js.map +1 -1
  103. package/dist/backend/llvm/expr-context.d.ts +14 -0
  104. package/dist/backend/llvm/expr-dynamic.js +18 -11
  105. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  106. package/dist/backend/llvm/expr-primitives.js +119 -38
  107. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  108. package/dist/backend/llvm/expr-primitives.test.js +11 -6
  109. package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
  110. package/dist/backend/llvm/expr-records.d.ts +12 -0
  111. package/dist/backend/llvm/expr-records.js +106 -0
  112. package/dist/backend/llvm/expr-records.js.map +1 -1
  113. package/dist/backend/llvm/expr-stream-bridges.d.ts +2 -2
  114. package/dist/backend/llvm/expr-stream-bridges.js +210 -69
  115. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  116. package/dist/backend/llvm/expr-stream-bridges.test.js +1 -1
  117. package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -1
  118. package/dist/backend/llvm/expr-stream-callbacks.d.ts +2 -2
  119. package/dist/backend/llvm/expr-stream-callbacks.js +74 -20
  120. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  121. package/dist/backend/llvm/int32-kind-loops.d.ts +39 -0
  122. package/dist/backend/llvm/int32-kind-loops.js +106 -0
  123. package/dist/backend/llvm/int32-kind-loops.js.map +1 -0
  124. package/dist/backend/llvm/integer-or-nan-indexes.test.d.ts +1 -0
  125. package/dist/backend/llvm/integer-or-nan-indexes.test.js +118 -0
  126. package/dist/backend/llvm/integer-or-nan-indexes.test.js.map +1 -0
  127. package/dist/backend/llvm/integer-values.d.ts +25 -1
  128. package/dist/backend/llvm/integer-values.js +95 -0
  129. package/dist/backend/llvm/integer-values.js.map +1 -1
  130. package/dist/backend/llvm/js-ic.d.ts +1 -1
  131. package/dist/backend/llvm/js-ic.js +1 -1
  132. package/dist/backend/llvm/js-ic.js.map +1 -1
  133. package/dist/backend/llvm/key-orders.d.ts +7 -0
  134. package/dist/backend/llvm/key-orders.js +33 -0
  135. package/dist/backend/llvm/key-orders.js.map +1 -0
  136. package/dist/backend/llvm/lib-connect.js +4 -0
  137. package/dist/backend/llvm/lib-connect.js.map +1 -1
  138. package/dist/backend/llvm/lib-datagram.js +11 -0
  139. package/dist/backend/llvm/lib-datagram.js.map +1 -1
  140. package/dist/backend/llvm/lib-dispatch.js +213 -5
  141. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  142. package/dist/backend/llvm/lib-filesystem.js +4 -4
  143. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  144. package/dist/backend/llvm/lib-http2.js +4 -0
  145. package/dist/backend/llvm/lib-http2.js.map +1 -1
  146. package/dist/backend/llvm/lib-lookup.js +16 -6
  147. package/dist/backend/llvm/lib-lookup.js.map +1 -1
  148. package/dist/backend/llvm/lib-process.js +37 -1
  149. package/dist/backend/llvm/lib-process.js.map +1 -1
  150. package/dist/backend/llvm/lib-shared.js +94 -2
  151. package/dist/backend/llvm/lib-shared.js.map +1 -1
  152. package/dist/backend/llvm/lib-stream.js +35 -5
  153. package/dist/backend/llvm/lib-stream.js.map +1 -1
  154. package/dist/backend/llvm/local-array-reads.js +115 -19
  155. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  156. package/dist/backend/llvm/local-array-reads.test.js +14 -0
  157. package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
  158. package/dist/backend/llvm/loop-state.d.ts +33 -0
  159. package/dist/backend/llvm/loop-state.js +42 -0
  160. package/dist/backend/llvm/loop-state.js.map +1 -0
  161. package/dist/backend/llvm/map-number-lookup.d.ts +26 -8
  162. package/dist/backend/llvm/map-number-lookup.js +91 -31
  163. package/dist/backend/llvm/map-number-lookup.js.map +1 -1
  164. package/dist/backend/llvm/map-number-lookup.test.js +55 -0
  165. package/dist/backend/llvm/map-number-lookup.test.js.map +1 -1
  166. package/dist/backend/llvm/map-read-lifetimes.js +4 -2
  167. package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
  168. package/dist/backend/llvm/nullable-unions.d.ts +2 -1
  169. package/dist/backend/llvm/nullable-unions.js +15 -3
  170. package/dist/backend/llvm/nullable-unions.js.map +1 -1
  171. package/dist/backend/llvm/publish.d.ts +10 -0
  172. package/dist/backend/llvm/publish.js +15 -3
  173. package/dist/backend/llvm/publish.js.map +1 -1
  174. package/dist/backend/llvm/receivers.js +6 -1
  175. package/dist/backend/llvm/receivers.js.map +1 -1
  176. package/dist/backend/llvm/record-results.d.ts +1 -9
  177. package/dist/backend/llvm/record-results.js +2 -11
  178. package/dist/backend/llvm/record-results.js.map +1 -1
  179. package/dist/backend/llvm/reference-effects.js +3 -0
  180. package/dist/backend/llvm/reference-effects.js.map +1 -1
  181. package/dist/backend/llvm/reference-writes.d.ts +7 -2
  182. package/dist/backend/llvm/reference-writes.js +89 -72
  183. package/dist/backend/llvm/reference-writes.js.map +1 -1
  184. package/dist/backend/llvm/running-extrema.d.ts +11 -0
  185. package/dist/backend/llvm/running-extrema.js +115 -0
  186. package/dist/backend/llvm/running-extrema.js.map +1 -0
  187. package/dist/backend/llvm/running-extrema.test.d.ts +1 -0
  188. package/dist/backend/llvm/running-extrema.test.js +89 -0
  189. package/dist/backend/llvm/running-extrema.test.js.map +1 -0
  190. package/dist/backend/llvm/shapes.d.ts +71 -15
  191. package/dist/backend/llvm/shapes.js +224 -40
  192. package/dist/backend/llvm/shapes.js.map +1 -1
  193. package/dist/backend/llvm/shapes.test.js +53 -7
  194. package/dist/backend/llvm/shapes.test.js.map +1 -1
  195. package/dist/backend/llvm/speculative-integers.d.ts +6 -0
  196. package/dist/backend/llvm/speculative-integers.js +2 -2
  197. package/dist/backend/llvm/speculative-integers.js.map +1 -1
  198. package/dist/backend/llvm/stack-captures.js +1 -5
  199. package/dist/backend/llvm/stack-captures.js.map +1 -1
  200. package/dist/backend/llvm/stack-objects.d.ts +3 -2
  201. package/dist/backend/llvm/stack-objects.js +5 -2
  202. package/dist/backend/llvm/stack-objects.js.map +1 -1
  203. package/dist/backend/llvm/string-reads.d.ts +12 -0
  204. package/dist/backend/llvm/string-reads.js +44 -0
  205. package/dist/backend/llvm/string-reads.js.map +1 -1
  206. package/dist/backend/llvm/union-repr.d.ts +4 -3
  207. package/dist/backend/llvm/union-repr.js +6 -5
  208. package/dist/backend/llvm/union-repr.js.map +1 -1
  209. package/dist/backend/llvm/walk-borrows.d.ts +3 -0
  210. package/dist/backend/llvm/walk-borrows.js +46 -41
  211. package/dist/backend/llvm/walk-borrows.js.map +1 -1
  212. package/dist/backend/llvm/walkers.d.ts +3 -0
  213. package/dist/backend/llvm/walkers.js +101 -65
  214. package/dist/backend/llvm/walkers.js.map +1 -1
  215. package/dist/backend/llvm/wrapping-sums.d.ts +16 -1
  216. package/dist/backend/llvm/wrapping-sums.js +126 -0
  217. package/dist/backend/llvm/wrapping-sums.js.map +1 -1
  218. package/dist/backend/may-throw.d.ts +8 -10
  219. package/dist/backend/may-throw.js +14 -10
  220. package/dist/backend/may-throw.js.map +1 -1
  221. package/dist/backend/native/contracts.d.ts +5 -0
  222. package/dist/backend/native/executable.js +7 -0
  223. package/dist/backend/native/executable.js.map +1 -1
  224. package/dist/backend/native/runtime-inputs.d.ts +1 -1
  225. package/dist/backend/native/runtime-inputs.js +1 -0
  226. package/dist/backend/native/runtime-inputs.js.map +1 -1
  227. package/dist/backend/native-codegen-core.d.ts +5 -3
  228. package/dist/backend/native-codegen-core.js +13 -6
  229. package/dist/backend/native-codegen-core.js.map +1 -1
  230. package/dist/backend/native-codegen.test.js +6 -4
  231. package/dist/backend/native-codegen.test.js.map +1 -1
  232. package/dist/backend/native-link-info-core.d.ts +4 -0
  233. package/dist/backend/native-link-info-core.js.map +1 -1
  234. package/dist/backend/publication.d.ts +12 -1
  235. package/dist/backend/publication.js +37 -14
  236. package/dist/backend/publication.js.map +1 -1
  237. package/dist/backend/publication.test.js +30 -0
  238. package/dist/backend/publication.test.js.map +1 -1
  239. package/dist/backend/result-slots.d.ts +16 -0
  240. package/dist/backend/result-slots.js +23 -0
  241. package/dist/backend/result-slots.js.map +1 -0
  242. package/dist/backend/runtime-abi.d.ts +2 -2
  243. package/dist/backend/runtime-abi.js +2 -2
  244. package/dist/backend/runtime-pack-core.d.ts +1 -0
  245. package/dist/backend/runtime-pack-core.js +1 -0
  246. package/dist/backend/runtime-pack-core.js.map +1 -1
  247. package/dist/backend/runtime-pack-targets.test.js +2 -1
  248. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  249. package/dist/backend/runtime-pack.test.js +2 -1
  250. package/dist/backend/runtime-pack.test.js.map +1 -1
  251. package/dist/backend/stack-observations.d.ts +2 -1
  252. package/dist/backend/stack-observations.js +67 -42
  253. package/dist/backend/stack-observations.js.map +1 -1
  254. package/dist/backend/target-cpu.d.ts +26 -0
  255. package/dist/backend/target-cpu.js +98 -0
  256. package/dist/backend/target-cpu.js.map +1 -0
  257. package/dist/backend/target-cpu.test.d.ts +1 -0
  258. package/dist/backend/target-cpu.test.js +38 -0
  259. package/dist/backend/target-cpu.test.js.map +1 -0
  260. package/dist/backend/target-diagnostics.js +5 -3
  261. package/dist/backend/target-diagnostics.js.map +1 -1
  262. package/dist/backend/warm-cache.js +1 -0
  263. package/dist/backend/warm-cache.js.map +1 -1
  264. package/dist/cli/command.js +20 -1
  265. package/dist/cli/command.js.map +1 -1
  266. package/dist/cli/usage.d.ts +4 -1
  267. package/dist/cli/usage.js +10 -3
  268. package/dist/cli/usage.js.map +1 -1
  269. package/dist/compat/fetch-profile.js +1 -1
  270. package/dist/compat/fetch-profile.js.map +1 -1
  271. package/dist/compile-types.d.ts +7 -0
  272. package/dist/contracts/check.js +4 -3
  273. package/dist/contracts/check.js.map +1 -1
  274. package/dist/contracts/int32-elements.js +10 -2
  275. package/dist/contracts/int32-elements.js.map +1 -1
  276. package/dist/coverage/report.js +12 -3
  277. package/dist/coverage/report.js.map +1 -1
  278. package/dist/diagnostics/diagnostic.d.ts +4 -0
  279. package/dist/diagnostics/diagnostic.js +1 -1
  280. package/dist/diagnostics/diagnostic.js.map +1 -1
  281. package/dist/diagnostics/envelope.d.ts +3 -0
  282. package/dist/diagnostics/envelope.js +1 -0
  283. package/dist/diagnostics/envelope.js.map +1 -1
  284. package/dist/executable/executable-cache.d.ts +5 -0
  285. package/dist/executable/executable-cache.js +5 -0
  286. package/dist/executable/executable-cache.js.map +1 -1
  287. package/dist/executable/executable-cache.test.js +3 -0
  288. package/dist/executable/executable-cache.test.js.map +1 -1
  289. package/dist/frontend/decl-projection.d.ts +41 -0
  290. package/dist/frontend/decl-projection.js +949 -0
  291. package/dist/frontend/decl-projection.js.map +1 -0
  292. package/dist/frontend/decl-projection.test.d.ts +1 -0
  293. package/dist/frontend/decl-projection.test.js +30 -0
  294. package/dist/frontend/decl-projection.test.js.map +1 -0
  295. package/dist/frontend/dts-paths.d.ts +15 -0
  296. package/dist/frontend/dts-paths.js +25 -0
  297. package/dist/frontend/dts-paths.js.map +1 -1
  298. package/dist/frontend/input-tracker.d.ts +6 -0
  299. package/dist/frontend/input-tracker.js +51 -28
  300. package/dist/frontend/input-tracker.js.map +1 -1
  301. package/dist/frontend/input-tracker.test.js +19 -0
  302. package/dist/frontend/input-tracker.test.js.map +1 -1
  303. package/dist/frontend/lowering/array-values.js +100 -2
  304. package/dist/frontend/lowering/array-values.js.map +1 -1
  305. package/dist/frontend/lowering/builtins/async-context.d.ts +8 -2
  306. package/dist/frontend/lowering/builtins/async-context.js +62 -3
  307. package/dist/frontend/lowering/builtins/async-context.js.map +1 -1
  308. package/dist/frontend/lowering/builtins/child-process-methods.js +46 -15
  309. package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
  310. package/dist/frontend/lowering/builtins/child-process.js +13 -2
  311. package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
  312. package/dist/frontend/lowering/builtins/crypto.js +87 -10
  313. package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
  314. package/dist/frontend/lowering/builtins/dates.js +4 -1
  315. package/dist/frontend/lowering/builtins/dates.js.map +1 -1
  316. package/dist/frontend/lowering/builtins/filesystem-calls.js +3 -3
  317. package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
  318. package/dist/frontend/lowering/builtins/fs-glob.js +6 -3
  319. package/dist/frontend/lowering/builtins/fs-glob.js.map +1 -1
  320. package/dist/frontend/lowering/builtins/fs-paths.d.ts +43 -5
  321. package/dist/frontend/lowering/builtins/fs-paths.js +245 -93
  322. package/dist/frontend/lowering/builtins/fs-paths.js.map +1 -1
  323. package/dist/frontend/lowering/builtins/global-namespace-keys.d.ts +3 -0
  324. package/dist/frontend/lowering/builtins/global-namespace-keys.js +122 -0
  325. package/dist/frontend/lowering/builtins/global-namespace-keys.js.map +1 -0
  326. package/dist/frontend/lowering/builtins/module-calls.js +6 -3
  327. package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
  328. package/dist/frontend/lowering/builtins/numbers.js +9 -1
  329. package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
  330. package/dist/frontend/lowering/builtins/promises.d.ts +7 -1
  331. package/dist/frontend/lowering/builtins/promises.js +236 -139
  332. package/dist/frontend/lowering/builtins/promises.js.map +1 -1
  333. package/dist/frontend/lowering/builtins/readline.d.ts +5 -1
  334. package/dist/frontend/lowering/builtins/readline.js +35 -3
  335. package/dist/frontend/lowering/builtins/readline.js.map +1 -1
  336. package/dist/frontend/lowering/builtins/url.js +24 -1
  337. package/dist/frontend/lowering/builtins/url.js.map +1 -1
  338. package/dist/frontend/lowering/builtins/webassembly.js +6 -3
  339. package/dist/frontend/lowering/builtins/webassembly.js.map +1 -1
  340. package/dist/frontend/lowering/call-signatures.js +0 -1
  341. package/dist/frontend/lowering/call-signatures.js.map +1 -1
  342. package/dist/frontend/lowering/cjs-exports-object.js +1 -1
  343. package/dist/frontend/lowering/cjs-exports-object.js.map +1 -1
  344. package/dist/frontend/lowering/cjs-inline-require.d.ts +32 -0
  345. package/dist/frontend/lowering/cjs-inline-require.js +307 -4
  346. package/dist/frontend/lowering/cjs-inline-require.js.map +1 -1
  347. package/dist/frontend/lowering/class-callbacks.d.ts +5 -2
  348. package/dist/frontend/lowering/class-callbacks.js +82 -12
  349. package/dist/frontend/lowering/class-callbacks.js.map +1 -1
  350. package/dist/frontend/lowering/class-construction.d.ts +4 -1
  351. package/dist/frontend/lowering/class-construction.js +17 -3
  352. package/dist/frontend/lowering/class-construction.js.map +1 -1
  353. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +49 -2
  354. package/dist/frontend/lowering/class-dynamic-dispatch.js +880 -108
  355. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  356. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +47 -0
  357. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
  358. package/dist/frontend/lowering/class-iterables.d.ts +2 -1
  359. package/dist/frontend/lowering/class-iterables.js +9 -1
  360. package/dist/frontend/lowering/class-iterables.js.map +1 -1
  361. package/dist/frontend/lowering/class-method-mutations.js +83 -24
  362. package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
  363. package/dist/frontend/lowering/class-protocols.d.ts +25 -0
  364. package/dist/frontend/lowering/class-protocols.js +183 -1
  365. package/dist/frontend/lowering/class-protocols.js.map +1 -1
  366. package/dist/frontend/lowering/class-prototypes.js +31 -2
  367. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  368. package/dist/frontend/lowering/class-runtime-statics.d.ts +9 -3
  369. package/dist/frontend/lowering/class-runtime-statics.js +29 -4
  370. package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
  371. package/dist/frontend/lowering/coercions/structural-plans.js +48 -1
  372. package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
  373. package/dist/frontend/lowering/coercions/structural.js +91 -1
  374. package/dist/frontend/lowering/coercions/structural.js.map +1 -1
  375. package/dist/frontend/lowering/completion-callbacks.d.ts +4 -0
  376. package/dist/frontend/lowering/completion-callbacks.js +146 -0
  377. package/dist/frontend/lowering/completion-callbacks.js.map +1 -0
  378. package/dist/frontend/lowering/containers/array-callback-call.js +2 -2
  379. package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -1
  380. package/dist/frontend/lowering/containers/array-callbacks.d.ts +5 -4
  381. package/dist/frontend/lowering/containers/array-callbacks.js +345 -24
  382. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  383. package/dist/frontend/lowering/containers/array-concat.js +10 -0
  384. package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
  385. package/dist/frontend/lowering/containers/array-construction.js +5 -0
  386. package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
  387. package/dist/frontend/lowering/containers/array-methods.js +26 -3
  388. package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
  389. package/dist/frontend/lowering/containers/array-pipelines.js +19 -8
  390. package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
  391. package/dist/frontend/lowering/containers/bytes.d.ts +25 -17
  392. package/dist/frontend/lowering/containers/bytes.js +455 -46
  393. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  394. package/dist/frontend/lowering/containers/callback-arguments.js +3 -0
  395. package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
  396. package/dist/frontend/lowering/containers/collection-methods.js +7 -2
  397. package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
  398. package/dist/frontend/lowering/containers/filter-predicates.d.ts +6 -0
  399. package/dist/frontend/lowering/containers/filter-predicates.js +205 -0
  400. package/dist/frontend/lowering/containers/filter-predicates.js.map +1 -0
  401. package/dist/frontend/lowering/containers/indexed-objects.d.ts +0 -12
  402. package/dist/frontend/lowering/containers/indexed-objects.js +46 -7
  403. package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
  404. package/dist/frontend/lowering/containers/string-and-regexp.js +55 -9
  405. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  406. package/dist/frontend/lowering/containers/string-replacement.js +43 -19
  407. package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
  408. package/dist/frontend/lowering/date-values.d.ts +11 -0
  409. package/dist/frontend/lowering/date-values.js +207 -0
  410. package/dist/frontend/lowering/date-values.js.map +1 -0
  411. package/dist/frontend/lowering/dispatch-sites.js +15 -1
  412. package/dist/frontend/lowering/dispatch-sites.js.map +1 -1
  413. package/dist/frontend/lowering/divergences.js +9 -1
  414. package/dist/frontend/lowering/divergences.js.map +1 -1
  415. package/dist/frontend/lowering/error-methods.js +47 -2
  416. package/dist/frontend/lowering/error-methods.js.map +1 -1
  417. package/dist/frontend/lowering/expressions/array-literals.js +53 -0
  418. package/dist/frontend/lowering/expressions/array-literals.js.map +1 -1
  419. package/dist/frontend/lowering/expressions/binary.js +100 -28
  420. package/dist/frontend/lowering/expressions/binary.js.map +1 -1
  421. package/dist/frontend/lowering/expressions/element-access.js +169 -13
  422. package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
  423. package/dist/frontend/lowering/expressions/identifiers.js +64 -5
  424. package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
  425. package/dist/frontend/lowering/expressions/narrowing.js +95 -1
  426. package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
  427. package/dist/frontend/lowering/expressions/nullish-assignment.js +3 -1
  428. package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
  429. package/dist/frontend/lowering/expressions/object-literals.d.ts +10 -0
  430. package/dist/frontend/lowering/expressions/object-literals.js +138 -51
  431. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  432. package/dist/frontend/lowering/expressions/optional-chains.js +12 -0
  433. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  434. package/dist/frontend/lowering/expressions/property-access.js +168 -10
  435. package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
  436. package/dist/frontend/lowering/expressions/relational.js +212 -33
  437. package/dist/frontend/lowering/expressions/relational.js.map +1 -1
  438. package/dist/frontend/lowering/expressions/typeof.js +6 -0
  439. package/dist/frontend/lowering/expressions/typeof.js.map +1 -1
  440. package/dist/frontend/lowering/expressions/union-fields.js +4 -0
  441. package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
  442. package/dist/frontend/lowering/expressions/updates.js +39 -3
  443. package/dist/frontend/lowering/expressions/updates.js.map +1 -1
  444. package/dist/frontend/lowering/frozen-records.d.ts +28 -0
  445. package/dist/frontend/lowering/frozen-records.js +322 -0
  446. package/dist/frontend/lowering/frozen-records.js.map +1 -0
  447. package/dist/frontend/lowering/function-returns.js +64 -0
  448. package/dist/frontend/lowering/function-returns.js.map +1 -1
  449. package/dist/frontend/lowering/generic-functions.js +7 -2
  450. package/dist/frontend/lowering/generic-functions.js.map +1 -1
  451. package/dist/frontend/lowering/indexed-unions.d.ts +54 -0
  452. package/dist/frontend/lowering/indexed-unions.js +401 -0
  453. package/dist/frontend/lowering/indexed-unions.js.map +1 -0
  454. package/dist/frontend/lowering/iterable-values.d.ts +49 -0
  455. package/dist/frontend/lowering/iterable-values.js +297 -0
  456. package/dist/frontend/lowering/iterable-values.js.map +1 -0
  457. package/dist/frontend/lowering/iterator-adapters.js +186 -1
  458. package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
  459. package/dist/frontend/lowering/js-class-fields.d.ts +8 -0
  460. package/dist/frontend/lowering/js-class-fields.js +45 -10
  461. package/dist/frontend/lowering/js-class-fields.js.map +1 -1
  462. package/dist/frontend/lowering/key-order-witness.d.ts +18 -3
  463. package/dist/frontend/lowering/key-order-witness.js +974 -48
  464. package/dist/frontend/lowering/key-order-witness.js.map +1 -1
  465. package/dist/frontend/lowering/key-order-witness.test.js +530 -10
  466. package/dist/frontend/lowering/key-order-witness.test.js.map +1 -1
  467. package/dist/frontend/lowering/lower-assert.js +15 -3
  468. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  469. package/dist/frontend/lowering/lower-async-iteration.js +4 -1
  470. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
  471. package/dist/frontend/lowering/lower-calls.d.ts +7 -0
  472. package/dist/frontend/lowering/lower-calls.js +462 -44
  473. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  474. package/dist/frontend/lowering/lower-classes.d.ts +11 -2
  475. package/dist/frontend/lowering/lower-classes.js +324 -69
  476. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  477. package/dist/frontend/lowering/lower-dgram.js +3 -1
  478. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  479. package/dist/frontend/lowering/lower-exprs.js +215 -3
  480. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  481. package/dist/frontend/lowering/lower-functions.d.ts +11 -0
  482. package/dist/frontend/lowering/lower-functions.js +83 -0
  483. package/dist/frontend/lowering/lower-functions.js.map +1 -1
  484. package/dist/frontend/lowering/lower-generators.js +42 -32
  485. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  486. package/dist/frontend/lowering/lower-global-value.js +6 -3
  487. package/dist/frontend/lowering/lower-global-value.js.map +1 -1
  488. package/dist/frontend/lowering/lower-inspect.d.ts +1 -1
  489. package/dist/frontend/lowering/lower-inspect.js +53 -17
  490. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  491. package/dist/frontend/lowering/lower-modules.js +53 -5
  492. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  493. package/dist/frontend/lowering/lower-namespaces.js +5 -1
  494. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  495. package/dist/frontend/lowering/lower-server.js +2 -2
  496. package/dist/frontend/lowering/lower-server.js.map +1 -1
  497. package/dist/frontend/lowering/lower-stdlib.d.ts +5 -0
  498. package/dist/frontend/lowering/lower-stdlib.js +30 -0
  499. package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
  500. package/dist/frontend/lowering/lower-stmts.d.ts +23 -0
  501. package/dist/frontend/lowering/lower-stmts.js +553 -81
  502. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  503. package/dist/frontend/lowering/lower-stream.d.ts +20 -2
  504. package/dist/frontend/lowering/lower-stream.js +1483 -156
  505. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  506. package/dist/frontend/lowering/lowerer.d.ts +107 -8
  507. package/dist/frontend/lowering/lowerer.js +381 -36
  508. package/dist/frontend/lowering/lowerer.js.map +1 -1
  509. package/dist/frontend/lowering/module-namespace-elements.d.ts +11 -1
  510. package/dist/frontend/lowering/module-namespace-elements.js +82 -5
  511. package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
  512. package/dist/frontend/lowering/new-target.d.ts +12 -0
  513. package/dist/frontend/lowering/new-target.js +280 -0
  514. package/dist/frontend/lowering/new-target.js.map +1 -0
  515. package/dist/frontend/lowering/object-factory-new.d.ts +5 -0
  516. package/dist/frontend/lowering/object-factory-new.js +20 -6
  517. package/dist/frontend/lowering/object-factory-new.js.map +1 -1
  518. package/dist/frontend/lowering/overload-choice.d.ts +33 -0
  519. package/dist/frontend/lowering/overload-choice.js +190 -0
  520. package/dist/frontend/lowering/overload-choice.js.map +1 -0
  521. package/dist/frontend/lowering/surfaces.d.ts +3 -0
  522. package/dist/frontend/lowering/surfaces.js +73 -8
  523. package/dist/frontend/lowering/surfaces.js.map +1 -1
  524. package/dist/frontend/lowering/undefined-index.d.ts +27 -0
  525. package/dist/frontend/lowering/undefined-index.js +82 -0
  526. package/dist/frontend/lowering/undefined-index.js.map +1 -0
  527. package/dist/frontend/lowering/var-hoisting.js +29 -13
  528. package/dist/frontend/lowering/var-hoisting.js.map +1 -1
  529. package/dist/frontend/lowering/width-lift.d.ts +18 -0
  530. package/dist/frontend/npm-static-bundled-chunks.js +9 -11
  531. package/dist/frontend/npm-static-bundled-chunks.js.map +1 -1
  532. package/dist/frontend/npm-static-bundled-chunks.test.js +6 -5
  533. package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -1
  534. package/dist/frontend/npm-static-rewrite-syntax.js +9 -1
  535. package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
  536. package/dist/frontend/npm-static.js +4 -20
  537. package/dist/frontend/npm-static.js.map +1 -1
  538. package/dist/frontend/package-shims.d.ts +3 -0
  539. package/dist/frontend/package-shims.js +71 -8
  540. package/dist/frontend/package-shims.js.map +1 -1
  541. package/dist/frontend/pipeline.js +19 -11
  542. package/dist/frontend/pipeline.js.map +1 -1
  543. package/dist/frontend/process-fork.d.ts +25 -0
  544. package/dist/frontend/process-fork.js +2 -0
  545. package/dist/frontend/process-fork.js.map +1 -0
  546. package/dist/frontend/program-analysis.d.ts +5 -1
  547. package/dist/frontend/program-analysis.js +5 -0
  548. package/dist/frontend/program-analysis.js.map +1 -1
  549. package/dist/frontend/program.d.ts +21 -6
  550. package/dist/frontend/program.js +681 -83
  551. package/dist/frontend/program.js.map +1 -1
  552. package/dist/frontend/program.test.js +43 -3
  553. package/dist/frontend/program.test.js.map +1 -1
  554. package/dist/frontend/token-equivalence.d.ts +3 -0
  555. package/dist/frontend/token-equivalence.js +409 -0
  556. package/dist/frontend/token-equivalence.js.map +1 -0
  557. package/dist/frontend/token-equivalence.test.d.ts +1 -0
  558. package/dist/frontend/token-equivalence.test.js +67 -0
  559. package/dist/frontend/token-equivalence.test.js.map +1 -0
  560. package/dist/frontend/ts7/ast-node.d.ts +22 -0
  561. package/dist/frontend/ts7/ast-node.js +1048 -103
  562. package/dist/frontend/ts7/ast-node.js.map +1 -1
  563. package/dist/frontend/ts7/ast-node.test.js +24 -0
  564. package/dist/frontend/ts7/ast-node.test.js.map +1 -1
  565. package/dist/frontend/ts7/ast-wire.d.ts +4 -3
  566. package/dist/frontend/ts7/ast-wire.js +34 -24
  567. package/dist/frontend/ts7/ast-wire.js.map +1 -1
  568. package/dist/frontend/ts7/ast-wire.test.js +23 -0
  569. package/dist/frontend/ts7/ast-wire.test.js.map +1 -1
  570. package/dist/frontend/ts7/checker-backend.d.ts +3 -4
  571. package/dist/frontend/ts7/checker-backend.js +2 -2
  572. package/dist/frontend/ts7/checker-backend.js.map +1 -1
  573. package/dist/frontend/ts7/checker-backend.test.js +5 -9
  574. package/dist/frontend/ts7/checker-backend.test.js.map +1 -1
  575. package/dist/frontend/ts7/checker.d.ts +4 -0
  576. package/dist/frontend/ts7/checker.js +7 -0
  577. package/dist/frontend/ts7/checker.js.map +1 -1
  578. package/dist/frontend/ts7/lib-diagnostics.d.ts +24 -0
  579. package/dist/frontend/ts7/lib-diagnostics.js +307 -0
  580. package/dist/frontend/ts7/lib-diagnostics.js.map +1 -0
  581. package/dist/frontend/ts7/lib-diagnostics.test.d.ts +1 -0
  582. package/dist/frontend/ts7/lib-diagnostics.test.js +199 -0
  583. package/dist/frontend/ts7/lib-diagnostics.test.js.map +1 -0
  584. package/dist/frontend/ts7/program-host.d.ts +7 -0
  585. package/dist/frontend/ts7/program-host.js +25 -2
  586. package/dist/frontend/ts7/program-host.js.map +1 -1
  587. package/dist/frontend/ts7/semantic-model.d.ts +3 -0
  588. package/dist/frontend/ts7/semantic-model.js +5 -0
  589. package/dist/frontend/ts7/semantic-model.js.map +1 -1
  590. package/dist/frontend/ts7/semantic-model.test.js +6 -1
  591. package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
  592. package/dist/frontend/ts7/semantic-types.d.ts +1 -1
  593. package/dist/frontend/ts7/semantic-types.js +1 -1
  594. package/dist/frontend/ts7/semantic-types.js.map +1 -1
  595. package/dist/frontend/ts7/session.d.ts +14 -1
  596. package/dist/frontend/ts7/session.js +22 -0
  597. package/dist/frontend/ts7/session.js.map +1 -1
  598. package/dist/frontend/type-mapper.d.ts +13 -1
  599. package/dist/frontend/type-mapper.js +229 -20
  600. package/dist/frontend/type-mapper.js.map +1 -1
  601. package/dist/index.d.ts +0 -5
  602. package/dist/index.js +46 -4
  603. package/dist/index.js.map +1 -1
  604. package/dist/ir/analysis.js +5 -3
  605. package/dist/ir/analysis.js.map +1 -1
  606. package/dist/ir/array-length-stability.d.ts +4 -0
  607. package/dist/ir/array-length-stability.js +19 -6
  608. package/dist/ir/array-length-stability.js.map +1 -1
  609. package/dist/ir/array-length-stability.test.js +24 -0
  610. package/dist/ir/array-length-stability.test.js.map +1 -1
  611. package/dist/ir/builtin-effects.d.ts +7 -0
  612. package/dist/ir/builtin-effects.js +60 -0
  613. package/dist/ir/builtin-effects.js.map +1 -1
  614. package/dist/ir/builtin-signatures.d.ts +6 -4
  615. package/dist/ir/builtin-signatures.js +222 -13
  616. package/dist/ir/builtin-signatures.js.map +1 -1
  617. package/dist/ir/callback-specialization.d.ts +2 -1
  618. package/dist/ir/callback-specialization.js +23 -18
  619. package/dist/ir/callback-specialization.js.map +1 -1
  620. package/dist/ir/char-unit-locals.d.ts +19 -0
  621. package/dist/ir/char-unit-locals.js +185 -0
  622. package/dist/ir/char-unit-locals.js.map +1 -0
  623. package/dist/ir/char-unit-locals.test.d.ts +1 -0
  624. package/dist/ir/char-unit-locals.test.js +94 -0
  625. package/dist/ir/char-unit-locals.test.js.map +1 -0
  626. package/dist/ir/final-fields.d.ts +2 -1
  627. package/dist/ir/final-fields.js +14 -16
  628. package/dist/ir/final-fields.js.map +1 -1
  629. package/dist/ir/function-references.d.ts +2 -0
  630. package/dist/ir/function-references.js +2 -0
  631. package/dist/ir/function-references.js.map +1 -1
  632. package/dist/ir/function-references.test.js +3 -0
  633. package/dist/ir/function-references.test.js.map +1 -1
  634. package/dist/ir/initializer-bindings.d.ts +2 -1
  635. package/dist/ir/initializer-bindings.js +27 -20
  636. package/dist/ir/initializer-bindings.js.map +1 -1
  637. package/dist/ir/int32-arrays.d.ts +108 -0
  638. package/dist/ir/int32-arrays.js +831 -0
  639. package/dist/ir/int32-arrays.js.map +1 -0
  640. package/dist/ir/int32-slots.d.ts +24 -2
  641. package/dist/ir/int32-slots.js +266 -57
  642. package/dist/ir/int32-slots.js.map +1 -1
  643. package/dist/ir/int32-slots.test.js +33 -0
  644. package/dist/ir/int32-slots.test.js.map +1 -1
  645. package/dist/ir/integer-loops.d.ts +3 -3
  646. package/dist/ir/integer-loops.js +28 -10
  647. package/dist/ir/integer-loops.js.map +1 -1
  648. package/dist/ir/integer-loops.test.js +10 -0
  649. package/dist/ir/integer-loops.test.js.map +1 -1
  650. package/dist/ir/integer-ranges.d.ts +5 -0
  651. package/dist/ir/integer-ranges.js +125 -12
  652. package/dist/ir/integer-ranges.js.map +1 -1
  653. package/dist/ir/integer-ranges.test.js +30 -0
  654. package/dist/ir/integer-ranges.test.js.map +1 -1
  655. package/dist/ir/ir.d.ts +83 -10
  656. package/dist/ir/ir.js +77 -6
  657. package/dist/ir/ir.js.map +1 -1
  658. package/dist/ir/ir.test.js +23 -2
  659. package/dist/ir/ir.test.js.map +1 -1
  660. package/dist/ir/js-ic.d.ts +4 -0
  661. package/dist/ir/js-ic.js +17 -1
  662. package/dist/ir/js-ic.js.map +1 -1
  663. package/dist/ir/js-ic.test.js +46 -0
  664. package/dist/ir/js-ic.test.js.map +1 -1
  665. package/dist/ir/node-index.d.ts +57 -0
  666. package/dist/ir/node-index.js +215 -0
  667. package/dist/ir/node-index.js.map +1 -0
  668. package/dist/ir/paired-while-loops.d.ts +25 -0
  669. package/dist/ir/paired-while-loops.js +335 -0
  670. package/dist/ir/paired-while-loops.js.map +1 -0
  671. package/dist/ir/paired-while-loops.test.d.ts +1 -0
  672. package/dist/ir/paired-while-loops.test.js +163 -0
  673. package/dist/ir/paired-while-loops.test.js.map +1 -0
  674. package/dist/ir/parameter-versions.d.ts +25 -0
  675. package/dist/ir/parameter-versions.js +300 -0
  676. package/dist/ir/parameter-versions.js.map +1 -0
  677. package/dist/ir/runtime-features.d.ts +34 -13
  678. package/dist/ir/runtime-features.js +177 -39
  679. package/dist/ir/runtime-features.js.map +1 -1
  680. package/dist/ir/serialize.d.ts +12 -2
  681. package/dist/ir/serialize.js +16 -3
  682. package/dist/ir/serialize.js.map +1 -1
  683. package/dist/ir/serialize.test.js +17 -0
  684. package/dist/ir/serialize.test.js.map +1 -1
  685. package/dist/ir/traverse.js +18 -6
  686. package/dist/ir/traverse.js.map +1 -1
  687. package/dist/ir/validate.js +167 -40
  688. package/dist/ir/validate.js.map +1 -1
  689. package/dist/library/ir-policy.js +3 -0
  690. package/dist/library/ir-policy.js.map +1 -1
  691. package/dist/native/cache.d.ts +6 -1
  692. package/dist/native/cache.js +28 -5
  693. package/dist/native/cache.js.map +1 -1
  694. package/dist/native/cache.test.js +16 -2
  695. package/dist/native/cache.test.js.map +1 -1
  696. package/dist/native/cli.js +21 -1
  697. package/dist/native/cli.js.map +1 -1
  698. package/dist/native/compiler.js +8 -6
  699. package/dist/native/compiler.js.map +1 -1
  700. package/dist/native/executable-cache.d.ts +1 -1
  701. package/dist/native/executable-cache.js +2 -2
  702. package/dist/native/executable-cache.js.map +1 -1
  703. package/dist/native/prepare.d.ts +4 -2
  704. package/dist/native/prepare.js +130 -32
  705. package/dist/native/prepare.js.map +1 -1
  706. package/dist/native/prepare.test.js +96 -20
  707. package/dist/native/prepare.test.js.map +1 -1
  708. package/dist/native/sanitizer.test.js +2 -0
  709. package/dist/native/sanitizer.test.js.map +1 -1
  710. package/dist/native/text-file.d.ts +13 -3
  711. package/dist/native/text-file.js +63 -9
  712. package/dist/native/text-file.js.map +1 -1
  713. package/dist/native/text-file.test.d.ts +1 -0
  714. package/dist/native/text-file.test.js +49 -0
  715. package/dist/native/text-file.test.js.map +1 -0
  716. package/dist/native/toolchain.js +4 -4
  717. package/dist/native/toolchain.js.map +1 -1
  718. package/dist/native/toolchain.test.js +3 -3
  719. package/dist/native/toolchain.test.js.map +1 -1
  720. package/package.json +21 -21
  721. package/shims/chalk/v5.ts +688 -0
  722. package/shims/hono-node-server/v2.ts +645 -0
  723. package/shims/hot-shots/client.ts +1126 -0
  724. package/shims/hot-shots/v8-unix-dgram.ts +8 -0
  725. package/shims/hot-shots/v8.ts +8 -0
  726. package/surface-manifest.json +27 -7
@@ -1,11 +1,13 @@
1
+ import { F64 } from "../../ir/ir.js";
1
2
  import { byteNumberAccess } from "../../ir/byte-numbers.js";
2
3
  import { everyExprChild, everyStmtChild } from "../../ir/traverse.js";
3
4
  import { exactInteger, widenInteger } from "./integer-values.js";
4
- import { emitCountedLoopLimit, emitCountedLoopSafety } from "./counted-loops.js";
5
+ import { emitCountedLoopLimit, emitCountedLoopSafety, emitExactIntegerTest, } from "./counted-loops.js";
5
6
  import { emitBytesHeaderLength, emitBytesSharedStorage } from "./expr-bytes.js";
6
7
  import { f64Lit } from "./common.js";
8
+ import { emitStringAsciiFlag, emitStringByteLength } from "./string-reads.js";
7
9
  const MAX_COST = 400;
8
- const MAX_FIXED_END = 2 ** 32;
10
+ const MAX_FIXED_END = 2 ** 31;
9
11
  const MAX_CHECKS = 8;
10
12
  const MAX_OFFSET = 2 ** 31;
11
13
  const SAFE = Number.MAX_SAFE_INTEGER;
@@ -27,6 +29,14 @@ const INVARIANT_OPS = new Set(["+", "-", "*", "&", "|", "^", "<<", ">>", ">>>"])
27
29
  * such as `base` for `const base = r * cols`, must also be an exact
28
30
  * integer between -2^32 and 2^32, which the guard tests.
29
31
  *
32
+ * `s.charCodeAt(index)` and `s.charAt(index)` (so `s[index]`) of a string
33
+ * binding qualify the same way. A string is immutable: its bytes, its
34
+ * length and the capacity-word bit that proves it ASCII (string-reads.ts)
35
+ * are fixed when it is built. The guard also requires that bit, so each
36
+ * UTF-16 unit is one byte and the length is the byte length. The fast copy
37
+ * reads each unit with one byte load, and each character as the immortal
38
+ * one-character string for its byte.
39
+ *
30
40
  * In worker programs, every access of a view that may be shared tests its
31
41
  * shared storage. A view's storage is also fixed at construction, so the
32
42
  * same guard tests each invariant receiver once, and the fast copy reads
@@ -36,7 +46,7 @@ const INVARIANT_OPS = new Set(["+", "-", "*", "&", "|", "^", "<<", ">>", ">>>"])
36
46
  * the emitter bounds how deeply versions nest. The checked loop runs
37
47
  * whenever the guard fails, and keeps every out-of-bounds read, ignored
38
48
  * write and NaN-index behavior. */
39
- export function matchBytesLoopVersion(loop, counted, facts) {
49
+ export function matchBytesLoopVersion(loop, counted, facts, paired = null) {
40
50
  const written = new Set();
41
51
  const temps = new Map();
42
52
  let cost = 0;
@@ -77,10 +87,10 @@ export function matchBytesLoopVersion(loop, counted, facts) {
77
87
  // The guard runs before the initializer, so a binding the initializer
78
88
  // writes is not invariant either: `for (let i = (a = b, 0); ...)` must
79
89
  // not keep the bounds the guard proved for the old `a`.
80
- if ((loop.init !== null && !scanStmt(loop.init)) ||
90
+ if ((loop.kind === "for" && loop.init !== null && !scanStmt(loop.init)) ||
81
91
  !loop.body.every(scanStmt) ||
82
92
  (loop.cond !== null && !scanExpr(loop.cond)) ||
83
- (loop.update !== null && !scanStmt(loop.update)))
93
+ (loop.kind === "for" && loop.update !== null && !scanStmt(loop.update)))
84
94
  return null;
85
95
  // A body temp stands for its initializer only when it is a constant
86
96
  // binding assigned exactly once, by that declaration.
@@ -117,7 +127,9 @@ export function matchBytesLoopVersion(loop, counted, facts) {
117
127
  };
118
128
  const resolving = new Set();
119
129
  const root = (e) => {
120
- if (e.kind !== "varRef" || e.type.kind !== "bytes")
130
+ if (e.kind !== "varRef" || (e.type.kind !== "bytes" && e.type.kind !== "string"))
131
+ return null;
132
+ if (facts.scalarStrings.has(e.localId))
121
133
  return null;
122
134
  const init = temp(e.localId);
123
135
  if (init) {
@@ -254,6 +266,39 @@ export function matchBytesLoopVersion(loop, counted, facts) {
254
266
  const r = termRange(t.expr);
255
267
  return sum + Math.max(Math.abs(r.min), Math.abs(r.max));
256
268
  }, 0);
269
+ const whileAccesses = loop.kind === "while" ? whileCounterAccesses(loop) : null;
270
+ function whileCounterAccesses(loop) {
271
+ return findWhileCounterAccesses(loop, {
272
+ counterLocal: (id) => {
273
+ const local = facts.locals.get(id);
274
+ return (local?.type.kind === "f64" &&
275
+ !local.boxed &&
276
+ !local.tdz &&
277
+ !facts.captured.has(id) &&
278
+ facts.initialized.has(id));
279
+ },
280
+ boundKey: (e) => {
281
+ if (e.type.kind !== "f64")
282
+ return null;
283
+ // The guard evaluates the bound before the loop: a typed array's
284
+ // length needs the binding itself, not a temp the body declares.
285
+ if (e.kind === "bytesIntrinsic" &&
286
+ e.method === "length" &&
287
+ e.receiver.kind === "varRef" &&
288
+ e.receiver.type.kind === "bytes" &&
289
+ invariant(e.receiver.localId))
290
+ return `bytes-length:${e.receiver.localId}`;
291
+ if (e.kind === "strIntrinsic" &&
292
+ e.method === "length" &&
293
+ e.args.length === 0 &&
294
+ e.receiver.kind === "varRef" &&
295
+ e.receiver.type.kind === "string" &&
296
+ invariant(e.receiver.localId))
297
+ return `string-length:${e.receiver.localId}`;
298
+ return pureKey(e);
299
+ },
300
+ });
301
+ }
257
302
  const receivers = [];
258
303
  const receiverIndex = new Map();
259
304
  const fixed = new Map();
@@ -263,18 +308,26 @@ export function matchBytesLoopVersion(loop, counted, facts) {
263
308
  if (index === undefined) {
264
309
  index = receivers.length;
265
310
  receiverIndex.set(ref.localId, index);
266
- receivers.push({ ref, global: !facts.locals.has(ref.localId) });
311
+ receivers.push({
312
+ ref,
313
+ global: !facts.locals.has(ref.localId),
314
+ string: ref.type.kind === "string",
315
+ });
267
316
  }
268
317
  return index;
269
318
  };
270
319
  // Worker programs: accesses through invariant receivers, proven or not,
271
320
  // become thread-owned when the guard finds no shared storage.
272
321
  const owned = new Map();
322
+ // While loops: accesses at a counter below a bound, by receiver and bound.
323
+ const boundedChecks = new Map();
324
+ const pairedCounters = paired !== null && counted === null ? new Set([paired.low.localId, paired.high.localId]) : null;
325
+ const pairedNodes = new Map();
273
326
  const access = (node, array, index, width) => {
274
327
  const ref = root(array);
275
328
  if (!ref)
276
329
  return;
277
- if (facts.workers && !facts.owned.has(node)) {
330
+ if (facts.workers && ref.type.kind === "bytes" && !facts.owned.has(node)) {
278
331
  const receiver = receiverOf(ref);
279
332
  const nodes = owned.get(receiver);
280
333
  if (nodes)
@@ -284,6 +337,20 @@ export function matchBytesLoopVersion(loop, counted, facts) {
284
337
  }
285
338
  if (facts.proven.has(node))
286
339
  return;
340
+ // An element at either counter of a two-counter loop.
341
+ if (pairedCounters !== null &&
342
+ width === 1 &&
343
+ ref.type.kind === "bytes" &&
344
+ index.kind === "varRef" &&
345
+ pairedCounters.has(index.localId)) {
346
+ const receiver = receiverOf(ref);
347
+ const nodes = pairedNodes.get(receiver);
348
+ if (nodes)
349
+ nodes.push(node);
350
+ else
351
+ pairedNodes.set(receiver, [node]);
352
+ return;
353
+ }
287
354
  const shape = counter !== null ? affine(index) : null;
288
355
  if (shape && shape.counter !== 0) {
289
356
  const operands = new Set();
@@ -308,12 +375,32 @@ export function matchBytesLoopVersion(loop, counted, facts) {
308
375
  });
309
376
  return;
310
377
  }
378
+ const bounded = whileAccesses?.accesses.get(node);
379
+ const loopCounter = bounded && whileAccesses.counters.get(bounded.counter);
380
+ if (bounded && loopCounter && (!loopCounter.wraps || loopCounter.bounds !== null)) {
381
+ const receiver = receiverOf(ref);
382
+ const key = `${receiver}|${bounded.key}|${bounded.adj}`;
383
+ const slack = bounded.offset + width - 1 + bounded.adj;
384
+ const group = boundedChecks.get(key);
385
+ if (group) {
386
+ group.check.slack = Math.max(group.check.slack, slack);
387
+ group.nodes.push({ node, access: bounded });
388
+ }
389
+ else
390
+ boundedChecks.set(key, {
391
+ check: { receiver, bound: bounded.bound, slack },
392
+ nodes: [{ node, access: bounded }],
393
+ });
394
+ return;
395
+ }
311
396
  const range = facts.ranges.get(index);
312
397
  if (!range)
313
398
  return;
314
399
  const end = range.max + width - 1;
315
- // Only a length a buffer can have: an outer loop must not pay for a
316
- // guard that bounds an inner loop's unbounded counter.
400
+ // Only an end below 2^31: an outer loop must not pay for a guard that
401
+ // bounds an inner loop's unbounded counter, and the counter of a loop to
402
+ // an array's length reaches 2^32 - 2, a length no typed array in
403
+ // practice has.
317
404
  if (range.min < 0 || end >= MAX_FIXED_END)
318
405
  return;
319
406
  const receiver = receiverOf(ref);
@@ -333,6 +420,10 @@ export function matchBytesLoopVersion(loop, counted, facts) {
333
420
  else if (e.method === "get" && e.args[0])
334
421
  access(e, e.receiver, e.args[0], 1);
335
422
  }
423
+ else if (e.kind === "strIntrinsic" &&
424
+ (e.method === "charCodeAt" || e.method === "charAt") &&
425
+ e.args[0])
426
+ access(e, e.receiver, e.args[0], 1);
336
427
  return everyExprChild(e, visitExpr, visitStmt);
337
428
  };
338
429
  const visitStmt = (s) => {
@@ -341,6 +432,8 @@ export function matchBytesLoopVersion(loop, counted, facts) {
341
432
  return everyStmtChild(s, visitExpr, visitStmt);
342
433
  };
343
434
  loop.body.every(visitStmt);
435
+ if (loop.kind === "while")
436
+ visitExpr(loop.cond);
344
437
  // Bound the counter so every counter operand stays a safe integer.
345
438
  let bound = SAFE;
346
439
  const affineGroups = [...affineChecks.values()].filter((group) => {
@@ -357,8 +450,20 @@ export function matchBytesLoopVersion(loop, counted, facts) {
357
450
  });
358
451
  const fixedKept = [...fixed.values()].slice(0, MAX_CHECKS);
359
452
  const affineKept = affineGroups.slice(0, MAX_CHECKS - fixedKept.length);
453
+ const boundedKept = [...boundedChecks.values()].slice(0, Math.max(0, MAX_CHECKS - fixedKept.length - affineKept.length));
360
454
  const ownedKept = [...owned.entries()].slice(0, MAX_CHECKS);
361
- if (fixedKept.length === 0 && affineKept.length === 0 && ownedKept.length === 0)
455
+ const pairedKept = [...pairedNodes.entries()].slice(0, Math.max(0, MAX_CHECKS - fixedKept.length - affineKept.length - boundedKept.length));
456
+ if (fixedKept.length === 0 &&
457
+ affineKept.length === 0 &&
458
+ boundedKept.length === 0 &&
459
+ ownedKept.length === 0 &&
460
+ pairedKept.length === 0)
461
+ return null;
462
+ // A while loop versions only for accesses at its counters. Its other
463
+ // checks (thread-owned receivers, static indices) save a test or two per
464
+ // pass, while a second copy of its body doubles the calls it makes, which
465
+ // can keep a worker's job loop from inlining the function that runs a job.
466
+ if (loop.kind === "while" && boundedKept.length === 0)
362
467
  return null;
363
468
  const bounds = new Set();
364
469
  const ownedNodes = new Set();
@@ -410,6 +515,42 @@ export function matchBytesLoopVersion(loop, counted, facts) {
410
515
  for (const [node, key] of guardedNodes)
411
516
  if (guarded.has(key))
412
517
  ranges.set(node, GUARDED_TERM);
518
+ // While loop counters of the kept checks: each entry value is an exact
519
+ // integer that no access offset takes below 0. In the fast copy each
520
+ // access's index is below its length, and its counter read at least the
521
+ // most negative offset.
522
+ const narrow = (e, range) => {
523
+ const known = ranges.get(e) ?? facts.ranges.get(e);
524
+ ranges.set(e, known ? { min: Math.max(known.min, range.min), max: Math.min(known.max, range.max) } : range);
525
+ };
526
+ const counterMins = new Map();
527
+ for (const group of boundedKept) {
528
+ used.add(group.check.receiver);
529
+ for (const { node, access } of group.nodes) {
530
+ bounds.add(node);
531
+ const min = 0 - access.offset;
532
+ counterMins.set(access.counter, Math.max(counterMins.get(access.counter) ?? -SAFE, min));
533
+ narrow(access.ref, { min: -MAX_OFFSET, max: SAFE });
534
+ if (access.index !== access.ref)
535
+ narrow(access.index, { min: 0, max: SAFE });
536
+ }
537
+ }
538
+ for (const [receiver, nodes] of pairedKept) {
539
+ used.add(receiver);
540
+ for (const node of nodes)
541
+ bounds.add(node);
542
+ }
543
+ const counterChecks = [];
544
+ for (const [id, min] of counterMins) {
545
+ const info = whileAccesses.counters.get(id);
546
+ counterChecks.push({
547
+ ref: { kind: "varRef", localId: id, type: F64, loc: loop.loc },
548
+ min,
549
+ wrapBounds: info.wraps
550
+ ? info.bounds.map((b) => ({ bound: b.bound, limit: 2 ** 31 - info.sum - b.adj }))
551
+ : [],
552
+ });
553
+ }
413
554
  // Renumber the receivers the kept checks use.
414
555
  const order = [...used].sort((a, b) => a - b);
415
556
  const renumber = new Map(order.map((old, index) => [old, index]));
@@ -432,12 +573,276 @@ export function matchBytesLoopVersion(loop, counted, facts) {
432
573
  minOffset: g.check.minOffset,
433
574
  maxEnd: g.check.maxEnd,
434
575
  })),
576
+ bounded: boundedKept.map((g) => ({
577
+ receiver: renumber.get(g.check.receiver),
578
+ bound: g.check.bound,
579
+ slack: g.check.slack,
580
+ })),
581
+ counters: counterChecks,
435
582
  guarded,
436
583
  counted: affineKept.length > 0 ? counted : null,
584
+ paired: paired !== null && pairedKept.length > 0
585
+ ? { loop: paired, receivers: pairedKept.map(([receiver]) => renumber.get(receiver)) }
586
+ : null,
437
587
  counterBound: needsBound ? bound : null,
438
588
  ranges,
439
589
  };
440
590
  }
591
+ /** `counter = counter + k`, `counter = (counter + k) | 0` or `counter++`. */
592
+ function counterStep(s) {
593
+ if (s.kind === "exprStmt" && s.expr.kind === "incDec" && s.expr.op === "+")
594
+ return { id: s.expr.localId, k: 1, wraps: false };
595
+ if (s.kind !== "assign")
596
+ return null;
597
+ let value = s.value, wraps = false;
598
+ if (value.kind === "bin" &&
599
+ value.op === "|" &&
600
+ value.right.kind === "numLit" &&
601
+ value.right.value === 0 &&
602
+ value.left.kind === "bin") {
603
+ value = value.left;
604
+ wraps = true;
605
+ }
606
+ if (value.kind !== "bin" ||
607
+ value.op !== "+" ||
608
+ value.left.kind !== "varRef" ||
609
+ value.left.localId !== s.localId ||
610
+ value.right.kind !== "numLit" ||
611
+ !Number.isSafeInteger(value.right.value) ||
612
+ value.right.value <= 0 ||
613
+ value.right.value > MAX_OFFSET)
614
+ return null;
615
+ return { id: s.localId, k: value.right.value, wraps };
616
+ }
617
+ /** Typed-array and string accesses of a while loop that happen at a
618
+ * counter below a loop-invariant bound. A counter is a number local that
619
+ * the loop changes only by positive integer increments, written as
620
+ * statements of the body, of its blocks and branches, or of nested while
621
+ * loops. The condition of the loop, an `if` or a `&&` chain that compares
622
+ * the counter below a bound (`while (pos < end && bytes[pos] === 32)
623
+ * pos++`, or `s.charCodeAt(pos)` of a string) makes it below that bound
624
+ * until the next increment on the path. The counter starts at its entry
625
+ * value and only grows (a `| 0` increment never wraps when every bound is
626
+ * at most 2^31 minus the increments), so an access at `counter + d` is in
627
+ * bounds for the whole loop when the entry value is at least `-d` and
628
+ * `bound + d < length` (`+ 1` for `<=`). */
629
+ function findWhileCounterAccesses(loop, host) {
630
+ const steps = new Map();
631
+ const refused = new Set();
632
+ // Increments count only as statements of the loop's straight-line
633
+ // structure; any other write refuses the binding.
634
+ const writes = (list, direct) => {
635
+ for (const s of list) {
636
+ const step = counterStep(s);
637
+ if (step && direct) {
638
+ const prior = steps.get(step.id);
639
+ steps.set(step.id, {
640
+ sum: (prior?.sum ?? 0) + step.k,
641
+ wraps: (prior?.wraps ?? false) || step.wraps,
642
+ });
643
+ continue;
644
+ }
645
+ if (step)
646
+ refused.add(step.id);
647
+ const nested = direct &&
648
+ (s.kind === "if" || s.kind === "while" || (s.kind === "block" && !s.labels?.length));
649
+ if (s.kind === "assign" || s.kind === "varDecl" || s.kind === "forOf")
650
+ refused.add(s.localId);
651
+ if (s.kind === "tryCatch" && s.catchLocalId)
652
+ refused.add(s.catchLocalId);
653
+ everyStmtChild(s, (e) => (exprWrites(e), true), (c) => (writes([c], nested), true));
654
+ }
655
+ };
656
+ const exprWrites = (e) => {
657
+ if (e.kind === "assignExpr" || e.kind === "incDec")
658
+ refused.add(e.localId);
659
+ everyExprChild(e, (c) => (exprWrites(c), true), (c) => (writes([c], false), true));
660
+ };
661
+ exprWrites(loop.cond);
662
+ writes(loop.body, true);
663
+ const counter = (id) => steps.has(id) && !refused.has(id) && host.counterLocal(id);
664
+ // The bounds a condition puts on counters while it holds.
665
+ const facts = (cond, into) => {
666
+ if (cond.kind === "toBool")
667
+ return facts(cond.operand, into);
668
+ if (cond.kind === "logical" && cond.op === "&&") {
669
+ facts(cond.left, into);
670
+ facts(cond.right, into);
671
+ return;
672
+ }
673
+ if (cond.kind !== "bin")
674
+ return;
675
+ const below = cond.op === "<" || cond.op === "<=", above = cond.op === ">" || cond.op === ">=";
676
+ const c = below ? cond.left : above ? cond.right : null, bound = below ? cond.right : cond.left;
677
+ if (c?.kind !== "varRef" || !counter(c.localId) || into.has(c.localId))
678
+ return;
679
+ const key = host.boundKey(bound);
680
+ if (key === null)
681
+ return;
682
+ into.set(c.localId, { bound, key, adj: cond.op === "<=" || cond.op === ">=" ? 1 : 0 });
683
+ };
684
+ // The facts that hold after either of two paths.
685
+ const meet = (a, b) => {
686
+ if (a === null)
687
+ return b;
688
+ if (b === null)
689
+ return a;
690
+ const out = new Map();
691
+ for (const [id, fact] of a)
692
+ if (b.get(id) === fact)
693
+ out.set(id, fact);
694
+ return out;
695
+ };
696
+ const withFacts = (clean, cond) => {
697
+ const out = new Map(clean);
698
+ facts(cond, out);
699
+ return out;
700
+ };
701
+ const accesses = new Map();
702
+ const record = (node, index, clean) => {
703
+ let ref = index, offset = 0;
704
+ if (index.kind === "bin" && (index.op === "+" || index.op === "-")) {
705
+ const literal = index.right.kind === "numLit" ? index.right : index.op === "+" ? index.left : null;
706
+ const other = literal === index.right ? index.left : index.right;
707
+ if (literal?.kind !== "numLit" || !Number.isSafeInteger(literal.value))
708
+ return;
709
+ if (Math.abs(literal.value) > MAX_OFFSET || Object.is(literal.value, -0))
710
+ return;
711
+ offset = index.op === "-" ? -literal.value : literal.value;
712
+ ref = other;
713
+ }
714
+ if (ref.kind !== "varRef")
715
+ return;
716
+ const fact = clean.get(ref.localId);
717
+ if (fact)
718
+ accesses.set(node, { counter: ref.localId, index, ref, ...fact, offset });
719
+ };
720
+ const expr = (e, clean) => {
721
+ if (e.kind === "bytesIntrinsic") {
722
+ const numeric = byteNumberAccess(e);
723
+ const index = numeric
724
+ ? e.args[numeric.offsetArg]
725
+ : e.method === "get"
726
+ ? e.args[0]
727
+ : undefined;
728
+ if (index)
729
+ record(e, index, clean);
730
+ }
731
+ if (e.kind === "strIntrinsic" &&
732
+ (e.method === "charCodeAt" || e.method === "charAt") &&
733
+ e.args[0])
734
+ record(e, e.args[0], clean);
735
+ if (e.kind === "logical" && e.op === "&&") {
736
+ expr(e.left, clean);
737
+ expr(e.right, withFacts(clean, e.left));
738
+ return;
739
+ }
740
+ if (e.kind === "ternary") {
741
+ expr(e.cond, clean);
742
+ expr(e.then, withFacts(clean, e.cond));
743
+ expr(e.else_, clean);
744
+ return;
745
+ }
746
+ everyExprChild(e, (c) => (expr(c, clean), true), (c) => (stmts([c], clean), true));
747
+ };
748
+ // Walks statements in order; the result is the clean state where the
749
+ // list falls through, or null when it never does.
750
+ const stmts = (list, clean) => {
751
+ let current = clean;
752
+ for (const s of list) {
753
+ if (current === null)
754
+ return null;
755
+ const step = counterStep(s);
756
+ if (step) {
757
+ const next = new Map(current);
758
+ next.delete(step.id);
759
+ current = next;
760
+ continue;
761
+ }
762
+ switch (s.kind) {
763
+ case "if": {
764
+ expr(s.cond, current);
765
+ const then = stmts(s.then, withFacts(current, s.cond));
766
+ const otherwise = stmts(s.else_ ?? [], current);
767
+ current = meet(then, otherwise);
768
+ break;
769
+ }
770
+ case "while": {
771
+ // A pass of the nested loop may follow its own increments.
772
+ const advanced = new Map(current);
773
+ for (const id of writtenCounters(s.body))
774
+ advanced.delete(id);
775
+ expr(s.cond, advanced);
776
+ stmts(s.body, withFacts(advanced, s.cond));
777
+ current = advanced;
778
+ break;
779
+ }
780
+ case "block":
781
+ if (!s.labels?.length) {
782
+ current = stmts(s.body, current);
783
+ break;
784
+ }
785
+ everyStmtChild(s, (e) => (expr(e, current), true), (c) => (stmts([c], current), true));
786
+ break;
787
+ case "bytesSet":
788
+ record(s, s.index, current);
789
+ everyStmtChild(s, (e) => (expr(e, current), true), (c) => (stmts([c], current), true));
790
+ break;
791
+ case "break":
792
+ case "continue":
793
+ case "return":
794
+ case "throw":
795
+ everyStmtChild(s, (e) => (expr(e, current), true), (c) => (stmts([c], current), true));
796
+ current = null;
797
+ break;
798
+ default:
799
+ everyStmtChild(s, (e) => (expr(e, current), true), (c) => (stmts([c], current), true));
800
+ break;
801
+ }
802
+ }
803
+ return current;
804
+ };
805
+ const writtenCounters = (list) => {
806
+ const out = new Set();
807
+ const visit = (s) => {
808
+ const step = counterStep(s);
809
+ if (step)
810
+ out.add(step.id);
811
+ return everyStmtChild(s, () => true, visit);
812
+ };
813
+ list.every(visit);
814
+ return out;
815
+ };
816
+ expr(loop.cond, new Map());
817
+ stmts(loop.body, withFacts(new Map(), loop.cond));
818
+ // Each counter's bounds: the loop's and those of nested while loops that
819
+ // advance it.
820
+ const counters = new Map();
821
+ const loops = [loop];
822
+ const collectLoops = (s) => {
823
+ if (s.kind === "while")
824
+ loops.push(s);
825
+ return everyStmtChild(s, () => true, collectLoops);
826
+ };
827
+ loop.body.every(collectLoops);
828
+ for (const [id, step] of steps) {
829
+ if (!counter(id))
830
+ continue;
831
+ let bounds = [];
832
+ for (const l of loops) {
833
+ if (l !== loop && !writtenCounters(l.body).has(id))
834
+ continue;
835
+ const fact = withFacts(new Map(), l.cond).get(id);
836
+ if (!fact) {
837
+ bounds = null;
838
+ break;
839
+ }
840
+ bounds.push({ bound: fact.bound, adj: fact.adj });
841
+ }
842
+ counters.set(id, { ...step, bounds });
843
+ }
844
+ return { accesses, counters };
845
+ }
441
846
  /** Branches to `fast` when every access the version proves is in bounds for
442
847
  * every iteration and every view it proves thread-owned has no shared
443
848
  * storage, and to `slow` otherwise (including a counted loop whose
@@ -463,8 +868,10 @@ export function emitBytesLoopVersionGuard(host, version, fast, slow) {
463
868
  }
464
869
  return value;
465
870
  });
466
- const lengths = receivers.map((receiver) => {
467
- const len = emitBytesHeaderLength(host, receiver);
871
+ const lengths = receivers.map((receiver, index) => {
872
+ const len = version.receivers[index].string
873
+ ? emitStringByteLength(host, receiver)
874
+ : emitBytesHeaderLength(host, receiver);
468
875
  if (host.sizeType === "i64")
469
876
  return len;
470
877
  const wide = B.tmp();
@@ -472,6 +879,11 @@ export function emitBytesLoopVersionGuard(host, version, fast, slow) {
472
879
  return wide;
473
880
  });
474
881
  const conditions = [];
882
+ // A string's byte length is its UTF-16 length when it is ASCII.
883
+ version.receivers.forEach(({ string }, index) => {
884
+ if (string)
885
+ conditions.push(emitStringAsciiFlag(host, receivers[index]));
886
+ });
475
887
  for (const index of version.ownedReceivers) {
476
888
  const owned = B.tmp();
477
889
  B.line(`${owned} = icmp eq ptr ${emitBytesSharedStorage(host, receivers[index])}, null`);
@@ -482,6 +894,40 @@ export function emitBytesLoopVersionGuard(host, version, fast, slow) {
482
894
  B.line(`${ok} = icmp ugt i64 ${lengths[check.receiver]}, ${check.end}`);
483
895
  conditions.push(ok);
484
896
  }
897
+ for (const counter of version.counters) {
898
+ const value = host.emitExpr(counter.ref);
899
+ // A counter held as an integer (an int32 slot) is exact already and
900
+ // needs at most its lower bound tested.
901
+ const integer = exactInteger(host, value, counter.ref);
902
+ if (integer && integer.range.max <= SAFE) {
903
+ if (integer.range.min < counter.min) {
904
+ const ok = B.tmp();
905
+ B.line(`${ok} = icmp sge i64 ${widenInteger(host, integer)}, ${counter.min}`);
906
+ conditions.push(ok);
907
+ }
908
+ }
909
+ else
910
+ conditions.push(emitExactIntegerTest(host, value.name, counter.min, SAFE).ok);
911
+ for (const wrap of counter.wrapBounds) {
912
+ const bound = host.emitExpr(wrap.bound);
913
+ const boundInteger = exactInteger(host, bound, wrap.bound);
914
+ if (boundInteger && boundInteger.range.max <= wrap.limit)
915
+ continue;
916
+ const ok = B.tmp();
917
+ B.line(`${ok} = fcmp ole double ${bound.name}, ${f64Lit(wrap.limit)}`);
918
+ conditions.push(ok);
919
+ }
920
+ }
921
+ for (const check of version.bounded) {
922
+ // `bound <= length - slack` in doubles: both sides are exact (a length
923
+ // is below 2^53 and a slack below 2^32), and NaN fails.
924
+ const bound = host.emitExpr(check.bound).name;
925
+ const length = B.tmp(), room = B.tmp(), ok = B.tmp();
926
+ B.line(`${length} = uitofp i64 ${lengths[check.receiver]} to double`);
927
+ B.line(`${room} = fsub double ${length}, ${f64Lit(check.slack)}`);
928
+ B.line(`${ok} = fcmp ole double ${bound}, ${room}`);
929
+ conditions.push(ok);
930
+ }
485
931
  if (counted && version.affine.length > 0) {
486
932
  // The first and last counter values, in ascending order. The last value
487
933
  // of a non-unit step is exact: `start + ⌊(limit ∓ 1 - start) / step⌋ *
@@ -524,7 +970,7 @@ export function emitBytesLoopVersionGuard(host, version, fast, slow) {
524
970
  for (const term of check.terms) {
525
971
  const value = host.emitExpr(term.expr);
526
972
  if (version.guarded.has(term.key)) {
527
- const tested = emitGuardedTerm(host, value.name);
973
+ const tested = emitExactIntegerTest(host, value.name, GUARDED_TERM.min, GUARDED_TERM.max);
528
974
  conditions.push(tested.ok);
529
975
  const sum = B.tmp();
530
976
  B.line(`${sum} = ${term.sign > 0 ? "add" : "sub"} i64 ${base}, ${tested.integer}`);
@@ -559,6 +1005,25 @@ export function emitBytesLoopVersionGuard(host, version, fast, slow) {
559
1005
  conditions.push(both);
560
1006
  }
561
1007
  }
1008
+ if (version.paired !== null) {
1009
+ // Both counters stay within [lo, hi] (exact integers below 2^53): every
1010
+ // access at either one is in bounds when `lo >= 0` and `hi < length`.
1011
+ const { loop } = version.paired;
1012
+ const [low, high] = [loop.low.start, loop.high.start].map((expr) => {
1013
+ const tested = emitExactIntegerTest(host, host.emitExpr(expr).name, -SAFE, SAFE);
1014
+ conditions.push(tested.ok);
1015
+ return tested.integer;
1016
+ });
1017
+ const nonNegative = B.tmp();
1018
+ B.line(`${nonNegative} = icmp sge i64 ${low}, 0`);
1019
+ conditions.push(nonNegative);
1020
+ for (const receiver of version.paired.receivers) {
1021
+ // Lengths are at most 2^53 elements: a signed comparison is exact.
1022
+ const below = B.tmp();
1023
+ B.line(`${below} = icmp slt i64 ${high}, ${lengths[receiver]}`);
1024
+ conditions.push(below);
1025
+ }
1026
+ }
562
1027
  let valid = "true";
563
1028
  for (const cond of conditions) {
564
1029
  if (valid === "true")
@@ -574,24 +1039,6 @@ export function emitBytesLoopVersionGuard(host, version, fast, slow) {
574
1039
  else
575
1040
  B.condBr(valid, fast, slow);
576
1041
  }
577
- /** Tests that a guarded term is an exact integer within GUARDED_TERM (not
578
- * -0; NaN fails the ordered comparisons) and gives its i64. The integer is
579
- * frozen, so it is a fixed value even when the test fails. */
580
- function emitGuardedTerm(host, value) {
581
- const B = host.B;
582
- const low = B.tmp(), high = B.tmp(), inRange = B.tmp(), raw = B.tmp(), integer = B.tmp(), back = B.tmp(), bits = B.tmp(), backBits = B.tmp(), exact = B.tmp(), ok = B.tmp();
583
- B.line(`${low} = fcmp oge double ${value}, ${f64Lit(GUARDED_TERM.min)}`);
584
- B.line(`${high} = fcmp ole double ${value}, ${f64Lit(GUARDED_TERM.max)}`);
585
- B.line(`${inRange} = and i1 ${low}, ${high}`);
586
- B.line(`${raw} = fptosi double ${value} to i64`);
587
- B.line(`${integer} = freeze i64 ${raw}`);
588
- B.line(`${back} = sitofp i64 ${integer} to double`);
589
- B.line(`${bits} = bitcast double ${value} to i64`);
590
- B.line(`${backBits} = bitcast double ${back} to i64`);
591
- B.line(`${exact} = icmp eq i64 ${bits}, ${backBits}`);
592
- B.line(`${ok} = and i1 ${inRange}, ${exact}`);
593
- return { ok, integer };
594
- }
595
1042
  function scaleCounter(host, value, scale) {
596
1043
  if (scale === 1)
597
1044
  return value;