@scriptc/compiler 0.2.6 → 0.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (588) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +7 -18
  2. package/dist/backend/cycle-analysis.d.ts +21 -9
  3. package/dist/backend/cycle-analysis.js +139 -67
  4. package/dist/backend/cycle-analysis.js.map +1 -1
  5. package/dist/backend/cycle-analysis.test.js +283 -3
  6. package/dist/backend/cycle-analysis.test.js.map +1 -1
  7. package/dist/backend/cycle-mutability.d.ts +39 -0
  8. package/dist/backend/cycle-mutability.js +205 -0
  9. package/dist/backend/cycle-mutability.js.map +1 -0
  10. package/dist/backend/link-plan-core.d.ts +2 -1
  11. package/dist/backend/link-plan-core.js +15 -3
  12. package/dist/backend/link-plan-core.js.map +1 -1
  13. package/dist/backend/link-plan.d.ts +2 -1
  14. package/dist/backend/link-plan.js.map +1 -1
  15. package/dist/backend/llvm/alloc.d.ts +43 -0
  16. package/dist/backend/llvm/alloc.js +246 -0
  17. package/dist/backend/llvm/alloc.js.map +1 -0
  18. package/dist/backend/llvm/alloc.test.d.ts +1 -0
  19. package/dist/backend/llvm/alloc.test.js +102 -0
  20. package/dist/backend/llvm/alloc.test.js.map +1 -0
  21. package/dist/backend/llvm/blocks.d.ts +9 -0
  22. package/dist/backend/llvm/blocks.js +9 -0
  23. package/dist/backend/llvm/blocks.js.map +1 -1
  24. package/dist/backend/llvm/borrowed-receivers.d.ts +7 -0
  25. package/dist/backend/llvm/borrowed-receivers.js +39 -0
  26. package/dist/backend/llvm/borrowed-receivers.js.map +1 -1
  27. package/dist/backend/llvm/call-lifetimes.d.ts +18 -3
  28. package/dist/backend/llvm/call-lifetimes.js +54 -19
  29. package/dist/backend/llvm/call-lifetimes.js.map +1 -1
  30. package/dist/backend/llvm/call-lifetimes.test.js +178 -3
  31. package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
  32. package/dist/backend/llvm/checked-narrows.d.ts +24 -0
  33. package/dist/backend/llvm/checked-narrows.js +108 -0
  34. package/dist/backend/llvm/checked-narrows.js.map +1 -0
  35. package/dist/backend/llvm/checked-narrows.test.d.ts +1 -0
  36. package/dist/backend/llvm/checked-narrows.test.js +208 -0
  37. package/dist/backend/llvm/checked-narrows.test.js.map +1 -0
  38. package/dist/backend/llvm/classes.d.ts +16 -1
  39. package/dist/backend/llvm/classes.js +60 -49
  40. package/dist/backend/llvm/classes.js.map +1 -1
  41. package/dist/backend/llvm/classes.test.js +68 -6
  42. package/dist/backend/llvm/classes.test.js.map +1 -1
  43. package/dist/backend/llvm/common.d.ts +13 -0
  44. package/dist/backend/llvm/common.js +30 -0
  45. package/dist/backend/llvm/common.js.map +1 -1
  46. package/dist/backend/llvm/constant-callbacks.d.ts +19 -3
  47. package/dist/backend/llvm/constant-callbacks.js +289 -52
  48. package/dist/backend/llvm/constant-callbacks.js.map +1 -1
  49. package/dist/backend/llvm/constant-callbacks.test.js +140 -3
  50. package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
  51. package/dist/backend/llvm/debug-info.d.ts +6 -2
  52. package/dist/backend/llvm/debug-info.js +11 -1
  53. package/dist/backend/llvm/debug-info.js.map +1 -1
  54. package/dist/backend/llvm/dense-array-access.d.ts +29 -0
  55. package/dist/backend/llvm/dense-array-access.js +335 -0
  56. package/dist/backend/llvm/dense-array-access.js.map +1 -0
  57. package/dist/backend/llvm/dense-array-access.test.d.ts +1 -0
  58. package/dist/backend/llvm/dense-array-access.test.js +238 -0
  59. package/dist/backend/llvm/dense-array-access.test.js.map +1 -0
  60. package/dist/backend/llvm/dyn.d.ts +38 -0
  61. package/dist/backend/llvm/dyn.js +213 -14
  62. package/dist/backend/llvm/dyn.js.map +1 -1
  63. package/dist/backend/llvm/emitter.d.ts +308 -15
  64. package/dist/backend/llvm/emitter.js +1788 -206
  65. package/dist/backend/llvm/emitter.js.map +1 -1
  66. package/dist/backend/llvm/emitter.test.js +89 -7
  67. package/dist/backend/llvm/emitter.test.js.map +1 -1
  68. package/dist/backend/llvm/expr-async.js +62 -8
  69. package/dist/backend/llvm/expr-async.js.map +1 -1
  70. package/dist/backend/llvm/expr-async.test.d.ts +1 -0
  71. package/dist/backend/llvm/expr-async.test.js +62 -0
  72. package/dist/backend/llvm/expr-async.test.js.map +1 -0
  73. package/dist/backend/llvm/expr-bytes.d.ts +1 -1
  74. package/dist/backend/llvm/expr-bytes.js +85 -8
  75. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  76. package/dist/backend/llvm/expr-callbacks.js +29 -21
  77. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  78. package/dist/backend/llvm/expr-calls.d.ts +5 -0
  79. package/dist/backend/llvm/expr-calls.js +118 -15
  80. package/dist/backend/llvm/expr-calls.js.map +1 -1
  81. package/dist/backend/llvm/expr-containers.d.ts +7 -1
  82. package/dist/backend/llvm/expr-containers.js +246 -32
  83. package/dist/backend/llvm/expr-containers.js.map +1 -1
  84. package/dist/backend/llvm/expr-control.js +113 -8
  85. package/dist/backend/llvm/expr-control.js.map +1 -1
  86. package/dist/backend/llvm/expr-dispatch.js +2 -0
  87. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  88. package/dist/backend/llvm/expr-dynamic.js +244 -44
  89. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  90. package/dist/backend/llvm/expr-island.js +3 -8
  91. package/dist/backend/llvm/expr-island.js.map +1 -1
  92. package/dist/backend/llvm/expr-primitives.d.ts +1 -1
  93. package/dist/backend/llvm/expr-primitives.js +93 -36
  94. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  95. package/dist/backend/llvm/expr-primitives.test.js +51 -3
  96. package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
  97. package/dist/backend/llvm/expr-records.js +31 -17
  98. package/dist/backend/llvm/expr-records.js.map +1 -1
  99. package/dist/backend/llvm/expr-stream-bridges.js +96 -29
  100. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  101. package/dist/backend/llvm/expr-stream-bridges.test.js +1 -1
  102. package/dist/backend/llvm/expr-stream-callbacks.js +6 -3
  103. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  104. package/dist/backend/llvm/integer-remainder.d.ts +11 -0
  105. package/dist/backend/llvm/integer-remainder.js +91 -0
  106. package/dist/backend/llvm/integer-remainder.js.map +1 -1
  107. package/dist/backend/llvm/layouts.d.ts +3 -1
  108. package/dist/backend/llvm/layouts.js +3 -2
  109. package/dist/backend/llvm/layouts.js.map +1 -1
  110. package/dist/backend/llvm/lazy-captures.d.ts +16 -0
  111. package/dist/backend/llvm/lazy-captures.js +96 -0
  112. package/dist/backend/llvm/lazy-captures.js.map +1 -0
  113. package/dist/backend/llvm/lazy-captures.test.d.ts +1 -0
  114. package/dist/backend/llvm/lazy-captures.test.js +78 -0
  115. package/dist/backend/llvm/lazy-captures.test.js.map +1 -0
  116. package/dist/backend/llvm/lib-abi.js +10 -0
  117. package/dist/backend/llvm/lib-abi.js.map +1 -1
  118. package/dist/backend/llvm/lib-filesystem.js +10 -15
  119. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  120. package/dist/backend/llvm/lib-process.js +8 -8
  121. package/dist/backend/llvm/lib-process.js.map +1 -1
  122. package/dist/backend/llvm/lib-shared.js +1 -0
  123. package/dist/backend/llvm/lib-shared.js.map +1 -1
  124. package/dist/backend/llvm/local-array-reads.d.ts +5 -1
  125. package/dist/backend/llvm/local-array-reads.js +147 -26
  126. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  127. package/dist/backend/llvm/local-array-reads.test.js +85 -4
  128. package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
  129. package/dist/backend/llvm/local-union-storage.d.ts +5 -1
  130. package/dist/backend/llvm/local-union-storage.js +54 -8
  131. package/dist/backend/llvm/local-union-storage.js.map +1 -1
  132. package/dist/backend/llvm/local-union-storage.test.js +94 -6
  133. package/dist/backend/llvm/local-union-storage.test.js.map +1 -1
  134. package/dist/backend/llvm/map-number-lookup.d.ts +18 -0
  135. package/dist/backend/llvm/map-number-lookup.js +62 -0
  136. package/dist/backend/llvm/map-number-lookup.js.map +1 -0
  137. package/dist/backend/llvm/map-read-lifetimes.d.ts +6 -0
  138. package/dist/backend/llvm/map-read-lifetimes.js +24 -3
  139. package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
  140. package/dist/backend/llvm/map-read-lifetimes.test.js +39 -20
  141. package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -1
  142. package/dist/backend/llvm/nullable-fields.d.ts +28 -0
  143. package/dist/backend/llvm/nullable-fields.js +45 -0
  144. package/dist/backend/llvm/nullable-fields.js.map +1 -0
  145. package/dist/backend/llvm/nullable-fields.test.d.ts +1 -0
  146. package/dist/backend/llvm/nullable-fields.test.js +48 -0
  147. package/dist/backend/llvm/nullable-fields.test.js.map +1 -0
  148. package/dist/backend/llvm/nullable-unions.d.ts +68 -0
  149. package/dist/backend/llvm/nullable-unions.js +132 -0
  150. package/dist/backend/llvm/nullable-unions.js.map +1 -0
  151. package/dist/backend/llvm/publish.d.ts +58 -0
  152. package/dist/backend/llvm/publish.js +286 -0
  153. package/dist/backend/llvm/publish.js.map +1 -0
  154. package/dist/backend/llvm/rebound-parameters.d.ts +12 -0
  155. package/dist/backend/llvm/rebound-parameters.js +72 -0
  156. package/dist/backend/llvm/rebound-parameters.js.map +1 -0
  157. package/dist/backend/llvm/rebound-parameters.test.d.ts +1 -0
  158. package/dist/backend/llvm/rebound-parameters.test.js +67 -0
  159. package/dist/backend/llvm/rebound-parameters.test.js.map +1 -0
  160. package/dist/backend/llvm/reference-effects.d.ts +18 -2
  161. package/dist/backend/llvm/reference-effects.js +106 -16
  162. package/dist/backend/llvm/reference-effects.js.map +1 -1
  163. package/dist/backend/llvm/reference-effects.test.js +52 -1
  164. package/dist/backend/llvm/reference-effects.test.js.map +1 -1
  165. package/dist/backend/llvm/serialized-ir-emission.test.d.ts +1 -0
  166. package/dist/backend/llvm/serialized-ir-emission.test.js +52 -0
  167. package/dist/backend/llvm/serialized-ir-emission.test.js.map +1 -0
  168. package/dist/backend/llvm/shapes.d.ts +104 -9
  169. package/dist/backend/llvm/shapes.js +356 -46
  170. package/dist/backend/llvm/shapes.js.map +1 -1
  171. package/dist/backend/llvm/shapes.test.js +139 -5
  172. package/dist/backend/llvm/shapes.test.js.map +1 -1
  173. package/dist/backend/llvm/stack-callbacks.js +2 -3
  174. package/dist/backend/llvm/stack-callbacks.js.map +1 -1
  175. package/dist/backend/llvm/stack-captures.d.ts +3 -1
  176. package/dist/backend/llvm/stack-captures.js +5 -3
  177. package/dist/backend/llvm/stack-captures.js.map +1 -1
  178. package/dist/backend/llvm/stack-unions.test.js +43 -3
  179. package/dist/backend/llvm/stack-unions.test.js.map +1 -1
  180. package/dist/backend/llvm/string-construction.d.ts +10 -0
  181. package/dist/backend/llvm/string-construction.js +42 -0
  182. package/dist/backend/llvm/string-construction.js.map +1 -1
  183. package/dist/backend/llvm/string-construction.test.js +1 -1
  184. package/dist/backend/llvm/string-key-hash.d.ts +15 -0
  185. package/dist/backend/llvm/string-key-hash.js +76 -0
  186. package/dist/backend/llvm/string-key-hash.js.map +1 -0
  187. package/dist/backend/llvm/string-key-hash.test.d.ts +1 -0
  188. package/dist/backend/llvm/string-key-hash.test.js +45 -0
  189. package/dist/backend/llvm/string-key-hash.test.js.map +1 -0
  190. package/dist/backend/llvm/string-lifetimes.test.js +65 -15
  191. package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
  192. package/dist/backend/llvm/string-reads.d.ts +7 -0
  193. package/dist/backend/llvm/string-reads.js +76 -0
  194. package/dist/backend/llvm/string-reads.js.map +1 -0
  195. package/dist/backend/llvm/switch-dispatch.js +1 -1
  196. package/dist/backend/llvm/switch-dispatch.js.map +1 -1
  197. package/dist/backend/llvm/switch-dispatch.test.js +3 -3
  198. package/dist/backend/llvm/switch-dispatch.test.js.map +1 -1
  199. package/dist/backend/llvm/test-boxed-unions.d.ts +5 -0
  200. package/dist/backend/llvm/test-boxed-unions.js +13 -0
  201. package/dist/backend/llvm/test-boxed-unions.js.map +1 -0
  202. package/dist/backend/llvm/union-repr.d.ts +15 -0
  203. package/dist/backend/llvm/union-repr.js +89 -0
  204. package/dist/backend/llvm/union-repr.js.map +1 -0
  205. package/dist/backend/llvm/virtual-borrows.d.ts +31 -0
  206. package/dist/backend/llvm/virtual-borrows.js +82 -0
  207. package/dist/backend/llvm/virtual-borrows.js.map +1 -0
  208. package/dist/backend/llvm/walk-borrows.d.ts +43 -0
  209. package/dist/backend/llvm/walk-borrows.js +150 -0
  210. package/dist/backend/llvm/walk-borrows.js.map +1 -0
  211. package/dist/backend/llvm/walk-borrows.test.d.ts +1 -0
  212. package/dist/backend/llvm/walk-borrows.test.js +119 -0
  213. package/dist/backend/llvm/walk-borrows.test.js.map +1 -0
  214. package/dist/backend/llvm/walkers.d.ts +5 -1
  215. package/dist/backend/llvm/walkers.js +24 -21
  216. package/dist/backend/llvm/walkers.js.map +1 -1
  217. package/dist/backend/may-throw.d.ts +29 -1
  218. package/dist/backend/may-throw.js +349 -3
  219. package/dist/backend/may-throw.js.map +1 -1
  220. package/dist/backend/may-throw.test.js +114 -2
  221. package/dist/backend/may-throw.test.js.map +1 -1
  222. package/dist/backend/native/cache-warm.d.ts +2 -1
  223. package/dist/backend/native/cache-warm.js.map +1 -1
  224. package/dist/backend/native/contracts.d.ts +3 -2
  225. package/dist/backend/native/contracts.js.map +1 -1
  226. package/dist/backend/native/runtime-inputs.d.ts +1 -1
  227. package/dist/backend/native/runtime-inputs.js +2 -0
  228. package/dist/backend/native/runtime-inputs.js.map +1 -1
  229. package/dist/backend/native-codegen-core.d.ts +7 -4
  230. package/dist/backend/native-codegen-core.js +14 -9
  231. package/dist/backend/native-codegen-core.js.map +1 -1
  232. package/dist/backend/native-codegen.d.ts +9 -0
  233. package/dist/backend/native-codegen.js +53 -2
  234. package/dist/backend/native-codegen.js.map +1 -1
  235. package/dist/backend/native-codegen.test.js +64 -10
  236. package/dist/backend/native-codegen.test.js.map +1 -1
  237. package/dist/backend/native-link-info-core.d.ts +3 -2
  238. package/dist/backend/native-link-info-core.js.map +1 -1
  239. package/dist/backend/native-link-info.d.ts +2 -1
  240. package/dist/backend/native-link-info.js.map +1 -1
  241. package/dist/backend/native-link-info.test.js +2 -2
  242. package/dist/backend/native-link-info.test.js.map +1 -1
  243. package/dist/backend/native-tools.d.ts +5 -1
  244. package/dist/backend/native-tools.js +3 -1
  245. package/dist/backend/native-tools.js.map +1 -1
  246. package/dist/backend/optimization.d.ts +25 -0
  247. package/dist/backend/optimization.js +21 -0
  248. package/dist/backend/optimization.js.map +1 -0
  249. package/dist/backend/optimization.test.d.ts +1 -0
  250. package/dist/backend/optimization.test.js +24 -0
  251. package/dist/backend/optimization.test.js.map +1 -0
  252. package/dist/backend/publication.d.ts +28 -0
  253. package/dist/backend/publication.js +155 -0
  254. package/dist/backend/publication.js.map +1 -0
  255. package/dist/backend/publication.test.d.ts +1 -0
  256. package/dist/backend/publication.test.js +72 -0
  257. package/dist/backend/publication.test.js.map +1 -0
  258. package/dist/backend/runtime-abi.d.ts +2 -2
  259. package/dist/backend/runtime-abi.js +2 -2
  260. package/dist/backend/runtime-pack-core.d.ts +15 -4
  261. package/dist/backend/runtime-pack-core.js +23 -12
  262. package/dist/backend/runtime-pack-core.js.map +1 -1
  263. package/dist/backend/runtime-pack-native.d.ts +7 -3
  264. package/dist/backend/runtime-pack-native.js +0 -3
  265. package/dist/backend/runtime-pack-native.js.map +1 -1
  266. package/dist/backend/runtime-pack-targets.test.js +1 -1
  267. package/dist/backend/runtime-pack.d.ts +20 -2
  268. package/dist/backend/runtime-pack.js +23 -0
  269. package/dist/backend/runtime-pack.js.map +1 -1
  270. package/dist/backend/runtime-pack.test.js +115 -2
  271. package/dist/backend/runtime-pack.test.js.map +1 -1
  272. package/dist/backend/target-diagnostics.test.js +1 -1
  273. package/dist/backend/targets.d.ts +2 -1
  274. package/dist/backend/targets.js +1 -1
  275. package/dist/backend/targets.js.map +1 -1
  276. package/dist/cli/command.js +75 -11
  277. package/dist/cli/command.js.map +1 -1
  278. package/dist/cli/host.d.ts +2 -1
  279. package/dist/cli/usage.d.ts +4 -1
  280. package/dist/cli/usage.js +13 -3
  281. package/dist/cli/usage.js.map +1 -1
  282. package/dist/compile-types.d.ts +17 -5
  283. package/dist/coverage/report.d.ts +25 -2
  284. package/dist/coverage/report.js +161 -33
  285. package/dist/coverage/report.js.map +1 -1
  286. package/dist/coverage/verdict-cache.d.ts +63 -0
  287. package/dist/coverage/verdict-cache.js +193 -0
  288. package/dist/coverage/verdict-cache.js.map +1 -0
  289. package/dist/coverage/verdict-cache.test.d.ts +1 -0
  290. package/dist/coverage/verdict-cache.test.js +52 -0
  291. package/dist/coverage/verdict-cache.test.js.map +1 -0
  292. package/dist/coverage/verdict-semantic.d.ts +2 -0
  293. package/dist/coverage/verdict-semantic.js +24 -0
  294. package/dist/coverage/verdict-semantic.js.map +1 -0
  295. package/dist/coverage/verdict-startup.d.ts +15 -0
  296. package/dist/coverage/verdict-startup.js +66 -0
  297. package/dist/coverage/verdict-startup.js.map +1 -0
  298. package/dist/diagnostics/diagnostic.d.ts +29 -1
  299. package/dist/diagnostics/diagnostic.js +84 -12
  300. package/dist/diagnostics/diagnostic.js.map +1 -1
  301. package/dist/diagnostics/envelope.d.ts +130 -0
  302. package/dist/diagnostics/envelope.js +257 -0
  303. package/dist/diagnostics/envelope.js.map +1 -0
  304. package/dist/diagnostics/envelope.test.d.ts +1 -0
  305. package/dist/diagnostics/envelope.test.js +91 -0
  306. package/dist/diagnostics/envelope.test.js.map +1 -0
  307. package/dist/diagnostics/render.d.ts +3 -0
  308. package/dist/diagnostics/render.js +13 -2
  309. package/dist/diagnostics/render.js.map +1 -1
  310. package/dist/executable/executable-cache.d.ts +2 -2
  311. package/dist/executable/executable-cache.js +7 -4
  312. package/dist/executable/executable-cache.js.map +1 -1
  313. package/dist/executable/executable-cache.test.js +20 -0
  314. package/dist/executable/executable-cache.test.js.map +1 -1
  315. package/dist/executable/prepare.d.ts +4 -0
  316. package/dist/executable/prepare.js +7 -1
  317. package/dist/executable/prepare.js.map +1 -1
  318. package/dist/frontend/analysis.js +1 -0
  319. package/dist/frontend/analysis.js.map +1 -1
  320. package/dist/frontend/lowering/abstract-equality.js +5 -49
  321. package/dist/frontend/lowering/abstract-equality.js.map +1 -1
  322. package/dist/frontend/lowering/array-values.d.ts +30 -0
  323. package/dist/frontend/lowering/array-values.js +246 -1
  324. package/dist/frontend/lowering/array-values.js.map +1 -1
  325. package/dist/frontend/lowering/builtins/errors.js +17 -2
  326. package/dist/frontend/lowering/builtins/errors.js.map +1 -1
  327. package/dist/frontend/lowering/builtins/numbers.js +29 -1
  328. package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
  329. package/dist/frontend/lowering/builtins/process.d.ts +10 -17
  330. package/dist/frontend/lowering/builtins/process.js +66 -29
  331. package/dist/frontend/lowering/builtins/process.js.map +1 -1
  332. package/dist/frontend/lowering/builtins/workers.js +4 -2
  333. package/dist/frontend/lowering/builtins/workers.js.map +1 -1
  334. package/dist/frontend/lowering/caught-value-dispatch.d.ts +11 -0
  335. package/dist/frontend/lowering/caught-value-dispatch.js +87 -0
  336. package/dist/frontend/lowering/caught-value-dispatch.js.map +1 -0
  337. package/dist/frontend/lowering/class-assertions.d.ts +12 -0
  338. package/dist/frontend/lowering/class-assertions.js +229 -5
  339. package/dist/frontend/lowering/class-assertions.js.map +1 -1
  340. package/dist/frontend/lowering/class-callbacks.d.ts +3 -3
  341. package/dist/frontend/lowering/class-callbacks.js +18 -5
  342. package/dist/frontend/lowering/class-callbacks.js.map +1 -1
  343. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +1 -0
  344. package/dist/frontend/lowering/class-dynamic-dispatch.js +12 -6
  345. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  346. package/dist/frontend/lowering/class-method-mutations.d.ts +5 -0
  347. package/dist/frontend/lowering/class-method-mutations.js +472 -0
  348. package/dist/frontend/lowering/class-method-mutations.js.map +1 -0
  349. package/dist/frontend/lowering/class-method-values.js +25 -5
  350. package/dist/frontend/lowering/class-method-values.js.map +1 -1
  351. package/dist/frontend/lowering/class-prototypes.js +8 -2
  352. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  353. package/dist/frontend/lowering/class-unions.d.ts +16 -0
  354. package/dist/frontend/lowering/class-unions.js +127 -0
  355. package/dist/frontend/lowering/class-unions.js.map +1 -0
  356. package/dist/frontend/lowering/coercions/builders.js +8 -1
  357. package/dist/frontend/lowering/coercions/builders.js.map +1 -1
  358. package/dist/frontend/lowering/coercions/function-adapters.js +2 -0
  359. package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
  360. package/dist/frontend/lowering/coercions/identity.d.ts +7 -0
  361. package/dist/frontend/lowering/coercions/identity.js +26 -0
  362. package/dist/frontend/lowering/coercions/identity.js.map +1 -0
  363. package/dist/frontend/lowering/coercions/state.d.ts +6 -0
  364. package/dist/frontend/lowering/coercions/state.js +2 -0
  365. package/dist/frontend/lowering/coercions/state.js.map +1 -1
  366. package/dist/frontend/lowering/coercions/structural.js +9 -6
  367. package/dist/frontend/lowering/coercions/structural.js.map +1 -1
  368. package/dist/frontend/lowering/coercions/unions.d.ts +8 -0
  369. package/dist/frontend/lowering/coercions/unions.js +67 -2
  370. package/dist/frontend/lowering/coercions/unions.js.map +1 -1
  371. package/dist/frontend/lowering/collation-repertoire.d.ts +1 -0
  372. package/dist/frontend/lowering/collation-repertoire.js +19 -0
  373. package/dist/frontend/lowering/collation-repertoire.js.map +1 -0
  374. package/dist/frontend/lowering/collection-narrowing.d.ts +6 -0
  375. package/dist/frontend/lowering/collection-narrowing.js +31 -0
  376. package/dist/frontend/lowering/collection-narrowing.js.map +1 -0
  377. package/dist/frontend/lowering/construction-escapes.d.ts +38 -0
  378. package/dist/frontend/lowering/construction-escapes.js +146 -0
  379. package/dist/frontend/lowering/construction-escapes.js.map +1 -0
  380. package/dist/frontend/lowering/construction-escapes.test.d.ts +1 -0
  381. package/dist/frontend/lowering/construction-escapes.test.js +150 -0
  382. package/dist/frontend/lowering/construction-escapes.test.js.map +1 -0
  383. package/dist/frontend/lowering/containers/array-callback-call.d.ts +7 -0
  384. package/dist/frontend/lowering/containers/array-callback-call.js +52 -0
  385. package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -0
  386. package/dist/frontend/lowering/containers/array-callbacks.d.ts +1 -1
  387. package/dist/frontend/lowering/containers/array-callbacks.js +416 -65
  388. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  389. package/dist/frontend/lowering/containers/array-concat.d.ts +7 -0
  390. package/dist/frontend/lowering/containers/array-concat.js +130 -0
  391. package/dist/frontend/lowering/containers/array-concat.js.map +1 -0
  392. package/dist/frontend/lowering/containers/array-construction.d.ts +2 -0
  393. package/dist/frontend/lowering/containers/array-construction.js +110 -5
  394. package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
  395. package/dist/frontend/lowering/containers/array-methods.d.ts +1 -11
  396. package/dist/frontend/lowering/containers/array-methods.js +274 -144
  397. package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
  398. package/dist/frontend/lowering/containers/callback-arguments.js +43 -1
  399. package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
  400. package/dist/frontend/lowering/containers/collection-methods.js +10 -1
  401. package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
  402. package/dist/frontend/lowering/containers/indexed-objects.js +56 -70
  403. package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
  404. package/dist/frontend/lowering/containers/string-and-regexp.js +7 -63
  405. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  406. package/dist/frontend/lowering/cycle-initialization.d.ts +46 -0
  407. package/dist/frontend/lowering/cycle-initialization.js +303 -0
  408. package/dist/frontend/lowering/cycle-initialization.js.map +1 -0
  409. package/dist/frontend/lowering/divergences.d.ts +9 -0
  410. package/dist/frontend/lowering/divergences.js +630 -0
  411. package/dist/frontend/lowering/divergences.js.map +1 -0
  412. package/dist/frontend/lowering/expressions/evaluation-safety.js +4 -0
  413. package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
  414. package/dist/frontend/lowering/expressions/object-literals.js +178 -34
  415. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  416. package/dist/frontend/lowering/expressions/union-field-write.d.ts +4 -4
  417. package/dist/frontend/lowering/expressions/union-field-write.js +54 -44
  418. package/dist/frontend/lowering/expressions/union-field-write.js.map +1 -1
  419. package/dist/frontend/lowering/iterator-adapters.d.ts +20 -0
  420. package/dist/frontend/lowering/iterator-adapters.js +605 -0
  421. package/dist/frontend/lowering/iterator-adapters.js.map +1 -0
  422. package/dist/frontend/lowering/lower-array-sort.d.ts +1 -1
  423. package/dist/frontend/lowering/lower-array-sort.js +44 -5
  424. package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
  425. package/dist/frontend/lowering/lower-array-sort.test.d.ts +1 -0
  426. package/dist/frontend/lowering/lower-array-sort.test.js +31 -0
  427. package/dist/frontend/lowering/lower-array-sort.test.js.map +1 -0
  428. package/dist/frontend/lowering/lower-assert.js +7 -0
  429. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  430. package/dist/frontend/lowering/lower-builtin-values.js +1 -0
  431. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  432. package/dist/frontend/lowering/lower-calls.d.ts +8 -3
  433. package/dist/frontend/lowering/lower-calls.js +388 -278
  434. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  435. package/dist/frontend/lowering/lower-classes.d.ts +6 -0
  436. package/dist/frontend/lowering/lower-classes.js +117 -65
  437. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  438. package/dist/frontend/lowering/lower-exprs.d.ts +22 -2
  439. package/dist/frontend/lowering/lower-exprs.js +811 -254
  440. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  441. package/dist/frontend/lowering/lower-functions.js +32 -19
  442. package/dist/frontend/lowering/lower-functions.js.map +1 -1
  443. package/dist/frontend/lowering/lower-generators.d.ts +19 -13
  444. package/dist/frontend/lowering/lower-generators.js +67 -44
  445. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  446. package/dist/frontend/lowering/lower-inspect.js +29 -4
  447. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  448. package/dist/frontend/lowering/lower-island.d.ts +1 -1
  449. package/dist/frontend/lowering/lower-island.js +24 -7
  450. package/dist/frontend/lowering/lower-island.js.map +1 -1
  451. package/dist/frontend/lowering/lower-modules.js +100 -3
  452. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  453. package/dist/frontend/lowering/lower-stmts.js +82 -64
  454. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  455. package/dist/frontend/lowering/lowerer.d.ts +115 -2
  456. package/dist/frontend/lowering/lowerer.js +1266 -88
  457. package/dist/frontend/lowering/lowerer.js.map +1 -1
  458. package/dist/frontend/lowering/native-ffi.js +3 -1
  459. package/dist/frontend/lowering/native-ffi.js.map +1 -1
  460. package/dist/frontend/lowering/runtime-optional-bounds.d.ts +19 -0
  461. package/dist/frontend/lowering/runtime-optional-bounds.js +354 -0
  462. package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -0
  463. package/dist/frontend/lowering/runtime-optional-bounds.test.d.ts +1 -0
  464. package/dist/frontend/lowering/runtime-optional-bounds.test.js +66 -0
  465. package/dist/frontend/lowering/runtime-optional-bounds.test.js.map +1 -0
  466. package/dist/frontend/lowering/runtime-optional-elements.d.ts +117 -0
  467. package/dist/frontend/lowering/runtime-optional-elements.js +738 -0
  468. package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -0
  469. package/dist/frontend/lowering/runtime-optional-guards.d.ts +36 -0
  470. package/dist/frontend/lowering/runtime-optional-guards.js +375 -0
  471. package/dist/frontend/lowering/runtime-optional-guards.js.map +1 -0
  472. package/dist/frontend/lowering/runtime-optional-guards.test.d.ts +1 -0
  473. package/dist/frontend/lowering/runtime-optional-guards.test.js +92 -0
  474. package/dist/frontend/lowering/runtime-optional-guards.test.js.map +1 -0
  475. package/dist/frontend/lowering/runtime-optional-ownership.d.ts +63 -0
  476. package/dist/frontend/lowering/runtime-optional-ownership.js +382 -0
  477. package/dist/frontend/lowering/runtime-optional-ownership.js.map +1 -0
  478. package/dist/frontend/lowering/runtime-optional-provenance.d.ts +16 -0
  479. package/dist/frontend/lowering/runtime-optional-provenance.js +41 -0
  480. package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -0
  481. package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
  482. package/dist/frontend/lowering/strict-equality.d.ts +9 -0
  483. package/dist/frontend/lowering/strict-equality.js +116 -0
  484. package/dist/frontend/lowering/strict-equality.js.map +1 -0
  485. package/dist/frontend/lowering/string-index-bounds.d.ts +36 -0
  486. package/dist/frontend/lowering/string-index-bounds.js +537 -0
  487. package/dist/frontend/lowering/string-index-bounds.js.map +1 -0
  488. package/dist/frontend/lowering/string-index-bounds.test.d.ts +1 -0
  489. package/dist/frontend/lowering/string-index-bounds.test.js +223 -0
  490. package/dist/frontend/lowering/string-index-bounds.test.js.map +1 -0
  491. package/dist/frontend/lowering/surfaces.js +3 -0
  492. package/dist/frontend/lowering/surfaces.js.map +1 -1
  493. package/dist/frontend/lowering/union-comparison.d.ts +5 -0
  494. package/dist/frontend/lowering/union-comparison.js +47 -0
  495. package/dist/frontend/lowering/union-comparison.js.map +1 -0
  496. package/dist/frontend/lowering/union-narrow.d.ts +2 -0
  497. package/dist/frontend/lowering/union-narrow.js +10 -6
  498. package/dist/frontend/lowering/union-narrow.js.map +1 -1
  499. package/dist/frontend/program-analysis.d.ts +10 -0
  500. package/dist/frontend/program-analysis.js +7 -0
  501. package/dist/frontend/program-analysis.js.map +1 -1
  502. package/dist/frontend/program.d.ts +63 -2
  503. package/dist/frontend/program.js +1038 -61
  504. package/dist/frontend/program.js.map +1 -1
  505. package/dist/frontend/program.test.js +122 -6
  506. package/dist/frontend/program.test.js.map +1 -1
  507. package/dist/frontend/resolve.d.ts +6 -0
  508. package/dist/frontend/resolve.js +14 -0
  509. package/dist/frontend/resolve.js.map +1 -1
  510. package/dist/frontend/threads-import.d.ts +5 -0
  511. package/dist/frontend/threads-import.js +21 -0
  512. package/dist/frontend/threads-import.js.map +1 -0
  513. package/dist/frontend/type-mapper.d.ts +4 -1
  514. package/dist/frontend/type-mapper.js +161 -20
  515. package/dist/frontend/type-mapper.js.map +1 -1
  516. package/dist/frontend/type-mapper.test.js +15 -3
  517. package/dist/frontend/type-mapper.test.js.map +1 -1
  518. package/dist/frontend/worker-target.d.ts +4 -0
  519. package/dist/frontend/worker-target.js +8 -1
  520. package/dist/frontend/worker-target.js.map +1 -1
  521. package/dist/index.d.ts +6 -1
  522. package/dist/index.js +70 -16
  523. package/dist/index.js.map +1 -1
  524. package/dist/ir/analysis.d.ts +3 -1
  525. package/dist/ir/analysis.js +4 -0
  526. package/dist/ir/analysis.js.map +1 -1
  527. package/dist/ir/build.d.ts +5 -0
  528. package/dist/ir/build.js +7 -0
  529. package/dist/ir/build.js.map +1 -1
  530. package/dist/ir/builtin-signatures.d.ts +1 -1
  531. package/dist/ir/builtin-signatures.js +5 -3
  532. package/dist/ir/builtin-signatures.js.map +1 -1
  533. package/dist/ir/constant-tables.test.js +1 -1
  534. package/dist/ir/initializer-bindings.test.js +1 -1
  535. package/dist/ir/int32-slots.d.ts +72 -0
  536. package/dist/ir/int32-slots.js +837 -0
  537. package/dist/ir/int32-slots.js.map +1 -0
  538. package/dist/ir/int32-slots.test.d.ts +1 -0
  539. package/dist/ir/int32-slots.test.js +222 -0
  540. package/dist/ir/int32-slots.test.js.map +1 -0
  541. package/dist/ir/integer-ranges.d.ts +19 -3
  542. package/dist/ir/integer-ranges.js +168 -23
  543. package/dist/ir/integer-ranges.js.map +1 -1
  544. package/dist/ir/integer-ranges.test.js +74 -2
  545. package/dist/ir/integer-ranges.test.js.map +1 -1
  546. package/dist/ir/ir.d.ts +101 -20
  547. package/dist/ir/ir.js +20 -6
  548. package/dist/ir/ir.js.map +1 -1
  549. package/dist/ir/scalar-records.test.js +1 -1
  550. package/dist/ir/serialize.d.ts +1 -1
  551. package/dist/ir/serialize.js +3 -3
  552. package/dist/ir/serialize.js.map +1 -1
  553. package/dist/ir/traverse.js +8 -0
  554. package/dist/ir/traverse.js.map +1 -1
  555. package/dist/ir/validate.js +139 -22
  556. package/dist/ir/validate.js.map +1 -1
  557. package/dist/ir/validate.test.js +308 -8
  558. package/dist/ir/validate.test.js.map +1 -1
  559. package/dist/library/fence-eval.test.js +1 -1
  560. package/dist/library/int-infer.test.js +4 -4
  561. package/dist/library/library-cache.test.js +5 -5
  562. package/dist/library/library-profile.d.ts +2 -1
  563. package/dist/library/library-profile.js +4 -3
  564. package/dist/library/library-profile.js.map +1 -1
  565. package/dist/native/cache.d.ts +3 -0
  566. package/dist/native/cache.js +49 -1
  567. package/dist/native/cache.js.map +1 -1
  568. package/dist/native/cache.test.js +21 -1
  569. package/dist/native/cache.test.js.map +1 -1
  570. package/dist/native/cli.js +1 -1
  571. package/dist/native/cli.js.map +1 -1
  572. package/dist/native/compiler.d.ts +5 -0
  573. package/dist/native/compiler.js +51 -4
  574. package/dist/native/compiler.js.map +1 -1
  575. package/dist/native/compiler.test.js +2 -2
  576. package/dist/native/library.d.ts +2 -1
  577. package/dist/native/library.js.map +1 -1
  578. package/dist/native/prepare.d.ts +4 -0
  579. package/dist/native/prepare.js +28 -3
  580. package/dist/native/prepare.js.map +1 -1
  581. package/dist/native/sanitizer.d.ts +3 -2
  582. package/dist/native/sanitizer.js +3 -13
  583. package/dist/native/sanitizer.js.map +1 -1
  584. package/dist/startup-cache.d.ts +2 -0
  585. package/dist/startup-cache.js +2 -0
  586. package/dist/startup-cache.js.map +1 -1
  587. package/package.json +20 -20
  588. package/surface-manifest.json +8 -2
