@scriptc/compiler 0.4.1 → 0.4.2

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 (680) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +582 -78
  2. package/dist/backend/cycle-analysis.d.ts +2 -1
  3. package/dist/backend/cycle-analysis.js +4 -4
  4. package/dist/backend/cycle-analysis.js.map +1 -1
  5. package/dist/backend/cycle-mutability.d.ts +2 -1
  6. package/dist/backend/cycle-mutability.js +2 -2
  7. package/dist/backend/cycle-mutability.js.map +1 -1
  8. package/dist/backend/executable-features.js +4 -1
  9. package/dist/backend/executable-features.js.map +1 -1
  10. package/dist/backend/immutability.d.ts +2 -1
  11. package/dist/backend/immutability.js +2 -2
  12. package/dist/backend/immutability.js.map +1 -1
  13. package/dist/backend/library-pack.js +4 -0
  14. package/dist/backend/library-pack.js.map +1 -1
  15. package/dist/backend/llvm/alloc.d.ts +7 -3
  16. package/dist/backend/llvm/alloc.js +7 -4
  17. package/dist/backend/llvm/alloc.js.map +1 -1
  18. package/dist/backend/llvm/array-search.js +2 -1
  19. package/dist/backend/llvm/array-search.js.map +1 -1
  20. package/dist/backend/llvm/bytes-loop-versions.d.ts +23 -2
  21. package/dist/backend/llvm/bytes-loop-versions.js +115 -19
  22. package/dist/backend/llvm/bytes-loop-versions.js.map +1 -1
  23. package/dist/backend/llvm/bytes-loop-versions.test.js +131 -0
  24. package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -1
  25. package/dist/backend/llvm/classes.d.ts +72 -1
  26. package/dist/backend/llvm/classes.js +331 -45
  27. package/dist/backend/llvm/classes.js.map +1 -1
  28. package/dist/backend/llvm/classes.test.js +223 -16
  29. package/dist/backend/llvm/classes.test.js.map +1 -1
  30. package/dist/backend/llvm/common.d.ts +1 -3
  31. package/dist/backend/llvm/common.js +1 -3
  32. package/dist/backend/llvm/common.js.map +1 -1
  33. package/dist/backend/llvm/constant-callbacks.js +8 -4
  34. package/dist/backend/llvm/constant-callbacks.js.map +1 -1
  35. package/dist/backend/llvm/constant-callbacks.test.js +4 -4
  36. package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
  37. package/dist/backend/llvm/counted-loops.d.ts +4 -1
  38. package/dist/backend/llvm/counted-loops.js +62 -23
  39. package/dist/backend/llvm/counted-loops.js.map +1 -1
  40. package/dist/backend/llvm/dense-array-loops.d.ts +19 -16
  41. package/dist/backend/llvm/dense-array-loops.js +46 -10
  42. package/dist/backend/llvm/dense-array-loops.js.map +1 -1
  43. package/dist/backend/llvm/dense-array-loops.test.js +50 -14
  44. package/dist/backend/llvm/dense-array-loops.test.js.map +1 -1
  45. package/dist/backend/llvm/dyn.d.ts +25 -1
  46. package/dist/backend/llvm/dyn.js +331 -8
  47. package/dist/backend/llvm/dyn.js.map +1 -1
  48. package/dist/backend/llvm/emit-function.js +22 -6
  49. package/dist/backend/llvm/emit-function.js.map +1 -1
  50. package/dist/backend/llvm/emit-module.js +17 -11
  51. package/dist/backend/llvm/emit-module.js.map +1 -1
  52. package/dist/backend/llvm/emit-statements.d.ts +0 -23
  53. package/dist/backend/llvm/emit-statements.js +325 -25
  54. package/dist/backend/llvm/emit-statements.js.map +1 -1
  55. package/dist/backend/llvm/emitter.d.ts +141 -15
  56. package/dist/backend/llvm/emitter.js +537 -64
  57. package/dist/backend/llvm/emitter.js.map +1 -1
  58. package/dist/backend/llvm/expr-async.js +19 -0
  59. package/dist/backend/llvm/expr-async.js.map +1 -1
  60. package/dist/backend/llvm/expr-bytes.d.ts +5 -2
  61. package/dist/backend/llvm/expr-bytes.js +110 -40
  62. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  63. package/dist/backend/llvm/expr-calls.d.ts +1 -1
  64. package/dist/backend/llvm/expr-calls.js +34 -22
  65. package/dist/backend/llvm/expr-calls.js.map +1 -1
  66. package/dist/backend/llvm/expr-containers.js +21 -5
  67. package/dist/backend/llvm/expr-containers.js.map +1 -1
  68. package/dist/backend/llvm/expr-control.js +2 -3
  69. package/dist/backend/llvm/expr-control.js.map +1 -1
  70. package/dist/backend/llvm/expr-dynamic.js +54 -6
  71. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  72. package/dist/backend/llvm/expr-primitives.js +26 -8
  73. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  74. package/dist/backend/llvm/expr-stream-bridges.js +38 -6
  75. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  76. package/dist/backend/llvm/expr-stream-callbacks.js +131 -35
  77. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  78. package/dist/backend/llvm/lib-dispatch.js +10 -0
  79. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  80. package/dist/backend/llvm/lib-filesystem.js +61 -0
  81. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  82. package/dist/backend/llvm/lib-http2.d.ts +4 -0
  83. package/dist/backend/llvm/lib-http2.js +20 -17
  84. package/dist/backend/llvm/lib-http2.js.map +1 -1
  85. package/dist/backend/llvm/lib-process.js +65 -14
  86. package/dist/backend/llvm/lib-process.js.map +1 -1
  87. package/dist/backend/llvm/lib-shared.js +53 -1
  88. package/dist/backend/llvm/lib-shared.js.map +1 -1
  89. package/dist/backend/llvm/lib-stream.js +65 -28
  90. package/dist/backend/llvm/lib-stream.js.map +1 -1
  91. package/dist/backend/llvm/lib-tls.js +23 -0
  92. package/dist/backend/llvm/lib-tls.js.map +1 -1
  93. package/dist/backend/llvm/local-array-reads.js +66 -45
  94. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  95. package/dist/backend/llvm/local-array-reads.test.js +14 -0
  96. package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
  97. package/dist/backend/llvm/publish.d.ts +8 -1
  98. package/dist/backend/llvm/publish.js +64 -25
  99. package/dist/backend/llvm/publish.js.map +1 -1
  100. package/dist/backend/llvm/publish.test.js +3 -0
  101. package/dist/backend/llvm/publish.test.js.map +1 -1
  102. package/dist/backend/llvm/receivers.js +1 -1
  103. package/dist/backend/llvm/receivers.js.map +1 -1
  104. package/dist/backend/llvm/reference-writes.js +2 -0
  105. package/dist/backend/llvm/reference-writes.js.map +1 -1
  106. package/dist/backend/llvm/regex-matchers.js +161 -14
  107. package/dist/backend/llvm/regex-matchers.js.map +1 -1
  108. package/dist/backend/llvm/regex-matchers.test.js +18 -0
  109. package/dist/backend/llvm/regex-matchers.test.js.map +1 -1
  110. package/dist/backend/llvm/shapes.d.ts +9 -7
  111. package/dist/backend/llvm/shapes.js +12 -10
  112. package/dist/backend/llvm/shapes.js.map +1 -1
  113. package/dist/backend/llvm/string-lifetimes.test.js +2 -1
  114. package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
  115. package/dist/backend/llvm/string-reads.d.ts +3 -0
  116. package/dist/backend/llvm/string-reads.js +84 -0
  117. package/dist/backend/llvm/string-reads.js.map +1 -1
  118. package/dist/backend/llvm/wasm-modules.d.ts +6 -5
  119. package/dist/backend/llvm/wasm-modules.js +32 -9
  120. package/dist/backend/llvm/wasm-modules.js.map +1 -1
  121. package/dist/backend/mangle.d.ts +3 -0
  122. package/dist/backend/mangle.js +5 -0
  123. package/dist/backend/mangle.js.map +1 -1
  124. package/dist/backend/native/contracts.d.ts +22 -4
  125. package/dist/backend/native/executable.js +24 -8
  126. package/dist/backend/native/executable.js.map +1 -1
  127. package/dist/backend/native/library.js +1 -0
  128. package/dist/backend/native/library.js.map +1 -1
  129. package/dist/backend/native-codegen.d.ts +11 -6
  130. package/dist/backend/native-codegen.js +36 -9
  131. package/dist/backend/native-codegen.js.map +1 -1
  132. package/dist/backend/native-codegen.test.js +0 -23
  133. package/dist/backend/native-codegen.test.js.map +1 -1
  134. package/dist/backend/native-link-info-core.d.ts +14 -4
  135. package/dist/backend/native-link-info-core.js.map +1 -1
  136. package/dist/backend/optimization.d.ts +2 -2
  137. package/dist/backend/runtime-abi.d.ts +2 -2
  138. package/dist/backend/runtime-abi.js +2 -2
  139. package/dist/backend/runtime-pack-core.d.ts +1 -1
  140. package/dist/backend/runtime-pack-core.js +1 -1
  141. package/dist/backend/runtime-pack-core.js.map +1 -1
  142. package/dist/backend/runtime-pack-targets.test.js +4 -1
  143. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  144. package/dist/backend/runtime-pack.d.ts +0 -21
  145. package/dist/backend/runtime-pack.js +0 -29
  146. package/dist/backend/runtime-pack.js.map +1 -1
  147. package/dist/backend/runtime-pack.test.js +9 -69
  148. package/dist/backend/runtime-pack.test.js.map +1 -1
  149. package/dist/backend/target-diagnostics.js +31 -1
  150. package/dist/backend/target-diagnostics.js.map +1 -1
  151. package/dist/backend/warm-cache.js +3 -0
  152. package/dist/backend/warm-cache.js.map +1 -1
  153. package/dist/cli/command.js +26 -6
  154. package/dist/cli/command.js.map +1 -1
  155. package/dist/cli/usage.d.ts +5 -1
  156. package/dist/cli/usage.js +7 -2
  157. package/dist/cli/usage.js.map +1 -1
  158. package/dist/contracts/check.js +1 -1
  159. package/dist/contracts/check.js.map +1 -1
  160. package/dist/coverage/report.d.ts +7 -2
  161. package/dist/coverage/report.js +18 -0
  162. package/dist/coverage/report.js.map +1 -1
  163. package/dist/coverage/verdict-cache.d.ts +1 -0
  164. package/dist/coverage/verdict-cache.js +4 -0
  165. package/dist/coverage/verdict-cache.js.map +1 -1
  166. package/dist/coverage/verdict-semantic.js +4 -0
  167. package/dist/coverage/verdict-semantic.js.map +1 -1
  168. package/dist/diagnostics/diagnostic.js.map +1 -1
  169. package/dist/diagnostics/dynamic-tier.d.ts +40 -0
  170. package/dist/diagnostics/dynamic-tier.js +57 -0
  171. package/dist/diagnostics/dynamic-tier.js.map +1 -0
  172. package/dist/diagnostics/envelope.d.ts +2 -1
  173. package/dist/diagnostics/envelope.js +5 -2
  174. package/dist/diagnostics/envelope.js.map +1 -1
  175. package/dist/executable/executable-cache.d.ts +23 -1
  176. package/dist/executable/executable-cache.js +59 -7
  177. package/dist/executable/executable-cache.js.map +1 -1
  178. package/dist/executable/executable-cache.test.js +45 -3
  179. package/dist/executable/executable-cache.test.js.map +1 -1
  180. package/dist/executable/prepare.js +3 -1
  181. package/dist/executable/prepare.js.map +1 -1
  182. package/dist/frontend/analysis.js +1 -0
  183. package/dist/frontend/analysis.js.map +1 -1
  184. package/dist/frontend/dispose-hook.d.ts +2 -0
  185. package/dist/frontend/dispose-hook.js +14 -0
  186. package/dist/frontend/dispose-hook.js.map +1 -0
  187. package/dist/frontend/jsx-entities.d.ts +4 -0
  188. package/dist/frontend/jsx-entities.js +259 -0
  189. package/dist/frontend/jsx-entities.js.map +1 -0
  190. package/dist/frontend/jsx-source.d.ts +71 -0
  191. package/dist/frontend/jsx-source.js +781 -0
  192. package/dist/frontend/jsx-source.js.map +1 -0
  193. package/dist/frontend/jsx-source.test.d.ts +1 -0
  194. package/dist/frontend/jsx-source.test.js +200 -0
  195. package/dist/frontend/jsx-source.test.js.map +1 -0
  196. package/dist/frontend/literal-values.test.js +8 -9
  197. package/dist/frontend/literal-values.test.js.map +1 -1
  198. package/dist/frontend/lowering/array-indexed-mutation.js +2 -1
  199. package/dist/frontend/lowering/array-indexed-mutation.js.map +1 -1
  200. package/dist/frontend/lowering/array-values.js +3 -2
  201. package/dist/frontend/lowering/array-values.js.map +1 -1
  202. package/dist/frontend/lowering/binding-analysis.d.ts +1 -1
  203. package/dist/frontend/lowering/binding-analysis.js +2 -2
  204. package/dist/frontend/lowering/binding-analysis.js.map +1 -1
  205. package/dist/frontend/lowering/builtins/arguments.d.ts +3 -0
  206. package/dist/frontend/lowering/builtins/arguments.js +30 -15
  207. package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
  208. package/dist/frontend/lowering/builtins/atomics.js +10 -6
  209. package/dist/frontend/lowering/builtins/atomics.js.map +1 -1
  210. package/dist/frontend/lowering/builtins/child-process-async.js +2 -1
  211. package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -1
  212. package/dist/frontend/lowering/builtins/child-process-sync.js +2 -1
  213. package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -1
  214. package/dist/frontend/lowering/builtins/crypto.d.ts +4 -2
  215. package/dist/frontend/lowering/builtins/crypto.js +59 -3
  216. package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
  217. package/dist/frontend/lowering/builtins/date-classes.d.ts +46 -0
  218. package/dist/frontend/lowering/builtins/date-classes.js +477 -0
  219. package/dist/frontend/lowering/builtins/date-classes.js.map +1 -0
  220. package/dist/frontend/lowering/builtins/dates.d.ts +11 -1
  221. package/dist/frontend/lowering/builtins/dates.js +55 -26
  222. package/dist/frontend/lowering/builtins/dates.js.map +1 -1
  223. package/dist/frontend/lowering/builtins/dh.d.ts +15 -0
  224. package/dist/frontend/lowering/builtins/dh.js +151 -0
  225. package/dist/frontend/lowering/builtins/dh.js.map +1 -0
  226. package/dist/frontend/lowering/builtins/disposable-stack.js +2 -1
  227. package/dist/frontend/lowering/builtins/disposable-stack.js.map +1 -1
  228. package/dist/frontend/lowering/builtins/ecdh.d.ts +12 -1
  229. package/dist/frontend/lowering/builtins/ecdh.js +7 -7
  230. package/dist/frontend/lowering/builtins/ecdh.js.map +1 -1
  231. package/dist/frontend/lowering/builtins/errors.d.ts +15 -0
  232. package/dist/frontend/lowering/builtins/errors.js +110 -0
  233. package/dist/frontend/lowering/builtins/errors.js.map +1 -1
  234. package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +1 -1
  235. package/dist/frontend/lowering/builtins/filesystem-calls.js +23 -17
  236. package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
  237. package/dist/frontend/lowering/builtins/filesystem.js +6 -4
  238. package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
  239. package/dist/frontend/lowering/builtins/fs-paths.d.ts +15 -0
  240. package/dist/frontend/lowering/builtins/fs-paths.js +209 -0
  241. package/dist/frontend/lowering/builtins/fs-paths.js.map +1 -0
  242. package/dist/frontend/lowering/builtins/hash-stream.d.ts +16 -4
  243. package/dist/frontend/lowering/builtins/hash-stream.js +86 -23
  244. package/dist/frontend/lowering/builtins/hash-stream.js.map +1 -1
  245. package/dist/frontend/lowering/builtins/json.js +2 -1
  246. package/dist/frontend/lowering/builtins/json.js.map +1 -1
  247. package/dist/frontend/lowering/builtins/key-object.d.ts +2 -1
  248. package/dist/frontend/lowering/builtins/key-object.js +20 -7
  249. package/dist/frontend/lowering/builtins/key-object.js.map +1 -1
  250. package/dist/frontend/lowering/builtins/module-calls.js +11 -4
  251. package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
  252. package/dist/frontend/lowering/builtins/numbers.js +9 -5
  253. package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
  254. package/dist/frontend/lowering/builtins/operating-system.js +4 -3
  255. package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
  256. package/dist/frontend/lowering/builtins/performance.js +3 -2
  257. package/dist/frontend/lowering/builtins/performance.js.map +1 -1
  258. package/dist/frontend/lowering/builtins/process.js +3 -2
  259. package/dist/frontend/lowering/builtins/process.js.map +1 -1
  260. package/dist/frontend/lowering/builtins/promises.js +3 -2
  261. package/dist/frontend/lowering/builtins/promises.js.map +1 -1
  262. package/dist/frontend/lowering/builtins/promisify-callback.js +2 -1
  263. package/dist/frontend/lowering/builtins/promisify-callback.js.map +1 -1
  264. package/dist/frontend/lowering/builtins/readline.d.ts +2 -1
  265. package/dist/frontend/lowering/builtins/readline.js +23 -6
  266. package/dist/frontend/lowering/builtins/readline.js.map +1 -1
  267. package/dist/frontend/lowering/builtins/strings.js +13 -5
  268. package/dist/frontend/lowering/builtins/strings.js.map +1 -1
  269. package/dist/frontend/lowering/builtins/text-codecs.js +2 -1
  270. package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
  271. package/dist/frontend/lowering/builtins/timers.js +1 -1
  272. package/dist/frontend/lowering/builtins/timers.js.map +1 -1
  273. package/dist/frontend/lowering/builtins/url.js +4 -3
  274. package/dist/frontend/lowering/builtins/url.js.map +1 -1
  275. package/dist/frontend/lowering/builtins/v8.js +2 -1
  276. package/dist/frontend/lowering/builtins/v8.js.map +1 -1
  277. package/dist/frontend/lowering/builtins/webcrypto.js +39 -20
  278. package/dist/frontend/lowering/builtins/webcrypto.js.map +1 -1
  279. package/dist/frontend/lowering/call-arguments.js +2 -1
  280. package/dist/frontend/lowering/call-arguments.js.map +1 -1
  281. package/dist/frontend/lowering/call-signatures.js +13 -6
  282. package/dist/frontend/lowering/call-signatures.js.map +1 -1
  283. package/dist/frontend/lowering/caught-value-dispatch.d.ts +18 -1
  284. package/dist/frontend/lowering/caught-value-dispatch.js +201 -32
  285. package/dist/frontend/lowering/caught-value-dispatch.js.map +1 -1
  286. package/dist/frontend/lowering/class-assertions.js +3 -2
  287. package/dist/frontend/lowering/class-assertions.js.map +1 -1
  288. package/dist/frontend/lowering/class-construction.d.ts +2 -1
  289. package/dist/frontend/lowering/class-construction.js +8 -13
  290. package/dist/frontend/lowering/class-construction.js.map +1 -1
  291. package/dist/frontend/lowering/class-descriptors.js +1 -1
  292. package/dist/frontend/lowering/class-descriptors.js.map +1 -1
  293. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +34 -0
  294. package/dist/frontend/lowering/class-dynamic-dispatch.js +568 -151
  295. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  296. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +77 -0
  297. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
  298. package/dist/frontend/lowering/class-method-mutations.js +3 -0
  299. package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
  300. package/dist/frontend/lowering/class-method-values.js +1 -1
  301. package/dist/frontend/lowering/class-method-values.js.map +1 -1
  302. package/dist/frontend/lowering/class-protocols.d.ts +7 -0
  303. package/dist/frontend/lowering/class-protocols.js +64 -4
  304. package/dist/frontend/lowering/class-protocols.js.map +1 -1
  305. package/dist/frontend/lowering/class-prototypes.d.ts +5 -0
  306. package/dist/frontend/lowering/class-prototypes.js +36 -3
  307. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  308. package/dist/frontend/lowering/class-to-primitive.js +25 -5
  309. package/dist/frontend/lowering/class-to-primitive.js.map +1 -1
  310. package/dist/frontend/lowering/class-unions.js +2 -1
  311. package/dist/frontend/lowering/class-unions.js.map +1 -1
  312. package/dist/frontend/lowering/coercions/function-adapters.js +6 -5
  313. package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
  314. package/dist/frontend/lowering/coercions/structural.js +8 -7
  315. package/dist/frontend/lowering/coercions/structural.js.map +1 -1
  316. package/dist/frontend/lowering/coercions/unions.js +8 -7
  317. package/dist/frontend/lowering/coercions/unions.js.map +1 -1
  318. package/dist/frontend/lowering/collection-ingestion.js +2 -1
  319. package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
  320. package/dist/frontend/lowering/containers/array-callbacks.d.ts +7 -0
  321. package/dist/frontend/lowering/containers/array-callbacks.js +14 -13
  322. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  323. package/dist/frontend/lowering/containers/array-concat.js +2 -1
  324. package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
  325. package/dist/frontend/lowering/containers/array-construction.js +25 -4
  326. package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
  327. package/dist/frontend/lowering/containers/array-methods.js +6 -5
  328. package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
  329. package/dist/frontend/lowering/containers/array-pipelines.js +2 -1
  330. package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
  331. package/dist/frontend/lowering/containers/bytes.d.ts +1 -1
  332. package/dist/frontend/lowering/containers/bytes.js +129 -28
  333. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  334. package/dist/frontend/lowering/containers/callback-arguments.js +52 -2
  335. package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
  336. package/dist/frontend/lowering/containers/collection-grouping.js +3 -2
  337. package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
  338. package/dist/frontend/lowering/containers/collection-methods.js +8 -7
  339. package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
  340. package/dist/frontend/lowering/containers/indexed-objects.js +8 -7
  341. package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
  342. package/dist/frontend/lowering/containers/iterator-helpers.d.ts +32 -1
  343. package/dist/frontend/lowering/containers/iterator-helpers.js +6 -5
  344. package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -1
  345. package/dist/frontend/lowering/containers/string-and-regexp.js +36 -9
  346. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  347. package/dist/frontend/lowering/containers/string-replacement.js +2 -1
  348. package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
  349. package/dist/frontend/lowering/cycle-initialization.js +25 -4
  350. package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
  351. package/dist/frontend/lowering/deferred-module-initializers.d.ts +18 -1
  352. package/dist/frontend/lowering/deferred-module-initializers.js +226 -115
  353. package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
  354. package/dist/frontend/lowering/deferred-module-initializers.test.js +28 -0
  355. package/dist/frontend/lowering/deferred-module-initializers.test.js.map +1 -1
  356. package/dist/frontend/lowering/dispatch-sites.d.ts +59 -0
  357. package/dist/frontend/lowering/dispatch-sites.js +204 -0
  358. package/dist/frontend/lowering/dispatch-sites.js.map +1 -0
  359. package/dist/frontend/lowering/dispatch-sites.test.d.ts +1 -0
  360. package/dist/frontend/lowering/dispatch-sites.test.js +59 -0
  361. package/dist/frontend/lowering/dispatch-sites.test.js.map +1 -0
  362. package/dist/frontend/lowering/dyn-streams.d.ts +3 -0
  363. package/dist/frontend/lowering/dyn-streams.js +1 -1
  364. package/dist/frontend/lowering/dyn-streams.js.map +1 -1
  365. package/dist/frontend/lowering/dynamic-tier.d.ts +25 -0
  366. package/dist/frontend/lowering/dynamic-tier.js +327 -0
  367. package/dist/frontend/lowering/dynamic-tier.js.map +1 -0
  368. package/dist/frontend/lowering/error-methods.js +4 -0
  369. package/dist/frontend/lowering/error-methods.js.map +1 -1
  370. package/dist/frontend/lowering/expressions/array-literals.js +15 -0
  371. package/dist/frontend/lowering/expressions/array-literals.js.map +1 -1
  372. package/dist/frontend/lowering/expressions/binary.js +45 -3
  373. package/dist/frontend/lowering/expressions/binary.js.map +1 -1
  374. package/dist/frontend/lowering/expressions/element-access.js +17 -1
  375. package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
  376. package/dist/frontend/lowering/expressions/identifiers.js +46 -7
  377. package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
  378. package/dist/frontend/lowering/expressions/narrowing.js +35 -5
  379. package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
  380. package/dist/frontend/lowering/expressions/object-literals.d.ts +0 -3
  381. package/dist/frontend/lowering/expressions/object-literals.js +27 -6
  382. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  383. package/dist/frontend/lowering/expressions/optional-chains.js +5 -5
  384. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  385. package/dist/frontend/lowering/expressions/property-access.d.ts +0 -4
  386. package/dist/frontend/lowering/expressions/property-access.js +99 -7
  387. package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
  388. package/dist/frontend/lowering/expressions/relational.js +63 -5
  389. package/dist/frontend/lowering/expressions/relational.js.map +1 -1
  390. package/dist/frontend/lowering/expressions/updates.js +63 -9
  391. package/dist/frontend/lowering/expressions/updates.js.map +1 -1
  392. package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +6 -1
  393. package/dist/frontend/lowering/generator-dynamic-dispatch.js +20 -30
  394. package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
  395. package/dist/frontend/lowering/generic-functions.d.ts +42 -1
  396. package/dist/frontend/lowering/generic-functions.js +448 -18
  397. package/dist/frontend/lowering/generic-functions.js.map +1 -1
  398. package/dist/frontend/lowering/intern-tables.js +2 -1
  399. package/dist/frontend/lowering/intern-tables.js.map +1 -1
  400. package/dist/frontend/lowering/iterator-adapters.js +9 -8
  401. package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
  402. package/dist/frontend/lowering/js-dynamic-objects.js +3 -2
  403. package/dist/frontend/lowering/js-dynamic-objects.js.map +1 -1
  404. package/dist/frontend/lowering/json-require.js +2 -1
  405. package/dist/frontend/lowering/json-require.js.map +1 -1
  406. package/dist/frontend/lowering/key-order-witness.d.ts +7 -2
  407. package/dist/frontend/lowering/key-order-witness.js +21 -4
  408. package/dist/frontend/lowering/key-order-witness.js.map +1 -1
  409. package/dist/frontend/lowering/key-order-witness.test.js +38 -2
  410. package/dist/frontend/lowering/key-order-witness.test.js.map +1 -1
  411. package/dist/frontend/lowering/lifetime-regions.js +2 -1
  412. package/dist/frontend/lowering/lifetime-regions.js.map +1 -1
  413. package/dist/frontend/lowering/lower-assert.js +6 -5
  414. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  415. package/dist/frontend/lowering/lower-async-iteration.js +3 -1
  416. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
  417. package/dist/frontend/lowering/lower-calls.d.ts +4 -0
  418. package/dist/frontend/lowering/lower-calls.js +339 -91
  419. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  420. package/dist/frontend/lowering/lower-classes.d.ts +18 -0
  421. package/dist/frontend/lowering/lower-classes.js +280 -25
  422. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  423. package/dist/frontend/lowering/lower-dgram.js +3 -2
  424. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  425. package/dist/frontend/lowering/lower-event-emitter.d.ts +14 -0
  426. package/dist/frontend/lowering/lower-event-emitter.js +267 -20
  427. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  428. package/dist/frontend/lowering/lower-exprs.d.ts +19 -2
  429. package/dist/frontend/lowering/lower-exprs.js +116 -11
  430. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  431. package/dist/frontend/lowering/lower-functions.js +304 -72
  432. package/dist/frontend/lowering/lower-functions.js.map +1 -1
  433. package/dist/frontend/lowering/lower-inspect.js +10 -6
  434. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  435. package/dist/frontend/lowering/lower-mixins.js +2 -1
  436. package/dist/frontend/lowering/lower-mixins.js.map +1 -1
  437. package/dist/frontend/lowering/lower-mock.js +2 -1
  438. package/dist/frontend/lowering/lower-mock.js.map +1 -1
  439. package/dist/frontend/lowering/lower-modules.js +15 -5
  440. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  441. package/dist/frontend/lowering/lower-modules.test.js +2 -2
  442. package/dist/frontend/lowering/lower-modules.test.js.map +1 -1
  443. package/dist/frontend/lowering/lower-namespaces.d.ts +2 -1
  444. package/dist/frontend/lowering/lower-namespaces.js +4 -3
  445. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  446. package/dist/frontend/lowering/lower-server.d.ts +10 -0
  447. package/dist/frontend/lowering/lower-server.js +237 -59
  448. package/dist/frontend/lowering/lower-server.js.map +1 -1
  449. package/dist/frontend/lowering/lower-stdlib.js +12 -10
  450. package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
  451. package/dist/frontend/lowering/lower-stmts.js +168 -20
  452. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  453. package/dist/frontend/lowering/lower-stmts.test.js +1 -1
  454. package/dist/frontend/lowering/lower-stmts.test.js.map +1 -1
  455. package/dist/frontend/lowering/lower-stream.js +575 -165
  456. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  457. package/dist/frontend/lowering/lower-timers.js +4 -3
  458. package/dist/frontend/lowering/lower-timers.js.map +1 -1
  459. package/dist/frontend/lowering/lowerer.d.ts +125 -28
  460. package/dist/frontend/lowering/lowerer.js +557 -63
  461. package/dist/frontend/lowering/lowerer.js.map +1 -1
  462. package/dist/frontend/lowering/lowerer.test.js +21 -9
  463. package/dist/frontend/lowering/lowerer.test.js.map +1 -1
  464. package/dist/frontend/lowering/narrowing-stability.js +5 -0
  465. package/dist/frontend/lowering/narrowing-stability.js.map +1 -1
  466. package/dist/frontend/lowering/native-ffi.js +1 -1
  467. package/dist/frontend/lowering/native-ffi.js.map +1 -1
  468. package/dist/frontend/lowering/object-enumeration-receiver.js +2 -1
  469. package/dist/frontend/lowering/object-enumeration-receiver.js.map +1 -1
  470. package/dist/frontend/lowering/pairs-snapshot.js +2 -1
  471. package/dist/frontend/lowering/pairs-snapshot.js.map +1 -1
  472. package/dist/frontend/lowering/private-brands.d.ts +9 -0
  473. package/dist/frontend/lowering/private-brands.js +66 -15
  474. package/dist/frontend/lowering/private-brands.js.map +1 -1
  475. package/dist/frontend/lowering/promise-executor-adapter.js +2 -1
  476. package/dist/frontend/lowering/promise-executor-adapter.js.map +1 -1
  477. package/dist/frontend/lowering/require-initialization.js +2 -1
  478. package/dist/frontend/lowering/require-initialization.js.map +1 -1
  479. package/dist/frontend/lowering/runtime-optional-elements.d.ts +5 -0
  480. package/dist/frontend/lowering/runtime-optional-elements.js +17 -1
  481. package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -1
  482. package/dist/frontend/lowering/runtime-optional-records.d.ts +2 -0
  483. package/dist/frontend/lowering/runtime-optional-records.js +18 -5
  484. package/dist/frontend/lowering/runtime-optional-records.js.map +1 -1
  485. package/dist/frontend/lowering/site-dependencies.d.ts +35 -0
  486. package/dist/frontend/lowering/site-dependencies.js +84 -0
  487. package/dist/frontend/lowering/site-dependencies.js.map +1 -0
  488. package/dist/frontend/lowering/site-dependencies.test.d.ts +1 -0
  489. package/dist/frontend/lowering/site-dependencies.test.js +53 -0
  490. package/dist/frontend/lowering/site-dependencies.test.js.map +1 -0
  491. package/dist/frontend/lowering/stable-names.d.ts +11 -0
  492. package/dist/frontend/lowering/stable-names.js +35 -0
  493. package/dist/frontend/lowering/stable-names.js.map +1 -0
  494. package/dist/frontend/lowering/static-typeof.d.ts +2 -2
  495. package/dist/frontend/lowering/static-typeof.js +42 -3
  496. package/dist/frontend/lowering/static-typeof.js.map +1 -1
  497. package/dist/frontend/lowering/strict-equality.js +2 -1
  498. package/dist/frontend/lowering/strict-equality.js.map +1 -1
  499. package/dist/frontend/lowering/structural-positions.d.ts +32 -0
  500. package/dist/frontend/lowering/structural-positions.js +108 -0
  501. package/dist/frontend/lowering/structural-positions.js.map +1 -0
  502. package/dist/frontend/lowering/surfaces.js +42 -26
  503. package/dist/frontend/lowering/surfaces.js.map +1 -1
  504. package/dist/frontend/lowering/var-hoisting.js +37 -3
  505. package/dist/frontend/lowering/var-hoisting.js.map +1 -1
  506. package/dist/frontend/npm-static-tsc-helpers.d.ts +5 -0
  507. package/dist/frontend/npm-static-tsc-helpers.js +106 -0
  508. package/dist/frontend/npm-static-tsc-helpers.js.map +1 -0
  509. package/dist/frontend/npm-static-tsc-helpers.test.d.ts +1 -0
  510. package/dist/frontend/npm-static-tsc-helpers.test.js +58 -0
  511. package/dist/frontend/npm-static-tsc-helpers.test.js.map +1 -0
  512. package/dist/frontend/npm-static-type-exports-host.d.ts +8 -0
  513. package/dist/frontend/npm-static-type-exports-host.js +214 -0
  514. package/dist/frontend/npm-static-type-exports-host.js.map +1 -0
  515. package/dist/frontend/npm-static-type-exports-host.test.d.ts +1 -0
  516. package/dist/frontend/npm-static-type-exports-host.test.js +53 -0
  517. package/dist/frontend/npm-static-type-exports-host.test.js.map +1 -0
  518. package/dist/frontend/npm-static-type-exports.d.ts +52 -0
  519. package/dist/frontend/npm-static-type-exports.js +261 -0
  520. package/dist/frontend/npm-static-type-exports.js.map +1 -0
  521. package/dist/frontend/npm-static-type-exports.test.d.ts +1 -0
  522. package/dist/frontend/npm-static-type-exports.test.js +103 -0
  523. package/dist/frontend/npm-static-type-exports.test.js.map +1 -0
  524. package/dist/frontend/npm-static-umd.d.ts +6 -0
  525. package/dist/frontend/npm-static-umd.js +203 -0
  526. package/dist/frontend/npm-static-umd.js.map +1 -0
  527. package/dist/frontend/npm-static-umd.test.d.ts +1 -0
  528. package/dist/frontend/npm-static-umd.test.js +105 -0
  529. package/dist/frontend/npm-static-umd.test.js.map +1 -0
  530. package/dist/frontend/npm-static.d.ts +8 -0
  531. package/dist/frontend/npm-static.js +47 -2
  532. package/dist/frontend/npm-static.js.map +1 -1
  533. package/dist/frontend/program.d.ts +13 -0
  534. package/dist/frontend/program.js +103 -6
  535. package/dist/frontend/program.js.map +1 -1
  536. package/dist/frontend/program.test.js +1 -1
  537. package/dist/frontend/program.test.js.map +1 -1
  538. package/dist/frontend/services.d.ts +6 -0
  539. package/dist/frontend/services.js +18 -0
  540. package/dist/frontend/services.js.map +1 -1
  541. package/dist/frontend/ts7/ast-node.d.ts +21 -7
  542. package/dist/frontend/ts7/ast-node.js +131 -29
  543. package/dist/frontend/ts7/ast-node.js.map +1 -1
  544. package/dist/frontend/ts7/ast-node.test.js +60 -0
  545. package/dist/frontend/ts7/ast-node.test.js.map +1 -1
  546. package/dist/frontend/ts7/ast-wire.d.ts +27 -2
  547. package/dist/frontend/ts7/ast-wire.js +124 -21
  548. package/dist/frontend/ts7/ast-wire.js.map +1 -1
  549. package/dist/frontend/ts7/ast.d.ts +23 -2
  550. package/dist/frontend/ts7/ast.js +143 -2
  551. package/dist/frontend/ts7/ast.js.map +1 -1
  552. package/dist/frontend/ts7/checker.d.ts +13 -1
  553. package/dist/frontend/ts7/checker.js +75 -1
  554. package/dist/frontend/ts7/checker.js.map +1 -1
  555. package/dist/frontend/ts7/checker.test.js +9 -6
  556. package/dist/frontend/ts7/checker.test.js.map +1 -1
  557. package/dist/frontend/ts7/enums.d.ts +3 -3
  558. package/dist/frontend/ts7/enums.generated.d.ts +10 -0
  559. package/dist/frontend/ts7/enums.generated.js +21 -0
  560. package/dist/frontend/ts7/enums.generated.js.map +1 -1
  561. package/dist/frontend/ts7/enums.js +19 -0
  562. package/dist/frontend/ts7/enums.js.map +1 -1
  563. package/dist/frontend/ts7/program-host.js +5 -2
  564. package/dist/frontend/ts7/program-host.js.map +1 -1
  565. package/dist/frontend/ts7/semantic-checker.d.ts +10 -0
  566. package/dist/frontend/ts7/semantic-checker.js +25 -20
  567. package/dist/frontend/ts7/semantic-checker.js.map +1 -1
  568. package/dist/frontend/ts7/semantic-json.d.ts +13 -0
  569. package/dist/frontend/ts7/semantic-json.js +146 -0
  570. package/dist/frontend/ts7/semantic-json.js.map +1 -1
  571. package/dist/frontend/ts7/semantic-json.test.js +57 -1
  572. package/dist/frontend/ts7/semantic-json.test.js.map +1 -1
  573. package/dist/frontend/ts7/semantic-model.d.ts +15 -0
  574. package/dist/frontend/ts7/semantic-model.js +67 -19
  575. package/dist/frontend/ts7/semantic-model.js.map +1 -1
  576. package/dist/frontend/ts7/semantic-model.test.js +3 -2
  577. package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
  578. package/dist/frontend/ts7/session.js +1 -1
  579. package/dist/frontend/ts7/session.js.map +1 -1
  580. package/dist/frontend/tsc-codes.d.ts +1 -1
  581. package/dist/frontend/tsc-codes.js +7 -0
  582. package/dist/frontend/tsc-codes.js.map +1 -1
  583. package/dist/frontend/type-mapper.d.ts +38 -6
  584. package/dist/frontend/type-mapper.js +265 -32
  585. package/dist/frontend/type-mapper.js.map +1 -1
  586. package/dist/frontend/type-mapper.test.js +1 -1
  587. package/dist/frontend/type-mapper.test.js.map +1 -1
  588. package/dist/frontend-process-args.d.ts +4 -0
  589. package/dist/frontend-process-args.js +52 -0
  590. package/dist/frontend-process-args.js.map +1 -0
  591. package/dist/frontend-process-args.test.d.ts +1 -0
  592. package/dist/frontend-process-args.test.js +47 -0
  593. package/dist/frontend-process-args.test.js.map +1 -0
  594. package/dist/frontend-process.d.ts +1 -0
  595. package/dist/frontend-process.js +23 -0
  596. package/dist/frontend-process.js.map +1 -0
  597. package/dist/heap-collection.d.ts +16 -0
  598. package/dist/heap-collection.js +42 -0
  599. package/dist/heap-collection.js.map +1 -0
  600. package/dist/heap-collection.test.d.ts +1 -0
  601. package/dist/heap-collection.test.js +59 -0
  602. package/dist/heap-collection.test.js.map +1 -0
  603. package/dist/heap-pressure.d.ts +2 -0
  604. package/dist/heap-pressure.js +12 -0
  605. package/dist/heap-pressure.js.map +1 -0
  606. package/dist/index.d.ts +7 -0
  607. package/dist/index.js +402 -86
  608. package/dist/index.js.map +1 -1
  609. package/dist/ir/array-length-stability.js +7 -0
  610. package/dist/ir/array-length-stability.js.map +1 -1
  611. package/dist/ir/array-length-stability.test.js +25 -0
  612. package/dist/ir/array-length-stability.test.js.map +1 -1
  613. package/dist/ir/builtin-effects.js +28 -0
  614. package/dist/ir/builtin-effects.js.map +1 -1
  615. package/dist/ir/builtin-signatures.d.ts +5 -1
  616. package/dist/ir/builtin-signatures.js +141 -12
  617. package/dist/ir/builtin-signatures.js.map +1 -1
  618. package/dist/ir/final-fields.d.ts +2 -1
  619. package/dist/ir/final-fields.js +2 -2
  620. package/dist/ir/final-fields.js.map +1 -1
  621. package/dist/ir/function-references.test.js +2 -0
  622. package/dist/ir/function-references.test.js.map +1 -1
  623. package/dist/ir/int32-slots.d.ts +13 -5
  624. package/dist/ir/int32-slots.js +112 -115
  625. package/dist/ir/int32-slots.js.map +1 -1
  626. package/dist/ir/int32-slots.test.js +3 -1
  627. package/dist/ir/int32-slots.test.js.map +1 -1
  628. package/dist/ir/integer-loop-facts.d.ts +9 -4
  629. package/dist/ir/integer-loop-facts.js +93 -18
  630. package/dist/ir/integer-loop-facts.js.map +1 -1
  631. package/dist/ir/integer-loops.d.ts +49 -0
  632. package/dist/ir/integer-loops.js +193 -39
  633. package/dist/ir/integer-loops.js.map +1 -1
  634. package/dist/ir/integer-loops.test.js +201 -1
  635. package/dist/ir/integer-loops.test.js.map +1 -1
  636. package/dist/ir/integer-ranges.test.js +64 -0
  637. package/dist/ir/integer-ranges.test.js.map +1 -1
  638. package/dist/ir/ir.d.ts +17 -2
  639. package/dist/ir/ir.js +3 -1
  640. package/dist/ir/ir.js.map +1 -1
  641. package/dist/ir/runtime-features.d.ts +31 -7
  642. package/dist/ir/runtime-features.js +138 -11
  643. package/dist/ir/runtime-features.js.map +1 -1
  644. package/dist/ir/tiers.js +1 -0
  645. package/dist/ir/tiers.js.map +1 -1
  646. package/dist/ir/traverse.d.ts +2 -0
  647. package/dist/ir/traverse.js +14 -2
  648. package/dist/ir/traverse.js.map +1 -1
  649. package/dist/ir/validate.js +56 -16
  650. package/dist/ir/validate.js.map +1 -1
  651. package/dist/library/ir-policy.js +10 -0
  652. package/dist/library/ir-policy.js.map +1 -1
  653. package/dist/library/library-cache.d.ts +2 -0
  654. package/dist/library/library-cache.js.map +1 -1
  655. package/dist/library/prepare.js +2 -0
  656. package/dist/library/prepare.js.map +1 -1
  657. package/dist/native/cli.js +5 -0
  658. package/dist/native/cli.js.map +1 -1
  659. package/dist/native/prepare.js +5 -1
  660. package/dist/native/prepare.js.map +1 -1
  661. package/dist/native/sanitizer.test.js +4 -1
  662. package/dist/native/sanitizer.test.js.map +1 -1
  663. package/dist/startup-cache.d.ts +1 -0
  664. package/dist/startup-cache.js +1 -0
  665. package/dist/startup-cache.js.map +1 -1
  666. package/dist/text-parts.d.ts +7 -0
  667. package/dist/text-parts.js +44 -0
  668. package/dist/text-parts.js.map +1 -1
  669. package/dist/text-parts.test.d.ts +1 -0
  670. package/dist/text-parts.test.js +46 -0
  671. package/dist/text-parts.test.js.map +1 -0
  672. package/dist/timing.d.ts +9 -2
  673. package/dist/timing.js +7 -4
  674. package/dist/timing.js.map +1 -1
  675. package/dist/wasm/translate.d.ts +4 -0
  676. package/dist/wasm/translate.js +2 -2
  677. package/dist/wasm/translate.js.map +1 -1
  678. package/package.json +21 -21
  679. package/shims/undici/core/client.ts +4 -4
  680. package/surface-manifest.json +19 -49
