@scriptc/compiler 0.2.9 → 0.3.0

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 (505) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +2 -36
  2. package/ambient/scriptc-overrides.d.ts +1 -25
  3. package/ambient/scriptc.d.ts +1 -9
  4. package/dist/backend/cycle-analysis.d.ts +56 -0
  5. package/dist/backend/cycle-analysis.js +175 -14
  6. package/dist/backend/cycle-analysis.js.map +1 -1
  7. package/dist/backend/cycle-analysis.test.js +95 -2
  8. package/dist/backend/cycle-analysis.test.js.map +1 -1
  9. package/dist/backend/cycle-mutability.d.ts +3 -7
  10. package/dist/backend/cycle-mutability.js +4 -30
  11. package/dist/backend/cycle-mutability.js.map +1 -1
  12. package/dist/backend/executable-features.d.ts +1 -1
  13. package/dist/backend/executable-features.js +3 -8
  14. package/dist/backend/executable-features.js.map +1 -1
  15. package/dist/backend/immutability.d.ts +57 -0
  16. package/dist/backend/immutability.js +178 -0
  17. package/dist/backend/immutability.js.map +1 -0
  18. package/dist/backend/immutability.test.js +131 -0
  19. package/dist/backend/immutability.test.js.map +1 -0
  20. package/dist/backend/library-pack.js +0 -2
  21. package/dist/backend/library-pack.js.map +1 -1
  22. package/dist/backend/linker.js +1 -1
  23. package/dist/backend/linker.js.map +1 -1
  24. package/dist/backend/llvm/borrowed-inputs.d.ts +9 -2
  25. package/dist/backend/llvm/borrowed-inputs.js +31 -3
  26. package/dist/backend/llvm/borrowed-inputs.js.map +1 -1
  27. package/dist/backend/llvm/checked-narrows.test.js +1 -1
  28. package/dist/backend/llvm/classes.d.ts +28 -0
  29. package/dist/backend/llvm/classes.js +48 -14
  30. package/dist/backend/llvm/classes.js.map +1 -1
  31. package/dist/backend/llvm/classes.test.js +134 -6
  32. package/dist/backend/llvm/classes.test.js.map +1 -1
  33. package/dist/backend/llvm/common.d.ts +13 -0
  34. package/dist/backend/llvm/common.js +13 -0
  35. package/dist/backend/llvm/common.js.map +1 -1
  36. package/dist/backend/llvm/constant-callbacks.d.ts +1 -1
  37. package/dist/backend/llvm/constant-callbacks.js +3 -3
  38. package/dist/backend/llvm/constant-callbacks.js.map +1 -1
  39. package/dist/backend/llvm/constant-callbacks.test.js +1 -1
  40. package/dist/backend/llvm/dense-array-access.js +5 -4
  41. package/dist/backend/llvm/dense-array-access.js.map +1 -1
  42. package/dist/backend/llvm/dense-array-access.test.js +10 -2
  43. package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
  44. package/dist/backend/llvm/dyn.d.ts +2 -1
  45. package/dist/backend/llvm/dyn.js +3 -76
  46. package/dist/backend/llvm/dyn.js.map +1 -1
  47. package/dist/backend/llvm/emitter.d.ts +67 -19
  48. package/dist/backend/llvm/emitter.js +443 -226
  49. package/dist/backend/llvm/emitter.js.map +1 -1
  50. package/dist/backend/llvm/emitter.test.js +21 -3
  51. package/dist/backend/llvm/emitter.test.js.map +1 -1
  52. package/dist/backend/llvm/expr-async.test.js +1 -1
  53. package/dist/backend/llvm/expr-calls.js +14 -6
  54. package/dist/backend/llvm/expr-calls.js.map +1 -1
  55. package/dist/backend/llvm/expr-containers.js +41 -14
  56. package/dist/backend/llvm/expr-containers.js.map +1 -1
  57. package/dist/backend/llvm/expr-control.js +4 -107
  58. package/dist/backend/llvm/expr-control.js.map +1 -1
  59. package/dist/backend/llvm/expr-dispatch.d.ts +1 -2
  60. package/dist/backend/llvm/expr-dispatch.js +0 -41
  61. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  62. package/dist/backend/llvm/expr-dynamic.d.ts +1 -1
  63. package/dist/backend/llvm/expr-dynamic.js +13 -27
  64. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  65. package/dist/backend/llvm/expr-primitives.js +30 -3
  66. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  67. package/dist/backend/llvm/expr-primitives.test.js +55 -2
  68. package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
  69. package/dist/backend/llvm/expr-stream-bridges.js +4 -4
  70. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  71. package/dist/backend/llvm/expr-stream-bridges.test.js +1 -1
  72. package/dist/backend/llvm/lib-dispatch.js +0 -1
  73. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  74. package/dist/backend/llvm/lib-filesystem.js +0 -13
  75. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  76. package/dist/backend/llvm/lib-shared.js +0 -8
  77. package/dist/backend/llvm/lib-shared.js.map +1 -1
  78. package/dist/backend/llvm/local-array-reads.js +3 -3
  79. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  80. package/dist/backend/llvm/local-array-reads.test.js +1 -1
  81. package/dist/backend/llvm/local-union-storage.test.js +1 -1
  82. package/dist/backend/llvm/loop-array-borrows.d.ts +5 -2
  83. package/dist/backend/llvm/loop-array-borrows.js +27 -8
  84. package/dist/backend/llvm/loop-array-borrows.js.map +1 -1
  85. package/dist/backend/llvm/map-number-lookup.d.ts +14 -0
  86. package/dist/backend/llvm/map-number-lookup.js +33 -2
  87. package/dist/backend/llvm/map-number-lookup.js.map +1 -1
  88. package/dist/backend/llvm/map-read-lifetimes.d.ts +5 -0
  89. package/dist/backend/llvm/map-read-lifetimes.js +20 -4
  90. package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
  91. package/dist/backend/llvm/map-read-lifetimes.test.js +25 -3
  92. package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -1
  93. package/dist/backend/llvm/reference-writes.d.ts +124 -0
  94. package/dist/backend/llvm/reference-writes.js +1090 -0
  95. package/dist/backend/llvm/reference-writes.js.map +1 -0
  96. package/dist/backend/llvm/shapes.d.ts +8 -5
  97. package/dist/backend/llvm/shapes.js +37 -13
  98. package/dist/backend/llvm/shapes.js.map +1 -1
  99. package/dist/backend/llvm/shapes.test.js +3 -3
  100. package/dist/backend/llvm/stack-unions.test.js +1 -1
  101. package/dist/backend/llvm/string-construction.test.js +1 -1
  102. package/dist/backend/llvm/string-lifetimes.test.js +40 -11
  103. package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
  104. package/dist/backend/llvm/string-reads.d.ts +3 -0
  105. package/dist/backend/llvm/string-reads.js +31 -0
  106. package/dist/backend/llvm/string-reads.js.map +1 -1
  107. package/dist/backend/llvm/switch-dispatch.d.ts +2 -2
  108. package/dist/backend/llvm/switch-dispatch.js +35 -22
  109. package/dist/backend/llvm/switch-dispatch.js.map +1 -1
  110. package/dist/backend/llvm/switch-dispatch.test.js +29 -11
  111. package/dist/backend/llvm/switch-dispatch.test.js.map +1 -1
  112. package/dist/backend/llvm/walk-borrows.d.ts +8 -1
  113. package/dist/backend/llvm/walk-borrows.js +15 -4
  114. package/dist/backend/llvm/walk-borrows.js.map +1 -1
  115. package/dist/backend/may-throw.d.ts +36 -2
  116. package/dist/backend/may-throw.js +308 -21
  117. package/dist/backend/may-throw.js.map +1 -1
  118. package/dist/backend/may-throw.test.js +147 -2
  119. package/dist/backend/may-throw.test.js.map +1 -1
  120. package/dist/backend/native/artifact-stamps.js +0 -2
  121. package/dist/backend/native/artifact-stamps.js.map +1 -1
  122. package/dist/backend/native/cache-warm.d.ts +1 -1
  123. package/dist/backend/native/cache-warm.js +2 -3
  124. package/dist/backend/native/cache-warm.js.map +1 -1
  125. package/dist/backend/native/compiler-fingerprint.d.ts +1 -1
  126. package/dist/backend/native/compiler-fingerprint.js +4 -7
  127. package/dist/backend/native/compiler-fingerprint.js.map +1 -1
  128. package/dist/backend/native/contracts.d.ts +3 -28
  129. package/dist/backend/native/driver.js +1 -3
  130. package/dist/backend/native/driver.js.map +1 -1
  131. package/dist/backend/native/executable.d.ts +0 -15
  132. package/dist/backend/native/executable.js +17 -172
  133. package/dist/backend/native/executable.js.map +1 -1
  134. package/dist/backend/native/tool-identity.js +0 -1
  135. package/dist/backend/native/tool-identity.js.map +1 -1
  136. package/dist/backend/native/vendor.d.ts +1 -1
  137. package/dist/backend/native/vendor.js +1 -1
  138. package/dist/backend/native/vendor.js.map +1 -1
  139. package/dist/backend/native-link-info-core.d.ts +0 -2
  140. package/dist/backend/native-link-info-core.js.map +1 -1
  141. package/dist/backend/native-toolchain.test.js +23 -33
  142. package/dist/backend/native-toolchain.test.js.map +1 -1
  143. package/dist/backend/publication.d.ts +5 -0
  144. package/dist/backend/publication.js +10 -0
  145. package/dist/backend/publication.js.map +1 -1
  146. package/dist/backend/publication.test.js +1 -1
  147. package/dist/backend/runtime-abi.d.ts +2 -2
  148. package/dist/backend/runtime-abi.js +2 -2
  149. package/dist/backend/runtime-pack-core.d.ts +1 -2
  150. package/dist/backend/runtime-pack-core.js +5 -14
  151. package/dist/backend/runtime-pack-core.js.map +1 -1
  152. package/dist/backend/runtime-pack-targets.test.js +3 -8
  153. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  154. package/dist/backend/runtime-pack.test.js +22 -19
  155. package/dist/backend/runtime-pack.test.js.map +1 -1
  156. package/dist/backend/target-diagnostics.d.ts +0 -5
  157. package/dist/backend/target-diagnostics.js +1 -11
  158. package/dist/backend/target-diagnostics.js.map +1 -1
  159. package/dist/backend/target-diagnostics.test.js +1 -1
  160. package/dist/backend/vendor-archives.d.ts +1 -7
  161. package/dist/backend/vendor-archives.js +9 -189
  162. package/dist/backend/vendor-archives.js.map +1 -1
  163. package/dist/backend/vendor-inputs.d.ts +0 -1
  164. package/dist/backend/vendor-inputs.js +0 -1
  165. package/dist/backend/vendor-inputs.js.map +1 -1
  166. package/dist/backend/warm-cache.js +3 -5
  167. package/dist/backend/warm-cache.js.map +1 -1
  168. package/dist/cli/command.js +4 -8
  169. package/dist/cli/command.js.map +1 -1
  170. package/dist/cli/host.d.ts +1 -1
  171. package/dist/cli/usage.d.ts +1 -5
  172. package/dist/cli/usage.js +4 -9
  173. package/dist/cli/usage.js.map +1 -1
  174. package/dist/compat/fetch-profile.d.ts +2 -2
  175. package/dist/compat/fetch-profile.js +16 -25
  176. package/dist/compat/fetch-profile.js.map +1 -1
  177. package/dist/compile-types.d.ts +2 -17
  178. package/dist/contracts/check.d.ts +8 -0
  179. package/dist/contracts/check.js +1573 -0
  180. package/dist/contracts/check.js.map +1 -0
  181. package/dist/coverage/report.d.ts +5 -22
  182. package/dist/coverage/report.js +12 -76
  183. package/dist/coverage/report.js.map +1 -1
  184. package/dist/coverage/surface-manifest.d.ts +3 -3
  185. package/dist/coverage/surface-manifest.js +22 -27
  186. package/dist/coverage/surface-manifest.js.map +1 -1
  187. package/dist/coverage/verdict-cache.d.ts +1 -3
  188. package/dist/coverage/verdict-cache.js +2 -7
  189. package/dist/coverage/verdict-cache.js.map +1 -1
  190. package/dist/diagnostics/diagnostic.d.ts +11 -60
  191. package/dist/diagnostics/diagnostic.js +39 -118
  192. package/dist/diagnostics/diagnostic.js.map +1 -1
  193. package/dist/diagnostics/envelope.d.ts +3 -4
  194. package/dist/diagnostics/envelope.js +0 -9
  195. package/dist/diagnostics/envelope.js.map +1 -1
  196. package/dist/diagnostics/envelope.test.js +1 -1
  197. package/dist/diagnostics/envelope.test.js.map +1 -1
  198. package/dist/executable/executable-cache.d.ts +0 -3
  199. package/dist/executable/executable-cache.js +2 -4
  200. package/dist/executable/executable-cache.js.map +1 -1
  201. package/dist/executable/executable-cache.test.js +0 -4
  202. package/dist/executable/executable-cache.test.js.map +1 -1
  203. package/dist/executable/prepare.js +14 -2
  204. package/dist/executable/prepare.js.map +1 -1
  205. package/dist/frontend/analysis.js +10 -10
  206. package/dist/frontend/analysis.js.map +1 -1
  207. package/dist/frontend/cjs-syntax.js +0 -88
  208. package/dist/frontend/cjs-syntax.js.map +1 -1
  209. package/dist/frontend/contract-types.d.ts +50 -0
  210. package/dist/frontend/contract-types.js +232 -0
  211. package/dist/frontend/contract-types.js.map +1 -0
  212. package/dist/frontend/dts-paths.d.ts +1 -1
  213. package/dist/frontend/dts-paths.js +1 -1
  214. package/dist/frontend/lowering/abstract-equality.js +1 -4
  215. package/dist/frontend/lowering/abstract-equality.js.map +1 -1
  216. package/dist/frontend/lowering/array-values.js +4 -11
  217. package/dist/frontend/lowering/array-values.js.map +1 -1
  218. package/dist/frontend/lowering/builtins/arguments.js +0 -13
  219. package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
  220. package/dist/frontend/lowering/builtins/crypto.d.ts +0 -4
  221. package/dist/frontend/lowering/builtins/crypto.js +0 -4
  222. package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
  223. package/dist/frontend/lowering/builtins/json.js +1 -39
  224. package/dist/frontend/lowering/builtins/json.js.map +1 -1
  225. package/dist/frontend/lowering/builtins/module-resolution.d.ts +0 -15
  226. package/dist/frontend/lowering/builtins/module-resolution.js +5 -44
  227. package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
  228. package/dist/frontend/lowering/builtins/numbers.d.ts +0 -6
  229. package/dist/frontend/lowering/builtins/numbers.js +6 -57
  230. package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
  231. package/dist/frontend/lowering/builtins/promises.js +4 -67
  232. package/dist/frontend/lowering/builtins/promises.js.map +1 -1
  233. package/dist/frontend/lowering/builtins/workers.js +1 -1
  234. package/dist/frontend/lowering/builtins/workers.js.map +1 -1
  235. package/dist/frontend/lowering/call-arguments.d.ts +1 -37
  236. package/dist/frontend/lowering/call-arguments.js +11 -94
  237. package/dist/frontend/lowering/call-arguments.js.map +1 -1
  238. package/dist/frontend/lowering/call-signatures.d.ts +1 -6
  239. package/dist/frontend/lowering/call-signatures.js +16 -68
  240. package/dist/frontend/lowering/call-signatures.js.map +1 -1
  241. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +19 -4
  242. package/dist/frontend/lowering/class-dynamic-dispatch.js +168 -98
  243. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  244. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +44 -4
  245. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
  246. package/dist/frontend/lowering/class-method-mutations.js +0 -2
  247. package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
  248. package/dist/frontend/lowering/class-protocols.js +1 -1
  249. package/dist/frontend/lowering/class-protocols.js.map +1 -1
  250. package/dist/frontend/lowering/coercions/function-adapters.js +5 -35
  251. package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
  252. package/dist/frontend/lowering/coercions/state.d.ts +0 -1
  253. package/dist/frontend/lowering/coercions/state.js +0 -1
  254. package/dist/frontend/lowering/coercions/state.js.map +1 -1
  255. package/dist/frontend/lowering/coercions/structural-plans.js +2 -4
  256. package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
  257. package/dist/frontend/lowering/coercions/structural.js +2 -12
  258. package/dist/frontend/lowering/coercions/structural.js.map +1 -1
  259. package/dist/frontend/lowering/coercions/unions.d.ts +12 -0
  260. package/dist/frontend/lowering/coercions/unions.js +63 -1
  261. package/dist/frontend/lowering/coercions/unions.js.map +1 -1
  262. package/dist/frontend/lowering/containers/array-callbacks.js +9 -28
  263. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  264. package/dist/frontend/lowering/containers/array-construction.js +2 -3
  265. package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
  266. package/dist/frontend/lowering/containers/array-methods.js +10 -54
  267. package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
  268. package/dist/frontend/lowering/containers/bytes.js +0 -1
  269. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  270. package/dist/frontend/lowering/containers/callback-arguments.js +2 -10
  271. package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
  272. package/dist/frontend/lowering/containers/collection-methods.js +1 -6
  273. package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
  274. package/dist/frontend/lowering/containers/indexed-objects.js +0 -2
  275. package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
  276. package/dist/frontend/lowering/containers/string-and-regexp.d.ts +0 -6
  277. package/dist/frontend/lowering/containers/string-and-regexp.js +2 -10
  278. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  279. package/dist/frontend/lowering/expressions/evaluation-safety.js +0 -3
  280. package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
  281. package/dist/frontend/lowering/expressions/native-proxy.js +1 -1
  282. package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
  283. package/dist/frontend/lowering/expressions/nullish-assignment.js +0 -1
  284. package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
  285. package/dist/frontend/lowering/expressions/object-literals.d.ts +0 -8
  286. package/dist/frontend/lowering/expressions/object-literals.js +8 -35
  287. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  288. package/dist/frontend/lowering/expressions/optional-chains.d.ts +0 -4
  289. package/dist/frontend/lowering/expressions/optional-chains.js +7 -67
  290. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  291. package/dist/frontend/lowering/function-context.js +0 -1
  292. package/dist/frontend/lowering/function-context.js.map +1 -1
  293. package/dist/frontend/lowering/generic-functions.js +0 -1
  294. package/dist/frontend/lowering/generic-functions.js.map +1 -1
  295. package/dist/frontend/lowering/lib-boundary.js +10 -77
  296. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  297. package/dist/frontend/lowering/lower-array-sort.js +1 -10
  298. package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
  299. package/dist/frontend/lowering/lower-array-sort.test.js +2 -2
  300. package/dist/frontend/lowering/lower-array-sort.test.js.map +1 -1
  301. package/dist/frontend/lowering/lower-assert.js +2 -3
  302. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  303. package/dist/frontend/lowering/lower-async-iteration.js +1 -1
  304. package/dist/frontend/lowering/lower-calls.d.ts +2 -27
  305. package/dist/frontend/lowering/lower-calls.js +56 -465
  306. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  307. package/dist/frontend/lowering/lower-classes.js +11 -49
  308. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  309. package/dist/frontend/lowering/lower-comptime.js +2 -3
  310. package/dist/frontend/lowering/lower-comptime.js.map +1 -1
  311. package/dist/frontend/lowering/lower-enums.js +5 -8
  312. package/dist/frontend/lowering/lower-enums.js.map +1 -1
  313. package/dist/frontend/lowering/lower-event-emitter.js +3 -4
  314. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  315. package/dist/frontend/lowering/lower-expando.js +3 -5
  316. package/dist/frontend/lowering/lower-expando.js.map +1 -1
  317. package/dist/frontend/lowering/lower-exprs.d.ts +0 -8
  318. package/dist/frontend/lowering/lower-exprs.js +133 -908
  319. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  320. package/dist/frontend/lowering/lower-functions.js +2 -5
  321. package/dist/frontend/lowering/lower-functions.js.map +1 -1
  322. package/dist/frontend/lowering/lower-inspect.js +1 -50
  323. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  324. package/dist/frontend/lowering/lower-modules.d.ts +0 -43
  325. package/dist/frontend/lowering/lower-modules.js +25 -329
  326. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  327. package/dist/frontend/lowering/lower-modules.test.js +5 -5
  328. package/dist/frontend/lowering/lower-modules.test.js.map +1 -1
  329. package/dist/frontend/lowering/lower-server.js +0 -30
  330. package/dist/frontend/lowering/lower-server.js.map +1 -1
  331. package/dist/frontend/lowering/lower-stdlib.d.ts +98 -0
  332. package/dist/frontend/lowering/{lower-island.js → lower-stdlib.js} +97 -1160
  333. package/dist/frontend/lowering/lower-stdlib.js.map +1 -0
  334. package/dist/frontend/lowering/lower-stmts.d.ts +0 -16
  335. package/dist/frontend/lowering/lower-stmts.js +58 -1016
  336. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  337. package/dist/frontend/lowering/lower-stmts.test.js +1 -1
  338. package/dist/frontend/lowering/lower-stmts.test.js.map +1 -1
  339. package/dist/frontend/lowering/lower-stream.js +1 -3
  340. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  341. package/dist/frontend/lowering/lowerer.d.ts +26 -151
  342. package/dist/frontend/lowering/lowerer.js +120 -770
  343. package/dist/frontend/lowering/lowerer.js.map +1 -1
  344. package/dist/frontend/lowering/lowerer.test.js +4 -51
  345. package/dist/frontend/lowering/lowerer.test.js.map +1 -1
  346. package/dist/frontend/lowering/narrowing-stability.d.ts +100 -0
  347. package/dist/frontend/lowering/narrowing-stability.js +1174 -0
  348. package/dist/frontend/lowering/narrowing-stability.js.map +1 -0
  349. package/dist/frontend/lowering/narrowing-stability.test.js +150 -0
  350. package/dist/frontend/lowering/narrowing-stability.test.js.map +1 -0
  351. package/dist/frontend/lowering/optional-arguments.js +0 -2
  352. package/dist/frontend/lowering/optional-arguments.js.map +1 -1
  353. package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
  354. package/dist/frontend/lowering/strict-equality.js +1 -1
  355. package/dist/frontend/lowering/strict-equality.js.map +1 -1
  356. package/dist/frontend/lowering/surfaces.d.ts +6 -45
  357. package/dist/frontend/lowering/surfaces.js +5 -65
  358. package/dist/frontend/lowering/surfaces.js.map +1 -1
  359. package/dist/frontend/module-syntax.d.ts +0 -3
  360. package/dist/frontend/module-syntax.js.map +1 -1
  361. package/dist/frontend/npm-node.d.ts +0 -7
  362. package/dist/frontend/npm-node.js +0 -7
  363. package/dist/frontend/npm-node.js.map +1 -1
  364. package/dist/frontend/npm-static-rewrite-syntax.d.ts +1 -1
  365. package/dist/frontend/npm-static-rewrite-syntax.js +6 -82
  366. package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
  367. package/dist/frontend/npm-static.d.ts +1 -1
  368. package/dist/frontend/npm-static.js +6 -71
  369. package/dist/frontend/npm-static.js.map +1 -1
  370. package/dist/frontend/npm.d.ts +3 -319
  371. package/dist/frontend/npm.js +6 -1007
  372. package/dist/frontend/npm.js.map +1 -1
  373. package/dist/frontend/npm.test.js +2 -197
  374. package/dist/frontend/npm.test.js.map +1 -1
  375. package/dist/frontend/pipeline-native.js +1 -2
  376. package/dist/frontend/pipeline-native.js.map +1 -1
  377. package/dist/frontend/pipeline.d.ts +3 -11
  378. package/dist/frontend/pipeline.js +37 -56
  379. package/dist/frontend/pipeline.js.map +1 -1
  380. package/dist/frontend/pipeline.test.js +12 -6
  381. package/dist/frontend/pipeline.test.js.map +1 -1
  382. package/dist/frontend/program.d.ts +0 -34
  383. package/dist/frontend/program.js +13 -98
  384. package/dist/frontend/program.js.map +1 -1
  385. package/dist/frontend/provenance-core.d.ts +0 -4
  386. package/dist/frontend/provenance-core.js +4 -37
  387. package/dist/frontend/provenance-core.js.map +1 -1
  388. package/dist/frontend/provenance-registry.d.ts +0 -4
  389. package/dist/frontend/provenance-registry.js +0 -20
  390. package/dist/frontend/provenance-registry.js.map +1 -1
  391. package/dist/frontend/resolve.d.ts +0 -12
  392. package/dist/frontend/resolve.js +0 -34
  393. package/dist/frontend/resolve.js.map +1 -1
  394. package/dist/frontend/runtime-resolve.js +2 -2
  395. package/dist/frontend/runtime-resolve.js.map +1 -1
  396. package/dist/frontend/services-node.js +2 -3
  397. package/dist/frontend/services-node.js.map +1 -1
  398. package/dist/frontend/services.d.ts +1 -8
  399. package/dist/frontend/services.js +2 -22
  400. package/dist/frontend/services.js.map +1 -1
  401. package/dist/frontend/services.test.js +0 -38
  402. package/dist/frontend/services.test.js.map +1 -1
  403. package/dist/frontend/tsc-codes.js +0 -11
  404. package/dist/frontend/tsc-codes.js.map +1 -1
  405. package/dist/frontend/type-mapper.d.ts +2 -27
  406. package/dist/frontend/type-mapper.js +85 -153
  407. package/dist/frontend/type-mapper.js.map +1 -1
  408. package/dist/index.d.ts +1 -1
  409. package/dist/index.js +7 -10
  410. package/dist/index.js.map +1 -1
  411. package/dist/ir/api.d.ts +1 -1
  412. package/dist/ir/api.js +1 -1
  413. package/dist/ir/api.js.map +1 -1
  414. package/dist/ir/builtin-effects.js +0 -5
  415. package/dist/ir/builtin-effects.js.map +1 -1
  416. package/dist/ir/builtin-signatures.d.ts +1 -1
  417. package/dist/ir/builtin-signatures.js +1 -55
  418. package/dist/ir/builtin-signatures.js.map +1 -1
  419. package/dist/ir/constant-globals.test.js +1 -1
  420. package/dist/ir/constant-tables.test.js +1 -1
  421. package/dist/ir/final-fields.test.js +1 -1
  422. package/dist/ir/initializer-bindings.test.js +1 -1
  423. package/dist/ir/int32-slots.d.ts +29 -3
  424. package/dist/ir/int32-slots.js +152 -66
  425. package/dist/ir/int32-slots.js.map +1 -1
  426. package/dist/ir/int32-slots.test.js +1 -1
  427. package/dist/ir/integer-loops.js +3 -0
  428. package/dist/ir/integer-loops.js.map +1 -1
  429. package/dist/ir/integer-loops.test.js +26 -1
  430. package/dist/ir/integer-loops.test.js.map +1 -1
  431. package/dist/ir/integer-ranges.d.ts +20 -0
  432. package/dist/ir/integer-ranges.js +178 -21
  433. package/dist/ir/integer-ranges.js.map +1 -1
  434. package/dist/ir/integer-ranges.test.js +148 -3
  435. package/dist/ir/integer-ranges.test.js.map +1 -1
  436. package/dist/ir/ir.d.ts +44 -284
  437. package/dist/ir/ir.js +10 -259
  438. package/dist/ir/ir.js.map +1 -1
  439. package/dist/ir/ir.test.js +2 -7
  440. package/dist/ir/ir.test.js.map +1 -1
  441. package/dist/ir/runtime-features.d.ts +3 -30
  442. package/dist/ir/runtime-features.js +5 -41
  443. package/dist/ir/runtime-features.js.map +1 -1
  444. package/dist/ir/scalar-records.test.js +1 -1
  445. package/dist/ir/serialize.d.ts +6 -2
  446. package/dist/ir/serialize.js +11 -3
  447. package/dist/ir/serialize.js.map +1 -1
  448. package/dist/ir/traverse.js +0 -21
  449. package/dist/ir/traverse.js.map +1 -1
  450. package/dist/ir/unshare.d.ts +14 -0
  451. package/dist/ir/unshare.js +60 -0
  452. package/dist/ir/unshare.js.map +1 -0
  453. package/dist/ir/unshare.test.js +115 -0
  454. package/dist/ir/unshare.test.js.map +1 -0
  455. package/dist/ir/validate.js +9 -207
  456. package/dist/ir/validate.js.map +1 -1
  457. package/dist/ir/validate.test.js +6 -6
  458. package/dist/library/fence-eval.test.js +1 -1
  459. package/dist/library/int-infer.test.js +4 -4
  460. package/dist/library/library-cache.test.js +5 -5
  461. package/dist/library/prepare.js +14 -20
  462. package/dist/library/prepare.js.map +1 -1
  463. package/dist/native/cli.js +0 -2
  464. package/dist/native/cli.js.map +1 -1
  465. package/dist/native/compiler.test.js +2 -4
  466. package/dist/native/compiler.test.js.map +1 -1
  467. package/dist/native/prepare.js +2 -4
  468. package/dist/native/prepare.js.map +1 -1
  469. package/dist/native/sanitizer.js +2 -16
  470. package/dist/native/sanitizer.js.map +1 -1
  471. package/dist/native/sanitizer.test.js +0 -3
  472. package/dist/native/sanitizer.test.js.map +1 -1
  473. package/dist/startup-cache.js +0 -2
  474. package/dist/startup-cache.js.map +1 -1
  475. package/package.json +20 -20
  476. package/surface-manifest.json +80 -88
  477. package/dist/backend/llvm/expr-island.d.ts +0 -15
  478. package/dist/backend/llvm/expr-island.js +0 -709
  479. package/dist/backend/llvm/expr-island.js.map +0 -1
  480. package/dist/frontend/lowering/coercions/island.d.ts +0 -37
  481. package/dist/frontend/lowering/coercions/island.js +0 -350
  482. package/dist/frontend/lowering/coercions/island.js.map +0 -1
  483. package/dist/frontend/lowering/lower-island.d.ts +0 -229
  484. package/dist/frontend/lowering/lower-island.js.map +0 -1
  485. package/dist/frontend/lowering/lower-island.test.js +0 -56
  486. package/dist/frontend/lowering/lower-island.test.js.map +0 -1
  487. package/dist/frontend/npm-fetch-analysis.d.ts +0 -17
  488. package/dist/frontend/npm-fetch-analysis.js +0 -109
  489. package/dist/frontend/npm-fetch-analysis.js.map +0 -1
  490. package/dist/frontend/npm-fetch-analysis.test.js +0 -130
  491. package/dist/frontend/npm-fetch-analysis.test.js.map +0 -1
  492. package/dist/frontend/npm-fetch-node.d.ts +0 -2
  493. package/dist/frontend/npm-fetch-node.js +0 -12
  494. package/dist/frontend/npm-fetch-node.js.map +0 -1
  495. package/dist/frontend/npm-fetch-syntax.d.ts +0 -6
  496. package/dist/frontend/npm-fetch-syntax.js +0 -202
  497. package/dist/frontend/npm-fetch-syntax.js.map +0 -1
  498. package/dist/native/runtime-typescript.d.ts +0 -4
  499. package/dist/native/runtime-typescript.js +0 -74
  500. package/dist/native/runtime-typescript.js.map +0 -1
  501. package/dist/native/runtime-typescript.test.js +0 -41
  502. package/dist/native/runtime-typescript.test.js.map +0 -1
  503. /package/dist/{frontend/lowering/lower-island.test.d.ts → backend/immutability.test.d.ts} +0 -0
  504. /package/dist/frontend/{npm-fetch-analysis.test.d.ts → lowering/narrowing-stability.test.d.ts} +0 -0
  505. /package/dist/{native/runtime-typescript.test.d.ts → ir/unshare.test.d.ts} +0 -0
