@scriptc/compiler 0.4.2 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (636) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +397 -37
  2. package/dist/backend/cycle-analysis.d.ts +4 -1
  3. package/dist/backend/cycle-analysis.js +6 -4
  4. package/dist/backend/cycle-analysis.js.map +1 -1
  5. package/dist/backend/cycle-analysis.test.js +55 -0
  6. package/dist/backend/cycle-analysis.test.js.map +1 -1
  7. package/dist/backend/cycle-mutability.d.ts +7 -0
  8. package/dist/backend/cycle-mutability.js +19 -1
  9. package/dist/backend/cycle-mutability.js.map +1 -1
  10. package/dist/backend/executable-features.js +2 -0
  11. package/dist/backend/executable-features.js.map +1 -1
  12. package/dist/backend/immutability.d.ts +6 -3
  13. package/dist/backend/immutability.js +33 -29
  14. package/dist/backend/immutability.js.map +1 -1
  15. package/dist/backend/library-pack.js +1 -0
  16. package/dist/backend/library-pack.js.map +1 -1
  17. package/dist/backend/llvm/alloc.d.ts +16 -1
  18. package/dist/backend/llvm/alloc.js +54 -4
  19. package/dist/backend/llvm/alloc.js.map +1 -1
  20. package/dist/backend/llvm/appended-array-literals.d.ts +2 -1
  21. package/dist/backend/llvm/appended-array-literals.js +44 -36
  22. package/dist/backend/llvm/appended-array-literals.js.map +1 -1
  23. package/dist/backend/llvm/appended-array-literals.test.js +4 -3
  24. package/dist/backend/llvm/appended-array-literals.test.js.map +1 -1
  25. package/dist/backend/llvm/array-search.d.ts +4 -3
  26. package/dist/backend/llvm/array-search.js +21 -9
  27. package/dist/backend/llvm/array-search.js.map +1 -1
  28. package/dist/backend/llvm/blocks.d.ts +1 -1
  29. package/dist/backend/llvm/blocks.js +2 -2
  30. package/dist/backend/llvm/blocks.js.map +1 -1
  31. package/dist/backend/llvm/byte-windows.js +2 -0
  32. package/dist/backend/llvm/byte-windows.js.map +1 -1
  33. package/dist/backend/llvm/bytes-alias.d.ts +6 -1
  34. package/dist/backend/llvm/bytes-alias.js +8 -2
  35. package/dist/backend/llvm/bytes-alias.js.map +1 -1
  36. package/dist/backend/llvm/bytes-loop-versions.d.ts +47 -5
  37. package/dist/backend/llvm/bytes-loop-versions.js +473 -32
  38. package/dist/backend/llvm/bytes-loop-versions.js.map +1 -1
  39. package/dist/backend/llvm/bytes-loop-versions.test.js +258 -2
  40. package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -1
  41. package/dist/backend/llvm/checked-value-lifetimes.js +2 -0
  42. package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
  43. package/dist/backend/llvm/classes.d.ts +7 -5
  44. package/dist/backend/llvm/classes.js +44 -20
  45. package/dist/backend/llvm/classes.js.map +1 -1
  46. package/dist/backend/llvm/classes.test.js +167 -7
  47. package/dist/backend/llvm/classes.test.js.map +1 -1
  48. package/dist/backend/llvm/common.d.ts +9 -3
  49. package/dist/backend/llvm/common.js +9 -3
  50. package/dist/backend/llvm/common.js.map +1 -1
  51. package/dist/backend/llvm/constant-callbacks.d.ts +2 -1
  52. package/dist/backend/llvm/constant-callbacks.js +83 -52
  53. package/dist/backend/llvm/constant-callbacks.js.map +1 -1
  54. package/dist/backend/llvm/counted-loops.d.ts +7 -0
  55. package/dist/backend/llvm/counted-loops.js +18 -0
  56. package/dist/backend/llvm/counted-loops.js.map +1 -1
  57. package/dist/backend/llvm/dense-array-access.d.ts +39 -8
  58. package/dist/backend/llvm/dense-array-access.js +222 -52
  59. package/dist/backend/llvm/dense-array-access.js.map +1 -1
  60. package/dist/backend/llvm/dense-array-access.test.js +36 -0
  61. package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
  62. package/dist/backend/llvm/dense-array-loops.d.ts +17 -1
  63. package/dist/backend/llvm/dense-array-loops.js +194 -5
  64. package/dist/backend/llvm/dense-array-loops.js.map +1 -1
  65. package/dist/backend/llvm/dense-array-loops.test.js +90 -1
  66. package/dist/backend/llvm/dense-array-loops.test.js.map +1 -1
  67. package/dist/backend/llvm/dyn-handle-tags.test.js +6 -1
  68. package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -1
  69. package/dist/backend/llvm/dyn.d.ts +26 -0
  70. package/dist/backend/llvm/dyn.js +352 -61
  71. package/dist/backend/llvm/dyn.js.map +1 -1
  72. package/dist/backend/llvm/emit-function.js +11 -20
  73. package/dist/backend/llvm/emit-function.js.map +1 -1
  74. package/dist/backend/llvm/emit-journal.d.ts +93 -0
  75. package/dist/backend/llvm/emit-journal.js +170 -0
  76. package/dist/backend/llvm/emit-journal.js.map +1 -0
  77. package/dist/backend/llvm/emit-module.js +195 -27
  78. package/dist/backend/llvm/emit-module.js.map +1 -1
  79. package/dist/backend/llvm/emit-statements.d.ts +0 -4
  80. package/dist/backend/llvm/emit-statements.js +268 -84
  81. package/dist/backend/llvm/emit-statements.js.map +1 -1
  82. package/dist/backend/llvm/emitter-state.d.ts +7 -0
  83. package/dist/backend/llvm/emitter-state.js +14 -0
  84. package/dist/backend/llvm/emitter-state.js.map +1 -0
  85. package/dist/backend/llvm/emitter.d.ts +176 -37
  86. package/dist/backend/llvm/emitter.js +724 -85
  87. package/dist/backend/llvm/emitter.js.map +1 -1
  88. package/dist/backend/llvm/emitter.test.js +54 -5
  89. package/dist/backend/llvm/emitter.test.js.map +1 -1
  90. package/dist/backend/llvm/expr-bytes.js +34 -12
  91. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  92. package/dist/backend/llvm/expr-callbacks.js +47 -0
  93. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  94. package/dist/backend/llvm/expr-calls.js +28 -14
  95. package/dist/backend/llvm/expr-calls.js.map +1 -1
  96. package/dist/backend/llvm/expr-containers.d.ts +14 -2
  97. package/dist/backend/llvm/expr-containers.js +129 -37
  98. package/dist/backend/llvm/expr-containers.js.map +1 -1
  99. package/dist/backend/llvm/expr-context.d.ts +14 -0
  100. package/dist/backend/llvm/expr-dynamic.js +18 -11
  101. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  102. package/dist/backend/llvm/expr-primitives.js +100 -28
  103. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  104. package/dist/backend/llvm/expr-primitives.test.js +11 -6
  105. package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
  106. package/dist/backend/llvm/expr-records.d.ts +12 -0
  107. package/dist/backend/llvm/expr-records.js +106 -0
  108. package/dist/backend/llvm/expr-records.js.map +1 -1
  109. package/dist/backend/llvm/expr-stream-bridges.d.ts +2 -2
  110. package/dist/backend/llvm/expr-stream-bridges.js +194 -65
  111. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  112. package/dist/backend/llvm/expr-stream-bridges.test.js +1 -1
  113. package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -1
  114. package/dist/backend/llvm/expr-stream-callbacks.d.ts +2 -2
  115. package/dist/backend/llvm/expr-stream-callbacks.js +74 -20
  116. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  117. package/dist/backend/llvm/int32-kind-loops.d.ts +39 -0
  118. package/dist/backend/llvm/int32-kind-loops.js +106 -0
  119. package/dist/backend/llvm/int32-kind-loops.js.map +1 -0
  120. package/dist/backend/llvm/integer-or-nan-indexes.test.d.ts +1 -0
  121. package/dist/backend/llvm/integer-or-nan-indexes.test.js +118 -0
  122. package/dist/backend/llvm/integer-or-nan-indexes.test.js.map +1 -0
  123. package/dist/backend/llvm/integer-values.d.ts +20 -1
  124. package/dist/backend/llvm/integer-values.js +71 -0
  125. package/dist/backend/llvm/integer-values.js.map +1 -1
  126. package/dist/backend/llvm/js-ic.d.ts +1 -1
  127. package/dist/backend/llvm/js-ic.js +1 -1
  128. package/dist/backend/llvm/js-ic.js.map +1 -1
  129. package/dist/backend/llvm/key-orders.d.ts +7 -0
  130. package/dist/backend/llvm/key-orders.js +33 -0
  131. package/dist/backend/llvm/key-orders.js.map +1 -0
  132. package/dist/backend/llvm/lib-connect.js +4 -0
  133. package/dist/backend/llvm/lib-connect.js.map +1 -1
  134. package/dist/backend/llvm/lib-datagram.js +11 -0
  135. package/dist/backend/llvm/lib-datagram.js.map +1 -1
  136. package/dist/backend/llvm/lib-dispatch.js +80 -2
  137. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  138. package/dist/backend/llvm/lib-filesystem.js +4 -4
  139. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  140. package/dist/backend/llvm/lib-http2.js +4 -0
  141. package/dist/backend/llvm/lib-http2.js.map +1 -1
  142. package/dist/backend/llvm/lib-lookup.js +16 -6
  143. package/dist/backend/llvm/lib-lookup.js.map +1 -1
  144. package/dist/backend/llvm/lib-shared.js +73 -2
  145. package/dist/backend/llvm/lib-shared.js.map +1 -1
  146. package/dist/backend/llvm/lib-stream.js +35 -5
  147. package/dist/backend/llvm/lib-stream.js.map +1 -1
  148. package/dist/backend/llvm/local-array-reads.js +115 -19
  149. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  150. package/dist/backend/llvm/local-array-reads.test.js +14 -0
  151. package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
  152. package/dist/backend/llvm/loop-state.d.ts +33 -0
  153. package/dist/backend/llvm/loop-state.js +42 -0
  154. package/dist/backend/llvm/loop-state.js.map +1 -0
  155. package/dist/backend/llvm/map-number-lookup.d.ts +26 -8
  156. package/dist/backend/llvm/map-number-lookup.js +91 -31
  157. package/dist/backend/llvm/map-number-lookup.js.map +1 -1
  158. package/dist/backend/llvm/map-number-lookup.test.js +55 -0
  159. package/dist/backend/llvm/map-number-lookup.test.js.map +1 -1
  160. package/dist/backend/llvm/map-read-lifetimes.js +4 -2
  161. package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
  162. package/dist/backend/llvm/nullable-unions.d.ts +2 -1
  163. package/dist/backend/llvm/nullable-unions.js +15 -3
  164. package/dist/backend/llvm/nullable-unions.js.map +1 -1
  165. package/dist/backend/llvm/publish.d.ts +10 -0
  166. package/dist/backend/llvm/publish.js +12 -0
  167. package/dist/backend/llvm/publish.js.map +1 -1
  168. package/dist/backend/llvm/receivers.js +6 -1
  169. package/dist/backend/llvm/receivers.js.map +1 -1
  170. package/dist/backend/llvm/record-results.d.ts +1 -9
  171. package/dist/backend/llvm/record-results.js +2 -11
  172. package/dist/backend/llvm/record-results.js.map +1 -1
  173. package/dist/backend/llvm/reference-writes.d.ts +7 -2
  174. package/dist/backend/llvm/reference-writes.js +89 -72
  175. package/dist/backend/llvm/reference-writes.js.map +1 -1
  176. package/dist/backend/llvm/running-extrema.d.ts +11 -0
  177. package/dist/backend/llvm/running-extrema.js +115 -0
  178. package/dist/backend/llvm/running-extrema.js.map +1 -0
  179. package/dist/backend/llvm/running-extrema.test.d.ts +1 -0
  180. package/dist/backend/llvm/running-extrema.test.js +89 -0
  181. package/dist/backend/llvm/running-extrema.test.js.map +1 -0
  182. package/dist/backend/llvm/shapes.d.ts +71 -15
  183. package/dist/backend/llvm/shapes.js +222 -33
  184. package/dist/backend/llvm/shapes.js.map +1 -1
  185. package/dist/backend/llvm/shapes.test.js +53 -7
  186. package/dist/backend/llvm/shapes.test.js.map +1 -1
  187. package/dist/backend/llvm/speculative-integers.d.ts +6 -0
  188. package/dist/backend/llvm/speculative-integers.js +2 -2
  189. package/dist/backend/llvm/speculative-integers.js.map +1 -1
  190. package/dist/backend/llvm/stack-objects.d.ts +3 -2
  191. package/dist/backend/llvm/stack-objects.js +5 -2
  192. package/dist/backend/llvm/stack-objects.js.map +1 -1
  193. package/dist/backend/llvm/string-reads.d.ts +12 -0
  194. package/dist/backend/llvm/string-reads.js +44 -0
  195. package/dist/backend/llvm/string-reads.js.map +1 -1
  196. package/dist/backend/llvm/walk-borrows.d.ts +3 -0
  197. package/dist/backend/llvm/walk-borrows.js +46 -41
  198. package/dist/backend/llvm/walk-borrows.js.map +1 -1
  199. package/dist/backend/llvm/walkers.d.ts +3 -0
  200. package/dist/backend/llvm/walkers.js +88 -65
  201. package/dist/backend/llvm/walkers.js.map +1 -1
  202. package/dist/backend/llvm/wrapping-sums.d.ts +16 -1
  203. package/dist/backend/llvm/wrapping-sums.js +126 -0
  204. package/dist/backend/llvm/wrapping-sums.js.map +1 -1
  205. package/dist/backend/may-throw.d.ts +8 -10
  206. package/dist/backend/may-throw.js +14 -10
  207. package/dist/backend/may-throw.js.map +1 -1
  208. package/dist/backend/native/contracts.d.ts +5 -0
  209. package/dist/backend/native/executable.js +7 -0
  210. package/dist/backend/native/executable.js.map +1 -1
  211. package/dist/backend/native/runtime-inputs.d.ts +1 -1
  212. package/dist/backend/native/runtime-inputs.js +1 -0
  213. package/dist/backend/native/runtime-inputs.js.map +1 -1
  214. package/dist/backend/native-link-info-core.d.ts +4 -0
  215. package/dist/backend/native-link-info-core.js.map +1 -1
  216. package/dist/backend/publication.d.ts +12 -1
  217. package/dist/backend/publication.js +37 -14
  218. package/dist/backend/publication.js.map +1 -1
  219. package/dist/backend/publication.test.js +30 -0
  220. package/dist/backend/publication.test.js.map +1 -1
  221. package/dist/backend/result-slots.d.ts +16 -0
  222. package/dist/backend/result-slots.js +23 -0
  223. package/dist/backend/result-slots.js.map +1 -0
  224. package/dist/backend/runtime-abi.d.ts +2 -2
  225. package/dist/backend/runtime-abi.js +2 -2
  226. package/dist/backend/runtime-pack-core.d.ts +1 -0
  227. package/dist/backend/runtime-pack-core.js +1 -0
  228. package/dist/backend/runtime-pack-core.js.map +1 -1
  229. package/dist/backend/runtime-pack-targets.test.js +2 -1
  230. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  231. package/dist/backend/runtime-pack.test.js +2 -1
  232. package/dist/backend/runtime-pack.test.js.map +1 -1
  233. package/dist/backend/stack-observations.d.ts +2 -1
  234. package/dist/backend/stack-observations.js +67 -42
  235. package/dist/backend/stack-observations.js.map +1 -1
  236. package/dist/backend/target-diagnostics.js +5 -3
  237. package/dist/backend/target-diagnostics.js.map +1 -1
  238. package/dist/backend/warm-cache.js +1 -0
  239. package/dist/backend/warm-cache.js.map +1 -1
  240. package/dist/cli/usage.d.ts +1 -1
  241. package/dist/cli/usage.js +3 -3
  242. package/dist/compat/fetch-profile.js +1 -1
  243. package/dist/compat/fetch-profile.js.map +1 -1
  244. package/dist/contracts/check.js +4 -3
  245. package/dist/contracts/check.js.map +1 -1
  246. package/dist/contracts/int32-elements.js +10 -2
  247. package/dist/contracts/int32-elements.js.map +1 -1
  248. package/dist/coverage/report.js +12 -3
  249. package/dist/coverage/report.js.map +1 -1
  250. package/dist/diagnostics/diagnostic.d.ts +4 -0
  251. package/dist/diagnostics/diagnostic.js.map +1 -1
  252. package/dist/diagnostics/envelope.d.ts +3 -0
  253. package/dist/diagnostics/envelope.js +1 -0
  254. package/dist/diagnostics/envelope.js.map +1 -1
  255. package/dist/executable/executable-cache.d.ts +2 -0
  256. package/dist/executable/executable-cache.js +1 -0
  257. package/dist/executable/executable-cache.js.map +1 -1
  258. package/dist/executable/executable-cache.test.js +1 -0
  259. package/dist/executable/executable-cache.test.js.map +1 -1
  260. package/dist/frontend/decl-projection.d.ts +41 -0
  261. package/dist/frontend/decl-projection.js +854 -0
  262. package/dist/frontend/decl-projection.js.map +1 -0
  263. package/dist/frontend/decl-projection.test.d.ts +1 -0
  264. package/dist/frontend/decl-projection.test.js +30 -0
  265. package/dist/frontend/decl-projection.test.js.map +1 -0
  266. package/dist/frontend/dts-paths.d.ts +15 -0
  267. package/dist/frontend/dts-paths.js +25 -0
  268. package/dist/frontend/dts-paths.js.map +1 -1
  269. package/dist/frontend/input-tracker.d.ts +6 -0
  270. package/dist/frontend/input-tracker.js +51 -28
  271. package/dist/frontend/input-tracker.js.map +1 -1
  272. package/dist/frontend/input-tracker.test.js +19 -0
  273. package/dist/frontend/input-tracker.test.js.map +1 -1
  274. package/dist/frontend/lowering/array-values.js +100 -2
  275. package/dist/frontend/lowering/array-values.js.map +1 -1
  276. package/dist/frontend/lowering/builtins/child-process-methods.js +46 -15
  277. package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
  278. package/dist/frontend/lowering/builtins/child-process.js +13 -2
  279. package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
  280. package/dist/frontend/lowering/builtins/crypto.js +84 -9
  281. package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
  282. package/dist/frontend/lowering/builtins/global-namespace-keys.d.ts +3 -0
  283. package/dist/frontend/lowering/builtins/global-namespace-keys.js +122 -0
  284. package/dist/frontend/lowering/builtins/global-namespace-keys.js.map +1 -0
  285. package/dist/frontend/lowering/builtins/numbers.js +9 -1
  286. package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
  287. package/dist/frontend/lowering/builtins/promises.d.ts +6 -0
  288. package/dist/frontend/lowering/builtins/promises.js +88 -2
  289. package/dist/frontend/lowering/builtins/promises.js.map +1 -1
  290. package/dist/frontend/lowering/builtins/readline.d.ts +5 -1
  291. package/dist/frontend/lowering/builtins/readline.js +35 -3
  292. package/dist/frontend/lowering/builtins/readline.js.map +1 -1
  293. package/dist/frontend/lowering/builtins/url.js +24 -1
  294. package/dist/frontend/lowering/builtins/url.js.map +1 -1
  295. package/dist/frontend/lowering/builtins/webassembly.js +6 -3
  296. package/dist/frontend/lowering/builtins/webassembly.js.map +1 -1
  297. package/dist/frontend/lowering/class-callbacks.d.ts +5 -2
  298. package/dist/frontend/lowering/class-callbacks.js +82 -12
  299. package/dist/frontend/lowering/class-callbacks.js.map +1 -1
  300. package/dist/frontend/lowering/class-construction.d.ts +4 -1
  301. package/dist/frontend/lowering/class-construction.js +17 -3
  302. package/dist/frontend/lowering/class-construction.js.map +1 -1
  303. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +39 -2
  304. package/dist/frontend/lowering/class-dynamic-dispatch.js +766 -108
  305. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  306. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +47 -0
  307. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
  308. package/dist/frontend/lowering/class-iterables.d.ts +2 -1
  309. package/dist/frontend/lowering/class-iterables.js +9 -1
  310. package/dist/frontend/lowering/class-iterables.js.map +1 -1
  311. package/dist/frontend/lowering/class-method-mutations.js +32 -9
  312. package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
  313. package/dist/frontend/lowering/class-prototypes.js +31 -2
  314. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  315. package/dist/frontend/lowering/class-runtime-statics.d.ts +9 -3
  316. package/dist/frontend/lowering/class-runtime-statics.js +29 -4
  317. package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
  318. package/dist/frontend/lowering/coercions/structural-plans.js +48 -1
  319. package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
  320. package/dist/frontend/lowering/coercions/structural.js +91 -1
  321. package/dist/frontend/lowering/coercions/structural.js.map +1 -1
  322. package/dist/frontend/lowering/containers/array-callback-call.js +2 -2
  323. package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -1
  324. package/dist/frontend/lowering/containers/array-callbacks.js +338 -18
  325. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  326. package/dist/frontend/lowering/containers/array-concat.js +10 -0
  327. package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
  328. package/dist/frontend/lowering/containers/array-methods.js +15 -0
  329. package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
  330. package/dist/frontend/lowering/containers/array-pipelines.js +19 -8
  331. package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
  332. package/dist/frontend/lowering/containers/bytes.js +2 -1
  333. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  334. package/dist/frontend/lowering/containers/callback-arguments.js +3 -0
  335. package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
  336. package/dist/frontend/lowering/containers/collection-methods.js +7 -2
  337. package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
  338. package/dist/frontend/lowering/containers/filter-predicates.d.ts +6 -0
  339. package/dist/frontend/lowering/containers/filter-predicates.js +205 -0
  340. package/dist/frontend/lowering/containers/filter-predicates.js.map +1 -0
  341. package/dist/frontend/lowering/containers/indexed-objects.d.ts +0 -12
  342. package/dist/frontend/lowering/containers/indexed-objects.js +46 -7
  343. package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
  344. package/dist/frontend/lowering/containers/string-and-regexp.js +55 -9
  345. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  346. package/dist/frontend/lowering/containers/string-replacement.js +43 -19
  347. package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
  348. package/dist/frontend/lowering/dispatch-sites.js +15 -1
  349. package/dist/frontend/lowering/dispatch-sites.js.map +1 -1
  350. package/dist/frontend/lowering/divergences.js +9 -1
  351. package/dist/frontend/lowering/divergences.js.map +1 -1
  352. package/dist/frontend/lowering/error-methods.js +47 -2
  353. package/dist/frontend/lowering/error-methods.js.map +1 -1
  354. package/dist/frontend/lowering/expressions/array-literals.js +47 -0
  355. package/dist/frontend/lowering/expressions/array-literals.js.map +1 -1
  356. package/dist/frontend/lowering/expressions/binary.js +36 -2
  357. package/dist/frontend/lowering/expressions/binary.js.map +1 -1
  358. package/dist/frontend/lowering/expressions/element-access.js +90 -13
  359. package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
  360. package/dist/frontend/lowering/expressions/identifiers.js +33 -4
  361. package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
  362. package/dist/frontend/lowering/expressions/narrowing.js +95 -1
  363. package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
  364. package/dist/frontend/lowering/expressions/nullish-assignment.js +3 -1
  365. package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
  366. package/dist/frontend/lowering/expressions/object-literals.d.ts +10 -0
  367. package/dist/frontend/lowering/expressions/object-literals.js +138 -51
  368. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  369. package/dist/frontend/lowering/expressions/optional-chains.js +12 -0
  370. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  371. package/dist/frontend/lowering/expressions/property-access.js +113 -11
  372. package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
  373. package/dist/frontend/lowering/expressions/relational.js +212 -33
  374. package/dist/frontend/lowering/expressions/relational.js.map +1 -1
  375. package/dist/frontend/lowering/expressions/union-fields.js +4 -0
  376. package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
  377. package/dist/frontend/lowering/expressions/updates.js +22 -3
  378. package/dist/frontend/lowering/expressions/updates.js.map +1 -1
  379. package/dist/frontend/lowering/frozen-records.d.ts +28 -0
  380. package/dist/frontend/lowering/frozen-records.js +322 -0
  381. package/dist/frontend/lowering/frozen-records.js.map +1 -0
  382. package/dist/frontend/lowering/function-returns.js +49 -0
  383. package/dist/frontend/lowering/function-returns.js.map +1 -1
  384. package/dist/frontend/lowering/generic-functions.js +7 -2
  385. package/dist/frontend/lowering/generic-functions.js.map +1 -1
  386. package/dist/frontend/lowering/iterable-values.d.ts +49 -0
  387. package/dist/frontend/lowering/iterable-values.js +297 -0
  388. package/dist/frontend/lowering/iterable-values.js.map +1 -0
  389. package/dist/frontend/lowering/iterator-adapters.js +186 -1
  390. package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
  391. package/dist/frontend/lowering/js-class-fields.d.ts +8 -0
  392. package/dist/frontend/lowering/js-class-fields.js +45 -10
  393. package/dist/frontend/lowering/js-class-fields.js.map +1 -1
  394. package/dist/frontend/lowering/key-order-witness.d.ts +18 -3
  395. package/dist/frontend/lowering/key-order-witness.js +770 -22
  396. package/dist/frontend/lowering/key-order-witness.js.map +1 -1
  397. package/dist/frontend/lowering/key-order-witness.test.js +428 -8
  398. package/dist/frontend/lowering/key-order-witness.test.js.map +1 -1
  399. package/dist/frontend/lowering/lower-async-iteration.js +4 -1
  400. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
  401. package/dist/frontend/lowering/lower-calls.d.ts +7 -0
  402. package/dist/frontend/lowering/lower-calls.js +443 -41
  403. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  404. package/dist/frontend/lowering/lower-classes.d.ts +11 -2
  405. package/dist/frontend/lowering/lower-classes.js +302 -22
  406. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  407. package/dist/frontend/lowering/lower-dgram.js +3 -1
  408. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  409. package/dist/frontend/lowering/lower-exprs.js +10 -2
  410. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  411. package/dist/frontend/lowering/lower-functions.d.ts +11 -0
  412. package/dist/frontend/lowering/lower-functions.js +83 -0
  413. package/dist/frontend/lowering/lower-functions.js.map +1 -1
  414. package/dist/frontend/lowering/lower-generators.js +41 -31
  415. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  416. package/dist/frontend/lowering/lower-global-value.js +6 -3
  417. package/dist/frontend/lowering/lower-global-value.js.map +1 -1
  418. package/dist/frontend/lowering/lower-inspect.js +18 -6
  419. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  420. package/dist/frontend/lowering/lower-modules.js +32 -0
  421. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  422. package/dist/frontend/lowering/lower-namespaces.js +5 -1
  423. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  424. package/dist/frontend/lowering/lower-server.js +2 -2
  425. package/dist/frontend/lowering/lower-server.js.map +1 -1
  426. package/dist/frontend/lowering/lower-stdlib.d.ts +5 -0
  427. package/dist/frontend/lowering/lower-stdlib.js +30 -0
  428. package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
  429. package/dist/frontend/lowering/lower-stmts.d.ts +23 -0
  430. package/dist/frontend/lowering/lower-stmts.js +454 -48
  431. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  432. package/dist/frontend/lowering/lower-stream.d.ts +20 -2
  433. package/dist/frontend/lowering/lower-stream.js +1483 -156
  434. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  435. package/dist/frontend/lowering/lowerer.d.ts +77 -6
  436. package/dist/frontend/lowering/lowerer.js +313 -29
  437. package/dist/frontend/lowering/lowerer.js.map +1 -1
  438. package/dist/frontend/lowering/module-namespace-elements.d.ts +11 -1
  439. package/dist/frontend/lowering/module-namespace-elements.js +82 -5
  440. package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
  441. package/dist/frontend/lowering/new-target.d.ts +12 -0
  442. package/dist/frontend/lowering/new-target.js +280 -0
  443. package/dist/frontend/lowering/new-target.js.map +1 -0
  444. package/dist/frontend/lowering/surfaces.d.ts +3 -0
  445. package/dist/frontend/lowering/surfaces.js +18 -6
  446. package/dist/frontend/lowering/surfaces.js.map +1 -1
  447. package/dist/frontend/lowering/undefined-index.d.ts +27 -0
  448. package/dist/frontend/lowering/undefined-index.js +82 -0
  449. package/dist/frontend/lowering/undefined-index.js.map +1 -0
  450. package/dist/frontend/lowering/var-hoisting.js +29 -13
  451. package/dist/frontend/lowering/var-hoisting.js.map +1 -1
  452. package/dist/frontend/lowering/width-lift.d.ts +18 -0
  453. package/dist/frontend/npm-static-bundled-chunks.js +9 -11
  454. package/dist/frontend/npm-static-bundled-chunks.js.map +1 -1
  455. package/dist/frontend/npm-static-bundled-chunks.test.js +6 -5
  456. package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -1
  457. package/dist/frontend/npm-static-rewrite-syntax.js +9 -1
  458. package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
  459. package/dist/frontend/npm-static.js +4 -20
  460. package/dist/frontend/npm-static.js.map +1 -1
  461. package/dist/frontend/package-shims.d.ts +3 -0
  462. package/dist/frontend/package-shims.js +71 -8
  463. package/dist/frontend/package-shims.js.map +1 -1
  464. package/dist/frontend/pipeline.js +18 -10
  465. package/dist/frontend/pipeline.js.map +1 -1
  466. package/dist/frontend/process-fork.d.ts +25 -0
  467. package/dist/frontend/process-fork.js +2 -0
  468. package/dist/frontend/process-fork.js.map +1 -0
  469. package/dist/frontend/program.d.ts +8 -1
  470. package/dist/frontend/program.js +484 -69
  471. package/dist/frontend/program.js.map +1 -1
  472. package/dist/frontend/program.test.js +43 -3
  473. package/dist/frontend/program.test.js.map +1 -1
  474. package/dist/frontend/token-equivalence.d.ts +3 -0
  475. package/dist/frontend/token-equivalence.js +409 -0
  476. package/dist/frontend/token-equivalence.js.map +1 -0
  477. package/dist/frontend/token-equivalence.test.d.ts +1 -0
  478. package/dist/frontend/token-equivalence.test.js +67 -0
  479. package/dist/frontend/token-equivalence.test.js.map +1 -0
  480. package/dist/frontend/ts7/ast-node.d.ts +22 -0
  481. package/dist/frontend/ts7/ast-node.js +1048 -103
  482. package/dist/frontend/ts7/ast-node.js.map +1 -1
  483. package/dist/frontend/ts7/ast-node.test.js +24 -0
  484. package/dist/frontend/ts7/ast-node.test.js.map +1 -1
  485. package/dist/frontend/ts7/ast-wire.d.ts +4 -3
  486. package/dist/frontend/ts7/ast-wire.js +34 -24
  487. package/dist/frontend/ts7/ast-wire.js.map +1 -1
  488. package/dist/frontend/ts7/ast-wire.test.js +23 -0
  489. package/dist/frontend/ts7/ast-wire.test.js.map +1 -1
  490. package/dist/frontend/ts7/checker-backend.d.ts +3 -4
  491. package/dist/frontend/ts7/checker-backend.js +2 -2
  492. package/dist/frontend/ts7/checker-backend.js.map +1 -1
  493. package/dist/frontend/ts7/checker-backend.test.js +5 -9
  494. package/dist/frontend/ts7/checker-backend.test.js.map +1 -1
  495. package/dist/frontend/ts7/checker.d.ts +4 -0
  496. package/dist/frontend/ts7/checker.js +7 -0
  497. package/dist/frontend/ts7/checker.js.map +1 -1
  498. package/dist/frontend/ts7/lib-diagnostics.d.ts +24 -0
  499. package/dist/frontend/ts7/lib-diagnostics.js +307 -0
  500. package/dist/frontend/ts7/lib-diagnostics.js.map +1 -0
  501. package/dist/frontend/ts7/lib-diagnostics.test.d.ts +1 -0
  502. package/dist/frontend/ts7/lib-diagnostics.test.js +199 -0
  503. package/dist/frontend/ts7/lib-diagnostics.test.js.map +1 -0
  504. package/dist/frontend/ts7/program-host.d.ts +7 -0
  505. package/dist/frontend/ts7/program-host.js +25 -2
  506. package/dist/frontend/ts7/program-host.js.map +1 -1
  507. package/dist/frontend/ts7/session.d.ts +14 -1
  508. package/dist/frontend/ts7/session.js +22 -0
  509. package/dist/frontend/ts7/session.js.map +1 -1
  510. package/dist/frontend/type-mapper.d.ts +13 -1
  511. package/dist/frontend/type-mapper.js +191 -11
  512. package/dist/frontend/type-mapper.js.map +1 -1
  513. package/dist/index.d.ts +0 -5
  514. package/dist/index.js +34 -4
  515. package/dist/index.js.map +1 -1
  516. package/dist/ir/analysis.js +5 -3
  517. package/dist/ir/analysis.js.map +1 -1
  518. package/dist/ir/array-length-stability.d.ts +4 -0
  519. package/dist/ir/array-length-stability.js +19 -6
  520. package/dist/ir/array-length-stability.js.map +1 -1
  521. package/dist/ir/array-length-stability.test.js +24 -0
  522. package/dist/ir/array-length-stability.test.js.map +1 -1
  523. package/dist/ir/builtin-effects.d.ts +7 -0
  524. package/dist/ir/builtin-effects.js +52 -0
  525. package/dist/ir/builtin-effects.js.map +1 -1
  526. package/dist/ir/builtin-signatures.d.ts +6 -4
  527. package/dist/ir/builtin-signatures.js +166 -13
  528. package/dist/ir/builtin-signatures.js.map +1 -1
  529. package/dist/ir/callback-specialization.d.ts +2 -1
  530. package/dist/ir/callback-specialization.js +23 -18
  531. package/dist/ir/callback-specialization.js.map +1 -1
  532. package/dist/ir/char-unit-locals.d.ts +19 -0
  533. package/dist/ir/char-unit-locals.js +185 -0
  534. package/dist/ir/char-unit-locals.js.map +1 -0
  535. package/dist/ir/char-unit-locals.test.d.ts +1 -0
  536. package/dist/ir/char-unit-locals.test.js +94 -0
  537. package/dist/ir/char-unit-locals.test.js.map +1 -0
  538. package/dist/ir/final-fields.d.ts +2 -1
  539. package/dist/ir/final-fields.js +14 -16
  540. package/dist/ir/final-fields.js.map +1 -1
  541. package/dist/ir/function-references.d.ts +2 -0
  542. package/dist/ir/function-references.js +2 -0
  543. package/dist/ir/function-references.js.map +1 -1
  544. package/dist/ir/function-references.test.js +3 -0
  545. package/dist/ir/function-references.test.js.map +1 -1
  546. package/dist/ir/initializer-bindings.d.ts +2 -1
  547. package/dist/ir/initializer-bindings.js +27 -20
  548. package/dist/ir/initializer-bindings.js.map +1 -1
  549. package/dist/ir/int32-arrays.d.ts +108 -0
  550. package/dist/ir/int32-arrays.js +831 -0
  551. package/dist/ir/int32-arrays.js.map +1 -0
  552. package/dist/ir/int32-slots.d.ts +24 -2
  553. package/dist/ir/int32-slots.js +259 -57
  554. package/dist/ir/int32-slots.js.map +1 -1
  555. package/dist/ir/integer-loops.d.ts +3 -3
  556. package/dist/ir/integer-loops.js +14 -6
  557. package/dist/ir/integer-loops.js.map +1 -1
  558. package/dist/ir/integer-loops.test.js +10 -0
  559. package/dist/ir/integer-loops.test.js.map +1 -1
  560. package/dist/ir/integer-ranges.d.ts +5 -0
  561. package/dist/ir/integer-ranges.js +125 -12
  562. package/dist/ir/integer-ranges.js.map +1 -1
  563. package/dist/ir/integer-ranges.test.js +30 -0
  564. package/dist/ir/integer-ranges.test.js.map +1 -1
  565. package/dist/ir/ir.d.ts +70 -7
  566. package/dist/ir/ir.js +58 -1
  567. package/dist/ir/ir.js.map +1 -1
  568. package/dist/ir/ir.test.js +21 -1
  569. package/dist/ir/ir.test.js.map +1 -1
  570. package/dist/ir/js-ic.d.ts +19 -2
  571. package/dist/ir/js-ic.js +95 -11
  572. package/dist/ir/js-ic.js.map +1 -1
  573. package/dist/ir/js-ic.test.js +188 -0
  574. package/dist/ir/js-ic.test.js.map +1 -1
  575. package/dist/ir/node-index.d.ts +57 -0
  576. package/dist/ir/node-index.js +215 -0
  577. package/dist/ir/node-index.js.map +1 -0
  578. package/dist/ir/paired-while-loops.d.ts +25 -0
  579. package/dist/ir/paired-while-loops.js +335 -0
  580. package/dist/ir/paired-while-loops.js.map +1 -0
  581. package/dist/ir/paired-while-loops.test.d.ts +1 -0
  582. package/dist/ir/paired-while-loops.test.js +163 -0
  583. package/dist/ir/paired-while-loops.test.js.map +1 -0
  584. package/dist/ir/parameter-versions.d.ts +25 -0
  585. package/dist/ir/parameter-versions.js +300 -0
  586. package/dist/ir/parameter-versions.js.map +1 -0
  587. package/dist/ir/runtime-features.d.ts +34 -13
  588. package/dist/ir/runtime-features.js +152 -38
  589. package/dist/ir/runtime-features.js.map +1 -1
  590. package/dist/ir/serialize.d.ts +12 -2
  591. package/dist/ir/serialize.js +16 -3
  592. package/dist/ir/serialize.js.map +1 -1
  593. package/dist/ir/serialize.test.js +17 -0
  594. package/dist/ir/serialize.test.js.map +1 -1
  595. package/dist/ir/traverse.js +18 -6
  596. package/dist/ir/traverse.js.map +1 -1
  597. package/dist/ir/validate.js +122 -36
  598. package/dist/ir/validate.js.map +1 -1
  599. package/dist/library/ir-policy.js +2 -0
  600. package/dist/library/ir-policy.js.map +1 -1
  601. package/dist/native/cache.d.ts +6 -1
  602. package/dist/native/cache.js +28 -5
  603. package/dist/native/cache.js.map +1 -1
  604. package/dist/native/cache.test.js +16 -2
  605. package/dist/native/cache.test.js.map +1 -1
  606. package/dist/native/cli.js +21 -1
  607. package/dist/native/cli.js.map +1 -1
  608. package/dist/native/compiler.js +8 -6
  609. package/dist/native/compiler.js.map +1 -1
  610. package/dist/native/executable-cache.d.ts +1 -1
  611. package/dist/native/executable-cache.js +2 -2
  612. package/dist/native/executable-cache.js.map +1 -1
  613. package/dist/native/prepare.d.ts +3 -1
  614. package/dist/native/prepare.js +119 -31
  615. package/dist/native/prepare.js.map +1 -1
  616. package/dist/native/prepare.test.js +78 -18
  617. package/dist/native/prepare.test.js.map +1 -1
  618. package/dist/native/sanitizer.test.js +2 -0
  619. package/dist/native/sanitizer.test.js.map +1 -1
  620. package/dist/native/text-file.d.ts +13 -3
  621. package/dist/native/text-file.js +63 -9
  622. package/dist/native/text-file.js.map +1 -1
  623. package/dist/native/text-file.test.d.ts +1 -0
  624. package/dist/native/text-file.test.js +49 -0
  625. package/dist/native/text-file.test.js.map +1 -0
  626. package/dist/native/toolchain.js +4 -4
  627. package/dist/native/toolchain.js.map +1 -1
  628. package/dist/native/toolchain.test.js +3 -3
  629. package/dist/native/toolchain.test.js.map +1 -1
  630. package/package.json +21 -21
  631. package/shims/chalk/v5.ts +688 -0
  632. package/shims/hono-node-server/v2.ts +645 -0
  633. package/shims/hot-shots/client.ts +1126 -0
  634. package/shims/hot-shots/v8-unix-dgram.ts +8 -0
  635. package/shims/hot-shots/v8.ts +8 -0
  636. package/surface-manifest.json +26 -4
