@scriptc/compiler 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (999) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +977 -113
  2. package/dist/backend/cycle-analysis.d.ts +5 -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 +9 -1
  8. package/dist/backend/cycle-mutability.js +21 -3
  9. package/dist/backend/cycle-mutability.js.map +1 -1
  10. package/dist/backend/executable-features.js +6 -1
  11. package/dist/backend/executable-features.js.map +1 -1
  12. package/dist/backend/immutability.d.ts +7 -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 +5 -0
  16. package/dist/backend/library-pack.js.map +1 -1
  17. package/dist/backend/llvm/alloc.d.ts +23 -4
  18. package/dist/backend/llvm/alloc.js +61 -8
  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 +23 -10
  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 +70 -7
  37. package/dist/backend/llvm/bytes-loop-versions.js +567 -30
  38. package/dist/backend/llvm/bytes-loop-versions.js.map +1 -1
  39. package/dist/backend/llvm/bytes-loop-versions.test.js +389 -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 +74 -1
  44. package/dist/backend/llvm/classes.js +364 -54
  45. package/dist/backend/llvm/classes.js.map +1 -1
  46. package/dist/backend/llvm/classes.test.js +384 -17
  47. package/dist/backend/llvm/classes.test.js.map +1 -1
  48. package/dist/backend/llvm/common.d.ts +10 -6
  49. package/dist/backend/llvm/common.js +10 -6
  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 +91 -56
  53. package/dist/backend/llvm/constant-callbacks.js.map +1 -1
  54. package/dist/backend/llvm/constant-callbacks.test.js +4 -4
  55. package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
  56. package/dist/backend/llvm/counted-loops.d.ts +11 -1
  57. package/dist/backend/llvm/counted-loops.js +80 -23
  58. package/dist/backend/llvm/counted-loops.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 +35 -16
  65. package/dist/backend/llvm/dense-array-loops.js +237 -12
  66. package/dist/backend/llvm/dense-array-loops.js.map +1 -1
  67. package/dist/backend/llvm/dense-array-loops.test.js +140 -15
  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 +51 -1
  72. package/dist/backend/llvm/dyn.js +683 -69
  73. package/dist/backend/llvm/dyn.js.map +1 -1
  74. package/dist/backend/llvm/emit-function.js +33 -26
  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 +208 -34
  80. package/dist/backend/llvm/emit-module.js.map +1 -1
  81. package/dist/backend/llvm/emit-statements.d.ts +0 -27
  82. package/dist/backend/llvm/emit-statements.js +577 -93
  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 +314 -49
  88. package/dist/backend/llvm/emitter.js +1241 -129
  89. package/dist/backend/llvm/emitter.js.map +1 -1
  90. package/dist/backend/llvm/emitter.test.js +54 -5
  91. package/dist/backend/llvm/emitter.test.js.map +1 -1
  92. package/dist/backend/llvm/expr-async.js +19 -0
  93. package/dist/backend/llvm/expr-async.js.map +1 -1
  94. package/dist/backend/llvm/expr-bytes.d.ts +5 -2
  95. package/dist/backend/llvm/expr-bytes.js +144 -52
  96. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  97. package/dist/backend/llvm/expr-callbacks.js +47 -0
  98. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  99. package/dist/backend/llvm/expr-calls.d.ts +1 -1
  100. package/dist/backend/llvm/expr-calls.js +62 -36
  101. package/dist/backend/llvm/expr-calls.js.map +1 -1
  102. package/dist/backend/llvm/expr-containers.d.ts +14 -2
  103. package/dist/backend/llvm/expr-containers.js +148 -40
  104. package/dist/backend/llvm/expr-containers.js.map +1 -1
  105. package/dist/backend/llvm/expr-context.d.ts +14 -0
  106. package/dist/backend/llvm/expr-control.js +2 -3
  107. package/dist/backend/llvm/expr-control.js.map +1 -1
  108. package/dist/backend/llvm/expr-dynamic.js +71 -16
  109. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  110. package/dist/backend/llvm/expr-primitives.js +126 -36
  111. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  112. package/dist/backend/llvm/expr-primitives.test.js +11 -6
  113. package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
  114. package/dist/backend/llvm/expr-records.d.ts +12 -0
  115. package/dist/backend/llvm/expr-records.js +106 -0
  116. package/dist/backend/llvm/expr-records.js.map +1 -1
  117. package/dist/backend/llvm/expr-stream-bridges.d.ts +2 -2
  118. package/dist/backend/llvm/expr-stream-bridges.js +225 -64
  119. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  120. package/dist/backend/llvm/expr-stream-bridges.test.js +1 -1
  121. package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -1
  122. package/dist/backend/llvm/expr-stream-callbacks.d.ts +2 -2
  123. package/dist/backend/llvm/expr-stream-callbacks.js +200 -50
  124. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  125. package/dist/backend/llvm/int32-kind-loops.d.ts +39 -0
  126. package/dist/backend/llvm/int32-kind-loops.js +106 -0
  127. package/dist/backend/llvm/int32-kind-loops.js.map +1 -0
  128. package/dist/backend/llvm/integer-or-nan-indexes.test.d.ts +1 -0
  129. package/dist/backend/llvm/integer-or-nan-indexes.test.js +118 -0
  130. package/dist/backend/llvm/integer-or-nan-indexes.test.js.map +1 -0
  131. package/dist/backend/llvm/integer-values.d.ts +20 -1
  132. package/dist/backend/llvm/integer-values.js +71 -0
  133. package/dist/backend/llvm/integer-values.js.map +1 -1
  134. package/dist/backend/llvm/js-ic.d.ts +1 -1
  135. package/dist/backend/llvm/js-ic.js +1 -1
  136. package/dist/backend/llvm/js-ic.js.map +1 -1
  137. package/dist/backend/llvm/key-orders.d.ts +7 -0
  138. package/dist/backend/llvm/key-orders.js +33 -0
  139. package/dist/backend/llvm/key-orders.js.map +1 -0
  140. package/dist/backend/llvm/lib-connect.js +4 -0
  141. package/dist/backend/llvm/lib-connect.js.map +1 -1
  142. package/dist/backend/llvm/lib-datagram.js +11 -0
  143. package/dist/backend/llvm/lib-datagram.js.map +1 -1
  144. package/dist/backend/llvm/lib-dispatch.js +90 -2
  145. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  146. package/dist/backend/llvm/lib-filesystem.js +65 -4
  147. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  148. package/dist/backend/llvm/lib-http2.d.ts +4 -0
  149. package/dist/backend/llvm/lib-http2.js +24 -17
  150. package/dist/backend/llvm/lib-http2.js.map +1 -1
  151. package/dist/backend/llvm/lib-lookup.js +16 -6
  152. package/dist/backend/llvm/lib-lookup.js.map +1 -1
  153. package/dist/backend/llvm/lib-process.js +65 -14
  154. package/dist/backend/llvm/lib-process.js.map +1 -1
  155. package/dist/backend/llvm/lib-shared.js +126 -3
  156. package/dist/backend/llvm/lib-shared.js.map +1 -1
  157. package/dist/backend/llvm/lib-stream.js +97 -30
  158. package/dist/backend/llvm/lib-stream.js.map +1 -1
  159. package/dist/backend/llvm/lib-tls.js +23 -0
  160. package/dist/backend/llvm/lib-tls.js.map +1 -1
  161. package/dist/backend/llvm/local-array-reads.js +181 -64
  162. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  163. package/dist/backend/llvm/local-array-reads.test.js +28 -0
  164. package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
  165. package/dist/backend/llvm/loop-state.d.ts +33 -0
  166. package/dist/backend/llvm/loop-state.js +42 -0
  167. package/dist/backend/llvm/loop-state.js.map +1 -0
  168. package/dist/backend/llvm/map-number-lookup.d.ts +26 -8
  169. package/dist/backend/llvm/map-number-lookup.js +91 -31
  170. package/dist/backend/llvm/map-number-lookup.js.map +1 -1
  171. package/dist/backend/llvm/map-number-lookup.test.js +55 -0
  172. package/dist/backend/llvm/map-number-lookup.test.js.map +1 -1
  173. package/dist/backend/llvm/map-read-lifetimes.js +4 -2
  174. package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
  175. package/dist/backend/llvm/nullable-unions.d.ts +2 -1
  176. package/dist/backend/llvm/nullable-unions.js +15 -3
  177. package/dist/backend/llvm/nullable-unions.js.map +1 -1
  178. package/dist/backend/llvm/publish.d.ts +18 -1
  179. package/dist/backend/llvm/publish.js +76 -25
  180. package/dist/backend/llvm/publish.js.map +1 -1
  181. package/dist/backend/llvm/publish.test.js +3 -0
  182. package/dist/backend/llvm/publish.test.js.map +1 -1
  183. package/dist/backend/llvm/receivers.js +7 -2
  184. package/dist/backend/llvm/receivers.js.map +1 -1
  185. package/dist/backend/llvm/record-results.d.ts +1 -9
  186. package/dist/backend/llvm/record-results.js +2 -11
  187. package/dist/backend/llvm/record-results.js.map +1 -1
  188. package/dist/backend/llvm/reference-writes.d.ts +7 -2
  189. package/dist/backend/llvm/reference-writes.js +91 -72
  190. package/dist/backend/llvm/reference-writes.js.map +1 -1
  191. package/dist/backend/llvm/regex-matchers.js +161 -14
  192. package/dist/backend/llvm/regex-matchers.js.map +1 -1
  193. package/dist/backend/llvm/regex-matchers.test.js +18 -0
  194. package/dist/backend/llvm/regex-matchers.test.js.map +1 -1
  195. package/dist/backend/llvm/running-extrema.d.ts +11 -0
  196. package/dist/backend/llvm/running-extrema.js +115 -0
  197. package/dist/backend/llvm/running-extrema.js.map +1 -0
  198. package/dist/backend/llvm/running-extrema.test.d.ts +1 -0
  199. package/dist/backend/llvm/running-extrema.test.js +89 -0
  200. package/dist/backend/llvm/running-extrema.test.js.map +1 -0
  201. package/dist/backend/llvm/shapes.d.ts +79 -21
  202. package/dist/backend/llvm/shapes.js +233 -42
  203. package/dist/backend/llvm/shapes.js.map +1 -1
  204. package/dist/backend/llvm/shapes.test.js +53 -7
  205. package/dist/backend/llvm/shapes.test.js.map +1 -1
  206. package/dist/backend/llvm/speculative-integers.d.ts +6 -0
  207. package/dist/backend/llvm/speculative-integers.js +2 -2
  208. package/dist/backend/llvm/speculative-integers.js.map +1 -1
  209. package/dist/backend/llvm/stack-objects.d.ts +3 -2
  210. package/dist/backend/llvm/stack-objects.js +5 -2
  211. package/dist/backend/llvm/stack-objects.js.map +1 -1
  212. package/dist/backend/llvm/string-lifetimes.test.js +2 -1
  213. package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
  214. package/dist/backend/llvm/string-reads.d.ts +15 -0
  215. package/dist/backend/llvm/string-reads.js +128 -0
  216. package/dist/backend/llvm/string-reads.js.map +1 -1
  217. package/dist/backend/llvm/walk-borrows.d.ts +3 -0
  218. package/dist/backend/llvm/walk-borrows.js +46 -41
  219. package/dist/backend/llvm/walk-borrows.js.map +1 -1
  220. package/dist/backend/llvm/walkers.d.ts +3 -0
  221. package/dist/backend/llvm/walkers.js +88 -65
  222. package/dist/backend/llvm/walkers.js.map +1 -1
  223. package/dist/backend/llvm/wasm-modules.d.ts +6 -5
  224. package/dist/backend/llvm/wasm-modules.js +32 -9
  225. package/dist/backend/llvm/wasm-modules.js.map +1 -1
  226. package/dist/backend/llvm/wrapping-sums.d.ts +16 -1
  227. package/dist/backend/llvm/wrapping-sums.js +126 -0
  228. package/dist/backend/llvm/wrapping-sums.js.map +1 -1
  229. package/dist/backend/mangle.d.ts +3 -0
  230. package/dist/backend/mangle.js +5 -0
  231. package/dist/backend/mangle.js.map +1 -1
  232. package/dist/backend/may-throw.d.ts +8 -10
  233. package/dist/backend/may-throw.js +14 -10
  234. package/dist/backend/may-throw.js.map +1 -1
  235. package/dist/backend/native/contracts.d.ts +27 -4
  236. package/dist/backend/native/executable.js +31 -8
  237. package/dist/backend/native/executable.js.map +1 -1
  238. package/dist/backend/native/library.js +1 -0
  239. package/dist/backend/native/library.js.map +1 -1
  240. package/dist/backend/native/runtime-inputs.d.ts +1 -1
  241. package/dist/backend/native/runtime-inputs.js +1 -0
  242. package/dist/backend/native/runtime-inputs.js.map +1 -1
  243. package/dist/backend/native-codegen.d.ts +11 -6
  244. package/dist/backend/native-codegen.js +36 -9
  245. package/dist/backend/native-codegen.js.map +1 -1
  246. package/dist/backend/native-codegen.test.js +0 -23
  247. package/dist/backend/native-codegen.test.js.map +1 -1
  248. package/dist/backend/native-link-info-core.d.ts +18 -4
  249. package/dist/backend/native-link-info-core.js.map +1 -1
  250. package/dist/backend/optimization.d.ts +2 -2
  251. package/dist/backend/publication.d.ts +12 -1
  252. package/dist/backend/publication.js +37 -14
  253. package/dist/backend/publication.js.map +1 -1
  254. package/dist/backend/publication.test.js +30 -0
  255. package/dist/backend/publication.test.js.map +1 -1
  256. package/dist/backend/result-slots.d.ts +16 -0
  257. package/dist/backend/result-slots.js +23 -0
  258. package/dist/backend/result-slots.js.map +1 -0
  259. package/dist/backend/runtime-abi.d.ts +2 -2
  260. package/dist/backend/runtime-abi.js +2 -2
  261. package/dist/backend/runtime-pack-core.d.ts +2 -1
  262. package/dist/backend/runtime-pack-core.js +2 -1
  263. package/dist/backend/runtime-pack-core.js.map +1 -1
  264. package/dist/backend/runtime-pack-targets.test.js +5 -1
  265. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  266. package/dist/backend/runtime-pack.d.ts +0 -21
  267. package/dist/backend/runtime-pack.js +0 -29
  268. package/dist/backend/runtime-pack.js.map +1 -1
  269. package/dist/backend/runtime-pack.test.js +10 -69
  270. package/dist/backend/runtime-pack.test.js.map +1 -1
  271. package/dist/backend/stack-observations.d.ts +2 -1
  272. package/dist/backend/stack-observations.js +67 -42
  273. package/dist/backend/stack-observations.js.map +1 -1
  274. package/dist/backend/target-diagnostics.js +33 -1
  275. package/dist/backend/target-diagnostics.js.map +1 -1
  276. package/dist/backend/warm-cache.js +4 -0
  277. package/dist/backend/warm-cache.js.map +1 -1
  278. package/dist/cli/command.js +26 -6
  279. package/dist/cli/command.js.map +1 -1
  280. package/dist/cli/usage.d.ts +5 -1
  281. package/dist/cli/usage.js +10 -5
  282. package/dist/cli/usage.js.map +1 -1
  283. package/dist/compat/fetch-profile.js +1 -1
  284. package/dist/compat/fetch-profile.js.map +1 -1
  285. package/dist/contracts/check.js +5 -4
  286. package/dist/contracts/check.js.map +1 -1
  287. package/dist/contracts/int32-elements.js +10 -2
  288. package/dist/contracts/int32-elements.js.map +1 -1
  289. package/dist/coverage/report.d.ts +7 -2
  290. package/dist/coverage/report.js +30 -3
  291. package/dist/coverage/report.js.map +1 -1
  292. package/dist/coverage/verdict-cache.d.ts +1 -0
  293. package/dist/coverage/verdict-cache.js +4 -0
  294. package/dist/coverage/verdict-cache.js.map +1 -1
  295. package/dist/coverage/verdict-semantic.js +4 -0
  296. package/dist/coverage/verdict-semantic.js.map +1 -1
  297. package/dist/diagnostics/diagnostic.d.ts +4 -0
  298. package/dist/diagnostics/diagnostic.js.map +1 -1
  299. package/dist/diagnostics/dynamic-tier.d.ts +40 -0
  300. package/dist/diagnostics/dynamic-tier.js +57 -0
  301. package/dist/diagnostics/dynamic-tier.js.map +1 -0
  302. package/dist/diagnostics/envelope.d.ts +5 -1
  303. package/dist/diagnostics/envelope.js +6 -2
  304. package/dist/diagnostics/envelope.js.map +1 -1
  305. package/dist/executable/executable-cache.d.ts +25 -1
  306. package/dist/executable/executable-cache.js +60 -7
  307. package/dist/executable/executable-cache.js.map +1 -1
  308. package/dist/executable/executable-cache.test.js +46 -3
  309. package/dist/executable/executable-cache.test.js.map +1 -1
  310. package/dist/executable/prepare.js +3 -1
  311. package/dist/executable/prepare.js.map +1 -1
  312. package/dist/frontend/analysis.js +1 -0
  313. package/dist/frontend/analysis.js.map +1 -1
  314. package/dist/frontend/decl-projection.d.ts +41 -0
  315. package/dist/frontend/decl-projection.js +854 -0
  316. package/dist/frontend/decl-projection.js.map +1 -0
  317. package/dist/frontend/decl-projection.test.d.ts +1 -0
  318. package/dist/frontend/decl-projection.test.js +30 -0
  319. package/dist/frontend/decl-projection.test.js.map +1 -0
  320. package/dist/frontend/dispose-hook.d.ts +2 -0
  321. package/dist/frontend/dispose-hook.js +14 -0
  322. package/dist/frontend/dispose-hook.js.map +1 -0
  323. package/dist/frontend/dts-paths.d.ts +15 -0
  324. package/dist/frontend/dts-paths.js +25 -0
  325. package/dist/frontend/dts-paths.js.map +1 -1
  326. package/dist/frontend/input-tracker.d.ts +6 -0
  327. package/dist/frontend/input-tracker.js +51 -28
  328. package/dist/frontend/input-tracker.js.map +1 -1
  329. package/dist/frontend/input-tracker.test.js +19 -0
  330. package/dist/frontend/input-tracker.test.js.map +1 -1
  331. package/dist/frontend/jsx-entities.d.ts +4 -0
  332. package/dist/frontend/jsx-entities.js +259 -0
  333. package/dist/frontend/jsx-entities.js.map +1 -0
  334. package/dist/frontend/jsx-source.d.ts +71 -0
  335. package/dist/frontend/jsx-source.js +781 -0
  336. package/dist/frontend/jsx-source.js.map +1 -0
  337. package/dist/frontend/jsx-source.test.d.ts +1 -0
  338. package/dist/frontend/jsx-source.test.js +200 -0
  339. package/dist/frontend/jsx-source.test.js.map +1 -0
  340. package/dist/frontend/literal-values.test.js +8 -9
  341. package/dist/frontend/literal-values.test.js.map +1 -1
  342. package/dist/frontend/lowering/array-indexed-mutation.js +2 -1
  343. package/dist/frontend/lowering/array-indexed-mutation.js.map +1 -1
  344. package/dist/frontend/lowering/array-values.js +103 -4
  345. package/dist/frontend/lowering/array-values.js.map +1 -1
  346. package/dist/frontend/lowering/binding-analysis.d.ts +1 -1
  347. package/dist/frontend/lowering/binding-analysis.js +2 -2
  348. package/dist/frontend/lowering/binding-analysis.js.map +1 -1
  349. package/dist/frontend/lowering/builtins/arguments.d.ts +3 -0
  350. package/dist/frontend/lowering/builtins/arguments.js +30 -15
  351. package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
  352. package/dist/frontend/lowering/builtins/atomics.js +10 -6
  353. package/dist/frontend/lowering/builtins/atomics.js.map +1 -1
  354. package/dist/frontend/lowering/builtins/child-process-async.js +2 -1
  355. package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -1
  356. package/dist/frontend/lowering/builtins/child-process-methods.js +46 -15
  357. package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
  358. package/dist/frontend/lowering/builtins/child-process-sync.js +2 -1
  359. package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -1
  360. package/dist/frontend/lowering/builtins/child-process.js +13 -2
  361. package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
  362. package/dist/frontend/lowering/builtins/crypto.d.ts +4 -2
  363. package/dist/frontend/lowering/builtins/crypto.js +136 -5
  364. package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
  365. package/dist/frontend/lowering/builtins/date-classes.d.ts +46 -0
  366. package/dist/frontend/lowering/builtins/date-classes.js +477 -0
  367. package/dist/frontend/lowering/builtins/date-classes.js.map +1 -0
  368. package/dist/frontend/lowering/builtins/dates.d.ts +11 -1
  369. package/dist/frontend/lowering/builtins/dates.js +55 -26
  370. package/dist/frontend/lowering/builtins/dates.js.map +1 -1
  371. package/dist/frontend/lowering/builtins/dh.d.ts +15 -0
  372. package/dist/frontend/lowering/builtins/dh.js +151 -0
  373. package/dist/frontend/lowering/builtins/dh.js.map +1 -0
  374. package/dist/frontend/lowering/builtins/disposable-stack.js +2 -1
  375. package/dist/frontend/lowering/builtins/disposable-stack.js.map +1 -1
  376. package/dist/frontend/lowering/builtins/ecdh.d.ts +12 -1
  377. package/dist/frontend/lowering/builtins/ecdh.js +7 -7
  378. package/dist/frontend/lowering/builtins/ecdh.js.map +1 -1
  379. package/dist/frontend/lowering/builtins/errors.d.ts +15 -0
  380. package/dist/frontend/lowering/builtins/errors.js +110 -0
  381. package/dist/frontend/lowering/builtins/errors.js.map +1 -1
  382. package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +1 -1
  383. package/dist/frontend/lowering/builtins/filesystem-calls.js +23 -17
  384. package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
  385. package/dist/frontend/lowering/builtins/filesystem.js +6 -4
  386. package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
  387. package/dist/frontend/lowering/builtins/fs-paths.d.ts +15 -0
  388. package/dist/frontend/lowering/builtins/fs-paths.js +209 -0
  389. package/dist/frontend/lowering/builtins/fs-paths.js.map +1 -0
  390. package/dist/frontend/lowering/builtins/global-namespace-keys.d.ts +3 -0
  391. package/dist/frontend/lowering/builtins/global-namespace-keys.js +122 -0
  392. package/dist/frontend/lowering/builtins/global-namespace-keys.js.map +1 -0
  393. package/dist/frontend/lowering/builtins/hash-stream.d.ts +16 -4
  394. package/dist/frontend/lowering/builtins/hash-stream.js +86 -23
  395. package/dist/frontend/lowering/builtins/hash-stream.js.map +1 -1
  396. package/dist/frontend/lowering/builtins/json.js +2 -1
  397. package/dist/frontend/lowering/builtins/json.js.map +1 -1
  398. package/dist/frontend/lowering/builtins/key-object.d.ts +2 -1
  399. package/dist/frontend/lowering/builtins/key-object.js +20 -7
  400. package/dist/frontend/lowering/builtins/key-object.js.map +1 -1
  401. package/dist/frontend/lowering/builtins/module-calls.js +11 -4
  402. package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
  403. package/dist/frontend/lowering/builtins/numbers.js +18 -6
  404. package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
  405. package/dist/frontend/lowering/builtins/operating-system.js +4 -3
  406. package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
  407. package/dist/frontend/lowering/builtins/performance.js +3 -2
  408. package/dist/frontend/lowering/builtins/performance.js.map +1 -1
  409. package/dist/frontend/lowering/builtins/process.js +3 -2
  410. package/dist/frontend/lowering/builtins/process.js.map +1 -1
  411. package/dist/frontend/lowering/builtins/promises.d.ts +6 -0
  412. package/dist/frontend/lowering/builtins/promises.js +91 -4
  413. package/dist/frontend/lowering/builtins/promises.js.map +1 -1
  414. package/dist/frontend/lowering/builtins/promisify-callback.js +2 -1
  415. package/dist/frontend/lowering/builtins/promisify-callback.js.map +1 -1
  416. package/dist/frontend/lowering/builtins/readline.d.ts +7 -2
  417. package/dist/frontend/lowering/builtins/readline.js +58 -9
  418. package/dist/frontend/lowering/builtins/readline.js.map +1 -1
  419. package/dist/frontend/lowering/builtins/strings.js +13 -5
  420. package/dist/frontend/lowering/builtins/strings.js.map +1 -1
  421. package/dist/frontend/lowering/builtins/text-codecs.js +2 -1
  422. package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
  423. package/dist/frontend/lowering/builtins/timers.js +1 -1
  424. package/dist/frontend/lowering/builtins/timers.js.map +1 -1
  425. package/dist/frontend/lowering/builtins/url.js +28 -4
  426. package/dist/frontend/lowering/builtins/url.js.map +1 -1
  427. package/dist/frontend/lowering/builtins/v8.js +2 -1
  428. package/dist/frontend/lowering/builtins/v8.js.map +1 -1
  429. package/dist/frontend/lowering/builtins/webassembly.js +6 -3
  430. package/dist/frontend/lowering/builtins/webassembly.js.map +1 -1
  431. package/dist/frontend/lowering/builtins/webcrypto.js +39 -20
  432. package/dist/frontend/lowering/builtins/webcrypto.js.map +1 -1
  433. package/dist/frontend/lowering/call-arguments.js +2 -1
  434. package/dist/frontend/lowering/call-arguments.js.map +1 -1
  435. package/dist/frontend/lowering/call-signatures.js +13 -6
  436. package/dist/frontend/lowering/call-signatures.js.map +1 -1
  437. package/dist/frontend/lowering/caught-value-dispatch.d.ts +18 -1
  438. package/dist/frontend/lowering/caught-value-dispatch.js +201 -32
  439. package/dist/frontend/lowering/caught-value-dispatch.js.map +1 -1
  440. package/dist/frontend/lowering/class-assertions.js +3 -2
  441. package/dist/frontend/lowering/class-assertions.js.map +1 -1
  442. package/dist/frontend/lowering/class-callbacks.d.ts +5 -2
  443. package/dist/frontend/lowering/class-callbacks.js +82 -12
  444. package/dist/frontend/lowering/class-callbacks.js.map +1 -1
  445. package/dist/frontend/lowering/class-construction.d.ts +6 -2
  446. package/dist/frontend/lowering/class-construction.js +25 -16
  447. package/dist/frontend/lowering/class-construction.js.map +1 -1
  448. package/dist/frontend/lowering/class-descriptors.js +1 -1
  449. package/dist/frontend/lowering/class-descriptors.js.map +1 -1
  450. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +73 -2
  451. package/dist/frontend/lowering/class-dynamic-dispatch.js +1334 -259
  452. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  453. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +124 -0
  454. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
  455. package/dist/frontend/lowering/class-iterables.d.ts +2 -1
  456. package/dist/frontend/lowering/class-iterables.js +9 -1
  457. package/dist/frontend/lowering/class-iterables.js.map +1 -1
  458. package/dist/frontend/lowering/class-method-mutations.js +35 -9
  459. package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
  460. package/dist/frontend/lowering/class-method-values.js +1 -1
  461. package/dist/frontend/lowering/class-method-values.js.map +1 -1
  462. package/dist/frontend/lowering/class-protocols.d.ts +7 -0
  463. package/dist/frontend/lowering/class-protocols.js +64 -4
  464. package/dist/frontend/lowering/class-protocols.js.map +1 -1
  465. package/dist/frontend/lowering/class-prototypes.d.ts +5 -0
  466. package/dist/frontend/lowering/class-prototypes.js +67 -5
  467. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  468. package/dist/frontend/lowering/class-runtime-statics.d.ts +9 -3
  469. package/dist/frontend/lowering/class-runtime-statics.js +29 -4
  470. package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
  471. package/dist/frontend/lowering/class-to-primitive.js +25 -5
  472. package/dist/frontend/lowering/class-to-primitive.js.map +1 -1
  473. package/dist/frontend/lowering/class-unions.js +2 -1
  474. package/dist/frontend/lowering/class-unions.js.map +1 -1
  475. package/dist/frontend/lowering/coercions/function-adapters.js +6 -5
  476. package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
  477. package/dist/frontend/lowering/coercions/structural-plans.js +48 -1
  478. package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
  479. package/dist/frontend/lowering/coercions/structural.js +99 -8
  480. package/dist/frontend/lowering/coercions/structural.js.map +1 -1
  481. package/dist/frontend/lowering/coercions/unions.js +8 -7
  482. package/dist/frontend/lowering/coercions/unions.js.map +1 -1
  483. package/dist/frontend/lowering/collection-ingestion.js +2 -1
  484. package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
  485. package/dist/frontend/lowering/containers/array-callback-call.js +2 -2
  486. package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -1
  487. package/dist/frontend/lowering/containers/array-callbacks.d.ts +7 -0
  488. package/dist/frontend/lowering/containers/array-callbacks.js +352 -31
  489. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  490. package/dist/frontend/lowering/containers/array-concat.js +12 -1
  491. package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
  492. package/dist/frontend/lowering/containers/array-construction.js +25 -4
  493. package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
  494. package/dist/frontend/lowering/containers/array-methods.js +21 -5
  495. package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
  496. package/dist/frontend/lowering/containers/array-pipelines.js +21 -9
  497. package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
  498. package/dist/frontend/lowering/containers/bytes.d.ts +1 -1
  499. package/dist/frontend/lowering/containers/bytes.js +131 -29
  500. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  501. package/dist/frontend/lowering/containers/callback-arguments.js +55 -2
  502. package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
  503. package/dist/frontend/lowering/containers/collection-grouping.js +3 -2
  504. package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
  505. package/dist/frontend/lowering/containers/collection-methods.js +15 -9
  506. package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
  507. package/dist/frontend/lowering/containers/filter-predicates.d.ts +6 -0
  508. package/dist/frontend/lowering/containers/filter-predicates.js +205 -0
  509. package/dist/frontend/lowering/containers/filter-predicates.js.map +1 -0
  510. package/dist/frontend/lowering/containers/indexed-objects.d.ts +0 -12
  511. package/dist/frontend/lowering/containers/indexed-objects.js +54 -14
  512. package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
  513. package/dist/frontend/lowering/containers/iterator-helpers.d.ts +32 -1
  514. package/dist/frontend/lowering/containers/iterator-helpers.js +6 -5
  515. package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -1
  516. package/dist/frontend/lowering/containers/string-and-regexp.js +87 -14
  517. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  518. package/dist/frontend/lowering/containers/string-replacement.js +45 -20
  519. package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
  520. package/dist/frontend/lowering/cycle-initialization.js +25 -4
  521. package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
  522. package/dist/frontend/lowering/deferred-module-initializers.d.ts +18 -1
  523. package/dist/frontend/lowering/deferred-module-initializers.js +226 -115
  524. package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
  525. package/dist/frontend/lowering/deferred-module-initializers.test.js +28 -0
  526. package/dist/frontend/lowering/deferred-module-initializers.test.js.map +1 -1
  527. package/dist/frontend/lowering/dispatch-sites.d.ts +59 -0
  528. package/dist/frontend/lowering/dispatch-sites.js +218 -0
  529. package/dist/frontend/lowering/dispatch-sites.js.map +1 -0
  530. package/dist/frontend/lowering/dispatch-sites.test.d.ts +1 -0
  531. package/dist/frontend/lowering/dispatch-sites.test.js +59 -0
  532. package/dist/frontend/lowering/dispatch-sites.test.js.map +1 -0
  533. package/dist/frontend/lowering/divergences.js +9 -1
  534. package/dist/frontend/lowering/divergences.js.map +1 -1
  535. package/dist/frontend/lowering/dyn-streams.d.ts +3 -0
  536. package/dist/frontend/lowering/dyn-streams.js +1 -1
  537. package/dist/frontend/lowering/dyn-streams.js.map +1 -1
  538. package/dist/frontend/lowering/dynamic-tier.d.ts +25 -0
  539. package/dist/frontend/lowering/dynamic-tier.js +327 -0
  540. package/dist/frontend/lowering/dynamic-tier.js.map +1 -0
  541. package/dist/frontend/lowering/error-methods.js +51 -2
  542. package/dist/frontend/lowering/error-methods.js.map +1 -1
  543. package/dist/frontend/lowering/expressions/array-literals.js +62 -0
  544. package/dist/frontend/lowering/expressions/array-literals.js.map +1 -1
  545. package/dist/frontend/lowering/expressions/binary.js +81 -5
  546. package/dist/frontend/lowering/expressions/binary.js.map +1 -1
  547. package/dist/frontend/lowering/expressions/element-access.js +107 -14
  548. package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
  549. package/dist/frontend/lowering/expressions/identifiers.js +79 -11
  550. package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
  551. package/dist/frontend/lowering/expressions/narrowing.js +130 -6
  552. package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
  553. package/dist/frontend/lowering/expressions/nullish-assignment.js +3 -1
  554. package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
  555. package/dist/frontend/lowering/expressions/object-literals.d.ts +10 -3
  556. package/dist/frontend/lowering/expressions/object-literals.js +164 -56
  557. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  558. package/dist/frontend/lowering/expressions/optional-chains.js +17 -5
  559. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  560. package/dist/frontend/lowering/expressions/property-access.d.ts +0 -4
  561. package/dist/frontend/lowering/expressions/property-access.js +211 -17
  562. package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
  563. package/dist/frontend/lowering/expressions/relational.js +267 -30
  564. package/dist/frontend/lowering/expressions/relational.js.map +1 -1
  565. package/dist/frontend/lowering/expressions/union-fields.js +4 -0
  566. package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
  567. package/dist/frontend/lowering/expressions/updates.js +85 -12
  568. package/dist/frontend/lowering/expressions/updates.js.map +1 -1
  569. package/dist/frontend/lowering/frozen-records.d.ts +28 -0
  570. package/dist/frontend/lowering/frozen-records.js +322 -0
  571. package/dist/frontend/lowering/frozen-records.js.map +1 -0
  572. package/dist/frontend/lowering/function-returns.js +49 -0
  573. package/dist/frontend/lowering/function-returns.js.map +1 -1
  574. package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +6 -1
  575. package/dist/frontend/lowering/generator-dynamic-dispatch.js +20 -30
  576. package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
  577. package/dist/frontend/lowering/generic-functions.d.ts +42 -1
  578. package/dist/frontend/lowering/generic-functions.js +455 -20
  579. package/dist/frontend/lowering/generic-functions.js.map +1 -1
  580. package/dist/frontend/lowering/intern-tables.js +2 -1
  581. package/dist/frontend/lowering/intern-tables.js.map +1 -1
  582. package/dist/frontend/lowering/iterable-values.d.ts +49 -0
  583. package/dist/frontend/lowering/iterable-values.js +297 -0
  584. package/dist/frontend/lowering/iterable-values.js.map +1 -0
  585. package/dist/frontend/lowering/iterator-adapters.js +195 -9
  586. package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
  587. package/dist/frontend/lowering/js-class-fields.d.ts +8 -0
  588. package/dist/frontend/lowering/js-class-fields.js +45 -10
  589. package/dist/frontend/lowering/js-class-fields.js.map +1 -1
  590. package/dist/frontend/lowering/js-dynamic-objects.js +3 -2
  591. package/dist/frontend/lowering/js-dynamic-objects.js.map +1 -1
  592. package/dist/frontend/lowering/json-require.js +2 -1
  593. package/dist/frontend/lowering/json-require.js.map +1 -1
  594. package/dist/frontend/lowering/key-order-witness.d.ts +24 -4
  595. package/dist/frontend/lowering/key-order-witness.js +790 -25
  596. package/dist/frontend/lowering/key-order-witness.js.map +1 -1
  597. package/dist/frontend/lowering/key-order-witness.test.js +466 -10
  598. package/dist/frontend/lowering/key-order-witness.test.js.map +1 -1
  599. package/dist/frontend/lowering/lifetime-regions.js +2 -1
  600. package/dist/frontend/lowering/lifetime-regions.js.map +1 -1
  601. package/dist/frontend/lowering/lower-assert.js +6 -5
  602. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  603. package/dist/frontend/lowering/lower-async-iteration.js +7 -2
  604. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
  605. package/dist/frontend/lowering/lower-calls.d.ts +11 -0
  606. package/dist/frontend/lowering/lower-calls.js +776 -126
  607. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  608. package/dist/frontend/lowering/lower-classes.d.ts +29 -2
  609. package/dist/frontend/lowering/lower-classes.js +581 -46
  610. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  611. package/dist/frontend/lowering/lower-dgram.js +6 -3
  612. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  613. package/dist/frontend/lowering/lower-event-emitter.d.ts +14 -0
  614. package/dist/frontend/lowering/lower-event-emitter.js +267 -20
  615. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  616. package/dist/frontend/lowering/lower-exprs.d.ts +19 -2
  617. package/dist/frontend/lowering/lower-exprs.js +126 -13
  618. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  619. package/dist/frontend/lowering/lower-functions.d.ts +11 -0
  620. package/dist/frontend/lowering/lower-functions.js +387 -72
  621. package/dist/frontend/lowering/lower-functions.js.map +1 -1
  622. package/dist/frontend/lowering/lower-generators.js +41 -31
  623. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  624. package/dist/frontend/lowering/lower-global-value.js +6 -3
  625. package/dist/frontend/lowering/lower-global-value.js.map +1 -1
  626. package/dist/frontend/lowering/lower-inspect.js +28 -12
  627. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  628. package/dist/frontend/lowering/lower-mixins.js +2 -1
  629. package/dist/frontend/lowering/lower-mixins.js.map +1 -1
  630. package/dist/frontend/lowering/lower-mock.js +2 -1
  631. package/dist/frontend/lowering/lower-mock.js.map +1 -1
  632. package/dist/frontend/lowering/lower-modules.js +47 -5
  633. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  634. package/dist/frontend/lowering/lower-modules.test.js +2 -2
  635. package/dist/frontend/lowering/lower-modules.test.js.map +1 -1
  636. package/dist/frontend/lowering/lower-namespaces.d.ts +2 -1
  637. package/dist/frontend/lowering/lower-namespaces.js +9 -4
  638. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  639. package/dist/frontend/lowering/lower-server.d.ts +10 -0
  640. package/dist/frontend/lowering/lower-server.js +239 -61
  641. package/dist/frontend/lowering/lower-server.js.map +1 -1
  642. package/dist/frontend/lowering/lower-stdlib.d.ts +5 -0
  643. package/dist/frontend/lowering/lower-stdlib.js +42 -10
  644. package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
  645. package/dist/frontend/lowering/lower-stmts.d.ts +23 -0
  646. package/dist/frontend/lowering/lower-stmts.js +622 -68
  647. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  648. package/dist/frontend/lowering/lower-stmts.test.js +1 -1
  649. package/dist/frontend/lowering/lower-stmts.test.js.map +1 -1
  650. package/dist/frontend/lowering/lower-stream.d.ts +20 -2
  651. package/dist/frontend/lowering/lower-stream.js +2055 -318
  652. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  653. package/dist/frontend/lowering/lower-timers.js +4 -3
  654. package/dist/frontend/lowering/lower-timers.js.map +1 -1
  655. package/dist/frontend/lowering/lowerer.d.ts +197 -29
  656. package/dist/frontend/lowering/lowerer.js +862 -84
  657. package/dist/frontend/lowering/lowerer.js.map +1 -1
  658. package/dist/frontend/lowering/lowerer.test.js +21 -9
  659. package/dist/frontend/lowering/lowerer.test.js.map +1 -1
  660. package/dist/frontend/lowering/module-namespace-elements.d.ts +11 -1
  661. package/dist/frontend/lowering/module-namespace-elements.js +82 -5
  662. package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
  663. package/dist/frontend/lowering/narrowing-stability.js +5 -0
  664. package/dist/frontend/lowering/narrowing-stability.js.map +1 -1
  665. package/dist/frontend/lowering/native-ffi.js +1 -1
  666. package/dist/frontend/lowering/native-ffi.js.map +1 -1
  667. package/dist/frontend/lowering/new-target.d.ts +12 -0
  668. package/dist/frontend/lowering/new-target.js +280 -0
  669. package/dist/frontend/lowering/new-target.js.map +1 -0
  670. package/dist/frontend/lowering/object-enumeration-receiver.js +2 -1
  671. package/dist/frontend/lowering/object-enumeration-receiver.js.map +1 -1
  672. package/dist/frontend/lowering/pairs-snapshot.js +2 -1
  673. package/dist/frontend/lowering/pairs-snapshot.js.map +1 -1
  674. package/dist/frontend/lowering/private-brands.d.ts +9 -0
  675. package/dist/frontend/lowering/private-brands.js +66 -15
  676. package/dist/frontend/lowering/private-brands.js.map +1 -1
  677. package/dist/frontend/lowering/promise-executor-adapter.js +2 -1
  678. package/dist/frontend/lowering/promise-executor-adapter.js.map +1 -1
  679. package/dist/frontend/lowering/require-initialization.js +2 -1
  680. package/dist/frontend/lowering/require-initialization.js.map +1 -1
  681. package/dist/frontend/lowering/runtime-optional-elements.d.ts +5 -0
  682. package/dist/frontend/lowering/runtime-optional-elements.js +17 -1
  683. package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -1
  684. package/dist/frontend/lowering/runtime-optional-records.d.ts +2 -0
  685. package/dist/frontend/lowering/runtime-optional-records.js +18 -5
  686. package/dist/frontend/lowering/runtime-optional-records.js.map +1 -1
  687. package/dist/frontend/lowering/site-dependencies.d.ts +35 -0
  688. package/dist/frontend/lowering/site-dependencies.js +84 -0
  689. package/dist/frontend/lowering/site-dependencies.js.map +1 -0
  690. package/dist/frontend/lowering/site-dependencies.test.d.ts +1 -0
  691. package/dist/frontend/lowering/site-dependencies.test.js +53 -0
  692. package/dist/frontend/lowering/site-dependencies.test.js.map +1 -0
  693. package/dist/frontend/lowering/stable-names.d.ts +11 -0
  694. package/dist/frontend/lowering/stable-names.js +35 -0
  695. package/dist/frontend/lowering/stable-names.js.map +1 -0
  696. package/dist/frontend/lowering/static-typeof.d.ts +2 -2
  697. package/dist/frontend/lowering/static-typeof.js +42 -3
  698. package/dist/frontend/lowering/static-typeof.js.map +1 -1
  699. package/dist/frontend/lowering/strict-equality.js +2 -1
  700. package/dist/frontend/lowering/strict-equality.js.map +1 -1
  701. package/dist/frontend/lowering/structural-positions.d.ts +32 -0
  702. package/dist/frontend/lowering/structural-positions.js +108 -0
  703. package/dist/frontend/lowering/structural-positions.js.map +1 -0
  704. package/dist/frontend/lowering/surfaces.d.ts +3 -0
  705. package/dist/frontend/lowering/surfaces.js +60 -32
  706. package/dist/frontend/lowering/surfaces.js.map +1 -1
  707. package/dist/frontend/lowering/undefined-index.d.ts +27 -0
  708. package/dist/frontend/lowering/undefined-index.js +82 -0
  709. package/dist/frontend/lowering/undefined-index.js.map +1 -0
  710. package/dist/frontend/lowering/var-hoisting.js +66 -16
  711. package/dist/frontend/lowering/var-hoisting.js.map +1 -1
  712. package/dist/frontend/lowering/width-lift.d.ts +18 -0
  713. package/dist/frontend/npm-static-bundled-chunks.js +9 -11
  714. package/dist/frontend/npm-static-bundled-chunks.js.map +1 -1
  715. package/dist/frontend/npm-static-bundled-chunks.test.js +6 -5
  716. package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -1
  717. package/dist/frontend/npm-static-rewrite-syntax.js +9 -1
  718. package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
  719. package/dist/frontend/npm-static-tsc-helpers.d.ts +5 -0
  720. package/dist/frontend/npm-static-tsc-helpers.js +106 -0
  721. package/dist/frontend/npm-static-tsc-helpers.js.map +1 -0
  722. package/dist/frontend/npm-static-tsc-helpers.test.d.ts +1 -0
  723. package/dist/frontend/npm-static-tsc-helpers.test.js +58 -0
  724. package/dist/frontend/npm-static-tsc-helpers.test.js.map +1 -0
  725. package/dist/frontend/npm-static-type-exports-host.d.ts +8 -0
  726. package/dist/frontend/npm-static-type-exports-host.js +214 -0
  727. package/dist/frontend/npm-static-type-exports-host.js.map +1 -0
  728. package/dist/frontend/npm-static-type-exports-host.test.d.ts +1 -0
  729. package/dist/frontend/npm-static-type-exports-host.test.js +53 -0
  730. package/dist/frontend/npm-static-type-exports-host.test.js.map +1 -0
  731. package/dist/frontend/npm-static-type-exports.d.ts +52 -0
  732. package/dist/frontend/npm-static-type-exports.js +261 -0
  733. package/dist/frontend/npm-static-type-exports.js.map +1 -0
  734. package/dist/frontend/npm-static-type-exports.test.d.ts +1 -0
  735. package/dist/frontend/npm-static-type-exports.test.js +103 -0
  736. package/dist/frontend/npm-static-type-exports.test.js.map +1 -0
  737. package/dist/frontend/npm-static-umd.d.ts +6 -0
  738. package/dist/frontend/npm-static-umd.js +203 -0
  739. package/dist/frontend/npm-static-umd.js.map +1 -0
  740. package/dist/frontend/npm-static-umd.test.d.ts +1 -0
  741. package/dist/frontend/npm-static-umd.test.js +105 -0
  742. package/dist/frontend/npm-static-umd.test.js.map +1 -0
  743. package/dist/frontend/npm-static.d.ts +8 -0
  744. package/dist/frontend/npm-static.js +51 -22
  745. package/dist/frontend/npm-static.js.map +1 -1
  746. package/dist/frontend/package-shims.d.ts +3 -0
  747. package/dist/frontend/package-shims.js +71 -8
  748. package/dist/frontend/package-shims.js.map +1 -1
  749. package/dist/frontend/pipeline.js +18 -10
  750. package/dist/frontend/pipeline.js.map +1 -1
  751. package/dist/frontend/process-fork.d.ts +25 -0
  752. package/dist/frontend/process-fork.js +2 -0
  753. package/dist/frontend/process-fork.js.map +1 -0
  754. package/dist/frontend/program.d.ts +21 -1
  755. package/dist/frontend/program.js +586 -74
  756. package/dist/frontend/program.js.map +1 -1
  757. package/dist/frontend/program.test.js +44 -4
  758. package/dist/frontend/program.test.js.map +1 -1
  759. package/dist/frontend/services.d.ts +6 -0
  760. package/dist/frontend/services.js +18 -0
  761. package/dist/frontend/services.js.map +1 -1
  762. package/dist/frontend/token-equivalence.d.ts +3 -0
  763. package/dist/frontend/token-equivalence.js +409 -0
  764. package/dist/frontend/token-equivalence.js.map +1 -0
  765. package/dist/frontend/token-equivalence.test.d.ts +1 -0
  766. package/dist/frontend/token-equivalence.test.js +67 -0
  767. package/dist/frontend/token-equivalence.test.js.map +1 -0
  768. package/dist/frontend/ts7/ast-node.d.ts +43 -7
  769. package/dist/frontend/ts7/ast-node.js +1176 -129
  770. package/dist/frontend/ts7/ast-node.js.map +1 -1
  771. package/dist/frontend/ts7/ast-node.test.js +84 -0
  772. package/dist/frontend/ts7/ast-node.test.js.map +1 -1
  773. package/dist/frontend/ts7/ast-wire.d.ts +29 -3
  774. package/dist/frontend/ts7/ast-wire.js +144 -31
  775. package/dist/frontend/ts7/ast-wire.js.map +1 -1
  776. package/dist/frontend/ts7/ast-wire.test.js +23 -0
  777. package/dist/frontend/ts7/ast-wire.test.js.map +1 -1
  778. package/dist/frontend/ts7/ast.d.ts +23 -2
  779. package/dist/frontend/ts7/ast.js +143 -2
  780. package/dist/frontend/ts7/ast.js.map +1 -1
  781. package/dist/frontend/ts7/checker-backend.d.ts +3 -4
  782. package/dist/frontend/ts7/checker-backend.js +2 -2
  783. package/dist/frontend/ts7/checker-backend.js.map +1 -1
  784. package/dist/frontend/ts7/checker-backend.test.js +5 -9
  785. package/dist/frontend/ts7/checker-backend.test.js.map +1 -1
  786. package/dist/frontend/ts7/checker.d.ts +17 -1
  787. package/dist/frontend/ts7/checker.js +82 -1
  788. package/dist/frontend/ts7/checker.js.map +1 -1
  789. package/dist/frontend/ts7/checker.test.js +9 -6
  790. package/dist/frontend/ts7/checker.test.js.map +1 -1
  791. package/dist/frontend/ts7/enums.d.ts +3 -3
  792. package/dist/frontend/ts7/enums.generated.d.ts +10 -0
  793. package/dist/frontend/ts7/enums.generated.js +21 -0
  794. package/dist/frontend/ts7/enums.generated.js.map +1 -1
  795. package/dist/frontend/ts7/enums.js +19 -0
  796. package/dist/frontend/ts7/enums.js.map +1 -1
  797. package/dist/frontend/ts7/lib-diagnostics.d.ts +24 -0
  798. package/dist/frontend/ts7/lib-diagnostics.js +307 -0
  799. package/dist/frontend/ts7/lib-diagnostics.js.map +1 -0
  800. package/dist/frontend/ts7/lib-diagnostics.test.d.ts +1 -0
  801. package/dist/frontend/ts7/lib-diagnostics.test.js +199 -0
  802. package/dist/frontend/ts7/lib-diagnostics.test.js.map +1 -0
  803. package/dist/frontend/ts7/program-host.d.ts +7 -0
  804. package/dist/frontend/ts7/program-host.js +30 -4
  805. package/dist/frontend/ts7/program-host.js.map +1 -1
  806. package/dist/frontend/ts7/semantic-checker.d.ts +10 -0
  807. package/dist/frontend/ts7/semantic-checker.js +25 -20
  808. package/dist/frontend/ts7/semantic-checker.js.map +1 -1
  809. package/dist/frontend/ts7/semantic-json.d.ts +13 -0
  810. package/dist/frontend/ts7/semantic-json.js +146 -0
  811. package/dist/frontend/ts7/semantic-json.js.map +1 -1
  812. package/dist/frontend/ts7/semantic-json.test.js +57 -1
  813. package/dist/frontend/ts7/semantic-json.test.js.map +1 -1
  814. package/dist/frontend/ts7/semantic-model.d.ts +15 -0
  815. package/dist/frontend/ts7/semantic-model.js +67 -19
  816. package/dist/frontend/ts7/semantic-model.js.map +1 -1
  817. package/dist/frontend/ts7/semantic-model.test.js +3 -2
  818. package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
  819. package/dist/frontend/ts7/session.d.ts +14 -1
  820. package/dist/frontend/ts7/session.js +23 -1
  821. package/dist/frontend/ts7/session.js.map +1 -1
  822. package/dist/frontend/tsc-codes.d.ts +1 -1
  823. package/dist/frontend/tsc-codes.js +7 -0
  824. package/dist/frontend/tsc-codes.js.map +1 -1
  825. package/dist/frontend/type-mapper.d.ts +51 -7
  826. package/dist/frontend/type-mapper.js +456 -43
  827. package/dist/frontend/type-mapper.js.map +1 -1
  828. package/dist/frontend/type-mapper.test.js +1 -1
  829. package/dist/frontend/type-mapper.test.js.map +1 -1
  830. package/dist/frontend-process-args.d.ts +4 -0
  831. package/dist/frontend-process-args.js +52 -0
  832. package/dist/frontend-process-args.js.map +1 -0
  833. package/dist/frontend-process-args.test.d.ts +1 -0
  834. package/dist/frontend-process-args.test.js +47 -0
  835. package/dist/frontend-process-args.test.js.map +1 -0
  836. package/dist/frontend-process.d.ts +1 -0
  837. package/dist/frontend-process.js +23 -0
  838. package/dist/frontend-process.js.map +1 -0
  839. package/dist/heap-collection.d.ts +16 -0
  840. package/dist/heap-collection.js +42 -0
  841. package/dist/heap-collection.js.map +1 -0
  842. package/dist/heap-collection.test.d.ts +1 -0
  843. package/dist/heap-collection.test.js +59 -0
  844. package/dist/heap-collection.test.js.map +1 -0
  845. package/dist/heap-pressure.d.ts +2 -0
  846. package/dist/heap-pressure.js +12 -0
  847. package/dist/heap-pressure.js.map +1 -0
  848. package/dist/index.d.ts +2 -0
  849. package/dist/index.js +435 -89
  850. package/dist/index.js.map +1 -1
  851. package/dist/ir/analysis.js +5 -3
  852. package/dist/ir/analysis.js.map +1 -1
  853. package/dist/ir/array-length-stability.d.ts +4 -0
  854. package/dist/ir/array-length-stability.js +26 -6
  855. package/dist/ir/array-length-stability.js.map +1 -1
  856. package/dist/ir/array-length-stability.test.js +49 -0
  857. package/dist/ir/array-length-stability.test.js.map +1 -1
  858. package/dist/ir/builtin-effects.d.ts +7 -0
  859. package/dist/ir/builtin-effects.js +80 -0
  860. package/dist/ir/builtin-effects.js.map +1 -1
  861. package/dist/ir/builtin-signatures.d.ts +7 -1
  862. package/dist/ir/builtin-signatures.js +303 -21
  863. package/dist/ir/builtin-signatures.js.map +1 -1
  864. package/dist/ir/callback-specialization.d.ts +2 -1
  865. package/dist/ir/callback-specialization.js +23 -18
  866. package/dist/ir/callback-specialization.js.map +1 -1
  867. package/dist/ir/char-unit-locals.d.ts +19 -0
  868. package/dist/ir/char-unit-locals.js +185 -0
  869. package/dist/ir/char-unit-locals.js.map +1 -0
  870. package/dist/ir/char-unit-locals.test.d.ts +1 -0
  871. package/dist/ir/char-unit-locals.test.js +94 -0
  872. package/dist/ir/char-unit-locals.test.js.map +1 -0
  873. package/dist/ir/final-fields.d.ts +3 -1
  874. package/dist/ir/final-fields.js +15 -17
  875. package/dist/ir/final-fields.js.map +1 -1
  876. package/dist/ir/function-references.d.ts +2 -0
  877. package/dist/ir/function-references.js +2 -0
  878. package/dist/ir/function-references.js.map +1 -1
  879. package/dist/ir/function-references.test.js +5 -0
  880. package/dist/ir/function-references.test.js.map +1 -1
  881. package/dist/ir/initializer-bindings.d.ts +2 -1
  882. package/dist/ir/initializer-bindings.js +27 -20
  883. package/dist/ir/initializer-bindings.js.map +1 -1
  884. package/dist/ir/int32-arrays.d.ts +108 -0
  885. package/dist/ir/int32-arrays.js +831 -0
  886. package/dist/ir/int32-arrays.js.map +1 -0
  887. package/dist/ir/int32-slots.d.ts +36 -6
  888. package/dist/ir/int32-slots.js +370 -171
  889. package/dist/ir/int32-slots.js.map +1 -1
  890. package/dist/ir/int32-slots.test.js +3 -1
  891. package/dist/ir/int32-slots.test.js.map +1 -1
  892. package/dist/ir/integer-loop-facts.d.ts +9 -4
  893. package/dist/ir/integer-loop-facts.js +93 -18
  894. package/dist/ir/integer-loop-facts.js.map +1 -1
  895. package/dist/ir/integer-loops.d.ts +49 -0
  896. package/dist/ir/integer-loops.js +202 -40
  897. package/dist/ir/integer-loops.js.map +1 -1
  898. package/dist/ir/integer-loops.test.js +211 -1
  899. package/dist/ir/integer-loops.test.js.map +1 -1
  900. package/dist/ir/integer-ranges.d.ts +5 -0
  901. package/dist/ir/integer-ranges.js +125 -12
  902. package/dist/ir/integer-ranges.js.map +1 -1
  903. package/dist/ir/integer-ranges.test.js +94 -0
  904. package/dist/ir/integer-ranges.test.js.map +1 -1
  905. package/dist/ir/ir.d.ts +87 -9
  906. package/dist/ir/ir.js +61 -2
  907. package/dist/ir/ir.js.map +1 -1
  908. package/dist/ir/ir.test.js +21 -1
  909. package/dist/ir/ir.test.js.map +1 -1
  910. package/dist/ir/js-ic.d.ts +19 -2
  911. package/dist/ir/js-ic.js +95 -11
  912. package/dist/ir/js-ic.js.map +1 -1
  913. package/dist/ir/js-ic.test.js +188 -0
  914. package/dist/ir/js-ic.test.js.map +1 -1
  915. package/dist/ir/node-index.d.ts +57 -0
  916. package/dist/ir/node-index.js +215 -0
  917. package/dist/ir/node-index.js.map +1 -0
  918. package/dist/ir/paired-while-loops.d.ts +25 -0
  919. package/dist/ir/paired-while-loops.js +335 -0
  920. package/dist/ir/paired-while-loops.js.map +1 -0
  921. package/dist/ir/paired-while-loops.test.d.ts +1 -0
  922. package/dist/ir/paired-while-loops.test.js +163 -0
  923. package/dist/ir/paired-while-loops.test.js.map +1 -0
  924. package/dist/ir/parameter-versions.d.ts +25 -0
  925. package/dist/ir/parameter-versions.js +300 -0
  926. package/dist/ir/parameter-versions.js.map +1 -0
  927. package/dist/ir/runtime-features.d.ts +60 -15
  928. package/dist/ir/runtime-features.js +276 -35
  929. package/dist/ir/runtime-features.js.map +1 -1
  930. package/dist/ir/serialize.d.ts +12 -2
  931. package/dist/ir/serialize.js +16 -3
  932. package/dist/ir/serialize.js.map +1 -1
  933. package/dist/ir/serialize.test.js +17 -0
  934. package/dist/ir/serialize.test.js.map +1 -1
  935. package/dist/ir/tiers.js +1 -0
  936. package/dist/ir/tiers.js.map +1 -1
  937. package/dist/ir/traverse.d.ts +2 -0
  938. package/dist/ir/traverse.js +29 -5
  939. package/dist/ir/traverse.js.map +1 -1
  940. package/dist/ir/validate.js +171 -45
  941. package/dist/ir/validate.js.map +1 -1
  942. package/dist/library/ir-policy.js +12 -0
  943. package/dist/library/ir-policy.js.map +1 -1
  944. package/dist/library/library-cache.d.ts +2 -0
  945. package/dist/library/library-cache.js.map +1 -1
  946. package/dist/library/prepare.js +2 -0
  947. package/dist/library/prepare.js.map +1 -1
  948. package/dist/native/cache.d.ts +6 -1
  949. package/dist/native/cache.js +28 -5
  950. package/dist/native/cache.js.map +1 -1
  951. package/dist/native/cache.test.js +16 -2
  952. package/dist/native/cache.test.js.map +1 -1
  953. package/dist/native/cli.js +26 -1
  954. package/dist/native/cli.js.map +1 -1
  955. package/dist/native/compiler.js +8 -6
  956. package/dist/native/compiler.js.map +1 -1
  957. package/dist/native/executable-cache.d.ts +1 -1
  958. package/dist/native/executable-cache.js +2 -2
  959. package/dist/native/executable-cache.js.map +1 -1
  960. package/dist/native/prepare.d.ts +3 -1
  961. package/dist/native/prepare.js +123 -31
  962. package/dist/native/prepare.js.map +1 -1
  963. package/dist/native/prepare.test.js +78 -18
  964. package/dist/native/prepare.test.js.map +1 -1
  965. package/dist/native/sanitizer.test.js +6 -1
  966. package/dist/native/sanitizer.test.js.map +1 -1
  967. package/dist/native/text-file.d.ts +13 -3
  968. package/dist/native/text-file.js +63 -9
  969. package/dist/native/text-file.js.map +1 -1
  970. package/dist/native/text-file.test.d.ts +1 -0
  971. package/dist/native/text-file.test.js +49 -0
  972. package/dist/native/text-file.test.js.map +1 -0
  973. package/dist/native/toolchain.js +4 -4
  974. package/dist/native/toolchain.js.map +1 -1
  975. package/dist/native/toolchain.test.js +3 -3
  976. package/dist/native/toolchain.test.js.map +1 -1
  977. package/dist/startup-cache.d.ts +1 -0
  978. package/dist/startup-cache.js +1 -0
  979. package/dist/startup-cache.js.map +1 -1
  980. package/dist/text-parts.d.ts +7 -0
  981. package/dist/text-parts.js +44 -0
  982. package/dist/text-parts.js.map +1 -1
  983. package/dist/text-parts.test.d.ts +1 -0
  984. package/dist/text-parts.test.js +46 -0
  985. package/dist/text-parts.test.js.map +1 -0
  986. package/dist/timing.d.ts +9 -2
  987. package/dist/timing.js +7 -4
  988. package/dist/timing.js.map +1 -1
  989. package/dist/wasm/translate.d.ts +4 -0
  990. package/dist/wasm/translate.js +2 -2
  991. package/dist/wasm/translate.js.map +1 -1
  992. package/package.json +21 -21
  993. package/shims/chalk/v5.ts +688 -0
  994. package/shims/hono-node-server/v2.ts +645 -0
  995. package/shims/hot-shots/client.ts +1126 -0
  996. package/shims/hot-shots/v8-unix-dgram.ts +8 -0
  997. package/shims/hot-shots/v8.ts +8 -0
  998. package/shims/undici/core/client.ts +4 -4
  999. package/surface-manifest.json +44 -52