@@ -1,8 +1,11 @@
1
+ import { lowerUnionEquality, tagEqualityMayMissAlias } from "./strict-equality.js";
2
+ import { lowerArrayCallbackCall } from "./containers/array-callback-call.js";
1
3
  /** Dispatch source calls, builtin members and receiver-specific operations.
2
4
  * Signature collection, argument completion and function bodies have their
3
5
  * own owners; this module selects the applicable call path. */
4
6
  import { dynUndefinedExpr, nodeThrowExpr, countedFor, numLit, varRef } from "../../ir/build.js";
5
7
  import { lowerBuiltinCall } from "./builtin-calls.js";
8
+ import { threadsImportOf } from "../threads-import.js";
6
9
  import { adaptZeroArgTimerCallback, lowerTimersMemberCall, TIMER_MODULE_MEMBERS, } from "./lower-timers.js";
7
10
  import { objectEnumerationReceiver } from "./object-enumeration-receiver.js";
8
11
  import { InternalCompilerError } from "../../errors.js";
@@ -24,6 +27,7 @@ import { lowerGroupByStaticCall } from "./containers/collection-grouping.js";
24
27
  import { lowerIteratorHelperCall } from "./containers/iterator-helpers.js";
25
28
  import { lowerObjectAssignIndexShape, lowerObjectConstructor, lowerObjectFromEntriesCall, lowerObjectIterOverIndexShape, } from "./containers/indexed-objects.js";