@@ -28,7 +28,7 @@ import { ClassConstructionDispatch } from "./class-construction.js";
28
28
  import { DispatchSites } from "./dispatch-sites.js";
29
29
  import { emitterRooted, lowerDynamicEmitterEmit, lowerDynamicEmitterOn, } from "./lower-event-emitter.js";
30
30
  import { protocolArm, protocolFieldArm } from "./class-protocol-dispatch.js";
31
- import { STREAM_OPERATORS } from "./lower-stream.js";
31
+ import { STREAM_OPERATORS, operatorSignalOptions, reduceSignalSetup } from "./lower-stream.js";
32
32
  import { deletedPropertyNames, fixedFieldFamily } from "./js-class-fields.js";
33
33
  const STREAM_METHODS = new Set([
34
34
  "on",
@@ -252,7 +252,7 @@ export function classInstanceOf(lowerer, value, info, loc, classValue) {
252
252
  localId: "candidate",
253
253
  value: {
254
254
  kind: "libCall",
255
- fn: "dyn.getPrototype",
255
+ fn: "dyn.getPrototypeForIdentity",
256
256
  args: [candidate],
257
257
  type: DYN,
258
258
  loc,
@@ -295,6 +295,37 @@ export function classInstanceOf(lowerer, value, info, loc, classValue) {
295
295
  loc,
296
296
  };
297
297
  }
298
+ /** `value` is the parameter itself, possibly through js.fromDyn. */
299
+ function returnsParam(value, param) {
300
+ if (value.kind === "varRef")
301
+ return value.localId === param;
302
+ return (value.kind === "libCall" &&
303
+ value.fn === "js.fromDyn" &&
304
+ value.args.length === 1 &&
305
+ value.args[0].kind === "varRef" &&
306
+ value.args[0].localId === param);
307
+ }
308
+ /** The kind a class-table branch requires of `param`: a capsule-key test
309
+ * (alone or guarding a conjunction) needs a capsule, a class-key test a
310
+ * function value; null for any other condition. */
311
+ function branchKind(cond, param) {
312
+ if (cond.kind === "libCall" &&
313
+ (cond.fn === "dyn.typedRefIs" ||
314
+ cond.fn === "dyn.typedRefKeyIs" ||
315
+ cond.fn === "dyn.classIs") &&
316
+ cond.args[0]?.kind === "varRef" &&
317
+ cond.args[0].localId === param) {
318
+ if (cond.fn === "dyn.classIs")
319
+ return "funcKind";
320
+ const key = cond.args[1];
321
+ return key?.kind === "strLit" && key.value.startsWith("object:") ? "classCapsule" : null;
322
+ }
323
+ if (cond.kind === "ternary" && cond.else_.kind === "boolLit" && cond.else_.value === false)
324
+ return branchKind(cond.cond, param);
325
+ if (cond.kind === "logical" && cond.op === "&&")
326
+ return branchKind(cond.left, param);
327
+ return null;
328
+ }
298
329
  const READ_PROPERTIES = "%dyn.class.readProperties";
299
330
  const READ_PROPERTIES_OR_EMPTY = "%dyn.class.readPropertiesOrEmpty";
300
331
  function isEmptyBag(value) {
@@ -557,15 +588,151 @@ export function trackClassFieldCreation(lowerer, functions) {
557
588
  return;
558
589
  const loc = functions[0].loc;
559
590
  const name = "%dyn.class.fieldCreated";
560
- const value = varRef("value", DYN, loc), key = varRef("key", DYN, loc);
561
- const bag = varRef("bag", DYN, loc);
562
- const created = (receiver, className, field, loc) => ({
591
+ const key = varRef("key", DYN, loc);
592
+ // One helper per class: the instance's bag is its own hidden field, so a
593
+ // creation reads it directly instead of boxing the instance and testing
594
+ // it against every class's capsule (%dyn.class.properties), which runs
595
+ // only to create the bag, once per instance.
596
+ const perClass = new Map();
597
+ const helperFor = (className) => {
598
+ const known = perClass.get(className);
599
+ if (known !== undefined)
600
+ return known;
601
+ const helperName = `${name}:${className}`;
602
+ perClass.set(className, helperName);
603
+ const self = varRef("this", { kind: "object", className }, loc);
604
+ const bagRef = varRef("bag", DYN, loc);
605
+ functions.push({
606
+ name: helperName,
607
+ params: [
608
+ { localId: "this", name: "this", type: { kind: "object", className } },
609
+ { localId: "key", name: "key", type: DYN },
610
+ ],
611
+ returnType: VOID,
612
+ locals: [
613
+ { id: "this", name: "this", type: { kind: "object", className }, mutable: false },
614
+ { id: "key", name: "key", type: DYN, mutable: false },
615
+ { id: "bag", name: "bag", type: DYN, mutable: true },
616
+ ],
617
+ body: [
618
+ {
619
+ kind: "varDecl",
620
+ localId: "bag",
621
+ init: { kind: "fieldGet", obj: self, className, field: PROPERTY_BAG, type: DYN, loc },
622
+ loc,
623
+ },
624
+ {
625
+ kind: "if",
626
+ cond: { kind: "dynTest", test: "undefined", value: bagRef, type: BOOL, loc },
627
+ then: initializeBag(lowerer, className, self, loc),
628
+ else_: null,
629
+ loc,
630
+ },
631
+ ...defineIfAbsent(lowerer, bagRef, key, loc),
632
+ ],
633
+ loc,
634
+ });
635
+ return helperName;
636
+ };
637
+ // String-keyed fields take the runtime's direct insert for an ordinary
638
+ // bag; the general path stays for any other bag and for symbol keys.
639
+ const stringHelperFor = (className) => {
640
+ const known = perClass.get(`str:${className}`);
641
+ if (known !== undefined)
642
+ return known;
643
+ const general = helperFor(className);
644
+ const helperName = `${name}.string:${className}`;
645
+ perClass.set(`str:${className}`, helperName);
646
+ const type = { kind: "object", className };
647
+ const self = varRef("this", type, loc);
648
+ const bagRef = varRef("bag", DYN, loc);
649
+ const field = varRef("field", STRING, loc);
650
+ functions.push({
651
+ name: helperName,
652
+ params: [
653
+ { localId: "this", name: "this", type },
654
+ { localId: "field", name: "field", type: STRING },
655
+ ],
656
+ returnType: VOID,
657
+ locals: [
658
+ { id: "this", name: "this", type, mutable: false },
659
+ { id: "field", name: "field", type: STRING, mutable: false },
660
+ { id: "bag", name: "bag", type: DYN, mutable: true },
661
+ ],
662
+ body: [
663
+ {
664
+ kind: "varDecl",
665
+ localId: "bag",
666
+ init: { kind: "fieldGet", obj: self, className, field: PROPERTY_BAG, type: DYN, loc },
667
+ loc,
668
+ },
669
+ {
670
+ kind: "if",
671
+ cond: { kind: "dynTest", test: "undefined", value: bagRef, type: BOOL, loc },
672
+ then: initializeBag(lowerer, className, self, loc),
673
+ else_: null,
674
+ loc,
675
+ },
676
+ {
677
+ kind: "if",
678
+ cond: {
679
+ kind: "libCall",
680
+ fn: "dyn.bagCreateField",
681
+ args: [bagRef, field],
682
+ type: BOOL,
683
+ loc,
684
+ },
685
+ then: [{ kind: "return", value: null, loc }],
686
+ else_: null,
687
+ loc,
688
+ },
689
+ {
690
+ kind: "exprStmt",
691
+ expr: {
692
+ kind: "call",
693
+ callee: general,
694
+ args: [self, lowerer.coerceToExpected(field, DYN)],
695
+ type: VOID,
696
+ loc,
697
+ },
698
+ loc,
699
+ },
700
+ ],
701
+ loc,
702
+ });
703
+ return helperName;
704
+ };
705
+ const created = (receiver, className, field, loc) => {
706
+ const symbolKey = symbolMemberKey(lowerer, lowerer.classes.get(className), field, loc);
707
+ if (symbolKey === null) {
708
+ return {
709
+ kind: "exprStmt",
710
+ expr: {
711
+ kind: "call",
712
+ callee: stringHelperFor(className),
713
+ args: [
714
+ receiver.type.kind === "object" && receiver.type.className !== className
715
+ ? { kind: "upcast", value: receiver, type: { kind: "object", className }, loc }
716
+ : receiver,
717
+ { kind: "strLit", value: field, type: STRING, loc },
718
+ ],
719
+ type: VOID,
720
+ loc,
721
+ },
722
+ loc,
723
+ };
724
+ }
725
+ return createdGeneral(receiver, className, field, loc);
726
+ };
727
+ const createdGeneral = (receiver, className, field, loc) => ({
563
728
  kind: "exprStmt",
564
729
  expr: {
565
730
  kind: "call",
566
- callee: name,
731
+ callee: helperFor(className),
567
732
  args: [
568
- lowerer.coerceToExpected(receiver, DYN),
733
+ receiver.type.kind === "object" && receiver.type.className !== className
734
+ ? { kind: "upcast", value: receiver, type: { kind: "object", className }, loc }
735
+ : receiver,
569
736
  symbolMemberKey(lowerer, lowerer.classes.get(className), field, loc) ??
570
737
  lowerer.coerceToExpected({ kind: "strLit", value: field, type: STRING, loc }, DYN),
571
738
  ],
@@ -633,77 +800,101 @@ export function trackClassFieldCreation(lowerer, functions) {
633
800
  },
634
801
  });
635
802
  }
636
- functions.push({
637
- name,
638
- params: [
639
- { localId: "value", name: "value", type: DYN },
640
- { localId: "key", name: "key", type: DYN },
641
- ],
642
- returnType: VOID,
643
- locals: [
644
- { id: "value", name: "value", type: DYN, mutable: false },
645
- { id: "key", name: "key", type: DYN, mutable: false },
646
- { id: "bag", name: "bag", type: DYN, mutable: false },
647
- ],
648
- body: [
803
+ }
804
+ /** `bag = <the class's new bag>`, stored in the instance's hidden field:
805
+ * the class's own initializer when recorded, else the class-table
806
+ * dispatch, which creates it. */
807
+ function initializeBag(lowerer, className, self, loc) {
808
+ const init = lowerer.classBagInitializers?.get(className);
809
+ if (init === undefined) {
810
+ return [
649
811
  {
650
- kind: "varDecl",
812
+ kind: "assign",
651
813
  localId: "bag",
652
- init: {
814
+ value: {
653
815
  kind: "call",
654
816
  callee: classPropertiesHelper(lowerer, loc).name,
655
- args: [value],
817
+ args: [lowerer.coerceToExpected(self, DYN)],
656
818
  type: DYN,
657
819
  loc,
658
820
  },
659
821
  loc,
660
822
  },
661
- {
662
- kind: "if",
663
- cond: {
664
- kind: "unary",
665
- op: "!",
666
- operand: { kind: "libCall", fn: "dyn.hasOwnComputed", args: [bag, key], type: BOOL, loc },
667
- type: BOOL,
668
- loc,
669
- },
670
- then: [
671
- {
672
- kind: "exprStmt",
673
- expr: {
674
- kind: "libCall",
675
- fn: "dyn.defineProperty",
676
- args: [
677
- bag,
678
- lowerer.coerceToExpected(key, DYN),
679
- {
680
- kind: "dynObjLit",
681
- fields: [
682
- {
683
- key: { kind: "strLit", value: "value", type: STRING, loc },
684
- value: dynUndefinedExpr(loc),
685
- },
686
- ...["writable", "enumerable", "configurable"].map((key) => ({
687
- key: { kind: "strLit", value: key, type: STRING, loc },
688
- value: lowerer.coerceToExpected({ kind: "boolLit", value: true, type: BOOL, loc }, DYN),
689
- })),
690
- ],
691
- type: DYN,
692
- loc,
693
- },
694
- ],
695
- type: DYN,
696
- loc,
697
- },
698
- loc,
699
- },
700
- ],
701
- else_: null,
823
+ ];
824
+ }
825
+ return [
826
+ {
827
+ kind: "fieldSet",
828
+ obj: self,
829
+ className,
830
+ field: PROPERTY_BAG,
831
+ value: structuredClone(init),
832
+ loc,
833
+ },
834
+ {
835
+ kind: "assign",
836
+ localId: "bag",
837
+ value: { kind: "fieldGet", obj: self, className, field: PROPERTY_BAG, type: DYN, loc },
838
+ loc,
839
+ },
840
+ ];
841
+ }
842
+ /** `value` as JSON without its source locations. */
843
+ function withoutLocations(value) {
844
+ return JSON.stringify(value, (key, field) => (key === "loc" ? undefined : field));
845
+ }
846
+ /** Whether `value` reads local `id`. */
847
+ function mentionsLocal(value, id) {
848
+ return JSON.stringify(value).includes(`"localId":${JSON.stringify(id)}`);
849
+ }
850
+ /** `if (!hasOwn(bag, key)) defineProperty(bag, key, <undefined data field>)`:
851
+ * a field's creation in its instance's property bag. */
852
+ function defineIfAbsent(lowerer, bag, key, loc) {
853
+ return [
854
+ {
855
+ kind: "if",
856
+ cond: {
857
+ kind: "unary",
858
+ op: "!",
859
+ operand: { kind: "libCall", fn: "dyn.hasOwnComputed", args: [bag, key], type: BOOL, loc },
860
+ type: BOOL,
702
861
  loc,
703
862
  },
704
- ],
705
- loc,
706
- });
863
+ then: [
864
+ {
865
+ kind: "exprStmt",
866
+ expr: {
867
+ kind: "libCall",
868
+ fn: "dyn.defineProperty",
869
+ args: [
870
+ bag,
871
+ lowerer.coerceToExpected(key, DYN),
872
+ {
873
+ kind: "dynObjLit",
874
+ fields: [
875
+ {
876
+ key: { kind: "strLit", value: "value", type: STRING, loc },
877
+ value: dynUndefinedExpr(loc),
878
+ },
879
+ ...["writable", "enumerable", "configurable"].map((key) => ({
880
+ key: { kind: "strLit", value: key, type: STRING, loc },
881
+ value: lowerer.coerceToExpected({ kind: "boolLit", value: true, type: BOOL, loc }, DYN),
882
+ })),
883
+ ],
884
+ type: DYN,
885
+ loc,
886
+ },
887
+ ],
888
+ type: DYN,
889
+ loc,
890
+ },
891
+ loc,
892
+ },
893
+ ],
894
+ else_: null,
895
+ loc,
896
+ },
897
+ ];
707
898
  }
708
899
  /** Calls on native class capsules keep the instance's compiled methods. The
709
900
  * reachable-body fixed point discovers both the boxed classes and method
@@ -724,6 +915,9 @@ export class ClassDynamicDispatch {
724
915
  deletedNames;
725
916
  boxed = new Set();
726
917
  boxedConstructors = new Set();
918
+ /** Every class a boxed value was statically typed as, runtime error
919
+ * classes included: the value's capsule can be any of its subclasses. */
920
+ boxedStatic = new Set();
727
921
  dispatches = new Map();
728
922
  properties = new Map();
729
923
  computed = new Map();
@@ -755,8 +949,17 @@ export class ClassDynamicDispatch {
755
949
  descriptorHelper = null;
756
950
  prototypeHelper = null;
757
951
  prototypeClasses = new Set();
758
- prototypeIdentityHelper = null;
759
- prototypeIdentityClasses = new Set();
952
+ /** The stand-in prototype object of each class without prototype data
953
+ * (prototypeStandIn), by class name. */
954
+ prototypeStandIns = new Set();
955
+ /** The prototype reads of identity walks, by libCall, and the classes
956
+ * each one answers for boxed instances. */
957
+ prototypeIdentityHelpers = new Map();
958
+ /** `value instanceof Error` through Error.prototype: boxed instances of
959
+ * classes with a heritage evaluated at run time test their prototype
960
+ * data's chain. */
961
+ errorPrototypeHelper = null;
962
+ errorPrototypeClasses = new Set();
760
963
  instancePrototypes = new Map();
761
964
  checkedCasts = new Map();
762
965
  /** The for-in key helpers, by libCall (dyn and native string[] keys). */
@@ -797,6 +1000,7 @@ export class ClassDynamicDispatch {
797
1000
  return;
798
1001
  seenTypes.add(key);
799
1002
  if (type.kind === "object") {
1003
+ this.boxedStatic.add(type.className);
800
1004
  if (isDynTypedRefType(type))
801
1005
  this.boxed.add(type.className);
802
1006
  }
@@ -947,9 +1151,11 @@ export class ClassDynamicDispatch {
947
1151
  });
948
1152
  changed = true;
949
1153
  }
950
- if (this.prototypeIdentityHelper && !this.prototypeIdentityClasses.has(className)) {
951
- this.prototypeIdentityClasses.add(className);
952
- const loc = this.prototypeIdentityHelper.loc;
1154
+ if (this.errorPrototypeHelper &&
1155
+ !this.errorPrototypeClasses.has(className) &&
1156
+ hasRuntimeHeritage(info)) {
1157
+ this.errorPrototypeClasses.add(className);
1158
+ const loc = this.errorPrototypeHelper.loc;
953
1159
  const type = { kind: "object", className };
954
1160
  const value = varRef("value", DYN, loc);
955
1161
  const prototype = classPrototypeData(lowerer, info, loc, {
@@ -959,7 +1165,7 @@ export class ClassDynamicDispatch {
959
1165
  loc,
960
1166
  });
961
1167
  if (prototype)
962
- this.prototypeIdentityHelper.body.unshift({
1168
+ this.errorPrototypeHelper.body.unshift({
963
1169
  kind: "if",
964
1170
  cond: {
965
1171
  kind: "libCall",
@@ -968,7 +1174,19 @@ export class ClassDynamicDispatch {
968
1174
  type: BOOL,
969
1175
  loc,
970
1176
  },
971
- then: [{ kind: "return", value: prototype, loc }],
1177
+ then: [
1178
+ {
1179
+ kind: "return",
1180
+ value: {
1181
+ kind: "libCall",
1182
+ fn: "dyn.inheritsErrorPrototype",
1183
+ args: [prototype],
1184
+ type: BOOL,
1185
+ loc,
1186
+ },
1187
+ loc,
1188
+ },
1189
+ ],
972
1190
  else_: null,
973
1191
  loc,
974
1192
  });
@@ -1033,6 +1251,101 @@ export class ClassDynamicDispatch {
1033
1251
  }
1034
1252
  }
1035
1253
  }
1254
+ // The runtime boxes a class instance as its exact class, so a value
1255
+ // boxed at a base (or Error) static type reaches the identity views as
1256
+ // any subclass's capsule.
1257
+ for (const helper of this.prototypeIdentityHelpers.values())
1258
+ for (const [className, info] of lowerer.classes) {
1259
+ if (helper.classes.has(className))
1260
+ continue;
1261
+ if (info.builtinEmitter || info.builtinStream || info.builtinError)
1262
+ continue;
1263
+ if (!isDynTypedRefType({ kind: "object", className }))
1264
+ continue;
1265
+ if (!this.boxed.has(className) &&
1266
+ ![...this.boxedStatic].some((base) => lowerer.isSubclassOf(className, base)))
1267
+ continue;
1268
+ helper.classes.add(className);
1269
+ const loc = helper.fn.loc;
1270
+ const type = { kind: "object", className };
1271
+ const value = varRef("value", DYN, loc);
1272
+ // A class with no prototype data in its chain (one extending
1273
+ // Error, or with no methods) has no prototype a program can name:
1274
+ // an object of the class's own stands in, so instances of one class
1275
+ // share it (`Object.getPrototypeOf(a) === Object.getPrototypeOf(b)`),
1276
+ // other prototypes differ from it, and an instanceof walk (through
1277
+ // Object.prototype to null) answers false instead of reaching the
1278
+ // reflection refusal. A function-local class is a new class at
1279
+ // each evaluation of its declaration, so its instances answer with
1280
+ // the prototype of their own class value instead.
1281
+ const answer = (name) => {
1282
+ const of = lowerer.classes.get(name);
1283
+ const prototype = hasClassPrototypeData(of) || of.localClass
1284
+ ? classPrototypeData(lowerer, of, loc, {
1285
+ kind: "dynCheck",
1286
+ value,
1287
+ type: { kind: "object", className: name },
1288
+ loc,
1289
+ })
1290
+ : null;
1291
+ if (prototype)
1292
+ return [{ kind: "return", value: prototype, loc }];
1293
+ return hasClassPrototypeData(of) ? null : this.prototypeStandIn(lowerer, name, loc);
1294
+ };
1295
+ const own = answer(className);
1296
+ if (!own) {
1297
+ changed = true;
1298
+ continue;
1299
+ }
1300
+ // A capsule boxed at this class can hold a subclass instance: the
1301
+ // most derived subclass the instance belongs to answers.
1302
+ const depth = (name) => {
1303
+ let n = 0;
1304
+ for (let at = lowerer.classes.get(name)?.base; at; at = at.base)
1305
+ n++;
1306
+ return n;
1307
+ };
1308
+ const subclasses = [...lowerer.classes.keys()]
1309
+ .filter((name) => name !== className &&
1310
+ lowerer.isSubclassOf(name, className) &&
1311
+ isDynTypedRefType({ kind: "object", className: name }))
1312
+ .sort((a, b) => depth(b) - depth(a));
1313
+ const then = [];
1314
+ for (const name of subclasses) {
1315
+ const sub = answer(name);
1316
+ if (!sub)
1317
+ continue;
1318
+ then.push({
1319
+ kind: "if",
1320
+ cond: {
1321
+ kind: "instanceOf",
1322
+ value: { kind: "dynCheck", value, type, loc },
1323
+ className: name,
1324
+ type: BOOL,
1325
+ loc,
1326
+ },
1327
+ then: sub,
1328
+ else_: null,
1329
+ loc,
1330
+ });
1331
+ }
1332
+ then.push(...own);
1333
+ helper.fn.body.unshift({
1334
+ kind: "if",
1335
+ cond: {
1336
+ kind: "libCall",
1337
+ fn: "dyn.typedRefIs",
1338
+ args: [value, { kind: "strLit", value: typeKey(type), type: STRING, loc }],
1339
+ type: BOOL,
1340
+ loc,
1341
+ },
1342
+ then,
1343
+ else_: null,
1344
+ loc,
1345
+ });
1346
+ changed = true;
1347
+ }
1348
+ let live = null;
1036
1349
  for (const plan of this.propertyReceivers(lowerer, false, false)) {
1037
1350
  const info = plan.info;
1038
1351
  const className = info.def.name;
@@ -1102,7 +1415,11 @@ export class ClassDynamicDispatch {
1102
1415
  const needsPrototype = (current) => hasClassPrototypeData(current) ||
1103
1416
  current.subclasses.some((child) => lowerer.classCanBeConstructed(child) && needsPrototype(child));
1104
1417
  const prototypeFor = (current, receiver, loc) => this.bagPrototype(lowerer, current, receiver, loc);
1105
- for (const existingInit of this.bagInitializers.get(className) ?? []) {
1418
+ live ??= this.liveBagInitializers();
1419
+ for (const existingInit of [
1420
+ ...(this.bagInitializers.get(className) ?? []),
1421
+ ...(live.get(className) ?? []),
1422
+ ]) {
1106
1423
  if (existingInit.value.kind === "dynObjLit" && needsPrototype(info)) {
1107
1424
  const prototype = prototypeFor(info, existingInit.obj, existingInit.loc);
1108
1425
  if (prototype) {
@@ -1113,6 +1430,14 @@ export class ClassDynamicDispatch {
1113
1430
  type: DYN,
1114
1431
  loc: existingInit.loc,
1115
1432
  };
1433
+ // The initializer is a statement of the property bag helpers;
1434
+ // their reused site summaries do not see an edit inside it.
1435
+ if (this.propertyBag)
1436
+ this.sites.forget(this.propertyBag);
1437
+ for (const fn of this.typedPropertyBags.values())
1438
+ this.sites.forget(fn);
1439
+ for (const fn of this.exactPropertyBags.values())
1440
+ this.sites.forget(fn);
1116
1441
  changed = true;
1117
1442
  }
1118
1443
  }
@@ -1358,29 +1683,65 @@ export class ClassDynamicDispatch {
1358
1683
  }
1359
1684
  return { kind: "call", callee: cast.fn.name, args: [expr.value], type, loc: expr.loc };
1360
1685
  }
1686
+ if (expr.kind === "libCall" && expr.fn === "dyn.inheritsErrorPrototype") {
1687
+ if (!this.errorPrototypeHelper) {
1688
+ const loc = expr.loc;
1689
+ this.errorPrototypeHelper = {
1690
+ name: "%dyn.class.inheritsErrorPrototype",
1691
+ params: [{ localId: "value", name: "value", type: DYN }],
1692
+ locals: [{ id: "value", name: "value", type: DYN, mutable: false }],
1693
+ returnType: BOOL,
1694
+ loc,
1695
+ body: [
1696
+ { kind: "return", value: { ...expr, args: [varRef("value", DYN, loc)] }, loc },
1697
+ ],
1698
+ };
1699
+ lowerer.liftedFns.push(this.errorPrototypeHelper);
1700
+ this.generated.add(this.errorPrototypeHelper);
1701
+ changed = true;
1702
+ }
1703
+ return {
1704
+ kind: "call",
1705
+ callee: this.errorPrototypeHelper.name,
1706
+ args: expr.args,
1707
+ type: BOOL,
1708
+ loc: expr.loc,
1709
+ };
1710
+ }
1361
1711
  if (expr.kind === "libCall" &&
1362
- expr.fn === "dyn.getPrototype" &&
1712
+ (expr.fn === "dyn.getPrototype" || expr.fn === "dyn.getPrototypeForIdentity") &&
1363
1713
  expr.args[0]?.kind !== "dynObjLit") {
1364
1714
  if (expr.prototypeIdentityOnly) {
1365
- if (!this.prototypeIdentityHelper) {
1715
+ let helper = this.prototypeIdentityHelpers.get(expr.fn);
1716
+ if (!helper) {
1366
1717
  const loc = expr.loc;
1367
- this.prototypeIdentityHelper = {
1368
- name: "%dyn.class.prototypeIdentity",
1369
- params: [{ localId: "value", name: "value", type: DYN }],
1370
- locals: [{ id: "value", name: "value", type: DYN, mutable: false }],
1371
- returnType: DYN,
1372
- loc,
1373
- body: [
1374
- { kind: "return", value: { ...expr, args: [varRef("value", DYN, loc)] }, loc },
1375
- ],
1718
+ helper = {
1719
+ fn: {
1720
+ name: expr.fn === "dyn.getPrototype"
1721
+ ? "%dyn.class.prototypeIdentity"
1722
+ : "%dyn.class.prototypeChainIdentity",
1723
+ params: [{ localId: "value", name: "value", type: DYN }],
1724
+ locals: [{ id: "value", name: "value", type: DYN, mutable: false }],
1725
+ returnType: DYN,
1726
+ loc,
1727
+ body: [
1728
+ {
1729
+ kind: "return",
1730
+ value: { ...expr, args: [varRef("value", DYN, loc)] },
1731
+ loc,
1732
+ },
1733
+ ],
1734
+ },
1735
+ classes: new Set(),
1376
1736
  };
1377
- lowerer.liftedFns.push(this.prototypeIdentityHelper);
1378
- this.generated.add(this.prototypeIdentityHelper);
1737
+ this.prototypeIdentityHelpers.set(expr.fn, helper);
1738
+ lowerer.liftedFns.push(helper.fn);
1739
+ this.generated.add(helper.fn);
1379
1740
  changed = true;
1380
1741
  }
1381
1742
  return {
1382
1743
  kind: "call",
1383
- callee: this.prototypeIdentityHelper.name,
1744
+ callee: helper.fn.name,
1384
1745
  args: expr.args,
1385
1746
  type: DYN,
1386
1747
  loc: expr.loc,
@@ -2152,7 +2513,28 @@ export class ClassDynamicDispatch {
2152
2513
  loc,
2153
2514
  });
2154
2515
  }
2155
- dispatch = { name, write: !!write, fn: helper, classes: new Set() };
2516
+ const receiverAccess = read
2517
+ ? [{ kind: "return", value: { ...read, value: varRef("p.0", DYN, loc) }, loc }]
2518
+ : [
2519
+ {
2520
+ kind: "exprStmt",
2521
+ expr: {
2522
+ ...write,
2523
+ args: [varRef("p.0", DYN, loc), write.args[1], varRef("p.1", DYN, loc)],
2524
+ },
2525
+ loc,
2526
+ },
2527
+ { kind: "return", value: null, loc },
2528
+ ];
2529
+ dispatch = {
2530
+ name,
2531
+ write: !!write,
2532
+ fn: helper,
2533
+ classes: new Set(),
2534
+ ...(name !== "constructor" && name !== "toString"
2535
+ ? { plain: { tail: [...helper.body], access: receiverAccess } }
2536
+ : {}),
2537
+ };
2156
2538
  this.properties.set(key, dispatch);
2157
2539
  this.generated.add(helper);
2158
2540
  lowerer.liftedFns.push(helper);
@@ -3273,6 +3655,39 @@ export class ClassDynamicDispatch {
3273
3655
  }
3274
3656
  /** The receiver's own dynamic properties for a read: undefined while it has
3275
3657
  * none, and never stored, so reads stay valid on published objects. */
3658
+ /** Statements that return `className`'s stand-in prototype: one empty
3659
+ * object per class, created on first use and kept in a module global. */
3660
+ prototypeStandIn(lowerer, className, loc) {
3661
+ const globalId = `%g.%prototype.standIn.${className}`;
3662
+ const readyId = `${globalId}.ready`;
3663
+ if (!this.prototypeStandIns.has(className)) {
3664
+ this.prototypeStandIns.add(className);
3665
+ lowerer.globalsList.push({ id: globalId, name: `${className}.prototype`, type: DYN, mutable: true }, { id: readyId, name: `${className}.prototype.ready`, type: BOOL, mutable: true });
3666
+ }
3667
+ return [
3668
+ {
3669
+ kind: "if",
3670
+ cond: { kind: "unary", op: "!", operand: varRef(readyId, BOOL, loc), type: BOOL, loc },
3671
+ then: [
3672
+ {
3673
+ kind: "assign",
3674
+ localId: globalId,
3675
+ value: { kind: "dynObjLit", fields: [], type: DYN, loc },
3676
+ loc,
3677
+ },
3678
+ {
3679
+ kind: "assign",
3680
+ localId: readyId,
3681
+ value: { kind: "boolLit", value: true, type: BOOL, loc },
3682
+ loc,
3683
+ },
3684
+ ],
3685
+ else_: null,
3686
+ loc,
3687
+ },
3688
+ { kind: "return", value: varRef(globalId, DYN, loc), loc },
3689
+ ];
3690
+ }
3276
3691
  readPropertyBag(lowerer, receiver, loc) {
3277
3692
  const helper = classPropertiesHelper(lowerer, loc, true);
3278
3693
  this.generated.add(helper);
@@ -4086,6 +4501,34 @@ export class ClassDynamicDispatch {
4086
4501
  * A class with constructible subclasses that have prototype data selects
4087
4502
  * it through its `%class.bagPrototype` helper; any other class reads its
4088
4503
  * own prototype data. */
4504
+ /** The lazy bag stores as they stand in the generated bodies, by class.
4505
+ * Worklist passes that transform every function rebuild statement
4506
+ * objects, so a recorded initializer can be a detached copy; a store that
4507
+ * gains its prototype must be updated where it runs. */
4508
+ liveBagInitializers() {
4509
+ const live = new Map();
4510
+ const add = (stmt) => {
4511
+ if (stmt?.kind !== "if")
4512
+ return;
4513
+ const store = stmt.then[0];
4514
+ if (store?.kind !== "fieldSet" || store.field !== PROPERTY_BAG)
4515
+ return;
4516
+ const list = live.get(store.className);
4517
+ if (list)
4518
+ list.push(store);
4519
+ else
4520
+ live.set(store.className, [store]);
4521
+ };
4522
+ // The complete dispatch guards each class's lazy store by its receiver.
4523
+ for (const stmt of this.propertyBag?.body ?? [])
4524
+ if (stmt.kind === "if")
4525
+ add(stmt.then[0]);
4526
+ for (const helper of this.typedPropertyBags.values())
4527
+ add(helper.body[0]);
4528
+ for (const helper of this.exactPropertyBags.values())
4529
+ add(helper.body[0]);
4530
+ return live;
4531
+ }
4089
4532
  bagPrototype(lowerer, current, receiver, loc) {
4090
4533
  const arg = receiver.type.kind === "object" && receiver.type.className !== current.def.name
4091
4534
  ? {
@@ -4159,6 +4602,8 @@ export class ClassDynamicDispatch {
4159
4602
  if (lowerer)
4160
4603
  for (const fn of this.generated)
4161
4604
  lowerer.shareHelper(fn);
4605
+ if (lowerer)
4606
+ this.recordBagInitializers(lowerer);
4162
4607
  for (const { helper, initialize, orEmpty } of this.readPropertyBags) {
4163
4608
  const absent = helper.body[0];
4164
4609
  if (isEmptyBag(initialize.value) && !orEmpty)
@@ -4175,6 +4620,170 @@ export class ClassDynamicDispatch {
4175
4620
  fn.locals = structuredClone(this.propertyBag.locals);
4176
4621
  fn.body = readOnlyBagBody(structuredClone(this.propertyBag.body), fn.name === READ_PROPERTIES_OR_EMPTY);
4177
4622
  }
4623
+ if (lowerer)
4624
+ this.guardClassTables(lowerer);
4625
+ if (lowerer)
4626
+ this.guardPropertyHelpers(lowerer);
4627
+ }
4628
+ /** Each tracked class's bag initializer over a typed receiver (`this`),
4629
+ * for the per-class field-creation helpers (trackClassFieldCreation),
4630
+ * which create an instance's bag without the class-table dispatch. */
4631
+ recordBagInitializers(lowerer) {
4632
+ for (const [className, initializers] of this.bagInitializers) {
4633
+ const init = initializers[0];
4634
+ if (!init || !lowerer.classes.get(className)?.def.tracksOwnFields)
4635
+ continue;
4636
+ const self = varRef("this", { kind: "object", className }, init.loc);
4637
+ const value = withTypedReceiver(structuredClone(init.value), self);
4638
+ if (mentionsLocal(value, "p.0"))
4639
+ continue;
4640
+ // The class-table branches can give the class's instances different
4641
+ // bags (a base class's own prototype for its instances, the
4642
+ // instance's class prototype for subclass instances); only a class
4643
+ // whose branches all agree has one initializer for every instance.
4644
+ const shape = withoutLocations(value);
4645
+ if (initializers.some((other) => withoutLocations(withTypedReceiver(structuredClone(other.value), self)) !== shape))
4646
+ continue;
4647
+ // Lowerer stand-ins in unit tests may not carry the table.
4648
+ lowerer.classBagInitializers?.set(className, value);
4649
+ }
4650
+ }
4651
+ /** Fast exits for the generated class tables: every class branch of
4652
+ * the property-bag, normalization and static-bag helpers tests the
4653
+ * value's capsule key (or class key), so a value of another kind (a
4654
+ * plain object, the common case in untyped code) skips straight to the
4655
+ * table's fallthrough instead of testing every class in the program. */
4656
+ guardClassTables(lowerer) {
4657
+ const names = new Set([
4658
+ "%dyn.class.properties",
4659
+ READ_PROPERTIES,
4660
+ READ_PROPERTIES_OR_EMPTY,
4661
+ "%dyn.class.normalize",
4662
+ "%dyn.class.staticProperties",
4663
+ ]);
4664
+ for (const fn of lowerer.liftedFns) {
4665
+ if (!names.has(fn.name) || fn.body.length < 2)
4666
+ continue;
4667
+ const param = fn.params[0]?.localId;
4668
+ if (param === undefined)
4669
+ continue;
4670
+ const last = fn.body[fn.body.length - 1];
4671
+ if (last.kind !== "return" || last.value === null || !returnsParam(last.value, param))
4672
+ continue;
4673
+ let test = null;
4674
+ let ok = true;
4675
+ for (const stmt of fn.body.slice(0, -1)) {
4676
+ if (stmt.kind === "assign" &&
4677
+ stmt.localId === param &&
4678
+ stmt.value.kind === "call" &&
4679
+ stmt.value.callee === "%dyn.class.normalize")
4680
+ continue;
4681
+ const kind = stmt.kind === "if" && stmt.else_ === null ? branchKind(stmt.cond, param) : null;
4682
+ if (kind === null || (test !== null && kind !== test)) {
4683
+ ok = false;
4684
+ break;
4685
+ }
4686
+ test = kind;
4687
+ }
4688
+ if (!ok || test === null)
4689
+ continue;
4690
+ const first = fn.body[0];
4691
+ if (first.kind === "if" && first.cond.kind === "dynTest" && first.cond.test === test)
4692
+ continue;
4693
+ const loc = fn.loc;
4694
+ fn.body.unshift({
4695
+ kind: "if",
4696
+ cond: {
4697
+ kind: "dynTest",
4698
+ test,
4699
+ negated: true,
4700
+ value: varRef(param, DYN, loc),
4701
+ type: BOOL,
4702
+ loc,
4703
+ },
4704
+ then: [structuredClone(last)],
4705
+ else_: null,
4706
+ loc,
4707
+ });
4708
+ }
4709
+ }
4710
+ /** Fast exits for the generated property helpers: when every class
4711
+ * branch tests a capsule key or a class key and the fallthrough is still
4712
+ * the bag access the helper was created with, a value of another kind
4713
+ * (a plain object, array or primitive) normalizes to itself, has itself
4714
+ * as its bag, and so gets the plain access directly, without the
4715
+ * normalization, bag and static-bag calls. */
4716
+ guardPropertyHelpers(lowerer) {
4717
+ // Every class table the fallthrough or normalization calls must answer
4718
+ // a plain value with the value itself: its kind exit is in place.
4719
+ const exits = (name) => {
4720
+ const helper = lowerer.liftedFnNamed(name);
4721
+ const first = helper?.body[0];
4722
+ const param = helper?.params[0]?.localId;
4723
+ return (param !== undefined &&
4724
+ first?.kind === "if" &&
4725
+ first.cond.kind === "dynTest" &&
4726
+ first.cond.negated === true &&
4727
+ first.then.length === 1 &&
4728
+ first.then[0].kind === "return" &&
4729
+ first.then[0].value !== null &&
4730
+ returnsParam(first.then[0].value, param));
4731
+ };
4732
+ const tables = new Set([
4733
+ "%dyn.class.properties",
4734
+ READ_PROPERTIES,
4735
+ READ_PROPERTIES_OR_EMPTY,
4736
+ "%dyn.class.normalize",
4737
+ "%dyn.class.staticProperties",
4738
+ ]);
4739
+ const callsOnlyGuardedTables = (statements) => everyStmtList(statements, {
4740
+ stmt: () => true,
4741
+ expr: (expression) => expression.kind !== "call" || (tables.has(expression.callee) && exits(expression.callee)),
4742
+ });
4743
+ for (const dispatch of this.properties.values()) {
4744
+ const plain = dispatch.plain;
4745
+ if (!plain)
4746
+ continue;
4747
+ const fn = dispatch.fn;
4748
+ const param = fn.params[0]?.localId;
4749
+ if (param === undefined)
4750
+ continue;
4751
+ const head = fn.body.length - plain.tail.length;
4752
+ if (head < 0 || plain.tail.some((stmt, i) => fn.body[head + i] !== stmt))
4753
+ continue;
4754
+ let ok = true;
4755
+ for (const stmt of fn.body.slice(0, head)) {
4756
+ if (stmt.kind === "assign" &&
4757
+ stmt.localId === param &&
4758
+ stmt.value.kind === "call" &&
4759
+ stmt.value.callee === "%dyn.class.normalize")
4760
+ continue;
4761
+ if (stmt.kind === "if" && stmt.else_ === null && branchKind(stmt.cond, param) !== null)
4762
+ continue;
4763
+ ok = false;
4764
+ break;
4765
+ }
4766
+ // Class branches never run for a plain value; the rest always does.
4767
+ if (!ok || !callsOnlyGuardedTables(fn.body.filter((stmt) => stmt.kind !== "if")))
4768
+ continue;
4769
+ const loc = fn.loc;
4770
+ const not = (test) => ({
4771
+ kind: "dynTest",
4772
+ test,
4773
+ negated: true,
4774
+ value: varRef(param, DYN, loc),
4775
+ type: BOOL,
4776
+ loc,
4777
+ });
4778
+ fn.body.unshift({
4779
+ kind: "if",
4780
+ cond: not("classCapsule"),
4781
+ then: [{ kind: "if", cond: not("funcKind"), then: plain.access, else_: null, loc }],
4782
+ else_: null,
4783
+ loc,
4784
+ });
4785
+ delete dispatch.plain;
4786
+ }
4178
4787
  }
4179
4788
  normalizedDispatches() {
4180
4789
  return [
@@ -4246,10 +4855,15 @@ export class ClassDynamicDispatch {
4246
4855
  this.normalizationKey = key;
4247
4856
  const loc = this.normalization.loc;
4248
4857
  const value = varRef("value", DYN, loc);
4249
- this.normalization.body = entries.map(({ capsule, children }) => {
4858
+ // The checked receiver is unboxed once per capsule branch, not once
4859
+ // per subclass test.
4860
+ this.normalization.locals = this.normalization.locals.filter((local) => !local.id.startsWith("%normalized."));
4861
+ this.normalization.body = entries.map(({ capsule, children }, index) => {
4250
4862
  const type = { kind: "object", className: capsule.def.name };
4251
- const receiver = { kind: "dynCheck", value, type, loc };
4252
- return {
4863
+ const id = `%normalized.${index}`;
4864
+ this.normalization.locals.push({ id, name: id, type, mutable: false });
4865
+ const receiver = varRef(id, type, loc);
4866
+ const branch = {
4253
4867
  kind: "if",
4254
4868
  cond: {
4255
4869
  kind: "libCall",
@@ -4290,6 +4904,15 @@ export class ClassDynamicDispatch {
4290
4904
  else_: null,
4291
4905
  loc,
4292
4906
  };
4907
+ // The capsule test stays the branch condition; its body unboxes.
4908
+ if (branch.kind === "if")
4909
+ branch.then.unshift({
4910
+ kind: "varDecl",
4911
+ localId: id,
4912
+ init: { kind: "dynCheck", value, type, loc },
4913
+ loc,
4914
+ });
4915
+ return branch;
4293
4916
  });
4294
4917
  this.normalization.body.push({ kind: "return", value, loc });
4295
4918
  }
@@ -5254,13 +5877,16 @@ export class ClassDynamicDispatch {
5254
5877
  const arg = (i) => incoming[i] ?? dynUndefinedExpr(loc);
5255
5878
  const readableT = { kind: "object", className: "%Readable" };
5256
5879
  const op = (fn, args, type) => ret({ kind: "libCall", fn: fn, args: [receiver, ...args], type, loc });
5880
+ // Node passes every callback its { signal }; the callback's
5881
+ // declared parameters are not known here.
5882
+ const sig = () => operatorSignalOptions(lowerer, arg(1), loc);
5257
5883
  switch (method) {
5258
5884
  case "map":
5259
- return op("readable.opMap", [arg(0), arg(1)], readableT);
5885
+ return op("readable.opMap", [arg(0), arg(1), sig()], readableT);
5260
5886
  case "filter":
5261
- return op("readable.opFilter", [arg(0), arg(1)], readableT);
5887
+ return op("readable.opFilter", [arg(0), arg(1), sig()], readableT);
5262
5888
  case "flatMap":
5263
- return op("readable.opFlatMap", [arg(0), arg(1)], readableT);
5889
+ return op("readable.opFlatMap", [arg(0), arg(1), sig()], readableT);
5264
5890
  case "drop":
5265
5891
  return op("readable.opDrop", [arg(0), arg(1)], readableT);
5266
5892
  case "take":
@@ -5268,21 +5894,45 @@ export class ClassDynamicDispatch {
5268
5894
  case "toArray":
5269
5895
  return op("readable.opToArray", [arg(0)], { kind: "promise", inner: DYN });
5270
5896
  case "forEach":
5271
- return op("readable.opForEach", [arg(0), arg(1)], { kind: "promise", inner: VOID });
5897
+ return op("readable.opForEach", [arg(0), arg(1), sig()], {
5898
+ kind: "promise",
5899
+ inner: VOID,
5900
+ });
5272
5901
  case "some":
5273
- return op("readable.opSome", [arg(0), arg(1)], { kind: "promise", inner: BOOL });
5902
+ return op("readable.opSome", [arg(0), arg(1), sig()], { kind: "promise", inner: BOOL });
5274
5903
  case "every":
5275
- return op("readable.opEvery", [arg(0), arg(1)], { kind: "promise", inner: BOOL });
5904
+ return op("readable.opEvery", [arg(0), arg(1), sig()], {
5905
+ kind: "promise",
5906
+ inner: BOOL,
5907
+ });
5276
5908
  case "find":
5277
- return op("readable.opFind", [arg(0), arg(1)], { kind: "promise", inner: DYN });
5278
- case "reduce":
5279
- return op("readable.opReduce", [
5280
- arg(0),
5281
- arg(1),
5282
- { kind: "boolLit", value: dispatch.source.args.length >= 2, type: BOOL, loc },
5283
- arg(2),
5284
- { kind: "numLit", value: 0, type: F64, loc },
5285
- ], { kind: "promise", inner: DYN });
5909
+ return op("readable.opFind", [arg(0), arg(1), sig()], { kind: "promise", inner: DYN });
5910
+ case "reduce": {
5911
+ // the dispatch function's locals: there is no function
5912
+ // context while dispatch bodies are built
5913
+ const setup = reduceSignalSetup(lowerer, arg(2), loc, (name, type) => {
5914
+ const local = {
5915
+ id: `${name}.${dispatch.fn.locals.length}`,
5916
+ name,
5917
+ type,
5918
+ mutable: false,
5919
+ };
5920
+ dispatch.fn.locals.push(local);
5921
+ return local;
5922
+ });
5923
+ return [
5924
+ ...setup.stmts,
5925
+ ...op("readable.opReduceSignal", [
5926
+ arg(0),
5927
+ arg(1),
5928
+ { kind: "boolLit", value: dispatch.source.args.length >= 2, type: BOOL, loc },
5929
+ arg(2),
5930
+ { kind: "numLit", value: 0, type: F64, loc },
5931
+ setup.abort,
5932
+ setup.cbOpts,
5933
+ ], { kind: "promise", inner: DYN }),
5934
+ ];
5935
+ }
5286
5936
  }
5287
5937
  }
5288
5938
  if (method === "destroy" && (!incoming.length || incoming[0]?.kind === "unitLit"))
@@ -5530,4 +6180,12 @@ const INHERITED_OBJECT_METHODS = new Set([
5530
6180
  "hasOwnProperty",
5531
6181
  "propertyIsEnumerable",
5532
6182
  ]);
6183
+ /** Whether a class or one of its bases has a heritage evaluated at run
6184
+ * time, whose prototype chain may reach Error.prototype. */
6185
+ function hasRuntimeHeritage(info) {
6186
+ for (let current = info; current; current = current.base)
6187
+ if (current.callableBase)
6188
+ return true;
6189
+ return false;
6190
+ }
5533
6191
  //# sourceMappingURL=class-dynamic-dispatch.js.map