@scriptc/compiler 0.4.6 → 0.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1082) hide show
  1. package/ambient/node-fallback/child_process.d.ts +71 -22
  2. package/ambient/node-fallback/crypto.d.ts +15 -7
  3. package/ambient/node-fallback/events.d.ts +29 -6
  4. package/ambient/node-fallback/fs-promises.d.ts +1 -1
  5. package/ambient/node-fallback/fs.d.ts +57 -12
  6. package/ambient/node-fallback/http.d.ts +26 -18
  7. package/ambient/node-fallback/https.d.ts +5 -2
  8. package/ambient/node-fallback/net.d.ts +25 -0
  9. package/ambient/node-fallback/os.d.ts +11 -1
  10. package/ambient/node-fallback/path-posix.d.ts +6 -0
  11. package/ambient/node-fallback/path-win32.d.ts +5 -0
  12. package/ambient/node-fallback/path.d.ts +2 -0
  13. package/ambient/node-fallback/querystring.d.ts +3 -3
  14. package/ambient/node-fallback/zlib.d.ts +31 -2
  15. package/ambient/scriptc-node-fallback.d.ts +95 -20
  16. package/ambient/scriptc.d.ts +7 -2
  17. package/dist/backend/executable-features.js +22 -1
  18. package/dist/backend/executable-features.js.map +1 -1
  19. package/dist/backend/immutability.d.ts +12 -1
  20. package/dist/backend/immutability.js +50 -4
  21. package/dist/backend/immutability.js.map +1 -1
  22. package/dist/backend/immutability.test.js +95 -1
  23. package/dist/backend/immutability.test.js.map +1 -1
  24. package/dist/backend/library-pack.d.ts +6 -0
  25. package/dist/backend/library-pack.js +18 -5
  26. package/dist/backend/library-pack.js.map +1 -1
  27. package/dist/backend/library-pack.test.d.ts +1 -0
  28. package/dist/backend/library-pack.test.js +28 -0
  29. package/dist/backend/library-pack.test.js.map +1 -0
  30. package/dist/backend/linker.d.ts +20 -2
  31. package/dist/backend/linker.js +221 -35
  32. package/dist/backend/linker.js.map +1 -1
  33. package/dist/backend/lld.d.ts +15 -6
  34. package/dist/backend/lld.js +24 -16
  35. package/dist/backend/lld.js.map +1 -1
  36. package/dist/backend/lld.test.js +13 -5
  37. package/dist/backend/lld.test.js.map +1 -1
  38. package/dist/backend/llvm/alloc.d.ts +15 -2
  39. package/dist/backend/llvm/alloc.js +172 -36
  40. package/dist/backend/llvm/alloc.js.map +1 -1
  41. package/dist/backend/llvm/alloc.test.js +69 -1
  42. package/dist/backend/llvm/alloc.test.js.map +1 -1
  43. package/dist/backend/llvm/arenas.d.ts +17 -4
  44. package/dist/backend/llvm/arenas.js +105 -10
  45. package/dist/backend/llvm/arenas.js.map +1 -1
  46. package/dist/backend/llvm/arenas.test.js +229 -0
  47. package/dist/backend/llvm/arenas.test.js.map +1 -1
  48. package/dist/backend/llvm/bytes-alias.js +10 -1
  49. package/dist/backend/llvm/bytes-alias.js.map +1 -1
  50. package/dist/backend/llvm/bytes-headers.js +6 -0
  51. package/dist/backend/llvm/bytes-headers.js.map +1 -1
  52. package/dist/backend/llvm/bytes-loop-versions.test.js +25 -0
  53. package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -1
  54. package/dist/backend/llvm/call-lifetimes.js +10 -0
  55. package/dist/backend/llvm/call-lifetimes.js.map +1 -1
  56. package/dist/backend/llvm/classes.d.ts +16 -9
  57. package/dist/backend/llvm/classes.js +142 -37
  58. package/dist/backend/llvm/classes.js.map +1 -1
  59. package/dist/backend/llvm/classes.test.js +42 -0
  60. package/dist/backend/llvm/classes.test.js.map +1 -1
  61. package/dist/backend/llvm/constant-callbacks.test.js +50 -1
  62. package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
  63. package/dist/backend/llvm/cpu-dispatch.d.ts +15 -5
  64. package/dist/backend/llvm/cpu-dispatch.js +34 -9
  65. package/dist/backend/llvm/cpu-dispatch.js.map +1 -1
  66. package/dist/backend/llvm/dyn.d.ts +64 -3
  67. package/dist/backend/llvm/dyn.js +251 -15
  68. package/dist/backend/llvm/dyn.js.map +1 -1
  69. package/dist/backend/llvm/emit-function.js +68 -5
  70. package/dist/backend/llvm/emit-function.js.map +1 -1
  71. package/dist/backend/llvm/emit-module.js +226 -77
  72. package/dist/backend/llvm/emit-module.js.map +1 -1
  73. package/dist/backend/llvm/emit-module.test.d.ts +1 -0
  74. package/dist/backend/llvm/emit-module.test.js +52 -0
  75. package/dist/backend/llvm/emit-module.test.js.map +1 -0
  76. package/dist/backend/llvm/emit-statements.js +138 -34
  77. package/dist/backend/llvm/emit-statements.js.map +1 -1
  78. package/dist/backend/llvm/emitter.d.ts +142 -10
  79. package/dist/backend/llvm/emitter.js +523 -73
  80. package/dist/backend/llvm/emitter.js.map +1 -1
  81. package/dist/backend/llvm/emitter.test.js +31 -3
  82. package/dist/backend/llvm/emitter.test.js.map +1 -1
  83. package/dist/backend/llvm/expr-async.js +19 -1
  84. package/dist/backend/llvm/expr-async.js.map +1 -1
  85. package/dist/backend/llvm/expr-bytes.js +16 -1
  86. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  87. package/dist/backend/llvm/expr-calls.d.ts +4 -1
  88. package/dist/backend/llvm/expr-calls.js +38 -6
  89. package/dist/backend/llvm/expr-calls.js.map +1 -1
  90. package/dist/backend/llvm/expr-dynamic.js +237 -23
  91. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  92. package/dist/backend/llvm/expr-primitives.js +123 -12
  93. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  94. package/dist/backend/llvm/expr-records.d.ts +1 -1
  95. package/dist/backend/llvm/expr-records.js +124 -56
  96. package/dist/backend/llvm/expr-records.js.map +1 -1
  97. package/dist/backend/llvm/expr-stream-bridges.d.ts +8 -0
  98. package/dist/backend/llvm/expr-stream-bridges.js +59 -2
  99. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  100. package/dist/backend/llvm/expr-stream-callbacks.d.ts +16 -0
  101. package/dist/backend/llvm/expr-stream-callbacks.js +206 -20
  102. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  103. package/dist/backend/llvm/integer-values.d.ts +2 -0
  104. package/dist/backend/llvm/integer-values.js +6 -0
  105. package/dist/backend/llvm/integer-values.js.map +1 -1
  106. package/dist/backend/llvm/js-groups.d.ts +21 -0
  107. package/dist/backend/llvm/js-groups.js +277 -0
  108. package/dist/backend/llvm/js-groups.js.map +1 -0
  109. package/dist/backend/llvm/js-ic.d.ts +57 -1
  110. package/dist/backend/llvm/js-ic.js +389 -22
  111. package/dist/backend/llvm/js-ic.js.map +1 -1
  112. package/dist/backend/llvm/lib-dispatch.js +152 -1
  113. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  114. package/dist/backend/llvm/lib-filesystem.js +116 -11
  115. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  116. package/dist/backend/llvm/lib-network.js +33 -6
  117. package/dist/backend/llvm/lib-network.js.map +1 -1
  118. package/dist/backend/llvm/lib-process.js +180 -27
  119. package/dist/backend/llvm/lib-process.js.map +1 -1
  120. package/dist/backend/llvm/lib-shared.js +139 -2
  121. package/dist/backend/llvm/lib-shared.js.map +1 -1
  122. package/dist/backend/llvm/lib-stream.js +67 -0
  123. package/dist/backend/llvm/lib-stream.js.map +1 -1
  124. package/dist/backend/llvm/local-union-storage.test.js +32 -0
  125. package/dist/backend/llvm/local-union-storage.test.js.map +1 -1
  126. package/dist/backend/llvm/loop-entry-versions.d.ts +2 -2
  127. package/dist/backend/llvm/loop-entry-versions.js +43 -21
  128. package/dist/backend/llvm/loop-entry-versions.js.map +1 -1
  129. package/dist/backend/llvm/loop-state.d.ts +7 -1
  130. package/dist/backend/llvm/loop-state.js +26 -3
  131. package/dist/backend/llvm/loop-state.js.map +1 -1
  132. package/dist/backend/llvm/map-entry-fusion.d.ts +8 -0
  133. package/dist/backend/llvm/map-entry-fusion.js +3 -3
  134. package/dist/backend/llvm/map-entry-fusion.js.map +1 -1
  135. package/dist/backend/llvm/map-number-lookup.d.ts +3 -1
  136. package/dist/backend/llvm/map-number-lookup.js +7 -3
  137. package/dist/backend/llvm/map-number-lookup.js.map +1 -1
  138. package/dist/backend/llvm/map-number-lookup.test.js +58 -17
  139. package/dist/backend/llvm/map-number-lookup.test.js.map +1 -1
  140. package/dist/backend/llvm/nullable-unions.js +7 -6
  141. package/dist/backend/llvm/nullable-unions.js.map +1 -1
  142. package/dist/backend/llvm/nullable-unions.test.js +4 -1
  143. package/dist/backend/llvm/nullable-unions.test.js.map +1 -1
  144. package/dist/backend/llvm/receiver-brackets.test.d.ts +1 -0
  145. package/dist/backend/llvm/receiver-brackets.test.js +68 -0
  146. package/dist/backend/llvm/receiver-brackets.test.js.map +1 -0
  147. package/dist/backend/llvm/receivers.js +3 -0
  148. package/dist/backend/llvm/receivers.js.map +1 -1
  149. package/dist/backend/llvm/record-entry-fusion.d.ts +32 -0
  150. package/dist/backend/llvm/record-entry-fusion.js +217 -0
  151. package/dist/backend/llvm/record-entry-fusion.js.map +1 -0
  152. package/dist/backend/llvm/record-results.d.ts +5 -2
  153. package/dist/backend/llvm/record-results.js +13 -12
  154. package/dist/backend/llvm/record-results.js.map +1 -1
  155. package/dist/backend/llvm/record-views.d.ts +22 -2
  156. package/dist/backend/llvm/record-views.js +147 -12
  157. package/dist/backend/llvm/record-views.js.map +1 -1
  158. package/dist/backend/llvm/record-views.test.js +76 -0
  159. package/dist/backend/llvm/record-views.test.js.map +1 -1
  160. package/dist/backend/llvm/reference-effects.js +1 -0
  161. package/dist/backend/llvm/reference-effects.js.map +1 -1
  162. package/dist/backend/llvm/reference-writes.js +4 -0
  163. package/dist/backend/llvm/reference-writes.js.map +1 -1
  164. package/dist/backend/llvm/region-ir.js +1 -0
  165. package/dist/backend/llvm/region-ir.js.map +1 -1
  166. package/dist/backend/llvm/region-sites.d.ts +18 -0
  167. package/dist/backend/llvm/region-sites.js +79 -1
  168. package/dist/backend/llvm/region-sites.js.map +1 -1
  169. package/dist/backend/llvm/runtime-registries.test.js +53 -6
  170. package/dist/backend/llvm/runtime-registries.test.js.map +1 -1
  171. package/dist/backend/llvm/serialized-ir-emission.test.js +3 -1
  172. package/dist/backend/llvm/serialized-ir-emission.test.js.map +1 -1
  173. package/dist/backend/llvm/shapes.d.ts +36 -3
  174. package/dist/backend/llvm/shapes.js +201 -16
  175. package/dist/backend/llvm/shapes.js.map +1 -1
  176. package/dist/backend/llvm/shapes.test.js +4 -0
  177. package/dist/backend/llvm/shapes.test.js.map +1 -1
  178. package/dist/backend/llvm/speculative-integers.d.ts +10 -1
  179. package/dist/backend/llvm/speculative-integers.js +59 -8
  180. package/dist/backend/llvm/speculative-integers.js.map +1 -1
  181. package/dist/backend/llvm/stack-objects.d.ts +1 -2
  182. package/dist/backend/llvm/stack-objects.js +8 -5
  183. package/dist/backend/llvm/stack-objects.js.map +1 -1
  184. package/dist/backend/llvm/unwind-abi.d.ts +3 -3
  185. package/dist/backend/llvm/unwind-abi.js +8 -3
  186. package/dist/backend/llvm/unwind-abi.js.map +1 -1
  187. package/dist/backend/llvm/walkers.d.ts +12 -0
  188. package/dist/backend/llvm/walkers.js +47 -3
  189. package/dist/backend/llvm/walkers.js.map +1 -1
  190. package/dist/backend/may-throw.js +12 -2
  191. package/dist/backend/may-throw.js.map +1 -1
  192. package/dist/backend/may-throw.test.js +13 -0
  193. package/dist/backend/may-throw.test.js.map +1 -1
  194. package/dist/backend/native/contracts.d.ts +94 -0
  195. package/dist/backend/native/executable.js +134 -10
  196. package/dist/backend/native/executable.js.map +1 -1
  197. package/dist/backend/native/helper-identity-record.d.ts +11 -0
  198. package/dist/backend/native/helper-identity-record.js +76 -0
  199. package/dist/backend/native/helper-identity-record.js.map +1 -0
  200. package/dist/backend/native/helper-identity-record.test.d.ts +1 -0
  201. package/dist/backend/native/helper-identity-record.test.js +101 -0
  202. package/dist/backend/native/helper-identity-record.test.js.map +1 -0
  203. package/dist/backend/native/library.js +10 -2
  204. package/dist/backend/native/library.js.map +1 -1
  205. package/dist/backend/native/runtime-inputs.js +8 -1
  206. package/dist/backend/native/runtime-inputs.js.map +1 -1
  207. package/dist/backend/native/vendor.d.ts +1 -1
  208. package/dist/backend/native/vendor.js +1 -1
  209. package/dist/backend/native/vendor.js.map +1 -1
  210. package/dist/backend/native-codegen-core.d.ts +13 -10
  211. package/dist/backend/native-codegen-core.js +26 -13
  212. package/dist/backend/native-codegen-core.js.map +1 -1
  213. package/dist/backend/native-codegen.js +30 -8
  214. package/dist/backend/native-codegen.js.map +1 -1
  215. package/dist/backend/native-codegen.test.js +110 -14
  216. package/dist/backend/native-codegen.test.js.map +1 -1
  217. package/dist/backend/native-link-info-core.d.ts +72 -0
  218. package/dist/backend/native-link-info-core.js.map +1 -1
  219. package/dist/backend/native-link-info.js +1 -0
  220. package/dist/backend/native-link-info.js.map +1 -1
  221. package/dist/backend/native-profile.d.ts +4 -1
  222. package/dist/backend/native-profile.js +12 -1
  223. package/dist/backend/native-profile.js.map +1 -1
  224. package/dist/backend/native-profile.test.js +10 -0
  225. package/dist/backend/native-profile.test.js.map +1 -1
  226. package/dist/backend/publication.d.ts +4 -1
  227. package/dist/backend/publication.js +4 -2
  228. package/dist/backend/publication.js.map +1 -1
  229. package/dist/backend/runtime-abi.d.ts +2 -2
  230. package/dist/backend/runtime-abi.js +2 -2
  231. package/dist/backend/runtime-pack-core.d.ts +46 -7
  232. package/dist/backend/runtime-pack-core.js +37 -2
  233. package/dist/backend/runtime-pack-core.js.map +1 -1
  234. package/dist/backend/runtime-pack-native.d.ts +18 -1
  235. package/dist/backend/runtime-pack-native.js +138 -29
  236. package/dist/backend/runtime-pack-native.js.map +1 -1
  237. package/dist/backend/runtime-pack-native.test.js +166 -4
  238. package/dist/backend/runtime-pack-native.test.js.map +1 -1
  239. package/dist/backend/runtime-pack-targets.test.js +3 -1
  240. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  241. package/dist/backend/runtime-pack.d.ts +7 -0
  242. package/dist/backend/runtime-pack.js +25 -3
  243. package/dist/backend/runtime-pack.js.map +1 -1
  244. package/dist/backend/runtime-pack.test.js +213 -12
  245. package/dist/backend/runtime-pack.test.js.map +1 -1
  246. package/dist/backend/tree-classes.d.ts +42 -0
  247. package/dist/backend/tree-classes.js +723 -0
  248. package/dist/backend/tree-classes.js.map +1 -0
  249. package/dist/backend/tree-classes.test.d.ts +1 -0
  250. package/dist/backend/tree-classes.test.js +338 -0
  251. package/dist/backend/tree-classes.test.js.map +1 -0
  252. package/dist/backend/vendor-archives.d.ts +8 -1
  253. package/dist/backend/vendor-archives.js +313 -8
  254. package/dist/backend/vendor-archives.js.map +1 -1
  255. package/dist/backend/vendor-inputs.d.ts +60 -3
  256. package/dist/backend/vendor-inputs.js +109 -3
  257. package/dist/backend/vendor-inputs.js.map +1 -1
  258. package/dist/backend/vendor-inputs.test.js +62 -1
  259. package/dist/backend/vendor-inputs.test.js.map +1 -1
  260. package/dist/backend/warm-cache.js +2 -0
  261. package/dist/backend/warm-cache.js.map +1 -1
  262. package/dist/compat/fetch-profile.d.ts +7 -1
  263. package/dist/compat/fetch-profile.js +25 -12
  264. package/dist/compat/fetch-profile.js.map +1 -1
  265. package/dist/compile-types.d.ts +7 -0
  266. package/dist/contracts/check.d.ts +3 -0
  267. package/dist/contracts/check.js +18 -5
  268. package/dist/contracts/check.js.map +1 -1
  269. package/dist/coverage/report.js +47 -0
  270. package/dist/coverage/report.js.map +1 -1
  271. package/dist/coverage/surface-manifest.js +1 -1
  272. package/dist/coverage/surface-manifest.js.map +1 -1
  273. package/dist/diagnostics/codes.d.ts +14 -0
  274. package/dist/diagnostics/codes.js +14 -0
  275. package/dist/diagnostics/codes.js.map +1 -1
  276. package/dist/diagnostics/diagnostic.d.ts +68 -0
  277. package/dist/diagnostics/diagnostic.js +186 -6
  278. package/dist/diagnostics/diagnostic.js.map +1 -1
  279. package/dist/diagnostics/dynamic-tier.js +3 -1
  280. package/dist/diagnostics/dynamic-tier.js.map +1 -1
  281. package/dist/diagnostics/envelope.d.ts +18 -0
  282. package/dist/diagnostics/envelope.js.map +1 -1
  283. package/dist/executable/executable-cache.d.ts +48 -0
  284. package/dist/executable/executable-cache.js +38 -0
  285. package/dist/executable/executable-cache.js.map +1 -1
  286. package/dist/executable/executable-cache.test.js +127 -1
  287. package/dist/executable/executable-cache.test.js.map +1 -1
  288. package/dist/executable/prepare.d.ts +13 -3
  289. package/dist/executable/prepare.js +438 -234
  290. package/dist/executable/prepare.js.map +1 -1
  291. package/dist/frontend/analysis.js +200 -18
  292. package/dist/frontend/analysis.js.map +1 -1
  293. package/dist/frontend/builtin-modules.d.ts +4 -0
  294. package/dist/frontend/builtin-modules.js +10 -0
  295. package/dist/frontend/builtin-modules.js.map +1 -1
  296. package/dist/frontend/early-errors.d.ts +24 -0
  297. package/dist/frontend/early-errors.js +836 -0
  298. package/dist/frontend/early-errors.js.map +1 -0
  299. package/dist/frontend/early-errors.test.d.ts +1 -0
  300. package/dist/frontend/early-errors.test.js +207 -0
  301. package/dist/frontend/early-errors.test.js.map +1 -0
  302. package/dist/frontend/inferred-js-diagnostics.test.js +88 -0
  303. package/dist/frontend/inferred-js-diagnostics.test.js.map +1 -1
  304. package/dist/frontend/input-tracker.d.ts +47 -0
  305. package/dist/frontend/input-tracker.js +173 -36
  306. package/dist/frontend/input-tracker.js.map +1 -1
  307. package/dist/frontend/input-tracker.test.js +86 -2
  308. package/dist/frontend/input-tracker.test.js.map +1 -1
  309. package/dist/frontend/js-inference.d.ts +2 -0
  310. package/dist/frontend/js-inference.js +18 -0
  311. package/dist/frontend/js-inference.js.map +1 -0
  312. package/dist/frontend/jsx-opinion-sites.test.d.ts +1 -0
  313. package/dist/frontend/jsx-opinion-sites.test.js +86 -0
  314. package/dist/frontend/jsx-opinion-sites.test.js.map +1 -0
  315. package/dist/frontend/lib-exports.d.ts +23 -4
  316. package/dist/frontend/lib-exports.js +98 -26
  317. package/dist/frontend/lib-exports.js.map +1 -1
  318. package/dist/frontend/lowering/binding-analysis.d.ts +2 -1
  319. package/dist/frontend/lowering/binding-analysis.js +86 -4
  320. package/dist/frontend/lowering/binding-analysis.js.map +1 -1
  321. package/dist/frontend/lowering/buffers.d.ts +8 -0
  322. package/dist/frontend/lowering/buffers.js +43 -0
  323. package/dist/frontend/lowering/buffers.js.map +1 -0
  324. package/dist/frontend/lowering/builtin-calls.js +13 -0
  325. package/dist/frontend/lowering/builtin-calls.js.map +1 -1
  326. package/dist/frontend/lowering/builtin-namespaces.d.ts +3 -2
  327. package/dist/frontend/lowering/builtin-namespaces.js +41 -3
  328. package/dist/frontend/lowering/builtin-namespaces.js.map +1 -1
  329. package/dist/frontend/lowering/builtin-statics.d.ts +24 -0
  330. package/dist/frontend/lowering/builtin-statics.js +407 -0
  331. package/dist/frontend/lowering/builtin-statics.js.map +1 -0
  332. package/dist/frontend/lowering/builtins/arguments.d.ts +4 -0
  333. package/dist/frontend/lowering/builtins/arguments.js +12 -0
  334. package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
  335. package/dist/frontend/lowering/builtins/atomics.d.ts +6 -1
  336. package/dist/frontend/lowering/builtins/atomics.js +87 -1
  337. package/dist/frontend/lowering/builtins/atomics.js.map +1 -1
  338. package/dist/frontend/lowering/builtins/child-process-methods.d.ts +7 -0
  339. package/dist/frontend/lowering/builtins/child-process-methods.js +52 -12
  340. package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
  341. package/dist/frontend/lowering/builtins/child-process-sync.d.ts +13 -0
  342. package/dist/frontend/lowering/builtins/child-process-sync.js +1 -13
  343. package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -1
  344. package/dist/frontend/lowering/builtins/child-process.d.ts +10 -4
  345. package/dist/frontend/lowering/builtins/child-process.js +565 -28
  346. package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
  347. package/dist/frontend/lowering/builtins/compression.d.ts +2 -2
  348. package/dist/frontend/lowering/builtins/compression.js +41 -21
  349. package/dist/frontend/lowering/builtins/compression.js.map +1 -1
  350. package/dist/frontend/lowering/builtins/constants.js +7 -2
  351. package/dist/frontend/lowering/builtins/constants.js.map +1 -1
  352. package/dist/frontend/lowering/builtins/dates.d.ts +1 -1
  353. package/dist/frontend/lowering/builtins/dates.js +23 -1
  354. package/dist/frontend/lowering/builtins/dates.js.map +1 -1
  355. package/dist/frontend/lowering/builtins/environment.d.ts +55 -0
  356. package/dist/frontend/lowering/builtins/environment.js +213 -2
  357. package/dist/frontend/lowering/builtins/environment.js.map +1 -1
  358. package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +1 -0
  359. package/dist/frontend/lowering/builtins/filesystem-calls.js +75 -18
  360. package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
  361. package/dist/frontend/lowering/builtins/filesystem.d.ts +25 -7
  362. package/dist/frontend/lowering/builtins/filesystem.js +185 -16
  363. package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
  364. package/dist/frontend/lowering/builtins/json.js +4 -0
  365. package/dist/frontend/lowering/builtins/json.js.map +1 -1
  366. package/dist/frontend/lowering/builtins/module-calls.js +42 -3
  367. package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
  368. package/dist/frontend/lowering/builtins/module-resolution.d.ts +8 -0
  369. package/dist/frontend/lowering/builtins/module-resolution.js +31 -5
  370. package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
  371. package/dist/frontend/lowering/builtins/numbers.d.ts +4 -1
  372. package/dist/frontend/lowering/builtins/numbers.js +10 -2
  373. package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
  374. package/dist/frontend/lowering/builtins/operating-system.d.ts +9 -5
  375. package/dist/frontend/lowering/builtins/operating-system.js +101 -20
  376. package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
  377. package/dist/frontend/lowering/builtins/process.d.ts +18 -2
  378. package/dist/frontend/lowering/builtins/process.js +386 -25
  379. package/dist/frontend/lowering/builtins/process.js.map +1 -1
  380. package/dist/frontend/lowering/builtins/promises.js +169 -8
  381. package/dist/frontend/lowering/builtins/promises.js.map +1 -1
  382. package/dist/frontend/lowering/builtins/properties.js +6 -2
  383. package/dist/frontend/lowering/builtins/properties.js.map +1 -1
  384. package/dist/frontend/lowering/builtins/querystring.d.ts +8 -0
  385. package/dist/frontend/lowering/builtins/querystring.js +202 -18
  386. package/dist/frontend/lowering/builtins/querystring.js.map +1 -1
  387. package/dist/frontend/lowering/builtins/readline.d.ts +6 -4
  388. package/dist/frontend/lowering/builtins/readline.js +200 -38
  389. package/dist/frontend/lowering/builtins/readline.js.map +1 -1
  390. package/dist/frontend/lowering/builtins/reflection.js +60 -1
  391. package/dist/frontend/lowering/builtins/reflection.js.map +1 -1
  392. package/dist/frontend/lowering/builtins/text-codecs.js +208 -59
  393. package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
  394. package/dist/frontend/lowering/builtins/url.js +55 -13
  395. package/dist/frontend/lowering/builtins/url.js.map +1 -1
  396. package/dist/frontend/lowering/builtins/v8.d.ts +5 -5
  397. package/dist/frontend/lowering/builtins/v8.js +7 -5
  398. package/dist/frontend/lowering/builtins/v8.js.map +1 -1
  399. package/dist/frontend/lowering/builtins/web-streams-dyn.d.ts +17 -2
  400. package/dist/frontend/lowering/builtins/web-streams-dyn.js +97 -9
  401. package/dist/frontend/lowering/builtins/web-streams-dyn.js.map +1 -1
  402. package/dist/frontend/lowering/builtins/webassembly.js +2 -0
  403. package/dist/frontend/lowering/builtins/webassembly.js.map +1 -1
  404. package/dist/frontend/lowering/call-arguments.d.ts +10 -0
  405. package/dist/frontend/lowering/call-arguments.js +37 -2
  406. package/dist/frontend/lowering/call-arguments.js.map +1 -1
  407. package/dist/frontend/lowering/call-signatures.d.ts +10 -0
  408. package/dist/frontend/lowering/call-signatures.js +180 -0
  409. package/dist/frontend/lowering/call-signatures.js.map +1 -1
  410. package/dist/frontend/lowering/cjs-exports-object.d.ts +3 -0
  411. package/dist/frontend/lowering/cjs-exports-object.js +1 -1
  412. package/dist/frontend/lowering/cjs-exports-object.js.map +1 -1
  413. package/dist/frontend/lowering/cjs-inline-require.js +5 -0
  414. package/dist/frontend/lowering/cjs-inline-require.js.map +1 -1
  415. package/dist/frontend/lowering/class-construction.d.ts +14 -2
  416. package/dist/frontend/lowering/class-construction.js +99 -5
  417. package/dist/frontend/lowering/class-construction.js.map +1 -1
  418. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +14 -0
  419. package/dist/frontend/lowering/class-dynamic-dispatch.js +1376 -1009
  420. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  421. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +158 -0
  422. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
  423. package/dist/frontend/lowering/class-protocols.js +59 -10
  424. package/dist/frontend/lowering/class-protocols.js.map +1 -1
  425. package/dist/frontend/lowering/class-prototypes.js +20 -15
  426. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  427. package/dist/frontend/lowering/class-runtime-statics.d.ts +8 -0
  428. package/dist/frontend/lowering/class-runtime-statics.js +35 -1
  429. package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
  430. package/dist/frontend/lowering/class-unions.js +21 -4
  431. package/dist/frontend/lowering/class-unions.js.map +1 -1
  432. package/dist/frontend/lowering/class-views.d.ts +13 -0
  433. package/dist/frontend/lowering/class-views.js +51 -0
  434. package/dist/frontend/lowering/class-views.js.map +1 -0
  435. package/dist/frontend/lowering/coercions/function-adapters.d.ts +15 -1
  436. package/dist/frontend/lowering/coercions/function-adapters.js +63 -10
  437. package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
  438. package/dist/frontend/lowering/coercions/state.d.ts +15 -0
  439. package/dist/frontend/lowering/coercions/state.js +24 -0
  440. package/dist/frontend/lowering/coercions/state.js.map +1 -1
  441. package/dist/frontend/lowering/coercions/structural-plans.js +75 -3
  442. package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
  443. package/dist/frontend/lowering/coercions/structural.js +39 -2
  444. package/dist/frontend/lowering/coercions/structural.js.map +1 -1
  445. package/dist/frontend/lowering/coercions/unions.d.ts +2 -1
  446. package/dist/frontend/lowering/coercions/unions.js +54 -10
  447. package/dist/frontend/lowering/coercions/unions.js.map +1 -1
  448. package/dist/frontend/lowering/constructor-returns.d.ts +23 -2
  449. package/dist/frontend/lowering/constructor-returns.js +284 -58
  450. package/dist/frontend/lowering/constructor-returns.js.map +1 -1
  451. package/dist/frontend/lowering/containers/array-callbacks.d.ts +8 -1
  452. package/dist/frontend/lowering/containers/array-callbacks.js +288 -90
  453. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  454. package/dist/frontend/lowering/containers/array-construction.js +37 -8
  455. package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
  456. package/dist/frontend/lowering/containers/array-from-async.js +139 -3
  457. package/dist/frontend/lowering/containers/array-from-async.js.map +1 -1
  458. package/dist/frontend/lowering/containers/array-iteration.d.ts +14 -4
  459. package/dist/frontend/lowering/containers/array-iteration.js +24 -7
  460. package/dist/frontend/lowering/containers/array-iteration.js.map +1 -1
  461. package/dist/frontend/lowering/containers/array-methods.js +30 -11
  462. package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
  463. package/dist/frontend/lowering/containers/bytes.d.ts +6 -0
  464. package/dist/frontend/lowering/containers/bytes.js +450 -86
  465. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  466. package/dist/frontend/lowering/containers/callback-arguments.d.ts +16 -0
  467. package/dist/frontend/lowering/containers/callback-arguments.js +74 -12
  468. package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
  469. package/dist/frontend/lowering/containers/collection-grouping.js +421 -2
  470. package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
  471. package/dist/frontend/lowering/containers/collection-methods.js +52 -17
  472. package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
  473. package/dist/frontend/lowering/containers/filter-predicates.d.ts +10 -0
  474. package/dist/frontend/lowering/containers/filter-predicates.js +69 -3
  475. package/dist/frontend/lowering/containers/filter-predicates.js.map +1 -1
  476. package/dist/frontend/lowering/containers/indexed-objects.js +46 -2
  477. package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
  478. package/dist/frontend/lowering/containers/iterator-helpers.d.ts +23 -0
  479. package/dist/frontend/lowering/containers/iterator-helpers.js +176 -10
  480. package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -1
  481. package/dist/frontend/lowering/containers/string-and-regexp.d.ts +5 -2
  482. package/dist/frontend/lowering/containers/string-and-regexp.js +45 -11
  483. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  484. package/dist/frontend/lowering/crypto-tables.d.ts +3 -3
  485. package/dist/frontend/lowering/crypto-tables.js +5 -5
  486. package/dist/frontend/lowering/dispatch-sites.js +3 -0
  487. package/dist/frontend/lowering/dispatch-sites.js.map +1 -1
  488. package/dist/frontend/lowering/divergences.d.ts +40 -0
  489. package/dist/frontend/lowering/divergences.js +239 -20
  490. package/dist/frontend/lowering/divergences.js.map +1 -1
  491. package/dist/frontend/lowering/effect-free.d.ts +12 -0
  492. package/dist/frontend/lowering/effect-free.js +44 -0
  493. package/dist/frontend/lowering/effect-free.js.map +1 -0
  494. package/dist/frontend/lowering/expressions/array-literals.d.ts +24 -0
  495. package/dist/frontend/lowering/expressions/array-literals.js +88 -10
  496. package/dist/frontend/lowering/expressions/array-literals.js.map +1 -1
  497. package/dist/frontend/lowering/expressions/binary.js +216 -14
  498. package/dist/frontend/lowering/expressions/binary.js.map +1 -1
  499. package/dist/frontend/lowering/expressions/element-access.js +272 -11
  500. package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
  501. package/dist/frontend/lowering/expressions/hosted-narrowing.d.ts +15 -0
  502. package/dist/frontend/lowering/expressions/hosted-narrowing.js +54 -1
  503. package/dist/frontend/lowering/expressions/hosted-narrowing.js.map +1 -1
  504. package/dist/frontend/lowering/expressions/identifiers.js +173 -4
  505. package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
  506. package/dist/frontend/lowering/expressions/keyed-field-targets.d.ts +11 -1
  507. package/dist/frontend/lowering/expressions/keyed-field-targets.js +22 -1
  508. package/dist/frontend/lowering/expressions/keyed-field-targets.js.map +1 -1
  509. package/dist/frontend/lowering/expressions/narrowing.d.ts +3 -0
  510. package/dist/frontend/lowering/expressions/narrowing.js +195 -18
  511. package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
  512. package/dist/frontend/lowering/expressions/object-literals.d.ts +5 -1
  513. package/dist/frontend/lowering/expressions/object-literals.js +951 -240
  514. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  515. package/dist/frontend/lowering/expressions/optional-chains.js +71 -21
  516. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  517. package/dist/frontend/lowering/expressions/property-access.d.ts +39 -0
  518. package/dist/frontend/lowering/expressions/property-access.js +1141 -87
  519. package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
  520. package/dist/frontend/lowering/expressions/relational.js +262 -4
  521. package/dist/frontend/lowering/expressions/relational.js.map +1 -1
  522. package/dist/frontend/lowering/expressions/typeof.js +25 -0
  523. package/dist/frontend/lowering/expressions/typeof.js.map +1 -1
  524. package/dist/frontend/lowering/expressions/union-fields.d.ts +20 -1
  525. package/dist/frontend/lowering/expressions/union-fields.js +103 -13
  526. package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
  527. package/dist/frontend/lowering/expressions/updates.js +156 -22
  528. package/dist/frontend/lowering/expressions/updates.js.map +1 -1
  529. package/dist/frontend/lowering/frozen-records.d.ts +6 -0
  530. package/dist/frontend/lowering/frozen-records.js +10 -4
  531. package/dist/frontend/lowering/frozen-records.js.map +1 -1
  532. package/dist/frontend/lowering/frozen-records.test.d.ts +1 -0
  533. package/dist/frontend/lowering/frozen-records.test.js +44 -0
  534. package/dist/frontend/lowering/frozen-records.test.js.map +1 -0
  535. package/dist/frontend/lowering/function-names.d.ts +9 -0
  536. package/dist/frontend/lowering/function-names.js +95 -0
  537. package/dist/frontend/lowering/function-names.js.map +1 -0
  538. package/dist/frontend/lowering/function-returns.js +42 -13
  539. package/dist/frontend/lowering/function-returns.js.map +1 -1
  540. package/dist/frontend/lowering/general-streams.js +5 -0
  541. package/dist/frontend/lowering/general-streams.js.map +1 -1
  542. package/dist/frontend/lowering/generator-delegation.d.ts +15 -7
  543. package/dist/frontend/lowering/generator-delegation.js +301 -118
  544. package/dist/frontend/lowering/generator-delegation.js.map +1 -1
  545. package/dist/frontend/lowering/generic-functions.d.ts +75 -0
  546. package/dist/frontend/lowering/generic-functions.js +790 -18
  547. package/dist/frontend/lowering/generic-functions.js.map +1 -1
  548. package/dist/frontend/lowering/global-function-values.d.ts +25 -0
  549. package/dist/frontend/lowering/global-function-values.js +193 -0
  550. package/dist/frontend/lowering/global-function-values.js.map +1 -0
  551. package/dist/frontend/lowering/global-values.d.ts +15 -4
  552. package/dist/frontend/lowering/global-values.js +67 -9
  553. package/dist/frontend/lowering/global-values.js.map +1 -1
  554. package/dist/frontend/lowering/handle-properties.js +34 -1
  555. package/dist/frontend/lowering/handle-properties.js.map +1 -1
  556. package/dist/frontend/lowering/host-global-values.d.ts +31 -0
  557. package/dist/frontend/lowering/host-global-values.js +121 -0
  558. package/dist/frontend/lowering/host-global-values.js.map +1 -0
  559. package/dist/frontend/lowering/host-globals.d.ts +74 -0
  560. package/dist/frontend/lowering/host-globals.js +344 -0
  561. package/dist/frontend/lowering/host-globals.js.map +1 -0
  562. package/dist/frontend/lowering/http2-constants.js +1 -1
  563. package/dist/frontend/lowering/iterator-adapters.js +46 -17
  564. package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
  565. package/dist/frontend/lowering/iterator-prototype.d.ts +30 -0
  566. package/dist/frontend/lowering/iterator-prototype.js +160 -0
  567. package/dist/frontend/lowering/iterator-prototype.js.map +1 -0
  568. package/dist/frontend/lowering/key-order-witness.d.ts +54 -0
  569. package/dist/frontend/lowering/key-order-witness.js +571 -9
  570. package/dist/frontend/lowering/key-order-witness.js.map +1 -1
  571. package/dist/frontend/lowering/key-order-witness.test.js +1 -0
  572. package/dist/frontend/lowering/key-order-witness.test.js.map +1 -1
  573. package/dist/frontend/lowering/lib-boundary.js +25 -3
  574. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  575. package/dist/frontend/lowering/lower-assert.js +140 -16
  576. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  577. package/dist/frontend/lowering/lower-async-iteration.d.ts +11 -0
  578. package/dist/frontend/lowering/lower-async-iteration.js +15 -0
  579. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
  580. package/dist/frontend/lowering/lower-builtin-values.d.ts +36 -6
  581. package/dist/frontend/lowering/lower-builtin-values.js +342 -58
  582. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  583. package/dist/frontend/lowering/lower-calls.d.ts +47 -1
  584. package/dist/frontend/lowering/lower-calls.js +1354 -273
  585. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  586. package/dist/frontend/lowering/lower-calls.test.d.ts +1 -0
  587. package/dist/frontend/lowering/lower-calls.test.js +121 -0
  588. package/dist/frontend/lowering/lower-calls.test.js.map +1 -0
  589. package/dist/frontend/lowering/lower-classes.d.ts +36 -5
  590. package/dist/frontend/lowering/lower-classes.js +630 -89
  591. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  592. package/dist/frontend/lowering/lower-event-emitter.d.ts +15 -2
  593. package/dist/frontend/lowering/lower-event-emitter.js +610 -98
  594. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  595. package/dist/frontend/lowering/lower-exprs.d.ts +15 -1
  596. package/dist/frontend/lowering/lower-exprs.js +96 -20
  597. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  598. package/dist/frontend/lowering/lower-functions.js +27 -6
  599. package/dist/frontend/lowering/lower-functions.js.map +1 -1
  600. package/dist/frontend/lowering/lower-generators.js +57 -10
  601. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  602. package/dist/frontend/lowering/lower-global-value.d.ts +6 -0
  603. package/dist/frontend/lowering/lower-global-value.js +14 -5
  604. package/dist/frontend/lowering/lower-global-value.js.map +1 -1
  605. package/dist/frontend/lowering/lower-inspect.d.ts +4 -0
  606. package/dist/frontend/lowering/lower-inspect.js +713 -92
  607. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  608. package/dist/frontend/lowering/lower-modules.js +135 -27
  609. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  610. package/dist/frontend/lowering/lower-namespaces.js +18 -0
  611. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  612. package/dist/frontend/lowering/lower-node-island.d.ts +35 -4
  613. package/dist/frontend/lowering/lower-node-island.js +472 -67
  614. package/dist/frontend/lowering/lower-node-island.js.map +1 -1
  615. package/dist/frontend/lowering/lower-server.js +463 -96
  616. package/dist/frontend/lowering/lower-server.js.map +1 -1
  617. package/dist/frontend/lowering/lower-shared-modules.js +13 -1
  618. package/dist/frontend/lowering/lower-shared-modules.js.map +1 -1
  619. package/dist/frontend/lowering/lower-stdlib.d.ts +3 -2
  620. package/dist/frontend/lowering/lower-stdlib.js +77 -18
  621. package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
  622. package/dist/frontend/lowering/lower-stmts.d.ts +24 -4
  623. package/dist/frontend/lowering/lower-stmts.js +831 -136
  624. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  625. package/dist/frontend/lowering/lower-stream.js +126 -8
  626. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  627. package/dist/frontend/lowering/lower-timers.js +243 -48
  628. package/dist/frontend/lowering/lower-timers.js.map +1 -1
  629. package/dist/frontend/lowering/lower-url.js +6 -3
  630. package/dist/frontend/lowering/lower-url.js.map +1 -1
  631. package/dist/frontend/lowering/lowerer.d.ts +363 -21
  632. package/dist/frontend/lowering/lowerer.js +1224 -129
  633. package/dist/frontend/lowering/lowerer.js.map +1 -1
  634. package/dist/frontend/lowering/lowerer.test.js +19 -1
  635. package/dist/frontend/lowering/lowerer.test.js.map +1 -1
  636. package/dist/frontend/lowering/lowering-facts.d.ts +110 -0
  637. package/dist/frontend/lowering/lowering-facts.js +323 -0
  638. package/dist/frontend/lowering/lowering-facts.js.map +1 -0
  639. package/dist/frontend/lowering/lowering-facts.test.d.ts +1 -0
  640. package/dist/frontend/lowering/lowering-facts.test.js +100 -0
  641. package/dist/frontend/lowering/lowering-facts.test.js.map +1 -0
  642. package/dist/frontend/lowering/module-namespace-elements.js +15 -0
  643. package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
  644. package/dist/frontend/lowering/nan-coded-reads.d.ts +27 -4
  645. package/dist/frontend/lowering/nan-coded-reads.js +112 -9
  646. package/dist/frontend/lowering/nan-coded-reads.js.map +1 -1
  647. package/dist/frontend/lowering/new-target.js +2 -2
  648. package/dist/frontend/lowering/nullish-empty-pattern.d.ts +17 -0
  649. package/dist/frontend/lowering/nullish-empty-pattern.js +118 -0
  650. package/dist/frontend/lowering/nullish-empty-pattern.js.map +1 -0
  651. package/dist/frontend/lowering/optional-arguments.d.ts +4 -0
  652. package/dist/frontend/lowering/optional-arguments.js +26 -2
  653. package/dist/frontend/lowering/optional-arguments.js.map +1 -1
  654. package/dist/frontend/lowering/partial-assertions.d.ts +36 -0
  655. package/dist/frontend/lowering/partial-assertions.js +189 -0
  656. package/dist/frontend/lowering/partial-assertions.js.map +1 -0
  657. package/dist/frontend/lowering/primitive-throws.d.ts +100 -0
  658. package/dist/frontend/lowering/primitive-throws.js +241 -0
  659. package/dist/frontend/lowering/primitive-throws.js.map +1 -0
  660. package/dist/frontend/lowering/primitive-wrappers.d.ts +34 -0
  661. package/dist/frontend/lowering/primitive-wrappers.js +221 -0
  662. package/dist/frontend/lowering/primitive-wrappers.js.map +1 -0
  663. package/dist/frontend/lowering/private-statics.d.ts +46 -0
  664. package/dist/frontend/lowering/private-statics.js +322 -0
  665. package/dist/frontend/lowering/private-statics.js.map +1 -0
  666. package/dist/frontend/lowering/record-inherited.d.ts +17 -1
  667. package/dist/frontend/lowering/record-inherited.js +16 -2
  668. package/dist/frontend/lowering/record-inherited.js.map +1 -1
  669. package/dist/frontend/lowering/record-links.d.ts +73 -0
  670. package/dist/frontend/lowering/record-links.js +797 -0
  671. package/dist/frontend/lowering/record-links.js.map +1 -0
  672. package/dist/frontend/lowering/record-sources.d.ts +12 -1
  673. package/dist/frontend/lowering/record-sources.js +60 -0
  674. package/dist/frontend/lowering/record-sources.js.map +1 -1
  675. package/dist/frontend/lowering/runtime-optional-provenance.d.ts +27 -7
  676. package/dist/frontend/lowering/runtime-optional-provenance.js +25 -11
  677. package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -1
  678. package/dist/frontend/lowering/runtime-optional-report.d.ts +40 -0
  679. package/dist/frontend/lowering/runtime-optional-report.js +300 -0
  680. package/dist/frontend/lowering/runtime-optional-report.js.map +1 -0
  681. package/dist/frontend/lowering/scoped-type-memo.test.d.ts +1 -0
  682. package/dist/frontend/lowering/scoped-type-memo.test.js +86 -0
  683. package/dist/frontend/lowering/scoped-type-memo.test.js.map +1 -0
  684. package/dist/frontend/lowering/static-typeof.d.ts +3 -1
  685. package/dist/frontend/lowering/static-typeof.js +6 -1
  686. package/dist/frontend/lowering/static-typeof.js.map +1 -1
  687. package/dist/frontend/lowering/strict-equality.d.ts +4 -0
  688. package/dist/frontend/lowering/strict-equality.js +14 -0
  689. package/dist/frontend/lowering/strict-equality.js.map +1 -1
  690. package/dist/frontend/lowering/strict-mode.d.ts +1 -5
  691. package/dist/frontend/lowering/strict-mode.js +4 -30
  692. package/dist/frontend/lowering/strict-mode.js.map +1 -1
  693. package/dist/frontend/lowering/structural-instances.d.ts +7 -0
  694. package/dist/frontend/lowering/structural-instances.js +23 -0
  695. package/dist/frontend/lowering/structural-instances.js.map +1 -1
  696. package/dist/frontend/lowering/surfaces.d.ts +42 -1
  697. package/dist/frontend/lowering/surfaces.js +212 -71
  698. package/dist/frontend/lowering/surfaces.js.map +1 -1
  699. package/dist/frontend/lowering/union-retag.d.ts +13 -1
  700. package/dist/frontend/lowering/union-retag.js +55 -1
  701. package/dist/frontend/lowering/union-retag.js.map +1 -1
  702. package/dist/frontend/lowering/union-retag.test.js +51 -0
  703. package/dist/frontend/lowering/union-retag.test.js.map +1 -1
  704. package/dist/frontend/lowering/unit-journal.d.ts +136 -17
  705. package/dist/frontend/lowering/unit-journal.js +324 -53
  706. package/dist/frontend/lowering/unit-journal.js.map +1 -1
  707. package/dist/frontend/lowering/unit-journal.test.js +126 -3
  708. package/dist/frontend/lowering/unit-journal.test.js.map +1 -1
  709. package/dist/frontend/lowering/unit-reuse.d.ts +92 -0
  710. package/dist/frontend/lowering/unit-reuse.js +1008 -0
  711. package/dist/frontend/lowering/unit-reuse.js.map +1 -0
  712. package/dist/frontend/lowering/width-lift.d.ts +12 -0
  713. package/dist/frontend/lowering/zlib-constants.js +3 -2
  714. package/dist/frontend/lowering/zlib-constants.js.map +1 -1
  715. package/dist/frontend/npm-file-import.test.d.ts +1 -0
  716. package/dist/frontend/npm-file-import.test.js +76 -0
  717. package/dist/frontend/npm-file-import.test.js.map +1 -0
  718. package/dist/frontend/npm-static.js +95 -11
  719. package/dist/frontend/npm-static.js.map +1 -1
  720. package/dist/frontend/npm-static.test.js +95 -2
  721. package/dist/frontend/npm-static.test.js.map +1 -1
  722. package/dist/frontend/npm.d.ts +9 -0
  723. package/dist/frontend/npm.js +82 -0
  724. package/dist/frontend/npm.js.map +1 -1
  725. package/dist/frontend/pipeline-native.js +2 -1
  726. package/dist/frontend/pipeline-native.js.map +1 -1
  727. package/dist/frontend/pipeline.d.ts +9 -4
  728. package/dist/frontend/pipeline.js +162 -38
  729. package/dist/frontend/pipeline.js.map +1 -1
  730. package/dist/frontend/pipeline.test.js +68 -11
  731. package/dist/frontend/pipeline.test.js.map +1 -1
  732. package/dist/frontend/program-node.d.ts +3 -0
  733. package/dist/frontend/program-node.js +13 -6
  734. package/dist/frontend/program-node.js.map +1 -1
  735. package/dist/frontend/program.d.ts +71 -2
  736. package/dist/frontend/program.js +836 -411
  737. package/dist/frontend/program.js.map +1 -1
  738. package/dist/frontend/program.test.js +37 -1
  739. package/dist/frontend/program.test.js.map +1 -1
  740. package/dist/frontend/provenance-core.js +4 -0
  741. package/dist/frontend/provenance-core.js.map +1 -1
  742. package/dist/frontend/services-node.d.ts +7 -0
  743. package/dist/frontend/services-node.js +32 -1
  744. package/dist/frontend/services-node.js.map +1 -1
  745. package/dist/frontend/services-node.test.js +51 -0
  746. package/dist/frontend/services-node.test.js.map +1 -1
  747. package/dist/frontend/services.d.ts +14 -0
  748. package/dist/frontend/services.js +52 -2
  749. package/dist/frontend/services.js.map +1 -1
  750. package/dist/frontend/services.test.js +61 -1
  751. package/dist/frontend/services.test.js.map +1 -1
  752. package/dist/frontend/shape-inference/analyze.d.ts +5 -0
  753. package/dist/frontend/shape-inference/analyze.js +104 -4
  754. package/dist/frontend/shape-inference/analyze.js.map +1 -1
  755. package/dist/frontend/shape-inference/domain.js +0 -1
  756. package/dist/frontend/shape-inference/domain.js.map +1 -1
  757. package/dist/frontend/shape-inference/index.js +5 -1
  758. package/dist/frontend/shape-inference/index.js.map +1 -1
  759. package/dist/frontend/shape-inference/memo.d.ts +2 -1
  760. package/dist/frontend/shape-inference/memo.js +6 -2
  761. package/dist/frontend/shape-inference/memo.js.map +1 -1
  762. package/dist/frontend/shape-inference/overlay.d.ts +1 -1
  763. package/dist/frontend/shape-inference/overlay.js +184 -4
  764. package/dist/frontend/shape-inference/overlay.js.map +1 -1
  765. package/dist/frontend/shape-inference/static-objects.js +11 -6
  766. package/dist/frontend/shape-inference/static-objects.js.map +1 -1
  767. package/dist/frontend/source-phase-imports.test.d.ts +1 -0
  768. package/dist/frontend/source-phase-imports.test.js +37 -0
  769. package/dist/frontend/source-phase-imports.test.js.map +1 -0
  770. package/dist/frontend/tier-analysis.d.ts +9 -0
  771. package/dist/frontend/tier-analysis.js +1 -0
  772. package/dist/frontend/tier-analysis.js.map +1 -1
  773. package/dist/frontend/ts7/ast-node.d.ts +6 -1
  774. package/dist/frontend/ts7/ast-node.js +12 -0
  775. package/dist/frontend/ts7/ast-node.js.map +1 -1
  776. package/dist/frontend/ts7/ast-wire-protocols.test.js +11 -3
  777. package/dist/frontend/ts7/ast-wire-protocols.test.js.map +1 -1
  778. package/dist/frontend/ts7/ast-wire.js +3 -5
  779. package/dist/frontend/ts7/ast-wire.js.map +1 -1
  780. package/dist/frontend/ts7/checker-backend.d.ts +13 -0
  781. package/dist/frontend/ts7/checker-backend.js +84 -2
  782. package/dist/frontend/ts7/checker-backend.js.map +1 -1
  783. package/dist/frontend/ts7/checker-backend.test.js +126 -2
  784. package/dist/frontend/ts7/checker-backend.test.js.map +1 -1
  785. package/dist/frontend/ts7/program-host.d.ts +22 -1
  786. package/dist/frontend/ts7/program-host.js +49 -4
  787. package/dist/frontend/ts7/program-host.js.map +1 -1
  788. package/dist/frontend/ts7/program-host.test.js +83 -0
  789. package/dist/frontend/ts7/program-host.test.js.map +1 -1
  790. package/dist/frontend/ts7/rpc-process.d.ts +16 -1
  791. package/dist/frontend/ts7/rpc-process.js +170 -92
  792. package/dist/frontend/ts7/rpc-process.js.map +1 -1
  793. package/dist/frontend/ts7/rpc-process.test.js +49 -21
  794. package/dist/frontend/ts7/rpc-process.test.js.map +1 -1
  795. package/dist/frontend/tsc-codes.d.ts +57 -3
  796. package/dist/frontend/tsc-codes.js +956 -101
  797. package/dist/frontend/tsc-codes.js.map +1 -1
  798. package/dist/frontend/tsc-codes.test.js +221 -12
  799. package/dist/frontend/tsc-codes.test.js.map +1 -1
  800. package/dist/frontend/type-mapper.d.ts +98 -11
  801. package/dist/frontend/type-mapper.js +770 -182
  802. package/dist/frontend/type-mapper.js.map +1 -1
  803. package/dist/index.d.ts +1 -1
  804. package/dist/index.js +224 -15
  805. package/dist/index.js.map +1 -1
  806. package/dist/index.test.d.ts +1 -0
  807. package/dist/index.test.js +60 -0
  808. package/dist/index.test.js.map +1 -0
  809. package/dist/ir/api.d.ts +1 -1
  810. package/dist/ir/api.js +1 -1
  811. package/dist/ir/api.js.map +1 -1
  812. package/dist/ir/build.d.ts +3 -2
  813. package/dist/ir/build.js +4 -2
  814. package/dist/ir/build.js.map +1 -1
  815. package/dist/ir/builtin-effects.js +96 -0
  816. package/dist/ir/builtin-effects.js.map +1 -1
  817. package/dist/ir/builtin-signatures.d.ts +1 -1
  818. package/dist/ir/builtin-signatures.js +453 -26
  819. package/dist/ir/builtin-signatures.js.map +1 -1
  820. package/dist/ir/callback-specialization.d.ts +3 -2
  821. package/dist/ir/callback-specialization.js +35 -25
  822. package/dist/ir/callback-specialization.js.map +1 -1
  823. package/dist/ir/capture-values.d.ts +8 -4
  824. package/dist/ir/capture-values.js +9 -6
  825. package/dist/ir/capture-values.js.map +1 -1
  826. package/dist/ir/char-unit-locals.d.ts +6 -2
  827. package/dist/ir/char-unit-locals.js +11 -2
  828. package/dist/ir/char-unit-locals.js.map +1 -1
  829. package/dist/ir/class-key-index.d.ts +18 -0
  830. package/dist/ir/class-key-index.js +29 -0
  831. package/dist/ir/class-key-index.js.map +1 -0
  832. package/dist/ir/class-key-index.test.d.ts +1 -0
  833. package/dist/ir/class-key-index.test.js +25 -0
  834. package/dist/ir/class-key-index.test.js.map +1 -0
  835. package/dist/ir/codec.d.ts +82 -0
  836. package/dist/ir/codec.generated.d.ts +13 -0
  837. package/dist/ir/codec.generated.js +5350 -0
  838. package/dist/ir/codec.generated.js.map +1 -0
  839. package/dist/ir/codec.js +325 -0
  840. package/dist/ir/codec.js.map +1 -0
  841. package/dist/ir/codec.test.d.ts +1 -0
  842. package/dist/ir/codec.test.js +225 -0
  843. package/dist/ir/codec.test.js.map +1 -0
  844. package/dist/ir/constant-globals.d.ts +5 -2
  845. package/dist/ir/constant-globals.js +25 -27
  846. package/dist/ir/constant-globals.js.map +1 -1
  847. package/dist/ir/expression-inlining.d.ts +4 -2
  848. package/dist/ir/expression-inlining.js +8 -2
  849. package/dist/ir/expression-inlining.js.map +1 -1
  850. package/dist/ir/field-values.d.ts +5 -2
  851. package/dist/ir/field-values.js +32 -21
  852. package/dist/ir/field-values.js.map +1 -1
  853. package/dist/ir/fields.generated.d.ts +29 -10
  854. package/dist/ir/fields.generated.js +1039 -11
  855. package/dist/ir/fields.generated.js.map +1 -1
  856. package/dist/ir/fields.test.js +46 -2
  857. package/dist/ir/fields.test.js.map +1 -1
  858. package/dist/ir/final-fields.js +1 -1
  859. package/dist/ir/final-fields.js.map +1 -1
  860. package/dist/ir/function-references.d.ts +6 -4
  861. package/dist/ir/function-references.js +11 -4
  862. package/dist/ir/function-references.js.map +1 -1
  863. package/dist/ir/function-references.test.js +14 -0
  864. package/dist/ir/function-references.test.js.map +1 -1
  865. package/dist/ir/init-only-globals.d.ts +4 -2
  866. package/dist/ir/init-only-globals.js +17 -18
  867. package/dist/ir/init-only-globals.js.map +1 -1
  868. package/dist/ir/inline-array-sources.js +4 -1
  869. package/dist/ir/inline-array-sources.js.map +1 -1
  870. package/dist/ir/inline-array-views.d.ts +13 -0
  871. package/dist/ir/inline-array-views.js +945 -0
  872. package/dist/ir/inline-array-views.js.map +1 -0
  873. package/dist/ir/inline-arrays.d.ts +7 -0
  874. package/dist/ir/inline-arrays.js +190 -55
  875. package/dist/ir/inline-arrays.js.map +1 -1
  876. package/dist/ir/inline-arrays.test.js +140 -2
  877. package/dist/ir/inline-arrays.test.js.map +1 -1
  878. package/dist/ir/int32-slots.js +7 -0
  879. package/dist/ir/int32-slots.js.map +1 -1
  880. package/dist/ir/integer-ranges.js +16 -6
  881. package/dist/ir/integer-ranges.js.map +1 -1
  882. package/dist/ir/ir.d.ts +130 -44
  883. package/dist/ir/ir.js +7 -0
  884. package/dist/ir/ir.js.map +1 -1
  885. package/dist/ir/js-groups.d.ts +51 -0
  886. package/dist/ir/js-groups.js +394 -0
  887. package/dist/ir/js-groups.js.map +1 -0
  888. package/dist/ir/js-groups.test.d.ts +1 -0
  889. package/dist/ir/js-groups.test.js +555 -0
  890. package/dist/ir/js-groups.test.js.map +1 -0
  891. package/dist/ir/js-ic.d.ts +10 -9
  892. package/dist/ir/js-ic.js +58 -25
  893. package/dist/ir/js-ic.js.map +1 -1
  894. package/dist/ir/js-ic.test.js +37 -3
  895. package/dist/ir/js-ic.test.js.map +1 -1
  896. package/dist/ir/jsval.js +374 -63
  897. package/dist/ir/jsval.js.map +1 -1
  898. package/dist/ir/jsval.test.js +96 -2
  899. package/dist/ir/jsval.test.js.map +1 -1
  900. package/dist/ir/loop-entry-ranges.js +112 -9
  901. package/dist/ir/loop-entry-ranges.js.map +1 -1
  902. package/dist/ir/loop-entry-ranges.test.js +40 -0
  903. package/dist/ir/loop-entry-ranges.test.js.map +1 -1
  904. package/dist/ir/node-index.d.ts +23 -6
  905. package/dist/ir/node-index.js +126 -49
  906. package/dist/ir/node-index.js.map +1 -1
  907. package/dist/ir/numeric-call-specialization.d.ts +4 -2
  908. package/dist/ir/numeric-call-specialization.js +40 -26
  909. package/dist/ir/numeric-call-specialization.js.map +1 -1
  910. package/dist/ir/paired-while-loops.d.ts +4 -2
  911. package/dist/ir/paired-while-loops.js +8 -2
  912. package/dist/ir/paired-while-loops.js.map +1 -1
  913. package/dist/ir/parameter-versions.d.ts +13 -3
  914. package/dist/ir/parameter-versions.js +63 -40
  915. package/dist/ir/parameter-versions.js.map +1 -1
  916. package/dist/ir/property-bags.d.ts +4 -2
  917. package/dist/ir/property-bags.js +22 -17
  918. package/dist/ir/property-bags.js.map +1 -1
  919. package/dist/ir/receiver-readers.js +58 -2
  920. package/dist/ir/receiver-readers.js.map +1 -1
  921. package/dist/ir/row-pairs.d.ts +4 -2
  922. package/dist/ir/row-pairs.js +12 -11
  923. package/dist/ir/row-pairs.js.map +1 -1
  924. package/dist/ir/runtime-features.d.ts +139 -5
  925. package/dist/ir/runtime-features.js +397 -19
  926. package/dist/ir/runtime-features.js.map +1 -1
  927. package/dist/ir/runtime-features.test.js +135 -1
  928. package/dist/ir/runtime-features.test.js.map +1 -1
  929. package/dist/ir/runtime-jam-loops.d.ts +35 -0
  930. package/dist/ir/runtime-jam-loops.js +604 -0
  931. package/dist/ir/runtime-jam-loops.js.map +1 -0
  932. package/dist/ir/runtime-jam-loops.test.d.ts +1 -0
  933. package/dist/ir/runtime-jam-loops.test.js +565 -0
  934. package/dist/ir/runtime-jam-loops.test.js.map +1 -0
  935. package/dist/ir/saturating-loop-jams.d.ts +11 -2
  936. package/dist/ir/saturating-loop-jams.js +56 -16
  937. package/dist/ir/saturating-loop-jams.js.map +1 -1
  938. package/dist/ir/saturating-loop-jams.test.js +39 -1
  939. package/dist/ir/saturating-loop-jams.test.js.map +1 -1
  940. package/dist/ir/scalar-records.d.ts +5 -2
  941. package/dist/ir/scalar-records.js +12 -2
  942. package/dist/ir/scalar-records.js.map +1 -1
  943. package/dist/ir/self-captures.d.ts +4 -2
  944. package/dist/ir/self-captures.js +40 -28
  945. package/dist/ir/self-captures.js.map +1 -1
  946. package/dist/ir/self-captures.test.js +15 -0
  947. package/dist/ir/self-captures.test.js.map +1 -1
  948. package/dist/ir/serialize.d.ts +8 -2
  949. package/dist/ir/serialize.js +92 -24
  950. package/dist/ir/serialize.js.map +1 -1
  951. package/dist/ir/serialize.test.js +26 -0
  952. package/dist/ir/serialize.test.js.map +1 -1
  953. package/dist/ir/tiers.js +1 -0
  954. package/dist/ir/tiers.js.map +1 -1
  955. package/dist/ir/traverse.js +4 -0
  956. package/dist/ir/traverse.js.map +1 -1
  957. package/dist/ir/typed-argument-clones.d.ts +30 -0
  958. package/dist/ir/typed-argument-clones.js +789 -0
  959. package/dist/ir/typed-argument-clones.js.map +1 -0
  960. package/dist/ir/union-arm-loops.d.ts +3 -0
  961. package/dist/ir/union-arm-loops.js +373 -0
  962. package/dist/ir/union-arm-loops.js.map +1 -0
  963. package/dist/ir/union-arm-loops.test.d.ts +1 -0
  964. package/dist/ir/union-arm-loops.test.js +230 -0
  965. package/dist/ir/union-arm-loops.test.js.map +1 -0
  966. package/dist/ir/validate.js +170 -22
  967. package/dist/ir/validate.js.map +1 -1
  968. package/dist/ir/validate.test.js +46 -0
  969. package/dist/ir/validate.test.js.map +1 -1
  970. package/dist/library/compiler-self-identity.d.ts +8 -2
  971. package/dist/library/compiler-self-identity.js +92 -18
  972. package/dist/library/compiler-self-identity.js.map +1 -1
  973. package/dist/library/compiler-self-identity.test.js +150 -3
  974. package/dist/library/compiler-self-identity.test.js.map +1 -1
  975. package/dist/library/int-infer.d.ts +5 -0
  976. package/dist/library/int-infer.js +15 -3
  977. package/dist/library/int-infer.js.map +1 -1
  978. package/dist/library/ir-policy.js +4 -0
  979. package/dist/library/ir-policy.js.map +1 -1
  980. package/dist/library/library-cache.d.ts +4 -0
  981. package/dist/library/library-cache.js +2 -0
  982. package/dist/library/library-cache.js.map +1 -1
  983. package/dist/library/library-cache.test.js +26 -0
  984. package/dist/library/library-cache.test.js.map +1 -1
  985. package/dist/library/prepare.js +99 -31
  986. package/dist/library/prepare.js.map +1 -1
  987. package/dist/native/cache.d.ts +7 -0
  988. package/dist/native/cache.js +49 -0
  989. package/dist/native/cache.js.map +1 -1
  990. package/dist/native/cache.test.js +13 -1
  991. package/dist/native/cache.test.js.map +1 -1
  992. package/dist/native/cli.js +2 -0
  993. package/dist/native/cli.js.map +1 -1
  994. package/dist/native/compiler.js +26 -5
  995. package/dist/native/compiler.js.map +1 -1
  996. package/dist/native/executable-cache-open.test.js +31 -5
  997. package/dist/native/executable-cache-open.test.js.map +1 -1
  998. package/dist/native/executable-cache.d.ts +6 -1
  999. package/dist/native/executable-cache.js +7 -1
  1000. package/dist/native/executable-cache.js.map +1 -1
  1001. package/dist/native/prepare.d.ts +3 -0
  1002. package/dist/native/prepare.js +74 -28
  1003. package/dist/native/prepare.js.map +1 -1
  1004. package/dist/native/prepare.test.js +25 -3
  1005. package/dist/native/prepare.test.js.map +1 -1
  1006. package/dist/native/sanitizer.js +63 -4
  1007. package/dist/native/sanitizer.js.map +1 -1
  1008. package/dist/native/sanitizer.test.js +93 -2
  1009. package/dist/native/sanitizer.test.js.map +1 -1
  1010. package/dist/native/toolchain.js +9 -2
  1011. package/dist/native/toolchain.js.map +1 -1
  1012. package/dist/node-islands/boundary.d.ts +37 -1
  1013. package/dist/node-islands/boundary.js +65 -7
  1014. package/dist/node-islands/boundary.js.map +1 -1
  1015. package/dist/node-islands/boundary.test.d.ts +1 -0
  1016. package/dist/node-islands/boundary.test.js +76 -0
  1017. package/dist/node-islands/boundary.test.js.map +1 -0
  1018. package/dist/node-islands/detect.d.ts +27 -1
  1019. package/dist/node-islands/detect.js +475 -40
  1020. package/dist/node-islands/detect.js.map +1 -1
  1021. package/dist/node-islands/detect.test.js +175 -4
  1022. package/dist/node-islands/detect.test.js.map +1 -1
  1023. package/dist/node-islands/effect-gate.js +30 -20
  1024. package/dist/node-islands/effect-gate.js.map +1 -1
  1025. package/dist/node-islands/effect-gate.test.js +4 -1
  1026. package/dist/node-islands/effect-gate.test.js.map +1 -1
  1027. package/dist/node-islands/graph-islands.d.ts +40 -0
  1028. package/dist/node-islands/graph-islands.js +128 -0
  1029. package/dist/node-islands/graph-islands.js.map +1 -0
  1030. package/dist/node-islands/growth.d.ts +57 -0
  1031. package/dist/node-islands/growth.js +205 -0
  1032. package/dist/node-islands/growth.js.map +1 -0
  1033. package/dist/node-islands/libnode.d.ts +1 -1
  1034. package/dist/node-islands/libnode.js +1 -1
  1035. package/dist/node-islands/libnode.js.map +1 -1
  1036. package/dist/node-islands/modules.d.ts +28 -0
  1037. package/dist/node-islands/modules.js +156 -0
  1038. package/dist/node-islands/modules.js.map +1 -1
  1039. package/dist/node-islands/modules.test.js +105 -1
  1040. package/dist/node-islands/modules.test.js.map +1 -1
  1041. package/dist/node-islands/policy.js +2 -3
  1042. package/dist/node-islands/policy.js.map +1 -1
  1043. package/dist/node-islands/probe-recorder.d.ts +1 -0
  1044. package/dist/node-islands/probe-recorder.js +596 -0
  1045. package/dist/node-islands/probe-recorder.js.map +1 -0
  1046. package/dist/node-islands/probe-recorder.test.d.ts +1 -0
  1047. package/dist/node-islands/probe-recorder.test.js +80 -0
  1048. package/dist/node-islands/probe-recorder.test.js.map +1 -0
  1049. package/dist/node-islands/report.d.ts +12 -0
  1050. package/dist/node-islands/report.js +28 -0
  1051. package/dist/node-islands/report.js.map +1 -1
  1052. package/dist/node-islands/report.test.js +4 -0
  1053. package/dist/node-islands/report.test.js.map +1 -1
  1054. package/dist/node-islands/rules.js +9 -0
  1055. package/dist/node-islands/rules.js.map +1 -1
  1056. package/dist/node-islands/scan.d.ts +16 -1
  1057. package/dist/node-islands/scan.js +110 -9
  1058. package/dist/node-islands/scan.js.map +1 -1
  1059. package/dist/node-islands/snapshot.d.ts +38 -1
  1060. package/dist/node-islands/snapshot.js +165 -161
  1061. package/dist/node-islands/snapshot.js.map +1 -1
  1062. package/dist/node-islands/snapshot.test.js +63 -2
  1063. package/dist/node-islands/snapshot.test.js.map +1 -1
  1064. package/dist/node-islands/summary.js +8 -0
  1065. package/dist/node-islands/summary.js.map +1 -1
  1066. package/dist/node-islands/type-strip.d.ts +11 -0
  1067. package/dist/node-islands/type-strip.js +157 -0
  1068. package/dist/node-islands/type-strip.js.map +1 -0
  1069. package/dist/node-islands/type-strip.test.d.ts +1 -0
  1070. package/dist/node-islands/type-strip.test.js +31 -0
  1071. package/dist/node-islands/type-strip.test.js.map +1 -0
  1072. package/dist/project-config.d.ts +4 -0
  1073. package/dist/project-config.js +19 -0
  1074. package/dist/project-config.js.map +1 -1
  1075. package/dist/project-config.test.js +10 -0
  1076. package/dist/project-config.test.js.map +1 -1
  1077. package/dist/wasm/translate.js +11 -5
  1078. package/dist/wasm/translate.js.map +1 -1
  1079. package/dist/wasm/translate.test.js +35 -0
  1080. package/dist/wasm/translate.test.js.map +1 -1
  1081. package/package.json +20 -20
  1082. package/surface-manifest.json +221 -122
