@scriptc/compiler 0.4.0 → 0.4.1

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 (433) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +35 -5
  2. package/dist/backend/executable-features.js +7 -0
  3. package/dist/backend/executable-features.js.map +1 -1
  4. package/dist/backend/library-pack.js +3 -0
  5. package/dist/backend/library-pack.js.map +1 -1
  6. package/dist/backend/link-plan-core.d.ts +2 -0
  7. package/dist/backend/link-plan-core.js +2 -0
  8. package/dist/backend/link-plan-core.js.map +1 -1
  9. package/dist/backend/link-plan.d.ts +1 -0
  10. package/dist/backend/link-plan.js +1 -0
  11. package/dist/backend/link-plan.js.map +1 -1
  12. package/dist/backend/llvm/array-search.js +3 -1
  13. package/dist/backend/llvm/array-search.js.map +1 -1
  14. package/dist/backend/llvm/classes.d.ts +27 -1
  15. package/dist/backend/llvm/classes.js +115 -22
  16. package/dist/backend/llvm/classes.js.map +1 -1
  17. package/dist/backend/llvm/classes.test.js +21 -9
  18. package/dist/backend/llvm/classes.test.js.map +1 -1
  19. package/dist/backend/llvm/common.d.ts +21 -3
  20. package/dist/backend/llvm/common.js +50 -3
  21. package/dist/backend/llvm/common.js.map +1 -1
  22. package/dist/backend/llvm/dense-array-access.d.ts +3 -1
  23. package/dist/backend/llvm/dense-array-access.js +61 -38
  24. package/dist/backend/llvm/dense-array-access.js.map +1 -1
  25. package/dist/backend/llvm/dense-array-access.test.js +4 -0
  26. package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
  27. package/dist/backend/llvm/dense-array-loops.js +3 -3
  28. package/dist/backend/llvm/dense-array-loops.js.map +1 -1
  29. package/dist/backend/llvm/dyn.d.ts +9 -0
  30. package/dist/backend/llvm/dyn.js +62 -6
  31. package/dist/backend/llvm/dyn.js.map +1 -1
  32. package/dist/backend/llvm/emit-function.js +5 -2
  33. package/dist/backend/llvm/emit-function.js.map +1 -1
  34. package/dist/backend/llvm/emit-module.js +54 -32
  35. package/dist/backend/llvm/emit-module.js.map +1 -1
  36. package/dist/backend/llvm/emit-statements.d.ts +3 -2
  37. package/dist/backend/llvm/emit-statements.js +90 -13
  38. package/dist/backend/llvm/emit-statements.js.map +1 -1
  39. package/dist/backend/llvm/emitter.d.ts +20 -9
  40. package/dist/backend/llvm/emitter.js +42 -31
  41. package/dist/backend/llvm/emitter.js.map +1 -1
  42. package/dist/backend/llvm/expr-calls.js +17 -4
  43. package/dist/backend/llvm/expr-calls.js.map +1 -1
  44. package/dist/backend/llvm/expr-containers.js +6 -9
  45. package/dist/backend/llvm/expr-containers.js.map +1 -1
  46. package/dist/backend/llvm/expr-dynamic.js +46 -4
  47. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  48. package/dist/backend/llvm/expr-primitives.js +3 -3
  49. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  50. package/dist/backend/llvm/expr-primitives.test.js +55 -0
  51. package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
  52. package/dist/backend/llvm/expr-stream-bridges.js +11 -15
  53. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  54. package/dist/backend/llvm/integer-clones.js +3 -3
  55. package/dist/backend/llvm/integer-clones.js.map +1 -1
  56. package/dist/backend/llvm/js-ic.d.ts +18 -0
  57. package/dist/backend/llvm/js-ic.js +712 -0
  58. package/dist/backend/llvm/js-ic.js.map +1 -0
  59. package/dist/backend/llvm/jsval.js +139 -11
  60. package/dist/backend/llvm/jsval.js.map +1 -1
  61. package/dist/backend/llvm/lib-process.js +4 -3
  62. package/dist/backend/llvm/lib-process.js.map +1 -1
  63. package/dist/backend/llvm/lib-shared.js +22 -0
  64. package/dist/backend/llvm/lib-shared.js.map +1 -1
  65. package/dist/backend/llvm/local-array-reads.js +40 -31
  66. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  67. package/dist/backend/llvm/map-number-lookup.d.ts +20 -4
  68. package/dist/backend/llvm/map-number-lookup.js +43 -7
  69. package/dist/backend/llvm/map-number-lookup.js.map +1 -1
  70. package/dist/backend/llvm/narrow-guards.js +64 -0
  71. package/dist/backend/llvm/narrow-guards.js.map +1 -1
  72. package/dist/backend/llvm/publish.d.ts +3 -0
  73. package/dist/backend/llvm/publish.js +36 -17
  74. package/dist/backend/llvm/publish.js.map +1 -1
  75. package/dist/backend/llvm/regions.js +2 -2
  76. package/dist/backend/llvm/regions.js.map +1 -1
  77. package/dist/backend/llvm/regions.test.js +7 -1
  78. package/dist/backend/llvm/regions.test.js.map +1 -1
  79. package/dist/backend/llvm/shapes.d.ts +8 -2
  80. package/dist/backend/llvm/shapes.js +9 -7
  81. package/dist/backend/llvm/shapes.js.map +1 -1
  82. package/dist/backend/llvm/speculative-integers.d.ts +20 -1
  83. package/dist/backend/llvm/speculative-integers.js +94 -6
  84. package/dist/backend/llvm/speculative-integers.js.map +1 -1
  85. package/dist/backend/llvm/speculative-integers.test.js +55 -1
  86. package/dist/backend/llvm/speculative-integers.test.js.map +1 -1
  87. package/dist/backend/llvm/string-reads.d.ts +1 -1
  88. package/dist/backend/llvm/string-reads.js +4 -4
  89. package/dist/backend/llvm/string-reads.js.map +1 -1
  90. package/dist/backend/llvm/thread-slots.test.js +5 -4
  91. package/dist/backend/llvm/thread-slots.test.js.map +1 -1
  92. package/dist/backend/mangle.d.ts +5 -0
  93. package/dist/backend/mangle.js +7 -0
  94. package/dist/backend/mangle.js.map +1 -1
  95. package/dist/backend/native/contracts.d.ts +20 -0
  96. package/dist/backend/native/executable.js +20 -3
  97. package/dist/backend/native/executable.js.map +1 -1
  98. package/dist/backend/native/library.js +2 -1
  99. package/dist/backend/native/library.js.map +1 -1
  100. package/dist/backend/native-codegen.d.ts +6 -0
  101. package/dist/backend/native-codegen.js +19 -0
  102. package/dist/backend/native-codegen.js.map +1 -1
  103. package/dist/backend/native-codegen.test.js +27 -0
  104. package/dist/backend/native-codegen.test.js.map +1 -1
  105. package/dist/backend/native-link-info-core.d.ts +18 -0
  106. package/dist/backend/native-link-info-core.js.map +1 -1
  107. package/dist/backend/native-profile.d.ts +32 -0
  108. package/dist/backend/native-profile.js +39 -0
  109. package/dist/backend/native-profile.js.map +1 -0
  110. package/dist/backend/native-profile.test.d.ts +1 -0
  111. package/dist/backend/native-profile.test.js +58 -0
  112. package/dist/backend/native-profile.test.js.map +1 -0
  113. package/dist/backend/native-tools.d.ts +14 -0
  114. package/dist/backend/native-tools.js +13 -0
  115. package/dist/backend/native-tools.js.map +1 -1
  116. package/dist/backend/runtime-abi.d.ts +2 -2
  117. package/dist/backend/runtime-abi.js +2 -2
  118. package/dist/backend/runtime-pack-core.d.ts +4 -0
  119. package/dist/backend/runtime-pack-core.js +4 -0
  120. package/dist/backend/runtime-pack-core.js.map +1 -1
  121. package/dist/backend/runtime-pack-targets.test.js +4 -1
  122. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  123. package/dist/backend/runtime-pack.test.js +4 -1
  124. package/dist/backend/runtime-pack.test.js.map +1 -1
  125. package/dist/backend/target-diagnostics.js +7 -0
  126. package/dist/backend/target-diagnostics.js.map +1 -1
  127. package/dist/backend/warm-cache.js +3 -0
  128. package/dist/backend/warm-cache.js.map +1 -1
  129. package/dist/cli/command.js +63 -1
  130. package/dist/cli/command.js.map +1 -1
  131. package/dist/cli/host.d.ts +3 -0
  132. package/dist/cli/output-options.d.ts +2 -0
  133. package/dist/cli/output-options.js +9 -0
  134. package/dist/cli/output-options.js.map +1 -1
  135. package/dist/cli/usage.d.ts +11 -1
  136. package/dist/cli/usage.js +23 -0
  137. package/dist/cli/usage.js.map +1 -1
  138. package/dist/compile-types.d.ts +9 -0
  139. package/dist/contracts/check.js +1 -2
  140. package/dist/contracts/check.js.map +1 -1
  141. package/dist/executable/executable-cache.d.ts +10 -0
  142. package/dist/executable/executable-cache.js +6 -0
  143. package/dist/executable/executable-cache.js.map +1 -1
  144. package/dist/executable/executable-cache.test.js +5 -0
  145. package/dist/executable/executable-cache.test.js.map +1 -1
  146. package/dist/frontend/arguments-usage.d.ts +8 -0
  147. package/dist/frontend/arguments-usage.js +98 -0
  148. package/dist/frontend/arguments-usage.js.map +1 -1
  149. package/dist/frontend/arguments-usage.test.d.ts +1 -0
  150. package/dist/frontend/arguments-usage.test.js +32 -0
  151. package/dist/frontend/arguments-usage.test.js.map +1 -0
  152. package/dist/frontend/builtin-package-aliases.d.ts +24 -0
  153. package/dist/frontend/builtin-package-aliases.js +133 -0
  154. package/dist/frontend/builtin-package-aliases.js.map +1 -0
  155. package/dist/frontend/builtin-package-aliases.test.d.ts +1 -0
  156. package/dist/frontend/builtin-package-aliases.test.js +48 -0
  157. package/dist/frontend/builtin-package-aliases.test.js.map +1 -0
  158. package/dist/frontend/dts-paths.d.ts +4 -0
  159. package/dist/frontend/dts-paths.js +9 -1
  160. package/dist/frontend/dts-paths.js.map +1 -1
  161. package/dist/frontend/lowering/builtins/builtin-class-dyn.d.ts +8 -0
  162. package/dist/frontend/lowering/builtins/builtin-class-dyn.js +50 -1
  163. package/dist/frontend/lowering/builtins/builtin-class-dyn.js.map +1 -1
  164. package/dist/frontend/lowering/builtins/callable-aliases.js +3 -2
  165. package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
  166. package/dist/frontend/lowering/builtins/crypto.d.ts +3 -0
  167. package/dist/frontend/lowering/builtins/crypto.js +4 -1
  168. package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
  169. package/dist/frontend/lowering/builtins/ecdh.d.ts +10 -0
  170. package/dist/frontend/lowering/builtins/ecdh.js +208 -0
  171. package/dist/frontend/lowering/builtins/ecdh.js.map +1 -0
  172. package/dist/frontend/lowering/builtins/json.js +52 -0
  173. package/dist/frontend/lowering/builtins/json.js.map +1 -1
  174. package/dist/frontend/lowering/builtins/process.d.ts +9 -0
  175. package/dist/frontend/lowering/builtins/process.js +44 -0
  176. package/dist/frontend/lowering/builtins/process.js.map +1 -1
  177. package/dist/frontend/lowering/builtins/promisify-callback.d.ts +3 -0
  178. package/dist/frontend/lowering/builtins/promisify-callback.js +21 -3
  179. package/dist/frontend/lowering/builtins/promisify-callback.js.map +1 -1
  180. package/dist/frontend/lowering/builtins/reflection.js +26 -0
  181. package/dist/frontend/lowering/builtins/reflection.js.map +1 -1
  182. package/dist/frontend/lowering/builtins/timers.js +5 -1
  183. package/dist/frontend/lowering/builtins/timers.js.map +1 -1
  184. package/dist/frontend/lowering/builtins/typed-array-members.d.ts +7 -0
  185. package/dist/frontend/lowering/builtins/typed-array-members.js +160 -0
  186. package/dist/frontend/lowering/builtins/typed-array-members.js.map +1 -0
  187. package/dist/frontend/lowering/call-signatures.d.ts +4 -0
  188. package/dist/frontend/lowering/call-signatures.js +126 -9
  189. package/dist/frontend/lowering/call-signatures.js.map +1 -1
  190. package/dist/frontend/lowering/cjs-exports-object.js +34 -1
  191. package/dist/frontend/lowering/cjs-exports-object.js.map +1 -1
  192. package/dist/frontend/lowering/class-dynamic-dispatch.js +9 -1
  193. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  194. package/dist/frontend/lowering/class-protocols.d.ts +10 -0
  195. package/dist/frontend/lowering/class-protocols.js +53 -3
  196. package/dist/frontend/lowering/class-protocols.js.map +1 -1
  197. package/dist/frontend/lowering/class-prototypes.js +6 -1
  198. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  199. package/dist/frontend/lowering/class-to-primitive.d.ts +2 -2
  200. package/dist/frontend/lowering/class-to-primitive.js +6 -3
  201. package/dist/frontend/lowering/class-to-primitive.js.map +1 -1
  202. package/dist/frontend/lowering/coercions/fresh-spread.d.ts +13 -0
  203. package/dist/frontend/lowering/coercions/fresh-spread.js +95 -0
  204. package/dist/frontend/lowering/coercions/fresh-spread.js.map +1 -0
  205. package/dist/frontend/lowering/coercions/function-adapters.js +99 -70
  206. package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
  207. package/dist/frontend/lowering/containers/array-callbacks.d.ts +8 -0
  208. package/dist/frontend/lowering/containers/array-callbacks.js +22 -19
  209. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  210. package/dist/frontend/lowering/containers/array-construction.js +7 -0
  211. package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
  212. package/dist/frontend/lowering/containers/array-methods.js +5 -0
  213. package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
  214. package/dist/frontend/lowering/containers/bytes.d.ts +9 -0
  215. package/dist/frontend/lowering/containers/bytes.js +493 -17
  216. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  217. package/dist/frontend/lowering/containers/collection-methods.js +72 -3
  218. package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
  219. package/dist/frontend/lowering/containers/string-and-regexp.js +49 -13
  220. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  221. package/dist/frontend/lowering/cycle-initialization.d.ts +26 -10
  222. package/dist/frontend/lowering/cycle-initialization.js +152 -35
  223. package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
  224. package/dist/frontend/lowering/expressions/array-literals.js +33 -13
  225. package/dist/frontend/lowering/expressions/array-literals.js.map +1 -1
  226. package/dist/frontend/lowering/expressions/binary.js +79 -5
  227. package/dist/frontend/lowering/expressions/binary.js.map +1 -1
  228. package/dist/frontend/lowering/expressions/element-access.js +13 -6
  229. package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
  230. package/dist/frontend/lowering/expressions/keyed-field-targets.d.ts +14 -2
  231. package/dist/frontend/lowering/expressions/keyed-field-targets.js +91 -10
  232. package/dist/frontend/lowering/expressions/keyed-field-targets.js.map +1 -1
  233. package/dist/frontend/lowering/expressions/narrowing.js +17 -2
  234. package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
  235. package/dist/frontend/lowering/expressions/object-literals.js +48 -1
  236. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  237. package/dist/frontend/lowering/expressions/optional-chains.d.ts +1 -1
  238. package/dist/frontend/lowering/expressions/optional-chains.js +12 -3
  239. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  240. package/dist/frontend/lowering/expressions/property-access.d.ts +5 -0
  241. package/dist/frontend/lowering/expressions/property-access.js +252 -9
  242. package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
  243. package/dist/frontend/lowering/expressions/relational.js +49 -4
  244. package/dist/frontend/lowering/expressions/relational.js.map +1 -1
  245. package/dist/frontend/lowering/expressions/typeof.js +13 -0
  246. package/dist/frontend/lowering/expressions/typeof.js.map +1 -1
  247. package/dist/frontend/lowering/expressions/updates.js +1 -1
  248. package/dist/frontend/lowering/expressions/updates.js.map +1 -1
  249. package/dist/frontend/lowering/generator-delegation.d.ts +8 -0
  250. package/dist/frontend/lowering/generator-delegation.js +191 -1
  251. package/dist/frontend/lowering/generator-delegation.js.map +1 -1
  252. package/dist/frontend/lowering/generic-functions.d.ts +4 -0
  253. package/dist/frontend/lowering/generic-functions.js +213 -56
  254. package/dist/frontend/lowering/generic-functions.js.map +1 -1
  255. package/dist/frontend/lowering/handle-properties.d.ts +24 -0
  256. package/dist/frontend/lowering/handle-properties.js +281 -0
  257. package/dist/frontend/lowering/handle-properties.js.map +1 -0
  258. package/dist/frontend/lowering/iterable-spelling.d.ts +7 -0
  259. package/dist/frontend/lowering/iterable-spelling.js +38 -0
  260. package/dist/frontend/lowering/iterable-spelling.js.map +1 -0
  261. package/dist/frontend/lowering/lower-array-sort.d.ts +33 -15
  262. package/dist/frontend/lowering/lower-array-sort.js +117 -21
  263. package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
  264. package/dist/frontend/lowering/lower-array-sort.test.js +93 -14
  265. package/dist/frontend/lowering/lower-array-sort.test.js.map +1 -1
  266. package/dist/frontend/lowering/lower-builtin-values.js +1 -0
  267. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  268. package/dist/frontend/lowering/lower-calls.js +166 -7
  269. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  270. package/dist/frontend/lowering/lower-classes.d.ts +4 -0
  271. package/dist/frontend/lowering/lower-classes.js +59 -7
  272. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  273. package/dist/frontend/lowering/lower-dgram.js +62 -13
  274. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  275. package/dist/frontend/lowering/lower-exprs.js +32 -1
  276. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  277. package/dist/frontend/lowering/lower-functions.js +4 -0
  278. package/dist/frontend/lowering/lower-functions.js.map +1 -1
  279. package/dist/frontend/lowering/lower-generators.js +10 -4
  280. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  281. package/dist/frontend/lowering/lower-inspect.js +569 -11
  282. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  283. package/dist/frontend/lowering/lower-modules.d.ts +11 -3
  284. package/dist/frontend/lowering/lower-modules.js +212 -67
  285. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  286. package/dist/frontend/lowering/lower-namespaces.js +20 -0
  287. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  288. package/dist/frontend/lowering/lower-server.js +26 -1
  289. package/dist/frontend/lowering/lower-server.js.map +1 -1
  290. package/dist/frontend/lowering/lower-stdlib.js +28 -9
  291. package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
  292. package/dist/frontend/lowering/lower-stmts.d.ts +7 -10
  293. package/dist/frontend/lowering/lower-stmts.js +418 -51
  294. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  295. package/dist/frontend/lowering/lower-timers.js +17 -1
  296. package/dist/frontend/lowering/lower-timers.js.map +1 -1
  297. package/dist/frontend/lowering/lowerer.d.ts +29 -5
  298. package/dist/frontend/lowering/lowerer.js +172 -25
  299. package/dist/frontend/lowering/lowerer.js.map +1 -1
  300. package/dist/frontend/lowering/rebindable-functions.d.ts +8 -0
  301. package/dist/frontend/lowering/rebindable-functions.js +54 -0
  302. package/dist/frontend/lowering/rebindable-functions.js.map +1 -0
  303. package/dist/frontend/lowering/static-typeof.d.ts +26 -0
  304. package/dist/frontend/lowering/static-typeof.js +133 -0
  305. package/dist/frontend/lowering/static-typeof.js.map +1 -0
  306. package/dist/frontend/lowering/string-index-bounds.js +3 -2
  307. package/dist/frontend/lowering/string-index-bounds.js.map +1 -1
  308. package/dist/frontend/lowering/surfaces.js +30 -4
  309. package/dist/frontend/lowering/surfaces.js.map +1 -1
  310. package/dist/frontend/lowering/thenables.d.ts +16 -0
  311. package/dist/frontend/lowering/thenables.js +124 -0
  312. package/dist/frontend/lowering/thenables.js.map +1 -0
  313. package/dist/frontend/npm-static-builtin-aliases.d.ts +8 -0
  314. package/dist/frontend/npm-static-builtin-aliases.js +65 -0
  315. package/dist/frontend/npm-static-builtin-aliases.js.map +1 -0
  316. package/dist/frontend/npm-static-bundled-chunks.d.ts +8 -1
  317. package/dist/frontend/npm-static-bundled-chunks.js +173 -2
  318. package/dist/frontend/npm-static-bundled-chunks.js.map +1 -1
  319. package/dist/frontend/npm-static-bundled-chunks.test.js +112 -0
  320. package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -1
  321. package/dist/frontend/npm-static-bundled-esm.js +224 -4
  322. package/dist/frontend/npm-static-bundled-esm.js.map +1 -1
  323. package/dist/frontend/npm-static-bundled-esm.test.js +129 -0
  324. package/dist/frontend/npm-static-bundled-esm.test.js.map +1 -1
  325. package/dist/frontend/npm-static-enum-iife.d.ts +6 -0
  326. package/dist/frontend/npm-static-enum-iife.js +280 -0
  327. package/dist/frontend/npm-static-enum-iife.js.map +1 -0
  328. package/dist/frontend/npm-static-enum-iife.test.d.ts +1 -0
  329. package/dist/frontend/npm-static-enum-iife.test.js +116 -0
  330. package/dist/frontend/npm-static-enum-iife.test.js.map +1 -0
  331. package/dist/frontend/npm-static.d.ts +8 -0
  332. package/dist/frontend/npm-static.js +46 -1
  333. package/dist/frontend/npm-static.js.map +1 -1
  334. package/dist/frontend/npm.js +13 -0
  335. package/dist/frontend/npm.js.map +1 -1
  336. package/dist/frontend/package-shims.d.ts +47 -0
  337. package/dist/frontend/package-shims.js +300 -0
  338. package/dist/frontend/package-shims.js.map +1 -0
  339. package/dist/frontend/pipeline.js +67 -1
  340. package/dist/frontend/pipeline.js.map +1 -1
  341. package/dist/frontend/program.d.ts +8 -0
  342. package/dist/frontend/program.js +72 -9
  343. package/dist/frontend/program.js.map +1 -1
  344. package/dist/frontend/resolve.js +13 -0
  345. package/dist/frontend/resolve.js.map +1 -1
  346. package/dist/frontend/services.d.ts +6 -0
  347. package/dist/frontend/services.js +19 -0
  348. package/dist/frontend/services.js.map +1 -1
  349. package/dist/frontend/ts7/program-host.d.ts +6 -5
  350. package/dist/frontend/ts7/program-host.js +7 -0
  351. package/dist/frontend/ts7/program-host.js.map +1 -1
  352. package/dist/frontend/ts7/semantic-model.d.ts +3 -0
  353. package/dist/frontend/ts7/semantic-model.js +26 -0
  354. package/dist/frontend/ts7/semantic-model.js.map +1 -1
  355. package/dist/frontend/ts7/session.d.ts +19 -4
  356. package/dist/frontend/ts7/session.js.map +1 -1
  357. package/dist/frontend/type-mapper.js +201 -15
  358. package/dist/frontend/type-mapper.js.map +1 -1
  359. package/dist/index.d.ts +1 -0
  360. package/dist/index.js +58 -6
  361. package/dist/index.js.map +1 -1
  362. package/dist/ir/array-length-stability.d.ts +3 -2
  363. package/dist/ir/array-length-stability.js +15 -2
  364. package/dist/ir/array-length-stability.js.map +1 -1
  365. package/dist/ir/array-length-stability.test.js +22 -1
  366. package/dist/ir/array-length-stability.test.js.map +1 -1
  367. package/dist/ir/builtin-effects.js +13 -0
  368. package/dist/ir/builtin-effects.js.map +1 -1
  369. package/dist/ir/builtin-signatures.d.ts +1 -1
  370. package/dist/ir/builtin-signatures.js +46 -4
  371. package/dist/ir/builtin-signatures.js.map +1 -1
  372. package/dist/ir/integer-loop-facts.d.ts +5 -0
  373. package/dist/ir/integer-loop-facts.js +79 -14
  374. package/dist/ir/integer-loop-facts.js.map +1 -1
  375. package/dist/ir/integer-ranges.d.ts +10 -1
  376. package/dist/ir/integer-ranges.js +122 -25
  377. package/dist/ir/integer-ranges.js.map +1 -1
  378. package/dist/ir/integer-ranges.test.js +191 -1
  379. package/dist/ir/integer-ranges.test.js.map +1 -1
  380. package/dist/ir/ir.js +8 -0
  381. package/dist/ir/ir.js.map +1 -1
  382. package/dist/ir/js-ic.d.ts +52 -0
  383. package/dist/ir/js-ic.js +199 -0
  384. package/dist/ir/js-ic.js.map +1 -0
  385. package/dist/ir/js-ic.test.d.ts +1 -0
  386. package/dist/ir/js-ic.test.js +148 -0
  387. package/dist/ir/js-ic.test.js.map +1 -0
  388. package/dist/ir/jsval.js +38 -4
  389. package/dist/ir/jsval.js.map +1 -1
  390. package/dist/ir/runtime-features.d.ts +39 -4
  391. package/dist/ir/runtime-features.js +229 -99
  392. package/dist/ir/runtime-features.js.map +1 -1
  393. package/dist/ir/traverse.js +110 -68
  394. package/dist/ir/traverse.js.map +1 -1
  395. package/dist/ir/validate.js +21 -8
  396. package/dist/ir/validate.js.map +1 -1
  397. package/dist/ir/validate.test.js +15 -2
  398. package/dist/ir/validate.test.js.map +1 -1
  399. package/dist/library/ir-policy.js +1 -0
  400. package/dist/library/ir-policy.js.map +1 -1
  401. package/dist/native/cli.js +17 -0
  402. package/dist/native/cli.js.map +1 -1
  403. package/dist/native/compiler.js +33 -4
  404. package/dist/native/compiler.js.map +1 -1
  405. package/dist/native/executable-cache.js +3 -0
  406. package/dist/native/executable-cache.js.map +1 -1
  407. package/dist/native/prepare.js +3 -0
  408. package/dist/native/prepare.js.map +1 -1
  409. package/dist/native/sanitizer.test.js +7 -0
  410. package/dist/native/sanitizer.test.js.map +1 -1
  411. package/package.json +21 -20
  412. package/shims/fs-extra/core/api.ts +1192 -0
  413. package/shims/fs-extra/index.ts +9 -0
  414. package/shims/undici/core/agent.ts +163 -0
  415. package/shims/undici/core/api.ts +93 -0
  416. package/shims/undici/core/client.ts +1304 -0
  417. package/shims/undici/core/connector.ts +157 -0
  418. package/shims/undici/core/diagnostics-types.ts +68 -0
  419. package/shims/undici/core/diagnostics.ts +16 -0
  420. package/shims/undici/core/dispatcher.ts +574 -0
  421. package/shims/undici/core/errors-v5.ts +22 -0
  422. package/shims/undici/core/errors-v7.ts +25 -0
  423. package/shims/undici/core/errors.ts +255 -0
  424. package/shims/undici/core/fetch.ts +635 -0
  425. package/shims/undici/core/pool.ts +280 -0
  426. package/shims/undici/core/readable.ts +268 -0
  427. package/shims/undici/core/request.ts +313 -0
  428. package/shims/undici/core/timers.ts +80 -0
  429. package/shims/undici/core/types.ts +167 -0
  430. package/shims/undici/core/util.ts +67 -0
  431. package/shims/undici/v5.ts +119 -0
  432. package/shims/undici/v7.ts +119 -0
  433. package/surface-manifest.json +2 -4
