@scriptc/compiler 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (364) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +490 -39
  2. package/dist/backend/cycle-analysis.js +6 -1
  3. package/dist/backend/cycle-analysis.js.map +1 -1
  4. package/dist/backend/llvm/alloc.js +24 -10
  5. package/dist/backend/llvm/alloc.js.map +1 -1
  6. package/dist/backend/llvm/alloc.test.js +47 -1
  7. package/dist/backend/llvm/alloc.test.js.map +1 -1
  8. package/dist/backend/llvm/array-search.d.ts +8 -0
  9. package/dist/backend/llvm/array-search.js +52 -0
  10. package/dist/backend/llvm/array-search.js.map +1 -0
  11. package/dist/backend/llvm/array-search.test.d.ts +1 -0
  12. package/dist/backend/llvm/array-search.test.js +72 -0
  13. package/dist/backend/llvm/array-search.test.js.map +1 -0
  14. package/dist/backend/llvm/call-lifetimes.d.ts +8 -1
  15. package/dist/backend/llvm/call-lifetimes.js +33 -11
  16. package/dist/backend/llvm/call-lifetimes.js.map +1 -1
  17. package/dist/backend/llvm/call-lifetimes.test.js +54 -0
  18. package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
  19. package/dist/backend/llvm/classes.js +87 -36
  20. package/dist/backend/llvm/classes.js.map +1 -1
  21. package/dist/backend/llvm/common.d.ts +1 -1
  22. package/dist/backend/llvm/common.js +1 -1
  23. package/dist/backend/llvm/dense-array-access.d.ts +5 -0
  24. package/dist/backend/llvm/dense-array-access.js +1 -1
  25. package/dist/backend/llvm/dense-array-access.js.map +1 -1
  26. package/dist/backend/llvm/dyn.d.ts +4 -0
  27. package/dist/backend/llvm/dyn.js +73 -9
  28. package/dist/backend/llvm/dyn.js.map +1 -1
  29. package/dist/backend/llvm/emitter.d.ts +65 -14
  30. package/dist/backend/llvm/emitter.js +297 -81
  31. package/dist/backend/llvm/emitter.js.map +1 -1
  32. package/dist/backend/llvm/emitter.test.js +26 -3
  33. package/dist/backend/llvm/emitter.test.js.map +1 -1
  34. package/dist/backend/llvm/expr-async.js +52 -1
  35. package/dist/backend/llvm/expr-async.js.map +1 -1
  36. package/dist/backend/llvm/expr-bytes.js +11 -0
  37. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  38. package/dist/backend/llvm/expr-callbacks.js +16 -2
  39. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  40. package/dist/backend/llvm/expr-calls.js +8 -1
  41. package/dist/backend/llvm/expr-calls.js.map +1 -1
  42. package/dist/backend/llvm/expr-containers.js +42 -15
  43. package/dist/backend/llvm/expr-containers.js.map +1 -1
  44. package/dist/backend/llvm/expr-dynamic.js +19 -8
  45. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  46. package/dist/backend/llvm/expr-primitives.js +28 -30
  47. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  48. package/dist/backend/llvm/expr-records.js +8 -4
  49. package/dist/backend/llvm/expr-records.js.map +1 -1
  50. package/dist/backend/llvm/expr-stream-bridges.js +35 -32
  51. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  52. package/dist/backend/llvm/expr-stream-callbacks.d.ts +13 -2
  53. package/dist/backend/llvm/expr-stream-callbacks.js +80 -5
  54. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  55. package/dist/backend/llvm/inline-unions.d.ts +48 -0
  56. package/dist/backend/llvm/inline-unions.js +134 -0
  57. package/dist/backend/llvm/inline-unions.js.map +1 -0
  58. package/dist/backend/llvm/inline-unions.test.d.ts +1 -0
  59. package/dist/backend/llvm/inline-unions.test.js +124 -0
  60. package/dist/backend/llvm/inline-unions.test.js.map +1 -0
  61. package/dist/backend/llvm/integer-remainder.d.ts +28 -5
  62. package/dist/backend/llvm/integer-remainder.js +80 -9
  63. package/dist/backend/llvm/integer-remainder.js.map +1 -1
  64. package/dist/backend/llvm/lib-dispatch.js +163 -28
  65. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  66. package/dist/backend/llvm/lib-filesystem.js +125 -7
  67. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  68. package/dist/backend/llvm/lib-network.js +9 -6
  69. package/dist/backend/llvm/lib-network.js.map +1 -1
  70. package/dist/backend/llvm/lib-process.js +2 -2
  71. package/dist/backend/llvm/lib-process.js.map +1 -1
  72. package/dist/backend/llvm/lib-shared.js +132 -0
  73. package/dist/backend/llvm/lib-shared.js.map +1 -1
  74. package/dist/backend/llvm/lib-stream.js +97 -0
  75. package/dist/backend/llvm/lib-stream.js.map +1 -1
  76. package/dist/backend/llvm/local-array-reads.js +7 -3
  77. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  78. package/dist/backend/llvm/local-array-reads.test.js +6 -3
  79. package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
  80. package/dist/backend/llvm/local-union-storage.d.ts +2 -0
  81. package/dist/backend/llvm/local-union-storage.js +5 -0
  82. package/dist/backend/llvm/local-union-storage.js.map +1 -1
  83. package/dist/backend/llvm/local-union-storage.test.js +1 -0
  84. package/dist/backend/llvm/local-union-storage.test.js.map +1 -1
  85. package/dist/backend/llvm/loop-array-borrows.d.ts +8 -2
  86. package/dist/backend/llvm/loop-array-borrows.js +93 -13
  87. package/dist/backend/llvm/loop-array-borrows.js.map +1 -1
  88. package/dist/backend/llvm/map-number-lookup.d.ts +20 -0
  89. package/dist/backend/llvm/map-number-lookup.js +66 -0
  90. package/dist/backend/llvm/map-number-lookup.js.map +1 -1
  91. package/dist/backend/llvm/map-number-lookup.test.d.ts +1 -0
  92. package/dist/backend/llvm/map-number-lookup.test.js +102 -0
  93. package/dist/backend/llvm/map-number-lookup.test.js.map +1 -0
  94. package/dist/backend/llvm/map-read-lifetimes.js +1 -0
  95. package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
  96. package/dist/backend/llvm/publish.d.ts +4 -0
  97. package/dist/backend/llvm/publish.js +3 -1
  98. package/dist/backend/llvm/publish.js.map +1 -1
  99. package/dist/backend/llvm/record-results.d.ts +8 -5
  100. package/dist/backend/llvm/record-results.js +20 -12
  101. package/dist/backend/llvm/record-results.js.map +1 -1
  102. package/dist/backend/llvm/reference-effects.js +13 -0
  103. package/dist/backend/llvm/reference-effects.js.map +1 -1
  104. package/dist/backend/llvm/reference-writes.js +14 -0
  105. package/dist/backend/llvm/reference-writes.js.map +1 -1
  106. package/dist/backend/llvm/regions.d.ts +1 -0
  107. package/dist/backend/llvm/regions.js +12 -7
  108. package/dist/backend/llvm/regions.js.map +1 -1
  109. package/dist/backend/llvm/serialized-ir-emission.test.js +2 -0
  110. package/dist/backend/llvm/serialized-ir-emission.test.js.map +1 -1
  111. package/dist/backend/llvm/shapes.d.ts +56 -10
  112. package/dist/backend/llvm/shapes.js +178 -39
  113. package/dist/backend/llvm/shapes.js.map +1 -1
  114. package/dist/backend/llvm/shapes.test.js +61 -3
  115. package/dist/backend/llvm/shapes.test.js.map +1 -1
  116. package/dist/backend/llvm/stack-objects.js +16 -4
  117. package/dist/backend/llvm/stack-objects.js.map +1 -1
  118. package/dist/backend/llvm/stack-objects.test.js +3 -0
  119. package/dist/backend/llvm/stack-objects.test.js.map +1 -1
  120. package/dist/backend/llvm/walkers.d.ts +11 -0
  121. package/dist/backend/llvm/walkers.js +106 -10
  122. package/dist/backend/llvm/walkers.js.map +1 -1
  123. package/dist/backend/may-throw.js +9 -4
  124. package/dist/backend/may-throw.js.map +1 -1
  125. package/dist/backend/native/contracts.d.ts +2 -2
  126. package/dist/backend/native/executable.js +14 -3
  127. package/dist/backend/native/executable.js.map +1 -1
  128. package/dist/backend/native/runtime-inputs.d.ts +1 -1
  129. package/dist/backend/native/runtime-inputs.js +1 -0
  130. package/dist/backend/native/runtime-inputs.js.map +1 -1
  131. package/dist/backend/native-toolchain.test.js +1 -1
  132. package/dist/backend/native-toolchain.test.js.map +1 -1
  133. package/dist/backend/runtime-abi.d.ts +2 -2
  134. package/dist/backend/runtime-abi.js +2 -2
  135. package/dist/backend/runtime-pack-targets.test.js +1 -1
  136. package/dist/backend/runtime-pack.test.js +1 -1
  137. package/dist/backend/target-diagnostics.js +4 -1
  138. package/dist/backend/target-diagnostics.js.map +1 -1
  139. package/dist/backend/target-diagnostics.test.js +4 -1
  140. package/dist/backend/target-diagnostics.test.js.map +1 -1
  141. package/dist/compat/fetch-profile.js +4 -4
  142. package/dist/compat/fetch-profile.js.map +1 -1
  143. package/dist/contracts/check.js +2 -0
  144. package/dist/contracts/check.js.map +1 -1
  145. package/dist/coverage/report.js +1 -1
  146. package/dist/coverage/report.js.map +1 -1
  147. package/dist/diagnostics/diagnostic.d.ts +6 -5
  148. package/dist/diagnostics/diagnostic.js +7 -6
  149. package/dist/diagnostics/diagnostic.js.map +1 -1
  150. package/dist/frontend/builtin-modules.d.ts +1 -1
  151. package/dist/frontend/builtin-modules.js +1 -0
  152. package/dist/frontend/builtin-modules.js.map +1 -1
  153. package/dist/frontend/comptime-node.js +2 -2
  154. package/dist/frontend/comptime-node.js.map +1 -1
  155. package/dist/frontend/lowering/binding-analysis.d.ts +1 -1
  156. package/dist/frontend/lowering/binding-analysis.js +1 -1
  157. package/dist/frontend/lowering/builtins/arguments.d.ts +4 -0
  158. package/dist/frontend/lowering/builtins/arguments.js +8 -4
  159. package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
  160. package/dist/frontend/lowering/builtins/blob.d.ts +20 -0
  161. package/dist/frontend/lowering/builtins/blob.js +167 -0
  162. package/dist/frontend/lowering/builtins/blob.js.map +1 -0
  163. package/dist/frontend/lowering/builtins/child-process-async.d.ts +2 -2
  164. package/dist/frontend/lowering/builtins/child-process-async.js +2 -2
  165. package/dist/frontend/lowering/builtins/child-process-methods.js +1 -1
  166. package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
  167. package/dist/frontend/lowering/builtins/child-process-sync.js +1 -1
  168. package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -1
  169. package/dist/frontend/lowering/builtins/compression.js +3 -2
  170. package/dist/frontend/lowering/builtins/compression.js.map +1 -1
  171. package/dist/frontend/lowering/builtins/crypto.js +415 -120
  172. package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
  173. package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +10 -0
  174. package/dist/frontend/lowering/builtins/filesystem-calls.js +89 -1
  175. package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
  176. package/dist/frontend/lowering/builtins/filesystem.d.ts +16 -7
  177. package/dist/frontend/lowering/builtins/filesystem.js +97 -15
  178. package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
  179. package/dist/frontend/lowering/builtins/fs-glob.d.ts +23 -0
  180. package/dist/frontend/lowering/builtins/fs-glob.js +224 -0
  181. package/dist/frontend/lowering/builtins/fs-glob.js.map +1 -0
  182. package/dist/frontend/lowering/builtins/key-object.d.ts +13 -0
  183. package/dist/frontend/lowering/builtins/key-object.js +56 -0
  184. package/dist/frontend/lowering/builtins/key-object.js.map +1 -0
  185. package/dist/frontend/lowering/builtins/module-calls.js +44 -11
  186. package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
  187. package/dist/frontend/lowering/builtins/performance.d.ts +25 -3
  188. package/dist/frontend/lowering/builtins/performance.js +340 -5
  189. package/dist/frontend/lowering/builtins/performance.js.map +1 -1
  190. package/dist/frontend/lowering/builtins/process.d.ts +2 -2
  191. package/dist/frontend/lowering/builtins/process.js +107 -14
  192. package/dist/frontend/lowering/builtins/process.js.map +1 -1
  193. package/dist/frontend/lowering/builtins/properties.d.ts +0 -7
  194. package/dist/frontend/lowering/builtins/properties.js +39 -11
  195. package/dist/frontend/lowering/builtins/properties.js.map +1 -1
  196. package/dist/frontend/lowering/builtins/readline.d.ts +23 -8
  197. package/dist/frontend/lowering/builtins/readline.js +266 -90
  198. package/dist/frontend/lowering/builtins/readline.js.map +1 -1
  199. package/dist/frontend/lowering/builtins/url.d.ts +8 -0
  200. package/dist/frontend/lowering/builtins/url.js +36 -0
  201. package/dist/frontend/lowering/builtins/url.js.map +1 -1
  202. package/dist/frontend/lowering/call-arguments.js +1 -1
  203. package/dist/frontend/lowering/call-arguments.js.map +1 -1
  204. package/dist/frontend/lowering/call-signatures.js +20 -2
  205. package/dist/frontend/lowering/call-signatures.js.map +1 -1
  206. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +2 -0
  207. package/dist/frontend/lowering/class-dynamic-dispatch.js +105 -1
  208. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  209. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +1 -0
  210. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
  211. package/dist/frontend/lowering/class-protocol-dispatch.d.ts +45 -0
  212. package/dist/frontend/lowering/class-protocol-dispatch.js +516 -0
  213. package/dist/frontend/lowering/class-protocol-dispatch.js.map +1 -0
  214. package/dist/frontend/lowering/coercions/structural-plans.js +2 -1
  215. package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
  216. package/dist/frontend/lowering/coercions/structural.js +3 -3
  217. package/dist/frontend/lowering/coercions/structural.js.map +1 -1
  218. package/dist/frontend/lowering/collation-repertoire.js +6 -5
  219. package/dist/frontend/lowering/collation-repertoire.js.map +1 -1
  220. package/dist/frontend/lowering/containers/array-callbacks.js +4 -7
  221. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  222. package/dist/frontend/lowering/containers/array-methods.d.ts +0 -7
  223. package/dist/frontend/lowering/containers/array-methods.js +43 -2
  224. package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
  225. package/dist/frontend/lowering/containers/bytes.js +38 -26
  226. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  227. package/dist/frontend/lowering/containers/for-of.d.ts +1 -1
  228. package/dist/frontend/lowering/containers/for-of.js +5 -1
  229. package/dist/frontend/lowering/containers/for-of.js.map +1 -1
  230. package/dist/frontend/lowering/containers/indexed-objects.js +1 -1
  231. package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
  232. package/dist/frontend/lowering/crypto-tables.d.ts +3 -3
  233. package/dist/frontend/lowering/crypto-tables.js +77 -12
  234. package/dist/frontend/lowering/crypto-tables.js.map +1 -1
  235. package/dist/frontend/lowering/expressions/nullish-assignment.js +10 -0
  236. package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
  237. package/dist/frontend/lowering/expressions/object-literals.js +16 -12
  238. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  239. package/dist/frontend/lowering/generic-functions.d.ts +2 -2
  240. package/dist/frontend/lowering/generic-functions.js +2 -2
  241. package/dist/frontend/lowering/generic-functions.js.map +1 -1
  242. package/dist/frontend/lowering/http2-constants.js +1 -1
  243. package/dist/frontend/lowering/lower-array-sort.d.ts +12 -1
  244. package/dist/frontend/lowering/lower-array-sort.js +561 -191
  245. package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
  246. package/dist/frontend/lowering/lower-array-sort.test.js +4 -2
  247. package/dist/frontend/lowering/lower-array-sort.test.js.map +1 -1
  248. package/dist/frontend/lowering/lower-assert.js +2 -2
  249. package/dist/frontend/lowering/lower-async-iteration.d.ts +6 -3
  250. package/dist/frontend/lowering/lower-async-iteration.js +248 -2
  251. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
  252. package/dist/frontend/lowering/lower-calls.js +101 -9
  253. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  254. package/dist/frontend/lowering/lower-classes.d.ts +8 -2
  255. package/dist/frontend/lowering/lower-classes.js +40 -9
  256. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  257. package/dist/frontend/lowering/lower-comptime.d.ts +1 -1
  258. package/dist/frontend/lowering/lower-comptime.js +4 -4
  259. package/dist/frontend/lowering/lower-comptime.js.map +1 -1
  260. package/dist/frontend/lowering/lower-event-target.d.ts +63 -0
  261. package/dist/frontend/lowering/lower-event-target.js +362 -0
  262. package/dist/frontend/lowering/lower-event-target.js.map +1 -0
  263. package/dist/frontend/lowering/lower-expando.js +2 -2
  264. package/dist/frontend/lowering/lower-exprs.js +112 -22
  265. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  266. package/dist/frontend/lowering/lower-inspect.js +129 -11
  267. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  268. package/dist/frontend/lowering/lower-mixins.js +1 -1
  269. package/dist/frontend/lowering/lower-modules.d.ts +1 -1
  270. package/dist/frontend/lowering/lower-modules.js +7 -3
  271. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  272. package/dist/frontend/lowering/lower-namespaces.d.ts +2 -2
  273. package/dist/frontend/lowering/lower-namespaces.js +2 -2
  274. package/dist/frontend/lowering/lower-server.js +39 -14
  275. package/dist/frontend/lowering/lower-server.js.map +1 -1
  276. package/dist/frontend/lowering/lower-stdlib.d.ts +7 -1
  277. package/dist/frontend/lowering/lower-stdlib.js +10 -3
  278. package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
  279. package/dist/frontend/lowering/lower-stmts.d.ts +2 -2
  280. package/dist/frontend/lowering/lower-stmts.js +46 -12
  281. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  282. package/dist/frontend/lowering/lower-stream.js +234 -22
  283. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  284. package/dist/frontend/lowering/lower-timers.js +1 -1
  285. package/dist/frontend/lowering/lowerer.d.ts +23 -5
  286. package/dist/frontend/lowering/lowerer.js +245 -41
  287. package/dist/frontend/lowering/lowerer.js.map +1 -1
  288. package/dist/frontend/lowering/native-ffi.js +2 -2
  289. package/dist/frontend/lowering/native-ffi.js.map +1 -1
  290. package/dist/frontend/lowering/runtime-optional-records.d.ts +115 -0
  291. package/dist/frontend/lowering/runtime-optional-records.js +715 -0
  292. package/dist/frontend/lowering/runtime-optional-records.js.map +1 -0
  293. package/dist/frontend/lowering/runtime-optional-records.test.d.ts +1 -0
  294. package/dist/frontend/lowering/runtime-optional-records.test.js +175 -0
  295. package/dist/frontend/lowering/runtime-optional-records.test.js.map +1 -0
  296. package/dist/frontend/lowering/surfaces.d.ts +7 -3
  297. package/dist/frontend/lowering/surfaces.js +273 -22
  298. package/dist/frontend/lowering/surfaces.js.map +1 -1
  299. package/dist/frontend/module-syntax.d.ts +1 -1
  300. package/dist/frontend/module-syntax.js +1 -1
  301. package/dist/frontend/npm-static-prune.js +1 -1
  302. package/dist/frontend/npm-static-prune.js.map +1 -1
  303. package/dist/frontend/npm-static-rewrite-syntax.js +4 -3
  304. package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
  305. package/dist/frontend/pipeline.js +1 -1
  306. package/dist/frontend/pipeline.js.map +1 -1
  307. package/dist/frontend/program.d.ts +3 -3
  308. package/dist/frontend/program.js +19 -17
  309. package/dist/frontend/program.js.map +1 -1
  310. package/dist/frontend/resolve.js +1 -1
  311. package/dist/frontend/ts7/adapter.js +1 -1
  312. package/dist/frontend/ts7/ast-bytes.d.ts +1 -1
  313. package/dist/frontend/ts7/ast-bytes.js +1 -1
  314. package/dist/frontend/ts7/semantic-json.d.ts +1 -1
  315. package/dist/frontend/ts7/semantic-json.js +1 -1
  316. package/dist/frontend/ts7/semantic-json.js.map +1 -1
  317. package/dist/frontend/ts7/world-check.js +1 -1
  318. package/dist/frontend/tsc-codes.js +2 -2
  319. package/dist/frontend/tsc-codes.js.map +1 -1
  320. package/dist/frontend/type-mapper.d.ts +16 -1
  321. package/dist/frontend/type-mapper.js +143 -18
  322. package/dist/frontend/type-mapper.js.map +1 -1
  323. package/dist/index.js +5 -4
  324. package/dist/index.js.map +1 -1
  325. package/dist/ir/analysis.d.ts +12 -6
  326. package/dist/ir/analysis.js +26 -10
  327. package/dist/ir/analysis.js.map +1 -1
  328. package/dist/ir/analysis.test.js +15 -3
  329. package/dist/ir/analysis.test.js.map +1 -1
  330. package/dist/ir/builtin-effects.js +79 -0
  331. package/dist/ir/builtin-effects.js.map +1 -1
  332. package/dist/ir/builtin-signatures.d.ts +1 -1
  333. package/dist/ir/builtin-signatures.js +291 -38
  334. package/dist/ir/builtin-signatures.js.map +1 -1
  335. package/dist/ir/int32-slots.js +1 -0
  336. package/dist/ir/int32-slots.js.map +1 -1
  337. package/dist/ir/ir.d.ts +64 -16
  338. package/dist/ir/ir.js +37 -1
  339. package/dist/ir/ir.js.map +1 -1
  340. package/dist/ir/runtime-features.js +83 -6
  341. package/dist/ir/runtime-features.js.map +1 -1
  342. package/dist/ir/serialize.js +1 -1
  343. package/dist/ir/serialize.js.map +1 -1
  344. package/dist/ir/traverse.js +1 -0
  345. package/dist/ir/traverse.js.map +1 -1
  346. package/dist/ir/validate.js +100 -9
  347. package/dist/ir/validate.js.map +1 -1
  348. package/dist/ir/validate.test.js +60 -0
  349. package/dist/ir/validate.test.js.map +1 -1
  350. package/dist/library/fence-eval.d.ts +1 -1
  351. package/dist/library/fence-eval.js +5 -4
  352. package/dist/library/fence-eval.js.map +1 -1
  353. package/dist/library/ir-policy.js +10 -4
  354. package/dist/library/ir-policy.js.map +1 -1
  355. package/dist/library/library-profile.js +13 -13
  356. package/dist/library/library-profile.js.map +1 -1
  357. package/dist/library/prepare.js +1 -1
  358. package/dist/library/prepare.js.map +1 -1
  359. package/dist/library/sidecar.js +3 -3
  360. package/dist/library/sidecar.js.map +1 -1
  361. package/dist/native/prepare.js +3 -2
  362. package/dist/native/prepare.js.map +1 -1
  363. package/package.json +20 -20
  364. package/surface-manifest.json +379 -142