@@ -17,18 +17,22 @@ import { emitDenseArrayGet, emitDenseArrayPop, emitDenseArraySet } from "./dense
17
17
  import { emitBorrowedInput } from "./borrowed-inputs.js";
18
18
  import { f64Lit, llvmCommentText, loadArrCount, sizeToDouble } from "./common.js";
19
19
  import { RESULT_DST_ID, RESULT_ENTRY_PREFIX } from "./record-results.js";
20
- import { matchIntegerArrayForLoop, matchIntegerBytesForLoop, matchIntegerCountedForLoop, } from "../../ir/integer-loops.js";
20
+ import { matchIntegerArrayForLoop, matchIntegerBytesForLoop, matchIntegerCountedForLoop, matchIntegerPairedForLoop, } from "../../ir/integer-loops.js";
21
21
  import { emitByteWindowGuard, matchByteWindow } from "./byte-windows.js";
22
22
  import { countedDenseShape, emitDenseLoopGuard, matchDenseArrayLoop } from "./dense-array-loops.js";
23
- import { emitCountedLoopLimit, emitCountedLoopSafety } from "./counted-loops.js";
23
+ import { emitCountedLoopLimit, emitCountedLoopSafety, emitPairedLoopSafety, } from "./counted-loops.js";
24
24
  import { emitBytesLoopVersionGuard } from "./bytes-loop-versions.js";