@@ -0,0 +1,281 @@
1
+ /* Own properties that JavaScript adds to a native ChildProcess: execa's
2
+ * mixin assigns `spawned.kill = ...` and defines then/catch/finally with
3
+ * Reflect.defineProperty, and its callers await the child as a thenable.
4
+ *
5
+ * The runtime keeps such properties in a side table per child
6
+ * (scr_dyn_handle_props.c). Only programs that can add one link it: a
7
+ * JavaScript write of a property onto a typed child, or JavaScript that
8
+ * calls defineProperty in a program whose JavaScript loads child_process. Those programs install the table at
9
+ * start, and their defineProperty, getOwnPropertyDescriptor, thenable
10
+ * await and typed `child.on(event, listener)` calls take the entries that
11
+ * consult it. Every other program lowers exactly as before. */
12
+ import * as ts from "../ts7/adapter.js";
13
+ import { isJsSourceFile, locOf } from "../program.js";
14
+ import { DYN, STRING, VOID } from "../../ir/ir.js";
15
+ import { everyStmt } from "../../ir/traverse.js";
16
+ import { tryLowerExpression } from "./expressions/try-lower-expression.js";
17
+ import { ENTRY_NAME } from "./lowerer.js";
18
+ /** `child.name = value` in a JavaScript file over a typed child: the write
19
+ * lands in the child's property table through its checked-dynamic box. */
20
+ export function lowerChildPropertyWrite(lowerer, recv, target, value, loc) {
21
+ lowerer.writesOntoChildren = true;
22
+ return {
23
+ kind: "exprStmt",
24
+ expr: {
25
+ kind: "libCall",
26
+ fn: "dyn.keySet",
27
+ args: [
28
+ lowerer.coerceToExpected(recv, DYN),
29
+ { kind: "strLit", value: target.name.text, type: STRING, loc },
30
+ lowerer.lowerExprExpecting(value, DYN),
31
+ ],
32
+ type: VOID,
33
+ loc,
34
+ },
35
+ loc,
36
+ };
37
+ }
38
+ /** `child.kill` as a value in a JavaScript file (`spawned.kill.bind(spawned)`):
39
+ * the method read off the child's checked-dynamic box, which answers a
40
+ * function acting on that child. */
41
+ export function lowerChildMethodValue(lowerer, node) {
42
+ if (!ts.isPropertyAccessExpression(node) || node.questionDotToken)
43
+ return null;
44
+ if (!isJsSourceFile(ts.getSourceFileOfNode(node)))
45
+ return null;
46
+ const recv = tryLowerExpression(lowerer, node.expression);
47
+ if (recv?.type.kind !== "child")
48
+ return null;
49
+ lowerer.writesOntoChildren = true;
50
+ const loc = locOf(node);
51
+ return {
52
+ kind: "dynKeyGet",
53
+ value: lowerer.coerceToExpected(recv, DYN),
54
+ key: { kind: "strLit", value: node.name.text, type: STRING, loc },
55
+ type: DYN,
56
+ loc,
57
+ };
58
+ }
59
+ /** ChildProcess and EventEmitter member names: reads and calls of these on
60
+ * a typed child keep their typed lowering (or its diagnostic) unless the
61
+ * program assigns the name onto a child. */
62
+ const CHILD_MEMBERS = new Set([
63
+ "addListener",
64
+ "channel",
65
+ "connected",
66
+ "disconnect",
67
+ "emit",
68
+ "eventNames",
69
+ "exitCode",
70
+ "getMaxListeners",
71
+ "kill",
72
+ "killed",
73
+ "listenerCount",
74
+ "listeners",
75
+ "off",
76
+ "on",
77
+ "once",
78
+ "pid",
79
+ "prependListener",
80
+ "prependOnceListener",
81
+ "rawListeners",
82
+ "ref",
83
+ "removeAllListeners",
84
+ "removeListener",
85
+ "send",
86
+ "setMaxListeners",
87
+ "signalCode",
88
+ "spawnargs",
89
+ "spawnfile",
90
+ "stderr",
91
+ "stdin",
92
+ "stdio",
93
+ "stdout",
94
+ "unref",
95
+ ]);
96
+ /** What the program's JavaScript adds to children: `child.name = value`
97
+ * writes onto typed children in any JavaScript file of a program that
98
+ * loads child_process, and defineProperty calls in such a program. */
99
+ function childAdditions(lowerer) {
100
+ let known = lowerer.childAdditions;
101
+ if (known)
102
+ return known;
103
+ const written = new Set();
104
+ const files = lowerer.program
105
+ .getImplementationSourceFiles()
106
+ .filter((sf) => !sf.isDeclarationFile && isJsSourceFile(sf));
107
+ const spawns = files.some((sf) => sf.text.includes("child_process"));
108
+ const defines = files.some((sf) => sf.text.includes("defineProperty"));
109
+ // A child can reach any module (`module.exports = (child) => { child.x =
110
+ // ... }`), so once some file loads child_process every JavaScript file's
111
+ // writes onto children count.
112
+ // A key that is not a literal may name any member, so every member then
113
+ // goes through the child's box.
114
+ let everyName = false;
115
+ const isChild = (e) => lowerer.mapTypeOf(lowerer.typeOf(e))?.kind === "child";
116
+ const key = (k) => {
117
+ if (ts.isIdentifier(k) || ts.isStringLiteralLike(k) || ts.isNumericLiteral(k))
118
+ written.add(k.text);
119
+ else
120
+ everyName = true;
121
+ };
122
+ for (const sf of spawns ? files : []) {
123
+ const visit = (node) => {
124
+ if (ts.isBinaryExpression(node) &&
125
+ node.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
126
+ (ts.isPropertyAccessExpression(node.left) || ts.isElementAccessExpression(node.left)) &&
127
+ isChild(node.left.expression)) {
128
+ if (ts.isPropertyAccessExpression(node.left))
129
+ written.add(node.left.name.text);
130
+ else
131
+ key(node.left.argumentExpression);
132
+ }
133
+ // `Object.defineProperty(child, "kill", { value })`, its Reflect
134
+ // twin, and `Object.defineProperties(child, { kill: ... })`.
135
+ if (ts.isCallExpression(node) &&
136
+ ts.isPropertyAccessExpression(node.expression) &&
137
+ ts.isIdentifier(node.expression.expression) &&
138
+ (node.expression.expression.text === "Object" ||
139
+ node.expression.expression.text === "Reflect")) {
140
+ const method = node.expression.name.text;
141
+ const [target, second] = node.arguments.nodes;
142
+ if (target && second && isChild(target)) {
143
+ if (method === "defineProperty")
144
+ key(second);
145
+ else if (method === "defineProperties") {
146
+ if (!ts.isObjectLiteralExpression(second))
147
+ everyName = true;
148
+ else
149
+ for (const prop of second.properties.nodes) {
150
+ const name = prop.name;
151
+ if (name !== undefined &&
152
+ (ts.isIdentifier(name) ||
153
+ ts.isStringLiteralLike(name) ||
154
+ ts.isNumericLiteral(name)))
155
+ written.add(name.text);
156
+ else
157
+ everyName = true;
158
+ }
159
+ }
160
+ }
161
+ }
162
+ ts.forEachChild(node, visit);
163
+ };
164
+ visit(sf);
165
+ }
166
+ known = { written, everyName, any: written.size > 0 || everyName || (spawns && defines) };
167
+ lowerer.childAdditions = known;
168
+ return known;
169
+ }
170
+ /** The typed child a JavaScript member access reads from, when the member
171
+ * is one the program may have added to it. `untyped` is the last resort
172
+ * when no typed lowering claimed the access (a receiver the checker does
173
+ * not type as a child, such as an untyped parameter the call site
174
+ * instantiated with one, or a member without a typed lowering): every
175
+ * member goes through the child's box. */
176
+ function childReceiverOf(lowerer, access, untyped) {
177
+ if (access.questionDotToken || !isJsSourceFile(ts.getSourceFileOfNode(access)))
178
+ return null;
179
+ const additions = childAdditions(lowerer);
180
+ const typed = lowerer.mapTypeOf(lowerer.typeOf(access.expression))?.kind === "child";
181
+ if (!untyped && (!typed || !additions.any))
182
+ return null;
183
+ const name = access.name.text;
184
+ if (!untyped && CHILD_MEMBERS.has(name) && !additions.everyName && !additions.written.has(name))
185
+ return null;
186
+ const recv = tryLowerExpression(lowerer, access.expression);
187
+ if (recv?.type.kind !== "child")
188
+ return null;
189
+ if (additions.any)
190
+ lowerer.writesOntoChildren = true;
191
+ return recv;
192
+ }
193
+ /** `child.name(...)` in JavaScript for a name the program adds to children
194
+ * (execa's `spawned.then(...)`, its replaced `spawned.kill(...)`), or on an
195
+ * untyped receiver holding a child (`untyped`): a member call on the
196
+ * child's checked-dynamic box. */
197
+ export function lowerChildPropertyCall(lowerer, call, access, untyped = false) {
198
+ if (call.questionDotToken || call.arguments.nodes.some(ts.isSpreadElement))
199
+ return null;
200
+ const child = childReceiverOf(lowerer, access, untyped);
201
+ // `spawned.stdin.on(...)` over an untyped child: the member read off
202
+ // the child's box, then the call on that value.
203
+ const recv = child
204
+ ? lowerer.coerceToExpected(child, DYN)
205
+ : untyped && ts.isPropertyAccessExpression(access.expression)
206
+ ? lowerChildPropertyRead(lowerer, access.expression)
207
+ : null;
208
+ if (!recv)
209
+ return null;
210
+ const loc = locOf(call);
211
+ return {
212
+ kind: "dynInvoke",
213
+ recv,
214
+ method: access.name.text,
215
+ calleeName: ts.getTextOfNode(access),
216
+ args: call.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
217
+ type: DYN,
218
+ loc,
219
+ };
220
+ }
221
+ /** `child.name` in JavaScript over an untyped receiver holding a child, or
222
+ * for a name the program adds to children. */
223
+ export function lowerChildPropertyRead(lowerer, access) {
224
+ const recv = childReceiverOf(lowerer, access, true) ?? childReceiverOf(lowerer, access, false);
225
+ if (!recv)
226
+ return null;
227
+ const loc = locOf(access);
228
+ return {
229
+ kind: "dynKeyGet",
230
+ value: lowerer.coerceToExpected(recv, DYN),
231
+ key: { kind: "strLit", value: access.name.text, type: STRING, loc },
232
+ type: DYN,
233
+ loc,
234
+ };
235
+ }
236
+ /** `await child` in JavaScript in a program that adds properties to
237
+ * children: the child may be a thenable (execa's mixin). */
238
+ export function awaitsChildThenable(lowerer, node, value) {
239
+ if (value.type.kind !== "child" ||
240
+ !isJsSourceFile(ts.getSourceFileOfNode(node)) ||
241
+ !childAdditions(lowerer).any)
242
+ return false;
243
+ lowerer.writesOntoChildren = true;
244
+ return true;
245
+ }
246
+ const RENAMES = new Map([
247
+ ["dyn.defineProperty", "child.propsDefine"],
248
+ ["dyn.getOwnPropertyDescriptor", "child.propsDescriptor"],
249
+ ["dyn.promiseResolve", "child.propsResolve"],
250
+ ["child.onDyn", "child.propsOnDyn"],
251
+ ]);
252
+ /** Switches a program that can add properties to children onto the
253
+ * property-table entries (in place) and installs the table in %main. */
254
+ export function applyHandleProperties(lowerer, functions) {
255
+ if (!lowerer.writesOntoChildren && !childAdditions(lowerer).any)
256
+ return;
257
+ const calls = [];
258
+ const visitor = {
259
+ expr: (e) => {
260
+ if (e.kind === "libCall" && RENAMES.has(e.fn))
261
+ calls.push(e);
262
+ return true;
263
+ },
264
+ stmt: () => true,
265
+ };
266
+ for (const fn of functions)
267
+ for (const s of fn.body)
268
+ everyStmt(s, visitor);
269
+ for (const call of calls)
270
+ call.fn = RENAMES.get(call.fn);
271
+ const main = functions.find((fn) => fn.name === ENTRY_NAME);
272
+ if (!main)
273
+ return;
274
+ const loc = main.loc;
275
+ main.body.unshift({
276
+ kind: "exprStmt",
277
+ expr: { kind: "libCall", fn: "child.propsInstall", args: [], type: VOID, loc },
278
+ loc,
279
+ });
280
+ }
281
+ //# sourceMappingURL=handle-properties.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handle-properties.js","sourceRoot":"","sources":["../../../src/frontend/lowering/handle-properties.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import * as ts from "../ts7/adapter.js";
2
+ /** V8's TypeError message for iterating a value that is not iterable:
3
+ * `x is not iterable` for an identifier or property path, `f is not a
4
+ * function or its return value is not iterable` for a call of one, and ""
5
+ * for other expressions, which the runtime words by the value's kind.
6
+ * for await words it with "async iterable". */
7
+ export declare function notIterableSpelling(expr: ts.Expression, word?: string): string;
@@ -0,0 +1,38 @@
1
+ import * as ts from "../ts7/adapter.js";
2
+ /** The expression under parentheses and type assertions, which leave no
3
+ * trace in the source text V8 prints. */
4
+ function unwrapped(expr) {
5
+ let e = expr;
6
+ while (ts.isParenthesizedExpression(e) ||
7
+ ts.isAsExpression(e) ||
8
+ ts.isSatisfiesExpression(e) ||
9
+ ts.isNonNullExpression(e))
10
+ e = e.expression;
11
+ return e;
12
+ }
13
+ /** The source text V8 prints for an iterated identifier or property path,
14
+ * or null for other expressions. */
15
+ function iterableHeadText(expr) {
16
+ const e = unwrapped(expr);
17
+ if (ts.isIdentifier(e))
18
+ return e.text;
19
+ if (ts.isPropertyAccessExpression(e) && !e.questionDotToken && ts.isIdentifier(e.name)) {
20
+ const base = iterableHeadText(e.expression);
21
+ return base === null ? null : `${base}.${e.name.text}`;
22
+ }
23
+ return null;
24
+ }
25
+ /** V8's TypeError message for iterating a value that is not iterable:
26
+ * `x is not iterable` for an identifier or property path, `f is not a
27
+ * function or its return value is not iterable` for a call of one, and ""
28
+ * for other expressions, which the runtime words by the value's kind.
29
+ * for await words it with "async iterable". */
30
+ export function notIterableSpelling(expr, word = "iterable") {
31
+ const name = iterableHeadText(expr);
32
+ if (name !== null)
33
+ return `${name} is not ${word}`;
34
+ const e = unwrapped(expr);
35
+ const callee = ts.isCallExpression(e) ? iterableHeadText(e.expression) : null;
36
+ return callee !== null ? `${callee} is not a function or its return value is not ${word}` : "";
37
+ }
38
+ //# sourceMappingURL=iterable-spelling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iterable-spelling.js","sourceRoot":"","sources":["../../../src/frontend/lowering/iterable-spelling.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAExC;yCACyC;AACzC,SAAS,SAAS,CAAC,IAAmB;IACpC,IAAI,CAAC,GAAG,IAAI,CAAC;IACb,OACE,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC;QAC/B,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;QACpB,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAC;QAC3B,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAEzB,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC;IACnB,OAAO,CAAC,CAAC;AACX,CAAC;AAED;oCACoC;AACpC,SAAS,gBAAgB,CAAC,IAAmB;IAC3C,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC,IAAI,CAAC;IACtC,IAAI,EAAE,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,IAAI,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;QACvF,MAAM,IAAI,GAAG,gBAAgB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QAC5C,OAAO,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACzD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;+CAI+C;AAC/C,MAAM,UAAU,mBAAmB,CAAC,IAAmB,EAAE,IAAI,GAAG,UAAU;IACxE,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,GAAG,IAAI,WAAW,IAAI,EAAE,CAAC;IACnD,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC1B,MAAM,MAAM,GAAG,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9E,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,iDAAiD,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACjG,CAAC"}
@@ -1,32 +1,50 @@
1
1
  import { type IrExpr, type IrFunction, type IrType, type SrcLoc } from "../../ir/ir.js";