@@ -1,8 +1,11 @@
1
1
  import { primitiveConstructorOr } from "./lower-exprs.js";
2
+ import { InternalCompilerError } from "../../errors.js";
2
3
  import { dynUndefinedExpr, helperLoc, nodeThrowExpr, varRef } from "../../ir/build.js";
3
4
  import { constructedValue } from "./constructor-returns.js";
4
5
  import { eventTargetApiMembers, eventTargetInheritedMember } from "./lower-event-target.js";
5
- import { BOOL, DYN, F64, DYN_CLASS_PROPERTIES as PROPERTY_BAG, STRING, VOID, canConvertToDyn, canDynCheckTo, isClassOwnEnumerableFieldName, isDynTypedRefType, isUnitType, typeEquals, typeKey, } from "../../ir/ir.js";
6
+ import { DATE_PROTOTYPE_METHOD_NAMES, DATE_TIME_FIELD, dateInheritedMember, dateRootOf, programDeclaresDateClass, } from "./builtins/date-classes.js";
7
+ import { dateValueMethod } from "./builtins/dates.js";
8
+ import { BOOL, DATE_T, DYN, F64, DYN_CLASS_PROPERTIES as PROPERTY_BAG, STRING, VOID, canConvertToDyn, canDynCheckTo, isClassOwnEnumerableFieldName, isDynTypedRefType, isUnitType, typeEquals, typeKey, } from "../../ir/ir.js";
6
9
  import { streamTypedRefEligible } from "../../ir/analysis.js";