@@ -0,0 +1,1090 @@
1
+ import { isRefCounted, } from "../../ir/ir.js";
2
+ import { everyExprChild, everyStmtChild } from "../../ir/traverse.js";
3
+ import { borrowsMapMutationReceiver, borrowsMapReadInputs } from "./map-read-lifetimes.js";
4
+ import { preservesRegexInputs, VirtualTargets } from "./reference-effects.js";
5
+ import { borrowsStringInputs } from "./string-lifetimes.js";
6
+ import { preservesDynTest } from "./checked-value-lifetimes.js";
7
+ import { isStableReceiverOperand } from "../../ir/analysis.js";
8
+ /** Every heap location (key 0). */
9
+ const HEAP_KEY = "*";
10
+ /** Array element slots of every reference array share one location: arrays
11
+ * are covariant, so element types do not separate them. */
12
+ const ARRAY_KEY = "a";
13
+ /** Entries of typed maps and sets. */
14
+ const MAP_KEY = "m";
15
+ /** Captured-binding boxes. */
16
+ const BOX_KEY = "bx";
17
+ /** Record fields written through a computed key. */
18
+ const ANY_RECORD_KEY = "r:*";
19
+ /** The pseudo-function standing for every indirect call target. */
20
+ const ANY_FUNCTION = "%anyFunctionValue";
21
+ /** Value-producing kinds that only move an existing function value. */
22
+ const FUNCTION_MOVES = new Set([
23
+ "closure",
24
+ "selfRef",
25
+ "varRef",
26
+ "fieldGet",
27
+ "recordGet",
28
+ "arrayGet",
29
+ "call",
30
+ "virtualCall",
31
+ "callValue",
32
+ "ternary",
33
+ "logical",
34
+ "nullish",
35
+ "orDefault",
36
+ "unionNarrow",
37
+ "seqExpr",
38
+ "assignExpr",
39
+ "optChain",
40
+ "chainRecv",
41
+ "upcast",
42
+ "downcast",
43
+ "mapIntrinsic",
44
+ "setIntrinsic",
45
+ "arrIntrinsic",
46
+ "recordKeyGet",
47
+ "unionKeyGet",
48
+ ]);
49
+ /** Runtime library families that run no user code and never write a
50
+ * program reference (scalars, strings, byte buffers, files, clocks). */
51
+ const INERT_LIB_PREFIXES = [
52
+ "math.",
53
+ "num.",
54
+ "number.",
55
+ "string.",
56
+ "str.",
57
+ "bigint.",
58
+ "buffer.",
59
+ "arrayBuffer.",
60
+ "sharedArrayBuffer.",
61
+ "atomics.",
62
+ "perf.",
63
+ "date.",
64
+ "text.",
65
+ "path.",
66
+ "fs.",
67
+ "stats.",
68
+ "spawnRes.",
69
+ ];
70
+ const INERT_LIB_CALLS = new Set([
71
+ "dyn.compare",
72
+ "error.new",
73
+ "error.nodeThrow",
74
+ "dyn.typedRefIs",
75
+ "dyn.bagGet",
76
+ "json.parse",
77
+ "process.stderrWrite",
78
+ "process.stdoutWrite",
79
+ "process.envGet",
80
+ "process.envPairs",
81
+ "process.cwd",
82
+ "process.argv",
83
+ "process.platform",
84
+ "process.execPath",
85
+ "process.isTTY",
86
+ "worker.data",
87
+ "worker.isMainThread",
88
+ "worker.parentPort",
89
+ "worker.root",
90
+ "cp.spawnSyncOpts",
91
+ ]);
92
+ /** Array methods that never release an existing element or run user code. */
93
+ const PRESERVING_ARRAY_METHODS = new Set([
94
+ "length",
95
+ "getNumber",
96
+ "indexEq",
97
+ "push",
98
+ "pushSpread",
99
+ "concatSpread",
100
+ "unshift",
101
+ "unshiftSpread",
102
+ "indexOf",
103
+ "includes",
104
+ "nextPresent",
105
+ "join",
106
+ "slice",
107
+ "flatCopy",
108
+ "flatOne",
109
+ "toReversed",
110
+ "toSpliced",
111
+ "with",
112
+ "withUndefined",
113
+ "toSortedPrimitive",
114
+ // Permutes primitive payloads in place: every element keeps its owner.
115
+ "sortPrimitive",
116
+ ]);
117
+ /** Which heap reference locations evaluating code may overwrite or remove.
118
+ *
119
+ * ReferenceEffects answers one bit (does anything remove any edge?). This
120
+ * analysis keeps the location, so a borrow that reads `x.f` only conflicts
121
+ * with code that can write field `f` of x's hierarchy (or array elements,
122
+ * map entries, a global or a captured box, for those reads), not with
123
+ * every reference store. Locations:
124
+ *
125
+ * - `f:<hierarchy root>.<field>` class fields (all classes of a hierarchy
126
+ * that name the field share it, so redeclarations alias);
127
+ * - `r:<field>` record fields, plus `r:*` for computed-key writes and
128
+ * deletions (every record read also depends on `r:*`);
129
+ * - `a` reference array elements, `m` map/set entries, `bx` boxes;
130
+ * - `g:<id>` module globals, `l:<id>` the current function's own locals
131
+ * (dropped from summaries: a callee cannot rebind its caller's locals);
132
+ * - ALL for anything unknown: dynamic code, callbacks, suspension, unknown
133
+ * runtime operations.
134
+ *
135
+ * Stores a constructor makes into its own `this` write a fresh object that
136
+ * no borrow outside the construction can reach, so `new` (and `super`
137
+ * calls from constructors) use a constructor summary without them, as long
138
+ * as constructors are invoked only through `new` and `super`.
139
+ *
140
+ * Facts belong to one finalized module and one emission. */
141
+ export class ReferenceWrites {
142
+ functions;
143
+ intrinsicCall;
144
+ globals;
145
+ immutable;
146
+ keys = new Map();
147
+ roots = new Map();
148
+ fieldOwners = new Map();
149
+ classes = new Map();
150
+ virtualTargets;
151
+ summaries = new Map();
152
+ exprCache = new Map();
153
+ stmtCache = new Map();
154
+ words = 0;
155
+ /** The unknown heap write alone. */
156
+ heapAll = new Uint32Array(1).fill(1);
157
+ /** Constructors only ever run on fresh objects. */
158
+ freshConstructors;
159
+ unions;
160
+ records;
161
+ inertJson = new Map();
162
+ /** Closure bodies an indirect call can reach. */
163
+ functionValues = new Set();
164
+ callTargets;
165
+ /** Some function value comes from outside the module's closures. */
166
+ foreignFunctionValues = false;
167
+ current = null;
168
+ currentBoxed = new Set();
169
+ currentLocals = new Set();
170
+ constructors = new Set();
171
+ inConstructor = false;
172
+ constructor(functions, classes, intrinsicCall, globals, types = {},
173
+ /** Fields no code writes once their object is constructed
174
+ * (immutability.ts, from cycle-mutability's construction-only facts). */
175
+ immutable = null) {
176
+ this.functions = functions;
177
+ this.intrinsicCall = intrinsicCall;
178
+ this.globals = globals;
179
+ this.immutable = immutable;
180
+ this.key(HEAP_KEY);
181
+ this.unions = new Map((types.unions ?? []).map((u) => [u.id, u]));
182
+ this.records = new Map((types.records ?? []).map((r) => [r.id, r]));
183
+ for (const cls of classes)
184
+ this.classes.set(cls.name, cls);
185
+ this.virtualTargets = new VirtualTargets(classes);
186
+ const constructors = new Set(classes.map((cls) => `%${cls.name}.constructor`));
187
+ this.constructors = constructors;
188
+ this.freshConstructors = [...functions.values()].every((fn) => fn.body.every((s) => this.onlySuperCalls(fn, s, constructors)));
189
+ this.callTargets = new CallTargets(functions, this.virtualTargets);
190
+ this.solve(constructors);
191
+ }
192
+ /** Every direct call of a constructor is a `super` call from a
193
+ * constructor on its own `this`. */
194
+ onlySuperCalls(fn, s, constructors) {
195
+ const thisId = constructors.has(fn.name) ? fn.params[0]?.localId : undefined;
196
+ const expr = (e) => {
197
+ if (e.kind === "call" && constructors.has(e.callee)) {
198
+ const self = e.args[0];
199
+ if (thisId === undefined || !self || !isThisRef(self, thisId))
200
+ return false;
201
+ }
202
+ return everyExprChild(e, expr, stmt);
203
+ };
204
+ const stmt = (node) => everyStmtChild(node, expr, stmt);
205
+ return stmt(s);
206
+ }
207
+ key(k) {
208
+ let id = this.keys.get(k);
209
+ if (id === undefined) {
210
+ id = this.keys.size;
211
+ this.keys.set(k, id);
212
+ }
213
+ return id;
214
+ }
215
+ /** The hierarchy root of a class (runtime bases included). */
216
+ root(className) {
217
+ let r = this.roots.get(className);
218
+ if (r !== undefined)
219
+ return r;
220
+ r = className;
221
+ for (let cls = this.classes.get(className); cls?.base !== undefined;) {
222
+ r = cls.base;
223
+ cls = this.classes.get(cls.base);
224
+ }
225
+ this.roots.set(className, r);
226
+ return r;
227
+ }
228
+ fieldKey(className, field) {
229
+ return `f:${this.root(className)}.${field}`;
230
+ }
231
+ // ── phase 1: per-function local writes and call edges ─────────────────
232
+ solve(constructors) {
233
+ const nodes = new Map();
234
+ const scan = (fn, external) => {
235
+ const node = { local: new Set(), edges: new Set() };
236
+ if (fn.async || fn.generator) {
237
+ node.local.add(0);
238
+ return node;
239
+ }
240
+ const thisId = external && constructors.has(fn.name) ? (fn.params[0]?.localId ?? null) : null;
241
+ const boxed = boxedLocals(fn);
242
+ const sink = {
243
+ add: (k) => {
244
+ // Interned for queries; a callee's locals are private to it.
245
+ const id = this.key(k);
246
+ if (!k.startsWith("l:"))
247
+ node.local.add(id);
248
+ },
249
+ all: () => node.local.add(0),
250
+ call: (callee, fresh) => {
251
+ if (callee === ANY_FUNCTION) {
252
+ node.edges.add(ANY_FUNCTION);
253
+ return true;
254
+ }
255
+ if (!this.functions.has(callee))
256
+ return false;
257
+ node.edges.add(fresh && this.freshConstructors && constructors.has(callee) ? `${callee}#ext` : callee);
258
+ return true;
259
+ },
260
+ };
261
+ const expr = (e) => {
262
+ this.nodeWrites(e, sink, boxed, fn, constructors);
263
+ if (e.kind === "closure")
264
+ this.functionValues.add(e.fnName);
265
+ else if (e.type?.kind === "func" &&
266
+ !FUNCTION_MOVES.has(e.kind) &&
267
+ !(e.kind === "libCall" && e.fn === "error.nodeThrow"))
268
+ this.foreignFunctionValues = true;
269
+ return everyExprChild(e, expr, stmt);
270
+ };
271
+ const stmt = (s) => {
272
+ if (thisId !== null && s.kind === "fieldSet" && isThisRef(s.obj, thisId)) {
273
+ // A store into the fresh `this`: no outside borrow can reach it.
274
+ }
275
+ else
276
+ this.stmtWrites(s, sink, boxed);
277
+ return everyStmtChild(s, expr, stmt);
278
+ };
279
+ fn.body.every(stmt);
280
+ return node;
281
+ };
282
+ for (const fn of this.functions.values()) {
283
+ nodes.set(fn.name, scan(fn, false));
284
+ if (this.freshConstructors && constructors.has(fn.name))
285
+ nodes.set(`${fn.name}#ext`, scan(fn, true));
286
+ }
287
+ // Indirect calls reach any closure body; values made elsewhere
288
+ // (dynamic conversions) reach unknown code.
289
+ nodes.set(ANY_FUNCTION, {
290
+ local: new Set(this.foreignFunctionValues ? [0] : []),
291
+ edges: new Set([...this.functionValues].filter((name) => this.functions.has(name))),
292
+ });
293
+ this.words = (this.keys.size + 31) >>> 5;
294
+ this.heapAll = new Uint32Array(this.words);
295
+ this.heapAll[0] = 1;
296
+ // Tarjan's SCCs, iteratively; components come out callees first.
297
+ const index = new Map();
298
+ const low = new Map();
299
+ const onStack = new Set();
300
+ const stack = [];
301
+ let counter = 0;
302
+ for (const start of nodes.keys()) {
303
+ if (index.has(start))
304
+ continue;
305
+ const work = [];
306
+ const enter = (name) => {
307
+ index.set(name, counter);
308
+ low.set(name, counter++);
309
+ stack.push(name);
310
+ onStack.add(name);
311
+ work.push({ name, edges: nodes.get(name).edges.values() });
312
+ };
313
+ enter(start);
314
+ while (work.length > 0) {
315
+ const top = work[work.length - 1];
316
+ const next = top.edges.next();
317
+ if (!next.done) {
318
+ const callee = next.value;
319
+ if (!nodes.has(callee))
320
+ continue;
321
+ if (!index.has(callee))
322
+ enter(callee);
323
+ else if (onStack.has(callee))
324
+ low.set(top.name, Math.min(low.get(top.name), index.get(callee)));
325
+ continue;
326
+ }
327
+ work.pop();
328
+ if (work.length > 0) {
329
+ const parent = work[work.length - 1].name;
330
+ low.set(parent, Math.min(low.get(parent), low.get(top.name)));
331
+ }
332
+ if (low.get(top.name) !== index.get(top.name))
333
+ continue;
334
+ const members = [];
335
+ for (;;) {
336
+ const m = stack.pop();
337
+ onStack.delete(m);
338
+ members.push(m);
339
+ if (m === top.name)
340
+ break;
341
+ }
342
+ const bits = new Uint32Array(this.words);
343
+ const inComponent = new Set(members);
344
+ for (const m of members) {
345
+ const node = nodes.get(m);
346
+ for (const id of node.local)
347
+ setBit(bits, id);
348
+ for (const callee of node.edges) {
349
+ if (inComponent.has(callee))
350
+ continue;
351
+ const s = this.summaries.get(callee);
352
+ if (s === undefined || s === null)
353
+ continue;
354
+ orInto(bits, s);
355
+ }
356
+ }
357
+ // An unknown heap write subsumes the precise heap keys.
358
+ const summary = (bits[0] & 1) !== 0 ? this.heapAll : anyBit(bits) ? bits : null;
359
+ for (const m of members)
360
+ this.summaries.set(m, summary);
361
+ }
362
+ }
363
+ }
364
+ /** Writes of one expression node itself (children are separate). */
365
+ nodeWrites(e, sink, boxed, fn, constructors) {
366
+ switch (e.kind) {
367
+ case "call": {
368
+ const fresh = fn !== null &&
369
+ constructors.has(e.callee) &&
370
+ constructors.has(fn.name) &&
371
+ e.args[0] !== undefined &&
372
+ isThisRef(e.args[0], fn.params[0]?.localId ?? "");
373
+ if (!sink.call(e.callee, fresh) && !this.intrinsicCall(e))
374
+ sink.all();
375
+ return;
376
+ }
377
+ case "new":
378
+ if (!sink.call(`%${e.className}.constructor`, true))
379
+ sink.all();
380
+ return;
381
+ case "virtualCall": {
382
+ const targets = this.virtualTargets.targets(e.className, e.method);
383
+ if (targets === null)
384
+ sink.all();
385
+ else
386
+ for (const t of targets)
387
+ if (!sink.call(t, false))
388
+ sink.all();
389
+ return;
390
+ }
391
+ case "assignExpr":
392
+ case "incDec":
393
+ if (isRefCounted(e.type))
394
+ sink.add(this.localKey(e.localId, boxed));
395
+ return;
396
+ case "callValue": {
397
+ const targets = fn !== null ? this.callTargets.of(e.callee, fn) : null;
398
+ if (targets === null) {
399
+ if (!sink.call(ANY_FUNCTION, false))
400
+ sink.all();
401
+ }
402
+ else
403
+ for (const t of targets)
404
+ if (!sink.call(t, false))
405
+ sink.all();
406
+ return;
407
+ }
408
+ case "arrIntrinsic":
409
+ if (!PRESERVING_ARRAY_METHODS.has(e.method)) {
410
+ // The comparator sort orders a private snapshot.
411
+ if (e.method === "sortValues") {
412
+ const comparator = e.args[1];
413
+ const targets = fn !== null && comparator !== undefined ? this.callTargets.of(comparator, fn) : null;
414
+ if (targets === null) {
415
+ if (!sink.call(ANY_FUNCTION, false))
416
+ sink.all();
417
+ }
418
+ else
419
+ for (const t of targets)
420
+ if (!sink.call(t, false))
421
+ sink.all();
422
+ }
423
+ sink.add(ARRAY_KEY);
424
+ }
425
+ return;
426
+ case "mapIntrinsic":
427
+ case "setIntrinsic":
428
+ if (borrowsMapReadInputs(e))
429
+ return;
430
+ if (borrowsMapMutationReceiver(e))
431
+ sink.add(MAP_KEY);
432
+ else if (e.receiver.type.kind === "map" || e.receiver.type.kind === "set") {
433
+ // Typed collections: copies and iteration bookkeeping run no
434
+ // user code; leaving an iteration may compact removed entries.
435
+ if (e.method === "iterEnter" || e.method === "iterExit")
436
+ sink.add(MAP_KEY);
437
+ else if (e.method !== "clone" &&
438
+ e.method !== "keySet" &&
439
+ e.method !== "valueSet" &&
440
+ e.method !== "toArray")
441
+ sink.all();
442
+ }
443
+ else
444
+ sink.all();
445
+ return;
446
+ case "intrinsic":
447
+ // A TDZ test reads; publication only makes objects immortal.
448
+ if (e.name !== "module.tdzCheck" && e.name !== "threads.publish")
449
+ sink.all();
450
+ return;
451
+ case "dynFrom":
452
+ case "dynArrLit":
453
+ case "dynObjLit":
454
+ return;
455
+ case "dynCheck":
456
+ // Identity and kind tests of class and primitive targets.
457
+ if (!this.checkedWithoutCode(e.type))
458
+ sink.all();
459
+ return;
460
+ case "jsonStringify":
461
+ if (!this.jsonInert(e.value.type))
462
+ sink.all();
463
+ return;
464
+ case "bytesNew":
465
+ case "bytesIntrinsic":
466
+ return;
467
+ case "strIntrinsic":
468
+ if (!borrowsStringInputs(e.method))
469
+ sink.all();
470
+ return;
471
+ case "regexIntrinsic":
472
+ if (!preservesRegexInputs(e.method))
473
+ sink.all();
474
+ return;
475
+ case "libCall":
476
+ if (!this.inertLibCall(e))
477
+ sink.all();
478
+ return;
479
+ case "toString":
480
+ if (!this.primitive(e.operand.type))
481
+ sink.all();
482
+ return;
483
+ case "dynTest":
484
+ if (!preservesDynTest(e.test))
485
+ sink.all();
486
+ return;
487
+ // Reads, tests, arithmetic and fresh allocations.
488
+ case "numLit":
489
+ case "boolLit":
490
+ case "strLit":
491
+ case "unitLit":
492
+ case "varRef":
493
+ case "bin":
494
+ case "unary":
495
+ case "toBool":
496
+ case "logical":
497
+ case "nullish":
498
+ case "ternary":
499
+ case "seqExpr":
500
+ case "fieldGet":
501
+ case "recordGet":
502
+ case "unionNarrow":
503
+ case "unionIsTag":
504
+ case "unionWrap":
505
+ case "downcast":
506
+ case "upcast":
507
+ case "instanceOf":
508
+ case "strConcat":
509
+ case "strEq":
510
+ case "strCmp":
511
+ case "arrayGet":
512
+ case "arrayHas":
513
+ case "arrayState":
514
+ case "unionEq":
515
+ case "unionFuncEq":
516
+ case "dynScalarEq":
517
+ case "caughtTest":
518
+ case "caughtNarrow":
519
+ case "caughtCheck":
520
+ case "classRef":
521
+ case "recordLit":
522
+ case "arrayLit":
523
+ case "arrayNewLen":
524
+ case "closure":
525
+ case "mapNew":
526
+ case "setNew":
527
+ case "regexLit":
528
+ case "recordHas":
529
+ case "recordKeyGet":
530
+ case "recordOvfHas":
531
+ case "recordOvfKeys":
532
+ case "fieldAbsent":
533
+ case "unionDisc":
534
+ case "unionKeyGet":
535
+ case "fieldIncDec":
536
+ case "optChain":
537
+ case "chainRecv":
538
+ case "orDefault":
539
+ case "instanceOfValue":
540
+ case "promiseVoidWiden":
541
+ return;
542
+ default:
543
+ sink.all();
544
+ }
545
+ }
546
+ /** Writes of one statement node itself. */
547
+ stmtWrites(s, sink, boxed) {
548
+ switch (s.kind) {
549
+ case "assign":
550
+ if (isRefCounted(s.value.type))
551
+ sink.add(this.localKey(s.localId, boxed));
552
+ return;
553
+ case "fieldSet":
554
+ if (isRefCounted(s.value.type))
555
+ sink.add(this.fieldKey(s.className, s.field));
556
+ return;
557
+ case "recordSet":
558
+ if (isRefCounted(s.value.type))
559
+ sink.add(`r:${s.field}`);
560
+ return;
561
+ case "recordKeySet":
562
+ case "recordKeyDelete":
563
+ sink.add(ANY_RECORD_KEY);
564
+ return;
565
+ case "arraySet":
566
+ case "arraySetUndefined":
567
+ case "arrayDelete":
568
+ case "arraySetLength":
569
+ sink.add(ARRAY_KEY);
570
+ return;
571
+ case "varDecl":
572
+ case "exprStmt":
573
+ case "return":
574
+ case "throw":
575
+ case "runtimeFence":
576
+ case "if":
577
+ case "for":
578
+ case "forOf":
579
+ case "while":
580
+ case "doWhile":
581
+ case "block":
582
+ case "switch":
583
+ case "break":
584
+ case "continue":
585
+ case "bytesSet":
586
+ case "tryCatch":
587
+ case "rethrow":
588
+ return;
589
+ default:
590
+ sink.all();
591
+ }
592
+ }
593
+ /** Library calls that run no user code: inert families without callback
594
+ * arguments, and an Error options bag that is a typed record (no
595
+ * accessors) or absent. */
596
+ inertLibCall(e) {
597
+ if (e.fn === "error.nodeThrow" || isStableReceiverOperand(e, ""))
598
+ return true;
599
+ if (e.fn === "error.newOptions")
600
+ return e.args.every((arg) => arg.type.kind !== "dyn" ||
601
+ (arg.kind === "dynFrom" &&
602
+ (arg.value.type.kind === "record" || this.primitive(arg.value.type))));
603
+ if (!INERT_LIB_CALLS.has(e.fn) && !INERT_LIB_PREFIXES.some((p) => e.fn.startsWith(p)))
604
+ return false;
605
+ return e.args.every((arg) => arg.type.kind !== "func" &&
606
+ (arg.type.kind !== "dyn" ||
607
+ (e.fn !== "dyn.compare" && e.fn.startsWith("dyn.")) ||
608
+ // A wrapped primitive has no methods to call back into.
609
+ (arg.kind === "dynFrom" && this.primitive(arg.value.type))));
610
+ }
611
+ /** Numbers, booleans, strings and unit values (and unions of them). */
612
+ primitive(t) {
613
+ switch (t.kind) {
614
+ case "f64":
615
+ case "bool":
616
+ case "string":
617
+ case "undefinedT":
618
+ case "nullT":
619
+ return true;
620
+ case "union":
621
+ return this.unions.get(t.unionId)?.arms.every((arm) => this.primitive(arm)) ?? false;
622
+ default:
623
+ return false;
624
+ }
625
+ }
626
+ /** A dynamic-to-typed check that only tests identity or kind. */
627
+ checkedWithoutCode(t) {
628
+ if (t.kind === "object" || this.primitive(t))
629
+ return true;
630
+ if (t.kind !== "union")
631
+ return false;
632
+ return (this.unions
633
+ .get(t.unionId)
634
+ ?.arms.every((arm) => arm.kind === "object" || this.primitive(arm)) ?? false);
635
+ }
636
+ /** JSON.stringify of this type calls no toJSON or accessor: primitives
637
+ * and records/arrays/unions of them (class instances may define both). */
638
+ jsonInert(t) {
639
+ if (this.primitive(t))
640
+ return true;
641
+ const key = JSON.stringify(t);
642
+ const known = this.inertJson.get(key);
643
+ if (known !== undefined)
644
+ return known;
645
+ this.inertJson.set(key, true); // recursive shapes: assume, then confirm
646
+ let result;
647
+ if (t.kind === "array")
648
+ result = this.jsonInert(t.elem);
649
+ else if (t.kind === "record")
650
+ result = this.records.get(t.shapeId)?.fields.every((f) => this.jsonInert(f.type)) ?? false;
651
+ else if (t.kind === "union")
652
+ result = this.unions.get(t.unionId)?.arms.every((arm) => this.jsonInert(arm)) ?? false;
653
+ else
654
+ result = false;
655
+ this.inertJson.set(key, result);
656
+ return result;
657
+ }
658
+ localKey(id, boxed, locals) {
659
+ if (this.globals.has(id))
660
+ return `g:${id}`;
661
+ // A binding of another function (never expected) counts as a box.
662
+ if (boxed.has(id) || (locals !== undefined && !locals.has(id)))
663
+ return BOX_KEY;
664
+ return `l:${id}`;
665
+ }
666
+ // ── queries ────────────────────────────────────────────────────────────
667
+ /** Start answering expression queries for one function body. */
668
+ enter(fn) {
669
+ this.current = fn;
670
+ this.currentBoxed = boxedLocals(fn);
671
+ this.currentLocals = new Set(fn.locals.map((local) => local.id));
672
+ this.inConstructor = this.constructors.has(fn.name);
673
+ for (const p of fn.params)
674
+ this.currentLocals.add(p.localId);
675
+ this.exprCache.clear();
676
+ this.stmtCache.clear();
677
+ }
678
+ bodyWrites = new Map();
679
+ /** Whether a walk of `fn` reads only locations its whole body never
680
+ * writes; the candidate walk locals' own rebinding is exempt. */
681
+ unwrittenWalk(fn, value, candidates, call) {
682
+ if (this.current !== fn)
683
+ this.enter(fn);
684
+ const keys = this.readKeys(value, call);
685
+ if (keys === null)
686
+ return false;
687
+ let body = this.bodyWrites.get(fn.name);
688
+ if (body === undefined) {
689
+ body = this.stmts(fn.body);
690
+ this.bodyWrites.set(fn.name, body);
691
+ }
692
+ return !this.conflicts(keys.filter((k) => !(k.startsWith("l:") && candidates.has(k.slice(2)))), body);
693
+ }
694
+ /** The transitive writes of a call to a module function (`#ext` for a
695
+ * constructor reached through `new`). */
696
+ summary(name) {
697
+ const known = this.summaries.get(name);
698
+ return known === undefined ? this.heapAll : known;
699
+ }
700
+ constructWrites(className) {
701
+ const ctor = `%${className}.constructor`;
702
+ if (!this.functions.has(ctor))
703
+ return this.heapAll;
704
+ return this.summary(this.freshConstructors ? `${ctor}#ext` : ctor);
705
+ }
706
+ virtualWrites(className, method) {
707
+ const targets = this.virtualTargets.targets(className, method);
708
+ if (targets === null)
709
+ return this.heapAll;
710
+ return this.union(targets.map((t) => this.summary(t)));
711
+ }
712
+ /** Writes of evaluating an expression, with its operands. */
713
+ expr(e) {
714
+ const known = this.exprCache.get(e);
715
+ if (known !== undefined)
716
+ return known;
717
+ const parts = [];
718
+ const sink = this.querySink(parts);
719
+ this.nodeWrites(e, sink, this.currentBoxed, this.current, new Set());
720
+ everyExprChild(e, (child) => (parts.push(this.expr(child)), true), (child) => (parts.push(this.stmt(child)), true));
721
+ const result = this.union(parts);
722
+ this.exprCache.set(e, result);
723
+ return result;
724
+ }
725
+ stmt(s) {
726
+ const known = this.stmtCache.get(s);
727
+ if (known !== undefined)
728
+ return known;
729
+ const parts = [];
730
+ this.stmtWrites(s, this.querySink(parts), this.currentBoxed);
731
+ everyStmtChild(s, (child) => (parts.push(this.expr(child)), true), (child) => (parts.push(this.stmt(child)), true));
732
+ const result = this.union(parts);
733
+ this.stmtCache.set(s, result);
734
+ return result;
735
+ }
736
+ stmts(list) {
737
+ return this.union(list.map((s) => this.stmt(s)));
738
+ }
739
+ querySink(parts) {
740
+ return {
741
+ add: (k) => parts.push(this.bitsOf([k])),
742
+ all: () => parts.push(this.heapAll),
743
+ call: (callee, fresh) => {
744
+ if (callee === ANY_FUNCTION) {
745
+ parts.push(this.summary(ANY_FUNCTION));
746
+ return true;
747
+ }
748
+ if (!this.functions.has(callee))
749
+ return false;
750
+ const ctor = fresh && callee.endsWith(".constructor") && this.freshConstructors;
751
+ parts.push(this.summary(ctor ? `${callee}#ext` : callee));
752
+ return true;
753
+ },
754
+ };
755
+ }
756
+ union(parts) {
757
+ let out = null;
758
+ for (const p of parts) {
759
+ if (p === null)
760
+ continue;
761
+ if (out === null)
762
+ out = new Uint32Array(this.words);
763
+ orInto(out, p);
764
+ }
765
+ return out;
766
+ }
767
+ /** A bitset over known keys; keys nothing writes are dropped. */
768
+ bitsOf(keys) {
769
+ let out = null;
770
+ for (const k of keys) {
771
+ const id = this.keys.get(k);
772
+ if (id === undefined || id >= this.words * 32)
773
+ continue;
774
+ if (out === null)
775
+ out = new Uint32Array(this.words);
776
+ setBit(out, id);
777
+ }
778
+ return out;
779
+ }
780
+ /** Whether writes may touch any of the read keys. */
781
+ conflicts(reads, writes) {
782
+ if (writes === null)
783
+ return false;
784
+ const heap = (writes[0] & 1) !== 0;
785
+ for (const k of reads) {
786
+ if (heap && !k.startsWith("l:"))
787
+ return true;
788
+ const id = this.keys.get(k);
789
+ if (id === undefined || id >= this.words * 32)
790
+ continue;
791
+ if ((writes[id >>> 5] & (1 << (id & 31))) !== 0)
792
+ return true;
793
+ }
794
+ return false;
795
+ }
796
+ /** The locations whose writes could release the object a borrowed read
797
+ * of `e` yields, or null when `e` is not such a projection. `call`
798
+ * resolves borrowed-return callees to the locations their walks read. */
799
+ readKeys(e, call) {
800
+ const out = [];
801
+ const walk = (node) => {
802
+ switch (node.kind) {
803
+ case "varRef":
804
+ out.push(this.localKey(node.localId, this.currentBoxed, this.currentLocals));
805
+ return true;
806
+ case "fieldGet":
807
+ // A construction-only field of an existing object never changes;
808
+ // only a constructor can still be writing it (its own `this`).
809
+ if (this.inConstructor || !this.immutable?.classField(node.className, node.field))
810
+ out.push(this.fieldKey(node.className, node.field));
811
+ return walk(node.obj);
812
+ case "recordGet":
813
+ if (this.inConstructor || !this.immutable?.recordField(node.shapeId, node.field))
814
+ out.push(`r:${node.field}`, ANY_RECORD_KEY);
815
+ return walk(node.obj);
816
+ case "arrayGet":
817
+ out.push(ARRAY_KEY);
818
+ return this.expr(node.index) === null && walk(node.arr);
819
+ case "unionNarrow":
820
+ case "upcast":
821
+ case "downcast":
822
+ return walk(node.value);
823
+ case "unionWrap":
824
+ return node.value.kind === "unitLit" || walk(node.value);
825
+ case "ternary":
826
+ return this.expr(node.cond) === null && armWalk(node.then) && armWalk(node.else_);
827
+ case "seqExpr": {
828
+ // Guarded projections: `(check, value)` where the checks only
829
+ // read and throw.
830
+ if (this.stmts(node.stmts) !== null)
831
+ return false;
832
+ return walk(node.result);
833
+ }
834
+ case "strLit":
835
+ return true;
836
+ case "call": {
837
+ const keys = call?.(node) ?? null;
838
+ if (keys === null)
839
+ return false;
840
+ out.push(...keys);
841
+ return node.args.every((arg) => !isRefCounted(arg.type) || walk(arg));
842
+ }
843
+ default:
844
+ return false;
845
+ }
846
+ };
847
+ const armWalk = (node) => (node.kind === "libCall" && node.fn === "error.nodeThrow") || walk(node);
848
+ return walk(e) ? out : null;
849
+ }
850
+ }
851
+ function isThisRef(e, thisId) {
852
+ if (e.kind === "varRef")
853
+ return e.localId === thisId;
854
+ if (e.kind === "upcast")
855
+ return isThisRef(e.value, thisId);
856
+ return false;
857
+ }
858
+ /** Locals living in boxes: declared boxed or captured from an enclosing
859
+ * function. */
860
+ function boxedLocals(fn) {
861
+ const out = new Set();
862
+ for (const local of fn.locals)
863
+ if (local.boxed)
864
+ out.add(local.id);
865
+ for (const c of fn.captures ?? [])
866
+ out.add(c.localId);
867
+ for (const c of fn.classCaptures ?? [])
868
+ out.add(c.localId);
869
+ return out;
870
+ }
871
+ /** The closure bodies a function value can be, when it flows only from
872
+ * closure expressions through stable locals and the function-typed
873
+ * parameters of functions that are only called directly (null: any
874
+ * function value). A small flow analysis over parameter positions: each
875
+ * position collects the targets every direct, virtual and `new` call site
876
+ * passes, to a fixpoint. */
877
+ class CallTargets {
878
+ functions;
879
+ sites = new Map();
880
+ opaque = new Set();
881
+ params = new Map();
882
+ definitions = new Map();
883
+ /** Functions creating each closure body. */
884
+ creators = new Map();
885
+ constructor(functions, virtualTargets) {
886
+ this.functions = functions;
887
+ const site = (callee, caller, args) => {
888
+ let list = this.sites.get(callee);
889
+ if (!list)
890
+ this.sites.set(callee, (list = []));
891
+ list.push({ caller, args });
892
+ };
893
+ for (const fn of functions.values()) {
894
+ if (fn.captures !== undefined || fn.classCaptures !== undefined)
895
+ this.opaque.add(fn.name);
896
+ const expr = (e) => {
897
+ if (e.kind === "call")
898
+ site(e.callee, fn, e.args);
899
+ else if (e.kind === "new")
900
+ site(`%${e.className}.constructor`, fn, [e, ...e.args]);
901
+ else if (e.kind === "virtualCall") {
902
+ const targets = virtualTargets.targets(e.className, e.method);
903
+ for (const t of targets ?? [])
904
+ site(t, fn, e.args);
905
+ }
906
+ else if (e.kind === "closure") {
907
+ this.opaque.add(e.fnName);
908
+ let list = this.creators.get(e.fnName);
909
+ if (!list)
910
+ this.creators.set(e.fnName, (list = []));
911
+ list.push(fn);
912
+ }
913
+ return everyExprChild(e, expr, stmt);
914
+ };
915
+ const stmt = (st) => everyStmtChild(st, expr, stmt);
916
+ fn.body.every(stmt);
917
+ }
918
+ // Fixpoint over function-typed parameter positions.
919
+ const positions = [];
920
+ for (const fn of functions.values())
921
+ fn.params.forEach((p, i) => {
922
+ if (p.type.kind === "func") {
923
+ positions.push([fn, i]);
924
+ this.params.set(`${fn.name}#${i}`, new Set());
925
+ }
926
+ });
927
+ for (let changed = true; changed;) {
928
+ changed = false;
929
+ for (const [fn, i] of positions) {
930
+ const key = `${fn.name}#${i}`;
931
+ const known = this.params.get(key);
932
+ if (known === null)
933
+ continue;
934
+ const sites = this.sites.get(fn.name);
935
+ let next = new Set(known);
936
+ if (this.opaque.has(fn.name) || !sites || this.assigned(fn, fn.params[i].localId))
937
+ next = null;
938
+ else
939
+ for (const { caller, args } of sites) {
940
+ const arg = args[i];
941
+ const t = arg === undefined ? null : this.resolve(arg, caller, 0);
942
+ if (t === null) {
943
+ next = null;
944
+ break;
945
+ }
946
+ for (const name of t)
947
+ next.add(name);
948
+ }
949
+ if (next === null || next.size !== known.size) {
950
+ this.params.set(key, next);
951
+ changed = true;
952
+ }
953
+ }
954
+ }
955
+ }
956
+ of(callee, fn) {
957
+ const t = this.resolve(callee, fn, 0);
958
+ return t === null ? null : [...t];
959
+ }
960
+ resolve(e, fn, depth) {
961
+ if (depth > 8)
962
+ return null;
963
+ switch (e.kind) {
964
+ case "closure":
965
+ return new Set([e.fnName]);
966
+ case "ternary":
967
+ case "logical":
968
+ case "nullish":
969
+ case "orDefault": {
970
+ const arms = e.kind === "ternary" ? [e.then, e.else_] : [e.left, e.right];
971
+ const out = new Set();
972
+ for (const arm of arms) {
973
+ if (arm.type.kind !== "func") {
974
+ if (arm.kind === "libCall" && arm.fn === "error.nodeThrow")
975
+ continue;
976
+ if (e.kind === "ternary")
977
+ return null;
978
+ continue; // the tested operand of `a ?? f`, `a || f`
979
+ }
980
+ const t = this.resolve(arm, fn, depth + 1);
981
+ if (t === null)
982
+ return null;
983
+ for (const name of t)
984
+ out.add(name);
985
+ }
986
+ return out;
987
+ }
988
+ case "varRef": {
989
+ if ((fn.captures ?? []).some((c) => c.localId === e.localId)) {
990
+ // A captured binding nothing rebinds holds what it held in every
991
+ // function creating this closure.
992
+ const creators = this.creators.get(fn.name);
993
+ if (!creators || this.assigned(fn, e.localId))
994
+ return null;
995
+ const out = new Set();
996
+ for (const creator of creators) {
997
+ const t = this.resolve(e, creator, depth + 1);
998
+ if (t === null)
999
+ return null;
1000
+ for (const name of t)
1001
+ out.add(name);
1002
+ }
1003
+ return out;
1004
+ }
1005
+ const index = fn.params.findIndex((p) => p.localId === e.localId);
1006
+ if (index >= 0) {
1007
+ if (this.assigned(fn, e.localId))
1008
+ return null;
1009
+ return this.params.get(`${fn.name}#${index}`) ?? null;
1010
+ }
1011
+ const def = this.definition(fn, e.localId);
1012
+ return def ? this.resolve(def, fn, depth + 1) : null;
1013
+ }
1014
+ case "call": {
1015
+ // A function value returned by a module function: whatever every
1016
+ // return yields (adapters return closures over their argument).
1017
+ const callee = this.functions.get(e.callee);
1018
+ if (!callee || callee.async || callee.generator)
1019
+ return null;
1020
+ const out = new Set();
1021
+ let ok = true;
1022
+ let any = false;
1023
+ const stmt = (st) => {
1024
+ if (st.kind === "return") {
1025
+ any = true;
1026
+ const t = st.value ? this.resolve(st.value, callee, depth + 1) : null;
1027
+ if (t === null)
1028
+ return (ok = false);
1029
+ for (const name of t)
1030
+ out.add(name);
1031
+ }
1032
+ return everyStmtChild(st, () => true, stmt);
1033
+ };
1034
+ callee.body.every(stmt);
1035
+ return ok && any ? out : null;
1036
+ }
1037
+ default:
1038
+ return null;
1039
+ }
1040
+ }
1041
+ /** The single initializer of a never-assigned, unboxed local. */
1042
+ definition(fn, id) {
1043
+ let defs = this.definitions.get(fn);
1044
+ if (!defs) {
1045
+ defs = new Map();
1046
+ const boxed = new Set(fn.locals.filter((l) => l.boxed).map((l) => l.id));
1047
+ const counts = new Map();
1048
+ const expr = (e) => {
1049
+ if (e.kind === "assignExpr" || e.kind === "incDec")
1050
+ counts.set(e.localId, 2);
1051
+ return everyExprChild(e, expr, stmt);
1052
+ };
1053
+ const stmt = (st) => {
1054
+ if (st.kind === "varDecl") {
1055
+ counts.set(st.localId, (counts.get(st.localId) ?? 0) + 1);
1056
+ defs.set(st.localId, st.init);
1057
+ }
1058
+ else if (st.kind === "assign")
1059
+ counts.set(st.localId, 2);
1060
+ return everyStmtChild(st, expr, stmt);
1061
+ };
1062
+ fn.body.every(stmt);
1063
+ for (const [local, n] of counts)
1064
+ if (n !== 1 || boxed.has(local))
1065
+ defs.set(local, null);
1066
+ this.definitions.set(fn, defs);
1067
+ }
1068
+ return defs.get(id) ?? null;
1069
+ }
1070
+ assigned(fn, id) {
1071
+ this.definition(fn, id);
1072
+ const defs = this.definitions.get(fn);
1073
+ return defs.has(id);
1074
+ }
1075
+ }
1076
+ function setBit(bits, id) {
1077
+ const w = id >>> 5;
1078
+ bits[w] = bits[w] | (1 << (id & 31));
1079
+ }
1080
+ function orInto(bits, other) {
1081
+ for (let w = 0; w < bits.length; w++)
1082
+ bits[w] = bits[w] | other[w];
1083
+ }
1084
+ function anyBit(bits) {
1085
+ for (let w = 0; w < bits.length; w++)
1086
+ if (bits[w] !== 0)
1087
+ return true;
1088
+ return false;
1089
+ }
1090
+ //# sourceMappingURL=reference-writes.js.map