2
- type SortKeyRead = IrExpr & {
2
+ type SortKeyField = IrExpr & {
3
3
  kind: "recordGet" | "fieldGet";
4
4
  };
5
- /** A comparator that orders by one number: the elements themselves or one
6
- * field of each, ascending or descending. */
5
+ /** A key read over the comparator's first parameter: one number field, or
6
+ * an optional number field with a number default (`x.k ?? 0`). */
7
+ export interface SortKeyRead {
8
+ field: SortKeyField;
9
+ fallback: (IrExpr & {
10
+ kind: "numLit";
11
+ }) | null;
12
+ }
13
+ /** One key of a comparator: the elements themselves or one field of each,
14
+ * ascending or descending. */
7
15
  export interface SortKeyOrder {
8
16
  /** 1 for ascending, -1 for descending. */
9
17
  order: 1 | -1;
10
- /** The field read over the comparator's first parameter, or null when
11
- * the elements are the numbers. */
18
+ /** The key read, or null when the elements are the numbers. */
12
19
  read: SortKeyRead | null;
13
20
  }
14
21
  /** Recognizes the lifted body of a capture-free numeric comparator:
15
22
  * `(a, b) => a - b`, `b - a`, `a < b ? -1 : a > b ? 1 : 0` (either test
16
23
  * first, either sign), or any of them over one number field of both
17
- * parameters (`a.k - b.k`). Such a comparator runs no user code, cannot
18
- * throw, and is consistent over numbers other than NaN, so the runtime may
19
- * order the elements by their keys without calling it. */
20
- export declare function recognizeKeyComparator(fn: IrFunction): SortKeyOrder | null;
21
- /** The key order of a comparator closure: a zero-capture closure (not a
24
+ * parameters (`a.k - b.k`, or `(a.k ?? 0) - (b.k ?? 0)` over an optional
25
+ * field). Such a comparator runs no user code, cannot throw, and is
26
+ * consistent over numbers other than NaN, so the runtime may order the
27
+ * elements by their keys without calling it. A chain `t0 || t1 || ...` of
28
+ * such terms over fields orders by several keys, the first deciding: a term
29
+ * that is 0 or NaN falls through to the next. Returns the keys in order. */
30
+ export declare function recognizeKeyComparator(fn: IrFunction): readonly SortKeyOrder[] | null;
31
+ /** The keys of a comparator closure: a zero-capture closure (not a
22
32
  * signature adapter) over a lifted function recognizeKeyComparator accepts. */
23
- export declare function closureKeyOrder(liftedFns: readonly IrFunction[], closure: IrExpr): SortKeyOrder | null;
24
- /** The key reader of a recognized field comparator: `(x) => x.k`, the same
25
- * field read as the comparator's. */
26
- export declare function buildSortKeyFn(name: string, elem: IrType, read: SortKeyRead, loc: SrcLoc): IrFunction;
33
+ export declare function closureKeyOrder(liftedFns: readonly IrFunction[], closure: IrExpr): readonly SortKeyOrder[] | null;
34
+ /** The order argument of a keyed sort: 1 or -1 for one key; for several,
35
+ * the key count in the low byte and, from bit 8, one bit per descending
36
+ * key (the runtime's SCR_SORT_KEYS encoding). */
37
+ export declare function sortKeysOrder(keys: readonly SortKeyOrder[]): number;
38
+ /** A cache key that identifies a recognized comparator's key reads. */
39
+ export declare function sortKeysId(keys: readonly SortKeyOrder[]): string;
40
+ /** The key reader of a recognized field comparator: `(x) => x.k` (or
41
+ * `x.k ?? d`), the same read as the comparator's. For several keys it takes
42
+ * the key's index too: `(x, j) => j === 0 ? key0 : j === 1 ? key1 : ...`. */
43
+ export declare function buildSortKeyFn(name: string, elem: IrType, reads: readonly SortKeyRead[], loc: SrcLoc): IrFunction;
27
44
  export declare function buildArraySortFn(name: string, elem: IrType, arity: number, copyFirst: boolean, undefinedTag: number | null, loc: SrcLoc, native?: boolean, keyed?: {
28
- order: 1 | -1;
45
+ order: number;
29
46
  key: boolean;
47
+ keys: number;
30
48
  } | null): IrFunction;
31
49
  /** Typed-array `sort` and `toSorted`. `toSorted` orders a private copy;
32
50
  * `sort` orders the receiver and returns it. Without a comparator, and for a
@@ -605,28 +605,66 @@ function timSortBody(b, src, n, less) {
605
605
  forceCollapse,
606
606
  ];
607
607
  }
608
+ /** Most keys a comparator chain is recognized with (the runtime's
609
+ * SCR_SORT_KEYS_MAX). */
610
+ const MAX_SORT_KEYS = 8;
608
611
  /** Recognizes the lifted body of a capture-free numeric comparator:
609
612
  * `(a, b) => a - b`, `b - a`, `a < b ? -1 : a > b ? 1 : 0` (either test
610
613
  * first, either sign), or any of them over one number field of both
611
- * parameters (`a.k - b.k`). Such a comparator runs no user code, cannot
612
- * throw, and is consistent over numbers other than NaN, so the runtime may
613
- * order the elements by their keys without calling it. */
614
+ * parameters (`a.k - b.k`, or `(a.k ?? 0) - (b.k ?? 0)` over an optional
615
+ * field). Such a comparator runs no user code, cannot throw, and is
616
+ * consistent over numbers other than NaN, so the runtime may order the
617
+ * elements by their keys without calling it. A chain `t0 || t1 || ...` of
618
+ * such terms over fields orders by several keys, the first deciding: a term
619
+ * that is 0 or NaN falls through to the next. Returns the keys in order. */
614
620
  export function recognizeKeyComparator(fn) {
615
621
  if (fn.params.length !== 2 || fn.async || fn.generator || (fn.captures?.length ?? 0) > 0)
616
622
  return null;
617
- const [first, second] = fn.params;
618
623
  const ret = fn.body.length === 1 ? fn.body[0] : null;
619
624
  if (ret?.kind !== "return" || !ret.value)
620
625
  return null;
626
+ const terms = [];
627
+ const flatten = (e) => {
628
+ if (e.kind === "logical" && e.op === "||" && e.type.kind === "f64") {
629
+ flatten(e.left);
630
+ flatten(e.right);
631
+ }
632
+ else
633
+ terms.push(e);
634
+ };
635
+ flatten(ret.value);
636
+ if (terms.length > MAX_SORT_KEYS)
637
+ return null;
638
+ const keys = [];
639
+ for (const term of terms) {
640
+ const key = recognizeKeyTerm(fn, term);
641
+ if (!key)
642
+ return null;
643
+ keys.push(key);
644
+ }
645
+ // Several keys order elements by their fields.
646
+ if (keys.length > 1 && keys.some((key) => key.read === null))
647
+ return null;
648
+ return keys;
649
+ }
650
+ /** One term of a key comparator over one key (recognizeKeyComparator). */
651
+ function recognizeKeyTerm(fn, value) {
652
+ const [first, second] = fn.params;
621
653
  let read;
622
654
  // Which parameter an operand reads; every operand must read the same key.
623
655
  const operand = (e) => {
624
656
  if (e.type.kind !== "f64")
625
657
  return null;
626
658
  let ref = e;
627
- let field = null;
628
- if (e.kind === "recordGet" || e.kind === "fieldGet") {
629
- field = e;
659
+ let key = null;
660
+ if (e.kind === "nullish" &&
661
+ (e.left.kind === "recordGet" || e.left.kind === "fieldGet") &&
662
+ e.right.kind === "numLit") {
663
+ key = { field: e.left, fallback: e.right };
664
+ ref = e.left.obj;
665
+ }
666
+ else if (e.kind === "recordGet" || e.kind === "fieldGet") {
667
+ key = { field: e, fallback: null };
630
668
  ref = e.obj;
631
669
  }
632
670
  if (ref.kind !== "varRef")
@@ -635,8 +673,8 @@ export function recognizeKeyComparator(fn) {
635
673
  if (param === null)
636
674
  return null;
637
675
  if (read === undefined)
638
- read = field;
639
- else if (!sameKeyRead(read, field))
676
+ read = key;
677
+ else if (!sameKeyRead(read, key))
640
678
  return null;
641
679
  return param;
642
680
  };
@@ -650,7 +688,6 @@ export function recognizeKeyComparator(fn) {
650
688
  return (e.op === "<") === (left === 0) ? "lt" : "gt";
651
689
  };
652
690
  const sign = (e) => e.kind === "numLit" && (e.value === 1 || e.value === -1 || e.value === 0) ? e.value : null;
653
- const value = ret.value;
654
691
  if (value.kind === "bin" && value.op === "-") {
655
692
  const left = operand(value.left), right = operand(value.right);
656
693
  if (left === null || right === null || left === right)
@@ -673,7 +710,7 @@ export function recognizeKeyComparator(fn) {
673
710
  }
674
711
  return null;
675
712
  }
676
- /** The key order of a comparator closure: a zero-capture closure (not a
713
+ /** The keys of a comparator closure: a zero-capture closure (not a
677
714
  * signature adapter) over a lifted function recognizeKeyComparator accepts. */
678
715
  export function closureKeyOrder(liftedFns, closure) {
679
716
  if (closure.kind !== "closure" || closure.captures.length > 0 || closure.adapts)
@@ -684,23 +721,81 @@ export function closureKeyOrder(liftedFns, closure) {
684
721
  function sameKeyRead(left, right) {
685
722
  if (left === null || right === null)
686
723
  return left === right;
687
- if (left.kind === "recordGet" && right.kind === "recordGet")
688
- return left.shapeId === right.shapeId && left.field === right.field;
689
- if (left.kind === "fieldGet" && right.kind === "fieldGet")
690
- return left.className === right.className && left.field === right.field;
724
+ if (!Object.is(left.fallback?.value, right.fallback?.value))
725
+ return false;
726
+ const a = left.field, b = right.field;
727
+ if (a.kind === "recordGet" && b.kind === "recordGet")
728
+ return a.shapeId === b.shapeId && a.field === b.field;
729
+ if (a.kind === "fieldGet" && b.kind === "fieldGet")
730
+ return a.className === b.className && a.field === b.field;
691
731
  return false;
692
732
  }
693
- /** The key reader of a recognized field comparator: `(x) => x.k`, the same
694
- * field read as the comparator's. */
695
- export function buildSortKeyFn(name, elem, read, loc) {
733
+ /** The order argument of a keyed sort: 1 or -1 for one key; for several,
734
+ * the key count in the low byte and, from bit 8, one bit per descending
735
+ * key (the runtime's SCR_SORT_KEYS encoding). */
736
+ export function sortKeysOrder(keys) {
737
+ if (keys.length === 1)
738
+ return keys[0].order;
739
+ return keys.reduce((code, key, j) => (key.order < 0 ? code | (1 << (8 + j)) : code), keys.length);
740
+ }
741
+ /** A cache key that identifies a recognized comparator's key reads. */
742
+ export function sortKeysId(keys) {
743
+ return keys
744
+ .map((key) => {
745
+ if (!key.read)
746
+ return "self";
747
+ const field = key.read.field;
748
+ const owner = field.kind === "recordGet" ? field.shapeId : field.className;
749
+ const fallback = key.read.fallback
750
+ ? `??${Object.is(key.read.fallback.value, -0) ? "-0" : key.read.fallback.value}`
751
+ : "";
752
+ return `${field.kind}:${owner}:${field.field}${fallback}`;
753
+ })
754
+ .join("|");
755
+ }
756
+ /** The key reader of a recognized field comparator: `(x) => x.k` (or
757
+ * `x.k ?? d`), the same read as the comparator's. For several keys it takes
758
+ * the key's index too: `(x, j) => j === 0 ? key0 : j === 1 ? key1 : ...`. */
759
+ export function buildSortKeyFn(name, elem, reads, loc) {
696
760
  const b = new SortIr(loc);
697
761
  const x = b.local("x", elem);
762
+ const read = (key) => {
763
+ const field = { ...key.field, obj: x, loc };
764
+ return key.fallback
765
+ ? { kind: "nullish", left: field, right: key.fallback, type: F64, loc }
766
+ : field;
767
+ };
768
+ if (reads.length === 1) {
769
+ return {
770
+ name,
771
+ params: [{ localId: x.localId, name: "x", type: elem }],
772
+ returnType: F64,
773
+ locals: b.locals,
774
+ body: distinctNodes([{ kind: "return", value: read(reads[0]), loc }]),
775
+ loc,
776
+ };
777
+ }
778
+ const j = b.local("j");
779
+ let value = read(reads[reads.length - 1]);
780
+ for (let index = reads.length - 2; index >= 0; index--) {
781
+ value = {
782
+ kind: "ternary",
783
+ cond: b.eq(j, b.num(index)),
784
+ then: read(reads[index]),
785
+ else_: value,
786
+ type: F64,
787
+ loc,
788
+ };
789
+ }
698
790
  return {
699
791
  name,
700
- params: [{ localId: x.localId, name: "x", type: elem }],
792
+ params: [
793
+ { localId: x.localId, name: "x", type: elem },
794
+ { localId: j.localId, name: "j", type: F64 },
795
+ ],
701
796
  returnType: F64,
702
797
  locals: b.locals,
703
- body: [{ kind: "return", value: { ...read, obj: x, loc }, loc }],
798
+ body: distinctNodes([{ kind: "return", value, loc }]),
704
799
  loc,
705
800
  };
706
801
  }
@@ -708,7 +803,8 @@ export function buildArraySortFn(name, elem, arity, copyFirst, undefinedTag, loc
708
803
  const b = new SortIr(loc);
709
804
  const arrT = arrayOf(elem), fnT = funcOf([elem, elem].slice(0, arity), F64);
710
805
  const a = b.local("a", arrT), f = b.local("f", fnT);
711
- const keyT = funcOf([elem], F64);
806
+ // A reader of several keys takes the key's index too (buildSortKeyFn).
807
+ const keyT = funcOf(keyed && keyed.keys > 1 ? [elem, F64] : [elem], F64);
712
808
  const key = keyed?.key ? b.local("key", keyT) : null;
713
809
  // A recognized comparator lets the runtime order by keys; it still
714
810
  // receives the comparator for inputs whose keys it does not order.