26
29
  import { lowerTupleReadMethodCall } from "./containers/array-methods.js";
30
+ import { tryFuseIndexRead } from "./array-values.js";
27
31
  import { lowerBytesStaticCall } from "./containers/bytes.js";
28
32
  import { lowerRegexMethodCall, lowerStringIndexCall, lowerStringMethodCall, lowerStringPaddingCall, lowerStringSplitCall, } from "./containers/string-and-regexp.js";
29
33
  import { createRequireSpecOf } from "./builtins/module-bindings.js";
@@ -332,7 +336,7 @@ export function lowerCall(lowerer, expr) {
332
336
  // inspect distinction, per arm), Maps/Sets, plain undefined/null,
333
337
  // regexes, symbols, error values, Buffers. Shapes inspect cannot
334
338
  // render fence honestly with the reason.
335
- return lowerConsoleInspectArg(lowerer, a, lowered, surface, loc);
339
+ return lowerConsoleInspectArg(lowerer, a, lowerer.deferredFieldSlot(lowered) ?? lowered, surface, loc);
336
340
  });
337
341
  return withReceiver({
338
342
  kind: "intrinsic",
@@ -792,6 +796,14 @@ export function lowerCall(lowerer, expr) {
792
796
  if (rf)
793
797
  return lowerHttpClientFnCall(lowerer, expr, rf, loc);
794
798
  }
799
+ if (threadsImportOf(lowerer.program, expr.expression) === "publish") {
800
+ // @scriptc/threads publish(value): the same value, its graph made
801
+ // immortal and immutable (backend/llvm/publish.ts).
802
+ if (expr.arguments.length !== 1 || ts.isSpreadElement(expr.arguments[0]))
803
+ lowerer.noLowering(`publish with ${expr.arguments.length} arguments`, expr);
804
+ const value = lowerer.lowerExpr(expr.arguments[0]);
805
+ return { kind: "intrinsic", name: "threads.publish", args: [value], type: value.type, loc };
806
+ }
795
807
  const bi = lowerer.builtinImportOf(expr.expression);
796
808
  if (bi)
797
809
  return lowerBuiltinCall(lowerer, expr, bi, loc);
@@ -847,138 +859,14 @@ export function lowerCall(lowerer, expr) {
847
859
  // checker-pinned (or checked) to number, where the global's ToNumber
848
860
  // coercion is the identity and the tests are Number.isNaN /
849
861
  // Number.isFinite exactly (ms's `isFinite(val)` guard).
850
- if ((expr.expression.text === "parseInt" || expr.expression.text === "isNaN") &&
862
+ if ((expr.expression.text === "parseInt" ||
863
+ expr.expression.text === "isNaN" ||
864
+ expr.expression.text === "parseFloat" ||
865
+ expr.expression.text === "isFinite") &&
851
866
  lowerer.isStdlibSymbol(lowerer.resolveValueSymbol(expr.expression) ?? undefined)) {
852
- const name = expr.expression.text;
853
- const maxArgs = name === "parseInt" ? 2 : 1;
854
- if (expr.arguments.length < 1 || expr.arguments.length > maxArgs) {
855
- lowerer.noLowering(`${name} with ${expr.arguments.length} argument${expr.arguments.length === 1 ? "" : "s"}`, expr);
856
- }
857
- if (name === "isNaN") {
858
- const x = lowerer.lowerExprExpecting(expr.arguments[0], F64);
859
- return { kind: "libCall", fn: "num.isNaN", args: [x], type: BOOL, loc };
860
- }
861
- const radix = expr.arguments[1]
862
- ? lowerer.lowerExprExpecting(expr.arguments[1], F64)
863
- : { kind: "numLit", value: 0, type: F64, loc };
864
- const optional = optionalCallValue(lowerer, expr.arguments[0]);
865
- if (optional?.type.kind === "union") {
866
- const def = lowerer.unions.get(optional.type.unionId);
867
- const stringTag = def?.arms.findIndex((arm) => arm.kind === "string") ?? -1;
868
- if (def &&
869
- stringTag >= 0 &&
870
- def.arms.every((arm) => arm.kind === "string" || isUnitType(arm))) {
871
- const unionT = optional.type;
872
- const key = `parseInt.optional:${unionT.unionId}`;
873
- let helper = lowerer.valueHelpers.get(key);
874
- if (!helper) {
875
- helper = `%parseInt.optional.${lowerer.valueHelpers.size}`;
876
- lowerer.valueHelpers.set(key, helper);
877
- const value = { kind: "varRef", localId: "value.0", type: unionT, loc };
878
- const radixRef = { kind: "varRef", localId: "radix.0", type: F64, loc };
879
- const body = def.arms.flatMap((arm, tag) => isUnitType(arm)
880
- ? [
881
- {
882
- kind: "if",
883
- cond: {
884
- kind: "unionIsTag",
885
- unionId: unionT.unionId,
886
- tag,
887
- negated: false,
888
- value,
889
- type: BOOL,
890
- loc,
891
- },
892
- then: [
893
- {
894
- kind: "return",
895
- value: { kind: "numLit", value: NaN, type: F64, loc },
896
- loc,
897
- },
898
- ],
899
- else_: null,
900
- loc,
901
- },
902
- ]
903
- : []);
904
- body.push({
905
- kind: "return",
906
- value: {
907
- kind: "libCall",
908
- fn: "num.parseInt",
909
- args: [
910
- {
911
- kind: "unionNarrow",
912
- unionId: unionT.unionId,
913
- tag: stringTag,
914
- value,
915
- type: STRING,
916
- loc,
917
- },
918
- radixRef,
919
- ],
920
- type: F64,
921
- loc,
922
- },
923
- loc,
924
- });
925
- lowerer.liftedFns.push({
926
- name: helper,
927
- params: [
928
- { localId: "value.0", name: "value", type: unionT },
929
- { localId: "radix.0", name: "radix", type: F64 },
930
- ],
931
- returnType: F64,
932
- locals: [
933
- { id: "value.0", name: "value", type: unionT, mutable: true },
934
- { id: "radix.0", name: "radix", type: F64, mutable: true },
935
- ],
936
- body,
937
- loc,
938
- });
939
- }
940
- return { kind: "call", callee: helper, args: [optional, radix], type: F64, loc };
941
- }
942
- }
943
- const s = lowerer.lowerExprExpecting(expr.arguments[0], STRING);
944
- return { kind: "libCall", fn: "num.parseInt", args: [s, radix], type: F64, loc };
945
- }
946
- // STATIC parseFloat/isFinite over exactly-typed arguments —
947
- // parseInt's siblings (num.parseFloat is ECMA 19.2.4's decimal-
948
- // literal prefix parse in scr_string.c; a number-typed isFinite IS
949
- // Number.isFinite — the global's ToNumber coercion is the identity
950
- // there, ms's `isFinite(val)` guard). Other argument types fall
951
- // through to today's island path (--dynamic) or its SC2012 fence:
952
- // the ToNumber/ToString coercions on arbitrary values stay engine
953
- // territory. The probe never emits — lowering is IR construction.
954
- if ((expr.expression.text === "parseFloat" || expr.expression.text === "isFinite") &&
955
- expr.arguments.length === 1 &&
956
- lowerer.isStdlibSymbol(lowerer.resolveValueSymbol(expr.expression) ?? undefined)) {
957
- const name = expr.expression.text;
958
- if (name === "parseFloat") {
959
- const optional = optionalCallValue(lowerer, expr.arguments[0]);
960
- if (optional) {
961
- const parsed = lowerOptionalStringNumber(lowerer, optional, loc, "num.parseFloat", "parseFloat");
962
- if (parsed)
963
- return parsed;
964
- }
965
- }
966
- const probed = tryLowerExpression(lowerer, expr.arguments[0]);
967
- if (name === "parseFloat" && probed?.type.kind === "string") {
968
- return { kind: "libCall", fn: "num.parseFloat", args: [probed], type: F64, loc };
969
- }
970
- if (name === "parseFloat" && probed?.type.kind === "dyn") {
971
- return {
972
- kind: "libCall",
973
- fn: "num.parseFloat",
974
- args: [{ kind: "libCall", fn: "dyn.toStringCoerce", args: [probed], type: STRING, loc }],
975
- type: F64,
976
- loc,
977
- };
978
- }
979
- if (name === "isFinite" && probed?.type.kind === "f64") {
980
- return { kind: "libCall", fn: "number.isFinite", args: [probed], type: BOOL, loc };
981
- }
867
+ const parsed = lowerStaticNumberGlobal(lowerer, expr.expression.text, expr, expr.arguments, loc);
868
+ if (parsed !== null)
869
+ return parsed;
982
870
  }
983
871
  // STATIC encodeURIComponent/encodeURI/decodeURIComponent
984
872
  // (str.encodeUriComponent / str.encodeUri / str.decodeUriComponent —
@@ -1071,7 +959,16 @@ export function lowerCall(lowerer, expr) {
1071
959
  lowerer.noLowering(`${name} with ${expr.arguments.length} argument${expr.arguments.length === 1 ? "" : "s"}`, expr);
1072
960
  }
1073
961
  if (islFn && expr.arguments.length === islFn.args.length) {
1074
- lowerer.requireDynamicApi(`'${expr.expression.text}'`, expr);
962
+ // The static forms above already took the exactly-typed argument
963
+ // (a string for parseFloat, a number for isFinite): name the
964
+ // argument type that sent this call to the engine, so the message
965
+ // states the condition rather than reading as if the global itself
966
+ // were unsupported.
967
+ const argText = lowerer.dynamic ? "" : loweredArgumentText(lowerer, expr.arguments[0]);
968
+ const exact = expr.expression.text === "isFinite" ? "number" : "string";
969
+ lowerer.requireDynamicApi(`'${expr.expression.text}' with a '${argText}' argument (only a ${exact} argument compiles statically)`, expr, exact === "string"
970
+ ? "convert the argument explicitly first (for example String(x), or narrow the union), or build with --dynamic to run the coercing call in the embedded engine (adds ~620KB to the binary)"
971
+ : "narrow the argument to a number first (isFinite over a number compiles statically), or build with --dynamic to run the coercing call in the embedded engine (adds ~620KB to the binary)");
1075
972
  const callee = {
1076
973
  kind: "jsOp",
1077
974
  op: "globalGet",
@@ -1143,6 +1040,23 @@ export function lowerCall(lowerer, expr) {
1143
1040
  if (sig && !(jsSpreadArgs && spreadNeedsRuntimeArity(lowerer, sig.params, expr.arguments))) {
1144
1041
  lowerer.noteEdge(sig.name);
1145
1042
  const args = lowerer.completeArgs(expr.arguments, sig.params, loc, expr);
1043
+ const symbol = lowerer.resolveValueSymbol(expr.expression);
1044
+ const declaration = symbol ? lowerer.checker.valueDeclarationOf(symbol) : undefined;
1045
+ // A bare call supplies undefined as this, even inside a callback
1046
+ // currently carrying a receiver. The value-call ABI saves and
1047
+ // restores that ambient receiver around the function invocation.
1048
+ if (declaration &&
1049
+ ts.isFunctionDeclaration(declaration) &&
1050
+ declaration.parameters.some(isThisParameter)) {
1051
+ const callee = lowerer.lowerExpr(expr.expression);
1052
+ return reconcileOverloadReturn(lowerer, expr, {
1053
+ kind: "callValue",
1054
+ callee,
1055
+ args,
1056
+ type: sig.returnType,
1057
+ loc,
1058
+ });
1059
+ }
1146
1060
  return reconcileOverloadReturn(lowerer, expr, {
1147
1061
  kind: "call",
1148
1062
  callee: sig.name,
@@ -1573,6 +1487,11 @@ export function lowerCall(lowerer, expr) {
1573
1487
  !symbolFieldInfo(lowerer, expr.expression)) {
1574
1488
  const access = expr.expression;
1575
1489
  const value = tryLowerExpression(lowerer, access.expression);
1490
+ if (value?.type.kind === "array" && !isJsSourceFile(expr.getSourceFile())) {
1491
+ const callback = lowerArrayCallbackCall(lowerer, expr, access, value);
1492
+ if (callback)
1493
+ return callback;
1494
+ }
1576
1495
  if (value?.type.kind === "dyn" ||
1577
1496
  value?.type.kind === "generator" ||
1578
1497
  (value &&
@@ -1864,13 +1783,7 @@ function lowerBufferStaticCallWithNarrowedArg(lowerer, call, access) {
1864
1783
  }
1865
1784
  const narrowedValue = {
1866
1785
  ...lowered,
1867
- source: {
1868
- kind: "call",
1869
- callee: helper,
1870
- args: [lowered.source],
1871
- type: narrowed,
1872
- loc: lowered.source.loc,
1873
- },
1786
+ source: lowerer.checkedNarrowCall(helper, lowered.source, narrowed, lowered.source.loc),
1874
1787
  };
1875
1788
  return branded ? { ...branded, args: [narrowedValue] } : narrowedValue;
1876
1789
  }
@@ -1996,6 +1909,23 @@ function lowerNumberConstructorValue(lowerer, argNode, loc) {
1996
1909
  return { kind: "libCall", fn: "num.fromString", args: [arg], type: F64, loc };
1997
1910
  if (arg.type.kind === "dyn")
1998
1911
  return { kind: "libCall", fn: "dyn.numberConstructor", args: [arg], type: F64, loc };
1912
+ // Number(strings[i]) without boxing `string | undefined`: a missing slot
1913
+ // converts like undefined, to NaN.
1914
+ const indexedString = arg.type.kind === "union" &&
1915
+ arg.kind === "call" &&
1916
+ arg.args[0]?.type.kind === "array" &&
1917
+ arg.args[0].type.elem.kind === "string"
1918
+ ? tryFuseIndexRead(lowerer, arg, F64, (read) => ({ kind: "libCall", fn: "num.fromString", args: [read], type: F64, loc }), {
1919
+ kind: "bin",
1920
+ op: "/",
1921
+ left: { kind: "numLit", value: 0, type: F64, loc },
1922
+ right: { kind: "numLit", value: 0, type: F64, loc },
1923
+ type: F64,
1924
+ loc,
1925
+ })
1926
+ : null;
1927
+ if (indexedString)
1928
+ return indexedString;
1999
1929
  if (arg.type.kind === "union" && lowerer.dynConvertible(arg.type))
2000
1930
  return {
2001
1931
  kind: "libCall",
@@ -4199,13 +4129,13 @@ function implicitReceiverOverloadReturn(lowerer, expr) {
4199
4129
  function reconcileOverloadReturn(lowerer, expr, call) {
4200
4130
  const rsig = lowerer.checker.getResolvedSignature(expr);
4201
4131
  const rdecl = rsig ? lowerer.checker.signatureDeclaration(rsig) : undefined;
4202
- // Fluent JS overrides share the base's return ABI, but their result
4203
- // still has the receiver's subclass layout at the call site.
4132
+ // Nominal covariant overrides share the base's return ABI, but retain
4133
+ // their declared subclass result at the call site. Unannotated fluent
4134
+ // JS overrides use the same bridge for their proven receiver result.
4204
4135
  if (call.type.kind === "object" &&
4205
4136
  rdecl &&
4206
4137
  ts.isMethodDeclaration(rdecl) &&
4207
- isJsSourceFile(rdecl.getSourceFile()) &&
4208
- returnsOnlyThis(rdecl)) {
4138
+ (!isJsSourceFile(rdecl.getSourceFile()) || returnsOnlyThis(rdecl))) {
4209
4139
  call = lowerer.maybeNarrow(call, expr);
4210
4140
  }
4211
4141
  const resolvedOverload = rsig &&
@@ -4244,7 +4174,7 @@ function reconcileOverloadReturn(lowerer, expr, call) {
4244
4174
  if (call.type.kind === "union" && rt.kind !== "union") {
4245
4175
  const helper = lowerer.narrowedArmHelper(call.type.unionId, rt, call.loc);
4246
4176
  if (helper)
4247
- return { kind: "call", callee: helper, args: [call], type: rt, loc: call.loc };
4177
+ return lowerer.checkedNarrowCall(helper, call, rt, call.loc);
4248
4178
  }
4249
4179
  return lowerer.coerceInto(expr, call, rt);
4250
4180
  }
@@ -5703,11 +5633,10 @@ function filterNarrowHelper(lowerer, test, elem, outElem, tag, loc) {
5703
5633
  * no runtime walk. ORDER is the shape's first-seen DECLARATION order
5704
5634
  * (threaded through the shape registry), which matches Node whenever
5705
5635
  * objects are constructed in declaration order — the divergence for
5706
- * reordered construction is SEMANTICS.md 36. Fields holding the
5707
- * undefined arm of their union are SKIPPED at runtime (Node's missing
5708
- * key: an unset optional never made it into the object), which also
5709
- * means an EXPLICIT `{ a: undefined }` key is dropped where Node lists
5710
- * it — same rule as jsonStringify, same SEMANTICS entry. Values wrap
5636
+ * reordered construction is SEMANTICS.md 36. Optional fields that are
5637
+ * absent (omitted or deleted) are SKIPPED at runtime, Node's missing key,
5638
+ * while an explicit `{ a: undefined }` is listed with its undefined
5639
+ * value. Values wrap
5711
5640
  * into the checker's result-element type per field; a multi-arm field
5712
5641
  * union that differs from the result union would need a re-tag — fenced.
5713
5642
  * Null when this isn't an Object static over a fixed record (index
@@ -5826,9 +5755,9 @@ function lowerSymbolMethodCall(lowerer, call, access) {
5826
5755
  }
5827
5756
  /** The interned keys-array helper over a FIXED record shape: a call of a
5828
5757
  * lifted helper whose body pushes each declared field name in first-seen
5829
- * DECLARATION order, skipping fields currently holding the undefined arm
5830
- * of their union at runtime (Node's missing key — an unset optional
5831
- * never made it into the object; SEMANTICS.md 37's rules). ONE
5758
+ * DECLARATION order, skipping optional fields that are currently absent
5759
+ * (omitted or deleted — Node's missing key; a field explicitly holding
5760
+ * undefined is present and listed). ONE
5832
5761
  * construction, interned per shape, shared by Object.keys and for-in —
5833
5762
  * for-in iterates exactly the keys Object.keys answers. */
5834
5763
  export function recordKeysArrayCall(lowerer, receiver, argIr, shape, loc) {
@@ -5877,32 +5806,11 @@ export function recordKeysArrayCall(lowerer, receiver, argIr, shape, loc) {
5877
5806
  },
5878
5807
  loc,
5879
5808
  };
5880
- // Undefined-armed fields: the push is guarded by a tag test (the
5809
+ // Fields that can be absent push behind their presence test (the
5881
5810
  // key exists exactly when Object.keys would list it).
5882
- const utag = f.type.kind === "union" ? lowerer.armTag(f.type.unionId, UNDEFINED_T) : -1;
5883
- body.push(utag >= 0 && f.type.kind === "union"
5884
- ? {
5885
- kind: "if",
5886
- cond: {
5887
- kind: "unionIsTag",
5888
- unionId: f.type.unionId,
5889
- tag: utag,
5890
- negated: true,
5891
- value: {
5892
- kind: "recordGet",
5893
- obj: ref,
5894
- shapeId: argIr.shapeId,
5895
- field: f.name,
5896
- type: f.type,
5897
- loc,
5898
- },
5899
- type: BOOL,
5900
- loc,
5901
- },
5902
- then: [pushStmt],
5903
- else_: null,
5904
- loc,
5905
- }
5811
+ const present = lowerer.recordFieldPresent(ref, argIr.shapeId, f.name, loc);
5812
+ body.push(present.kind === "recordHas"
5813
+ ? { kind: "if", cond: present, then: [pushStmt], else_: null, loc }
5906
5814
  : pushStmt);
5907
5815
  }
5908
5816
  body.push({ kind: "return", value: outRef, loc });
@@ -5916,9 +5824,9 @@ export function recordKeysArrayCall(lowerer, receiver, argIr, shape, loc) {
5916
5824
  }
5917
5825
  /** Interned `%obj.hasOwn.<n>(r, k)` — Object.hasOwn's membership walk
5918
5826
  * over a record shape: the key compares against each
5919
- * declared field name, undefined-armed fields answering by their tag
5827
+ * declared field name, optional fields answering by their presence
5920
5828
  * (a key is own exactly when Object.keys would list it — the two share
5921
- * the guard), everything else true. Unmatched keys probe the overflow
5829
+ * the test), everything else true. Unmatched keys probe the overflow
5922
5830
  * map when present, so explicit undefined values remain own keys. */
5923
5831
  function recordHasOwnHelper(lowerer, shapeId, loc) {
5924
5832
  const key = `obj.hasOwn:${shapeId}`;
@@ -5933,18 +5841,7 @@ function recordHasOwnHelper(lowerer, shapeId, loc) {
5933
5841
  const kRef = { kind: "varRef", localId: "k.0", type: STRING, loc };
5934
5842
  const body = [];
5935
5843
  for (const f of shape.fields) {
5936
- const utag = f.type.kind === "union" ? lowerer.armTag(f.type.unionId, UNDEFINED_T) : -1;
5937
- const answer = utag >= 0 && f.type.kind === "union"
5938
- ? {
5939
- kind: "unionIsTag",
5940
- unionId: f.type.unionId,
5941
- tag: utag,
5942
- negated: true,
5943
- value: { kind: "recordGet", obj: rRef, shapeId, field: f.name, type: f.type, loc },
5944
- type: BOOL,
5945
- loc,
5946
- }
5947
- : { kind: "boolLit", value: true, type: BOOL, loc };
5844
+ const answer = lowerer.recordFieldPresent(rRef, shapeId, f.name, loc);
5948
5845
  body.push({
5949
5846
  kind: "if",
5950
5847
  cond: {
@@ -5982,8 +5879,9 @@ function recordHasOwnHelper(lowerer, shapeId, loc) {
5982
5879
  }
5983
5880
  /** Interned `%obj.assign.<n>(t, s)` — Object.assign's per-field copy
5984
5881
  * over signature-free records (every source field lands on a same-named,
5985
- * same-typed target field — the caller's gate): undefined-armed source
5986
- * fields copy behind the not-undefined guard, everything else straight,
5882
+ * same-typed target field — the caller's gate): optional source fields
5883
+ * copy only when present (an explicit undefined copies), everything else
5884
+ * straight,
5987
5885
  * and the TARGET returns (JS's aliasing). */
5988
5886
  function recordAssignHelper(lowerer, targetShapeId, srcShapeId, loc) {
5989
5887
  const key = `obj.assign:${targetShapeId}:${srcShapeId}`;
@@ -6015,23 +5913,9 @@ function recordAssignHelper(lowerer, targetShapeId, srcShapeId, loc) {
6015
5913
  value: get,
6016
5914
  loc,
6017
5915
  };
6018
- const utag = f.type.kind === "union" ? lowerer.armTag(f.type.unionId, UNDEFINED_T) : -1;
6019
- body.push(utag >= 0 && f.type.kind === "union"
6020
- ? {
6021
- kind: "if",
6022
- cond: {
6023
- kind: "unionIsTag",
6024
- unionId: f.type.unionId,
6025
- tag: utag,
6026
- negated: true,
6027
- value: get,
6028
- type: BOOL,
6029
- loc,
6030
- },
6031
- then: [set],
6032
- else_: null,
6033
- loc,
6034
- }
5916
+ const present = lowerer.recordFieldPresent(sRef, srcShapeId, f.name, loc);
5917
+ body.push(present.kind === "recordHas"
5918
+ ? { kind: "if", cond: present, then: [set], else_: null, loc }
6035
5919
  : set);
6036
5920
  }
6037
5921
  body.push({ kind: "return", value: tRef, loc });
@@ -6309,6 +6193,9 @@ function lowerObjectStaticCall(lowerer, call, access) {
6309
6193
  };
6310
6194
  }
6311
6195
  if (left.type.kind === "union" || right.type.kind === "union") {
6196
+ const compared = lowerUnionEquality(lowerer, left, right, false, true, loc);
6197
+ if (compared)
6198
+ return compared;
6312
6199
  const ut = left.type.kind === "union" ? left.type : right.type;
6313
6200
  const bothUnion = left.type.kind === "union" && right.type.kind === "union";
6314
6201
  const sameUnion = bothUnion && typeEquals(left.type, right.type);
@@ -6316,9 +6203,16 @@ function lowerObjectStaticCall(lowerer, call, access) {
6316
6203
  const plain = left.type.kind === "union" ? right : left;
6317
6204
  const arms = lowerer.unions.get(ut.unionId)?.arms ?? [];
6318
6205
  // The plain side wraps into the union exactly like === when the
6319
- // union holds its type; a plain PRIMITIVE the union has no arm
6320
- // for is the disjoint constant false (coercing it would strand).
6321
- if (bothUnion || arms.some((a) => typeEquals(a, plain.type))) {
6206
+ // union holds its type, or when a plain class instance upcasts
6207
+ // into exactly one class arm (the same pointer under a base tag);
6208
+ // a plain PRIMITIVE the union has no arm for is the disjoint
6209
+ // constant false (coercing it would strand).
6210
+ const plainType = plain.type;
6211
+ const upcastArm = plainType.kind === "object" &&
6212
+ arms.filter((a) => a.kind === "object" && lowerer.isSubclassOf(plainType.className, a.className)).length === 1;
6213
+ if (bothUnion || upcastArm || arms.some((a) => typeEquals(a, plain.type))) {
6214
+ if (tagEqualityMayMissAlias(lowerer, ut))
6215
+ lowerer.noLowering("Object.is over related class values beside structural union members", call, NARROW_FIRST);
6322
6216
  const sameValue = arms.some((a) => a.kind === "f64");
6323
6217
  return {
6324
6218
  kind: "unionEq",
@@ -6530,12 +6424,10 @@ function lowerObjectStaticCall(lowerer, call, access) {
6530
6424
  // (the mockable-clock restore: `Object.assign(mocked,
6531
6425
  // implementations)` over one shape): the per-field copy helper,
6532
6426
  // returning the TARGET — JS's aliasing, the target mutates in
6533
- // place. Undefined-armed source fields copy behind the
6534
- // not-undefined guard (an omitted optional field holds the
6535
- // undefined arm and must not erase the target's value — Node
6536
- // copies own keys only; an EXPLICIT `k: undefined` source diverges,
6537
- // the explicit-undefined-is-absent stance). Everything else keeps
6538
- // the spread hint.
6427
+ // place. Optional source fields copy only when present (an omitted
6428
+ // optional field must not erase the target's value — Node copies own
6429
+ // keys only — while an explicit `k: undefined` does). Everything
6430
+ // else keeps the spread hint.
6539
6431
  if (call.arguments.length === 2 && !call.arguments.some((a) => ts.isSpreadElement(a))) {
6540
6432
  const tProbe = tryLowerExpression(lowerer, call.arguments[0]);
6541
6433
  const sProbe = tryLowerExpression(lowerer, call.arguments[1]);
@@ -6912,11 +6804,9 @@ function lowerObjectStaticCall(lowerer, call, access) {
6912
6804
  }
6913
6805
  // `Object.hasOwn(r, k)` over a RECORD receiver: a record's own-key set
6914
6806
  // is its declared field list, so membership is a compare chain against
6915
- // the field names (interned per shape). Undefined-armed (optional)
6916
- // fields answer by their runtime tag — the explicit-undefined-is-absent
6917
- // stance: an omitted optional field holds the undefined arm and reads
6918
- // as NOT own, exactly Node's absent key (an EXPLICIT `k: undefined`
6919
- // diverges — documented next to the child-env/JSON rule). Tuple
6807
+ // the field names (interned per shape). Optional fields answer by
6808
+ // their runtime presence: an omitted or deleted optional field is NOT
6809
+ // own, while an explicit `k: undefined` is, exactly Node's keys. Tuple
6920
6810
  // and accessor-carrying shapes keep the SC2020 fence. Index-signature
6921
6811
  // records additionally probe the overflow map; non-record receivers
6922
6812
  // do too.
@@ -7113,9 +7003,12 @@ function lowerObjectStaticCall(lowerer, call, access) {
7113
7003
  return lowerObjectIterOverIndexShape(lowerer, call, member, argIr, shape);
7114
7004
  }
7115
7005
  const loc = locOf(call);
7116
- const resultT = lowerer.irTypeOf(call);
7117
- if (resultT.kind !== "array")
7006
+ const checkedT = lowerer.irTypeOf(call);
7007
+ if (checkedT.kind !== "array")
7118
7008
  lowerer.badType(call, lowerer.typeOf(call)); // defensive
7009
+ const resultT = member === "entries" && consumesEntryPairs(call)
7010
+ ? runtimeOptionalEntriesType(lowerer, argIr, checkedT)
7011
+ : checkedT;
7119
7012
  const receiver = objectEnumerationReceiver(lowerer, lowerer.lowerExpr(argNode), argIr, loc);
7120
7013
  if (member === "keys") {
7121
7014
  // The keys walk is shared with for-in (which iterates exactly the
@@ -7195,8 +7088,8 @@ function lowerObjectStaticCall(lowerer, call, access) {
7195
7088
  }
7196
7089
  return null;
7197
7090
  };
7198
- // Undefined-armed fields: the push is guarded by a tag test, and
7199
- // the pushed value is the narrowed non-undefined arm.
7091
+ // Undefined-armed fields: the push is guarded by the field's
7092
+ // presence; a narrowed push re-tags the non-undefined arm.
7200
7093
  let guardUndefTag = null;
7201
7094
  let value = raw;
7202
7095
  let vt = f.type;
@@ -7247,46 +7140,83 @@ function lowerObjectStaticCall(lowerer, call, access) {
7247
7140
  lowerer.unsupported("SC1090", call, `Object.${member} over '${lowerer.fmt(argIr)}' (field '${f.name}' of type '${lowerer.fmt(f.type)}' ` +
7248
7141
  `cannot flow into the '${lowerer.fmt(valueT)}' result element — read the fields directly)`);
7249
7142
  }
7250
- const pushed = member === "values"
7251
- ? coerced
7252
- : {
7253
- kind: "recordLit",
7254
- fields: [
7255
- { name: "0", value: { kind: "strLit", value: f.name, type: STRING, loc } },
7256
- { name: "1", value: coerced },
7257
- ],
7258
- type: tupleT,
7259
- loc,
7260
- };
7261
- const pushStmt = {
7143
+ const pushOf = (element) => ({
7262
7144
  kind: "exprStmt",
7263
7145
  expr: {
7264
7146
  kind: "arrIntrinsic",
7265
7147
  method: "push",
7266
7148
  receiver: outRef,
7267
- args: [pushed],
7149
+ args: [
7150
+ member === "values"
7151
+ ? element
7152
+ : {
7153
+ kind: "recordLit",
7154
+ fields: [
7155
+ { name: "0", value: { kind: "strLit", value: f.name, type: STRING, loc } },
7156
+ { name: "1", value: element },
7157
+ ],
7158
+ type: tupleT,
7159
+ loc,
7160
+ },
7161
+ ],
7268
7162
  type: F64,
7269
7163
  loc,
7270
7164
  },
7271
7165
  loc,
7272
- };
7273
- body.push(guardUndefTag !== null && f.type.kind === "union"
7274
- ? {
7275
- kind: "if",
7276
- cond: {
7277
- kind: "unionIsTag",
7278
- unionId: f.type.unionId,
7279
- tag: guardUndefTag,
7280
- negated: true,
7281
- value: raw,
7282
- type: BOOL,
7166
+ });
7167
+ let stmt = pushOf(coerced);
7168
+ if (guardUndefTag !== null && f.type.kind === "union") {
7169
+ if (value !== raw) {
7170
+ // A narrowed push: a present field holding undefined pushes
7171
+ // the result element's own undefined when it has one; a values
7172
+ // array without one stores a present undefined element (a
7173
+ // runtime-optional field the checker typed as required). An
7174
+ // entries tuple slot has no spelling for it.
7175
+ const undefinedElement = valueT ? lowerer.wrappedUndefined(valueT, loc) : null;
7176
+ const undefinedPush = undefinedElement
7177
+ ? pushOf(undefinedElement)
7178
+ : member === "values"
7179
+ ? {
7180
+ kind: "arraySetUndefined",
7181
+ arr: outRef,
7182
+ index: {
7183
+ kind: "arrIntrinsic",
7184
+ method: "length",
7185
+ receiver: outRef,
7186
+ args: [],
7187
+ type: F64,
7188
+ loc,
7189
+ },
7190
+ loc,
7191
+ }
7192
+ : null;
7193
+ stmt = {
7194
+ kind: "if",
7195
+ cond: {
7196
+ kind: "unionIsTag",
7197
+ unionId: f.type.unionId,
7198
+ tag: guardUndefTag,
7199
+ negated: true,
7200
+ value: raw,
7201
+ type: BOOL,
7202
+ loc,
7203
+ },
7204
+ then: [stmt],
7205
+ else_: undefinedPush ? [undefinedPush] : null,
7283
7206
  loc,
7284
- },
7285
- then: [pushStmt],
7207
+ };
7208
+ }
7209
+ // Absent fields contribute nothing; present ones push their
7210
+ // value, undefined included.
7211
+ stmt = {
7212
+ kind: "if",
7213
+ cond: lowerer.recordFieldPresent(ref, argIr.shapeId, f.name, loc),
7214
+ then: [stmt],
7286
7215
  else_: null,
7287
7216
  loc,
7288
- }
7289
- : pushStmt);
7217
+ };
7218
+ }
7219
+ body.push(stmt);
7290
7220
  }
7291
7221
  body.push({ kind: "return", value: outRef, loc });
7292
7222
  fn.body = body;
@@ -7298,6 +7228,53 @@ function lowerObjectStaticCall(lowerer, call, access) {
7298
7228
  }
7299
7229
  return { kind: "call", callee: helper, args: [receiver], type: resultT, loc };
7300
7230
  }
7231
+ /** An entries array consumed pair by pair right where it is built: a
7232
+ * for-of loop or an array callback method. These consumers bind each pair
7233
+ * from the array's own layout, so the pair's value slot can keep a
7234
+ * runtime-optional field's undefined arm. */
7235
+ function consumesEntryPairs(call) {
7236
+ let node = call;
7237
+ while (ts.isParenthesizedExpression(node.parent))
7238
+ node = node.parent;
7239
+ const parent = node.parent;
7240
+ if (ts.isForOfStatement(parent))
7241
+ return parent.expression === node;
7242
+ return (ts.isPropertyAccessExpression(parent) &&
7243
+ parent.expression === node &&
7244
+ ENTRY_PAIR_CALLBACK_METHODS.has(parent.name.text) &&
7245
+ ts.isCallExpression(parent.parent) &&
7246
+ parent.parent.expression === parent);
7247
+ }
7248
+ const ENTRY_PAIR_CALLBACK_METHODS = new Set([
7249
+ "every",
7250
+ "filter",
7251
+ "find",
7252
+ "findIndex",
7253
+ "flatMap",
7254
+ "forEach",
7255
+ "map",
7256
+ "some",
7257
+ ]);
7258
+ /** The entries array of a record whose runtime-optional fields (unchecked
7259
+ * indexed reads the checker calls present) can hold undefined: the pair's
7260
+ * value slot gains the undefined arm, so such an entry is listed with its
7261
+ * undefined value as Node lists it. Reads of the slot follow the
7262
+ * runtime-optional field rules. */
7263
+ function runtimeOptionalEntriesType(lowerer, record, resultT) {
7264
+ const shape = lowerer.shapes.get(record.shapeId);
7265
+ if (resultT.elem.kind !== "record" || !shape)
7266
+ return resultT;
7267
+ const pair = lowerer.shapes.get(resultT.elem.shapeId);
7268
+ const slot = pair?.tuple ? pair.fields.find((f) => f.name === "1") : undefined;
7269
+ if (!slot)
7270
+ return resultT;
7271
+ const optional = shape.fields.find((f) => lowerer.isRuntimeOptionalField(record.shapeId, f.name) &&
7272
+ lowerer.runtimeOptionalWidening(f.type, slot.type) !== null);
7273
+ if (!optional)
7274
+ return resultT;
7275
+ const widened = lowerer.runtimeOptionalWidening(optional.type, slot.type);
7276
+ return { kind: "array", elem: lowerer.runtimeOptionalRecordField(resultT.elem, "1", widened) };
7277
+ }
7301
7278
  /** `r.f(args)` where `r` is a record and `f` a func-typed field: an
7302
7279
  * ordinary indirect call through the field's closure value. Deliberately
7303
7280
  * record-only — calling a func-typed CLASS field stays rejected (the
@@ -7355,7 +7332,7 @@ function lowerObjectAssignHybrid(lowerer, call) {
7355
7332
  for (const f of shape.fields) {
7356
7333
  const v = values.get(f.name);
7357
7334
  if (!v) {
7358
- const absent = lowerer.wrappedUndefined(f.type, loc);
7335
+ const absent = lowerer.absentFieldValue(f.type, loc);
7359
7336
  if (!absent) {
7360
7337
  lowerer.unsupported("SC1090", call, `Object.assign leaving the required field '${f.name}' of '${lowerer.fmt(mapped)}' unfilled`);
7361
7338
  }
@@ -7883,13 +7860,7 @@ export function lowerObjectMethodCall(lowerer, call, access) {
7883
7860
  if (receiver.type.kind === "union") {
7884
7861
  const helper = lowerer.narrowedArmHelper(receiver.type.unionId, receiverIr, locOf(access.expression));
7885
7862
  if (helper !== null)
7886
- return {
7887
- kind: "call",
7888
- callee: helper,
7889
- args: [receiver],
7890
- type: receiverIr,
7891
- loc: locOf(access.expression),
7892
- };
7863
+ return lowerer.checkedNarrowCall(helper, receiver, receiverIr, locOf(access.expression));
7893
7864
  }
7894
7865
  return receiver.type.kind === "dyn"
7895
7866
  ? lowerer.coerceInto(access.expression, receiver, receiverIr)
@@ -7955,7 +7926,9 @@ export function lowerObjectMethodCall(lowerer, call, access) {
7955
7926
  const receiverLocal = lowerer.declareHiddenLocal("%callReceiver", target.obj.type);
7956
7927
  const init = { kind: "varDecl", localId: receiverLocal.id, init: target.obj, loc };
7957
7928
  target.obj = { kind: "varRef", localId: receiverLocal.id, type: receiverLocal.type, loc };
7958
- const receiver = lowerer.coerceToExpected(target.obj, DYN);
7929
+ const receiver = {};
7930
+ if (!lowerer.receiverFreeCallbackFields.has(access.name.text))
7931
+ receiver.receiver = lowerer.coerceToExpected(target.obj, DYN);
7959
7932
  const finish = (result) => ({
7960
7933
  kind: "seqExpr",
7961
7934
  stmts: [init],
@@ -7967,13 +7940,7 @@ export function lowerObjectMethodCall(lowerer, call, access) {
7967
7940
  if (callee?.type.kind === "union" && callableType !== null) {
7968
7941
  const helper = lowerer.narrowedArmHelper(callee.type.unionId, callableType, locOf(access));
7969
7942
  if (helper !== null) {
7970
- callee = {
7971
- kind: "call",
7972
- callee: helper,
7973
- args: [callee],
7974
- type: callableType,
7975
- loc: locOf(access),
7976
- };
7943
+ callee = lowerer.checkedNarrowCall(helper, callee, callableType, locOf(access));
7977
7944
  }
7978
7945
  }
7979
7946
  if (callee?.type.kind === "func") {
@@ -7984,12 +7951,12 @@ export function lowerObjectMethodCall(lowerer, call, access) {
7984
7951
  const boxed = { kind: "dynFrom", value: callee, type: DYN, loc };
7985
7952
  const spread = lowerSpreadArgsCall(lowerer, call, boxed, loc);
7986
7953
  if (spread?.kind === "dynCall")
7987
- return finish({ ...spread, receiver });
7954
+ return finish({ ...spread, ...receiver });
7988
7955
  const args = call.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN));
7989
7956
  return finish({
7990
7957
  kind: "dynCall",
7991
7958
  callee: boxed,
7992
- receiver,
7959
+ ...receiver,
7993
7960
  calleeName: access.getText(),
7994
7961
  args,
7995
7962
  type: DYN,
@@ -7997,7 +7964,7 @@ export function lowerObjectMethodCall(lowerer, call, access) {
7997
7964
  });
7998
7965
  }
7999
7966
  const args = completeFuncValueArgs(lowerer, call, callee.type, locOf(call));
8000
- return finish({ kind: "callValue", callee, receiver, args, type: callee.type.ret, loc });
7967
+ return finish({ kind: "callValue", callee, ...receiver, args, type: callee.type.ret, loc });
8001
7968
  }
8002
7969
  if (callee?.type.kind === "dyn") {
8003
7970
  if (call.arguments.some((a) => ts.isSpreadElement(a))) {
@@ -8007,7 +7974,7 @@ export function lowerObjectMethodCall(lowerer, call, access) {
8007
7974
  return finish({
8008
7975
  kind: "dynCall",
8009
7976
  callee,
8010
- receiver,
7977
+ ...receiver,
8011
7978
  calleeName: access.getText(),
8012
7979
  args,
8013
7980
  type: DYN,
@@ -8089,7 +8056,7 @@ export function lowerObjectMethodCall(lowerer, call, access) {
8089
8056
  type: found.sig.ret,
8090
8057
  loc,
8091
8058
  };
8092
- const result = classCallbackCall(lowerer, value, method, call.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)), fallback, loc, access.getText());
8059
+ const result = classCallbackCall(lowerer, value, method, call.arguments, fallback, loc, access.getText());
8093
8060
  return {
8094
8061
  kind: "seqExpr",
8095
8062
  stmts: [{ kind: "varDecl", localId: local.id, init: receiver, loc }],
@@ -8412,4 +8379,147 @@ function unionObjectMethodHelper(lowerer, sourceCall, receiverT, method, plans,
8412
8379
  lowerer.liftedFns.push({ name, params, returnType: resultT, locals, body, loc });
8413
8380
  return name;
8414
8381
  }
8382
+ /** The argument's lowered type for a message (what the static form saw),
8383
+ * or the checker's text when the argument itself does not lower. */
8384
+ function loweredArgumentText(lowerer, arg) {
8385
+ const probed = tryLowerExpression(lowerer, arg);
8386
+ return probed !== null
8387
+ ? lowerer.fmt(probed.type)
8388
+ : lowerer.checker.typeToString(lowerer.checker.getTypeAtLocation(arg));
8389
+ }
8390
+ /** The static global number parsers (parseInt/parseFloat/isNaN/isFinite),
8391
+ * shared by the globals and their Number.* aliases. `call` blames arity
8392
+ * fences; null when the argument shape needs the engine (the caller keeps
8393
+ * its island path or SC2012 fence). */
8394
+ export function lowerStaticNumberGlobal(lowerer, name, call, args, loc) {
8395
+ if (name === "parseInt" || name === "isNaN") {
8396
+ const maxArgs = name === "parseInt" ? 2 : 1;
8397
+ if (args.length < 1 || args.length > maxArgs) {
8398
+ lowerer.noLowering(`${name} with ${args.length} argument${args.length === 1 ? "" : "s"}`, call);
8399
+ }
8400
+ if (name === "isNaN") {
8401
+ const x = lowerer.lowerExprExpecting(args[0], F64);
8402
+ return { kind: "libCall", fn: "num.isNaN", args: [x], type: BOOL, loc };
8403
+ }
8404
+ const radix = args[1]
8405
+ ? lowerer.lowerExprExpecting(args[1], F64)
8406
+ : { kind: "numLit", value: 0, type: F64, loc };
8407
+ const optional = optionalCallValue(lowerer, args[0]);
8408
+ if (optional?.type.kind === "union") {
8409
+ const def = lowerer.unions.get(optional.type.unionId);
8410
+ const stringTag = def?.arms.findIndex((arm) => arm.kind === "string") ?? -1;
8411
+ if (def &&
8412
+ stringTag >= 0 &&
8413
+ def.arms.every((arm) => arm.kind === "string" || isUnitType(arm))) {
8414
+ const unionT = optional.type;
8415
+ const key = `parseInt.optional:${unionT.unionId}`;
8416
+ let helper = lowerer.valueHelpers.get(key);
8417
+ if (!helper) {
8418
+ helper = `%parseInt.optional.${lowerer.valueHelpers.size}`;
8419
+ lowerer.valueHelpers.set(key, helper);
8420
+ const value = { kind: "varRef", localId: "value.0", type: unionT, loc };
8421
+ const radixRef = { kind: "varRef", localId: "radix.0", type: F64, loc };
8422
+ const body = def.arms.flatMap((arm, tag) => isUnitType(arm)
8423
+ ? [
8424
+ {
8425
+ kind: "if",
8426
+ cond: {
8427
+ kind: "unionIsTag",
8428
+ unionId: unionT.unionId,
8429
+ tag,
8430
+ negated: false,
8431
+ value,
8432
+ type: BOOL,
8433
+ loc,
8434
+ },
8435
+ then: [
8436
+ {
8437
+ kind: "return",
8438
+ value: { kind: "numLit", value: NaN, type: F64, loc },
8439
+ loc,
8440
+ },
8441
+ ],
8442
+ else_: null,
8443
+ loc,
8444
+ },
8445
+ ]
8446
+ : []);
8447
+ body.push({
8448
+ kind: "return",
8449
+ value: {
8450
+ kind: "libCall",
8451
+ fn: "num.parseInt",
8452
+ args: [
8453
+ {
8454
+ kind: "unionNarrow",
8455
+ unionId: unionT.unionId,
8456
+ tag: stringTag,
8457
+ value,
8458
+ type: STRING,
8459
+ loc,
8460
+ },
8461
+ radixRef,
8462
+ ],
8463
+ type: F64,
8464
+ loc,
8465
+ },
8466
+ loc,
8467
+ });
8468
+ lowerer.liftedFns.push({
8469
+ name: helper,
8470
+ params: [
8471
+ { localId: "value.0", name: "value", type: unionT },
8472
+ { localId: "radix.0", name: "radix", type: F64 },
8473
+ ],
8474
+ returnType: F64,
8475
+ locals: [
8476
+ { id: "value.0", name: "value", type: unionT, mutable: true },
8477
+ { id: "radix.0", name: "radix", type: F64, mutable: true },
8478
+ ],
8479
+ body,
8480
+ loc,
8481
+ });
8482
+ }
8483
+ return { kind: "call", callee: helper, args: [optional, radix], type: F64, loc };
8484
+ }
8485
+ }
8486
+ const s = lowerer.lowerExprExpecting(args[0], STRING);
8487
+ return { kind: "libCall", fn: "num.parseInt", args: [s, radix], type: F64, loc };
8488
+ }
8489
+ // STATIC parseFloat/isFinite over exactly-typed arguments —
8490
+ // parseInt's siblings (num.parseFloat is ECMA 19.2.4's decimal-
8491
+ // literal prefix parse in scr_string.c; a number-typed isFinite IS
8492
+ // Number.isFinite — the global's ToNumber coercion is the identity
8493
+ // there, ms's `isFinite(val)` guard). Other argument types fall
8494
+ // through to today's island path (--dynamic) or its SC2012 fence:
8495
+ // the ToNumber/ToString coercions on arbitrary values stay engine
8496
+ // territory. The probe never emits — lowering is IR construction.
8497
+ if ((name === "parseFloat" || name === "isFinite") && args.length === 1) {
8498
+ if (name === "parseFloat") {
8499
+ const optional = optionalCallValue(lowerer, args[0]);
8500
+ if (optional) {
8501
+ const parsed = lowerOptionalStringNumber(lowerer, optional, loc, "num.parseFloat", "parseFloat");
8502
+ if (parsed)
8503
+ return parsed;
8504
+ }
8505
+ }
8506
+ const probed = tryLowerExpression(lowerer, args[0]);
8507
+ if (name === "parseFloat" && probed?.type.kind === "string") {
8508
+ return { kind: "libCall", fn: "num.parseFloat", args: [probed], type: F64, loc };
8509
+ }
8510
+ if (name === "parseFloat" && probed?.type.kind === "dyn") {
8511
+ return {
8512
+ kind: "libCall",
8513
+ fn: "num.parseFloat",
8514
+ args: [{ kind: "libCall", fn: "dyn.toStringCoerce", args: [probed], type: STRING, loc }],
8515
+ type: F64,
8516
+ loc,
8517
+ };
8518
+ }
8519
+ if (name === "isFinite" && probed?.type.kind === "f64") {
8520
+ return { kind: "libCall", fn: "number.isFinite", args: [probed], type: BOOL, loc };
8521
+ }
8522
+ }
8523
+ return null;
8524
+ }
8415
8525
  //# sourceMappingURL=lower-calls.js.map