@@ -1,7 +1,8 @@
1
1
  import { primitiveConstructorOr } from "./lower-exprs.js";
2
2
  import { TO_STRING_TAG_FIELD, wellKnownSymbolOfField } from "./symbol-fields.js";
3
3
  import { InternalCompilerError } from "../../errors.js";
4
- import { dynUndefinedExpr, helperLoc, nodeThrowExpr, varRef } from "../../ir/build.js";
4
+ import { dynUndefinedExpr, helperLoc, nodeThrowExpr, numLit, varRef } from "../../ir/build.js";
5
+ import { classKeyHash } from "../../ir/class-key-index.js";
5
6
  import { constructedValue } from "./constructor-returns.js";
6
7
  import { eventTargetApiMembers, eventTargetInheritedMember } from "./lower-event-target.js";
7
8
  import { DATE_PROTOTYPE_METHOD_NAMES, DATE_TIME_FIELD, dateInheritedMember, dateRootOf, programDeclaresDateClass, } from "./builtins/date-classes.js";
@@ -15,6 +16,7 @@ import { erasedGenericInstance, implicitDefaultInstance } from "./generic-functi
15
16
  import {} from "./call-signatures.js";
16
17
  import { accessorCall, classValueRef, findGenericMethodOn, findGenericStaticOn, findMethodOn, findStaticOn, genericOverrideBelow, upcastTo, } from "./lower-classes.js";