@@ -1,4 +1,5 @@
1
- import { lowerBuiltinByteInput, errorFirstBytesCallback } from "./arguments.js";
1
+ import { lowerBuiltinByteInput, errorFirstBytesCallback, errorFirstCallback } from "./arguments.js";
2
+ import { isKeyObjectValue } from "./key-object.js";
2
3
  import { dynUndefinedExpr } from "../../../ir/build.js";
3
4
  import * as ts from "../../ts7/adapter.js";
4
5
  import { own } from "../lowerer.js";
@@ -95,7 +96,7 @@ function lowerHashDigestChain(lowerer, call, access) {
95
96
  const dataNode = updateCall.arguments[0];
96
97
  const dataIr = lowerer.mapTypeOf(lowerer.typeOf(dataNode));
97
98
  if (dataIr?.kind === "bytes") {
98
- const data = lowerer.lowerExpr(dataNode);
99
+ const data = cryptoByteView(lowerer, dataNode, lowerer.lowerExpr(dataNode));
99
100
  const enc = lowerer.lowerExprExpecting(call.arguments[0], STRING);
100
101
  return {
101
102
  kind: "libCall",
@@ -118,19 +119,83 @@ function lowerHashDigestChain(lowerer, call, access) {
118
119
  }
119
120
  return null;
120
121
  }
121
- function cryptoEncoding(lowerer, node, use) {
122
- const type = lowerer.typeOf(node);
123
- if (!type.isStringLiteralType() || (type.value !== "hex" && type.value !== "base64")) {
124
- lowerer.noLowering(`${use} with this encoding`, node, 'the lowered output encodings are "hex" and "base64"');
122
+ /** Node's normalizeEncoding(): the canonical name of a Buffer encoding,
123
+ * compared case-insensitively, or undefined for a name Node does not know. */
124
+ function cryptoEncodingName(value) {
125
+ switch (value.toLowerCase()) {
126
+ case "hex":
127
+ return "hex";
128
+ case "base64":
129
+ return "base64";
130
+ case "base64url":
131
+ return "base64url";
132
+ case "":
133
+ case "utf8":
134
+ case "utf-8":
135
+ return "utf8";
136
+ case "latin1":
137
+ case "binary":
138
+ return "latin1";
139
+ case "ascii":
140
+ return "ascii";
141
+ case "utf16le":
142
+ case "utf-16le":
143
+ case "ucs2":
144
+ case "ucs-2":
145
+ return "utf16le";
146
+ default:
147
+ return undefined;
125
148
  }
126
- return lowerer.lowerExprExpecting(node, STRING);
127
149
  }
128
- function cryptoAlgorithm(lowerer, node, use) {
129
- const type = lowerer.typeOf(node);
130
- if (type.isStringLiteralType() &&
131
- !["md5", "sha1", "sha224", "sha256", "sha384", "sha512"].includes(type.value.toLowerCase())) {
132
- lowerer.noLowering(`${use} with algorithm '${type.value}'`, node, "md5, sha1, sha224, sha256, sha384, and sha512 are the lowered digest algorithms");
150
+ /** The values of a string literal type or a union of them; undefined when
151
+ * the type allows other values. */
152
+ function stringLiteralValues(type) {
153
+ if (type.isStringLiteralType())
154
+ return [type.value];
155
+ if (!type.isUnionType())
156
+ return undefined;
157
+ const values = [];
158
+ for (const member of ts.constituentTypes(type)) {
159
+ if (!member.isStringLiteralType())
160
+ return undefined;
161
+ values.push(member.value);
133
162
  }
163
+ return values;
164
+ }
165
+ /** Whether every value the node's type allows is an encoding that gives a
166
+ * string digest: a Buffer encoding Node knows. Hash.digest() treats ""
167
+ * as no encoding and returns a Buffer; crypto.hash() reads it as UTF-8. */
168
+ function isStringDigestEncoding(lowerer, node, emptyIsString) {
169
+ const values = stringLiteralValues(lowerer.typeOf(node));
170
+ return (!!values &&
171
+ values.every((value) => (value !== "" || emptyIsString) && cryptoEncodingName(value) !== undefined));
172
+ }
173
+ /** Whether every offset/size argument is statically a number; other
174
+ * values take the runtime checks, which throw Node's errors or apply its
175
+ * defaults. */
176
+ function cryptoNumberArgs(lowerer, nodes) {
177
+ return nodes.every((node) => lowerer.mapTypeOf(lowerer.typeOf(node))?.kind === "f64");
178
+ }
179
+ /** A view's bytes as the Uint8Array the byte-input libCalls take: other
180
+ * TypedArrays and DataViews become a u8 view of the same memory. */
181
+ function cryptoByteView(lowerer, node, value) {
182
+ if (value.type.kind !== "bytes" || value.type.elem === "u8")
183
+ return value;
184
+ return {
185
+ kind: "libCall",
186
+ fn: "bytes.bufferSource",
187
+ args: [lowerer.coerceInto(node, value, DYN)],
188
+ type: BYTES_U8,
189
+ loc: locOf(node),
190
+ };
191
+ }
192
+ function dynArg(lowerer, node, loc) {
193
+ return node ? lowerer.lowerExprExpecting(node, DYN) : dynUndefinedExpr(loc);
194
+ }
195
+ /** A digest name. The runtime resolves every name and alias Node 24
196
+ * accepts and throws Node's error for the others, so literals are not
197
+ * checked here. */
198
+ function cryptoAlgorithm(lowerer, node) {
134
199
  return lowerer.lowerExprExpecting(node, STRING);
135
200
  }
136
201
  function cryptoKdfInput(lowerer, node) {
@@ -144,7 +209,7 @@ function cryptoKdfInput(lowerer, node) {
144
209
  const value = lowerer.coerceInto(node, lowerer.lowerExpr(node), DYN);
145
210
  return { kind: "libCall", fn: "bytes.bufferSource", args: [value], type: BYTES_U8, loc };
146
211
  }
147
- lowerer.noLowering("crypto key derivation with this input", node, "strings, Buffers, numeric typed arrays, DataViews, and fixed-length ArrayBuffers are supported; KeyObjects are not yet lowered");
212
+ lowerer.noLowering("crypto key derivation with this input", node, "strings, Buffers, numeric typed arrays, DataViews, and fixed-length ArrayBuffers are supported; KeyObjects are accepted only as hkdf's key, as in Node");
148
213
  }
149
214
  export function lowerCryptoModuleCall(lowerer, expr, bi, loc) {
150
215
  if (bi.module !== "crypto")
@@ -182,7 +247,7 @@ export function lowerCryptoModuleCall(lowerer, expr, bi, loc) {
182
247
  lowerBuiltinByteInput(lowerer, args[1], locOf(args[1]), "crypto"),
183
248
  lowerer.lowerExprExpecting(args[2], F64),
184
249
  lowerer.lowerExprExpecting(args[3], F64),
185
- cryptoAlgorithm(lowerer, args[4], "crypto.pbkdf2"),
250
+ cryptoAlgorithm(lowerer, args[4]),
186
251
  errorFirstBytesCallback(lowerer, args[5], "crypto"),
187
252
  ],
188
253
  type: VOID,
@@ -194,8 +259,16 @@ export function lowerCryptoModuleCall(lowerer, expr, bi, loc) {
194
259
  if (args.length !== (async ? 6 : 5))
195
260
  lowerer.noLowering(`crypto.${bi.member} with ${args.length} arguments`, expr);
196
261
  const values = [
197
- cryptoAlgorithm(lowerer, args[0], `crypto.${bi.member}`),
198
- cryptoKdfInput(lowerer, args[1]),
262
+ cryptoAlgorithm(lowerer, args[0]),
263
+ isKeyObjectValue(lowerer, args[1])
264
+ ? {
265
+ kind: "libCall",
266
+ fn: "crypto.keyObjectInput",
267
+ args: [lowerer.lowerExprExpecting(args[1], DYN)],
268
+ type: BYTES_U8,
269
+ loc,
270
+ }
271
+ : cryptoKdfInput(lowerer, args[1]),
199
272
  cryptoKdfInput(lowerer, args[2]),
200
273
  cryptoKdfInput(lowerer, args[3]),
201
274
  lowerer.lowerExprExpecting(args[4], F64),
@@ -235,121 +308,323 @@ export function lowerCryptoModuleCall(lowerer, expr, bi, loc) {
235
308
  };
236
309
  }
237
310
  if (bi.member === "createHash") {
238
- if (args.length !== 1) {
239
- lowerer.noLowering(`crypto.createHash with ${args.length} arguments`, expr, "createHash(algorithm) is supported; options are not yet lowered");
311
+ if (args.length < 1 || args.length > 2 || args.some(ts.isSpreadElement)) {
312
+ lowerer.noLowering(`crypto.createHash with ${args.length} arguments`, expr, "createHash(algorithm[, options]) is supported");
313
+ }
314
+ const algorithm = cryptoAlgorithm(lowerer, args[0]);
315
+ if (args.length === 1) {
316
+ return { kind: "libCall", fn: "crypto.hashNew", args: [algorithm], type: CRYPTOHASH_T, loc };
240
317
  }
241
318
  return {
242
319
  kind: "libCall",
243
- fn: "crypto.hashNew",
244
- args: [cryptoAlgorithm(lowerer, args[0], "crypto.createHash")],
320
+ fn: "crypto.hashNewOpts",
321
+ args: [algorithm, lowerer.lowerExprExpecting(args[1], DYN)],
245
322
  type: CRYPTOHASH_T,
246
323
  loc,
247
324
  };
248
325
  }
249
326
  if (bi.member === "createHmac") {
250
- if (args.length !== 2) {
251
- lowerer.noLowering(`crypto.createHmac with ${args.length} arguments`, expr, "createHmac(algorithm, stringOrBufferKey) is supported; options and KeyObject keys are not yet lowered");
327
+ if (args.length < 2 || args.length > 3 || args.some(ts.isSpreadElement)) {
328
+ lowerer.noLowering(`crypto.createHmac with ${args.length} arguments`, expr, "createHmac(algorithm, key[, options]) is supported");
252
329
  }
253
- const algorithm = cryptoAlgorithm(lowerer, args[0], "crypto.createHmac");
330
+ const algorithm = cryptoAlgorithm(lowerer, args[0]);
254
331
  const key = lowerer.lowerExpr(args[1]);
255
- if (key.type.kind === "string") {
332
+ if (args.length === 3 || (key.type.kind !== "string" && key.type.kind !== "bytes")) {
333
+ // Views, ArrayBuffers, options.encoding and values of other types
334
+ // take Node's prepareSecretKey checks at run time.
256
335
  return {
257
336
  kind: "libCall",
258
- fn: "crypto.hmacNewStr",
259
- args: [algorithm, key],
337
+ fn: "crypto.hmacNewDyn",
338
+ args: [algorithm, lowerer.coerceInto(args[1], key, DYN), dynArg(lowerer, args[2], loc)],
260
339
  type: CRYPTOHMAC_T,
261
340
  loc,
262
341
  };
263
342
  }
264
- if (key.type.kind === "bytes" && key.type.elem === "u8") {
343
+ if (key.type.kind === "string") {
265
344
  return {
266
345
  kind: "libCall",
267
- fn: "crypto.hmacNewBytes",
346
+ fn: "crypto.hmacNewStr",
268
347
  args: [algorithm, key],
269
348
  type: CRYPTOHMAC_T,
270
349
  loc,
271
350
  };
272
351
  }
273
- lowerer.noLowering(`crypto.createHmac with a '${lowerer.fmt(key.type)}' key`, args[1], "string and Buffer/Uint8Array keys are supported");
352
+ return {
353
+ kind: "libCall",
354
+ fn: "crypto.hmacNewBytes",
355
+ args: [algorithm, cryptoByteView(lowerer, args[1], key)],
356
+ type: CRYPTOHMAC_T,
357
+ loc,
358
+ };
274
359
  }
275
360
  if (bi.member === "hash") {
276
- if (args.length < 2 || args.length > 3) {
277
- lowerer.noLowering(`crypto.hash with ${args.length} arguments`, expr, 'hash(algorithm, stringOrBuffer[, "hex" | "base64"]) is supported');
361
+ if (args.length < 2 || args.length > 3 || args.some(ts.isSpreadElement)) {
362
+ lowerer.noLowering(`crypto.hash with ${args.length} arguments`, expr, "hash(algorithm, data[, outputEncodingOrOptions]) is supported");
278
363
  }
279
- const algorithm = cryptoAlgorithm(lowerer, args[0], "crypto.hash");
364
+ const algorithm = cryptoAlgorithm(lowerer, args[0]);
280
365
  const data = lowerer.lowerExpr(args[1]);
281
- const encoding = args[2]
282
- ? cryptoEncoding(lowerer, args[2], "crypto.hash")
283
- : { kind: "strLit", value: "hex", type: STRING, loc };
284
- if (data.type.kind === "string") {
366
+ let options = args[2];
367
+ // An options literal holding only a literal string-digest
368
+ // outputEncoding is that encoding; evaluating it observes nothing.
369
+ if (options && ts.isObjectLiteralExpression(options) && options.properties.length === 1) {
370
+ const property = options.properties[0];
371
+ if (ts.isPropertyAssignment(property) &&
372
+ ts.isIdentifier(property.name) &&
373
+ property.name.text === "outputEncoding" &&
374
+ ts.isStringLiteral(property.initializer) &&
375
+ isStringDigestEncoding(lowerer, property.initializer, true)) {
376
+ options = property.initializer;
377
+ }
378
+ }
379
+ // String data or a view with no options or a string-digest encoding
380
+ // has a string result; every other form takes Node's checks at run
381
+ // time and returns the string or Buffer it produces.
382
+ if ((data.type.kind === "string" || data.type.kind === "bytes") &&
383
+ (options === undefined || isStringDigestEncoding(lowerer, options, true))) {
384
+ const encoding = options
385
+ ? lowerer.lowerExprExpecting(options, STRING)
386
+ : { kind: "strLit", value: "hex", type: STRING, loc };
285
387
  return {
286
388
  kind: "libCall",
287
- fn: "crypto.hashDigestStr",
288
- args: [algorithm, data, encoding],
389
+ fn: data.type.kind === "string" ? "crypto.hashDigestStr" : "crypto.hashDigestBytes",
390
+ args: [algorithm, cryptoByteView(lowerer, args[1], data), encoding],
289
391
  type: STRING,
290
392
  loc,
291
393
  };
292
394
  }
293
- if (data.type.kind === "bytes" && data.type.elem === "u8") {
395
+ return {
396
+ kind: "libCall",
397
+ fn: "crypto.hashOneshot",
398
+ args: [algorithm, lowerer.coerceInto(args[1], data, DYN), dynArg(lowerer, options, loc)],
399
+ type: DYN,
400
+ loc,
401
+ };
402
+ }
403
+ if (bi.member === "timingSafeEqual") {
404
+ if (args.length < 1 || args.length > 2 || args.some(ts.isSpreadElement))
405
+ lowerer.noLowering(`crypto.timingSafeEqual with ${args.length} arguments`, expr);
406
+ const left = lowerer.lowerExpr(args[0]);
407
+ const right = args[1] ? lowerer.lowerExpr(args[1]) : undefined;
408
+ // Views of every element kind compare their bytes; ArrayBuffers and
409
+ // other values take Node's checks at run time.
410
+ if (left.type.kind === "bytes" && right?.type.kind === "bytes") {
294
411
  return {
295
412
  kind: "libCall",
296
- fn: "crypto.hashDigestBytes",
297
- args: [algorithm, data, encoding],
298
- type: STRING,
413
+ fn: "crypto.timingSafeEqual",
414
+ args: [left, right],
415
+ type: BOOL,
299
416
  loc,
300
417
  };
301
418
  }
302
- lowerer.noLowering(`crypto.hash of '${lowerer.fmt(data.type)}' data`, args[1], "string and Buffer/Uint8Array data are supported");
303
- }
304
- if (bi.member === "timingSafeEqual") {
305
- if (args.length !== 2)
306
- lowerer.noLowering(`crypto.timingSafeEqual with ${args.length} arguments`, expr);
307
419
  return {
308
420
  kind: "libCall",
309
- fn: "crypto.timingSafeEqual",
421
+ fn: "crypto.timingSafeEqualDyn",
310
422
  args: [
311
- lowerer.lowerExprExpecting(args[0], BYTES_U8),
312
- lowerer.lowerExprExpecting(args[1], BYTES_U8),
423
+ lowerer.coerceInto(args[0], left, DYN),
424
+ right ? lowerer.coerceInto(args[1], right, DYN) : dynUndefinedExpr(loc),
313
425
  ],
314
426
  type: BOOL,
315
427
  loc,
316
428
  };
317
429
  }
318
430
  if (bi.member === "randomFillSync") {
319
- if (args.length < 1 || args.length > 3) {
431
+ if (args.length < 1 || args.length > 3 || args.some(ts.isSpreadElement)) {
320
432
  lowerer.noLowering(`crypto.randomFillSync with ${args.length} arguments`, expr, "randomFillSync(buffer[, offset[, size]]) is supported");
321
433
  }
322
- const buffer = lowerer.lowerExprExpecting(args[0], BYTES_U8);
323
- const offset = args[1]
324
- ? lowerer.lowerExprExpecting(args[1], F64)
325
- : { kind: "numLit", value: 0, type: F64, loc };
326
- if (args[2]) {
327
- const size = lowerer.lowerExprExpecting(args[2], F64);
434
+ const buffer = lowerer.lowerExpr(args[0]);
435
+ if (buffer.type.kind === "bytes" && cryptoNumberArgs(lowerer, args.slice(1))) {
436
+ // A view returns itself, at its own type.
437
+ const offset = args[1]
438
+ ? lowerer.lowerExprExpecting(args[1], F64)
439
+ : { kind: "numLit", value: 0, type: F64, loc };
440
+ if (args[2]) {
441
+ return {
442
+ kind: "libCall",
443
+ fn: "crypto.randomFillView",
444
+ args: [buffer, offset, lowerer.lowerExprExpecting(args[2], F64)],
445
+ type: buffer.type,
446
+ loc,
447
+ };
448
+ }
328
449
  return {
329
450
  kind: "libCall",
330
- fn: "crypto.randomFill",
331
- args: [buffer, offset, size],
332
- type: BYTES_U8,
451
+ fn: "crypto.randomFillViewRest",
452
+ args: [buffer, offset],
453
+ type: buffer.type,
333
454
  loc,
334
455
  };
335
456
  }
457
+ // ArrayBuffers and other values take Node's checks at run time.
336
458
  return {
337
459
  kind: "libCall",
338
- fn: "crypto.randomFillRest",
339
- args: [buffer, offset],
340
- type: BYTES_U8,
460
+ fn: "crypto.randomFillSyncDyn",
461
+ args: [
462
+ lowerer.coerceInto(args[0], buffer, DYN),
463
+ dynArg(lowerer, args[1], loc),
464
+ dynArg(lowerer, args[2], loc),
465
+ ],
466
+ type: DYN,
467
+ loc,
468
+ };
469
+ }
470
+ if (bi.member === "randomFill") {
471
+ if (args.length < 2 || args.length > 4 || args.some(ts.isSpreadElement)) {
472
+ lowerer.noLowering(`crypto.randomFill with ${args.length} arguments`, expr, "randomFill(buffer[, offset[, size]], callback) is supported");
473
+ }
474
+ const form = { kind: "numLit", value: args.length - 1, type: F64, loc };
475
+ const buffer = lowerer.lowerExpr(args[0]);
476
+ if (buffer.type.kind === "bytes" && cryptoNumberArgs(lowerer, args.slice(1, -1))) {
477
+ const view = buffer.type;
478
+ const offset = args.length >= 3
479
+ ? lowerer.lowerExprExpecting(args[1], F64)
480
+ : { kind: "numLit", value: 0, type: F64, loc };
481
+ const size = args.length === 4
482
+ ? lowerer.lowerExprExpecting(args[2], F64)
483
+ : { kind: "numLit", value: 0, type: F64, loc };
484
+ const callback = errorFirstCallback(lowerer, args[args.length - 1], "crypto.randomFill", (value) => value.kind === "bytes" && value.elem === view.elem, "the buffer's own view");
485
+ return {
486
+ kind: "libCall",
487
+ fn: "crypto.randomFillCb",
488
+ args: [buffer, offset, size, form, callback],
489
+ type: VOID,
490
+ loc,
491
+ };
492
+ }
493
+ const callback = errorFirstCallback(lowerer, args[args.length - 1], "crypto.randomFill", () => false, "unknown-typed");
494
+ return {
495
+ kind: "libCall",
496
+ fn: "crypto.randomFillCbDyn",
497
+ args: [
498
+ lowerer.coerceInto(args[0], buffer, DYN),
499
+ args.length >= 3 ? lowerer.lowerExprExpecting(args[1], DYN) : dynUndefinedExpr(loc),
500
+ args.length === 4 ? lowerer.lowerExprExpecting(args[2], DYN) : dynUndefinedExpr(loc),
501
+ form,
502
+ callback,
503
+ ],
504
+ type: VOID,
341
505
  loc,
342
506
  };
343
507
  }
344
508
  if (bi.member === "randomInt") {
345
- if (args.length !== 1 && args.length !== 2) {
346
- lowerer.noLowering(`crypto.randomInt with ${args.length} arguments`, expr, "the synchronous randomInt(max) and randomInt(min, max) forms are supported");
509
+ if (args.length < 1 || args.length > 3 || args.some(ts.isSpreadElement)) {
510
+ lowerer.noLowering(`crypto.randomInt with ${args.length} arguments`, expr, "randomInt([min, ]max[, callback]) is supported");
347
511
  }
348
- const min = args.length === 1
512
+ const last = args[args.length - 1];
513
+ const lastType = lowerer.mapTypeOf(lowerer.typeOf(last));
514
+ const withCallback = args.length === 3 || (args.length === 2 && lastType?.kind === "func");
515
+ const numbers = withCallback ? args.slice(0, -1) : args;
516
+ const min = numbers.length === 1
349
517
  ? { kind: "numLit", value: 0, type: F64, loc }
350
- : lowerer.lowerExprExpecting(args[0], F64);
351
- const max = lowerer.lowerExprExpecting(args[args.length - 1], F64);
352
- return { kind: "libCall", fn: "crypto.randomInt", args: [min, max], type: F64, loc };
518
+ : lowerer.lowerExprExpecting(numbers[0], F64);
519
+ const max = lowerer.lowerExprExpecting(numbers[numbers.length - 1], F64);
520
+ if (!withCallback) {
521
+ if (numbers.length === 1)
522
+ return { kind: "libCall", fn: "crypto.randomIntMax", args: [max], type: F64, loc };
523
+ return { kind: "libCall", fn: "crypto.randomInt", args: [min, max], type: F64, loc };
524
+ }
525
+ const callback = errorFirstCallback(lowerer, last, "crypto.randomInt", (value) => value.kind === "f64", "number");
526
+ const minGiven = {
527
+ kind: "numLit",
528
+ value: numbers.length === 2 ? 1 : 0,
529
+ type: F64,
530
+ loc,
531
+ };
532
+ return {
533
+ kind: "libCall",
534
+ fn: "crypto.randomIntCb",
535
+ args: [min, max, minGiven, callback],
536
+ type: VOID,
537
+ loc,
538
+ };
539
+ }
540
+ if (bi.member === "randomUUID" && args.length > 0) {
541
+ if (args.length > 1 || args.some(ts.isSpreadElement))
542
+ lowerer.noLowering(`crypto.randomUUID with ${args.length} arguments`, expr, "randomUUID([options]) is supported");
543
+ return {
544
+ kind: "libCall",
545
+ fn: "crypto.randomUUIDOpts",
546
+ args: [dynArg(lowerer, args[0], loc)],
547
+ type: STRING,
548
+ loc,
549
+ };
550
+ }
551
+ if (bi.member === "createSecretKey") {
552
+ if (args.length < 1 || args.length > 2 || args.some(ts.isSpreadElement))
553
+ lowerer.noLowering(`crypto.createSecretKey with ${args.length} arguments`, expr, "createSecretKey(key[, encoding]) is supported");
554
+ return {
555
+ kind: "libCall",
556
+ fn: "crypto.createSecretKey",
557
+ args: [lowerer.lowerExprExpecting(args[0], DYN), dynArg(lowerer, args[1], loc)],
558
+ type: DYN,
559
+ loc,
560
+ };
561
+ }
562
+ if (bi.member === "generateKeySync") {
563
+ if (args.length < 1 || args.length > 2 || args.some(ts.isSpreadElement))
564
+ lowerer.noLowering(`crypto.generateKeySync with ${args.length} arguments`, expr, "generateKeySync(type, options) is supported");
565
+ return {
566
+ kind: "libCall",
567
+ fn: "crypto.generateKeySync",
568
+ args: [lowerer.lowerExprExpecting(args[0], DYN), dynArg(lowerer, args[1], loc)],
569
+ type: DYN,
570
+ loc,
571
+ };
572
+ }
573
+ if (bi.member === "generateKey") {
574
+ if (args.length < 1 || args.length > 3 || args.some(ts.isSpreadElement))
575
+ lowerer.noLowering(`crypto.generateKey with ${args.length} arguments`, expr, "generateKey(type, options, callback) is supported");
576
+ const isFunction = (node) => !!node && lowerer.mapTypeOf(lowerer.typeOf(node))?.kind === "func";
577
+ // Node takes a function in the options position as the callback, and
578
+ // checks the callback before the type and options.
579
+ const optionsNode = args.length === 2 && isFunction(args[1]) ? undefined : args[1];
580
+ const callbackNode = args.length === 2 && isFunction(args[1]) ? args[1] : args[2];
581
+ const callbackType = callbackNode ? lowerer.mapTypeOf(lowerer.typeOf(callbackNode)) : undefined;
582
+ const type = lowerer.lowerExprExpecting(args[0], DYN);
583
+ const options = dynArg(lowerer, optionsNode, loc);
584
+ if (callbackType?.kind !== "func" && callbackType?.kind !== "dyn") {
585
+ const got = callbackNode
586
+ ? lowerer.lowerExprExpecting(callbackNode, DYN)
587
+ : dynUndefinedExpr(loc);
588
+ return {
589
+ kind: "seqExpr",
590
+ stmts: [
591
+ { kind: "exprStmt", expr: type, loc },
592
+ { kind: "exprStmt", expr: options, loc },
593
+ ],
594
+ result: {
595
+ kind: "libCall",
596
+ fn: "error.argTypeThrow",
597
+ args: [
598
+ { kind: "strLit", value: "callback", type: STRING, loc },
599
+ { kind: "strLit", value: "of type function", type: STRING, loc },
600
+ got,
601
+ ],
602
+ type: VOID,
603
+ loc,
604
+ },
605
+ type: VOID,
606
+ loc,
607
+ };
608
+ }
609
+ const callback = errorFirstCallback(lowerer, callbackNode, "crypto.generateKey", () => false, "KeyObject");
610
+ return {
611
+ kind: "libCall",
612
+ fn: "crypto.generateKeyCb",
613
+ args: [type, options, callback],
614
+ type: VOID,
615
+ loc,
616
+ };
617
+ }
618
+ if (bi.member === "randomUUIDv7") {
619
+ if (args.length > 1 || args.some(ts.isSpreadElement))
620
+ lowerer.noLowering(`crypto.randomUUIDv7 with ${args.length} arguments`, expr, "randomUUIDv7([options]) is supported");
621
+ return {
622
+ kind: "libCall",
623
+ fn: "crypto.randomUUIDv7",
624
+ args: [dynArg(lowerer, args[0], loc)],
625
+ type: STRING,
626
+ loc,
627
+ };
353
628
  }
354
629
  if (bi.member === "pbkdf2Sync") {
355
630
  if (args.length !== 5) {
@@ -365,7 +640,7 @@ export function lowerCryptoModuleCall(lowerer, expr, bi, loc) {
365
640
  salt,
366
641
  lowerer.lowerExprExpecting(args[2], F64),
367
642
  lowerer.lowerExprExpecting(args[3], F64),
368
- cryptoAlgorithm(lowerer, args[4], "crypto.pbkdf2Sync"),
643
+ cryptoAlgorithm(lowerer, args[4]),
369
644
  ],
370
645
  type: BYTES_U8,
371
646
  loc,
@@ -406,106 +681,126 @@ export function lowerCryptoHashMethodCall(lowerer, call, access) {
406
681
  const name = access.name.text;
407
682
  const loc = locOf(call);
408
683
  const receiver = () => lowerer.lowerExprExpecting(access.expression, receiverType);
684
+ const hash = receiverType.kind === "cryptoHash";
685
+ const label = hash ? "Hash" : "Hmac";
686
+ if (call.arguments.some(ts.isSpreadElement))
687
+ lowerer.noLowering(`${label}.${name} with spread arguments`, call);
409
688
  if (name === "update") {
410
- if (call.arguments.length < 1 ||
411
- call.arguments.length > 2 ||
412
- call.arguments.some(ts.isSpreadElement)) {
413
- lowerer.noLowering(`${receiverType.kind === "cryptoHash" ? "Hash" : "Hmac"}.update with ${call.arguments.length} arguments`, call, "update(stringOrBuffer[, inputEncoding]) is supported");
689
+ if (call.arguments.length < 1 || call.arguments.length > 2) {
690
+ lowerer.noLowering(`${label}.update with ${call.arguments.length} arguments`, call, "update(data[, inputEncoding]) is supported");
414
691
  }
692
+ const target = receiver();
415
693
  const dataNode = call.arguments[0];
694
+ const encodingNode = call.arguments[1];
416
695
  const dataType = lowerer.mapTypeOf(lowerer.typeOf(dataNode));
417
696
  // Indexed reads can retain optional storage after a nullish fallback
418
697
  // or narrowing. Use the proven argument type through a checked coercion.
419
698
  const data = dataType?.kind === "string" || dataType?.kind === "bytes"
420
699
  ? lowerer.lowerExprExpecting(dataNode, dataType)
421
700
  : lowerer.lowerExpr(dataNode);
422
- const prefix = receiverType.kind === "cryptoHash" ? "crypto.hashUpdate" : "crypto.hmacUpdate";
423
- if (data.type.kind === "bytes" && data.type.elem === "u8") {
424
- if (call.arguments.length !== 1) {
425
- lowerer.noLowering("Hash/Hmac.update with an encoding for Buffer data", call.arguments[1], "input encodings apply only to string data");
426
- }
701
+ const prefix = hash ? "crypto.hashUpdate" : "crypto.hmacUpdate";
702
+ const encodingType = encodingNode ? lowerer.mapTypeOf(lowerer.typeOf(encodingNode)) : undefined;
703
+ if (data.type.kind === "bytes" && encodingNode === undefined) {
427
704
  return {
428
705
  kind: "libCall",
429
706
  fn: `${prefix}Bytes`,
430
- args: [receiver(), data],
707
+ args: [target, cryptoByteView(lowerer, dataNode, data)],
431
708
  type: receiverType,
432
709
  loc,
433
710
  };
434
711
  }
435
712
  if (data.type.kind === "string") {
436
- const encodingNode = call.arguments[1];
437
- if (encodingNode === undefined) {
713
+ const literal = encodingNode ? stringLiteralValues(lowerer.typeOf(encodingNode)) : undefined;
714
+ const utf8 = encodingNode === undefined ||
715
+ (literal?.length === 1 && cryptoEncodingName(literal[0]) === "utf8");
716
+ if (utf8) {
717
+ if (encodingNode)
718
+ lowerer.lowerExprExpecting(encodingNode, STRING);
438
719
  return {
439
720
  kind: "libCall",
440
721
  fn: `${prefix}Str`,
441
- args: [receiver(), data],
722
+ args: [target, data],
442
723
  type: receiverType,
443
724
  loc,
444
725
  };
445
726
  }
446
- const encodingType = lowerer.typeOf(encodingNode);
447
- if (!encodingType.isStringLiteralType() ||
448
- !["utf8", "utf-8", "hex", "base64"].includes(encodingType.value)) {
449
- lowerer.noLowering("Hash/Hmac.update with this input encoding", encodingNode, "utf8, hex, and base64 string inputs are supported");
450
- }
451
- if (encodingType.value === "utf8" || encodingType.value === "utf-8") {
452
- lowerer.lowerExprExpecting(encodingNode, STRING);
727
+ if (encodingType?.kind === "string") {
453
728
  return {
454
729
  kind: "libCall",
455
- fn: `${prefix}Str`,
456
- args: [receiver(), data],
730
+ fn: `${prefix}Enc`,
731
+ args: [target, data, lowerer.lowerExprExpecting(encodingNode, STRING)],
457
732
  type: receiverType,
458
733
  loc,
459
734
  };
460
735
  }
461
- const encoded = {
736
+ }
737
+ // Other data and encodings take Node's checks at run time: views and
738
+ // strings hash, anything else throws ERR_INVALID_ARG_TYPE.
739
+ return {
740
+ kind: "libCall",
741
+ fn: `${prefix}Dyn`,
742
+ args: [target, lowerer.coerceInto(dataNode, data, DYN), dynArg(lowerer, encodingNode, loc)],
743
+ type: receiverType,
744
+ loc,
745
+ };
746
+ }
747
+ if (name === "digest") {
748
+ if (call.arguments.length > 1) {
749
+ lowerer.noLowering(`${label}.digest with ${call.arguments.length} arguments`, call, "digest([outputEncoding]) is supported");
750
+ }
751
+ const encodingNode = call.arguments[0];
752
+ if (encodingNode === undefined) {
753
+ return {
462
754
  kind: "libCall",
463
- fn: "buffer.fromStr",
464
- args: [data, lowerer.lowerExprExpecting(encodingNode, STRING)],
755
+ fn: hash ? "crypto.hashDigestBuffer" : "crypto.hmacDigestBuffer",
756
+ args: [receiver()],
465
757
  type: BYTES_U8,
466
758
  loc,
467
759
  };
760
+ }
761
+ if (isStringDigestEncoding(lowerer, encodingNode, false)) {
468
762
  return {
469
763
  kind: "libCall",
470
- fn: `${prefix}Bytes`,
471
- args: [receiver(), encoded],
472
- type: receiverType,
764
+ fn: hash ? "crypto.hashDigestString" : "crypto.hmacDigestString",
765
+ args: [receiver(), lowerer.lowerExprExpecting(encodingNode, STRING)],
766
+ type: STRING,
473
767
  loc,
474
768
  };
475
769
  }
476
- lowerer.noLowering(`Hash/Hmac.update of '${lowerer.fmt(data.type)}' values`, dataNode, "string and Buffer/Uint8Array inputs are supported");
477
- }
478
- if (name === "digest") {
479
- if (call.arguments.length > 1 || call.arguments.some(ts.isSpreadElement)) {
480
- lowerer.noLowering(`${receiverType.kind === "cryptoHash" ? "Hash" : "Hmac"}.digest with ${call.arguments.length} arguments`, call, 'digest() and digest("hex" | "base64") are supported');
770
+ // Node returns a Buffer for a falsy or unknown encoding. A literal
771
+ // whose Buffer result the declared string type cannot hold is refused.
772
+ const literal = stringLiteralValues(lowerer.typeOf(encodingNode));
773
+ const declared = lowerer.mapTypeOf(lowerer.typeOf(call));
774
+ if (literal && declared?.kind === "string") {
775
+ lowerer.noLowering(`${label}.digest with encoding '${literal.join("' | '")}'`, encodingNode, "Node returns a Buffer for this encoding, and the call's declared type is string");
481
776
  }
482
- if (call.arguments.length === 0) {
777
+ return {
778
+ kind: "libCall",
779
+ fn: hash ? "crypto.hashDigestDyn" : "crypto.hmacDigestDyn",
780
+ args: [receiver(), lowerer.lowerExprExpecting(encodingNode, DYN)],
781
+ type: DYN,
782
+ loc,
783
+ };
784
+ }
785
+ if (name === "copy" && hash) {
786
+ if (call.arguments.length > 1)
787
+ lowerer.noLowering(`Hash.copy with ${call.arguments.length} arguments`, call, "copy([options]) is supported");
788
+ if (call.arguments.length === 0)
483
789
  return {
484
790
  kind: "libCall",
485
- fn: receiverType.kind === "cryptoHash"
486
- ? "crypto.hashDigestBuffer"
487
- : "crypto.hmacDigestBuffer",
791
+ fn: "crypto.hashCopy",
488
792
  args: [receiver()],
489
- type: BYTES_U8,
793
+ type: CRYPTOHASH_T,
490
794
  loc,
491
795
  };
492
- }
493
796
  return {
494
797
  kind: "libCall",
495
- fn: receiverType.kind === "cryptoHash" ? "crypto.hashDigestString" : "crypto.hmacDigestString",
496
- args: [
497
- receiver(),
498
- cryptoEncoding(lowerer, call.arguments[0], `${receiverType.kind === "cryptoHash" ? "Hash" : "Hmac"}.digest`),
499
- ],
500
- type: STRING,
798
+ fn: "crypto.hashCopyOpts",
799
+ args: [receiver(), lowerer.lowerExprExpecting(call.arguments[0], DYN)],
800
+ type: CRYPTOHASH_T,
501
801
  loc,
502
802
  };
503
803
  }
504
- if (name === "copy" && receiverType.kind === "cryptoHash") {
505
- if (call.arguments.length !== 0)
506
- lowerer.noLowering(`Hash.copy with ${call.arguments.length} arguments`, call, "copy() without options is supported");
507
- return { kind: "libCall", fn: "crypto.hashCopy", args: [receiver()], type: CRYPTOHASH_T, loc };
508
- }
509
804
  lowerer.noLowering(`${receiverType.kind === "cryptoHash" ? "Hash" : "Hmac"}.${name}`, call, receiverType.kind === "cryptoHash"
510
805
  ? "update(), digest(), and copy() are supported"
511
806
  : "update() and digest() are supported", lowerer.checker.getSymbolAtLocation(access.name));