25
25
  import { mangleLocal } from "../mangle.js";
26
26
  import { LlvmUnsupportedError } from "./unsupported.js";
27
+ import { everyExprChild, everyStmtChild } from "../../ir/traverse.js";
28
+ import { widenInteger } from "./integer-values.js";
27
29
  import { SCALAR_UNION_RESULT } from "./int32-abi.js";
28
30
  import { emitLiteralSwitch } from "./switch-dispatch.js";
29
31
  import { SPECULATIVE_RANGE, emitSafeIntegerCheck, emitSpeculativeInteger, planProvenIntegerLoop, planSpeculativeLoop, speculativeReads, speculativeWriteTarget, } from "./speculative-integers.js";
30
32
  import { emitConcatInputs, emitMixedConcat, numberPart, stringParts, } from "./string-construction.js";
31
33
  import { emitStringInputs } from "./string-lifetimes.js";
34
+ /** A callback loop version copies the loop; keep the copies small. */
35
+ const MAX_CALLBACK_VERSION_COST = 400;
32
36
  export function emitStmtBody(emitter, s) {
33
37
  const B = emitter.B;
34
38
  emitter.frames.push([]);
@@ -216,6 +220,7 @@ export function emitStmtBody(emitter, s) {
216
220
  emitter.toFrame(v);
217
221
  B.line(`store ${emitter.llType(b.type)} ${v.name}, ptr ${b.slot}`);
218
222
  emitter.storeIntegerView(s.localId, v, s.init);
223
+ storeIntegerTemp(emitter, s.localId, b, v);
219
224
  if (isRefCounted(b.type)) {
220
225
  emitter.scopes[emitter.scopes.length - 1].push({ slot: b.slot, type: b.type });
221
226
  emitter.noteLastUseMove(s, b);
@@ -443,7 +448,7 @@ export function emitStmtBody(emitter, s) {
443
448
  const v = emitter.emitExpr(s.value);
444
449
  if (s.arr.type.kind !== "bytes")
445
450
  throw new InternalCompilerError("llvm emitter bug: bytesSet on non-bytes");
446
- emitter.emitBytesSet(s.arr.type.elem, arr.name, idx, v, s.index, s.value, emitter.bytesBounds.has(s));
451
+ emitter.emitBytesSet(s.arr.type.elem, arr.name, idx, v, s.index, s.value, emitter.bytesBounds.has(s), emitter.bytesOwned.has(s));
447
452
  break;
448
453
  }
449
454
  case "fieldSet":
@@ -481,7 +486,7 @@ export function emitStmtBody(emitter, s) {
481
486
  else if (emitter.publishedTypes?.recordGuarded(s.shapeId) === true)
482
487
  emitter.emitPublishedFieldGuard(obj.name, null, s.field);
483
488
  const { ptr, type, inline } = s.kind === "fieldSet"
484
- ? emitter.classFieldPtr(obj.name, s.className, s.field)
489
+ ? emitter.classFieldPtr(obj.name, s.className, s.field, "compressed")
485
490
  : emitter.recordFieldPtr(obj.name, s.shapeId, s.field);
486
491
  // A result-slot entry fills zeroed caller storage, each field once.
487
492
  if (s.kind === "recordSet" &&
@@ -704,6 +709,11 @@ export function emitStmtBody(emitter, s) {
704
709
  break;
705
710
  }
706
711
  case "while": {
712
+ const callbacks = callbackVersionBindings(emitter, s);
713
+ if (callbacks) {
714
+ emitCallbackVersionedLoop(emitter, s, callbacks);
715
+ break;
716
+ }
707
717
  const workerBudget = emitter.workerLoopBudget(s);
708
718
  const le = B.newLabel("loop.e");
709
719
  emitter.emitLoopCopies(s, true, le, (exit) => {
@@ -712,6 +722,7 @@ export function emitStmtBody(emitter, s) {
712
722
  const lp = workerBudget !== null ? B.newLabel("loop.p") : lc;
713
723
  B.br(lc);
714
724
  B.startBlock(lc);
725
+ enterLoopHeader(emitter, lc);
715
726
  B.condBr(emitter.emitCondition(s.cond), lb, exit);
716
727
  B.startBlock(lb);
717
728
  emitter.jumpTargets.push({
@@ -736,6 +747,11 @@ export function emitStmtBody(emitter, s) {
736
747
  break;
737
748
  }
738
749
  case "doWhile": {
750
+ const callbacks = callbackVersionBindings(emitter, s);
751
+ if (callbacks) {
752
+ emitCallbackVersionedLoop(emitter, s, callbacks);
753
+ break;
754
+ }
739
755
  const workerBudget = emitter.workerLoopBudget(s);
740
756
  // Body first (runs at least once); continue jumps to the CONDITION.
741
757
  const le = B.newLabel("loop.e");
@@ -744,6 +760,7 @@ export function emitStmtBody(emitter, s) {
744
760
  const lc = B.newLabel("loop.c");
745
761
  B.br(lb);
746
762
  B.startBlock(lb);
763
+ enterLoopHeader(emitter, lb);
747
764
  emitter.jumpTargets.push({
748
765
  kind: "loop",
749
766
  brkLabel: exit,
@@ -764,6 +781,11 @@ export function emitStmtBody(emitter, s) {
764
781
  break;
765
782
  }
766
783
  case "for": {
784
+ const callbacks = callbackVersionBindings(emitter, s);
785
+ if (callbacks) {
786
+ emitCallbackVersionedLoop(emitter, s, callbacks);
787
+ break;
788
+ }
767
789
  // The init's scope wraps the whole loop (break/continue must NOT
768
790
  // release it — scopeDepth captured after the push, C parity).
769
791
  const integerArrayLoop = emitter.debug === null
@@ -774,7 +796,13 @@ export function emitStmtBody(emitter, s) {
774
796
  const countedLoop = !integerLoop && emitter.countedLoopsEnabled
775
797
  ? matchIntegerCountedForLoop(s, emitter.numericLocals, emitter.integerRanges, emitter.unaliasedArrays)
776
798
  : null;
777
- const window = countedLoop && emitter.byteWindowsEnabled
799
+ // Two counters closing in on each other (`lo++, hi--`) take the same
800
+ // integer storage as a counted loop's one.
801
+ const pairedLoop = !integerLoop && !countedLoop && emitter.countedLoopsEnabled
802
+ ? matchIntegerPairedForLoop(s, emitter.numericLocals, emitter.integerRanges)
803
+ : null;
804
+ // Byte windows and dense loops reason about one counter.
805
+ const window = countedLoop && countedLoop.followers.length === 0 && emitter.byteWindowsEnabled
778
806
  ? matchByteWindow(s, countedLoop, emitter.numericLocals, emitter.captureIds, emitter.integerRanges, emitter.byteWindowEntries.get(s) ?? new Set())
779
807
  : null;
780
808
  const denseShape = !emitter.denseLoopsEnabled
@@ -785,7 +813,7 @@ export function emitStmtBody(emitter, s) {
785
813
  length: integerArrayLoop.limitReceiver,
786
814
  range: { min: 0, max: 4294967294 },
787
815
  }
788
- : countedLoop && !countedLoop.guarded
816
+ : countedLoop && !countedLoop.guarded && countedLoop.followers.length === 0
789
817
  ? countedDenseShape(s, countedLoop)
790
818
  : null;
791
819
  const dense = denseShape && !window
@@ -836,15 +864,22 @@ export function emitStmtBody(emitter, s) {
836
864
  B.startBlock(done);
837
865
  break;
838
866
  }
839
- const version = emitter.bytesLoopVersionsEnabled &&
867
+ const versionable = emitter.bytesLoopVersionsEnabled &&
840
868
  emitter.bytesLoopVersioning.size < MAX_BYTES_LOOP_VERSION_DEPTH &&
841
- !emitter.bytesLoopVersioning.has(s)
842
- ? emitter.matchBytesLoopVersion(s, countedLoop)
843
- : null;
869
+ !emitter.bytesLoopVersioning.has(s);
870
+ // A loop to a typed array's or an array's length keeps its integer
871
+ // induction. Its counted form only gives the version guard the
872
+ // counter's iteration space, so the guard also covers accesses of
873
+ // other typed arrays at the counter, such as `x[i]` and `y[i]` in
874
+ // `for (let i = 0; i < out.length; i++) out[i] = x[i] * y[i]`.
875
+ const versionCounted = versionable && !countedLoop && integerLoop && emitter.countedLoopsEnabled
876
+ ? matchIntegerCountedForLoop(s, emitter.numericLocals, emitter.integerRanges, emitter.unaliasedArrays)
877
+ : countedLoop;
878
+ const version = versionable ? emitter.matchBytesLoopVersion(s, versionCounted) : null;
844
879
  if (version) {
845
880
  const fast = B.newLabel("bytes.version.fast"), slow = B.newLabel("bytes.version.slow"), done = B.newLabel("bytes.version.done");
846
881
  emitBytesLoopVersionGuard(emitter, version, fast, slow);
847
- const originalBounds = emitter.bytesBounds, originalRanges = emitter.integerRanges;
882
+ const originalBounds = emitter.bytesBounds, originalOwned = emitter.bytesOwned, originalRanges = emitter.integerRanges;
848
883
  emitter.bytesLoopVersioning.add(s);
849
884
  try {
850
885
  B.startBlock(slow);
@@ -852,6 +887,8 @@ export function emitStmtBody(emitter, s) {
852
887
  B.br(done);
853
888
  B.startBlock(fast);
854
889
  emitter.bytesBounds = new Set([...originalBounds, ...version.bounds]);
890
+ if (version.owned.size > 0)
891
+ emitter.bytesOwned = new Set([...originalOwned, ...version.owned]);
855
892
  if (version.ranges.size > 0)
856
893
  emitter.integerRanges = new Map([...originalRanges, ...version.ranges]);
857
894
  if (version.counted?.guarded)
@@ -861,6 +898,7 @@ export function emitStmtBody(emitter, s) {
861
898
  }
862
899
  finally {
863
900
  emitter.bytesBounds = originalBounds;
901
+ emitter.bytesOwned = originalOwned;
864
902
  emitter.integerRanges = originalRanges;
865
903
  emitter.provenCountedGuards.delete(s);
866
904
  emitter.bytesLoopVersioning.delete(s);
@@ -869,8 +907,10 @@ export function emitStmtBody(emitter, s) {
869
907
  break;
870
908
  }
871
909
  let countedJoin = null;
872
- if (countedLoop?.guarded && !emitter.provenCountedGuards.has(s)) {
873
- const safe = emitCountedLoopSafety(emitter, countedLoop);
910
+ if ((countedLoop?.guarded && !emitter.provenCountedGuards.has(s)) || pairedLoop?.guarded) {
911
+ const safe = countedLoop
912
+ ? emitCountedLoopSafety(emitter, countedLoop)
913
+ : emitPairedLoopSafety(emitter, pairedLoop);
874
914
  const fast = B.newLabel("counted.fast");
875
915
  const slow = B.newLabel("counted.slow");
876
916
  countedJoin = B.newLabel("counted.done");
@@ -885,6 +925,8 @@ export function emitStmtBody(emitter, s) {
885
925
  emitter.scopes.push([]);
886
926
  let integerSlot = null;
887
927
  let countedLimit = null;
928
+ const pairedSlots = [];
929
+ const followerSlots = [];
888
930
  if (integerLoop) {
889
931
  integerSlot = B.slot();
890
932
  B.entryAllocas.push(`${integerSlot} = alloca ${emitter.sizeType} ; integer induction ${emitter.currentLocals.get(integerLoop.localId).name}`);
@@ -923,8 +965,40 @@ export function emitStmtBody(emitter, s) {
923
965
  ? emitter.denseLoop.range
924
966
  : countedLoop.range,
925
967
  });
968
+ for (const follower of countedLoop.followers) {
969
+ const slot = B.slot();
970
+ B.entryAllocas.push(`${slot} = alloca i64 ; integer induction ${emitter.currentLocals.get(follower.localId).name}`);
971
+ const value = emitter.emitExpr(follower.start);
972
+ const followerStart = B.tmp();
973
+ B.line(`${followerStart} = fptosi double ${value.name} to i64`);
974
+ B.line(`store i64 ${followerStart}, ptr ${slot}`);
975
+ followerSlots.push(slot);
976
+ emitter.integerLoopBindings.set(follower.localId, {
977
+ slot,
978
+ type: "i64",
979
+ signed: true,
980
+ range: follower.range,
981
+ });
982
+ }
926
983
  countedLimit = emitCountedLoopLimit(emitter, countedLoop);
927
984
  }
985
+ else if (pairedLoop) {
986
+ for (const counter of [pairedLoop.low, pairedLoop.high]) {
987
+ const slot = B.slot();
988
+ B.entryAllocas.push(`${slot} = alloca i64 ; integer induction ${emitter.currentLocals.get(counter.localId).name}`);
989
+ const value = emitter.emitExpr(counter.start);
990
+ const start = B.tmp();
991
+ B.line(`${start} = fptosi double ${value.name} to i64`);
992
+ B.line(`store i64 ${start}, ptr ${slot}`);
993
+ pairedSlots.push(slot);
994
+ emitter.integerLoopBindings.set(counter.localId, {
995
+ slot,
996
+ type: "i64",
997
+ signed: true,
998
+ range: pairedLoop.range,
999
+ });
1000
+ }
1001
+ }
928
1002
  else if (s.init) {
929
1003
  // A multi-declarator head shares the loop's scope. Emitting its
930
1004
  // IR block as an ordinary block would release captured/ref locals
@@ -966,6 +1040,7 @@ export function emitStmtBody(emitter, s) {
966
1040
  const lu = s.update || capturedLets.length > 0 || workerBudget !== null ? B.newLabel("loop.u") : lc;
967
1041
  B.br(lc);
968
1042
  B.startBlock(lc);
1043
+ enterLoopHeader(emitter, lc);
969
1044
  if (integerLoop && integerSlot) {
970
1045
  const receiver = emitter.emitStableReceiver(integerLoop.limitReceiver, []);
971
1046
  const lenPtr = B.tmp();
@@ -1001,6 +1076,13 @@ export function emitStmtBody(emitter, s) {
1001
1076
  B.line(`${inBounds} = icmp ${countedLoop.step > 0 ? "slt" : "sgt"} i64 ${index}, ${countedLimit}`);
1002
1077
  B.condBr(inBounds, lb, exit);
1003
1078
  }
1079
+ else if (pairedLoop) {
1080
+ const low = B.tmp(), high = B.tmp(), open = B.tmp();
1081
+ B.line(`${low} = load i64, ptr ${pairedSlots[0]}`);
1082
+ B.line(`${high} = load i64, ptr ${pairedSlots[1]}`);
1083
+ B.line(`${open} = icmp ${pairedLoop.inclusive ? "sle" : "slt"} i64 ${low}, ${high}`);
1084
+ B.condBr(open, lb, exit);
1085
+ }
1004
1086
  else if (s.cond)
1005
1087
  B.condBr(emitter.emitCondition(s.cond), lb, exit);
1006
1088
  else
@@ -1035,6 +1117,22 @@ export function emitStmtBody(emitter, s) {
1035
1117
  B.line(`${old} = load i64, ptr ${integerSlot}`);
1036
1118
  B.line(`${next} = add nsw i64 ${old}, ${countedLoop.step}`);
1037
1119
  B.line(`store i64 ${next}, ptr ${integerSlot}`);
1120
+ countedLoop.followers.forEach((follower, i) => {
1121
+ const was = B.tmp();
1122
+ const now = B.tmp();
1123
+ B.line(`${was} = load i64, ptr ${followerSlots[i]}`);
1124
+ B.line(`${now} = add nsw i64 ${was}, ${follower.step}`);
1125
+ B.line(`store i64 ${now}, ptr ${followerSlots[i]}`);
1126
+ });
1127
+ }
1128
+ else if (pairedLoop) {
1129
+ [pairedLoop.low, pairedLoop.high].forEach((counter, i) => {
1130
+ const old = B.tmp();
1131
+ const next = B.tmp();
1132
+ B.line(`${old} = load i64, ptr ${pairedSlots[i]}`);
1133
+ B.line(`${next} = add nsw i64 ${old}, ${counter.step}`);
1134
+ B.line(`store i64 ${next}, ptr ${pairedSlots[i]}`);
1135
+ });
1038
1136
  }
1039
1137
  else if (s.update)
1040
1138
  emitter.emitStmt(s.update);
@@ -1045,8 +1143,15 @@ export function emitStmtBody(emitter, s) {
1045
1143
  emitter.releaseScope(emitter.scopes.pop());
1046
1144
  if (integerLoop)
1047
1145
  emitter.integerLoopBindings.delete(integerLoop.localId);
1048
- if (countedLoop)
1146
+ if (countedLoop) {
1049
1147
  emitter.integerLoopBindings.delete(countedLoop.localId);
1148
+ for (const follower of countedLoop.followers)
1149
+ emitter.integerLoopBindings.delete(follower.localId);
1150
+ }
1151
+ if (pairedLoop) {
1152
+ emitter.integerLoopBindings.delete(pairedLoop.low.localId);
1153
+ emitter.integerLoopBindings.delete(pairedLoop.high.localId);
1154
+ }
1050
1155
  if (integerArrayLoop)
1051
1156
  emitter.integerArrayBindings.delete(integerArrayLoop.localId);
1052
1157
  if (countedJoin) {
@@ -1416,6 +1521,40 @@ export function emitStmtBody(emitter, s) {
1416
1521
  * Abrupt completions inside tryBody/catchBody ride the finallyStack:
1417
1522
  * returns inline copies at the return site, while break/continue use the
1418
1523
  * shared region walk before branching to their resolved target. */
1524
+ /** A constant number local whose initializer has an exact integer form
1525
+ * (such as `const j = i * 4` in a typed-array loop version) keeps that
1526
+ * integer in an i64 slot beside the double, so reads such as `px[j + 1]`
1527
+ * index with integer arithmetic instead of converting the double back.
1528
+ * Every other declaration of the local drops the integer: the same
1529
+ * declaration is emitted once per loop copy, and a copy must not read the
1530
+ * integer another copy stored. */
1531
+ function storeIntegerTemp(emitter, localId, b, v) {
1532
+ const local = b.local;
1533
+ if (!emitter.integerTempsEnabled ||
1534
+ b.kind !== "local" ||
1535
+ !local ||
1536
+ local.type.kind !== "f64" ||
1537
+ local.mutable ||
1538
+ local.tdz === true ||
1539
+ emitter.captureIds.has(localId) ||
1540
+ !v.integer) {
1541
+ emitter.integerTemps.delete(localId);
1542
+ return;
1543
+ }
1544
+ const B = emitter.B;
1545
+ let slot = emitter.integerTemps.get(localId)?.slot;
1546
+ if (slot === undefined) {
1547
+ slot = B.slot();
1548
+ B.entryAllocas.push(`${slot} = alloca i64 ; integer ${local.name}`);
1549
+ }
1550
+ B.line(`store i64 ${widenInteger(emitter, v.integer)}, ptr ${slot}`);
1551
+ emitter.integerTemps.set(localId, {
1552
+ slot,
1553
+ type: "i64",
1554
+ signed: true,
1555
+ range: v.integer.range,
1556
+ });
1557
+ }
1419
1558
  export function emitTryCatch(emitter, s) {
1420
1559
  const B = emitter.B;
1421
1560
  const hasCatch = s.catchBody !== null;
@@ -1668,6 +1807,99 @@ export function emitSwitch(emitter, s) {
1668
1807
  B.br(end);
1669
1808
  B.startBlock(end);
1670
1809
  }
1810
+ /** The loop copies a callback loop version needs: the bindings the loop
1811
+ * calls that the constant-callback census resolves to one function, each
1812
+ * with that function's direct entry. Only small loops of optimized
1813
+ * synchronous functions, and only bindings declared before the loop,
1814
+ * qualify: the guard reads each binding before the loop runs. Versions do
1815
+ * not nest: a loop inside either copy of a version (including the
1816
+ * versioned loop itself, emitted again for each copy) keeps its calls as
1817
+ * they are, so a loop nest is emitted at most twice. */
1818
+ function callbackVersionBindings(emitter, s) {
1819
+ if (!emitter.callbackVersionsEnabled ||
1820
+ emitter.currentConstantCallbacks.size === 0 ||
1821
+ emitter.callbackVersioning.size > 0)
1822
+ return null;
1823
+ const found = new Map();
1824
+ // Bindings the loop declares or writes (a callback declared in its body).
1825
+ const bound = new Set();
1826
+ let cost = 0;
1827
+ const expr = (e) => {
1828
+ if (++cost > MAX_CALLBACK_VERSION_COST)
1829
+ return false;
1830
+ if (e.kind === "assignExpr")
1831
+ bound.add(e.localId);
1832
+ if (e.kind === "callValue" && e.callee.kind === "varRef" && !found.has(e.callee.localId)) {
1833
+ const local = emitter.currentLocals.get(e.callee.localId);
1834
+ const target = local && local.tdz !== true ? emitter.knownCallbackTarget(e.callee) : undefined;
1835
+ if (target)
1836
+ found.set(e.callee.localId, { ref: e.callee, direct: target.direct });
1837
+ }
1838
+ return everyExprChild(e, expr, stmt);
1839
+ };
1840
+ const stmt = (x) => {
1841
+ if (++cost > MAX_CALLBACK_VERSION_COST)
1842
+ return false;
1843
+ if (x.kind === "varDecl" || x.kind === "assign" || x.kind === "forOf")
1844
+ bound.add(x.localId);
1845
+ else if (x.kind === "tryCatch" && x.catchLocalId !== null)
1846
+ bound.add(x.catchLocalId);
1847
+ return everyStmtChild(x, expr, stmt);
1848
+ };
1849
+ if (!stmt(s))
1850
+ return null;
1851
+ const bindings = [...found.values()].filter(({ ref }) => !bound.has(ref.localId));
1852
+ return bindings.length > 0 ? bindings : null;
1853
+ }
1854
+ /** A callback loop version. The guard tests, once before the loop, that
1855
+ * each binding's closure holds its known function: a closure's code
1856
+ * pointer is written only when the closure is built, and the census
1857
+ * resolves only bindings the function never rebinds. The copy where the
1858
+ * guard holds calls those functions directly, with no indirect fallback
1859
+ * that could rewrite the closure or what it captures, so LLVM can keep a
1860
+ * captured scalar the callback updates in a register. The other copy is the
1861
+ * ordinary loop. */
1862
+ function emitCallbackVersionedLoop(emitter, s, bindings) {
1863
+ const B = emitter.B;
1864
+ let ok = "true";
1865
+ for (const { ref, direct } of bindings) {
1866
+ // A borrowed read: the guard only compares the code pointer.
1867
+ const closure = emitter.emitReadReceiver(ref).name;
1868
+ const fnp = B.tmp(), fn = B.tmp(), same = B.tmp();
1869
+ B.line(`${fnp} = getelementptr inbounds %ScrClosure, ptr ${closure}, i64 0, i32 1`);
1870
+ B.line(`${fn} = load ptr, ptr ${fnp}`);
1871
+ B.line(`${same} = icmp eq ptr ${fn}, ${direct}`);
1872
+ if (ok === "true")
1873
+ ok = same;
1874
+ else {
1875
+ const both = B.tmp();
1876
+ B.line(`${both} = and i1 ${ok}, ${same}`);
1877
+ ok = both;
1878
+ }
1879
+ }
1880
+ const fast = B.newLabel("callback.version.fast"), slow = B.newLabel("callback.version.slow"), done = B.newLabel("callback.version.done");
1881
+ B.condBr(ok, fast, slow);
1882
+ emitter.callbackVersioning.add(s);
1883
+ try {
1884
+ B.startBlock(slow);
1885
+ emitter.emitStmt(s);
1886
+ B.br(done);
1887
+ B.startBlock(fast);
1888
+ for (const { ref } of bindings)
1889
+ emitter.knownCallbacks.add(ref.localId);
1890
+ emitter.emitStmt(s);
1891
+ B.br(done);
1892
+ }
1893
+ finally {
1894
+ for (const { ref } of bindings)
1895
+ emitter.knownCallbacks.delete(ref.localId);
1896
+ emitter.callbackVersioning.delete(s);
1897
+ }
1898
+ B.startBlock(done);
1899
+ }
1900
+ /** Entries in a row whose fast copy bailed before a speculative loop site
1901
+ * stops trying it. */
1902
+ const SPECULATION_BAILS = 8;
1671
1903
  /** Emit a loop's condition, body and update through `emitCopy`, twice
1672
1904
  * when speculative-integers.ts plans a fast integer copy. Both copies
1673
1905
  * share the loop's setup and exit; the ordinary copy comes first so the
@@ -1711,24 +1943,68 @@ export function emitLoopCopies(emitter, loop, allowed, exit, emitCopy) {
1711
1943
  ok = both;
1712
1944
  }
1713
1945
  }
1946
+ // Each entry whose fast copy bails counts at the loop site, and a fast
1947
+ // copy that completes a speculated write and leaves the loop clears the
1948
+ // count. After SPECULATION_BAILS bailing entries in a row, the site runs
1949
+ // the ordinary copy only. The count is a hint: both copies give the same
1950
+ // results, and a race between workers loses at most an update.
1951
+ const bails = `@scr.spec.bails.${emitter.speculativeLoopSites++}`;
1952
+ emitter.declare(`${bails} = internal global i8 0`);
1953
+ const count = B.tmp(), trying = B.tmp();
1954
+ B.line(`${count} = load atomic i8, ptr ${bails} unordered, align 1`);
1955
+ B.line(`${trying} = icmp ult i8 ${count}, ${SPECULATION_BAILS}`);
1956
+ if (ok === "true")
1957
+ ok = trying;
1958
+ else {
1959
+ const both = B.tmp();
1960
+ B.line(`${both} = and i1 ${ok}, ${trying}`);
1961
+ ok = both;
1962
+ }
1714
1963
  const fast = B.newLabel("spec.fast"), slow = B.newLabel("spec.slow");
1715
1964
  B.condBr(ok, fast, slow);
1716
1965
  const resume = new Map();
1717
1966
  for (const s of plan.writes)
1718
1967
  resume.set(s, { label: B.newLabel("spec.resume"), placed: false });
1968
+ // A failed check finishes its iteration in a third copy, entered only
1969
+ // there: it re-executes the statement and the rest of the body and the
1970
+ // update, then enters the ordinary copy through its header. Jumping
1971
+ // into the middle of the ordinary copy instead would give that loop a
1972
+ // second entry, and LLVM does not optimize an irreducible loop.
1973
+ const points = [...resume.values()];
1974
+ let header = null;
1719
1975
  B.startBlock(slow);
1976
+ emitter.speculationHeader = (label) => {
1977
+ header = label;
1978
+ };
1979
+ try {
1980
+ emitCopy(exit);
1981
+ }
1982
+ finally {
1983
+ emitter.speculationHeader = null;
1984
+ }
1985
+ if (header === null)
1986
+ throw new InternalCompilerError("llvm emitter bug: speculative loop copy without a header");
1987
+ B.startBlock(B.newLabel("spec.tail"));
1720
1988
  emitter.speculationResume = resume;
1989
+ emitter.speculationHeader = () => {
1990
+ B.br(header);
1991
+ B.startBlock(B.newLabel("spec.unused"));
1992
+ };
1721
1993
  try {
1722
1994
  emitCopy(exit);
1723
1995
  }
1724
1996
  finally {
1725
1997
  emitter.speculationResume = null;
1998
+ emitter.speculationHeader = null;
1726
1999
  }
1727
2000
  B.startBlock(fast);
1728
- if (![...resume.values()].every((r) => r.placed)) {
2001
+ if (!points.every((r) => r.placed)) {
1729
2002
  B.br(slow);
1730
2003
  return;
1731
2004
  }
2005
+ const ran = B.slot();
2006
+ B.entryAllocas.push(`${ran} = alloca i1 ; speculated write completed`);
2007
+ B.line(`store i1 false, ptr ${ran}`);
1732
2008
  for (const id of plan.locals.keys()) {
1733
2009
  const shadow = B.slot();
1734
2010
  B.entryAllocas.push(`${shadow} = alloca i64 ; speculative integer ${emitter.currentLocals.get(id)?.name ?? id}`);
@@ -1766,17 +2042,25 @@ export function emitLoopCopies(emitter, loop, allowed, exit, emitCopy) {
1766
2042
  writes: plan.writes,
1767
2043
  resume: new Map([...resume].map(([s, r]) => [s, r.label])),
1768
2044
  deferred,
2045
+ bails,
2046
+ ran,
1769
2047
  };
1770
2048
  try {
1771
- if (deferred.size === 0)
1772
- emitCopy(exit);
1773
- else {
1774
- const leave = B.newLabel("spec.leave");
1775
- emitCopy(leave);
1776
- B.startBlock(leave);
1777
- emitter.writeBackDeferred(deferred);
1778
- B.br(exit);
1779
- }
2049
+ const leave = B.newLabel("spec.leave");
2050
+ emitCopy(leave);
2051
+ B.startBlock(leave);
2052
+ emitter.writeBackDeferred(deferred);
2053
+ // An entry that never ran a speculated write (a loop of no iterations)
2054
+ // says nothing about the site.
2055
+ const wrote = B.tmp(), left = B.tmp(), counted = B.tmp(), both = B.tmp(), clear = B.newLabel("spec.clear");
2056
+ B.line(`${wrote} = load i1, ptr ${ran}`);
2057
+ B.line(`${left} = load atomic i8, ptr ${bails} unordered, align 1`);
2058
+ B.line(`${counted} = icmp ne i8 ${left}, 0`);
2059
+ B.line(`${both} = and i1 ${wrote}, ${counted}`);
2060
+ B.condBr(both, clear, exit);
2061
+ B.startBlock(clear);
2062
+ B.line(`store atomic i8 0, ptr ${bails} unordered, align 1`);
2063
+ B.br(exit);
1780
2064
  }
1781
2065
  finally {
1782
2066
  emitter.speculation = null;
@@ -1784,6 +2068,13 @@ export function emitLoopCopies(emitter, loop, allowed, exit, emitCopy) {
1784
2068
  emitter.integerLoopBindings.delete(id);
1785
2069
  }
1786
2070
  }
2071
+ /** At the top of a loop copy's header: lets a speculative loop find its
2072
+ * ordinary copy's header, and keeps its third copy out of the loop. */
2073
+ function enterLoopHeader(emitter, header) {
2074
+ const dispatch = emitter.speculationHeader;
2075
+ emitter.speculationHeader = null;
2076
+ dispatch?.(header);
2077
+ }
1787
2078
  /** A proven integer loop (speculative-integers.ts) for this loop, or null.
1788
2079
  * A shadowed local's double is stale until the loop is left, which only
1789
2080
  * the loop's exit, a return and an exception do: the loop is planned only
@@ -1890,7 +2181,9 @@ export function emitSpeculativeWrite(emitter, s, resume) {
1890
2181
  if (emitter.frames.pop().length > 0)
1891
2182
  throw new InternalCompilerError("llvm emitter bug: speculative write owns a temporary");
1892
2183
  B.line(`store i64 ${result}, ptr ${binding.slot}`);
1893
- const deferred = emitter.speculation.deferred;
2184
+ const { deferred, bails: site, ran } = emitter.speculation;
2185
+ if (ran !== undefined)
2186
+ B.line(`store i1 true, ptr ${ran}`);
1894
2187
  if (!deferred.has(target.localId)) {
1895
2188
  const number = B.tmp();
1896
2189
  B.line(`${number} = sitofp i64 ${result} to double`);
@@ -1902,6 +2195,13 @@ export function emitSpeculativeWrite(emitter, s, resume) {
1902
2195
  B.br(done);
1903
2196
  B.startBlock(failed);
1904
2197
  emitter.writeBackDeferred(deferred);
2198
+ if (site !== undefined) {
2199
+ const count = B.tmp(), next = B.tmp();
2200
+ emitter.declare("declare i8 @llvm.uadd.sat.i8(i8, i8)");
2201
+ B.line(`${count} = load atomic i8, ptr ${site} unordered, align 1`);
2202
+ B.line(`${next} = call i8 @llvm.uadd.sat.i8(i8 ${count}, i8 1)`);
2203
+ B.line(`store atomic i8 ${next}, ptr ${site} unordered, align 1`);
2204
+ }
1905
2205
  B.br(resume);
1906
2206
  B.startBlock(done);
1907
2207
  }