17
18
  import { classPrototypeData, hasClassPrototypeData, prototypeReflectedFlag, observedPrototypeMethod, reflectClassPrototype, } from "./class-prototypes.js";
19
+ import { runtimeStaticDefines } from "./class-runtime-statics.js";
18
20
  import { perEvaluationPrivateNames } from "./private-brands.js";
19
21
  import { errorPropertyRead, errorPropertyWrite, errorToStringCall, errorToStringMethod, refreshErrorPropertyDispatch, refreshErrorMethodDispatch, } from "./error-methods.js";
20
22
  import { GeneratorDynamicDispatch } from "./generator-dynamic-dispatch.js";
@@ -33,6 +35,8 @@ import { emitterRooted, lowerDynamicEmitterEmit, lowerDynamicEmitterOn, } from "
33
35
  import { protocolArm, protocolFieldArm } from "./class-protocol-dispatch.js";
34
36
  import { STREAM_OPERATORS, operatorSignalOptions, reduceSignalSetup } from "./lower-stream.js";
35
37
  import { deletedPropertyNames, fixedFieldFamily } from "./js-class-fields.js";
38
+ /** The receiver local of a call rewritten for a getter-only name. */
39
+ const GETTER_RECEIVER = "%dispatch.getter.receiver.";
36
40
  const STREAM_METHODS = new Set([
37
41
  "on",
38
42
  "addListener",
@@ -358,6 +362,217 @@ function branchKind(cond, param) {
358
362
  return branchKind(cond.left, param);
359
363
  return null;
360
364
  }
365
+ /** The fewest distinct classes a run can dispatch on. Indexing costs a key
366
+ * load, a multiply and a compare tree whatever the table's size, while the
367
+ * chain costs a key test per class it skips: measured per read over tables
368
+ * read in rotation, indexing is 1.2 ns a read ahead at 20 classes, 4.1 ns at
369
+ * 40, 8.3 ns at 60 and 15 to 48 ns at 200. The crossover is far below this
370
+ * threshold, so what it decides is which tables change at all. Whole
371
+ * programs whose largest table holds fewer than this many classes measured
372
+ * within noise; the ones that gained (a nested decode -36.5%, 200-class reads
373
+ * -47%) gained through tables above it, and every smaller table keeps the
374
+ * chain it had. */
375
+ const MIN_CLASS_DISPATCH_CASES = 64;
376
+ /** A class table's branch whose condition tests one class's type key on a
377
+ * receiver local, or null for a statement of another form. A branch
378
+ * qualifies when it returns: a run is a dispatch, so the branch the switch
379
+ * selects leaves the helper rather than continuing into the statements after
380
+ * the run, which only the unselected branches would reach. */
381
+ function classBranch(stmt) {
382
+ if (stmt.kind !== "if" || stmt.else_ !== null)
383
+ return null;
384
+ const test = classKeyTest(stmt.cond);
385
+ if (test === null)
386
+ return null;
387
+ if (stmt.then[stmt.then.length - 1]?.kind !== "return")
388
+ return null;
389
+ if (assignsLocal(stmt.then, test.receiver))
390
+ return null;
391
+ if (leavesSwitch(stmt.then))
392
+ return null;
393
+ return test;
394
+ }
395
+ /** Whether the branch would `break` the switch its body moves into: an
396
+ * unlabeled break that no loop or switch inside the body binds. A labeled
397
+ * break and an unlabeled one already bound inside the body keep their
398
+ * targets. */
399
+ function leavesSwitch(statements) {
400
+ let found = false;
401
+ const scan = (body, bound) => {
402
+ for (const stmt of body) {
403
+ if (found)
404
+ return;
405
+ switch (stmt.kind) {
406
+ case "break":
407
+ if (stmt.label === undefined && bound === 0)
408
+ found = true;
409
+ break;
410
+ case "while":
411
+ case "doWhile":
412
+ case "for":
413
+ case "forOf":
414
+ scan(stmt.body, bound + 1);
415
+ break;
416
+ case "switch":
417
+ for (const { body: caseBody } of stmt.cases)
418
+ scan(caseBody, bound + 1);
419
+ break;
420
+ case "if":
421
+ scan(stmt.then, bound);
422
+ if (stmt.else_)
423
+ scan(stmt.else_, bound);
424
+ break;
425
+ case "block":
426
+ scan(stmt.body, bound);
427
+ break;
428
+ case "tryCatch":
429
+ scan(stmt.tryBody, bound);
430
+ if (stmt.catchBody)
431
+ scan(stmt.catchBody, bound);
432
+ if (stmt.finallyBody)
433
+ scan(stmt.finallyBody, bound);
434
+ break;
435
+ default:
436
+ break;
437
+ }
438
+ }
439
+ };
440
+ scan(statements, 0);
441
+ return found;
442
+ }
443
+ /** The receiver local and interned type key of `dyn.typedRefIs(v, "object:C")`,
444
+ * or of the branch-conditional form `test ? instanceOf(v, C) : false`. The
445
+ * key must be ASCII: the dispatch indexes on the key's length and last four
446
+ * bytes, which for ASCII are the key text's own. */
447
+ function classKeyTest(cond) {
448
+ if (cond.kind === "ternary" && cond.else_.kind === "boolLit" && cond.else_.value === false)
449
+ return classKeyTest(cond.cond);
450
+ if (cond.kind !== "libCall" || cond.fn !== "dyn.typedRefIs" || cond.args.length !== 2)
451
+ return null;
452
+ const [value, key] = cond.args;
453
+ if (value?.kind !== "varRef" || key?.kind !== "strLit")
454
+ return null;
455
+ if (!key.value.startsWith("object:") || !/^[\x20-\x7e]*$/.test(key.value))
456
+ return null;
457
+ return { value, receiver: value.localId, key: key.value };
458
+ }
459
+ /** Whether the branch writes its receiver local, which would make the
460
+ * dispatch read a value the branch tests do not. */
461
+ function assignsLocal(statements, localId) {
462
+ let found = false;
463
+ everyStmtList(statements, {
464
+ stmt: (stmt) => {
465
+ if ((stmt.kind === "assign" || stmt.kind === "varDecl" || stmt.kind === "forOf") &&
466
+ stmt.localId === localId)
467
+ found = true;
468
+ return !found;
469
+ },
470
+ expr: () => !found,
471
+ });
472
+ return found;
473
+ }
474
+ /** The class branches of a generated table, whether its body lists them or
475
+ * reaches them through the indexed dispatch indexBranchRuns builds. The
476
+ * passes that read a table's branches run after it: the switch selects a
477
+ * branch by its class's key and the branch keeps its own key guard, so a
478
+ * reader treats the branches as the chain they were lowered from. */
479
+ function classTableBranches(body) {
480
+ if (!body.some(isClassDispatch))
481
+ return body;
482
+ const branches = [];
483
+ for (const stmt of body) {
484
+ if (isClassDispatch(stmt))
485
+ for (const { body: caseBody } of stmt.cases)
486
+ branches.push(...caseBody);
487
+ else
488
+ branches.push(stmt);
489
+ }
490
+ return branches;
491
+ }
492
+ /** The switch indexBranchRuns builds over a table's branches. */
493
+ function isClassDispatch(stmt) {
494
+ return stmt.kind === "switch" && stmt.disc.kind === "libCall" && stmt.disc.fn === "dyn.classHash";
495
+ }
496
+ /** The run's leading branches that stay in the chain ahead of the switch.
497
+ * Indexing costs a key load, a multiply and a walk of the compare tree before
498
+ * the matching branch's own guard runs, so a class the table tests early is
499
+ * cheaper in the chain: a read that hits one of them never computes the
500
+ * index. Keeping the first two measured the difference: one effect program
501
+ * whose tables are large but read near their front ran 3.3% slower with every
502
+ * branch in the switch (757.0 ms against 735.5 ms over 30 interleaved rounds)
503
+ * and at the baseline time with two peeled (737.5 ms), while a 200-class read,
504
+ * where the hit sits deep, keeps its gain. */
505
+ const CLASS_DISPATCH_HEAD = 2;
506
+ /** Replace each run of consecutive class branches on one receiver (at least
507
+ * MIN_CLASS_DISPATCH_CASES distinct classes) with a switch that selects the
508
+ * receiver's class. The branches move into the switch's cases unchanged and
509
+ * in order, branches whose keys hash together in one case; a key shared
510
+ * with a class outside the table selects that case, whose guards are false,
511
+ * and the switch's fallthrough reaches the remaining guards and the
512
+ * statements after the run exactly as the chain would. The run's first
513
+ * CLASS_DISPATCH_HEAD branches stay in the chain ahead of the switch: they
514
+ * run in order before it, and a class they select returns as it always did,
515
+ * so the switch only sees the receiver once those tests have failed. */
516
+ function indexBranchRuns(body) {
517
+ let rebuilt = null;
518
+ let i = 0;
519
+ while (i < body.length) {
520
+ const start = i;
521
+ const first = classBranch(body[i]);
522
+ if (first === null) {
523
+ rebuilt?.push(body[i]);
524
+ i++;
525
+ continue;
526
+ }
527
+ const run = [];
528
+ let branch = first;
529
+ while (branch !== null && branch.receiver === first.receiver) {
530
+ run.push({ value: branch.value, receiver: branch.receiver, key: branch.key, stmt: body[i] });
531
+ i++;
532
+ branch = i < body.length ? classBranch(body[i]) : null;
533
+ }
534
+ const keys = [...new Set(run.map((branch) => branch.key))];
535
+ if (keys.length < MIN_CLASS_DISPATCH_CASES) {
536
+ if (rebuilt)
537
+ for (const branch of run)
538
+ rebuilt.push(branch.stmt);
539
+ continue;
540
+ }
541
+ rebuilt ??= body.slice(0, start);
542
+ const head = Math.min(CLASS_DISPATCH_HEAD, run.length - 1);
543
+ for (const branch of run.slice(0, head))
544
+ rebuilt.push(branch.stmt);
545
+ rebuilt.push(classDispatch(run.slice(head)));
546
+ }
547
+ return rebuilt ?? body;
548
+ }
549
+ /** The switch that selects one of the run's branches, keyed by the class
550
+ * hash the emitted code computes from the receiver's key. */
551
+ function classDispatch(run) {
552
+ const first = run[0];
553
+ const loc = first.stmt.loc;
554
+ const branches = new Map();
555
+ for (const branch of run) {
556
+ const hash = classKeyHash(branch.key);
557
+ const ofHash = branches.get(hash);
558
+ if (ofHash)
559
+ ofHash.push(branch.stmt);
560
+ else
561
+ branches.set(hash, [branch.stmt]);
562
+ }
563
+ return {
564
+ kind: "switch",
565
+ disc: {
566
+ kind: "libCall",
567
+ fn: "dyn.classHash",
568
+ args: [varRef(first.receiver, first.value.type, loc)],
569
+ type: F64,
570
+ loc,
571
+ },
572
+ cases: [...branches].map(([hash, body]) => ({ test: numLit(hash, loc), body })),
573
+ loc,
574
+ };
575
+ }
361
576
  const READ_PROPERTIES = "%dyn.class.readProperties";
362
577
  const READ_PROPERTIES_OR_EMPTY = "%dyn.class.readPropertiesOrEmpty";
363
578
  function isEmptyBag(value) {
@@ -627,7 +842,7 @@ export function boxClassInstancesExactly(lowerer, functions) {
627
842
  return;
628
843
  // Static class → its constructible descendants in normalization order.
629
844
  const branches = new Map();
630
- for (const stmt of normalize.body) {
845
+ for (const stmt of classTableBranches(normalize.body)) {
631
846
  if (stmt.kind !== "if" || stmt.cond.kind !== "libCall" || stmt.cond.fn !== "dyn.typedRefIs")
632
847
  continue;
633
848
  const key = stmt.cond.args[1];
@@ -1056,6 +1271,11 @@ export class ClassDynamicDispatch {
1056
1271
  * classes included: the value's capsule can be any of its subclasses. */
1057
1272
  boxedStatic = new Set();
1058
1273
  dispatches = new Map();
1274
+ /** Per receiver local of a call rewritten for a getter-only name, the
1275
+ * classes whose instances it already reads the getter on. A later wave
1276
+ * that reaches another class with the getter rewrites the fallback call
1277
+ * for that class. */
1278
+ getterReceivers = new Map();
1059
1279
  properties = new Map();
1060
1280
  computed = new Map();
1061
1281
  computedClassHelpers = new Map();
@@ -1720,6 +1940,102 @@ export class ClassDynamicDispatch {
1720
1940
  byMethod.set(method, matching);
1721
1941
  return matching;
1722
1942
  };
1943
+ // A name some class declares as a getter, and no class as a method: on
1944
+ // an instance of such a class the call reads the member (running the
1945
+ // getter) before it evaluates the arguments, as JavaScript reads the
1946
+ // callee first, and then calls what it read. Any other receiver keeps
1947
+ // the runtime's method dispatch, which answers builtin methods of the
1948
+ // same name (`n.toFixed(2)` while a class declares `get toFixed()`).
1949
+ // The runtime reads fields and other own properties of class instances
1950
+ // that early itself (scr_dyn_prepare_method).
1951
+ const getterCapsules = (method) => {
1952
+ const keys = new Set();
1953
+ for (const { info, capsule } of this.propertyReceivers(lowerer, true))
1954
+ if (findMethodOn(lowerer, info, `get:${method}`))
1955
+ keys.add(typeKey({ kind: "object", className: capsule.def.name }));
1956
+ return [...keys];
1957
+ };
1958
+ const getterCall = (fn, invoke, capsules, covered) => {
1959
+ const loc = invoke.loc;
1960
+ const receiverLocal = {
1961
+ id: `${GETTER_RECEIVER}${this.getterReceivers.size}`,
1962
+ name: "receiver",
1963
+ type: DYN,
1964
+ mutable: false,
1965
+ };
1966
+ fn.locals.push(receiverLocal);
1967
+ const keys = new Set(capsules);
1968
+ if (covered)
1969
+ for (const key of covered)
1970
+ keys.add(key);
1971
+ this.getterReceivers.set(receiverLocal.id, keys);
1972
+ const calleeLocal = {
1973
+ id: `%dispatch.callee.${fn.locals.length}`,
1974
+ name: "callee",
1975
+ type: DYN,
1976
+ mutable: false,
1977
+ };
1978
+ fn.locals.push(calleeLocal);
1979
+ const receiver = varRef(receiverLocal.id, DYN, loc);
1980
+ const isCapsule = (key) => ({
1981
+ kind: "libCall",
1982
+ fn: "dyn.typedRefIs",
1983
+ args: [receiver, { kind: "strLit", value: key, type: STRING, loc }],
1984
+ type: BOOL,
1985
+ loc,
1986
+ });
1987
+ const cond = capsules.slice(1).reduce((rest, key) => ({
1988
+ kind: "ternary",
1989
+ cond: isCapsule(key),
1990
+ then: { kind: "boolLit", value: true, type: BOOL, loc },
1991
+ else_: rest,
1992
+ type: BOOL,
1993
+ loc,
1994
+ }), isCapsule(capsules[0]));
1995
+ const read = {
1996
+ kind: "seqExpr",
1997
+ stmts: [
1998
+ {
1999
+ kind: "varDecl",
2000
+ localId: calleeLocal.id,
2001
+ init: {
2002
+ kind: "dynKeyGet",
2003
+ key: { kind: "strLit", value: invoke.method, type: STRING, loc },
2004
+ value: receiver,
2005
+ type: DYN,
2006
+ loc,
2007
+ },
2008
+ loc,
2009
+ },
2010
+ ],
2011
+ result: {
2012
+ kind: "dynCall",
2013
+ callee: varRef(calleeLocal.id, DYN, loc),
2014
+ receiver,
2015
+ calleeName: invoke.calleeName,
2016
+ ...(invoke.calleeNameValue ? { calleeNameValue: invoke.calleeNameValue } : {}),
2017
+ args: invoke.args,
2018
+ type: DYN,
2019
+ loc,
2020
+ },
2021
+ type: DYN,
2022
+ loc,
2023
+ };
2024
+ return {
2025
+ kind: "seqExpr",
2026
+ stmts: [{ kind: "varDecl", localId: receiverLocal.id, init: invoke.recv, loc }],
2027
+ result: {
2028
+ kind: "ternary",
2029
+ cond,
2030
+ then: read,
2031
+ else_: { ...invoke, recv: receiver },
2032
+ type: DYN,
2033
+ loc,
2034
+ },
2035
+ type: DYN,
2036
+ loc,
2037
+ };
2038
+ };
1723
2039
  const candidateSets = new Map();
1724
2040
  const candidateSet = (method) => {
1725
2041
  let set = candidateSets.get(method);
@@ -1735,23 +2051,33 @@ export class ClassDynamicDispatch {
1735
2051
  // every reachability pass. Recompute this set as new bodies appear.
1736
2052
  if (this.generated.has(fn) || !rewrite.has(fn))
1737
2053
  continue;
1738
- const keyInitializers = new Map();
1739
- const written = new Set();
1740
- everyStmtList(fn.body, {
1741
- expr: (expression) => {
1742
- if (expression.kind === "incDec" || expression.kind === "assignExpr")
1743
- written.add(expression.localId);
1744
- return true;
1745
- },
1746
- stmt: (statement) => {
1747
- if (statement.kind === "varDecl" && statement.init)
1748
- keyInitializers.set(statement.localId, statement.init);
1749
- if (statement.kind === "assign")
1750
- written.add(statement.localId);
1751
- return true;
1752
- },
1753
- });
2054
+ // The bindings a key expression reads through, and the ones a write
2055
+ // rebinds. Only a dynamic-key site asks for them, so a body without one
2056
+ // keeps its IR walk.
2057
+ let keyTables = null;
2058
+ const keysOf = () => {
2059
+ if (keyTables !== null)
2060
+ return keyTables;
2061
+ const initializers = new Map();
2062
+ const written = new Set();
2063
+ everyStmtList(fn.body, {
2064
+ expr: (expression) => {
2065
+ if (expression.kind === "incDec" || expression.kind === "assignExpr")
2066
+ written.add(expression.localId);
2067
+ return true;
2068
+ },
2069
+ stmt: (statement) => {
2070
+ if (statement.kind === "varDecl" && statement.init)
2071
+ initializers.set(statement.localId, statement.init);
2072
+ if (statement.kind === "assign")
2073
+ written.add(statement.localId);
2074
+ return true;
2075
+ },
2076
+ });
2077
+ return (keyTables = { initializers, written });
2078
+ };
1754
2079
  const keyValue = (value) => {
2080
+ const { initializers: keyInitializers, written } = keysOf();
1755
2081
  const visited = new Set();
1756
2082
  while (true) {
1757
2083
  if (value.kind === "dynFrom") {
@@ -1773,562 +2099,603 @@ export class ClassDynamicDispatch {
1773
2099
  return value;
1774
2100
  }
1775
2101
  };
1776
- fn.body = transformStmtList(fn.body, {
1777
- stmt: (stmt) => stmt,
1778
- expr: (expr) => {
1779
- if (expr.kind === "dynHasKey" && prototypeMembers.has(expr.key)) {
1780
- // A class instance's snapshot can carry its class's prototype
1781
- // data, which holds only the methods the program reads through
1782
- // the prototype. The computed-key form answers methods and
1783
- // accessors from the class itself.
2102
+ const rewriteExpr = (expr) => {
2103
+ if (expr.kind === "dynHasKey" && prototypeMembers.has(expr.key)) {
2104
+ // A class instance's snapshot can carry its class's prototype
2105
+ // data, which holds only the methods the program reads through
2106
+ // the prototype. The computed-key form answers methods and
2107
+ // accessors from the class itself.
2108
+ const loc = expr.loc;
2109
+ const test = {
2110
+ kind: "libCall",
2111
+ fn: "dyn.hasKeyComputed",
2112
+ args: [
2113
+ expr.value,
2114
+ {
2115
+ kind: "dynFrom",
2116
+ value: { kind: "strLit", value: expr.key, type: STRING, loc },
2117
+ type: DYN,
2118
+ loc,
2119
+ },
2120
+ ],
2121
+ type: BOOL,
2122
+ loc,
2123
+ };
2124
+ changed = true;
2125
+ return {
2126
+ kind: "seqExpr",
2127
+ stmts: [],
2128
+ result: expr.negated
2129
+ ? { kind: "unary", op: "!", operand: test, type: BOOL, loc }
2130
+ : test,
2131
+ type: BOOL,
2132
+ loc,
2133
+ };
2134
+ }
2135
+ const called = calling.size ? this.convertMethodCall(lowerer, fn, expr, calling) : null;
2136
+ if (called) {
2137
+ changed = true;
2138
+ return called;
2139
+ }
2140
+ const converted = converting.size
2141
+ ? this.convertOperands(lowerer, fn, expr, converting)
2142
+ : null;
2143
+ if (converted) {
2144
+ changed = true;
2145
+ // A hoisting sequence revisits the operation as its child; a
2146
+ // wrapped operation continues through the rewrites below.
2147
+ if (converted.kind === "seqExpr")
2148
+ return converted;
2149
+ expr = converted;
2150
+ }
2151
+ if (expr.kind === "dynCheck" && isDynTypedRefType(expr.type)) {
2152
+ const type = expr.type;
2153
+ let cast = this.checkedCasts.get(type.className);
2154
+ if (!cast) {
1784
2155
  const loc = expr.loc;
1785
- const test = {
1786
- kind: "libCall",
1787
- fn: "dyn.hasKeyComputed",
1788
- args: [
1789
- expr.value,
1790
- {
1791
- kind: "dynFrom",
1792
- value: { kind: "strLit", value: expr.key, type: STRING, loc },
1793
- type: DYN,
1794
- loc,
1795
- },
1796
- ],
1797
- type: BOOL,
2156
+ const fn = {
2157
+ name: `%dyn.class.cast:${type.className}`,
2158
+ params: [{ localId: "value", name: "value", type: DYN }],
2159
+ locals: [{ id: "value", name: "value", type: DYN, mutable: false }],
2160
+ returnType: type,
2161
+ body: [{ kind: "return", value: { ...expr, value: varRef("value", DYN, loc) }, loc }],
1798
2162
  loc,
1799
2163
  };
2164
+ cast = { fn, classes: new Set() };
2165
+ this.checkedCasts.set(type.className, cast);
2166
+ this.generated.add(fn);
2167
+ lowerer.liftedFns.push(fn);
1800
2168
  changed = true;
1801
- return {
1802
- kind: "seqExpr",
1803
- stmts: [],
1804
- result: expr.negated
1805
- ? { kind: "unary", op: "!", operand: test, type: BOOL, loc }
1806
- : test,
1807
- type: BOOL,
2169
+ }
2170
+ return { kind: "call", callee: cast.fn.name, args: [expr.value], type, loc: expr.loc };
2171
+ }
2172
+ if (expr.kind === "libCall" && expr.fn === "dyn.inheritsErrorPrototype") {
2173
+ if (!this.errorPrototypeHelper) {
2174
+ const loc = expr.loc;
2175
+ this.errorPrototypeHelper = {
2176
+ name: "%dyn.class.inheritsErrorPrototype",
2177
+ params: [{ localId: "value", name: "value", type: DYN }],
2178
+ locals: [{ id: "value", name: "value", type: DYN, mutable: false }],
2179
+ returnType: BOOL,
1808
2180
  loc,
2181
+ body: [
2182
+ { kind: "return", value: { ...expr, args: [varRef("value", DYN, loc)] }, loc },
2183
+ ],
1809
2184
  };
1810
- }
1811
- const called = calling.size ? this.convertMethodCall(lowerer, fn, expr, calling) : null;
1812
- if (called) {
1813
- changed = true;
1814
- return called;
1815
- }
1816
- const converted = converting.size
1817
- ? this.convertOperands(lowerer, fn, expr, converting)
1818
- : null;
1819
- if (converted) {
2185
+ lowerer.liftedFns.push(this.errorPrototypeHelper);
2186
+ this.generated.add(this.errorPrototypeHelper);
1820
2187
  changed = true;
1821
- // A hoisting sequence revisits the operation as its child; a
1822
- // wrapped operation continues through the rewrites below.
1823
- if (converted.kind === "seqExpr")
1824
- return converted;
1825
- expr = converted;
1826
2188
  }
1827
- if (expr.kind === "dynCheck" && isDynTypedRefType(expr.type)) {
1828
- const type = expr.type;
1829
- let cast = this.checkedCasts.get(type.className);
1830
- if (!cast) {
1831
- const loc = expr.loc;
1832
- const fn = {
1833
- name: `%dyn.class.cast:${type.className}`,
1834
- params: [{ localId: "value", name: "value", type: DYN }],
1835
- locals: [{ id: "value", name: "value", type: DYN, mutable: false }],
1836
- returnType: type,
1837
- body: [
1838
- { kind: "return", value: { ...expr, value: varRef("value", DYN, loc) }, loc },
1839
- ],
1840
- loc,
1841
- };
1842
- cast = { fn, classes: new Set() };
1843
- this.checkedCasts.set(type.className, cast);
1844
- this.generated.add(fn);
1845
- lowerer.liftedFns.push(fn);
1846
- changed = true;
1847
- }
1848
- return { kind: "call", callee: cast.fn.name, args: [expr.value], type, loc: expr.loc };
1849
- }
1850
- if (expr.kind === "libCall" && expr.fn === "dyn.inheritsErrorPrototype") {
1851
- if (!this.errorPrototypeHelper) {
2189
+ return {
2190
+ kind: "call",
2191
+ callee: this.errorPrototypeHelper.name,
2192
+ args: expr.args,
2193
+ type: BOOL,
2194
+ loc: expr.loc,
2195
+ };
2196
+ }
2197
+ if (expr.kind === "libCall" &&
2198
+ (expr.fn === "dyn.getPrototype" || expr.fn === "dyn.getPrototypeForIdentity") &&
2199
+ expr.args[0]?.kind !== "dynObjLit") {
2200
+ if (expr.prototypeIdentityOnly) {
2201
+ let helper = this.prototypeIdentityHelpers.get(expr.fn);
2202
+ if (!helper) {
1852
2203
  const loc = expr.loc;
1853
- this.errorPrototypeHelper = {
1854
- name: "%dyn.class.inheritsErrorPrototype",
1855
- params: [{ localId: "value", name: "value", type: DYN }],
1856
- locals: [{ id: "value", name: "value", type: DYN, mutable: false }],
1857
- returnType: BOOL,
1858
- loc,
1859
- body: [
1860
- { kind: "return", value: { ...expr, args: [varRef("value", DYN, loc)] }, loc },
1861
- ],
2204
+ helper = {
2205
+ fn: {
2206
+ name: expr.fn === "dyn.getPrototype"
2207
+ ? "%dyn.class.prototypeIdentity"
2208
+ : "%dyn.class.prototypeChainIdentity",
2209
+ params: [{ localId: "value", name: "value", type: DYN }],
2210
+ locals: [{ id: "value", name: "value", type: DYN, mutable: false }],
2211
+ returnType: DYN,
2212
+ loc,
2213
+ body: [
2214
+ {
2215
+ kind: "return",
2216
+ value: { ...expr, args: [varRef("value", DYN, loc)] },
2217
+ loc,
2218
+ },
2219
+ ],
2220
+ },
2221
+ classes: new Set(),
1862
2222
  };
1863
- lowerer.liftedFns.push(this.errorPrototypeHelper);
1864
- this.generated.add(this.errorPrototypeHelper);
2223
+ this.prototypeIdentityHelpers.set(expr.fn, helper);
2224
+ lowerer.liftedFns.push(helper.fn);
2225
+ this.generated.add(helper.fn);
1865
2226
  changed = true;
1866
2227
  }
1867
2228
  return {
1868
2229
  kind: "call",
1869
- callee: this.errorPrototypeHelper.name,
2230
+ callee: helper.fn.name,
1870
2231
  args: expr.args,
1871
- type: BOOL,
2232
+ type: DYN,
1872
2233
  loc: expr.loc,
1873
2234
  };
1874
2235
  }
1875
- if (expr.kind === "libCall" &&
1876
- (expr.fn === "dyn.getPrototype" || expr.fn === "dyn.getPrototypeForIdentity") &&
1877
- expr.args[0]?.kind !== "dynObjLit") {
1878
- if (expr.prototypeIdentityOnly) {
1879
- let helper = this.prototypeIdentityHelpers.get(expr.fn);
1880
- if (!helper) {
1881
- const loc = expr.loc;
1882
- helper = {
1883
- fn: {
1884
- name: expr.fn === "dyn.getPrototype"
1885
- ? "%dyn.class.prototypeIdentity"
1886
- : "%dyn.class.prototypeChainIdentity",
1887
- params: [{ localId: "value", name: "value", type: DYN }],
1888
- locals: [{ id: "value", name: "value", type: DYN, mutable: false }],
1889
- returnType: DYN,
1890
- loc,
1891
- body: [
1892
- {
1893
- kind: "return",
1894
- value: { ...expr, args: [varRef("value", DYN, loc)] },
1895
- loc,
1896
- },
1897
- ],
1898
- },
1899
- classes: new Set(),
1900
- };
1901
- this.prototypeIdentityHelpers.set(expr.fn, helper);
1902
- lowerer.liftedFns.push(helper.fn);
1903
- this.generated.add(helper.fn);
1904
- changed = true;
1905
- }
1906
- return {
1907
- kind: "call",
1908
- callee: helper.fn.name,
1909
- args: expr.args,
1910
- type: DYN,
1911
- loc: expr.loc,
1912
- };
1913
- }
1914
- if (!this.prototypeHelper) {
1915
- const loc = expr.loc;
1916
- this.prototypeHelper = {
1917
- name: "%dyn.class.getPrototype",
1918
- params: [{ localId: "value", name: "value", type: DYN }],
1919
- locals: [{ id: "value", name: "value", type: DYN, mutable: false }],
1920
- returnType: DYN,
1921
- loc,
1922
- body: [
1923
- { kind: "return", value: { ...expr, args: [varRef("value", DYN, loc)] }, loc },
1924
- ],
1925
- };
1926
- lowerer.liftedFns.push(this.prototypeHelper);
1927
- this.generated.add(this.prototypeHelper);
1928
- changed = true;
1929
- }
1930
- return {
1931
- kind: "call",
1932
- callee: this.prototypeHelper.name,
1933
- args: expr.args,
1934
- type: DYN,
1935
- loc: expr.loc,
2236
+ if (!this.prototypeHelper) {
2237
+ const loc = expr.loc;
2238
+ this.prototypeHelper = {
2239
+ name: "%dyn.class.getPrototype",
2240
+ params: [{ localId: "value", name: "value", type: DYN }],
2241
+ locals: [{ id: "value", name: "value", type: DYN, mutable: false }],
2242
+ returnType: DYN,
2243
+ loc,
2244
+ body: [
2245
+ { kind: "return", value: { ...expr, args: [varRef("value", DYN, loc)] }, loc },
2246
+ ],
1936
2247
  };
2248
+ lowerer.liftedFns.push(this.prototypeHelper);
2249
+ this.generated.add(this.prototypeHelper);
2250
+ changed = true;
1937
2251
  }
1938
- if (expr.kind === "libCall" &&
1939
- (expr.fn === "dyn.toString" || expr.fn === "dyn.stringConstructor") &&
1940
- lowerer.classes.has("%Error")) {
1941
- const key = JSON.stringify([expr.fn, ...expr.args.map((arg) => typeKey(arg.type))]);
1942
- let errorString = this.errorStrings.get(key);
1943
- if (!errorString) {
1944
- const loc = expr.loc;
1945
- const params = expr.args.map((arg, i) => ({
1946
- localId: `p.${i}`,
1947
- name: `p${i}`,
1948
- type: arg.type,
1949
- }));
1950
- const value = varRef("p.0", DYN, loc);
1951
- errorString = {
1952
- name: `%dyn.error.${expr.fn.slice(4)}.${this.errorStrings.size}`,
1953
- params,
1954
- returnType: STRING,
1955
- locals: params.map((p) => ({
1956
- id: p.localId,
1957
- name: p.name,
1958
- type: p.type,
1959
- mutable: false,
1960
- })),
1961
- loc,
1962
- body: [
1963
- {
1964
- kind: "if",
1965
- cond: { kind: "dynTest", test: "error", value, type: BOOL, loc },
1966
- then: [
1967
- {
1968
- kind: "return",
2252
+ return {
2253
+ kind: "call",
2254
+ callee: this.prototypeHelper.name,
2255
+ args: expr.args,
2256
+ type: DYN,
2257
+ loc: expr.loc,
2258
+ };
2259
+ }
2260
+ if (expr.kind === "libCall" &&
2261
+ (expr.fn === "dyn.toString" || expr.fn === "dyn.stringConstructor") &&
2262
+ lowerer.classes.has("%Error")) {
2263
+ const key = JSON.stringify([expr.fn, ...expr.args.map((arg) => typeKey(arg.type))]);
2264
+ let errorString = this.errorStrings.get(key);
2265
+ if (!errorString) {
2266
+ const loc = expr.loc;
2267
+ const params = expr.args.map((arg, i) => ({
2268
+ localId: `p.${i}`,
2269
+ name: `p${i}`,
2270
+ type: arg.type,
2271
+ }));
2272
+ const value = varRef("p.0", DYN, loc);
2273
+ errorString = {
2274
+ name: `%dyn.error.${expr.fn.slice(4)}.${this.errorStrings.size}`,
2275
+ params,
2276
+ returnType: STRING,
2277
+ locals: params.map((p) => ({
2278
+ id: p.localId,
2279
+ name: p.name,
2280
+ type: p.type,
2281
+ mutable: false,
2282
+ })),
2283
+ loc,
2284
+ body: [
2285
+ {
2286
+ kind: "if",
2287
+ cond: { kind: "dynTest", test: "error", value, type: BOOL, loc },
2288
+ then: [
2289
+ {
2290
+ kind: "return",
2291
+ value: {
2292
+ kind: "dynCheck",
2293
+ type: STRING,
2294
+ loc,
1969
2295
  value: {
1970
- kind: "dynCheck",
1971
- type: STRING,
1972
- loc,
1973
- value: {
1974
- kind: "dynCall",
1975
- callee: errorToStringMethod(lowerer, {
1976
- kind: "dynCheck",
1977
- value,
1978
- type: { kind: "object", className: "%Error" },
1979
- loc,
1980
- }),
1981
- receiver: value,
1982
- calleeName: "value.toString",
1983
- args: params
1984
- .slice(1)
1985
- .map((p) => lowerer.coerceToExpected(varRef(p.localId, p.type, loc), DYN)),
1986
- type: DYN,
2296
+ kind: "dynCall",
2297
+ callee: errorToStringMethod(lowerer, {
2298
+ kind: "dynCheck",
2299
+ value,
2300
+ type: { kind: "object", className: "%Error" },
1987
2301
  loc,
1988
- },
2302
+ }),
2303
+ receiver: value,
2304
+ calleeName: "value.toString",
2305
+ args: params
2306
+ .slice(1)
2307
+ .map((p) => lowerer.coerceToExpected(varRef(p.localId, p.type, loc), DYN)),
2308
+ type: DYN,
2309
+ loc,
1989
2310
  },
1990
- loc,
1991
2311
  },
1992
- ],
1993
- else_: null,
1994
- loc,
1995
- },
1996
- {
1997
- kind: "return",
1998
- value: { ...expr, args: params.map((p) => varRef(p.localId, p.type, loc)) },
1999
- loc,
2000
- },
2001
- ],
2002
- };
2003
- this.errorStrings.set(key, errorString);
2004
- this.generated.add(errorString);
2005
- lowerer.liftedFns.push(errorString);
2006
- changed = true;
2007
- }
2008
- return {
2009
- kind: "call",
2010
- callee: errorString.name,
2011
- args: expr.args,
2012
- type: STRING,
2013
- loc: expr.loc,
2312
+ loc,
2313
+ },
2314
+ ],
2315
+ else_: null,
2316
+ loc,
2317
+ },
2318
+ {
2319
+ kind: "return",
2320
+ value: { ...expr, args: params.map((p) => varRef(p.localId, p.type, loc)) },
2321
+ loc,
2322
+ },
2323
+ ],
2014
2324
  };
2325
+ this.errorStrings.set(key, errorString);
2326
+ this.generated.add(errorString);
2327
+ lowerer.liftedFns.push(errorString);
2328
+ changed = true;
2015
2329
  }
2016
- if (expr.kind === "call" &&
2017
- (expr.callee === this.propertyBag.name || expr.callee === "%dyn.class.readProperties")) {
2018
- const boxed = expr.args[0];
2019
- if (boxed?.kind === "dynFrom" && isDynTypedRefType(boxed.value.type)) {
2020
- const helper = this.typedPropertyBag(lowerer, boxed.value.type, expr.loc, expr.callee === "%dyn.class.readProperties");
2021
- if (helper) {
2022
- changed = true;
2023
- return { ...expr, callee: helper.name, args: [boxed.value] };
2024
- }
2025
- }
2026
- }
2027
- if (expr.kind === "libCall" && expr.fn === "bytes.construct") {
2028
- if (!this.constructDispatch) {
2029
- const loc = expr.loc;
2030
- const params = [DYN, DYN, STRING].map((type, i) => ({
2031
- localId: `p.${i}`,
2032
- name: `p${i}`,
2033
- type,
2034
- }));
2035
- this.constructDispatch = {
2036
- name: "%dyn.class.construct",
2037
- params,
2038
- returnType: DYN,
2039
- locals: params.map((p) => ({
2040
- id: p.localId,
2041
- name: p.name,
2042
- type: p.type,
2043
- mutable: false,
2044
- })),
2045
- body: [
2046
- {
2047
- kind: "return",
2048
- value: { ...expr, args: params.map((p) => varRef(p.localId, p.type, loc)) },
2049
- loc,
2050
- },
2051
- ],
2052
- loc,
2053
- };
2054
- this.generated.add(this.constructDispatch);
2055
- lowerer.liftedFns.push(this.constructDispatch);
2330
+ return {
2331
+ kind: "call",
2332
+ callee: errorString.name,
2333
+ args: expr.args,
2334
+ type: STRING,
2335
+ loc: expr.loc,
2336
+ };
2337
+ }
2338
+ if (expr.kind === "call" &&
2339
+ (expr.callee === this.propertyBag.name || expr.callee === "%dyn.class.readProperties")) {
2340
+ const boxed = expr.args[0];
2341
+ if (boxed?.kind === "dynFrom" && isDynTypedRefType(boxed.value.type)) {
2342
+ const helper = this.typedPropertyBag(lowerer, boxed.value.type, expr.loc, expr.callee === "%dyn.class.readProperties");
2343
+ if (helper) {
2056
2344
  changed = true;
2345
+ return { ...expr, callee: helper.name, args: [boxed.value] };
2057
2346
  }
2058
- return {
2059
- kind: "call",
2060
- callee: this.constructDispatch.name,
2061
- args: expr.args,
2062
- type: DYN,
2063
- loc: expr.loc,
2064
- };
2065
2347
  }
2066
- if (expr.kind === "libCall" &&
2067
- (expr.fn === "dyn.forInKeys" || expr.fn === "dyn.forInKeyStrings")) {
2068
- let enumeration = this.enumerations.get(expr.fn);
2069
- if (!enumeration) {
2070
- const loc = expr.loc;
2071
- const value = varRef("p.0", DYN, loc);
2072
- enumeration = {
2073
- name: expr.fn === "dyn.forInKeys"
2074
- ? "%dyn.class.forInKeys"
2075
- : "%dyn.class.forInKeyStrings",
2076
- params: [{ localId: "p.0", name: "value", type: DYN }],
2077
- returnType: expr.type,
2078
- locals: [{ id: "p.0", name: "value", type: DYN, mutable: false }],
2079
- body: [{ kind: "return", value: { ...expr, args: [value] }, loc }],
2080
- loc,
2081
- };
2082
- this.enumerations.set(expr.fn, enumeration);
2083
- this.generated.add(enumeration);
2084
- lowerer.liftedFns.push(enumeration);
2085
- changed = true;
2086
- }
2087
- return {
2088
- kind: "call",
2089
- callee: enumeration.name,
2090
- args: expr.args,
2091
- type: expr.type,
2092
- loc: expr.loc,
2348
+ }
2349
+ if (expr.kind === "libCall" && expr.fn === "bytes.construct") {
2350
+ if (!this.constructDispatch) {
2351
+ const loc = expr.loc;
2352
+ const params = [DYN, DYN, STRING].map((type, i) => ({
2353
+ localId: `p.${i}`,
2354
+ name: `p${i}`,
2355
+ type,
2356
+ }));
2357
+ this.constructDispatch = {
2358
+ name: "%dyn.class.construct",
2359
+ params,
2360
+ returnType: DYN,
2361
+ locals: params.map((p) => ({
2362
+ id: p.localId,
2363
+ name: p.name,
2364
+ type: p.type,
2365
+ mutable: false,
2366
+ })),
2367
+ body: [
2368
+ {
2369
+ kind: "return",
2370
+ value: { ...expr, args: params.map((p) => varRef(p.localId, p.type, loc)) },
2371
+ loc,
2372
+ },
2373
+ ],
2374
+ loc,
2093
2375
  };
2376
+ this.generated.add(this.constructDispatch);
2377
+ lowerer.liftedFns.push(this.constructDispatch);
2378
+ changed = true;
2094
2379
  }
2095
- if (expr.kind === "libCall" && expr.fn === "dyn.defineProperty") {
2380
+ return {
2381
+ kind: "call",
2382
+ callee: this.constructDispatch.name,
2383
+ args: expr.args,
2384
+ type: DYN,
2385
+ loc: expr.loc,
2386
+ };
2387
+ }
2388
+ if (expr.kind === "libCall" &&
2389
+ (expr.fn === "dyn.forInKeys" || expr.fn === "dyn.forInKeyStrings")) {
2390
+ let enumeration = this.enumerations.get(expr.fn);
2391
+ if (!enumeration) {
2096
2392
  const loc = expr.loc;
2097
- if (!this.descriptorHelper) {
2098
- const params = ["target", "key", "descriptor"].map((name) => ({
2099
- localId: name,
2100
- name,
2393
+ const value = varRef("p.0", DYN, loc);
2394
+ enumeration = {
2395
+ name: expr.fn === "dyn.forInKeys" ? "%dyn.class.forInKeys" : "%dyn.class.forInKeyStrings",
2396
+ params: [{ localId: "p.0", name: "value", type: DYN }],
2397
+ returnType: expr.type,
2398
+ locals: [{ id: "p.0", name: "value", type: DYN, mutable: false }],
2399
+ body: [{ kind: "return", value: { ...expr, args: [value] }, loc }],
2400
+ loc,
2401
+ };
2402
+ this.enumerations.set(expr.fn, enumeration);
2403
+ this.generated.add(enumeration);
2404
+ lowerer.liftedFns.push(enumeration);
2405
+ changed = true;
2406
+ }
2407
+ return {
2408
+ kind: "call",
2409
+ callee: enumeration.name,
2410
+ args: expr.args,
2411
+ type: expr.type,
2412
+ loc: expr.loc,
2413
+ };
2414
+ }
2415
+ if (expr.kind === "libCall" && expr.fn === "dyn.defineProperty") {
2416
+ const loc = expr.loc;
2417
+ if (!this.descriptorHelper) {
2418
+ const params = ["target", "key", "descriptor"].map((name) => ({
2419
+ localId: name,
2420
+ name,
2421
+ type: DYN,
2422
+ }));
2423
+ const target = varRef("target", DYN, loc);
2424
+ const key = varRef("key", DYN, loc);
2425
+ const descriptor = varRef("descriptor", DYN, loc);
2426
+ this.descriptorHelper = {
2427
+ name: "%dyn.class.defineProperty",
2428
+ params,
2429
+ returnType: DYN,
2430
+ locals: params.map((param) => ({
2431
+ id: param.localId,
2432
+ name: param.name,
2101
2433
  type: DYN,
2102
- }));
2103
- const target = varRef("target", DYN, loc);
2104
- const key = varRef("key", DYN, loc);
2105
- const descriptor = varRef("descriptor", DYN, loc);
2106
- this.descriptorHelper = {
2107
- name: "%dyn.class.defineProperty",
2108
- params,
2109
- returnType: DYN,
2110
- locals: params.map((param) => ({
2111
- id: param.localId,
2112
- name: param.name,
2113
- type: DYN,
2114
- mutable: false,
2115
- })),
2116
- body: [
2117
- {
2118
- kind: "if",
2119
- cond: { kind: "dynTest", test: "symbol", value: key, type: BOOL, loc },
2120
- then: [
2121
- {
2122
- kind: "exprStmt",
2123
- expr: {
2124
- ...expr,
2125
- args: [
2126
- {
2127
- kind: "call",
2128
- callee: this.propertyBag.name,
2129
- args: [target],
2130
- type: DYN,
2131
- loc,
2132
- },
2133
- key,
2134
- descriptor,
2135
- ],
2136
- },
2137
- loc,
2434
+ mutable: false,
2435
+ })),
2436
+ body: [
2437
+ {
2438
+ kind: "if",
2439
+ cond: { kind: "dynTest", test: "symbol", value: key, type: BOOL, loc },
2440
+ then: [
2441
+ {
2442
+ kind: "exprStmt",
2443
+ expr: {
2444
+ ...expr,
2445
+ args: [
2446
+ {
2447
+ kind: "call",
2448
+ callee: this.propertyBag.name,
2449
+ args: [target],
2450
+ type: DYN,
2451
+ loc,
2452
+ },
2453
+ key,
2454
+ descriptor,
2455
+ ],
2138
2456
  },
2139
- { kind: "return", value: target, loc },
2140
- ],
2141
- else_: null,
2142
- loc,
2143
- },
2144
- { kind: "return", value: { ...expr, args: [target, key, descriptor] }, loc },
2145
- ],
2146
- loc,
2147
- };
2148
- this.generated.add(this.descriptorHelper);
2149
- lowerer.liftedFns.push(this.descriptorHelper);
2150
- changed = true;
2151
- }
2152
- return {
2153
- kind: "call",
2154
- callee: this.descriptorHelper.name,
2155
- args: expr.args,
2156
- type: DYN,
2457
+ loc,
2458
+ },
2459
+ { kind: "return", value: target, loc },
2460
+ ],
2461
+ else_: null,
2462
+ loc,
2463
+ },
2464
+ { kind: "return", value: { ...expr, args: [target, key, descriptor] }, loc },
2465
+ ],
2157
2466
  loc,
2158
2467
  };
2468
+ this.generated.add(this.descriptorHelper);
2469
+ lowerer.liftedFns.push(this.descriptorHelper);
2470
+ changed = true;
2159
2471
  }
2160
- if (expr.kind === "dynKeyGet" && expr.value.kind === "dynObjLit")
2161
- return expr;
2162
- const reflectRead = expr.kind === "libCall" && expr.fn === "dyn.reflectGet" ? expr : null;
2163
- const reflectWrite = expr.kind === "libCall" && expr.fn === "dyn.reflectSet" ? expr : null;
2164
- const reflect = !!reflectRead || !!reflectWrite;
2165
- const computedRead = reflectRead
2166
- ? {
2167
- kind: "dynKeyGet",
2168
- value: reflectRead.args[0],
2169
- key: reflectRead.args[1],
2170
- type: DYN,
2171
- loc: expr.loc,
2172
- }
2173
- : expr.kind === "dynKeyGet" && expr.key.kind !== "strLit"
2174
- ? expr
2175
- : null;
2176
- const computedWrite = reflectWrite
2177
- ? {
2178
- ...reflectWrite,
2179
- fn: "dyn.keySetComputed",
2180
- args: reflectWrite.args.slice(0, 3),
2181
- type: VOID,
2182
- }
2183
- : expr.kind === "libCall" &&
2184
- (expr.fn === "dyn.keySetComputed" ||
2185
- (expr.fn === "dyn.keySet" && expr.args[1]?.kind !== "strLit"))
2186
- ? expr
2187
- : null;
2188
- const computedProbe = expr.kind === "libCall" &&
2189
- [
2190
- "dyn.hasKeyComputed",
2191
- "dyn.hasOwnComputed",
2192
- "dyn.propertyIsEnumerableComputed",
2193
- ].includes(expr.fn)
2472
+ return {
2473
+ kind: "call",
2474
+ callee: this.descriptorHelper.name,
2475
+ args: expr.args,
2476
+ type: DYN,
2477
+ loc,
2478
+ };
2479
+ }
2480
+ if (expr.kind === "dynKeyGet" && expr.value.kind === "dynObjLit")
2481
+ return expr;
2482
+ const reflectRead = expr.kind === "libCall" && expr.fn === "dyn.reflectGet" ? expr : null;
2483
+ const reflectWrite = expr.kind === "libCall" && expr.fn === "dyn.reflectSet" ? expr : null;
2484
+ const reflect = !!reflectRead || !!reflectWrite;
2485
+ const computedRead = reflectRead
2486
+ ? {
2487
+ kind: "dynKeyGet",
2488
+ value: reflectRead.args[0],
2489
+ key: reflectRead.args[1],
2490
+ type: DYN,
2491
+ loc: expr.loc,
2492
+ }
2493
+ : expr.kind === "dynKeyGet" && expr.key.kind !== "strLit"
2194
2494
  ? expr
2195
2495
  : null;
2196
- if (computedRead || computedWrite || computedProbe) {
2197
- const probe = computedProbe
2198
- ? computedProbe.fn === "dyn.hasKeyComputed"
2199
- ? "in"
2200
- : computedProbe.fn === "dyn.hasOwnComputed"
2201
- ? "own"
2202
- : "enumerable"
2203
- : undefined;
2204
- const dynamicKey = reflect ||
2205
- !!computedProbe ||
2206
- computedWrite?.fn === "dyn.keySetComputed" ||
2207
- computedRead?.key.type.kind === "dyn";
2208
- const sourceKey = keyValue(computedRead?.key ?? (computedWrite ?? computedProbe).args[1]);
2209
- const numericKey = sourceKey.type.kind === "f64" ||
2210
- (sourceKey.kind === "dynFrom" && sourceKey.value.type.kind === "f64") ||
2211
- (sourceKey.kind === "toString" && sourceKey.operand.type.kind === "f64");
2212
- // `value[i]` with a number `i`: the helper takes the number and
2213
- // reads a dense checked array element directly, formatting the
2214
- // property name only when that does not apply.
2215
- const indexKey = computedRead &&
2216
- !reflect &&
2217
- !dynamicKey &&
2218
- !computedRead.optional &&
2219
- computedRead.key.kind === "toString" &&
2220
- computedRead.key.operand.type.kind === "f64"
2221
- ? computedRead.key
2222
- : null;
2223
- // A sloppy-mode write ignores a refused assignment
2224
- // (sloppyDynamicWrites), so its sites share their own helper,
2225
- // whose write takes the first such site's source range.
2226
- const sloppyWrite = !!computedWrite && !reflect && isSloppyAt(lowerer, computedWrite.loc);
2227
- const key = JSON.stringify([
2228
- !!computedWrite,
2229
- computedRead?.optional ?? false,
2230
- dynamicKey,
2231
- probe,
2232
- numericKey,
2233
- reflect,
2234
- !!indexKey,
2235
- ...(sloppyWrite ? ["sloppy"] : []),
2236
- ]);
2237
- let dispatch = this.computed.get(key);
2238
- if (!dispatch) {
2239
- const loc = expr.loc;
2240
- const params = [
2241
- { localId: "p.0", name: "value", type: DYN },
2242
- indexKey
2243
- ? { localId: "p.index", name: "index", type: F64 }
2244
- : { localId: "p.key", name: "key", type: dynamicKey ? DYN : STRING },
2245
- ...(computedWrite ? [{ localId: "p.1", name: "stored", type: DYN }] : []),
2246
- ...(reflect ? [{ localId: "p.reflectReceiver", name: "receiver", type: DYN }] : []),
2247
- ];
2248
- const keyLocal = dynamicKey ? "key.string" : "p.key";
2249
- const bag = computedWrite
2496
+ const computedWrite = reflectWrite
2497
+ ? {
2498
+ ...reflectWrite,
2499
+ fn: "dyn.keySetComputed",
2500
+ args: reflectWrite.args.slice(0, 3),
2501
+ type: VOID,
2502
+ }
2503
+ : expr.kind === "libCall" &&
2504
+ (expr.fn === "dyn.keySetComputed" ||
2505
+ (expr.fn === "dyn.keySet" && expr.args[1]?.kind !== "strLit"))
2506
+ ? expr
2507
+ : null;
2508
+ const computedProbe = expr.kind === "libCall" &&
2509
+ ["dyn.hasKeyComputed", "dyn.hasOwnComputed", "dyn.propertyIsEnumerableComputed"].includes(expr.fn)
2510
+ ? expr
2511
+ : null;
2512
+ if (computedRead || computedWrite || computedProbe) {
2513
+ const probe = computedProbe
2514
+ ? computedProbe.fn === "dyn.hasKeyComputed"
2515
+ ? "in"
2516
+ : computedProbe.fn === "dyn.hasOwnComputed"
2517
+ ? "own"
2518
+ : "enumerable"
2519
+ : undefined;
2520
+ const dynamicKey = reflect ||
2521
+ !!computedProbe ||
2522
+ computedWrite?.fn === "dyn.keySetComputed" ||
2523
+ computedRead?.key.type.kind === "dyn";
2524
+ const sourceKey = keyValue(computedRead?.key ?? (computedWrite ?? computedProbe).args[1]);
2525
+ const numericKey = sourceKey.type.kind === "f64" ||
2526
+ (sourceKey.kind === "dynFrom" && sourceKey.value.type.kind === "f64") ||
2527
+ (sourceKey.kind === "toString" && sourceKey.operand.type.kind === "f64");
2528
+ // `value[i]` with a number `i`: the helper takes the number and
2529
+ // reads a dense checked array element directly, formatting the
2530
+ // property name only when that does not apply.
2531
+ const indexKey = computedRead &&
2532
+ !reflect &&
2533
+ !dynamicKey &&
2534
+ !computedRead.optional &&
2535
+ computedRead.key.kind === "toString" &&
2536
+ computedRead.key.operand.type.kind === "f64"
2537
+ ? computedRead.key
2538
+ : null;
2539
+ // A sloppy-mode write ignores a refused assignment
2540
+ // (sloppyDynamicWrites), so its sites share their own helper,
2541
+ // whose write takes the first such site's source range.
2542
+ const sloppyWrite = !!computedWrite && !reflect && isSloppyAt(lowerer, computedWrite.loc);
2543
+ const key = JSON.stringify([
2544
+ !!computedWrite,
2545
+ computedRead?.optional ?? false,
2546
+ dynamicKey,
2547
+ probe,
2548
+ numericKey,
2549
+ reflect,
2550
+ !!indexKey,
2551
+ ...(sloppyWrite ? ["sloppy"] : []),
2552
+ ]);
2553
+ let dispatch = this.computed.get(key);
2554
+ if (!dispatch) {
2555
+ const loc = expr.loc;
2556
+ const params = [
2557
+ { localId: "p.0", name: "value", type: DYN },
2558
+ indexKey
2559
+ ? { localId: "p.index", name: "index", type: F64 }
2560
+ : { localId: "p.key", name: "key", type: dynamicKey ? DYN : STRING },
2561
+ ...(computedWrite ? [{ localId: "p.1", name: "stored", type: DYN }] : []),
2562
+ ...(reflect ? [{ localId: "p.reflectReceiver", name: "receiver", type: DYN }] : []),
2563
+ ];
2564
+ const keyLocal = dynamicKey ? "key.string" : "p.key";
2565
+ const bag = computedWrite
2566
+ ? {
2567
+ kind: "call",
2568
+ callee: this.propertyBag.name,
2569
+ args: [varRef("p.0", DYN, loc)],
2570
+ type: DYN,
2571
+ loc,
2572
+ }
2573
+ : this.readPropertyBagOrEmpty(lowerer, varRef("p.0", DYN, loc), loc);
2574
+ const reflectionFallback = (target, property) => ({
2575
+ kind: "libCall",
2576
+ fn: computedWrite ? "dyn.reflectSet" : "dyn.reflectGet",
2577
+ args: [
2578
+ target,
2579
+ lowerer.coerceToExpected(property, DYN),
2580
+ ...(computedWrite ? [varRef("p.1", DYN, loc)] : []),
2581
+ varRef("p.reflectReceiver", DYN, loc),
2582
+ ],
2583
+ type: computedWrite ? BOOL : DYN,
2584
+ loc,
2585
+ });
2586
+ const fallback = reflect
2587
+ ? reflectionFallback(bag, varRef(keyLocal, STRING, loc))
2588
+ : computedProbe
2250
2589
  ? {
2251
- kind: "call",
2252
- callee: this.propertyBag.name,
2253
- args: [varRef("p.0", DYN, loc)],
2254
- type: DYN,
2255
- loc,
2590
+ ...computedProbe,
2591
+ fn: probe === "in"
2592
+ ? "dyn.in"
2593
+ : probe === "own"
2594
+ ? "dyn.hasOwn"
2595
+ : "dyn.propertyIsEnumerable",
2596
+ args: [bag, varRef(keyLocal, STRING, loc)],
2256
2597
  }
2257
- : this.readPropertyBagOrEmpty(lowerer, varRef("p.0", DYN, loc), loc);
2258
- const reflectionFallback = (target, property) => ({
2259
- kind: "libCall",
2260
- fn: computedWrite ? "dyn.reflectSet" : "dyn.reflectGet",
2261
- args: [
2262
- target,
2263
- lowerer.coerceToExpected(property, DYN),
2264
- ...(computedWrite ? [varRef("p.1", DYN, loc)] : []),
2265
- varRef("p.reflectReceiver", DYN, loc),
2266
- ],
2267
- type: computedWrite ? BOOL : DYN,
2268
- loc,
2269
- });
2270
- const fallback = reflect
2271
- ? reflectionFallback(bag, varRef(keyLocal, STRING, loc))
2272
- : computedProbe
2273
- ? {
2274
- ...computedProbe,
2275
- fn: probe === "in"
2276
- ? "dyn.in"
2277
- : probe === "own"
2278
- ? "dyn.hasOwn"
2279
- : "dyn.propertyIsEnumerable",
2280
- args: [bag, varRef(keyLocal, STRING, loc)],
2281
- }
2282
- : computedRead
2283
- ? { ...computedRead, value: bag, key: varRef(keyLocal, STRING, loc) }
2284
- : {
2285
- ...computedWrite,
2286
- fn: "dyn.keySet",
2287
- args: [bag, varRef(keyLocal, STRING, loc), varRef("p.1", DYN, loc)],
2288
- };
2289
- const helper = {
2290
- name: `%dyn.class.computed.${this.computed.size}`,
2291
- params,
2292
- returnType: (reflect && computedWrite) || computedProbe ? BOOL : computedWrite ? VOID : DYN,
2293
- locals: [
2294
- ...params.map((p) => ({
2295
- id: p.localId,
2296
- name: p.name,
2297
- type: p.type,
2298
- mutable: false,
2299
- })),
2300
- ...(dynamicKey || indexKey
2301
- ? [{ id: keyLocal, name: "key", type: STRING, mutable: false }]
2302
- : []),
2303
- ],
2304
- body: reflect
2305
- ? [{ kind: "return", value: fallback, loc }]
2306
- : computedWrite
2598
+ : computedRead
2599
+ ? { ...computedRead, value: bag, key: varRef(keyLocal, STRING, loc) }
2600
+ : {
2601
+ ...computedWrite,
2602
+ fn: "dyn.keySet",
2603
+ args: [bag, varRef(keyLocal, STRING, loc), varRef("p.1", DYN, loc)],
2604
+ };
2605
+ const helper = {
2606
+ name: `%dyn.class.computed.${this.computed.size}`,
2607
+ params,
2608
+ returnType: (reflect && computedWrite) || computedProbe ? BOOL : computedWrite ? VOID : DYN,
2609
+ locals: [
2610
+ ...params.map((p) => ({
2611
+ id: p.localId,
2612
+ name: p.name,
2613
+ type: p.type,
2614
+ mutable: false,
2615
+ })),
2616
+ ...(dynamicKey || indexKey
2617
+ ? [{ id: keyLocal, name: "key", type: STRING, mutable: false }]
2618
+ : []),
2619
+ ],
2620
+ body: reflect
2621
+ ? [{ kind: "return", value: fallback, loc }]
2622
+ : computedWrite
2623
+ ? [
2624
+ { kind: "exprStmt", expr: fallback, loc },
2625
+ { kind: "return", value: null, loc },
2626
+ ]
2627
+ : [{ kind: "return", value: fallback, loc }],
2628
+ loc,
2629
+ ...(numericKey && computedRead && !reflect && !dynamicKey
2630
+ ? { fastRead: "index" }
2631
+ : {}),
2632
+ };
2633
+ if (dynamicKey)
2634
+ helper.body.unshift({
2635
+ kind: "if",
2636
+ cond: {
2637
+ kind: "dynTest",
2638
+ test: "symbol",
2639
+ value: varRef("p.key", DYN, loc),
2640
+ type: BOOL,
2641
+ loc,
2642
+ },
2643
+ then: reflect
2644
+ ? [
2645
+ {
2646
+ kind: "return",
2647
+ value: reflectionFallback(bag, varRef("p.key", DYN, loc)),
2648
+ loc,
2649
+ },
2650
+ ]
2651
+ : computedProbe
2307
2652
  ? [
2308
- { kind: "exprStmt", expr: fallback, loc },
2309
- { kind: "return", value: null, loc },
2653
+ {
2654
+ kind: "return",
2655
+ value: { ...computedProbe, args: [bag, varRef("p.key", DYN, loc)] },
2656
+ loc,
2657
+ },
2310
2658
  ]
2311
- : [{ kind: "return", value: fallback, loc }],
2659
+ : computedRead
2660
+ ? [
2661
+ {
2662
+ kind: "return",
2663
+ value: {
2664
+ ...computedRead,
2665
+ value: bag,
2666
+ key: varRef("p.key", DYN, loc),
2667
+ },
2668
+ loc,
2669
+ },
2670
+ ]
2671
+ : [
2672
+ {
2673
+ kind: "exprStmt",
2674
+ expr: {
2675
+ ...computedWrite,
2676
+ args: [bag, varRef("p.key", DYN, loc), varRef("p.1", DYN, loc)],
2677
+ },
2678
+ loc,
2679
+ },
2680
+ { kind: "return", value: null, loc },
2681
+ ],
2682
+ else_: null,
2312
2683
  loc,
2313
- ...(numericKey && computedRead && !reflect && !dynamicKey
2314
- ? { fastRead: "index" }
2315
- : {}),
2316
- };
2317
- if (dynamicKey)
2318
- helper.body.unshift({
2319
- kind: "if",
2320
- cond: {
2321
- kind: "dynTest",
2322
- test: "symbol",
2323
- value: varRef("p.key", DYN, loc),
2324
- type: BOOL,
2325
- loc,
2326
- },
2327
- then: reflect
2684
+ }, {
2685
+ kind: "if",
2686
+ cond: {
2687
+ kind: "dynTest",
2688
+ test: "nullish",
2689
+ value: varRef("p.0", DYN, loc),
2690
+ type: BOOL,
2691
+ loc,
2692
+ },
2693
+ then: [
2694
+ ...(reflect
2328
2695
  ? [
2329
2696
  {
2330
2697
  kind: "return",
2331
- value: reflectionFallback(bag, varRef("p.key", DYN, loc)),
2698
+ value: reflectionFallback(varRef("p.0", DYN, loc), varRef("p.key", DYN, loc)),
2332
2699
  loc,
2333
2700
  },
2334
2701
  ]
@@ -2336,7 +2703,10 @@ export class ClassDynamicDispatch {
2336
2703
  ? [
2337
2704
  {
2338
2705
  kind: "return",
2339
- value: { ...computedProbe, args: [bag, varRef("p.key", DYN, loc)] },
2706
+ value: {
2707
+ ...computedProbe,
2708
+ args: [varRef("p.0", DYN, loc), varRef("p.key", DYN, loc)],
2709
+ },
2340
2710
  loc,
2341
2711
  },
2342
2712
  ]
@@ -2346,7 +2716,7 @@ export class ClassDynamicDispatch {
2346
2716
  kind: "return",
2347
2717
  value: {
2348
2718
  ...computedRead,
2349
- value: bag,
2719
+ value: varRef("p.0", DYN, loc),
2350
2720
  key: varRef("p.key", DYN, loc),
2351
2721
  },
2352
2722
  loc,
@@ -2357,461 +2727,257 @@ export class ClassDynamicDispatch {
2357
2727
  kind: "exprStmt",
2358
2728
  expr: {
2359
2729
  ...computedWrite,
2360
- args: [bag, varRef("p.key", DYN, loc), varRef("p.1", DYN, loc)],
2730
+ args: [
2731
+ varRef("p.0", DYN, loc),
2732
+ varRef("p.key", DYN, loc),
2733
+ varRef("p.1", DYN, loc),
2734
+ ],
2361
2735
  },
2362
2736
  loc,
2363
2737
  },
2364
2738
  { kind: "return", value: null, loc },
2365
- ],
2366
- else_: null,
2367
- loc,
2368
- }, {
2369
- kind: "if",
2370
- cond: {
2371
- kind: "dynTest",
2372
- test: "nullish",
2373
- value: varRef("p.0", DYN, loc),
2374
- type: BOOL,
2375
- loc,
2376
- },
2377
- then: [
2378
- ...(reflect
2379
- ? [
2380
- {
2381
- kind: "return",
2382
- value: reflectionFallback(varRef("p.0", DYN, loc), varRef("p.key", DYN, loc)),
2383
- loc,
2384
- },
2385
- ]
2386
- : computedProbe
2387
- ? [
2388
- {
2389
- kind: "return",
2390
- value: {
2391
- ...computedProbe,
2392
- args: [varRef("p.0", DYN, loc), varRef("p.key", DYN, loc)],
2393
- },
2394
- loc,
2395
- },
2396
- ]
2397
- : computedRead
2398
- ? [
2399
- {
2400
- kind: "return",
2401
- value: {
2402
- ...computedRead,
2403
- value: varRef("p.0", DYN, loc),
2404
- key: varRef("p.key", DYN, loc),
2405
- },
2406
- loc,
2407
- },
2408
- ]
2409
- : [
2410
- {
2411
- kind: "exprStmt",
2412
- expr: {
2413
- ...computedWrite,
2414
- args: [
2415
- varRef("p.0", DYN, loc),
2416
- varRef("p.key", DYN, loc),
2417
- varRef("p.1", DYN, loc),
2418
- ],
2419
- },
2420
- loc,
2421
- },
2422
- { kind: "return", value: null, loc },
2423
- ]),
2424
- ],
2425
- else_: null,
2426
- loc,
2427
- }, {
2428
- kind: "varDecl",
2429
- localId: keyLocal,
2430
- init: {
2431
- kind: "libCall",
2432
- fn: "dyn.toStringCoerce",
2433
- args: [varRef("p.key", DYN, loc)],
2434
- type: STRING,
2435
- loc,
2436
- },
2437
- loc,
2438
- });
2439
- if (indexKey) {
2440
- // An integer index below a checked array's length names an
2441
- // element (-0 included: its property name is "0"); dyn.arrLen
2442
- // answers 0 for every other kind. Holes keep dyn.arrAt's
2443
- // ordinary named lookup.
2444
- const index = varRef("p.index", F64, loc);
2445
- const elementRead = {
2446
- kind: "if",
2447
- cond: { kind: "libCall", fn: "number.isInteger", args: [index], type: BOOL, loc },
2448
- then: [
2449
- {
2450
- kind: "if",
2451
- cond: {
2452
- kind: "bin",
2453
- op: ">=",
2454
- left: index,
2455
- right: { kind: "numLit", value: 0, type: F64, loc },
2456
- type: BOOL,
2457
- loc,
2458
- },
2459
- then: [
2460
- {
2461
- kind: "if",
2462
- cond: {
2463
- kind: "bin",
2464
- op: "<",
2465
- left: index,
2466
- right: {
2467
- kind: "libCall",
2468
- fn: "dyn.arrLen",
2469
- args: [varRef("p.0", DYN, loc)],
2470
- type: F64,
2471
- loc,
2472
- },
2473
- type: BOOL,
2474
- loc,
2475
- },
2476
- then: [
2477
- {
2478
- kind: "return",
2479
- value: {
2480
- kind: "libCall",
2481
- fn: "dyn.arrAt",
2482
- args: [varRef("p.0", DYN, loc), index],
2483
- type: DYN,
2484
- loc,
2485
- },
2486
- loc,
2487
- },
2488
- ],
2489
- else_: null,
2490
- loc,
2491
- },
2492
- ],
2493
- else_: null,
2494
- loc,
2495
- },
2496
- ],
2497
- else_: null,
2498
- loc,
2499
- };
2500
- helper.body.unshift(elementRead, {
2501
- kind: "varDecl",
2502
- localId: keyLocal,
2503
- init: { ...indexKey, operand: index },
2504
- loc,
2505
- });
2506
- }
2507
- dispatch = {
2508
- write: !!computedWrite,
2509
- reflect,
2510
- fn: helper,
2511
- classes: new Set(),
2512
- keyLocal,
2513
- branchIndex: dynamicKey ? 3 : indexKey ? 2 : 0,
2514
- dynamicKey,
2515
- numericKey,
2516
- probe,
2517
- };
2518
- this.computed.set(key, dispatch);
2519
- this.generated.add(helper);
2520
- lowerer.liftedFns.push(helper);
2521
- changed = true;
2522
- }
2523
- return {
2524
- kind: "call",
2525
- callee: dispatch.fn.name,
2526
- args: reflect
2527
- ? (reflectRead ?? reflectWrite).args
2528
- : computedRead
2529
- ? [computedRead.value, indexKey ? indexKey.operand : computedRead.key]
2530
- : (computedWrite ?? computedProbe).args,
2531
- type: dispatch.fn.returnType,
2532
- loc: expr.loc,
2533
- };
2534
- }
2535
- const read = expr.kind === "dynKeyGet" && expr.key.kind === "strLit" ? expr : null;
2536
- const write = expr.kind === "libCall" && expr.fn === "dyn.keySet" && expr.args[1]?.kind === "strLit"
2537
- ? expr
2538
- : null;
2539
- const name = read?.key.kind === "strLit"
2540
- ? read.key.value
2541
- : write?.args[1]?.kind === "strLit"
2542
- ? write.args[1].value
2543
- : null;
2544
- if (name !== null) {
2545
- const key = JSON.stringify([name, !!write, read?.optional ?? false]);
2546
- let dispatch = this.properties.get(key);
2547
- if (!dispatch) {
2548
- const loc = expr.loc;
2549
- const params = (write ? [0, 1] : [0]).map((i) => ({
2550
- localId: `p.${i}`,
2551
- name: `p${i}`,
2552
- type: DYN,
2553
- }));
2554
- const instanceBag = read
2555
- ? this.readPropertyBagOrEmpty(lowerer, varRef("p.0", DYN, loc), loc)
2556
- : {
2557
- kind: "call",
2558
- callee: this.propertyBag.name,
2559
- args: [varRef("p.0", DYN, loc)],
2560
- type: DYN,
2561
- loc,
2562
- };
2563
- const bag = read && !["name", "length", "apply"].includes(name)
2564
- ? {
2565
- kind: "call",
2566
- callee: this.constructorPropertyBag(lowerer, loc).name,
2567
- args: [instanceBag],
2568
- type: DYN,
2569
- loc,
2570
- }
2571
- : instanceBag;
2572
- // A read compares the bag with the receiver and then reads it:
2573
- // evaluate it once, so each read retains the receiver once.
2574
- const bagRead = varRef("bag.0", DYN, loc);
2575
- const bagGet = read
2576
- ? {
2577
- kind: "libCall",
2578
- fn: "dyn.bagGet",
2579
- args: [bagRead, read.key, varRef("p.0", DYN, loc)],
2580
- type: DYN,
2581
- loc,
2582
- }
2583
- : null;
2584
- // A class instance whose class chain declares no member of an
2585
- // Object.prototype method's name (classes that do answer in
2586
- // their own branches) inherits it unless an own property
2587
- // shadows it; a class constructor's static bag reads as before.
2588
- const instanceRead = read && INHERITED_OBJECT_METHODS.has(name)
2589
- ? {
2590
- kind: "ternary",
2591
- cond: {
2592
- kind: "dynTest",
2593
- test: "function",
2594
- value: varRef("p.0", DYN, loc),
2595
- type: BOOL,
2596
- loc,
2597
- },
2598
- then: bagGet,
2599
- else_: {
2600
- kind: "ternary",
2601
- cond: this.readBagHas(lowerer, "dyn.hasKey", bagRead, read.key, loc),
2602
- then: bagGet,
2603
- else_: {
2604
- kind: "libCall",
2605
- fn: "dyn.builtinMethod",
2606
- args: [{ kind: "strLit", value: "Object", type: STRING, loc }, read.key],
2607
- type: DYN,
2608
- loc,
2609
- },
2610
- type: DYN,
2611
- loc,
2612
- },
2613
- type: DYN,
2614
- loc,
2615
- }
2616
- : bagGet;
2617
- const fallback = read
2618
- ? {
2619
- kind: "ternary",
2620
- cond: {
2621
- kind: "dynScalarEq",
2622
- left: bagRead,
2623
- right: varRef("p.0", DYN, loc),
2624
- type: BOOL,
2625
- loc,
2626
- },
2627
- then: { ...read, value: bagRead },
2628
- else_: instanceRead,
2629
- type: DYN,
2630
- loc,
2631
- }
2632
- : { ...write, args: [bag, write.args[1], varRef("p.1", DYN, loc)] };
2633
- const helper = {
2634
- name: `%dyn.class.property.${this.properties.size}`,
2635
- params,
2636
- returnType: write ? VOID : DYN,
2637
- locals: [
2638
- ...params.map((p) => ({
2639
- id: p.localId,
2640
- name: p.name,
2641
- type: DYN,
2642
- mutable: false,
2643
- })),
2644
- ...(read ? [{ id: "bag.0", name: "bag", type: DYN, mutable: false }] : []),
2739
+ ]),
2645
2740
  ],
2646
- body: write
2647
- ? [
2648
- { kind: "exprStmt", expr: fallback, loc },
2649
- { kind: "return", value: null, loc },
2650
- ]
2651
- : [
2652
- { kind: "varDecl", localId: "bag.0", init: bag, loc },
2653
- {
2654
- kind: "return",
2655
- // Primitives answer their wrapper constructors.
2656
- value: name === "constructor"
2657
- ? primitiveConstructorOr(lowerer, varRef("p.0", DYN, loc), fallback, loc)
2658
- : fallback,
2659
- loc,
2660
- },
2661
- ],
2741
+ else_: null,
2662
2742
  loc,
2663
- };
2664
- if (!write && name === "toString" && lowerer.classes.has("%Error")) {
2665
- const value = varRef("p.0", DYN, loc);
2666
- helper.body.unshift({
2667
- kind: "if",
2668
- cond: { kind: "dynTest", test: "error", value, type: BOOL, loc },
2669
- then: [
2670
- {
2671
- kind: "return",
2672
- value: errorToStringMethod(lowerer, {
2673
- kind: "dynCheck",
2674
- value,
2675
- type: { kind: "object", className: "%Error" },
2676
- loc,
2677
- }),
2678
- loc,
2679
- },
2680
- ],
2681
- else_: null,
2743
+ }, {
2744
+ kind: "varDecl",
2745
+ localId: keyLocal,
2746
+ init: {
2747
+ kind: "libCall",
2748
+ fn: "dyn.toStringCoerce",
2749
+ args: [varRef("p.key", DYN, loc)],
2750
+ type: STRING,
2682
2751
  loc,
2683
- });
2684
- }
2685
- const receiverAccess = read
2686
- ? [{ kind: "return", value: { ...read, value: varRef("p.0", DYN, loc) }, loc }]
2687
- : [
2752
+ },
2753
+ loc,
2754
+ });
2755
+ if (indexKey) {
2756
+ // An integer index below a checked array's length names an
2757
+ // element (-0 included: its property name is "0"); dyn.arrLen
2758
+ // answers 0 for every other kind. Holes keep dyn.arrAt's
2759
+ // ordinary named lookup.
2760
+ const index = varRef("p.index", F64, loc);
2761
+ const elementRead = {
2762
+ kind: "if",
2763
+ cond: { kind: "libCall", fn: "number.isInteger", args: [index], type: BOOL, loc },
2764
+ then: [
2688
2765
  {
2689
- kind: "exprStmt",
2690
- expr: {
2691
- ...write,
2692
- args: [varRef("p.0", DYN, loc), write.args[1], varRef("p.1", DYN, loc)],
2766
+ kind: "if",
2767
+ cond: {
2768
+ kind: "bin",
2769
+ op: ">=",
2770
+ left: index,
2771
+ right: { kind: "numLit", value: 0, type: F64, loc },
2772
+ type: BOOL,
2773
+ loc,
2693
2774
  },
2775
+ then: [
2776
+ {
2777
+ kind: "if",
2778
+ cond: {
2779
+ kind: "bin",
2780
+ op: "<",
2781
+ left: index,
2782
+ right: {
2783
+ kind: "libCall",
2784
+ fn: "dyn.arrLen",
2785
+ args: [varRef("p.0", DYN, loc)],
2786
+ type: F64,
2787
+ loc,
2788
+ },
2789
+ type: BOOL,
2790
+ loc,
2791
+ },
2792
+ then: [
2793
+ {
2794
+ kind: "return",
2795
+ value: {
2796
+ kind: "libCall",
2797
+ fn: "dyn.arrAt",
2798
+ args: [varRef("p.0", DYN, loc), index],
2799
+ type: DYN,
2800
+ loc,
2801
+ },
2802
+ loc,
2803
+ },
2804
+ ],
2805
+ else_: null,
2806
+ loc,
2807
+ },
2808
+ ],
2809
+ else_: null,
2694
2810
  loc,
2695
2811
  },
2696
- { kind: "return", value: null, loc },
2697
- ];
2698
- dispatch = {
2699
- name,
2700
- write: !!write,
2701
- fn: helper,
2702
- classes: new Set(),
2703
- ...(name !== "constructor" && name !== "toString"
2704
- ? { plain: { tail: [...helper.body], access: receiverAccess } }
2705
- : {}),
2812
+ ],
2813
+ else_: null,
2814
+ loc,
2706
2815
  };
2707
- this.properties.set(key, dispatch);
2708
- this.generated.add(helper);
2709
- lowerer.liftedFns.push(helper);
2710
- changed = true;
2816
+ helper.body.unshift(elementRead, {
2817
+ kind: "varDecl",
2818
+ localId: keyLocal,
2819
+ init: { ...indexKey, operand: index },
2820
+ loc,
2821
+ });
2711
2822
  }
2712
- return {
2713
- kind: "call",
2714
- callee: dispatch.fn.name,
2715
- args: read ? [read.value] : [write.args[0], write.args[2]],
2716
- type: dispatch.fn.returnType,
2717
- loc: expr.loc,
2823
+ dispatch = {
2824
+ write: !!computedWrite,
2825
+ reflect,
2826
+ fn: helper,
2827
+ classes: new Set(),
2828
+ keyLocal,
2829
+ branchIndex: dynamicKey ? 3 : indexKey ? 2 : 0,
2830
+ dynamicKey,
2831
+ numericKey,
2832
+ probe,
2718
2833
  };
2834
+ this.computed.set(key, dispatch);
2835
+ this.generated.add(helper);
2836
+ lowerer.liftedFns.push(helper);
2837
+ changed = true;
2719
2838
  }
2720
- const iterator = expr.kind === "libCall" &&
2721
- (expr.fn === "dyn.iterator" ||
2722
- expr.fn === "dyn.arrayFromIterator" ||
2723
- expr.fn === "dyn.asyncIteratorOpen")
2724
- ? expr
2839
+ return {
2840
+ kind: "call",
2841
+ callee: dispatch.fn.name,
2842
+ args: reflect
2843
+ ? (reflectRead ?? reflectWrite).args
2844
+ : computedRead
2845
+ ? [computedRead.value, indexKey ? indexKey.operand : computedRead.key]
2846
+ : (computedWrite ?? computedProbe).args,
2847
+ type: dispatch.fn.returnType,
2848
+ loc: expr.loc,
2849
+ };
2850
+ }
2851
+ const read = expr.kind === "dynKeyGet" && expr.key.kind === "strLit" ? expr : null;
2852
+ const write = expr.kind === "libCall" && expr.fn === "dyn.keySet" && expr.args[1]?.kind === "strLit"
2853
+ ? expr
2854
+ : null;
2855
+ const name = read?.key.kind === "strLit"
2856
+ ? read.key.value
2857
+ : write?.args[1]?.kind === "strLit"
2858
+ ? write.args[1].value
2725
2859
  : null;
2726
- // `for await` opens a class instance's [Symbol.asyncIterator]().
2727
- const asyncOpen = iterator?.fn === "dyn.asyncIteratorOpen";
2728
- const invoke = iterator
2729
- ? {
2730
- kind: "dynInvoke",
2731
- recv: iterator.args[0],
2732
- method: asyncOpen ? "sym:asyncIterator" : "sym:iterator",
2733
- calleeName: asyncOpen ? "value[Symbol.asyncIterator]" : "value[Symbol.iterator]",
2734
- args: [],
2735
- type: DYN,
2736
- loc: iterator.loc,
2737
- }
2738
- : expr.kind === "dynInvoke"
2739
- ? expr
2740
- : null;
2741
- // Static methods matter only for methods no instance answers.
2742
- const staticCandidates = (method) => [...this.boxedConstructors].some((name) => {
2743
- const info = lowerer.classes.get(name);
2744
- return info && findStaticOn(lowerer, info, method)?.method;
2745
- });
2746
- if (!invoke ||
2747
- (candidates(invoke.method).length === 0 &&
2748
- !staticCandidates(invoke.method) &&
2749
- !(invoke.method === "toString" && lowerer.classes.has("%Error"))))
2750
- return expr;
2751
- const key = JSON.stringify([
2752
- invoke.method,
2753
- invoke.args.length,
2754
- iterator?.fn,
2755
- iterator?.args[1],
2756
- ]);
2757
- let dispatch = this.dispatches.get(key);
2860
+ if (name !== null) {
2861
+ const key = JSON.stringify([name, !!write, read?.optional ?? false]);
2862
+ let dispatch = this.properties.get(key);
2758
2863
  if (!dispatch) {
2759
- const params = [invoke.recv, ...invoke.args].map((_, i) => ({
2864
+ const loc = expr.loc;
2865
+ const params = (write ? [0, 1] : [0]).map((i) => ({
2760
2866
  localId: `p.${i}`,
2761
2867
  name: `p${i}`,
2762
2868
  type: DYN,
2763
2869
  }));
2764
- params.splice(1, 0, { localId: "p.callback", name: "callback", type: DYN });
2765
- iterator?.args.slice(1).forEach((argument, i) => params.push({
2766
- localId: `p.iterator.${i}`,
2767
- name: `iterator${i}`,
2768
- type: argument.type,
2769
- }));
2770
- params.push({ localId: "p.calleeName", name: "calleeName", type: STRING });
2771
- const callback = {
2772
- name: `%dyn.class.callback.${this.dispatches.size}`,
2773
- params: [params[0]],
2774
- returnType: DYN,
2775
- locals: [{ id: "p.0", name: "receiver", type: DYN, mutable: false }],
2776
- body: [{ kind: "return", value: dynUndefinedExpr(expr.loc), loc: expr.loc }],
2777
- loc: expr.loc,
2778
- };
2870
+ const instanceBag = read
2871
+ ? this.readPropertyBagOrEmpty(lowerer, varRef("p.0", DYN, loc), loc)
2872
+ : {
2873
+ kind: "call",
2874
+ callee: this.propertyBag.name,
2875
+ args: [varRef("p.0", DYN, loc)],
2876
+ type: DYN,
2877
+ loc,
2878
+ };
2879
+ const bag = read && !["name", "length", "apply"].includes(name)
2880
+ ? {
2881
+ kind: "call",
2882
+ callee: this.constructorPropertyBag(lowerer, loc).name,
2883
+ args: [instanceBag],
2884
+ type: DYN,
2885
+ loc,
2886
+ }
2887
+ : instanceBag;
2888
+ // A read compares the bag with the receiver and then reads it:
2889
+ // evaluate it once, so each read retains the receiver once.
2890
+ const bagRead = varRef("bag.0", DYN, loc);
2891
+ const bagGet = read
2892
+ ? {
2893
+ kind: "libCall",
2894
+ fn: "dyn.bagGet",
2895
+ args: [bagRead, read.key, varRef("p.0", DYN, loc)],
2896
+ type: DYN,
2897
+ loc,
2898
+ }
2899
+ : null;
2900
+ // A class instance whose class chain declares no member of an
2901
+ // Object.prototype method's name (classes that do answer in
2902
+ // their own branches) inherits it unless an own property
2903
+ // shadows it; a class constructor's static bag reads as before.
2904
+ const instanceRead = read && INHERITED_OBJECT_METHODS.has(name)
2905
+ ? {
2906
+ kind: "ternary",
2907
+ cond: {
2908
+ kind: "dynTest",
2909
+ test: "function",
2910
+ value: varRef("p.0", DYN, loc),
2911
+ type: BOOL,
2912
+ loc,
2913
+ },
2914
+ then: bagGet,
2915
+ else_: {
2916
+ kind: "ternary",
2917
+ cond: this.readBagHas(lowerer, "dyn.hasKey", bagRead, read.key, loc),
2918
+ then: bagGet,
2919
+ else_: {
2920
+ kind: "libCall",
2921
+ fn: "dyn.builtinMethod",
2922
+ args: [{ kind: "strLit", value: "Object", type: STRING, loc }, read.key],
2923
+ type: DYN,
2924
+ loc,
2925
+ },
2926
+ type: DYN,
2927
+ loc,
2928
+ },
2929
+ type: DYN,
2930
+ loc,
2931
+ }
2932
+ : bagGet;
2933
+ const fallback = read
2934
+ ? {
2935
+ kind: "ternary",
2936
+ cond: {
2937
+ kind: "dynScalarEq",
2938
+ left: bagRead,
2939
+ right: varRef("p.0", DYN, loc),
2940
+ type: BOOL,
2941
+ loc,
2942
+ },
2943
+ then: { ...read, value: bagRead },
2944
+ else_: instanceRead,
2945
+ type: DYN,
2946
+ loc,
2947
+ }
2948
+ : { ...write, args: [bag, write.args[1], varRef("p.1", DYN, loc)] };
2779
2949
  const helper = {
2780
- name: `%dyn.class.call.${this.dispatches.size}`,
2950
+ name: `%dyn.class.property.${this.properties.size}`,
2781
2951
  params,
2782
- returnType: DYN,
2783
- locals: params.map((p) => ({
2784
- id: p.localId,
2785
- name: p.name,
2786
- type: p.type,
2787
- mutable: false,
2788
- })),
2789
- body: [
2790
- {
2791
- kind: "return",
2792
- value: iterator
2793
- ? {
2794
- ...iterator,
2795
- args: [
2796
- varRef("p.0", DYN, expr.loc),
2797
- ...iterator.args
2798
- .slice(1)
2799
- .map((argument, i) => varRef(`p.iterator.${i}`, argument.type, expr.loc)),
2800
- ],
2801
- }
2802
- : {
2803
- ...invoke,
2804
- calleeNameValue: varRef("p.calleeName", STRING, expr.loc),
2805
- recv: varRef("p.0", DYN, expr.loc),
2806
- args: invoke.args.map((_, i) => varRef(`p.${i + 1}`, DYN, expr.loc)),
2807
- },
2808
- loc: expr.loc,
2809
- },
2952
+ returnType: write ? VOID : DYN,
2953
+ locals: [
2954
+ ...params.map((p) => ({
2955
+ id: p.localId,
2956
+ name: p.name,
2957
+ type: DYN,
2958
+ mutable: false,
2959
+ })),
2960
+ ...(read ? [{ id: "bag.0", name: "bag", type: DYN, mutable: false }] : []),
2810
2961
  ],
2811
- loc: expr.loc,
2962
+ body: write
2963
+ ? [
2964
+ { kind: "exprStmt", expr: fallback, loc },
2965
+ { kind: "return", value: null, loc },
2966
+ ]
2967
+ : [
2968
+ { kind: "varDecl", localId: "bag.0", init: bag, loc },
2969
+ {
2970
+ kind: "return",
2971
+ // Primitives answer their wrapper constructors.
2972
+ value: name === "constructor"
2973
+ ? primitiveConstructorOr(lowerer, varRef("p.0", DYN, loc), fallback, loc)
2974
+ : fallback,
2975
+ loc,
2976
+ },
2977
+ ],
2978
+ loc,
2812
2979
  };
2813
- if (invoke.method === "toString" && lowerer.classes.has("%Error")) {
2814
- const loc = expr.loc;
2980
+ if (!write && name === "toString" && lowerer.classes.has("%Error")) {
2815
2981
  const value = varRef("p.0", DYN, loc);
2816
2982
  helper.body.unshift({
2817
2983
  kind: "if",
@@ -2819,21 +2985,12 @@ export class ClassDynamicDispatch {
2819
2985
  then: [
2820
2986
  {
2821
2987
  kind: "return",
2822
- value: {
2823
- kind: "dynCall",
2824
- callee: errorToStringMethod(lowerer, {
2825
- kind: "dynCheck",
2826
- value,
2827
- type: { kind: "object", className: "%Error" },
2828
- loc,
2829
- }),
2830
- receiver: value,
2831
- calleeName: invoke.calleeName,
2832
- calleeNameValue: varRef("p.calleeName", STRING, loc),
2833
- args: invoke.args.map((_, i) => varRef(`p.${i + 1}`, DYN, loc)),
2834
- type: DYN,
2988
+ value: errorToStringMethod(lowerer, {
2989
+ kind: "dynCheck",
2990
+ value,
2991
+ type: { kind: "object", className: "%Error" },
2835
2992
  loc,
2836
- },
2993
+ }),
2837
2994
  loc,
2838
2995
  },
2839
2996
  ],
@@ -2841,54 +2998,237 @@ export class ClassDynamicDispatch {
2841
2998
  loc,
2842
2999
  });
2843
3000
  }
2844
- dispatch = { source: invoke, fn: helper, callback, classes: new Set() };
2845
- this.dispatches.set(key, dispatch);
3001
+ const receiverAccess = read
3002
+ ? [{ kind: "return", value: { ...read, value: varRef("p.0", DYN, loc) }, loc }]
3003
+ : [
3004
+ {
3005
+ kind: "exprStmt",
3006
+ expr: {
3007
+ ...write,
3008
+ args: [varRef("p.0", DYN, loc), write.args[1], varRef("p.1", DYN, loc)],
3009
+ },
3010
+ loc,
3011
+ },
3012
+ { kind: "return", value: null, loc },
3013
+ ];
3014
+ dispatch = {
3015
+ name,
3016
+ write: !!write,
3017
+ fn: helper,
3018
+ classes: new Set(),
3019
+ ...(name !== "constructor" && name !== "toString"
3020
+ ? { plain: { tail: [...helper.body], access: receiverAccess } }
3021
+ : {}),
3022
+ };
3023
+ this.properties.set(key, dispatch);
2846
3024
  this.generated.add(helper);
2847
- this.generated.add(callback);
2848
- lowerer.liftedFns.push(helper, callback);
3025
+ lowerer.liftedFns.push(helper);
2849
3026
  changed = true;
2850
3027
  }
2851
- // Resolve an own callback before argument effects can replace it.
2852
- const local = {
2853
- id: `%dispatch.receiver.${fn.locals.length}`,
2854
- name: "receiver",
3028
+ return {
3029
+ kind: "call",
3030
+ callee: dispatch.fn.name,
3031
+ args: read ? [read.value] : [write.args[0], write.args[2]],
3032
+ type: dispatch.fn.returnType,
3033
+ loc: expr.loc,
3034
+ };
3035
+ }
3036
+ const iterator = expr.kind === "libCall" &&
3037
+ (expr.fn === "dyn.iterator" ||
3038
+ expr.fn === "dyn.arrayFromIterator" ||
3039
+ expr.fn === "dyn.asyncIteratorOpen")
3040
+ ? expr
3041
+ : null;
3042
+ // `for await` opens a class instance's [Symbol.asyncIterator]().
3043
+ const asyncOpen = iterator?.fn === "dyn.asyncIteratorOpen";
3044
+ const invoke = iterator
3045
+ ? {
3046
+ kind: "dynInvoke",
3047
+ recv: iterator.args[0],
3048
+ method: asyncOpen ? "sym:asyncIterator" : "sym:iterator",
3049
+ calleeName: asyncOpen ? "value[Symbol.asyncIterator]" : "value[Symbol.iterator]",
3050
+ args: [],
2855
3051
  type: DYN,
2856
- mutable: false,
3052
+ loc: iterator.loc,
3053
+ }
3054
+ : expr.kind === "dynInvoke"
3055
+ ? expr
3056
+ : null;
3057
+ // Static methods matter only for methods no instance answers.
3058
+ const staticCandidates = (method) => [...this.boxedConstructors].some((name) => {
3059
+ const info = lowerer.classes.get(name);
3060
+ return info && findStaticOn(lowerer, info, method)?.method;
3061
+ });
3062
+ if (invoke &&
3063
+ expr.kind === "dynInvoke" &&
3064
+ candidates(invoke.method).length === 0 &&
3065
+ !staticCandidates(invoke.method)) {
3066
+ // The other receivers' call a rewrite left in place tests only
3067
+ // the classes that rewrite did not.
3068
+ const covered = expr.recv.kind === "varRef" ? this.getterReceivers.get(expr.recv.localId) : undefined;
3069
+ const capsules = getterCapsules(invoke.method).filter((key) => !covered?.has(key));
3070
+ if (capsules.length > 0)
3071
+ return getterCall(fn, expr, capsules, covered);
3072
+ }
3073
+ if (!invoke ||
3074
+ (candidates(invoke.method).length === 0 &&
3075
+ !staticCandidates(invoke.method) &&
3076
+ !(invoke.method === "toString" && lowerer.classes.has("%Error"))))
3077
+ return expr;
3078
+ const key = JSON.stringify([
3079
+ invoke.method,
3080
+ invoke.args.length,
3081
+ iterator?.fn,
3082
+ iterator?.args[1],
3083
+ ]);
3084
+ let dispatch = this.dispatches.get(key);
3085
+ if (!dispatch) {
3086
+ const params = [invoke.recv, ...invoke.args].map((_, i) => ({
3087
+ localId: `p.${i}`,
3088
+ name: `p${i}`,
3089
+ type: DYN,
3090
+ }));
3091
+ params.splice(1, 0, { localId: "p.callback", name: "callback", type: DYN });
3092
+ iterator?.args.slice(1).forEach((argument, i) => params.push({
3093
+ localId: `p.iterator.${i}`,
3094
+ name: `iterator${i}`,
3095
+ type: argument.type,
3096
+ }));
3097
+ params.push({ localId: "p.calleeName", name: "calleeName", type: STRING });
3098
+ const callback = {
3099
+ name: `%dyn.class.callback.${this.dispatches.size}`,
3100
+ params: [params[0]],
3101
+ returnType: DYN,
3102
+ locals: [{ id: "p.0", name: "receiver", type: DYN, mutable: false }],
3103
+ body: [{ kind: "return", value: dynUndefinedExpr(expr.loc), loc: expr.loc }],
3104
+ loc: expr.loc,
2857
3105
  };
2858
- fn.locals.push(local);
2859
- const receiver = varRef(local.id, DYN, expr.loc);
2860
- return {
2861
- kind: "seqExpr",
2862
- stmts: [{ kind: "varDecl", localId: local.id, init: invoke.recv, loc: expr.loc }],
2863
- result: {
2864
- kind: "call",
2865
- callee: dispatch.fn.name,
2866
- args: [
2867
- receiver,
3106
+ const helper = {
3107
+ name: `%dyn.class.call.${this.dispatches.size}`,
3108
+ params,
3109
+ returnType: DYN,
3110
+ locals: params.map((p) => ({
3111
+ id: p.localId,
3112
+ name: p.name,
3113
+ type: p.type,
3114
+ mutable: false,
3115
+ })),
3116
+ body: [
3117
+ {
3118
+ kind: "return",
3119
+ value: iterator
3120
+ ? {
3121
+ ...iterator,
3122
+ args: [
3123
+ varRef("p.0", DYN, expr.loc),
3124
+ ...iterator.args
3125
+ .slice(1)
3126
+ .map((argument, i) => varRef(`p.iterator.${i}`, argument.type, expr.loc)),
3127
+ ],
3128
+ }
3129
+ : {
3130
+ ...invoke,
3131
+ calleeNameValue: varRef("p.calleeName", STRING, expr.loc),
3132
+ recv: varRef("p.0", DYN, expr.loc),
3133
+ args: invoke.args.map((_, i) => varRef(`p.${i + 1}`, DYN, expr.loc)),
3134
+ },
3135
+ loc: expr.loc,
3136
+ },
3137
+ ],
3138
+ loc: expr.loc,
3139
+ };
3140
+ if (invoke.method === "toString" && lowerer.classes.has("%Error")) {
3141
+ const loc = expr.loc;
3142
+ const value = varRef("p.0", DYN, loc);
3143
+ helper.body.unshift({
3144
+ kind: "if",
3145
+ cond: { kind: "dynTest", test: "error", value, type: BOOL, loc },
3146
+ then: [
2868
3147
  {
2869
- kind: "call",
2870
- callee: dispatch.callback.name,
2871
- args: [receiver],
2872
- type: DYN,
2873
- loc: expr.loc,
2874
- },
2875
- ...invoke.args,
2876
- ...(iterator?.args.slice(1) ?? []),
2877
- invoke.calleeNameValue ?? {
2878
- kind: "strLit",
2879
- value: invoke.calleeName,
2880
- type: STRING,
2881
- loc: expr.loc,
3148
+ kind: "return",
3149
+ value: {
3150
+ kind: "dynCall",
3151
+ callee: errorToStringMethod(lowerer, {
3152
+ kind: "dynCheck",
3153
+ value,
3154
+ type: { kind: "object", className: "%Error" },
3155
+ loc,
3156
+ }),
3157
+ receiver: value,
3158
+ calleeName: invoke.calleeName,
3159
+ calleeNameValue: varRef("p.calleeName", STRING, loc),
3160
+ args: invoke.args.map((_, i) => varRef(`p.${i + 1}`, DYN, loc)),
3161
+ type: DYN,
3162
+ loc,
3163
+ },
3164
+ loc,
2882
3165
  },
2883
3166
  ],
2884
- type: DYN,
2885
- loc: expr.loc,
2886
- },
3167
+ else_: null,
3168
+ loc,
3169
+ });
3170
+ }
3171
+ dispatch = { source: invoke, fn: helper, callback, classes: new Set() };
3172
+ this.dispatches.set(key, dispatch);
3173
+ this.generated.add(helper);
3174
+ this.generated.add(callback);
3175
+ lowerer.liftedFns.push(helper, callback);
3176
+ changed = true;
3177
+ }
3178
+ // Resolve an own callback before argument effects can replace it.
3179
+ const local = {
3180
+ id: `%dispatch.receiver.${fn.locals.length}`,
3181
+ name: "receiver",
3182
+ type: DYN,
3183
+ mutable: false,
3184
+ };
3185
+ fn.locals.push(local);
3186
+ const receiver = varRef(local.id, DYN, expr.loc);
3187
+ return {
3188
+ kind: "seqExpr",
3189
+ stmts: [{ kind: "varDecl", localId: local.id, init: invoke.recv, loc: expr.loc }],
3190
+ result: {
3191
+ kind: "call",
3192
+ callee: dispatch.fn.name,
3193
+ args: [
3194
+ receiver,
3195
+ {
3196
+ kind: "call",
3197
+ callee: dispatch.callback.name,
3198
+ args: [receiver],
3199
+ type: DYN,
3200
+ loc: expr.loc,
3201
+ },
3202
+ ...invoke.args,
3203
+ ...(iterator?.args.slice(1) ?? []),
3204
+ invoke.calleeNameValue ?? {
3205
+ kind: "strLit",
3206
+ value: invoke.calleeName,
3207
+ type: STRING,
3208
+ loc: expr.loc,
3209
+ },
3210
+ ],
2887
3211
  type: DYN,
2888
3212
  loc: expr.loc,
2889
- };
3213
+ },
3214
+ type: DYN,
3215
+ loc: expr.loc,
3216
+ };
3217
+ };
3218
+ let touched = false;
3219
+ const body = transformStmtList(fn.body, {
3220
+ stmt: (stmt) => stmt,
3221
+ expr: (expr) => {
3222
+ const rewritten = rewriteExpr(expr);
3223
+ if (rewritten !== expr)
3224
+ touched = true;
3225
+ return rewritten;
2890
3226
  },
2891
3227
  });
3228
+ // A body the rewrite did not change keeps its statement list, so the
3229
+ // dispatch-site summaries the pass keeps stay valid.
3230
+ if (touched)
3231
+ fn.body = body;
2892
3232
  }
2893
3233
  for (const [target, cast] of this.checkedCasts) {
2894
3234
  for (const source of this.boxed) {
@@ -2932,6 +3272,11 @@ export class ClassDynamicDispatch {
2932
3272
  for (const dispatch of this.dispatches.values()) {
2933
3273
  for (const name of this.boxedConstructors) {
2934
3274
  const info = lowerer.classes.get(name);
3275
+ // The class value's property table answers a static its chain defines
3276
+ // there, computed names included; the declarer's method is not what
3277
+ // the class value holds.
3278
+ if (info && runtimeStaticDefines(lowerer, info, dispatch.source.method))
3279
+ continue;
2935
3280
  const found = info && findStaticOn(lowerer, info, dispatch.source.method);
2936
3281
  const key = `constructor:${name}`;
2937
3282
  if (!found?.method || dispatch.classes.has(key))
@@ -3222,6 +3567,9 @@ export class ClassDynamicDispatch {
3222
3567
  if (!dispatch.write)
3223
3568
  for (const name of this.boxedConstructors) {
3224
3569
  const info = lowerer.classes.get(name);
3570
+ // A table the chain defines the name in answers the read itself.
3571
+ if (info && runtimeStaticDefines(lowerer, info, dispatch.name))
3572
+ continue;
3225
3573
  const found = info && findStaticOn(lowerer, info, dispatch.name);
3226
3574
  const field = found?.field;
3227
3575
  const key = `constructor:${name}`;
@@ -4906,6 +5254,25 @@ export class ClassDynamicDispatch {
4906
5254
  this.guardClassTables(lowerer);
4907
5255
  if (lowerer)
4908
5256
  this.guardPropertyHelpers(lowerer);
5257
+ if (lowerer)
5258
+ this.indexClassBranches(lowerer);
5259
+ }
5260
+ /** Each generated class table tests its classes in order, one exact type
5261
+ * key test per class, so a receiver costs time linear in the program's
5262
+ * class count. Replace each run of such branches with a switch on the
5263
+ * length and last four bytes of the receiver's key: the branches
5264
+ * themselves stay, each still guarded by its key test, and the switch
5265
+ * selects the class the receiver is. Runs whose branches continue instead
5266
+ * of leaving the helper, or that hold fewer than sixty-four distinct classes,
5267
+ * keep the chain. */
5268
+ indexClassBranches(lowerer) {
5269
+ const seen = new Set();
5270
+ for (const fn of [...this.generated, ...lowerer.liftedFns]) {
5271
+ if (seen.has(fn))
5272
+ continue;
5273
+ seen.add(fn);
5274
+ fn.body = indexBranchRuns(fn.body);
5275
+ }
4909
5276
  }
4910
5277
  /** Each tracked class's bag initializer over a typed receiver (`this`),
4911
5278
  * for the per-class field-creation helpers (trackClassFieldCreation),