7
10
  import { everyStmtList, transformExpr, transformStmtList } from "../../ir/traverse.js";
8
11
  import { PoisonError } from "./lowerer.js";
@@ -22,9 +25,10 @@ import { isClassCallback } from "./class-callbacks.js";
22
25
  import { CaughtValueDispatch } from "./caught-value-dispatch.js";
23
26
  import { refreshDescriptorGuards } from "./class-descriptors.js";
24
27
  import { ClassConstructionDispatch } from "./class-construction.js";
25
- import { emitterRooted } from "./lower-event-emitter.js";
28
+ import { DispatchSites } from "./dispatch-sites.js";
29
+ import { emitterRooted, lowerDynamicEmitterEmit, lowerDynamicEmitterOn, } from "./lower-event-emitter.js";
26
30
  import { protocolArm, protocolFieldArm } from "./class-protocol-dispatch.js";
27
- import { STREAM_OPERATORS } from "./lower-stream.js";
31
+ import { STREAM_OPERATORS, operatorSignalOptions, reduceSignalSetup } from "./lower-stream.js";
28
32
  import { deletedPropertyNames, fixedFieldFamily } from "./js-class-fields.js";
29
33
  const STREAM_METHODS = new Set([
30
34
  "on",
@@ -50,6 +54,25 @@ const EMITTER_METHODS = new Set([
50
54
  "off",
51
55
  "removeListener",
52
56
  ]);
57
+ /** The rest of EventEmitter.prototype, answered through an untyped value
58
+ * on emitters that are not streams (streams keep their own surface). */
59
+ const EMITTER_INTROSPECTION_METHODS = new Set([
60
+ "listenerCount",
61
+ "eventNames",
62
+ "removeAllListeners",
63
+ "listeners",
64
+ "rawListeners",
65
+ "setMaxListeners",
66
+ "getMaxListeners",
67
+ ]);
68
+ /** True when the class is or extends one of the runtime stream classes. */
69
+ function streamRooted(info) {
70
+ for (let c = info; c; c = c.base) {
71
+ if (c.builtinStream !== undefined)
72
+ return true;
73
+ }
74
+ return false;
75
+ }
53
76
  const STREAM_BOOL_PROPERTIES = new Set([
54
77
  "readable",
55
78
  "readableEnded",
@@ -128,7 +151,7 @@ const KEY_CALLS = new Map([
128
151
  ["dyn.keyDeleteComputed", "value"],
129
152
  ["dyn.keySetComputed", "value"],
130
153
  ]);
131
- function toPrimitiveHint(expr) {
154
+ export function toPrimitiveHint(expr) {
132
155
  if (expr.kind === "toString")
133
156
  return expr.operand.type.kind === "dyn" ? "string" : null;
134
157
  if (expr.kind === "dynKeyGet")
@@ -176,6 +199,7 @@ function isPrimitive(value, loc) {
176
199
  }
177
200
  export function classInstanceOf(lowerer, value, info, loc, classValue) {
178
201
  const name = `%dyn.class.${classValue ? "valueInstanceof" : "instanceof"}:${info.def.name}`;
202
+ lowerer.shareHelper(name);
179
203
  const params = [
180
204
  { localId: "value", name: "value", type: DYN },
181
205
  ...(classValue ? [{ localId: "class", name: "class", type: classValue.type }] : []),
@@ -185,6 +209,32 @@ export function classInstanceOf(lowerer, value, info, loc, classValue) {
185
209
  const prototype = classPrototypeData(lowerer, info, loc, classValue ? varRef("class", classValue.type, loc) : undefined);
186
210
  const body = prototype
187
211
  ? [
212
+ // In a program that declares a class extending Date, a Date can
213
+ // meet a class test (`date instanceof Moment`): its prototype
214
+ // chain holds no class prototype.
215
+ ...(programDeclaresDateClass(lowerer)
216
+ ? [
217
+ {
218
+ kind: "if",
219
+ cond: {
220
+ kind: "libCall",
221
+ fn: "dyn.nativeDateHandleIs",
222
+ args: [varRef("value", DYN, loc)],
223
+ type: BOOL,
224
+ loc,
225
+ },
226
+ then: [
227
+ {
228
+ kind: "return",
229
+ value: { kind: "boolLit", value: false, type: BOOL, loc },
230
+ loc,
231
+ },
232
+ ],
233
+ else_: null,
234
+ loc,
235
+ },
236
+ ]
237
+ : []),
188
238
  { kind: "varDecl", localId: "candidate", init: varRef("value", DYN, loc), loc },
189
239
  {
190
240
  kind: "while",
@@ -202,7 +252,7 @@ export function classInstanceOf(lowerer, value, info, loc, classValue) {
202
252
  localId: "candidate",
203
253
  value: {
204
254
  kind: "libCall",
205
- fn: "dyn.getPrototype",
255
+ fn: "dyn.getPrototypeForIdentity",
206
256
  args: [candidate],
207
257
  type: DYN,
208
258
  loc,
@@ -245,6 +295,37 @@ export function classInstanceOf(lowerer, value, info, loc, classValue) {
245
295
  loc,
246
296
  };
247
297
  }
298
+ /** `value` is the parameter itself, possibly through js.fromDyn. */
299
+ function returnsParam(value, param) {
300
+ if (value.kind === "varRef")
301
+ return value.localId === param;
302
+ return (value.kind === "libCall" &&
303
+ value.fn === "js.fromDyn" &&
304
+ value.args.length === 1 &&
305
+ value.args[0].kind === "varRef" &&
306
+ value.args[0].localId === param);
307
+ }
308
+ /** The kind a class-table branch requires of `param`: a capsule-key test
309
+ * (alone or guarding a conjunction) needs a capsule, a class-key test a
310
+ * function value; null for any other condition. */
311
+ function branchKind(cond, param) {
312
+ if (cond.kind === "libCall" &&
313
+ (cond.fn === "dyn.typedRefIs" ||
314
+ cond.fn === "dyn.typedRefKeyIs" ||
315
+ cond.fn === "dyn.classIs") &&
316
+ cond.args[0]?.kind === "varRef" &&
317
+ cond.args[0].localId === param) {
318
+ if (cond.fn === "dyn.classIs")
319
+ return "funcKind";
320
+ const key = cond.args[1];
321
+ return key?.kind === "strLit" && key.value.startsWith("object:") ? "classCapsule" : null;
322
+ }
323
+ if (cond.kind === "ternary" && cond.else_.kind === "boolLit" && cond.else_.value === false)
324
+ return branchKind(cond.cond, param);
325
+ if (cond.kind === "logical" && cond.op === "&&")
326
+ return branchKind(cond.left, param);
327
+ return null;
328
+ }
248
329
  const READ_PROPERTIES = "%dyn.class.readProperties";
249
330
  const READ_PROPERTIES_OR_EMPTY = "%dyn.class.readPropertiesOrEmpty";
250
331
  function isEmptyBag(value) {
@@ -273,9 +354,106 @@ function readOnlyBagBody(body, orEmpty = false) {
273
354
  }
274
355
  return body;
275
356
  }
357
+ /** `value` with the class branch's checked receiver (`p.0` as a dynamic
358
+ * value, possibly cast to the branch's class) replaced by `receiver`, the
359
+ * typed receiver of a per-class helper. */
360
+ function withTypedReceiver(value, receiver) {
361
+ const checked = (e) => e.kind === "dynCheck" && e.value.kind === "varRef" && e.value.localId === "p.0";
362
+ return transformExpr(value, {
363
+ stmt: (stmt) => stmt,
364
+ expr: (expr) => (expr.kind === "downcast" &&
365
+ checked(expr.value) &&
366
+ expr.type.kind === "object" &&
367
+ receiver.type.kind === "object" &&
368
+ expr.type.className === receiver.type.className) ||
369
+ checked(expr)
370
+ ? receiver
371
+ : expr,
372
+ });
373
+ }
374
+ /** Re-adds the classes of `set` after the first `from` in a fixed order:
375
+ * the program's classes by name, then the classes the runtime implements by
376
+ * name. The dispatch helpers add each class's branch in front of the
377
+ * earlier ones, so a runtime class's branch, which answers its methods for
378
+ * instances of the program's subclasses too, is tested before the
379
+ * subclasses' own branches. */
380
+ function sortAdded(lowerer, set, from) {
381
+ const runtime = (name) => {
382
+ const info = lowerer.classes.get(name);
383
+ return !!(info &&
384
+ (info.def.runtime || info.builtinEmitter || info.builtinStream || info.builtinError));
385
+ };
386
+ const added = [...set]
387
+ .slice(from)
388
+ .sort((left, right) => Number(runtime(left)) - Number(runtime(right)) ||
389
+ (left < right ? -1 : left > right ? 1 : 0));
390
+ for (const name of added)
391
+ set.delete(name);
392
+ for (const name of added)
393
+ set.add(name);
394
+ }
395
+ function receiverIndex(lowerer, plans) {
396
+ const methods = new Map();
397
+ const members = new Map();
398
+ const rooted = [];
399
+ const add = (table, name, position) => {
400
+ const positions = table.get(name);
401
+ if (positions === undefined)
402
+ table.set(name, [position]);
403
+ else if (positions[positions.length - 1] !== position)
404
+ positions.push(position);
405
+ };
406
+ plans.forEach(({ info }, position) => {
407
+ if (emitterRooted(lowerer, info) ||
408
+ info.builtinStream !== undefined ||
409
+ eventTargetApiMembers(info) !== null ||
410
+ dateRootOf(info) !== null) {
411
+ rooted.push(position);
412
+ return;
413
+ }
414
+ for (let c = info; c; c = c.base) {
415
+ for (const name of c.methods.keys()) {
416
+ add(methods, name, position);
417
+ // A `get:`/`set:` key is an accessor of the property after the
418
+ // prefix, or a method whose quoted name has that prefix; the test
419
+ // looks up both.
420
+ add(members, name, position);
421
+ if (name.startsWith("get:") || name.startsWith("set:"))
422
+ add(members, name.slice(4), position);
423
+ }
424
+ if (c.genericMethods)
425
+ for (const name of c.genericMethods.keys()) {
426
+ add(methods, name, position);
427
+ add(members, name, position);
428
+ }
429
+ }
430
+ for (const name of info.fields.keys())
431
+ add(members, name, position);
432
+ });
433
+ for (const table of [methods, members])
434
+ for (const positions of table.values())
435
+ positions.sort((a, b) => a - b);
436
+ return { plans, methods, members, rooted };
437
+ }
438
+ /** The ascending union of two ascending position lists. */
439
+ function mergePositions(left, right) {
440
+ const out = [];
441
+ let i = 0;
442
+ let j = 0;
443
+ while (i < left.length || j < right.length) {
444
+ const next = j >= right.length || (i < left.length && left[i] <= right[j]) ? left[i++] : right[j++];
445
+ if (out[out.length - 1] !== next)
446
+ out.push(next);
447
+ }
448
+ return out;
449
+ }
450
+ /** SCRIPTC_CHECK_DISPATCH_CANDIDATES=1 checks every indexed receiver selection
451
+ * against a test of every receiver. */
452
+ const CHECK_CANDIDATES = process.env["SCRIPTC_CHECK_DISPATCH_CANDIDATES"] === "1";
276
453
  export function classPropertiesHelper(lowerer, loc, readOnly = false) {
277
454
  const name = readOnly ? READ_PROPERTIES : "%dyn.class.properties";
278
- const existing = lowerer.liftedFns.find((fn) => fn.name === name);
455
+ lowerer.shareHelper(name);
456
+ const existing = lowerer.liftedFnNamed(name);
279
457
  if (existing)
280
458
  return existing;
281
459
  const helper = {
@@ -309,6 +487,8 @@ export function classPropertiesHelper(lowerer, loc, readOnly = false) {
309
487
  * than that table, so a miss rechecks the instance itself. */
310
488
  export function classForInHasKey(lowerer, value, key, loc) {
311
489
  const name = "%dyn.class.forInHasKey";
490
+ lowerer.shareHelper(name);
491
+ lowerer.shareHelper("%dyn.class.forInBagHas");
312
492
  if (!lowerer.liftedFns.some((fn) => fn.name === name)) {
313
493
  // The read-only table: a recheck never creates an instance's table, which
314
494
  // is undefined while the instance has no own dynamic properties.
@@ -408,15 +588,151 @@ export function trackClassFieldCreation(lowerer, functions) {
408
588
  return;
409
589
  const loc = functions[0].loc;
410
590
  const name = "%dyn.class.fieldCreated";
411
- const value = varRef("value", DYN, loc), key = varRef("key", DYN, loc);
412
- const bag = varRef("bag", DYN, loc);
413
- const created = (receiver, className, field, loc) => ({
591
+ const key = varRef("key", DYN, loc);
592
+ // One helper per class: the instance's bag is its own hidden field, so a
593
+ // creation reads it directly instead of boxing the instance and testing
594
+ // it against every class's capsule (%dyn.class.properties), which runs
595
+ // only to create the bag, once per instance.
596
+ const perClass = new Map();
597
+ const helperFor = (className) => {
598
+ const known = perClass.get(className);
599
+ if (known !== undefined)
600
+ return known;
601
+ const helperName = `${name}:${className}`;
602
+ perClass.set(className, helperName);
603
+ const self = varRef("this", { kind: "object", className }, loc);
604
+ const bagRef = varRef("bag", DYN, loc);
605
+ functions.push({
606
+ name: helperName,
607
+ params: [
608
+ { localId: "this", name: "this", type: { kind: "object", className } },
609
+ { localId: "key", name: "key", type: DYN },
610
+ ],
611
+ returnType: VOID,
612
+ locals: [
613
+ { id: "this", name: "this", type: { kind: "object", className }, mutable: false },
614
+ { id: "key", name: "key", type: DYN, mutable: false },
615
+ { id: "bag", name: "bag", type: DYN, mutable: true },
616
+ ],
617
+ body: [
618
+ {
619
+ kind: "varDecl",
620
+ localId: "bag",
621
+ init: { kind: "fieldGet", obj: self, className, field: PROPERTY_BAG, type: DYN, loc },
622
+ loc,
623
+ },
624
+ {
625
+ kind: "if",
626
+ cond: { kind: "dynTest", test: "undefined", value: bagRef, type: BOOL, loc },
627
+ then: initializeBag(lowerer, className, self, loc),
628
+ else_: null,
629
+ loc,
630
+ },
631
+ ...defineIfAbsent(lowerer, bagRef, key, loc),
632
+ ],
633
+ loc,
634
+ });
635
+ return helperName;
636
+ };
637
+ // String-keyed fields take the runtime's direct insert for an ordinary
638
+ // bag; the general path stays for any other bag and for symbol keys.
639
+ const stringHelperFor = (className) => {
640
+ const known = perClass.get(`str:${className}`);
641
+ if (known !== undefined)
642
+ return known;
643
+ const general = helperFor(className);
644
+ const helperName = `${name}.string:${className}`;
645
+ perClass.set(`str:${className}`, helperName);
646
+ const type = { kind: "object", className };
647
+ const self = varRef("this", type, loc);
648
+ const bagRef = varRef("bag", DYN, loc);
649
+ const field = varRef("field", STRING, loc);
650
+ functions.push({
651
+ name: helperName,
652
+ params: [
653
+ { localId: "this", name: "this", type },
654
+ { localId: "field", name: "field", type: STRING },
655
+ ],
656
+ returnType: VOID,
657
+ locals: [
658
+ { id: "this", name: "this", type, mutable: false },
659
+ { id: "field", name: "field", type: STRING, mutable: false },
660
+ { id: "bag", name: "bag", type: DYN, mutable: true },
661
+ ],
662
+ body: [
663
+ {
664
+ kind: "varDecl",
665
+ localId: "bag",
666
+ init: { kind: "fieldGet", obj: self, className, field: PROPERTY_BAG, type: DYN, loc },
667
+ loc,
668
+ },
669
+ {
670
+ kind: "if",
671
+ cond: { kind: "dynTest", test: "undefined", value: bagRef, type: BOOL, loc },
672
+ then: initializeBag(lowerer, className, self, loc),
673
+ else_: null,
674
+ loc,
675
+ },
676
+ {
677
+ kind: "if",
678
+ cond: {
679
+ kind: "libCall",
680
+ fn: "dyn.bagCreateField",
681
+ args: [bagRef, field],
682
+ type: BOOL,
683
+ loc,
684
+ },
685
+ then: [{ kind: "return", value: null, loc }],
686
+ else_: null,
687
+ loc,
688
+ },
689
+ {
690
+ kind: "exprStmt",
691
+ expr: {
692
+ kind: "call",
693
+ callee: general,
694
+ args: [self, lowerer.coerceToExpected(field, DYN)],
695
+ type: VOID,
696
+ loc,
697
+ },
698
+ loc,
699
+ },
700
+ ],
701
+ loc,
702
+ });
703
+ return helperName;
704
+ };
705
+ const created = (receiver, className, field, loc) => {
706
+ const symbolKey = symbolMemberKey(lowerer, lowerer.classes.get(className), field, loc);
707
+ if (symbolKey === null) {
708
+ return {
709
+ kind: "exprStmt",
710
+ expr: {
711
+ kind: "call",
712
+ callee: stringHelperFor(className),
713
+ args: [
714
+ receiver.type.kind === "object" && receiver.type.className !== className
715
+ ? { kind: "upcast", value: receiver, type: { kind: "object", className }, loc }
716
+ : receiver,
717
+ { kind: "strLit", value: field, type: STRING, loc },
718
+ ],
719
+ type: VOID,
720
+ loc,
721
+ },
722
+ loc,
723
+ };
724
+ }
725
+ return createdGeneral(receiver, className, field, loc);
726
+ };
727
+ const createdGeneral = (receiver, className, field, loc) => ({
414
728
  kind: "exprStmt",
415
729
  expr: {
416
730
  kind: "call",
417
- callee: name,
731
+ callee: helperFor(className),
418
732
  args: [
419
- lowerer.coerceToExpected(receiver, DYN),
733
+ receiver.type.kind === "object" && receiver.type.className !== className
734
+ ? { kind: "upcast", value: receiver, type: { kind: "object", className }, loc }
735
+ : receiver,
420
736
  symbolMemberKey(lowerer, lowerer.classes.get(className), field, loc) ??
421
737
  lowerer.coerceToExpected({ kind: "strLit", value: field, type: STRING, loc }, DYN),
422
738
  ],
@@ -484,77 +800,101 @@ export function trackClassFieldCreation(lowerer, functions) {
484
800
  },
485
801
  });
486
802
  }
487
- functions.push({
488
- name,
489
- params: [
490
- { localId: "value", name: "value", type: DYN },
491
- { localId: "key", name: "key", type: DYN },
492
- ],
493
- returnType: VOID,
494
- locals: [
495
- { id: "value", name: "value", type: DYN, mutable: false },
496
- { id: "key", name: "key", type: DYN, mutable: false },
497
- { id: "bag", name: "bag", type: DYN, mutable: false },
498
- ],
499
- body: [
803
+ }
804
+ /** `bag = <the class's new bag>`, stored in the instance's hidden field:
805
+ * the class's own initializer when recorded, else the class-table
806
+ * dispatch, which creates it. */
807
+ function initializeBag(lowerer, className, self, loc) {
808
+ const init = lowerer.classBagInitializers?.get(className);
809
+ if (init === undefined) {
810
+ return [
500
811
  {
501
- kind: "varDecl",
812
+ kind: "assign",
502
813
  localId: "bag",
503
- init: {
814
+ value: {
504
815
  kind: "call",
505
816
  callee: classPropertiesHelper(lowerer, loc).name,
506
- args: [value],
817
+ args: [lowerer.coerceToExpected(self, DYN)],
507
818
  type: DYN,
508
819
  loc,
509
820
  },
510
821
  loc,
511
822
  },
512
- {
513
- kind: "if",
514
- cond: {
515
- kind: "unary",
516
- op: "!",
517
- operand: { kind: "libCall", fn: "dyn.hasOwnComputed", args: [bag, key], type: BOOL, loc },
518
- type: BOOL,
519
- loc,
520
- },
521
- then: [
522
- {
523
- kind: "exprStmt",
524
- expr: {
525
- kind: "libCall",
526
- fn: "dyn.defineProperty",
527
- args: [
528
- bag,
529
- lowerer.coerceToExpected(key, DYN),
530
- {
531
- kind: "dynObjLit",
532
- fields: [
533
- {
534
- key: { kind: "strLit", value: "value", type: STRING, loc },
535
- value: dynUndefinedExpr(loc),
536
- },
537
- ...["writable", "enumerable", "configurable"].map((key) => ({
538
- key: { kind: "strLit", value: key, type: STRING, loc },
539
- value: lowerer.coerceToExpected({ kind: "boolLit", value: true, type: BOOL, loc }, DYN),
540
- })),
541
- ],
542
- type: DYN,
543
- loc,
544
- },
545
- ],
546
- type: DYN,
547
- loc,
548
- },
549
- loc,
550
- },
551
- ],
552
- else_: null,
823
+ ];
824
+ }
825
+ return [
826
+ {
827
+ kind: "fieldSet",
828
+ obj: self,
829
+ className,
830
+ field: PROPERTY_BAG,
831
+ value: structuredClone(init),
832
+ loc,
833
+ },
834
+ {
835
+ kind: "assign",
836
+ localId: "bag",
837
+ value: { kind: "fieldGet", obj: self, className, field: PROPERTY_BAG, type: DYN, loc },
838
+ loc,
839
+ },
840
+ ];
841
+ }
842
+ /** `value` as JSON without its source locations. */
843
+ function withoutLocations(value) {
844
+ return JSON.stringify(value, (key, field) => (key === "loc" ? undefined : field));
845
+ }
846
+ /** Whether `value` reads local `id`. */
847
+ function mentionsLocal(value, id) {
848
+ return JSON.stringify(value).includes(`"localId":${JSON.stringify(id)}`);
849
+ }
850
+ /** `if (!hasOwn(bag, key)) defineProperty(bag, key, <undefined data field>)`:
851
+ * a field's creation in its instance's property bag. */
852
+ function defineIfAbsent(lowerer, bag, key, loc) {
853
+ return [
854
+ {
855
+ kind: "if",
856
+ cond: {
857
+ kind: "unary",
858
+ op: "!",
859
+ operand: { kind: "libCall", fn: "dyn.hasOwnComputed", args: [bag, key], type: BOOL, loc },
860
+ type: BOOL,
553
861
  loc,
554
862
  },
555
- ],
556
- loc,
557
- });
863
+ then: [
864
+ {
865
+ kind: "exprStmt",
866
+ expr: {
867
+ kind: "libCall",
868
+ fn: "dyn.defineProperty",
869
+ args: [
870
+ bag,
871
+ lowerer.coerceToExpected(key, DYN),
872
+ {
873
+ kind: "dynObjLit",
874
+ fields: [
875
+ {
876
+ key: { kind: "strLit", value: "value", type: STRING, loc },
877
+ value: dynUndefinedExpr(loc),
878
+ },
879
+ ...["writable", "enumerable", "configurable"].map((key) => ({
880
+ key: { kind: "strLit", value: key, type: STRING, loc },
881
+ value: lowerer.coerceToExpected({ kind: "boolLit", value: true, type: BOOL, loc }, DYN),
882
+ })),
883
+ ],
884
+ type: DYN,
885
+ loc,
886
+ },
887
+ ],
888
+ type: DYN,
889
+ loc,
890
+ },
891
+ loc,
892
+ },
893
+ ],
894
+ else_: null,
895
+ loc,
896
+ },
897
+ ];
558
898
  }
559
899
  /** Calls on native class capsules keep the instance's compiled methods. The
560
900
  * reachable-body fixed point discovers both the boxed classes and method
@@ -568,11 +908,16 @@ export class ClassDynamicDispatch {
568
908
  generatorDispatch = new GeneratorDynamicDispatch();
569
909
  caughtDispatch = new CaughtValueDispatch();
570
910
  constructionDispatch = new ClassConstructionDispatch();
911
+ /** What each function's body holds for this pass and its sub-passes. */
912
+ sites = new DispatchSites();
571
913
  /** Property names a delete can remove (null: any name), for the field
572
914
  * creation tracking decision. */
573
915
  deletedNames;
574
916
  boxed = new Set();
575
917
  boxedConstructors = new Set();
918
+ /** Every class a boxed value was statically typed as, runtime error
919
+ * classes included: the value's capsule can be any of its subclasses. */
920
+ boxedStatic = new Set();
576
921
  dispatches = new Map();
577
922
  properties = new Map();
578
923
  computed = new Map();
@@ -589,6 +934,9 @@ export class ClassDynamicDispatch {
589
934
  /** Per-class prototype selection for new property bags (bagPrototypeHelper). */
590
935
  bagPrototypeHelpers = new Map();
591
936
  readPropertyBags = [];
937
+ /** Read-only bags of exactly one class (exactPropertyBag), by class and
938
+ * whether an absent bag reads as a fresh empty object. */
939
+ exactPropertyBags = new Map();
592
940
  generated = new Set();
593
941
  /** Protocol dispatch helpers and callee reads whose receivers normalize. */
594
942
  protocols = [];
@@ -601,8 +949,17 @@ export class ClassDynamicDispatch {
601
949
  descriptorHelper = null;
602
950
  prototypeHelper = null;
603
951
  prototypeClasses = new Set();
604
- prototypeIdentityHelper = null;
605
- prototypeIdentityClasses = new Set();
952
+ /** The stand-in prototype object of each class without prototype data
953
+ * (prototypeStandIn), by class name. */
954
+ prototypeStandIns = new Set();
955
+ /** The prototype reads of identity walks, by libCall, and the classes
956
+ * each one answers for boxed instances. */
957
+ prototypeIdentityHelpers = new Map();
958
+ /** `value instanceof Error` through Error.prototype: boxed instances of
959
+ * classes with a heritage evaluated at run time test their prototype
960
+ * data's chain. */
961
+ errorPrototypeHelper = null;
962
+ errorPrototypeClasses = new Set();
606
963
  instancePrototypes = new Map();
607
964
  checkedCasts = new Map();
608
965
  /** The for-in key helpers, by libCall (dyn and native string[] keys). */
@@ -625,22 +982,25 @@ export class ClassDynamicDispatch {
625
982
  first.value.callee === this.normalization?.name)
626
983
  fn.body.shift();
627
984
  }
628
- let changed = this.caughtDispatch.process(lowerer, functions);
985
+ let changed = this.caughtDispatch.process(lowerer, functions, this.sites);
629
986
  changed = refreshErrorMethodDispatch(lowerer, functions) || changed;
630
987
  changed = refreshClassMethodValueSelections(lowerer) || changed;
631
988
  changed = refreshErrorPropertyDispatch(lowerer, functions) || changed;
632
- changed = this.generatorDispatch.process(lowerer, functions, this.generated) || changed;
633
- changed = this.constructionDispatch.process(lowerer, functions) || changed;
989
+ changed =
990
+ this.generatorDispatch.process(lowerer, functions, this.generated, this.sites) || changed;
991
+ changed = this.constructionDispatch.process(lowerer, functions, this.sites) || changed;
634
992
  const seenTypes = new Set();
635
993
  const rewrite = new Set();
636
994
  const toPrimitiveSites = new Set();
637
995
  const hasKeySites = new Set();
996
+ const caughtSites = new Set();
638
997
  const discover = (type) => {
639
998
  const key = typeKey(type);
640
999
  if (seenTypes.has(key))
641
1000
  return;
642
1001
  seenTypes.add(key);
643
1002
  if (type.kind === "object") {
1003
+ this.boxedStatic.add(type.className);
644
1004
  if (isDynTypedRefType(type))
645
1005
  this.boxed.add(type.className);
646
1006
  }
@@ -661,83 +1021,30 @@ export class ClassDynamicDispatch {
661
1021
  else if (type.kind === "promise")
662
1022
  discover(type.inner);
663
1023
  };
664
- for (const fn of functions)
665
- everyStmtList(fn.body, {
666
- stmt: (statement) => {
667
- // Field-creation instrumentation can box a base-constructor receiver
668
- // even when only its derived instances otherwise cross the boundary.
669
- if (statement.kind === "fieldSet" &&
670
- lowerer.classes.get(statement.className)?.def.tracksOwnFields &&
671
- isClassOwnEnumerableFieldName(statement.field))
672
- discover(statement.obj.type);
673
- return true;
674
- },
675
- expr: (expr) => {
676
- if (expr.kind === "jsonStringify" ||
677
- (expr.kind === "libCall" &&
678
- (expr.fn === "json.stringifyValue" || expr.fn === "json.stringifyReplacer"))) {
679
- this.serializesClasses = true;
680
- }
681
- if (toPrimitiveHint(expr) !== null ||
682
- (expr.kind === "libCall" && (expr.fn === "dyn.valueOf" || expr.fn === "dyn.toString")))
683
- toPrimitiveSites.add(fn);
684
- switch (expr.kind) {
685
- case "dynFrom":
686
- discover(expr.value.type);
687
- break;
688
- case "fieldIncDec":
689
- if (lowerer.classes.get(expr.className)?.def.tracksOwnFields &&
690
- isClassOwnEnumerableFieldName(expr.field))
691
- discover(expr.obj.type);
692
- break;
693
- case "call":
694
- if ((expr.callee === "%dyn.class.properties" ||
695
- expr.callee === "%dyn.class.readProperties") &&
696
- expr.args[0]?.kind === "dynFrom" &&
697
- isDynTypedRefType(expr.args[0].value.type))
698
- rewrite.add(fn);
699
- break;
700
- case "dynHasKey":
701
- hasKeySites.add(fn);
702
- break;
703
- case "dynKeyGet":
704
- case "dynInvoke":
705
- rewrite.add(fn);
706
- break;
707
- case "dynCheck":
708
- if (isDynTypedRefType(expr.type))
709
- rewrite.add(fn);
710
- // A dynamic function checked into a native function type
711
- // receives its arguments as dynamic values: class instances
712
- // passed to it cross the boundary when it is called (a JS
713
- // `list.map((rec) => rec.match(x))` callback with an untyped
714
- // parameter).
715
- if (expr.type.kind === "func")
716
- expr.type.params.forEach(discover);
717
- break;
718
- case "libCall":
719
- if (expr.fn === "bytes.construct" ||
720
- expr.fn === "dyn.keySet" ||
721
- expr.fn === "dyn.keySetComputed" ||
722
- expr.fn === "dyn.iterator" ||
723
- expr.fn === "dyn.arrayFromIterator" ||
724
- expr.fn === "dyn.toString" ||
725
- expr.fn === "dyn.stringConstructor" ||
726
- expr.fn === "dyn.forInKeys" ||
727
- expr.fn === "dyn.forInKeyStrings" ||
728
- expr.fn === "dyn.hasKeyComputed" ||
729
- expr.fn === "dyn.hasOwnComputed" ||
730
- expr.fn === "dyn.propertyIsEnumerableComputed" ||
731
- expr.fn === "dyn.defineProperty" ||
732
- expr.fn === "dyn.getPrototype" ||
733
- expr.fn === "dyn.reflectGet" ||
734
- expr.fn === "dyn.reflectSet")
735
- rewrite.add(fn);
736
- break;
737
- }
738
- return true;
739
- },
740
- });
1024
+ const boxedBefore = this.boxed.size;
1025
+ const boxedConstructorsBefore = this.boxedConstructors.size;
1026
+ for (const fn of functions) {
1027
+ const found = this.sites.of(fn);
1028
+ // A class starts tracking its own fields during this pass.
1029
+ for (const { type, fieldClass } of found.boxing)
1030
+ if (fieldClass === undefined || lowerer.classes.get(fieldClass)?.def.tracksOwnFields)
1031
+ discover(type);
1032
+ if (found.serializes)
1033
+ this.serializesClasses = true;
1034
+ if (found.conversions)
1035
+ toPrimitiveSites.add(fn);
1036
+ if (found.dispatches)
1037
+ rewrite.add(fn);
1038
+ if (found.keyTests)
1039
+ hasKeySites.add(fn);
1040
+ if (found.caughtClassTests)
1041
+ caughtSites.add(fn);
1042
+ }
1043
+ // The classes this pass found join the tables in a fixed order, not in
1044
+ // the order the scan met them.
1045
+ sortAdded(lowerer, this.boxed, boxedBefore);
1046
+ sortAdded(lowerer, this.boxedConstructors, boxedConstructorsBefore);
1047
+ changed = this.caughtDispatch.dynamicPayloads(lowerer, caughtSites, this.boxed) || changed;
741
1048
  if (this.boxed.size === 0 && rewrite.size === 0)
742
1049
  return changed;
743
1050
  const converting = this.convertingHints(lowerer);
@@ -844,9 +1151,11 @@ export class ClassDynamicDispatch {
844
1151
  });
845
1152
  changed = true;
846
1153
  }
847
- if (this.prototypeIdentityHelper && !this.prototypeIdentityClasses.has(className)) {
848
- this.prototypeIdentityClasses.add(className);
849
- const loc = this.prototypeIdentityHelper.loc;
1154
+ if (this.errorPrototypeHelper &&
1155
+ !this.errorPrototypeClasses.has(className) &&
1156
+ hasRuntimeHeritage(info)) {
1157
+ this.errorPrototypeClasses.add(className);
1158
+ const loc = this.errorPrototypeHelper.loc;
850
1159
  const type = { kind: "object", className };
851
1160
  const value = varRef("value", DYN, loc);
852
1161
  const prototype = classPrototypeData(lowerer, info, loc, {
@@ -856,7 +1165,7 @@ export class ClassDynamicDispatch {
856
1165
  loc,
857
1166
  });
858
1167
  if (prototype)
859
- this.prototypeIdentityHelper.body.unshift({
1168
+ this.errorPrototypeHelper.body.unshift({
860
1169
  kind: "if",
861
1170
  cond: {
862
1171
  kind: "libCall",
@@ -865,7 +1174,19 @@ export class ClassDynamicDispatch {
865
1174
  type: BOOL,
866
1175
  loc,
867
1176
  },
868
- then: [{ kind: "return", value: prototype, loc }],
1177
+ then: [
1178
+ {
1179
+ kind: "return",
1180
+ value: {
1181
+ kind: "libCall",
1182
+ fn: "dyn.inheritsErrorPrototype",
1183
+ args: [prototype],
1184
+ type: BOOL,
1185
+ loc,
1186
+ },
1187
+ loc,
1188
+ },
1189
+ ],
869
1190
  else_: null,
870
1191
  loc,
871
1192
  });
@@ -879,7 +1200,7 @@ export class ClassDynamicDispatch {
879
1200
  const loc = this.propertyBag.loc;
880
1201
  const method = classMethodValue(lowerer, info.decl, info, "toJSON", loc);
881
1202
  const prototype = method ? classPrototypeData(lowerer, info, loc) : null;
882
- const helper = lowerer.liftedFns.find((fn) => fn.name === info.def.prototypeDataHelper);
1203
+ const helper = lowerer.liftedFnNamed(info.def.prototypeDataHelper);
883
1204
  const init = helper?.body[0];
884
1205
  if (!info.prototypeReflectionReady &&
885
1206
  method &&
@@ -930,6 +1251,101 @@ export class ClassDynamicDispatch {
930
1251
  }
931
1252
  }
932
1253
  }
1254
+ // The runtime boxes a class instance as its exact class, so a value
1255
+ // boxed at a base (or Error) static type reaches the identity views as
1256
+ // any subclass's capsule.
1257
+ for (const helper of this.prototypeIdentityHelpers.values())
1258
+ for (const [className, info] of lowerer.classes) {
1259
+ if (helper.classes.has(className))
1260
+ continue;
1261
+ if (info.builtinEmitter || info.builtinStream || info.builtinError)
1262
+ continue;
1263
+ if (!isDynTypedRefType({ kind: "object", className }))
1264
+ continue;
1265
+ if (!this.boxed.has(className) &&
1266
+ ![...this.boxedStatic].some((base) => lowerer.isSubclassOf(className, base)))
1267
+ continue;
1268
+ helper.classes.add(className);
1269
+ const loc = helper.fn.loc;
1270
+ const type = { kind: "object", className };
1271
+ const value = varRef("value", DYN, loc);
1272
+ // A class with no prototype data in its chain (one extending
1273
+ // Error, or with no methods) has no prototype a program can name:
1274
+ // an object of the class's own stands in, so instances of one class
1275
+ // share it (`Object.getPrototypeOf(a) === Object.getPrototypeOf(b)`),
1276
+ // other prototypes differ from it, and an instanceof walk (through
1277
+ // Object.prototype to null) answers false instead of reaching the
1278
+ // reflection refusal. A function-local class is a new class at
1279
+ // each evaluation of its declaration, so its instances answer with
1280
+ // the prototype of their own class value instead.
1281
+ const answer = (name) => {
1282
+ const of = lowerer.classes.get(name);
1283
+ const prototype = hasClassPrototypeData(of) || of.localClass
1284
+ ? classPrototypeData(lowerer, of, loc, {
1285
+ kind: "dynCheck",
1286
+ value,
1287
+ type: { kind: "object", className: name },
1288
+ loc,
1289
+ })
1290
+ : null;
1291
+ if (prototype)
1292
+ return [{ kind: "return", value: prototype, loc }];
1293
+ return hasClassPrototypeData(of) ? null : this.prototypeStandIn(lowerer, name, loc);
1294
+ };
1295
+ const own = answer(className);
1296
+ if (!own) {
1297
+ changed = true;
1298
+ continue;
1299
+ }
1300
+ // A capsule boxed at this class can hold a subclass instance: the
1301
+ // most derived subclass the instance belongs to answers.
1302
+ const depth = (name) => {
1303
+ let n = 0;
1304
+ for (let at = lowerer.classes.get(name)?.base; at; at = at.base)
1305
+ n++;
1306
+ return n;
1307
+ };
1308
+ const subclasses = [...lowerer.classes.keys()]
1309
+ .filter((name) => name !== className &&
1310
+ lowerer.isSubclassOf(name, className) &&
1311
+ isDynTypedRefType({ kind: "object", className: name }))
1312
+ .sort((a, b) => depth(b) - depth(a));
1313
+ const then = [];
1314
+ for (const name of subclasses) {
1315
+ const sub = answer(name);
1316
+ if (!sub)
1317
+ continue;
1318
+ then.push({
1319
+ kind: "if",
1320
+ cond: {
1321
+ kind: "instanceOf",
1322
+ value: { kind: "dynCheck", value, type, loc },
1323
+ className: name,
1324
+ type: BOOL,
1325
+ loc,
1326
+ },
1327
+ then: sub,
1328
+ else_: null,
1329
+ loc,
1330
+ });
1331
+ }
1332
+ then.push(...own);
1333
+ helper.fn.body.unshift({
1334
+ kind: "if",
1335
+ cond: {
1336
+ kind: "libCall",
1337
+ fn: "dyn.typedRefIs",
1338
+ args: [value, { kind: "strLit", value: typeKey(type), type: STRING, loc }],
1339
+ type: BOOL,
1340
+ loc,
1341
+ },
1342
+ then,
1343
+ else_: null,
1344
+ loc,
1345
+ });
1346
+ changed = true;
1347
+ }
1348
+ let live = null;
933
1349
  for (const plan of this.propertyReceivers(lowerer, false, false)) {
934
1350
  const info = plan.info;
935
1351
  const className = info.def.name;
@@ -999,7 +1415,11 @@ export class ClassDynamicDispatch {
999
1415
  const needsPrototype = (current) => hasClassPrototypeData(current) ||
1000
1416
  current.subclasses.some((child) => lowerer.classCanBeConstructed(child) && needsPrototype(child));
1001
1417
  const prototypeFor = (current, receiver, loc) => this.bagPrototype(lowerer, current, receiver, loc);
1002
- for (const existingInit of this.bagInitializers.get(className) ?? []) {
1418
+ live ??= this.liveBagInitializers();
1419
+ for (const existingInit of [
1420
+ ...(this.bagInitializers.get(className) ?? []),
1421
+ ...(live.get(className) ?? []),
1422
+ ]) {
1003
1423
  if (existingInit.value.kind === "dynObjLit" && needsPrototype(info)) {
1004
1424
  const prototype = prototypeFor(info, existingInit.obj, existingInit.loc);
1005
1425
  if (prototype) {
@@ -1010,6 +1430,14 @@ export class ClassDynamicDispatch {
1010
1430
  type: DYN,
1011
1431
  loc: existingInit.loc,
1012
1432
  };
1433
+ // The initializer is a statement of the property bag helpers;
1434
+ // their reused site summaries do not see an edit inside it.
1435
+ if (this.propertyBag)
1436
+ this.sites.forget(this.propertyBag);
1437
+ for (const fn of this.typedPropertyBags.values())
1438
+ this.sites.forget(fn);
1439
+ for (const fn of this.exactPropertyBags.values())
1440
+ this.sites.forget(fn);
1013
1441
  changed = true;
1014
1442
  }
1015
1443
  }
@@ -1079,15 +1507,36 @@ export class ClassDynamicDispatch {
1079
1507
  }
1080
1508
  refreshDescriptorGuards(lowerer);
1081
1509
  const byMethod = new Map();
1510
+ // A query asks every receiver about one name, and the program's dispatch
1511
+ // sites ask about thousands: index the receivers by name once per list.
1512
+ let index = null;
1513
+ const indexOf = (plans) => index?.plans === plans ? index : (index = receiverIndex(lowerer, plans));
1514
+ /** The receivers of `plans` that can answer `name`, in list order: those
1515
+ * `table` lists under it and the rooted ones. Emit-override
1516
+ * specializations (`emit:<event>`) join a class's methods while bodies
1517
+ * lower, so they keep every receiver. */
1518
+ const receiversFor = (plans, name, table) => {
1519
+ if (name.startsWith("emit:"))
1520
+ return plans;
1521
+ const found = indexOf(plans);
1522
+ const positions = (table === "methods" ? found.methods : found.members).get(name);
1523
+ return mergePositions(positions ?? [], found.rooted).map((position) => plans[position]);
1524
+ };
1082
1525
  const candidates = (method) => {
1083
1526
  const found = byMethod.get(method);
1084
1527
  if (found)
1085
1528
  return found;
1086
- const matching = this.propertyReceivers(lowerer, true).flatMap(({ info }) => {
1529
+ const plans = this.propertyReceivers(lowerer, true);
1530
+ const test = ({ info }) => {
1087
1531
  if (!info || info.fields.has(method) || info.builtinError)
1088
1532
  return [];
1089
1533
  if (emitterRooted(lowerer, info) && EMITTER_METHODS.has(method))
1090
1534
  return [info];
1535
+ if (emitterRooted(lowerer, info) &&
1536
+ !streamRooted(info) &&
1537
+ EMITTER_INTROSPECTION_METHODS.has(method) &&
1538
+ !findMethodOn(lowerer, info, method))
1539
+ return [info];
1091
1540
  if (info.builtinStream) {
1092
1541
  return STREAM_METHODS.has(method) ||
1093
1542
  (STREAM_OPERATORS.has(method) && info.builtinStream !== "w")
@@ -1097,10 +1546,25 @@ export class ClassDynamicDispatch {
1097
1546
  return findMethodOn(lowerer, info, method) || findGenericMethodOn(lowerer, info, method)
1098
1547
  ? [info]
1099
1548
  : [];
1100
- });
1549
+ };
1550
+ const matching = receiversFor(plans, method, "methods").flatMap(test);
1551
+ if (CHECK_CANDIDATES) {
1552
+ const every = plans.flatMap(test);
1553
+ if (every.length !== matching.length || every.some((info, i) => info !== matching[i]))
1554
+ throw new InternalCompilerError(`indexed candidates for ${method} differ`);
1555
+ }
1101
1556
  byMethod.set(method, matching);
1102
1557
  return matching;
1103
1558
  };
1559
+ const candidateSets = new Map();
1560
+ const candidateSet = (method) => {
1561
+ let set = candidateSets.get(method);
1562
+ if (!set) {
1563
+ set = new Set(candidates(method));
1564
+ candidateSets.set(method, set);
1565
+ }
1566
+ return set;
1567
+ };
1104
1568
  for (const fn of functions) {
1105
1569
  // Discovery already visits every expression. Preserve bodies without
1106
1570
  // dispatch sites instead of rebuilding their entire typed IR tree on
@@ -1219,29 +1683,65 @@ export class ClassDynamicDispatch {
1219
1683
  }
1220
1684
  return { kind: "call", callee: cast.fn.name, args: [expr.value], type, loc: expr.loc };
1221
1685
  }
1686
+ if (expr.kind === "libCall" && expr.fn === "dyn.inheritsErrorPrototype") {
1687
+ if (!this.errorPrototypeHelper) {
1688
+ const loc = expr.loc;
1689
+ this.errorPrototypeHelper = {
1690
+ name: "%dyn.class.inheritsErrorPrototype",
1691
+ params: [{ localId: "value", name: "value", type: DYN }],
1692
+ locals: [{ id: "value", name: "value", type: DYN, mutable: false }],
1693
+ returnType: BOOL,
1694
+ loc,
1695
+ body: [
1696
+ { kind: "return", value: { ...expr, args: [varRef("value", DYN, loc)] }, loc },
1697
+ ],
1698
+ };
1699
+ lowerer.liftedFns.push(this.errorPrototypeHelper);
1700
+ this.generated.add(this.errorPrototypeHelper);
1701
+ changed = true;
1702
+ }
1703
+ return {
1704
+ kind: "call",
1705
+ callee: this.errorPrototypeHelper.name,
1706
+ args: expr.args,
1707
+ type: BOOL,
1708
+ loc: expr.loc,
1709
+ };
1710
+ }
1222
1711
  if (expr.kind === "libCall" &&
1223
- expr.fn === "dyn.getPrototype" &&
1712
+ (expr.fn === "dyn.getPrototype" || expr.fn === "dyn.getPrototypeForIdentity") &&
1224
1713
  expr.args[0]?.kind !== "dynObjLit") {
1225
1714
  if (expr.prototypeIdentityOnly) {
1226
- if (!this.prototypeIdentityHelper) {
1715
+ let helper = this.prototypeIdentityHelpers.get(expr.fn);
1716
+ if (!helper) {
1227
1717
  const loc = expr.loc;
1228
- this.prototypeIdentityHelper = {
1229
- name: "%dyn.class.prototypeIdentity",
1230
- params: [{ localId: "value", name: "value", type: DYN }],
1231
- locals: [{ id: "value", name: "value", type: DYN, mutable: false }],
1232
- returnType: DYN,
1233
- loc,
1234
- body: [
1235
- { kind: "return", value: { ...expr, args: [varRef("value", DYN, loc)] }, loc },
1236
- ],
1718
+ helper = {
1719
+ fn: {
1720
+ name: expr.fn === "dyn.getPrototype"
1721
+ ? "%dyn.class.prototypeIdentity"
1722
+ : "%dyn.class.prototypeChainIdentity",
1723
+ params: [{ localId: "value", name: "value", type: DYN }],
1724
+ locals: [{ id: "value", name: "value", type: DYN, mutable: false }],
1725
+ returnType: DYN,
1726
+ loc,
1727
+ body: [
1728
+ {
1729
+ kind: "return",
1730
+ value: { ...expr, args: [varRef("value", DYN, loc)] },
1731
+ loc,
1732
+ },
1733
+ ],
1734
+ },
1735
+ classes: new Set(),
1237
1736
  };
1238
- lowerer.liftedFns.push(this.prototypeIdentityHelper);
1239
- this.generated.add(this.prototypeIdentityHelper);
1737
+ this.prototypeIdentityHelpers.set(expr.fn, helper);
1738
+ lowerer.liftedFns.push(helper.fn);
1739
+ this.generated.add(helper.fn);
1240
1740
  changed = true;
1241
1741
  }
1242
1742
  return {
1243
1743
  kind: "call",
1244
- callee: this.prototypeIdentityHelper.name,
1744
+ callee: helper.fn.name,
1245
1745
  args: expr.args,
1246
1746
  type: DYN,
1247
1747
  loc: expr.loc,
@@ -2013,7 +2513,28 @@ export class ClassDynamicDispatch {
2013
2513
  loc,
2014
2514
  });
2015
2515
  }
2016
- dispatch = { name, write: !!write, fn: helper, classes: new Set() };
2516
+ const receiverAccess = read
2517
+ ? [{ kind: "return", value: { ...read, value: varRef("p.0", DYN, loc) }, loc }]
2518
+ : [
2519
+ {
2520
+ kind: "exprStmt",
2521
+ expr: {
2522
+ ...write,
2523
+ args: [varRef("p.0", DYN, loc), write.args[1], varRef("p.1", DYN, loc)],
2524
+ },
2525
+ loc,
2526
+ },
2527
+ { kind: "return", value: null, loc },
2528
+ ];
2529
+ dispatch = {
2530
+ name,
2531
+ write: !!write,
2532
+ fn: helper,
2533
+ classes: new Set(),
2534
+ ...(name !== "constructor" && name !== "toString"
2535
+ ? { plain: { tail: [...helper.body], access: receiverAccess } }
2536
+ : {}),
2537
+ };
2017
2538
  this.properties.set(key, dispatch);
2018
2539
  this.generated.add(helper);
2019
2540
  lowerer.liftedFns.push(helper);
@@ -2044,14 +2565,14 @@ export class ClassDynamicDispatch {
2044
2565
  : expr.kind === "dynInvoke"
2045
2566
  ? expr
2046
2567
  : null;
2047
- const staticCandidates = invoke &&
2048
- [...this.boxedConstructors].some((name) => {
2049
- const info = lowerer.classes.get(name);
2050
- return info && findStaticOn(lowerer, info, invoke.method)?.method;
2051
- });
2568
+ // Static methods matter only for methods no instance answers.
2569
+ const staticCandidates = (method) => [...this.boxedConstructors].some((name) => {
2570
+ const info = lowerer.classes.get(name);
2571
+ return info && findStaticOn(lowerer, info, method)?.method;
2572
+ });
2052
2573
  if (!invoke ||
2053
2574
  (candidates(invoke.method).length === 0 &&
2054
- !staticCandidates &&
2575
+ !staticCandidates(invoke.method) &&
2055
2576
  !(invoke.method === "toString" && lowerer.classes.has("%Error"))))
2056
2577
  return expr;
2057
2578
  const key = JSON.stringify([
@@ -2316,17 +2837,41 @@ export class ClassDynamicDispatch {
2316
2837
  });
2317
2838
  changed = true;
2318
2839
  }
2319
- for (const plan of this.propertyReceivers(lowerer, true)) {
2840
+ // Compute the candidates where the first plan would have, so the
2841
+ // memoized set is the same whichever plans are already answered.
2842
+ const plans = this.propertyReceivers(lowerer, true);
2843
+ const matching = plans.length ? candidateSet(dispatch.source.method) : null;
2844
+ for (const plan of plans) {
2320
2845
  const { info } = plan;
2321
- if (!candidates(dispatch.source.method).includes(info) || dispatch.classes.has(plan.key))
2846
+ if (dispatch.classes.has(plan.key) || !matching.has(info))
2322
2847
  continue;
2323
2848
  dispatch.classes.add(plan.key);
2324
2849
  const loc = dispatch.source.loc;
2325
- const value = varRef("p.0", DYN, loc);
2326
2850
  const { receiver, condition } = this.propertyReceiver(plan, loc);
2327
2851
  if (isClassCallback(lowerer, info, dispatch.source.method)) {
2328
2852
  const prototypeMethod = observedPrototypeMethod(lowerer, info, dispatch.source.method, loc, receiver);
2329
- const bag = this.readPropertyBagOrEmpty(lowerer, value, loc);
2853
+ const bag = this.branchPropertyBag(lowerer, info, receiver, true, loc);
2854
+ const methodKey = {
2855
+ kind: "strLit",
2856
+ value: dispatch.source.method,
2857
+ type: STRING,
2858
+ loc,
2859
+ };
2860
+ const bagHas = {
2861
+ kind: "libCall",
2862
+ fn: "dyn.hasKey",
2863
+ args: [bag, methodKey],
2864
+ type: BOOL,
2865
+ loc,
2866
+ };
2867
+ // An observed prototype slot answers through the bag when the bag
2868
+ // holds the name (own or through its prototype). A bag read as a
2869
+ // fresh empty object (an instance with no own dynamic properties
2870
+ // whose bag initializer predates the class's prototype data) does
2871
+ // not, so the method then comes from the class's prototype data.
2872
+ const prototype = prototypeMethod
2873
+ ? classPrototypeData(lowerer, info, loc, receiver)
2874
+ : null;
2330
2875
  dispatch.callback.body.unshift({
2331
2876
  kind: "if",
2332
2877
  cond: condition,
@@ -2335,18 +2880,7 @@ export class ClassDynamicDispatch {
2335
2880
  kind: "return",
2336
2881
  value: {
2337
2882
  kind: "ternary",
2338
- cond: prototypeMethod
2339
- ? { kind: "boolLit", value: true, type: BOOL, loc }
2340
- : {
2341
- kind: "libCall",
2342
- fn: "dyn.hasKey",
2343
- args: [
2344
- bag,
2345
- { kind: "strLit", value: dispatch.source.method, type: STRING, loc },
2346
- ],
2347
- type: BOOL,
2348
- loc,
2349
- },
2883
+ cond: prototype ? { kind: "boolLit", value: true, type: BOOL, loc } : bagHas,
2350
2884
  then: {
2351
2885
  kind: "dynObjLit",
2352
2886
  fields: [
@@ -2354,8 +2888,17 @@ export class ClassDynamicDispatch {
2354
2888
  key: { kind: "strLit", value: "value", type: STRING, loc },
2355
2889
  value: {
2356
2890
  kind: "dynKeyGet",
2357
- value: bag,
2358
- key: { kind: "strLit", value: dispatch.source.method, type: STRING, loc },
2891
+ value: prototype
2892
+ ? {
2893
+ kind: "ternary",
2894
+ cond: bagHas,
2895
+ then: bag,
2896
+ else_: prototype,
2897
+ type: DYN,
2898
+ loc,
2899
+ }
2900
+ : bag,
2901
+ key: methodKey,
2359
2902
  type: DYN,
2360
2903
  loc,
2361
2904
  },
@@ -2462,7 +3005,7 @@ export class ClassDynamicDispatch {
2462
3005
  for (const plan of this.propertyReceivers(lowerer)) {
2463
3006
  if (plan.info !== plan.capsule ||
2464
3007
  dispatch.classes.has(plan.key) ||
2465
- (!dispatch.field && !candidates(dispatch.method).includes(plan.info)))
3008
+ (!dispatch.field && !candidateSet(dispatch.method).has(plan.info)))
2466
3009
  continue;
2467
3010
  dispatch.classes.add(plan.key);
2468
3011
  const loc = dispatch.fn.loc;
@@ -2545,28 +3088,52 @@ export class ClassDynamicDispatch {
2545
3088
  });
2546
3089
  changed = true;
2547
3090
  }
2548
- for (const plan of this.propertyReceivers(lowerer, true)) {
3091
+ // Only the receivers that declare or hold the name, and the rooted
3092
+ // ones, can pass the test, except for names it decides on every
3093
+ // receiver. Fields added while bodies lower (the property bag and the
3094
+ // attribute words) have compiler names, which take every receiver.
3095
+ const plans = this.propertyReceivers(lowerer, true);
3096
+ const anyReceiver = !isClassOwnEnumerableFieldName(dispatch.name) ||
3097
+ dispatch.name === "constructor" ||
3098
+ dispatch.name === "stack";
3099
+ const skips = (plan) => !isClassOwnEnumerableFieldName(dispatch.name) ||
3100
+ (!(plan.info.builtinStream !== undefined && streamProperty(dispatch.name)) &&
3101
+ !eventTargetInheritedMember(plan.info, dispatch.name) &&
3102
+ !dateInheritedMember(lowerer, plan.info, dispatch.name) &&
3103
+ !findMethodOn(lowerer, plan.info, dispatch.name) &&
3104
+ !findGenericMethodOn(lowerer, plan.info, dispatch.name) &&
3105
+ dispatch.name !== "constructor" &&
3106
+ !plan.info.fields.has(dispatch.name) &&
3107
+ !(dispatch.name === "stack" && lowerer.isSubclassOf(plan.info.def.name, "%Error")) &&
3108
+ !findMethodOn(lowerer, plan.info, `get:${dispatch.name}`) &&
3109
+ !findMethodOn(lowerer, plan.info, `set:${dispatch.name}`));
3110
+ const selected = anyReceiver ? plans : receiversFor(plans, dispatch.name, "members");
3111
+ if (CHECK_CANDIDATES &&
3112
+ plans.some((plan) => !dispatch.classes.has(plan.key) && !skips(plan) && !selected.includes(plan)))
3113
+ throw new InternalCompilerError(`indexed receivers for ${dispatch.name} differ`);
3114
+ for (const plan of selected) {
2549
3115
  const { info } = plan;
2550
- if (!isClassOwnEnumerableFieldName(dispatch.name) ||
2551
- (!(info.builtinStream !== undefined && streamProperty(dispatch.name)) &&
2552
- !eventTargetInheritedMember(info, dispatch.name) &&
2553
- !findMethodOn(lowerer, info, dispatch.name) &&
2554
- !findGenericMethodOn(lowerer, info, dispatch.name) &&
2555
- dispatch.name !== "constructor" &&
2556
- !info.fields.has(dispatch.name) &&
2557
- !(dispatch.name === "stack" && lowerer.isSubclassOf(info.def.name, "%Error")) &&
2558
- !findMethodOn(lowerer, info, `get:${dispatch.name}`) &&
2559
- !findMethodOn(lowerer, info, `set:${dispatch.name}`)))
2560
- continue;
3116
+ // Classes answered in an earlier pass skip the member lookups.
2561
3117
  if (dispatch.classes.has(plan.key))
2562
3118
  continue;
3119
+ if (skips(plan))
3120
+ continue;
2563
3121
  dispatch.classes.add(plan.key);
2564
3122
  const loc = dispatch.fn.loc;
2565
3123
  const { receiver, condition } = this.propertyReceiver(plan, loc);
3124
+ // The branch checks its receiver once: each use of the checked
3125
+ // receiver would repeat the check.
3126
+ const local = `receiver.${dispatch.fn.locals.length}`;
3127
+ dispatch.fn.locals.push({
3128
+ id: local,
3129
+ name: "receiver",
3130
+ type: receiver.type,
3131
+ mutable: false,
3132
+ });
2566
3133
  const before = lowerer.diags.length;
2567
3134
  let branch;
2568
3135
  try {
2569
- branch = this.propertyBody(lowerer, dispatch, info, receiver);
3136
+ branch = this.propertyBody(lowerer, dispatch, info, varRef(local, receiver.type, loc));
2570
3137
  }
2571
3138
  catch (error) {
2572
3139
  if (!(error instanceof PoisonError) || !info.decl)
@@ -2579,7 +3146,7 @@ export class ClassDynamicDispatch {
2579
3146
  dispatch.fn.body.unshift({
2580
3147
  kind: "if",
2581
3148
  cond: condition,
2582
- then: branch,
3149
+ then: [{ kind: "varDecl", localId: local, init: receiver, loc }, ...branch],
2583
3150
  else_: null,
2584
3151
  loc,
2585
3152
  });
@@ -2655,7 +3222,8 @@ export class ClassDynamicDispatch {
2655
3222
  },
2656
3223
  ];
2657
3224
  if (((info.builtinStream !== undefined && streamProperty(name)) ||
2658
- eventTargetInheritedMember(info, name)) &&
3225
+ eventTargetInheritedMember(info, name) ||
3226
+ dateInheritedMember(lowerer, info, name)) &&
2659
3227
  dispatch.probe)
2660
3228
  return [
2661
3229
  {
@@ -2671,7 +3239,7 @@ export class ClassDynamicDispatch {
2671
3239
  const prototypeMethod = !info.fields.has(name) && observedPrototypeMethod(lowerer, info, name, loc, receiver);
2672
3240
  if (info.fields.has(name) || (dispatch.probe === "in" && !prototypeMethod)) {
2673
3241
  if (info.fields.has(name) && info.def.tracksOwnFields) {
2674
- const bag = this.readPropertyBagOrEmpty(lowerer, lowerer.coerceToExpected(receiver, DYN), loc);
3242
+ const bag = this.branchPropertyBag(lowerer, info, receiver, true, loc);
2675
3243
  const symbol = symbolMemberKey(lowerer, info, name, loc);
2676
3244
  const fn = dispatch.probe === "in"
2677
3245
  ? "dyn.hasKey"
@@ -2696,7 +3264,7 @@ export class ClassDynamicDispatch {
2696
3264
  { kind: "return", value: { kind: "boolLit", value: true, type: BOOL, loc }, loc },
2697
3265
  ];
2698
3266
  }
2699
- const bag = this.readPropertyBagOrEmpty(lowerer, lowerer.coerceToExpected(receiver, DYN), loc);
3267
+ const bag = this.branchPropertyBag(lowerer, info, receiver, true, loc);
2700
3268
  const symbol = name.startsWith("sym:") || name.startsWith("%symbol:");
2701
3269
  const fn = dispatch.probe === "in"
2702
3270
  ? "dyn.hasKey"
@@ -2762,9 +3330,8 @@ export class ClassDynamicDispatch {
2762
3330
  }
2763
3331
  const branches = [];
2764
3332
  if (!dispatch.write && !dispatch.reflect && !info.def.tracksOwnFields) {
2765
- const value = varRef("p.0", DYN, loc);
2766
3333
  const key = varRef("p.key", DYN, loc);
2767
- const bag = this.readPropertyBagOrEmpty(lowerer, value, loc);
3334
+ const bag = this.branchPropertyBag(lowerer, info, receiver, true, loc);
2768
3335
  branches.push({
2769
3336
  kind: "if",
2770
3337
  cond: {
@@ -2866,6 +3433,10 @@ export class ClassDynamicDispatch {
2866
3433
  if (inherited)
2867
3434
  for (const name of inherited)
2868
3435
  names.add(name);
3436
+ if (dateRootOf(info))
3437
+ for (const name of DATE_PROTOTYPE_METHOD_NAMES)
3438
+ if (dateInheritedMember(lowerer, info, name))
3439
+ names.add(name);
2869
3440
  for (let owner = info; owner; owner = owner.base) {
2870
3441
  const methodNames = [...owner.methods.keys()];
2871
3442
  if (owner.genericMethods)
@@ -3084,6 +3655,39 @@ export class ClassDynamicDispatch {
3084
3655
  }
3085
3656
  /** The receiver's own dynamic properties for a read: undefined while it has
3086
3657
  * none, and never stored, so reads stay valid on published objects. */
3658
+ /** Statements that return `className`'s stand-in prototype: one empty
3659
+ * object per class, created on first use and kept in a module global. */
3660
+ prototypeStandIn(lowerer, className, loc) {
3661
+ const globalId = `%g.%prototype.standIn.${className}`;
3662
+ const readyId = `${globalId}.ready`;
3663
+ if (!this.prototypeStandIns.has(className)) {
3664
+ this.prototypeStandIns.add(className);
3665
+ lowerer.globalsList.push({ id: globalId, name: `${className}.prototype`, type: DYN, mutable: true }, { id: readyId, name: `${className}.prototype.ready`, type: BOOL, mutable: true });
3666
+ }
3667
+ return [
3668
+ {
3669
+ kind: "if",
3670
+ cond: { kind: "unary", op: "!", operand: varRef(readyId, BOOL, loc), type: BOOL, loc },
3671
+ then: [
3672
+ {
3673
+ kind: "assign",
3674
+ localId: globalId,
3675
+ value: { kind: "dynObjLit", fields: [], type: DYN, loc },
3676
+ loc,
3677
+ },
3678
+ {
3679
+ kind: "assign",
3680
+ localId: readyId,
3681
+ value: { kind: "boolLit", value: true, type: BOOL, loc },
3682
+ loc,
3683
+ },
3684
+ ],
3685
+ else_: null,
3686
+ loc,
3687
+ },
3688
+ { kind: "return", value: varRef(globalId, DYN, loc), loc },
3689
+ ];
3690
+ }
3087
3691
  readPropertyBag(lowerer, receiver, loc) {
3088
3692
  const helper = classPropertiesHelper(lowerer, loc, true);
3089
3693
  this.generated.add(helper);
@@ -3105,7 +3709,7 @@ export class ClassDynamicDispatch {
3105
3709
  * each class branch as small as the storing form. */
3106
3710
  readBagHas(lowerer, fn, bag, key, loc) {
3107
3711
  const name = fn === "dyn.hasKey" ? "%dyn.class.bagHas" : "%dyn.class.bagHasComputed";
3108
- let helper = lowerer.liftedFns.find((item) => item.name === name);
3712
+ let helper = lowerer.liftedFnNamed(name);
3109
3713
  if (!helper) {
3110
3714
  const keyType = fn === "dyn.hasKey" ? STRING : DYN;
3111
3715
  const value = varRef("p.0", DYN, loc);
@@ -3498,6 +4102,66 @@ export class ClassDynamicDispatch {
3498
4102
  ];
3499
4103
  return { kind: "if", cond: condition, then: body, else_: null, loc };
3500
4104
  }
4105
+ // Date.prototype[Symbol.toPrimitive] takes "default" as "string", and a
4106
+ // class declared `extends Date` inherits Date's toString and valueOf,
4107
+ // which answer primitives from the time value.
4108
+ const dateRoot = dateRootOf(info);
4109
+ if (dateRoot) {
4110
+ const dateOrder = hint === "number" ? ["valueOf", "toString"] : ["toString", "valueOf"];
4111
+ const { receiver } = this.propertyReceiver(plan, loc);
4112
+ const body = [];
4113
+ for (const method of dateOrder) {
4114
+ if (!conversionMethod(lowerer, info, method)) {
4115
+ const time = {
4116
+ kind: "fieldGet",
4117
+ obj: upcastTo(lowerer, receiver, dateRoot.def.name),
4118
+ className: dateRoot.def.name,
4119
+ field: DATE_TIME_FIELD,
4120
+ type: DATE_T,
4121
+ loc,
4122
+ };
4123
+ body.push({
4124
+ kind: "return",
4125
+ value: lowerer.coerceToExpected(dateValueMethod(method, time, loc), DYN),
4126
+ loc,
4127
+ });
4128
+ break;
4129
+ }
4130
+ const result = `%toPrimitive.${method}.${helper.locals.length}`;
4131
+ helper.locals.push({ id: result, name: method, type: DYN, mutable: false });
4132
+ body.push({
4133
+ kind: "varDecl",
4134
+ localId: result,
4135
+ init: {
4136
+ kind: "call",
4137
+ callee: this.toPrimitiveCall(lowerer, plan, method, 0, loc),
4138
+ args: [varRef("p.0", DYN, loc)],
4139
+ type: DYN,
4140
+ loc,
4141
+ },
4142
+ loc,
4143
+ }, {
4144
+ kind: "if",
4145
+ cond: isPrimitive(varRef(result, DYN, loc), loc),
4146
+ then: [{ kind: "return", value: varRef(result, DYN, loc), loc }],
4147
+ else_: null,
4148
+ loc,
4149
+ });
4150
+ }
4151
+ if (body.at(-1)?.kind !== "return")
4152
+ body.push({
4153
+ kind: "return",
4154
+ value: nodeThrowExpr(1, "", "Cannot convert object to primitive value", DYN, loc),
4155
+ loc,
4156
+ });
4157
+ return {
4158
+ kind: "if",
4159
+ cond: this.propertyReceiver(plan, loc).condition,
4160
+ then: body,
4161
+ else_: null,
4162
+ loc,
4163
+ };
4164
+ }
3501
4165
  const order = hint === "string" ? ["toString", "valueOf"] : ["valueOf", "toString"];
3502
4166
  if (!order.some((method) => conversionMethod(lowerer, info, method)))
3503
4167
  return null;
@@ -3665,7 +4329,7 @@ export class ClassDynamicDispatch {
3665
4329
  readPropertyBagOrEmpty(lowerer, receiver, loc) {
3666
4330
  // One call per read site: large JS programs have a branch per class and
3667
4331
  // property, so the absent-bag handling lives in the shared helper.
3668
- let helper = lowerer.liftedFns.find((fn) => fn.name === READ_PROPERTIES_OR_EMPTY);
4332
+ let helper = lowerer.liftedFnNamed(READ_PROPERTIES_OR_EMPTY);
3669
4333
  if (!helper) {
3670
4334
  // Settled by finalize; until then, the read-only bag's own dispatch.
3671
4335
  helper = {
@@ -3752,11 +4416,119 @@ export class ClassDynamicDispatch {
3752
4416
  lowerer.liftedFns.push(helper);
3753
4417
  return helper;
3754
4418
  }
4419
+ /** The read-only bag a class branch reads for its receiver: the
4420
+ * receiver's own field when the branch selected the receiver's exact
4421
+ * class, otherwise the dispatch over every class (readPropertyBag, or
4422
+ * readPropertyBagOrEmpty with `orEmpty`). */
4423
+ branchPropertyBag(lowerer, info, receiver, orEmpty, loc) {
4424
+ const helper = this.exactPropertyBag(lowerer, info, receiver, orEmpty, loc);
4425
+ if (helper)
4426
+ return { kind: "call", callee: helper.name, args: [receiver], type: DYN, loc };
4427
+ return orEmpty
4428
+ ? this.readPropertyBagOrEmpty(lowerer, lowerer.coerceToExpected(receiver, DYN), loc)
4429
+ : this.readPropertyBag(lowerer, receiver, loc);
4430
+ }
4431
+ /** `%class.branchProperties[OrEmpty]:<class>(receiver)`: the read-only bag of
4432
+ * an instance of exactly `info`. A class branch of the dispatch helpers
4433
+ * selects a canonical receiver (normalizeDispatches gives an instance its
4434
+ * actual class's capsule), so its branch for `info` sees only instances
4435
+ * of `info`; instances of its subclasses take their own branches. Such a
4436
+ * receiver needs neither the dispatch over every class nor a boxed copy of
4437
+ * itself. Null
4438
+ * when `receiver` is not typed as `info`, when a runtime or builtin class
4439
+ * in the family keeps its own property contract, or before the class has
4440
+ * a bag. */
4441
+ exactPropertyBag(lowerer, info, receiver, orEmpty, loc) {
4442
+ const type = receiver.type;
4443
+ if (type.kind !== "object" || type.className !== info.def.name)
4444
+ return null;
4445
+ for (let current = info; current; current = current.base)
4446
+ if (current.def.runtime ||
4447
+ current.builtinEmitter ||
4448
+ current.builtinStream ||
4449
+ current.builtinError)
4450
+ return null;
4451
+ const key = `${type.className}:${orEmpty}`;
4452
+ const existing = this.exactPropertyBags.get(key);
4453
+ if (existing)
4454
+ return existing;
4455
+ const initializers = this.bagInitializers.get(type.className);
4456
+ if (!initializers)
4457
+ return null;
4458
+ const self = varRef("p.0", type, loc);
4459
+ const bag = {
4460
+ kind: "fieldGet",
4461
+ obj: self,
4462
+ className: type.className,
4463
+ field: PROPERTY_BAG,
4464
+ type: DYN,
4465
+ loc,
4466
+ };
4467
+ const initialize = {
4468
+ ...initializers[0],
4469
+ obj: self,
4470
+ value: withTypedReceiver(initializers[0].value, self),
4471
+ loc,
4472
+ };
4473
+ const helper = {
4474
+ name: `%class.branchProperties${orEmpty ? "OrEmpty" : ""}:${type.className}`,
4475
+ params: [{ localId: "p.0", name: "value", type }],
4476
+ returnType: DYN,
4477
+ locals: [{ id: "p.0", name: "value", type, mutable: false }],
4478
+ loc,
4479
+ body: [
4480
+ {
4481
+ kind: "if",
4482
+ cond: { kind: "dynTest", test: "undefined", value: bag, type: BOOL, loc },
4483
+ then: [initialize],
4484
+ else_: null,
4485
+ loc,
4486
+ },
4487
+ { kind: "return", value: bag, loc },
4488
+ ],
4489
+ };
4490
+ // Initializers gain their prototype as subclasses become constructible;
4491
+ // finalize then turns the lazy store into the read's result.
4492
+ initializers.push(initialize);
4493
+ this.exactPropertyBags.set(key, helper);
4494
+ this.readPropertyBags.push({ helper, initialize, orEmpty });
4495
+ this.generated.add(helper);
4496
+ lowerer.liftedFns.push(helper);
4497
+ return helper;
4498
+ }
3755
4499
  /** The prototype a new property bag of `current` (or of the subclass the
3756
4500
  * receiver is) starts from, or null when `current` has no prototype data.
3757
4501
  * A class with constructible subclasses that have prototype data selects
3758
4502
  * it through its `%class.bagPrototype` helper; any other class reads its
3759
4503
  * own prototype data. */
4504
+ /** The lazy bag stores as they stand in the generated bodies, by class.
4505
+ * Worklist passes that transform every function rebuild statement
4506
+ * objects, so a recorded initializer can be a detached copy; a store that
4507
+ * gains its prototype must be updated where it runs. */
4508
+ liveBagInitializers() {
4509
+ const live = new Map();
4510
+ const add = (stmt) => {
4511
+ if (stmt?.kind !== "if")
4512
+ return;
4513
+ const store = stmt.then[0];
4514
+ if (store?.kind !== "fieldSet" || store.field !== PROPERTY_BAG)
4515
+ return;
4516
+ const list = live.get(store.className);
4517
+ if (list)
4518
+ list.push(store);
4519
+ else
4520
+ live.set(store.className, [store]);
4521
+ };
4522
+ // The complete dispatch guards each class's lazy store by its receiver.
4523
+ for (const stmt of this.propertyBag?.body ?? [])
4524
+ if (stmt.kind === "if")
4525
+ add(stmt.then[0]);
4526
+ for (const helper of this.typedPropertyBags.values())
4527
+ add(helper.body[0]);
4528
+ for (const helper of this.exactPropertyBags.values())
4529
+ add(helper.body[0]);
4530
+ return live;
4531
+ }
3760
4532
  bagPrototype(lowerer, current, receiver, loc) {
3761
4533
  const arg = receiver.type.kind === "object" && receiver.type.className !== current.def.name
3762
4534
  ? {
@@ -3826,9 +4598,15 @@ export class ClassDynamicDispatch {
3826
4598
  * prototype-backed bag is produced for this read only. A published object
3827
4599
  * cannot take the store, and Node's reads never write. */
3828
4600
  finalize(lowerer) {
3829
- for (const { helper, initialize } of this.readPropertyBags) {
4601
+ // Each table serves every site that reaches it.
4602
+ if (lowerer)
4603
+ for (const fn of this.generated)
4604
+ lowerer.shareHelper(fn);
4605
+ if (lowerer)
4606
+ this.recordBagInitializers(lowerer);
4607
+ for (const { helper, initialize, orEmpty } of this.readPropertyBags) {
3830
4608
  const absent = helper.body[0];
3831
- if (isEmptyBag(initialize.value))
4609
+ if (isEmptyBag(initialize.value) && !orEmpty)
3832
4610
  helper.body.shift();
3833
4611
  else if (absent?.kind === "if")
3834
4612
  absent.then = [{ kind: "return", value: initialize.value, loc: initialize.loc }];
@@ -3842,6 +4620,170 @@ export class ClassDynamicDispatch {
3842
4620
  fn.locals = structuredClone(this.propertyBag.locals);
3843
4621
  fn.body = readOnlyBagBody(structuredClone(this.propertyBag.body), fn.name === READ_PROPERTIES_OR_EMPTY);
3844
4622
  }
4623
+ if (lowerer)
4624
+ this.guardClassTables(lowerer);
4625
+ if (lowerer)
4626
+ this.guardPropertyHelpers(lowerer);
4627
+ }
4628
+ /** Each tracked class's bag initializer over a typed receiver (`this`),
4629
+ * for the per-class field-creation helpers (trackClassFieldCreation),
4630
+ * which create an instance's bag without the class-table dispatch. */
4631
+ recordBagInitializers(lowerer) {
4632
+ for (const [className, initializers] of this.bagInitializers) {
4633
+ const init = initializers[0];
4634
+ if (!init || !lowerer.classes.get(className)?.def.tracksOwnFields)
4635
+ continue;
4636
+ const self = varRef("this", { kind: "object", className }, init.loc);
4637
+ const value = withTypedReceiver(structuredClone(init.value), self);
4638
+ if (mentionsLocal(value, "p.0"))
4639
+ continue;
4640
+ // The class-table branches can give the class's instances different
4641
+ // bags (a base class's own prototype for its instances, the
4642
+ // instance's class prototype for subclass instances); only a class
4643
+ // whose branches all agree has one initializer for every instance.
4644
+ const shape = withoutLocations(value);
4645
+ if (initializers.some((other) => withoutLocations(withTypedReceiver(structuredClone(other.value), self)) !== shape))
4646
+ continue;
4647
+ // Lowerer stand-ins in unit tests may not carry the table.
4648
+ lowerer.classBagInitializers?.set(className, value);
4649
+ }
4650
+ }
4651
+ /** Fast exits for the generated class tables: every class branch of
4652
+ * the property-bag, normalization and static-bag helpers tests the
4653
+ * value's capsule key (or class key), so a value of another kind (a
4654
+ * plain object, the common case in untyped code) skips straight to the
4655
+ * table's fallthrough instead of testing every class in the program. */
4656
+ guardClassTables(lowerer) {
4657
+ const names = new Set([
4658
+ "%dyn.class.properties",
4659
+ READ_PROPERTIES,
4660
+ READ_PROPERTIES_OR_EMPTY,
4661
+ "%dyn.class.normalize",
4662
+ "%dyn.class.staticProperties",
4663
+ ]);
4664
+ for (const fn of lowerer.liftedFns) {
4665
+ if (!names.has(fn.name) || fn.body.length < 2)
4666
+ continue;
4667
+ const param = fn.params[0]?.localId;
4668
+ if (param === undefined)
4669
+ continue;
4670
+ const last = fn.body[fn.body.length - 1];
4671
+ if (last.kind !== "return" || last.value === null || !returnsParam(last.value, param))
4672
+ continue;
4673
+ let test = null;
4674
+ let ok = true;
4675
+ for (const stmt of fn.body.slice(0, -1)) {
4676
+ if (stmt.kind === "assign" &&
4677
+ stmt.localId === param &&
4678
+ stmt.value.kind === "call" &&
4679
+ stmt.value.callee === "%dyn.class.normalize")
4680
+ continue;
4681
+ const kind = stmt.kind === "if" && stmt.else_ === null ? branchKind(stmt.cond, param) : null;
4682
+ if (kind === null || (test !== null && kind !== test)) {
4683
+ ok = false;
4684
+ break;
4685
+ }
4686
+ test = kind;
4687
+ }
4688
+ if (!ok || test === null)
4689
+ continue;
4690
+ const first = fn.body[0];
4691
+ if (first.kind === "if" && first.cond.kind === "dynTest" && first.cond.test === test)
4692
+ continue;
4693
+ const loc = fn.loc;
4694
+ fn.body.unshift({
4695
+ kind: "if",
4696
+ cond: {
4697
+ kind: "dynTest",
4698
+ test,
4699
+ negated: true,
4700
+ value: varRef(param, DYN, loc),
4701
+ type: BOOL,
4702
+ loc,
4703
+ },
4704
+ then: [structuredClone(last)],
4705
+ else_: null,
4706
+ loc,
4707
+ });
4708
+ }
4709
+ }
4710
+ /** Fast exits for the generated property helpers: when every class
4711
+ * branch tests a capsule key or a class key and the fallthrough is still
4712
+ * the bag access the helper was created with, a value of another kind
4713
+ * (a plain object, array or primitive) normalizes to itself, has itself
4714
+ * as its bag, and so gets the plain access directly, without the
4715
+ * normalization, bag and static-bag calls. */
4716
+ guardPropertyHelpers(lowerer) {
4717
+ // Every class table the fallthrough or normalization calls must answer
4718
+ // a plain value with the value itself: its kind exit is in place.
4719
+ const exits = (name) => {
4720
+ const helper = lowerer.liftedFnNamed(name);
4721
+ const first = helper?.body[0];
4722
+ const param = helper?.params[0]?.localId;
4723
+ return (param !== undefined &&
4724
+ first?.kind === "if" &&
4725
+ first.cond.kind === "dynTest" &&
4726
+ first.cond.negated === true &&
4727
+ first.then.length === 1 &&
4728
+ first.then[0].kind === "return" &&
4729
+ first.then[0].value !== null &&
4730
+ returnsParam(first.then[0].value, param));
4731
+ };
4732
+ const tables = new Set([
4733
+ "%dyn.class.properties",
4734
+ READ_PROPERTIES,
4735
+ READ_PROPERTIES_OR_EMPTY,
4736
+ "%dyn.class.normalize",
4737
+ "%dyn.class.staticProperties",
4738
+ ]);
4739
+ const callsOnlyGuardedTables = (statements) => everyStmtList(statements, {
4740
+ stmt: () => true,
4741
+ expr: (expression) => expression.kind !== "call" || (tables.has(expression.callee) && exits(expression.callee)),
4742
+ });
4743
+ for (const dispatch of this.properties.values()) {
4744
+ const plain = dispatch.plain;
4745
+ if (!plain)
4746
+ continue;
4747
+ const fn = dispatch.fn;
4748
+ const param = fn.params[0]?.localId;
4749
+ if (param === undefined)
4750
+ continue;
4751
+ const head = fn.body.length - plain.tail.length;
4752
+ if (head < 0 || plain.tail.some((stmt, i) => fn.body[head + i] !== stmt))
4753
+ continue;
4754
+ let ok = true;
4755
+ for (const stmt of fn.body.slice(0, head)) {
4756
+ if (stmt.kind === "assign" &&
4757
+ stmt.localId === param &&
4758
+ stmt.value.kind === "call" &&
4759
+ stmt.value.callee === "%dyn.class.normalize")
4760
+ continue;
4761
+ if (stmt.kind === "if" && stmt.else_ === null && branchKind(stmt.cond, param) !== null)
4762
+ continue;
4763
+ ok = false;
4764
+ break;
4765
+ }
4766
+ // Class branches never run for a plain value; the rest always does.
4767
+ if (!ok || !callsOnlyGuardedTables(fn.body.filter((stmt) => stmt.kind !== "if")))
4768
+ continue;
4769
+ const loc = fn.loc;
4770
+ const not = (test) => ({
4771
+ kind: "dynTest",
4772
+ test,
4773
+ negated: true,
4774
+ value: varRef(param, DYN, loc),
4775
+ type: BOOL,
4776
+ loc,
4777
+ });
4778
+ fn.body.unshift({
4779
+ kind: "if",
4780
+ cond: not("classCapsule"),
4781
+ then: [{ kind: "if", cond: not("funcKind"), then: plain.access, else_: null, loc }],
4782
+ else_: null,
4783
+ loc,
4784
+ });
4785
+ delete dispatch.plain;
4786
+ }
3845
4787
  }
3846
4788
  normalizedDispatches() {
3847
4789
  return [
@@ -3913,10 +4855,15 @@ export class ClassDynamicDispatch {
3913
4855
  this.normalizationKey = key;
3914
4856
  const loc = this.normalization.loc;
3915
4857
  const value = varRef("value", DYN, loc);
3916
- this.normalization.body = entries.map(({ capsule, children }) => {
4858
+ // The checked receiver is unboxed once per capsule branch, not once
4859
+ // per subclass test.
4860
+ this.normalization.locals = this.normalization.locals.filter((local) => !local.id.startsWith("%normalized."));
4861
+ this.normalization.body = entries.map(({ capsule, children }, index) => {
3917
4862
  const type = { kind: "object", className: capsule.def.name };
3918
- const receiver = { kind: "dynCheck", value, type, loc };
3919
- return {
4863
+ const id = `%normalized.${index}`;
4864
+ this.normalization.locals.push({ id, name: id, type, mutable: false });
4865
+ const receiver = varRef(id, type, loc);
4866
+ const branch = {
3920
4867
  kind: "if",
3921
4868
  cond: {
3922
4869
  kind: "libCall",
@@ -3957,6 +4904,15 @@ export class ClassDynamicDispatch {
3957
4904
  else_: null,
3958
4905
  loc,
3959
4906
  };
4907
+ // The capsule test stays the branch condition; its body unboxes.
4908
+ if (branch.kind === "if")
4909
+ branch.then.unshift({
4910
+ kind: "varDecl",
4911
+ localId: id,
4912
+ init: { kind: "dynCheck", value, type, loc },
4913
+ loc,
4914
+ });
4915
+ return branch;
3960
4916
  });
3961
4917
  this.normalization.body.push({ kind: "return", value, loc });
3962
4918
  }
@@ -3997,21 +4953,43 @@ export class ClassDynamicDispatch {
3997
4953
  };
3998
4954
  add(root);
3999
4955
  }
4956
+ /** propertyReceivers results by mode, with the class graph they were
4957
+ * computed from: the boxed classes, the registered classes, the subclass
4958
+ * links and the constructed classes only grow, so equal counts and the
4959
+ * same capsules give the same plans. */
4960
+ receiverPlans = new Map();
4000
4961
  /** A capsule retains its static type, while its object may be a subclass.
4001
4962
  * Preorder insertion lets later branches test the most derived layout first. */
4002
4963
  propertyReceivers(lowerer, streams = false, normalize = true) {
4964
+ const mode = `${streams}:${normalize}`;
4965
+ const revision = `${this.boxed.size}:${lowerer.classes.size}:${lowerer.subclassLinks}:${lowerer.constructedClassCount()}`;
4966
+ const cached = this.receiverPlans.get(mode);
4967
+ if (cached?.revision === revision) {
4968
+ let i = 0;
4969
+ let same = true;
4970
+ for (const name of this.boxed)
4971
+ if (lowerer.classes.get(name) !== cached.capsules[i++])
4972
+ same = false;
4973
+ if (same)
4974
+ return cached.plans;
4975
+ }
4976
+ const capsules = [];
4003
4977
  const plans = [];
4004
4978
  const seen = new Set();
4005
4979
  for (const name of this.boxed) {
4006
4980
  const capsule = lowerer.classes.get(name);
4981
+ capsules.push(capsule);
4007
4982
  if (!capsule ||
4008
4983
  ((capsule.builtinEmitter || capsule.builtinStream) && !streams) ||
4009
4984
  capsule.builtinError)
4010
4985
  continue;
4011
4986
  const canonical = normalize && !capsule.builtinStream && !capsule.builtinEmitter;
4012
4987
  const visit = (info) => {
4013
- if ((!canonical || !seen.has(info.def.name)) &&
4014
- (info === capsule || lowerer.classCanBeConstructed(info))) {
4988
+ // A seen class was visited with its whole subtree, and a canonical
4989
+ // visit adds no plan for a seen class.
4990
+ if (canonical && seen.has(info.def.name))
4991
+ return;
4992
+ if (info === capsule || lowerer.classCanBeConstructed(info)) {
4015
4993
  seen.add(info.def.name);
4016
4994
  plans.push({
4017
4995
  info,
@@ -4024,6 +5002,7 @@ export class ClassDynamicDispatch {
4024
5002
  };
4025
5003
  visit(capsule);
4026
5004
  }
5005
+ this.receiverPlans.set(mode, { revision, capsules, plans });
4027
5006
  return plans;
4028
5007
  }
4029
5008
  propertyReceiver(plan, loc) {
@@ -4204,9 +5183,11 @@ export class ClassDynamicDispatch {
4204
5183
  propertyBody(lowerer, dispatch, info, receiver) {
4205
5184
  const { name, write } = dispatch;
4206
5185
  const loc = dispatch.fn.loc;
4207
- // The inherited EventTarget/Event members of a subclass instance: the
4208
- // runtime's capsule view answers the accessors and method values.
4209
- if (eventTargetInheritedMember(info, name)) {
5186
+ // The inherited EventTarget/Event members of a subclass instance, and
5187
+ // the inherited Date methods of an instance of a class declared
5188
+ // `extends Date`: the runtime's capsule view answers the accessors and
5189
+ // method values.
5190
+ if (eventTargetInheritedMember(info, name) || dateInheritedMember(lowerer, info, name)) {
4210
5191
  const key = { kind: "strLit", value: name, type: STRING, loc };
4211
5192
  if (!write)
4212
5193
  return [
@@ -4348,7 +5329,7 @@ export class ClassDynamicDispatch {
4348
5329
  },
4349
5330
  {
4350
5331
  kind: "if",
4351
- cond: this.readBagHas(lowerer, "dyn.hasKey", this.readPropertyBag(lowerer, receiver, loc), key, loc),
5332
+ cond: this.readBagHas(lowerer, "dyn.hasKey", this.branchPropertyBag(lowerer, info, receiver, false, loc), key, loc),
4352
5333
  then: [store],
4353
5334
  else_: null,
4354
5335
  loc,
@@ -4360,7 +5341,7 @@ export class ClassDynamicDispatch {
4360
5341
  { kind: "return", value: null, loc },
4361
5342
  ];
4362
5343
  }
4363
- const bag = this.readPropertyBag(lowerer, receiver, loc);
5344
+ const bag = this.branchPropertyBag(lowerer, info, receiver, false, loc);
4364
5345
  return [
4365
5346
  {
4366
5347
  kind: "return",
@@ -4418,7 +5399,7 @@ export class ClassDynamicDispatch {
4418
5399
  !info.classDecorators) {
4419
5400
  this.constructors.set(info.def.name, info);
4420
5401
  const cls = lowerer.coerceToExpected(classValueRef(lowerer, info, info.decl), DYN);
4421
- const bag = this.readPropertyBag(lowerer, receiver, loc);
5402
+ const bag = this.branchPropertyBag(lowerer, info, receiver, false, loc);
4422
5403
  const key = { kind: "strLit", value: name, type: STRING, loc };
4423
5404
  return [
4424
5405
  {
@@ -4489,7 +5470,7 @@ export class ClassDynamicDispatch {
4489
5470
  if (symbol || (isClassOwnEnumerableFieldName(name) && !name.startsWith("sym:"))) {
4490
5471
  const prototypeMethod = observedPrototypeMethod(lowerer, info, name, loc, receiver);
4491
5472
  // Selecting the method must not give the object own storage.
4492
- const bag = this.readPropertyBag(lowerer, receiver, loc);
5473
+ const bag = this.branchPropertyBag(lowerer, info, receiver, false, loc);
4493
5474
  const key = symbol ?? { kind: "strLit", value: name, type: STRING, loc };
4494
5475
  body.push({
4495
5476
  kind: "if",
@@ -4550,7 +5531,7 @@ export class ClassDynamicDispatch {
4550
5531
  }
4551
5532
  if (!field && !accessor) {
4552
5533
  const instance = lowerer.coerceToExpected(receiver, DYN);
4553
- const bag = this.readPropertyBagOrEmpty(lowerer, instance, loc);
5534
+ const bag = this.branchPropertyBag(lowerer, info, receiver, true, loc);
4554
5535
  const key = { kind: "strLit", value: name, type: STRING, loc };
4555
5536
  const own = {
4556
5537
  kind: "libCall",
@@ -4598,7 +5579,7 @@ export class ClassDynamicDispatch {
4598
5579
  if (boxed.kind === "dynFrom" && mutable(boxed.value.type))
4599
5580
  boxed.liveRef = true;
4600
5581
  if (accessor) {
4601
- const bag = this.readPropertyBagOrEmpty(lowerer, lowerer.coerceToExpected(receiver, DYN), loc);
5582
+ const bag = this.branchPropertyBag(lowerer, info, receiver, true, loc);
4602
5583
  const key = { kind: "strLit", value: name, type: STRING, loc };
4603
5584
  return [
4604
5585
  {
@@ -4625,7 +5606,7 @@ export class ClassDynamicDispatch {
4625
5606
  }
4626
5607
  if (field && info.def.tracksOwnFields) {
4627
5608
  const instance = lowerer.coerceToExpected(receiver, DYN);
4628
- const bag = this.readPropertyBagOrEmpty(lowerer, instance, loc);
5609
+ const bag = this.branchPropertyBag(lowerer, info, receiver, true, loc);
4629
5610
  const symbol = symbolMemberKey(lowerer, info, name, loc);
4630
5611
  const key = symbol ?? { kind: "strLit", value: name, type: STRING, loc };
4631
5612
  return [
@@ -4730,6 +5711,50 @@ export class ClassDynamicDispatch {
4730
5711
  };
4731
5712
  return [store, { kind: "return", value: null, loc }];
4732
5713
  }
5714
+ /** EventEmitter.prototype's introspection and bookkeeping members on an
5715
+ * emitter seen through an untyped value: Node's results over the native
5716
+ * listener registry. */
5717
+ emitterIntrospection(lowerer, dispatch, receiver) {
5718
+ const { method, loc } = dispatch.source;
5719
+ const incoming = dispatch.source.args.map((_, i) => varRef(`p.${i + 1}`, DYN, loc));
5720
+ const ret = (value) => [
5721
+ { kind: "return", value: lowerer.coerceToExpected(value, DYN), loc },
5722
+ ];
5723
+ const call = (fn, args, type) => ({
5724
+ kind: "libCall",
5725
+ fn,
5726
+ args: [receiver, ...args],
5727
+ type,
5728
+ loc,
5729
+ });
5730
+ // Node indexes _events with the argument itself: an omitted name is
5731
+ // the key "undefined".
5732
+ const eventName = () => incoming.length
5733
+ ? lowerer.coerceToExpected(incoming[0], STRING)
5734
+ : { kind: "strLit", value: "undefined", type: STRING, loc };
5735
+ switch (method) {
5736
+ case "listenerCount":
5737
+ return ret(incoming.length >= 2
5738
+ ? call("emitter.countDyn", [eventName(), incoming[1]], F64)
5739
+ : call("emitter.count", [eventName()], F64));
5740
+ case "eventNames":
5741
+ return ret(call("emitter.names", [], { kind: "array", elem: STRING }));
5742
+ case "removeAllListeners":
5743
+ return ret(incoming.length
5744
+ ? call("emitter.removeAll", [eventName(), { kind: "boolLit", value: false, type: BOOL, loc }], receiver.type)
5745
+ : call("emitter.removeAll", [
5746
+ { kind: "strLit", value: "", type: STRING, loc },
5747
+ { kind: "boolLit", value: true, type: BOOL, loc },
5748
+ ], receiver.type));
5749
+ case "listeners":
5750
+ case "rawListeners":
5751
+ return ret(call("emitter.listenersDyn", [eventName()], DYN));
5752
+ case "setMaxListeners":
5753
+ return ret(call("emitter.setMaxChk", [incoming[0] ?? dynUndefinedExpr(loc)], receiver.type));
5754
+ default:
5755
+ return ret(call("emitter.getMax", [], F64));
5756
+ }
5757
+ }
4733
5758
  methodBody(lowerer, dispatch, info, receiver) {
4734
5759
  const { method, loc } = dispatch.source;
4735
5760
  const fence = () => [
@@ -4740,6 +5765,12 @@ export class ClassDynamicDispatch {
4740
5765
  loc,
4741
5766
  },
4742
5767
  ];
5768
+ if (emitterRooted(lowerer, info) &&
5769
+ !streamRooted(info) &&
5770
+ EMITTER_INTROSPECTION_METHODS.has(method) &&
5771
+ !findMethodOn(lowerer, info, method)) {
5772
+ return this.emitterIntrospection(lowerer, dispatch, receiver);
5773
+ }
4743
5774
  if (info.builtinStream ||
4744
5775
  (emitterRooted(lowerer, info) &&
4745
5776
  EMITTER_METHODS.has(method) &&
@@ -4759,10 +5790,14 @@ export class ClassDynamicDispatch {
4759
5790
  if (method === "emit") {
4760
5791
  if (!incoming.length)
4761
5792
  return fence();
4762
- return ret({
5793
+ const event = lowerer.coerceToExpected(incoming[0], STRING);
5794
+ const bridged = streamRooted(info)
5795
+ ? null
5796
+ : lowerDynamicEmitterEmit(lowerer, receiver, event, incoming.slice(1), loc);
5797
+ return ret(bridged ?? {
4763
5798
  kind: "libCall",
4764
- fn: "emitter.emitFlex",
4765
- args: [receiver, lowerer.coerceToExpected(incoming[0], STRING), ...incoming.slice(1)],
5799
+ fn: "emitter.emitAny",
5800
+ args: [receiver, event, ...incoming.slice(1)],
4766
5801
  type: BOOL,
4767
5802
  loc,
4768
5803
  });
@@ -4772,6 +5807,11 @@ export class ClassDynamicDispatch {
4772
5807
  return fence();
4773
5808
  const event = lowerer.coerceToExpected(incoming[0], STRING);
4774
5809
  const cb = incoming[1];
5810
+ const bridged = registering && !streamRooted(info)
5811
+ ? lowerDynamicEmitterOn(lowerer, receiver, event, cb, method === "once" || method === "prependOnceListener", method.startsWith("prepend"), loc)
5812
+ : null;
5813
+ if (bridged)
5814
+ return ret(bridged);
4775
5815
  return [
4776
5816
  {
4777
5817
  kind: "exprStmt",
@@ -4783,7 +5823,7 @@ export class ClassDynamicDispatch {
4783
5823
  fn: registering
4784
5824
  ? info.builtinStream
4785
5825
  ? "stream.onDyn"
4786
- : "emitter.onFlex"
5826
+ : "emitter.onAny"
4787
5827
  : "emitter.offDyn",
4788
5828
  args: [
4789
5829
  receiver,
@@ -4837,13 +5877,16 @@ export class ClassDynamicDispatch {
4837
5877
  const arg = (i) => incoming[i] ?? dynUndefinedExpr(loc);
4838
5878
  const readableT = { kind: "object", className: "%Readable" };
4839
5879
  const op = (fn, args, type) => ret({ kind: "libCall", fn: fn, args: [receiver, ...args], type, loc });
5880
+ // Node passes every callback its { signal }; the callback's
5881
+ // declared parameters are not known here.
5882
+ const sig = () => operatorSignalOptions(lowerer, arg(1), loc);
4840
5883
  switch (method) {
4841
5884
  case "map":
4842
- return op("readable.opMap", [arg(0), arg(1)], readableT);
5885
+ return op("readable.opMap", [arg(0), arg(1), sig()], readableT);
4843
5886
  case "filter":
4844
- return op("readable.opFilter", [arg(0), arg(1)], readableT);
5887
+ return op("readable.opFilter", [arg(0), arg(1), sig()], readableT);
4845
5888
  case "flatMap":
4846
- return op("readable.opFlatMap", [arg(0), arg(1)], readableT);
5889
+ return op("readable.opFlatMap", [arg(0), arg(1), sig()], readableT);
4847
5890
  case "drop":
4848
5891
  return op("readable.opDrop", [arg(0), arg(1)], readableT);
4849
5892
  case "take":
@@ -4851,21 +5894,45 @@ export class ClassDynamicDispatch {
4851
5894
  case "toArray":
4852
5895
  return op("readable.opToArray", [arg(0)], { kind: "promise", inner: DYN });
4853
5896
  case "forEach":
4854
- return op("readable.opForEach", [arg(0), arg(1)], { kind: "promise", inner: VOID });
5897
+ return op("readable.opForEach", [arg(0), arg(1), sig()], {
5898
+ kind: "promise",
5899
+ inner: VOID,
5900
+ });
4855
5901
  case "some":
4856
- return op("readable.opSome", [arg(0), arg(1)], { kind: "promise", inner: BOOL });
5902
+ return op("readable.opSome", [arg(0), arg(1), sig()], { kind: "promise", inner: BOOL });
4857
5903
  case "every":
4858
- return op("readable.opEvery", [arg(0), arg(1)], { kind: "promise", inner: BOOL });
5904
+ return op("readable.opEvery", [arg(0), arg(1), sig()], {
5905
+ kind: "promise",
5906
+ inner: BOOL,
5907
+ });
4859
5908
  case "find":
4860
- return op("readable.opFind", [arg(0), arg(1)], { kind: "promise", inner: DYN });
4861
- case "reduce":
4862
- return op("readable.opReduce", [
4863
- arg(0),
4864
- arg(1),
4865
- { kind: "boolLit", value: dispatch.source.args.length >= 2, type: BOOL, loc },
4866
- arg(2),
4867
- { kind: "numLit", value: 0, type: F64, loc },
4868
- ], { kind: "promise", inner: DYN });
5909
+ return op("readable.opFind", [arg(0), arg(1), sig()], { kind: "promise", inner: DYN });
5910
+ case "reduce": {
5911
+ // the dispatch function's locals: there is no function
5912
+ // context while dispatch bodies are built
5913
+ const setup = reduceSignalSetup(lowerer, arg(2), loc, (name, type) => {
5914
+ const local = {
5915
+ id: `${name}.${dispatch.fn.locals.length}`,
5916
+ name,
5917
+ type,
5918
+ mutable: false,
5919
+ };
5920
+ dispatch.fn.locals.push(local);
5921
+ return local;
5922
+ });
5923
+ return [
5924
+ ...setup.stmts,
5925
+ ...op("readable.opReduceSignal", [
5926
+ arg(0),
5927
+ arg(1),
5928
+ { kind: "boolLit", value: dispatch.source.args.length >= 2, type: BOOL, loc },
5929
+ arg(2),
5930
+ { kind: "numLit", value: 0, type: F64, loc },
5931
+ setup.abort,
5932
+ setup.cbOpts,
5933
+ ], { kind: "promise", inner: DYN }),
5934
+ ];
5935
+ }
4869
5936
  }
4870
5937
  }
4871
5938
  if (method === "destroy" && (!incoming.length || incoming[0]?.kind === "unitLit"))
@@ -5113,4 +6180,12 @@ const INHERITED_OBJECT_METHODS = new Set([
5113
6180
  "hasOwnProperty",
5114
6181
  "propertyIsEnumerable",
5115
6182
  ]);
6183
+ /** Whether a class or one of its bases has a heritage evaluated at run
6184
+ * time, whose prototype chain may reach Error.prototype. */
6185
+ function hasRuntimeHeritage(info) {
6186
+ for (let current = info; current; current = current.base)
6187
+ if (current.callableBase)
6188
+ return true;
6189
+ return false;
6190
+ }
5116
6191
  //# sourceMappingURL=class-dynamic-dispatch.js.map