@scriptc/compiler 0.3.2 → 0.3.4

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 (454) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +1202 -64
  2. package/dist/backend/cycle-analysis.js +6 -1
  3. package/dist/backend/cycle-analysis.js.map +1 -1
  4. package/dist/backend/cycle-mutability.d.ts +5 -0
  5. package/dist/backend/cycle-mutability.js +62 -3
  6. package/dist/backend/cycle-mutability.js.map +1 -1
  7. package/dist/backend/executable-features.js +1 -0
  8. package/dist/backend/executable-features.js.map +1 -1
  9. package/dist/backend/library-pack.js +1 -0
  10. package/dist/backend/library-pack.js.map +1 -1
  11. package/dist/backend/llvm/alloc.js +24 -10
  12. package/dist/backend/llvm/alloc.js.map +1 -1
  13. package/dist/backend/llvm/alloc.test.js +47 -1
  14. package/dist/backend/llvm/alloc.test.js.map +1 -1
  15. package/dist/backend/llvm/array-search.d.ts +8 -0
  16. package/dist/backend/llvm/array-search.js +52 -0
  17. package/dist/backend/llvm/array-search.js.map +1 -0
  18. package/dist/backend/llvm/array-search.test.d.ts +1 -0
  19. package/dist/backend/llvm/array-search.test.js +72 -0
  20. package/dist/backend/llvm/array-search.test.js.map +1 -0
  21. package/dist/backend/llvm/call-lifetimes.d.ts +12 -1
  22. package/dist/backend/llvm/call-lifetimes.js +41 -11
  23. package/dist/backend/llvm/call-lifetimes.js.map +1 -1
  24. package/dist/backend/llvm/call-lifetimes.test.js +85 -1
  25. package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
  26. package/dist/backend/llvm/classes.js +87 -36
  27. package/dist/backend/llvm/classes.js.map +1 -1
  28. package/dist/backend/llvm/common.d.ts +6 -1
  29. package/dist/backend/llvm/common.js +8 -1
  30. package/dist/backend/llvm/common.js.map +1 -1
  31. package/dist/backend/llvm/dense-array-access.d.ts +5 -0
  32. package/dist/backend/llvm/dense-array-access.js +3 -3
  33. package/dist/backend/llvm/dense-array-access.js.map +1 -1
  34. package/dist/backend/llvm/dyn.d.ts +44 -1
  35. package/dist/backend/llvm/dyn.js +251 -36
  36. package/dist/backend/llvm/dyn.js.map +1 -1
  37. package/dist/backend/llvm/emitter.d.ts +77 -14
  38. package/dist/backend/llvm/emitter.js +461 -108
  39. package/dist/backend/llvm/emitter.js.map +1 -1
  40. package/dist/backend/llvm/emitter.test.js +26 -3
  41. package/dist/backend/llvm/emitter.test.js.map +1 -1
  42. package/dist/backend/llvm/expr-async.js +52 -1
  43. package/dist/backend/llvm/expr-async.js.map +1 -1
  44. package/dist/backend/llvm/expr-bytes.d.ts +9 -0
  45. package/dist/backend/llvm/expr-bytes.js +169 -63
  46. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  47. package/dist/backend/llvm/expr-callbacks.js +16 -2
  48. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  49. package/dist/backend/llvm/expr-calls.d.ts +3 -1
  50. package/dist/backend/llvm/expr-calls.js +57 -2
  51. package/dist/backend/llvm/expr-calls.js.map +1 -1
  52. package/dist/backend/llvm/expr-containers.js +57 -19
  53. package/dist/backend/llvm/expr-containers.js.map +1 -1
  54. package/dist/backend/llvm/expr-dynamic.js +19 -8
  55. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  56. package/dist/backend/llvm/expr-primitives.js +28 -30
  57. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  58. package/dist/backend/llvm/expr-records.js +8 -4
  59. package/dist/backend/llvm/expr-records.js.map +1 -1
  60. package/dist/backend/llvm/expr-stream-bridges.js +35 -32
  61. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  62. package/dist/backend/llvm/expr-stream-callbacks.d.ts +13 -2
  63. package/dist/backend/llvm/expr-stream-callbacks.js +80 -5
  64. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  65. package/dist/backend/llvm/inline-unions.d.ts +48 -0
  66. package/dist/backend/llvm/inline-unions.js +134 -0
  67. package/dist/backend/llvm/inline-unions.js.map +1 -0
  68. package/dist/backend/llvm/inline-unions.test.d.ts +1 -0
  69. package/dist/backend/llvm/inline-unions.test.js +124 -0
  70. package/dist/backend/llvm/inline-unions.test.js.map +1 -0
  71. package/dist/backend/llvm/integer-remainder.d.ts +28 -5
  72. package/dist/backend/llvm/integer-remainder.js +80 -9
  73. package/dist/backend/llvm/integer-remainder.js.map +1 -1
  74. package/dist/backend/llvm/intern-tables.test.d.ts +1 -0
  75. package/dist/backend/llvm/intern-tables.test.js +77 -0
  76. package/dist/backend/llvm/intern-tables.test.js.map +1 -0
  77. package/dist/backend/llvm/lib-datagram.js +10 -0
  78. package/dist/backend/llvm/lib-datagram.js.map +1 -1
  79. package/dist/backend/llvm/lib-dispatch.js +255 -29
  80. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  81. package/dist/backend/llvm/lib-filesystem.js +176 -7
  82. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  83. package/dist/backend/llvm/lib-network.js +25 -6
  84. package/dist/backend/llvm/lib-network.js.map +1 -1
  85. package/dist/backend/llvm/lib-process.js +2 -2
  86. package/dist/backend/llvm/lib-process.js.map +1 -1
  87. package/dist/backend/llvm/lib-shared.d.ts +5 -0
  88. package/dist/backend/llvm/lib-shared.js +212 -1
  89. package/dist/backend/llvm/lib-shared.js.map +1 -1
  90. package/dist/backend/llvm/lib-stream.js +184 -0
  91. package/dist/backend/llvm/lib-stream.js.map +1 -1
  92. package/dist/backend/llvm/lib-test.js +9 -0
  93. package/dist/backend/llvm/lib-test.js.map +1 -1
  94. package/dist/backend/llvm/local-array-reads.js +7 -3
  95. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  96. package/dist/backend/llvm/local-array-reads.test.js +6 -3
  97. package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
  98. package/dist/backend/llvm/local-union-storage.d.ts +2 -0
  99. package/dist/backend/llvm/local-union-storage.js +5 -0
  100. package/dist/backend/llvm/local-union-storage.js.map +1 -1
  101. package/dist/backend/llvm/local-union-storage.test.js +1 -0
  102. package/dist/backend/llvm/local-union-storage.test.js.map +1 -1
  103. package/dist/backend/llvm/loop-array-borrows.d.ts +8 -2
  104. package/dist/backend/llvm/loop-array-borrows.js +93 -13
  105. package/dist/backend/llvm/loop-array-borrows.js.map +1 -1
  106. package/dist/backend/llvm/map-number-lookup.d.ts +24 -0
  107. package/dist/backend/llvm/map-number-lookup.js +88 -0
  108. package/dist/backend/llvm/map-number-lookup.js.map +1 -1
  109. package/dist/backend/llvm/map-number-lookup.test.d.ts +1 -0
  110. package/dist/backend/llvm/map-number-lookup.test.js +158 -0
  111. package/dist/backend/llvm/map-number-lookup.test.js.map +1 -0
  112. package/dist/backend/llvm/map-read-lifetimes.d.ts +9 -0
  113. package/dist/backend/llvm/map-read-lifetimes.js +90 -1
  114. package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
  115. package/dist/backend/llvm/map-read-lifetimes.test.js +129 -1
  116. package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -1
  117. package/dist/backend/llvm/publish.d.ts +9 -0
  118. package/dist/backend/llvm/publish.js +25 -4
  119. package/dist/backend/llvm/publish.js.map +1 -1
  120. package/dist/backend/llvm/record-results.d.ts +8 -5
  121. package/dist/backend/llvm/record-results.js +20 -12
  122. package/dist/backend/llvm/record-results.js.map +1 -1
  123. package/dist/backend/llvm/reference-effects.js +13 -0
  124. package/dist/backend/llvm/reference-effects.js.map +1 -1
  125. package/dist/backend/llvm/reference-writes.js +19 -2
  126. package/dist/backend/llvm/reference-writes.js.map +1 -1
  127. package/dist/backend/llvm/regions.d.ts +5 -1
  128. package/dist/backend/llvm/regions.js +24 -10
  129. package/dist/backend/llvm/regions.js.map +1 -1
  130. package/dist/backend/llvm/serialized-ir-emission.test.js +2 -0
  131. package/dist/backend/llvm/serialized-ir-emission.test.js.map +1 -1
  132. package/dist/backend/llvm/shapes.d.ts +56 -10
  133. package/dist/backend/llvm/shapes.js +178 -39
  134. package/dist/backend/llvm/shapes.js.map +1 -1
  135. package/dist/backend/llvm/shapes.test.js +61 -3
  136. package/dist/backend/llvm/shapes.test.js.map +1 -1
  137. package/dist/backend/llvm/stack-objects.js +16 -4
  138. package/dist/backend/llvm/stack-objects.js.map +1 -1
  139. package/dist/backend/llvm/stack-objects.test.js +3 -0
  140. package/dist/backend/llvm/stack-objects.test.js.map +1 -1
  141. package/dist/backend/llvm/string-reads.js +2 -2
  142. package/dist/backend/llvm/string-reads.js.map +1 -1
  143. package/dist/backend/llvm/string-slices.js +2 -2
  144. package/dist/backend/llvm/string-slices.js.map +1 -1
  145. package/dist/backend/llvm/walkers.d.ts +11 -0
  146. package/dist/backend/llvm/walkers.js +106 -10
  147. package/dist/backend/llvm/walkers.js.map +1 -1
  148. package/dist/backend/may-throw.js +13 -4
  149. package/dist/backend/may-throw.js.map +1 -1
  150. package/dist/backend/native/contracts.d.ts +5 -2
  151. package/dist/backend/native/executable.js +27 -8
  152. package/dist/backend/native/executable.js.map +1 -1
  153. package/dist/backend/native/runtime-inputs.d.ts +1 -1
  154. package/dist/backend/native/runtime-inputs.js +2 -0
  155. package/dist/backend/native/runtime-inputs.js.map +1 -1
  156. package/dist/backend/native-codegen-core.d.ts +4 -4
  157. package/dist/backend/native-codegen-core.js +4 -6
  158. package/dist/backend/native-codegen-core.js.map +1 -1
  159. package/dist/backend/native-codegen.test.js +7 -8
  160. package/dist/backend/native-codegen.test.js.map +1 -1
  161. package/dist/backend/native-link-info-core.d.ts +3 -0
  162. package/dist/backend/native-link-info-core.js.map +1 -1
  163. package/dist/backend/native-toolchain.test.js +1 -1
  164. package/dist/backend/native-toolchain.test.js.map +1 -1
  165. package/dist/backend/publication.js +3 -1
  166. package/dist/backend/publication.js.map +1 -1
  167. package/dist/backend/runtime-abi.d.ts +2 -2
  168. package/dist/backend/runtime-abi.js +2 -2
  169. package/dist/backend/runtime-pack-targets.test.js +2 -1
  170. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  171. package/dist/backend/runtime-pack.test.js +2 -1
  172. package/dist/backend/runtime-pack.test.js.map +1 -1
  173. package/dist/backend/target-diagnostics.js +11 -1
  174. package/dist/backend/target-diagnostics.js.map +1 -1
  175. package/dist/backend/target-diagnostics.test.js +4 -1
  176. package/dist/backend/target-diagnostics.test.js.map +1 -1
  177. package/dist/backend/warm-cache.js +1 -0
  178. package/dist/backend/warm-cache.js.map +1 -1
  179. package/dist/compat/fetch-profile.js +4 -4
  180. package/dist/compat/fetch-profile.js.map +1 -1
  181. package/dist/contracts/check.js +2 -0
  182. package/dist/contracts/check.js.map +1 -1
  183. package/dist/coverage/report.js +1 -1
  184. package/dist/coverage/report.js.map +1 -1
  185. package/dist/diagnostics/diagnostic.d.ts +6 -5
  186. package/dist/diagnostics/diagnostic.js +7 -6
  187. package/dist/diagnostics/diagnostic.js.map +1 -1
  188. package/dist/executable/executable-cache.d.ts +1 -0
  189. package/dist/executable/executable-cache.js +1 -0
  190. package/dist/executable/executable-cache.js.map +1 -1
  191. package/dist/executable/executable-cache.test.js +1 -0
  192. package/dist/executable/executable-cache.test.js.map +1 -1
  193. package/dist/frontend/builtin-modules.d.ts +1 -1
  194. package/dist/frontend/builtin-modules.js +1 -0
  195. package/dist/frontend/builtin-modules.js.map +1 -1
  196. package/dist/frontend/comptime-node.js +2 -2
  197. package/dist/frontend/comptime-node.js.map +1 -1
  198. package/dist/frontend/experimental-import.d.ts +5 -1
  199. package/dist/frontend/experimental-import.js +28 -3
  200. package/dist/frontend/experimental-import.js.map +1 -1
  201. package/dist/frontend/lowering/assert-instances.d.ts +38 -0
  202. package/dist/frontend/lowering/assert-instances.js +269 -0
  203. package/dist/frontend/lowering/assert-instances.js.map +1 -0
  204. package/dist/frontend/lowering/binding-analysis.d.ts +1 -1
  205. package/dist/frontend/lowering/binding-analysis.js +1 -1
  206. package/dist/frontend/lowering/builtins/arguments.d.ts +4 -0
  207. package/dist/frontend/lowering/builtins/arguments.js +8 -4
  208. package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
  209. package/dist/frontend/lowering/builtins/blob.d.ts +20 -0
  210. package/dist/frontend/lowering/builtins/blob.js +167 -0
  211. package/dist/frontend/lowering/builtins/blob.js.map +1 -0
  212. package/dist/frontend/lowering/builtins/child-process-async.d.ts +2 -2
  213. package/dist/frontend/lowering/builtins/child-process-async.js +2 -2
  214. package/dist/frontend/lowering/builtins/child-process-methods.js +1 -1
  215. package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
  216. package/dist/frontend/lowering/builtins/child-process-sync.js +1 -1
  217. package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -1
  218. package/dist/frontend/lowering/builtins/compression.d.ts +18 -0
  219. package/dist/frontend/lowering/builtins/compression.js +178 -4
  220. package/dist/frontend/lowering/builtins/compression.js.map +1 -1
  221. package/dist/frontend/lowering/builtins/constants.js +7 -2
  222. package/dist/frontend/lowering/builtins/constants.js.map +1 -1
  223. package/dist/frontend/lowering/builtins/crypto.d.ts +6 -0
  224. package/dist/frontend/lowering/builtins/crypto.js +526 -121
  225. package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
  226. package/dist/frontend/lowering/builtins/errors.js +23 -0
  227. package/dist/frontend/lowering/builtins/errors.js.map +1 -1
  228. package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +10 -0
  229. package/dist/frontend/lowering/builtins/filesystem-calls.js +89 -1
  230. package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
  231. package/dist/frontend/lowering/builtins/filesystem.d.ts +16 -7
  232. package/dist/frontend/lowering/builtins/filesystem.js +97 -15
  233. package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
  234. package/dist/frontend/lowering/builtins/fs-glob.d.ts +23 -0
  235. package/dist/frontend/lowering/builtins/fs-glob.js +224 -0
  236. package/dist/frontend/lowering/builtins/fs-glob.js.map +1 -0
  237. package/dist/frontend/lowering/builtins/key-object.d.ts +13 -0
  238. package/dist/frontend/lowering/builtins/key-object.js +56 -0
  239. package/dist/frontend/lowering/builtins/key-object.js.map +1 -0
  240. package/dist/frontend/lowering/builtins/module-calls.js +44 -11
  241. package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
  242. package/dist/frontend/lowering/builtins/performance.d.ts +25 -3
  243. package/dist/frontend/lowering/builtins/performance.js +340 -5
  244. package/dist/frontend/lowering/builtins/performance.js.map +1 -1
  245. package/dist/frontend/lowering/builtins/process.d.ts +2 -2
  246. package/dist/frontend/lowering/builtins/process.js +107 -14
  247. package/dist/frontend/lowering/builtins/process.js.map +1 -1
  248. package/dist/frontend/lowering/builtins/properties.d.ts +0 -7
  249. package/dist/frontend/lowering/builtins/properties.js +39 -11
  250. package/dist/frontend/lowering/builtins/properties.js.map +1 -1
  251. package/dist/frontend/lowering/builtins/readline.d.ts +23 -8
  252. package/dist/frontend/lowering/builtins/readline.js +266 -90
  253. package/dist/frontend/lowering/builtins/readline.js.map +1 -1
  254. package/dist/frontend/lowering/builtins/timers.d.ts +3 -0
  255. package/dist/frontend/lowering/builtins/timers.js +109 -23
  256. package/dist/frontend/lowering/builtins/timers.js.map +1 -1
  257. package/dist/frontend/lowering/builtins/url.d.ts +8 -0
  258. package/dist/frontend/lowering/builtins/url.js +36 -0
  259. package/dist/frontend/lowering/builtins/url.js.map +1 -1
  260. package/dist/frontend/lowering/call-arguments.js +1 -1
  261. package/dist/frontend/lowering/call-arguments.js.map +1 -1
  262. package/dist/frontend/lowering/call-signatures.js +26 -2
  263. package/dist/frontend/lowering/call-signatures.js.map +1 -1
  264. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +2 -0
  265. package/dist/frontend/lowering/class-dynamic-dispatch.js +171 -13
  266. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  267. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +1 -0
  268. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
  269. package/dist/frontend/lowering/class-protocol-dispatch.d.ts +45 -0
  270. package/dist/frontend/lowering/class-protocol-dispatch.js +516 -0
  271. package/dist/frontend/lowering/class-protocol-dispatch.js.map +1 -0
  272. package/dist/frontend/lowering/coercions/structural-plans.js +2 -1
  273. package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
  274. package/dist/frontend/lowering/coercions/structural.js +3 -3
  275. package/dist/frontend/lowering/coercions/structural.js.map +1 -1
  276. package/dist/frontend/lowering/collation-repertoire.js +6 -5
  277. package/dist/frontend/lowering/collation-repertoire.js.map +1 -1
  278. package/dist/frontend/lowering/containers/array-callbacks.js +4 -7
  279. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  280. package/dist/frontend/lowering/containers/array-methods.d.ts +0 -7
  281. package/dist/frontend/lowering/containers/array-methods.js +43 -2
  282. package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
  283. package/dist/frontend/lowering/containers/bytes.js +38 -26
  284. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  285. package/dist/frontend/lowering/containers/for-of.d.ts +1 -1
  286. package/dist/frontend/lowering/containers/for-of.js +5 -1
  287. package/dist/frontend/lowering/containers/for-of.js.map +1 -1
  288. package/dist/frontend/lowering/containers/indexed-objects.js +1 -1
  289. package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
  290. package/dist/frontend/lowering/crypto-tables.d.ts +3 -3
  291. package/dist/frontend/lowering/crypto-tables.js +77 -12
  292. package/dist/frontend/lowering/crypto-tables.js.map +1 -1
  293. package/dist/frontend/lowering/expressions/nullish-assignment.js +10 -0
  294. package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
  295. package/dist/frontend/lowering/expressions/object-literals.js +16 -12
  296. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  297. package/dist/frontend/lowering/generic-functions.d.ts +2 -2
  298. package/dist/frontend/lowering/generic-functions.js +2 -2
  299. package/dist/frontend/lowering/generic-functions.js.map +1 -1
  300. package/dist/frontend/lowering/http2-constants.js +1 -1
  301. package/dist/frontend/lowering/intern-tables.d.ts +13 -0
  302. package/dist/frontend/lowering/intern-tables.js +536 -0
  303. package/dist/frontend/lowering/intern-tables.js.map +1 -0
  304. package/dist/frontend/lowering/lower-array-sort.d.ts +12 -1
  305. package/dist/frontend/lowering/lower-array-sort.js +561 -191
  306. package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
  307. package/dist/frontend/lowering/lower-array-sort.test.js +4 -2
  308. package/dist/frontend/lowering/lower-array-sort.test.js.map +1 -1
  309. package/dist/frontend/lowering/lower-assert.js +702 -63
  310. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  311. package/dist/frontend/lowering/lower-async-iteration.d.ts +6 -3
  312. package/dist/frontend/lowering/lower-async-iteration.js +259 -4
  313. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
  314. package/dist/frontend/lowering/lower-calls.js +118 -12
  315. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  316. package/dist/frontend/lowering/lower-classes.d.ts +11 -2
  317. package/dist/frontend/lowering/lower-classes.js +76 -9
  318. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  319. package/dist/frontend/lowering/lower-comptime.d.ts +1 -1
  320. package/dist/frontend/lowering/lower-comptime.js +4 -4
  321. package/dist/frontend/lowering/lower-comptime.js.map +1 -1
  322. package/dist/frontend/lowering/lower-dgram.js +77 -52
  323. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  324. package/dist/frontend/lowering/lower-event-target.d.ts +63 -0
  325. package/dist/frontend/lowering/lower-event-target.js +362 -0
  326. package/dist/frontend/lowering/lower-event-target.js.map +1 -0
  327. package/dist/frontend/lowering/lower-expando.js +2 -2
  328. package/dist/frontend/lowering/lower-exprs.js +124 -22
  329. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  330. package/dist/frontend/lowering/lower-inspect.d.ts +6 -0
  331. package/dist/frontend/lowering/lower-inspect.js +240 -49
  332. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  333. package/dist/frontend/lowering/lower-mixins.js +1 -1
  334. package/dist/frontend/lowering/lower-mock.d.ts +11 -0
  335. package/dist/frontend/lowering/lower-mock.js +504 -0
  336. package/dist/frontend/lowering/lower-mock.js.map +1 -0
  337. package/dist/frontend/lowering/lower-modules.d.ts +1 -1
  338. package/dist/frontend/lowering/lower-modules.js +14 -3
  339. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  340. package/dist/frontend/lowering/lower-namespaces.d.ts +2 -2
  341. package/dist/frontend/lowering/lower-namespaces.js +2 -2
  342. package/dist/frontend/lowering/lower-server.d.ts +3 -0
  343. package/dist/frontend/lowering/lower-server.js +419 -44
  344. package/dist/frontend/lowering/lower-server.js.map +1 -1
  345. package/dist/frontend/lowering/lower-stdlib.d.ts +7 -1
  346. package/dist/frontend/lowering/lower-stdlib.js +10 -3
  347. package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
  348. package/dist/frontend/lowering/lower-stmts.d.ts +2 -2
  349. package/dist/frontend/lowering/lower-stmts.js +69 -14
  350. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  351. package/dist/frontend/lowering/lower-stream.d.ts +10 -6
  352. package/dist/frontend/lowering/lower-stream.js +1020 -49
  353. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  354. package/dist/frontend/lowering/lower-test.js +86 -8
  355. package/dist/frontend/lowering/lower-test.js.map +1 -1
  356. package/dist/frontend/lowering/lower-timers.js +1 -1
  357. package/dist/frontend/lowering/lowerer.d.ts +45 -5
  358. package/dist/frontend/lowering/lowerer.js +317 -48
  359. package/dist/frontend/lowering/lowerer.js.map +1 -1
  360. package/dist/frontend/lowering/native-ffi.js +2 -2
  361. package/dist/frontend/lowering/native-ffi.js.map +1 -1
  362. package/dist/frontend/lowering/pairs-snapshot.d.ts +6 -0
  363. package/dist/frontend/lowering/pairs-snapshot.js +49 -0
  364. package/dist/frontend/lowering/pairs-snapshot.js.map +1 -1
  365. package/dist/frontend/lowering/runtime-optional-records.d.ts +115 -0
  366. package/dist/frontend/lowering/runtime-optional-records.js +715 -0
  367. package/dist/frontend/lowering/runtime-optional-records.js.map +1 -0
  368. package/dist/frontend/lowering/runtime-optional-records.test.d.ts +1 -0
  369. package/dist/frontend/lowering/runtime-optional-records.test.js +175 -0
  370. package/dist/frontend/lowering/runtime-optional-records.test.js.map +1 -0
  371. package/dist/frontend/lowering/surfaces.d.ts +11 -3
  372. package/dist/frontend/lowering/surfaces.js +334 -37
  373. package/dist/frontend/lowering/surfaces.js.map +1 -1
  374. package/dist/frontend/lowering/zlib-constants.d.ts +1 -0
  375. package/dist/frontend/lowering/zlib-constants.js +181 -0
  376. package/dist/frontend/lowering/zlib-constants.js.map +1 -0
  377. package/dist/frontend/mock-shapes.d.ts +10 -0
  378. package/dist/frontend/mock-shapes.js +76 -0
  379. package/dist/frontend/mock-shapes.js.map +1 -0
  380. package/dist/frontend/module-syntax.d.ts +1 -1
  381. package/dist/frontend/module-syntax.js +1 -1
  382. package/dist/frontend/npm-static-prune.js +1 -1
  383. package/dist/frontend/npm-static-prune.js.map +1 -1
  384. package/dist/frontend/npm-static-rewrite-syntax.js +4 -3
  385. package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
  386. package/dist/frontend/pipeline.js +6 -4
  387. package/dist/frontend/pipeline.js.map +1 -1
  388. package/dist/frontend/program.d.ts +3 -3
  389. package/dist/frontend/program.js +25 -18
  390. package/dist/frontend/program.js.map +1 -1
  391. package/dist/frontend/resolve.d.ts +4 -0
  392. package/dist/frontend/resolve.js +15 -1
  393. package/dist/frontend/resolve.js.map +1 -1
  394. package/dist/frontend/ts7/adapter.js +1 -1
  395. package/dist/frontend/ts7/ast-bytes.d.ts +1 -1
  396. package/dist/frontend/ts7/ast-bytes.js +1 -1
  397. package/dist/frontend/ts7/semantic-json.d.ts +1 -1
  398. package/dist/frontend/ts7/semantic-json.js +1 -1
  399. package/dist/frontend/ts7/semantic-json.js.map +1 -1
  400. package/dist/frontend/ts7/world-check.js +1 -1
  401. package/dist/frontend/tsc-codes.js +3 -2
  402. package/dist/frontend/tsc-codes.js.map +1 -1
  403. package/dist/frontend/type-mapper.d.ts +21 -1
  404. package/dist/frontend/type-mapper.js +245 -27
  405. package/dist/frontend/type-mapper.js.map +1 -1
  406. package/dist/index.js +7 -5
  407. package/dist/index.js.map +1 -1
  408. package/dist/ir/analysis.d.ts +12 -6
  409. package/dist/ir/analysis.js +26 -10
  410. package/dist/ir/analysis.js.map +1 -1
  411. package/dist/ir/analysis.test.js +15 -3
  412. package/dist/ir/analysis.test.js.map +1 -1
  413. package/dist/ir/builtin-effects.js +115 -0
  414. package/dist/ir/builtin-effects.js.map +1 -1
  415. package/dist/ir/builtin-signatures.d.ts +1 -1
  416. package/dist/ir/builtin-signatures.js +438 -46
  417. package/dist/ir/builtin-signatures.js.map +1 -1
  418. package/dist/ir/int32-slots.js +1 -0
  419. package/dist/ir/int32-slots.js.map +1 -1
  420. package/dist/ir/ir.d.ts +84 -17
  421. package/dist/ir/ir.js +54 -1
  422. package/dist/ir/ir.js.map +1 -1
  423. package/dist/ir/runtime-features.d.ts +1 -0
  424. package/dist/ir/runtime-features.js +111 -7
  425. package/dist/ir/runtime-features.js.map +1 -1
  426. package/dist/ir/serialize.js +1 -1
  427. package/dist/ir/serialize.js.map +1 -1
  428. package/dist/ir/traverse.js +1 -0
  429. package/dist/ir/traverse.js.map +1 -1
  430. package/dist/ir/validate.js +295 -14
  431. package/dist/ir/validate.js.map +1 -1
  432. package/dist/ir/validate.test.js +60 -0
  433. package/dist/ir/validate.test.js.map +1 -1
  434. package/dist/library/fence-eval.d.ts +1 -1
  435. package/dist/library/fence-eval.js +5 -4
  436. package/dist/library/fence-eval.js.map +1 -1
  437. package/dist/library/ir-policy.js +11 -4
  438. package/dist/library/ir-policy.js.map +1 -1
  439. package/dist/library/library-profile.js +13 -13
  440. package/dist/library/library-profile.js.map +1 -1
  441. package/dist/library/prepare.js +1 -1
  442. package/dist/library/prepare.js.map +1 -1
  443. package/dist/library/sidecar.js +3 -3
  444. package/dist/library/sidecar.js.map +1 -1
  445. package/dist/native/cli.js +1 -0
  446. package/dist/native/cli.js.map +1 -1
  447. package/dist/native/compiler.js +1 -3
  448. package/dist/native/compiler.js.map +1 -1
  449. package/dist/native/prepare.js +4 -2
  450. package/dist/native/prepare.js.map +1 -1
  451. package/dist/native/sanitizer.test.js +1 -0
  452. package/dist/native/sanitizer.test.js.map +1 -1
  453. package/package.json +20 -20
  454. package/surface-manifest.json +1279 -221
@@ -1,8 +1,10 @@
1
- import { lowerBuiltinByteInput, errorFirstBytesCallback } from "./arguments.js";
2
- import { dynUndefinedExpr } from "../../../ir/build.js";
1
+ import { lowerBuiltinByteInput, errorFirstBytesCallback, errorFirstCallback } from "./arguments.js";
2
+ import { isKeyObjectValue } from "./key-object.js";
3
+ import { boolLit, dynUndefinedExpr, varRef } from "../../../ir/build.js";
3
4
  import * as ts from "../../ts7/adapter.js";
4
5
  import { own } from "../lowerer.js";
5
6
  import { locOf } from "../../program.js";
7
+ import { CIPHER_TYPE_NAMES } from "../../type-mapper.js";
6
8
  import { CRYPTO_CIPHERS, CRYPTO_CURVES, CRYPTO_HASHES } from "../crypto-tables.js";
7
9
  import { BOOL, BYTES_U8, CRYPTOHASH_T, CRYPTOHMAC_T, DYN, F64, STRING, VOID, arrayOf, } from "../../../ir/ir.js";
8
10
  /** The composed crypto pattern: `randomBytes(n).toString(enc)` lowers
@@ -95,7 +97,7 @@ function lowerHashDigestChain(lowerer, call, access) {
95
97
  const dataNode = updateCall.arguments[0];
96
98
  const dataIr = lowerer.mapTypeOf(lowerer.typeOf(dataNode));
97
99
  if (dataIr?.kind === "bytes") {
98
- const data = lowerer.lowerExpr(dataNode);
100
+ const data = cryptoByteView(lowerer, dataNode, lowerer.lowerExpr(dataNode));
99
101
  const enc = lowerer.lowerExprExpecting(call.arguments[0], STRING);
100
102
  return {
101
103
  kind: "libCall",
@@ -118,19 +120,83 @@ function lowerHashDigestChain(lowerer, call, access) {
118
120
  }
119
121
  return null;
120
122
  }
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"');
123
+ /** Node's normalizeEncoding(): the canonical name of a Buffer encoding,
124
+ * compared case-insensitively, or undefined for a name Node does not know. */
125
+ function cryptoEncodingName(value) {
126
+ switch (value.toLowerCase()) {
127
+ case "hex":
128
+ return "hex";
129
+ case "base64":
130
+ return "base64";
131
+ case "base64url":
132
+ return "base64url";
133
+ case "":
134
+ case "utf8":
135
+ case "utf-8":
136
+ return "utf8";
137
+ case "latin1":
138
+ case "binary":
139
+ return "latin1";
140
+ case "ascii":
141
+ return "ascii";
142
+ case "utf16le":
143
+ case "utf-16le":
144
+ case "ucs2":
145
+ case "ucs-2":
146
+ return "utf16le";
147
+ default:
148
+ return undefined;
125
149
  }
126
- return lowerer.lowerExprExpecting(node, STRING);
127
150
  }
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");
151
+ /** The values of a string literal type or a union of them; undefined when
152
+ * the type allows other values. */
153
+ function stringLiteralValues(type) {
154
+ if (type.isStringLiteralType())
155
+ return [type.value];
156
+ if (!type.isUnionType())
157
+ return undefined;
158
+ const values = [];
159
+ for (const member of ts.constituentTypes(type)) {
160
+ if (!member.isStringLiteralType())
161
+ return undefined;
162
+ values.push(member.value);
133
163
  }
164
+ return values;
165
+ }
166
+ /** Whether every value the node's type allows is an encoding that gives a
167
+ * string digest: a Buffer encoding Node knows. Hash.digest() treats ""
168
+ * as no encoding and returns a Buffer; crypto.hash() reads it as UTF-8. */
169
+ function isStringDigestEncoding(lowerer, node, emptyIsString) {
170
+ const values = stringLiteralValues(lowerer.typeOf(node));
171
+ return (!!values &&
172
+ values.every((value) => (value !== "" || emptyIsString) && cryptoEncodingName(value) !== undefined));
173
+ }
174
+ /** Whether every offset/size argument is statically a number; other
175
+ * values take the runtime checks, which throw Node's errors or apply its
176
+ * defaults. */
177
+ function cryptoNumberArgs(lowerer, nodes) {
178
+ return nodes.every((node) => lowerer.mapTypeOf(lowerer.typeOf(node))?.kind === "f64");
179
+ }
180
+ /** A view's bytes as the Uint8Array the byte-input libCalls take: other
181
+ * TypedArrays and DataViews become a u8 view of the same memory. */
182
+ function cryptoByteView(lowerer, node, value) {
183
+ if (value.type.kind !== "bytes" || value.type.elem === "u8")
184
+ return value;
185
+ return {
186
+ kind: "libCall",
187
+ fn: "bytes.bufferSource",
188
+ args: [lowerer.coerceInto(node, value, DYN)],
189
+ type: BYTES_U8,
190
+ loc: locOf(node),
191
+ };
192
+ }
193
+ function dynArg(lowerer, node, loc) {
194
+ return node ? lowerer.lowerExprExpecting(node, DYN) : dynUndefinedExpr(loc);
195
+ }
196
+ /** A digest name. The runtime resolves every name and alias Node 24
197
+ * accepts and throws Node's error for the others, so literals are not
198
+ * checked here. */
199
+ function cryptoAlgorithm(lowerer, node) {
134
200
  return lowerer.lowerExprExpecting(node, STRING);
135
201
  }
136
202
  function cryptoKdfInput(lowerer, node) {
@@ -144,7 +210,7 @@ function cryptoKdfInput(lowerer, node) {
144
210
  const value = lowerer.coerceInto(node, lowerer.lowerExpr(node), DYN);
145
211
  return { kind: "libCall", fn: "bytes.bufferSource", args: [value], type: BYTES_U8, loc };
146
212
  }
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");
213
+ 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
214
  }
149
215
  export function lowerCryptoModuleCall(lowerer, expr, bi, loc) {
150
216
  if (bi.module !== "crypto")
@@ -182,7 +248,7 @@ export function lowerCryptoModuleCall(lowerer, expr, bi, loc) {
182
248
  lowerBuiltinByteInput(lowerer, args[1], locOf(args[1]), "crypto"),
183
249
  lowerer.lowerExprExpecting(args[2], F64),
184
250
  lowerer.lowerExprExpecting(args[3], F64),
185
- cryptoAlgorithm(lowerer, args[4], "crypto.pbkdf2"),
251
+ cryptoAlgorithm(lowerer, args[4]),
186
252
  errorFirstBytesCallback(lowerer, args[5], "crypto"),
187
253
  ],
188
254
  type: VOID,
@@ -194,8 +260,16 @@ export function lowerCryptoModuleCall(lowerer, expr, bi, loc) {
194
260
  if (args.length !== (async ? 6 : 5))
195
261
  lowerer.noLowering(`crypto.${bi.member} with ${args.length} arguments`, expr);
196
262
  const values = [
197
- cryptoAlgorithm(lowerer, args[0], `crypto.${bi.member}`),
198
- cryptoKdfInput(lowerer, args[1]),
263
+ cryptoAlgorithm(lowerer, args[0]),
264
+ isKeyObjectValue(lowerer, args[1])
265
+ ? {
266
+ kind: "libCall",
267
+ fn: "crypto.keyObjectInput",
268
+ args: [lowerer.lowerExprExpecting(args[1], DYN)],
269
+ type: BYTES_U8,
270
+ loc,
271
+ }
272
+ : cryptoKdfInput(lowerer, args[1]),
199
273
  cryptoKdfInput(lowerer, args[2]),
200
274
  cryptoKdfInput(lowerer, args[3]),
201
275
  lowerer.lowerExprExpecting(args[4], F64),
@@ -235,121 +309,349 @@ export function lowerCryptoModuleCall(lowerer, expr, bi, loc) {
235
309
  };
236
310
  }
237
311
  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");
312
+ if (args.length < 1 || args.length > 2 || args.some(ts.isSpreadElement)) {
313
+ lowerer.noLowering(`crypto.createHash with ${args.length} arguments`, expr, "createHash(algorithm[, options]) is supported");
314
+ }
315
+ const algorithm = cryptoAlgorithm(lowerer, args[0]);
316
+ if (args.length === 1) {
317
+ return { kind: "libCall", fn: "crypto.hashNew", args: [algorithm], type: CRYPTOHASH_T, loc };
240
318
  }
241
319
  return {
242
320
  kind: "libCall",
243
- fn: "crypto.hashNew",
244
- args: [cryptoAlgorithm(lowerer, args[0], "crypto.createHash")],
321
+ fn: "crypto.hashNewOpts",
322
+ args: [algorithm, lowerer.lowerExprExpecting(args[1], DYN)],
245
323
  type: CRYPTOHASH_T,
246
324
  loc,
247
325
  };
248
326
  }
327
+ if (bi.member === "createCipheriv" || bi.member === "createDecipheriv") {
328
+ const algorithm = args[0];
329
+ if (algorithm)
330
+ checkCipherName(lowerer, algorithm, `crypto.${bi.member}`);
331
+ const stmts = [];
332
+ const values = [boolLit(bi.member === "createDecipheriv", loc)];
333
+ // Every argument is evaluated, left to right, before the runtime
334
+ // checks them; surplus arguments are evaluated and dropped.
335
+ for (let i = 0; i < 4; i++) {
336
+ const input = args[i]
337
+ ? lowerer.lowerExprExpecting(args[i], DYN)
338
+ : dynUndefinedExpr(loc);
339
+ const saved = lowerer.declareHiddenLocal("%cipherInput", DYN);
340
+ stmts.push({ kind: "varDecl", localId: saved.id, init: input, loc });
341
+ values.push(varRef(saved.id, DYN, loc));
342
+ }
343
+ for (const arg of args.slice(4))
344
+ stmts.push({ kind: "exprStmt", expr: lowerer.lowerExpr(arg), loc });
345
+ return {
346
+ kind: "seqExpr",
347
+ stmts,
348
+ result: { kind: "libCall", fn: "crypto.cipherNew", args: values, type: DYN, loc },
349
+ type: DYN,
350
+ loc,
351
+ };
352
+ }
249
353
  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");
354
+ if (args.length < 2 || args.length > 3 || args.some(ts.isSpreadElement)) {
355
+ lowerer.noLowering(`crypto.createHmac with ${args.length} arguments`, expr, "createHmac(algorithm, key[, options]) is supported");
252
356
  }
253
- const algorithm = cryptoAlgorithm(lowerer, args[0], "crypto.createHmac");
357
+ const algorithm = cryptoAlgorithm(lowerer, args[0]);
254
358
  const key = lowerer.lowerExpr(args[1]);
255
- if (key.type.kind === "string") {
359
+ if (args.length === 3 || (key.type.kind !== "string" && key.type.kind !== "bytes")) {
360
+ // Views, ArrayBuffers, options.encoding and values of other types
361
+ // take Node's prepareSecretKey checks at run time.
256
362
  return {
257
363
  kind: "libCall",
258
- fn: "crypto.hmacNewStr",
259
- args: [algorithm, key],
364
+ fn: "crypto.hmacNewDyn",
365
+ args: [algorithm, lowerer.coerceInto(args[1], key, DYN), dynArg(lowerer, args[2], loc)],
260
366
  type: CRYPTOHMAC_T,
261
367
  loc,
262
368
  };
263
369
  }
264
- if (key.type.kind === "bytes" && key.type.elem === "u8") {
370
+ if (key.type.kind === "string") {
265
371
  return {
266
372
  kind: "libCall",
267
- fn: "crypto.hmacNewBytes",
373
+ fn: "crypto.hmacNewStr",
268
374
  args: [algorithm, key],
269
375
  type: CRYPTOHMAC_T,
270
376
  loc,
271
377
  };
272
378
  }
273
- lowerer.noLowering(`crypto.createHmac with a '${lowerer.fmt(key.type)}' key`, args[1], "string and Buffer/Uint8Array keys are supported");
379
+ return {
380
+ kind: "libCall",
381
+ fn: "crypto.hmacNewBytes",
382
+ args: [algorithm, cryptoByteView(lowerer, args[1], key)],
383
+ type: CRYPTOHMAC_T,
384
+ loc,
385
+ };
274
386
  }
275
387
  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');
388
+ if (args.length < 2 || args.length > 3 || args.some(ts.isSpreadElement)) {
389
+ lowerer.noLowering(`crypto.hash with ${args.length} arguments`, expr, "hash(algorithm, data[, outputEncodingOrOptions]) is supported");
278
390
  }
279
- const algorithm = cryptoAlgorithm(lowerer, args[0], "crypto.hash");
391
+ const algorithm = cryptoAlgorithm(lowerer, args[0]);
280
392
  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") {
393
+ let options = args[2];
394
+ // An options literal holding only a literal string-digest
395
+ // outputEncoding is that encoding; evaluating it observes nothing.
396
+ if (options && ts.isObjectLiteralExpression(options) && options.properties.length === 1) {
397
+ const property = options.properties[0];
398
+ if (ts.isPropertyAssignment(property) &&
399
+ ts.isIdentifier(property.name) &&
400
+ property.name.text === "outputEncoding" &&
401
+ ts.isStringLiteral(property.initializer) &&
402
+ isStringDigestEncoding(lowerer, property.initializer, true)) {
403
+ options = property.initializer;
404
+ }
405
+ }
406
+ // String data or a view with no options or a string-digest encoding
407
+ // has a string result; every other form takes Node's checks at run
408
+ // time and returns the string or Buffer it produces.
409
+ if ((data.type.kind === "string" || data.type.kind === "bytes") &&
410
+ (options === undefined || isStringDigestEncoding(lowerer, options, true))) {
411
+ const encoding = options
412
+ ? lowerer.lowerExprExpecting(options, STRING)
413
+ : { kind: "strLit", value: "hex", type: STRING, loc };
285
414
  return {
286
415
  kind: "libCall",
287
- fn: "crypto.hashDigestStr",
288
- args: [algorithm, data, encoding],
416
+ fn: data.type.kind === "string" ? "crypto.hashDigestStr" : "crypto.hashDigestBytes",
417
+ args: [algorithm, cryptoByteView(lowerer, args[1], data), encoding],
289
418
  type: STRING,
290
419
  loc,
291
420
  };
292
421
  }
293
- if (data.type.kind === "bytes" && data.type.elem === "u8") {
422
+ return {
423
+ kind: "libCall",
424
+ fn: "crypto.hashOneshot",
425
+ args: [algorithm, lowerer.coerceInto(args[1], data, DYN), dynArg(lowerer, options, loc)],
426
+ type: DYN,
427
+ loc,
428
+ };
429
+ }
430
+ if (bi.member === "timingSafeEqual") {
431
+ if (args.length < 1 || args.length > 2 || args.some(ts.isSpreadElement))
432
+ lowerer.noLowering(`crypto.timingSafeEqual with ${args.length} arguments`, expr);
433
+ const left = lowerer.lowerExpr(args[0]);
434
+ const right = args[1] ? lowerer.lowerExpr(args[1]) : undefined;
435
+ // Views of every element kind compare their bytes; ArrayBuffers and
436
+ // other values take Node's checks at run time.
437
+ if (left.type.kind === "bytes" && right?.type.kind === "bytes") {
294
438
  return {
295
439
  kind: "libCall",
296
- fn: "crypto.hashDigestBytes",
297
- args: [algorithm, data, encoding],
298
- type: STRING,
440
+ fn: "crypto.timingSafeEqual",
441
+ args: [left, right],
442
+ type: BOOL,
299
443
  loc,
300
444
  };
301
445
  }
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
446
  return {
308
447
  kind: "libCall",
309
- fn: "crypto.timingSafeEqual",
448
+ fn: "crypto.timingSafeEqualDyn",
310
449
  args: [
311
- lowerer.lowerExprExpecting(args[0], BYTES_U8),
312
- lowerer.lowerExprExpecting(args[1], BYTES_U8),
450
+ lowerer.coerceInto(args[0], left, DYN),
451
+ right ? lowerer.coerceInto(args[1], right, DYN) : dynUndefinedExpr(loc),
313
452
  ],
314
453
  type: BOOL,
315
454
  loc,
316
455
  };
317
456
  }
318
457
  if (bi.member === "randomFillSync") {
319
- if (args.length < 1 || args.length > 3) {
458
+ if (args.length < 1 || args.length > 3 || args.some(ts.isSpreadElement)) {
320
459
  lowerer.noLowering(`crypto.randomFillSync with ${args.length} arguments`, expr, "randomFillSync(buffer[, offset[, size]]) is supported");
321
460
  }
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);
461
+ const buffer = lowerer.lowerExpr(args[0]);
462
+ if (buffer.type.kind === "bytes" && cryptoNumberArgs(lowerer, args.slice(1))) {
463
+ // A view returns itself, at its own type.
464
+ const offset = args[1]
465
+ ? lowerer.lowerExprExpecting(args[1], F64)
466
+ : { kind: "numLit", value: 0, type: F64, loc };
467
+ if (args[2]) {
468
+ return {
469
+ kind: "libCall",
470
+ fn: "crypto.randomFillView",
471
+ args: [buffer, offset, lowerer.lowerExprExpecting(args[2], F64)],
472
+ type: buffer.type,
473
+ loc,
474
+ };
475
+ }
328
476
  return {
329
477
  kind: "libCall",
330
- fn: "crypto.randomFill",
331
- args: [buffer, offset, size],
332
- type: BYTES_U8,
478
+ fn: "crypto.randomFillViewRest",
479
+ args: [buffer, offset],
480
+ type: buffer.type,
333
481
  loc,
334
482
  };
335
483
  }
484
+ // ArrayBuffers and other values take Node's checks at run time.
336
485
  return {
337
486
  kind: "libCall",
338
- fn: "crypto.randomFillRest",
339
- args: [buffer, offset],
340
- type: BYTES_U8,
487
+ fn: "crypto.randomFillSyncDyn",
488
+ args: [
489
+ lowerer.coerceInto(args[0], buffer, DYN),
490
+ dynArg(lowerer, args[1], loc),
491
+ dynArg(lowerer, args[2], loc),
492
+ ],
493
+ type: DYN,
494
+ loc,
495
+ };
496
+ }
497
+ if (bi.member === "randomFill") {
498
+ if (args.length < 2 || args.length > 4 || args.some(ts.isSpreadElement)) {
499
+ lowerer.noLowering(`crypto.randomFill with ${args.length} arguments`, expr, "randomFill(buffer[, offset[, size]], callback) is supported");
500
+ }
501
+ const form = { kind: "numLit", value: args.length - 1, type: F64, loc };
502
+ const buffer = lowerer.lowerExpr(args[0]);
503
+ if (buffer.type.kind === "bytes" && cryptoNumberArgs(lowerer, args.slice(1, -1))) {
504
+ const view = buffer.type;
505
+ const offset = args.length >= 3
506
+ ? lowerer.lowerExprExpecting(args[1], F64)
507
+ : { kind: "numLit", value: 0, type: F64, loc };
508
+ const size = args.length === 4
509
+ ? lowerer.lowerExprExpecting(args[2], F64)
510
+ : { kind: "numLit", value: 0, type: F64, loc };
511
+ const callback = errorFirstCallback(lowerer, args[args.length - 1], "crypto.randomFill", (value) => value.kind === "bytes" && value.elem === view.elem, "the buffer's own view");
512
+ return {
513
+ kind: "libCall",
514
+ fn: "crypto.randomFillCb",
515
+ args: [buffer, offset, size, form, callback],
516
+ type: VOID,
517
+ loc,
518
+ };
519
+ }
520
+ const callback = errorFirstCallback(lowerer, args[args.length - 1], "crypto.randomFill", () => false, "unknown-typed");
521
+ return {
522
+ kind: "libCall",
523
+ fn: "crypto.randomFillCbDyn",
524
+ args: [
525
+ lowerer.coerceInto(args[0], buffer, DYN),
526
+ args.length >= 3 ? lowerer.lowerExprExpecting(args[1], DYN) : dynUndefinedExpr(loc),
527
+ args.length === 4 ? lowerer.lowerExprExpecting(args[2], DYN) : dynUndefinedExpr(loc),
528
+ form,
529
+ callback,
530
+ ],
531
+ type: VOID,
341
532
  loc,
342
533
  };
343
534
  }
344
535
  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");
536
+ if (args.length < 1 || args.length > 3 || args.some(ts.isSpreadElement)) {
537
+ lowerer.noLowering(`crypto.randomInt with ${args.length} arguments`, expr, "randomInt([min, ]max[, callback]) is supported");
347
538
  }
348
- const min = args.length === 1
539
+ const last = args[args.length - 1];
540
+ const lastType = lowerer.mapTypeOf(lowerer.typeOf(last));
541
+ const withCallback = args.length === 3 || (args.length === 2 && lastType?.kind === "func");
542
+ const numbers = withCallback ? args.slice(0, -1) : args;
543
+ const min = numbers.length === 1
349
544
  ? { 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 };
545
+ : lowerer.lowerExprExpecting(numbers[0], F64);
546
+ const max = lowerer.lowerExprExpecting(numbers[numbers.length - 1], F64);
547
+ if (!withCallback) {
548
+ if (numbers.length === 1)
549
+ return { kind: "libCall", fn: "crypto.randomIntMax", args: [max], type: F64, loc };
550
+ return { kind: "libCall", fn: "crypto.randomInt", args: [min, max], type: F64, loc };
551
+ }
552
+ const callback = errorFirstCallback(lowerer, last, "crypto.randomInt", (value) => value.kind === "f64", "number");
553
+ const minGiven = {
554
+ kind: "numLit",
555
+ value: numbers.length === 2 ? 1 : 0,
556
+ type: F64,
557
+ loc,
558
+ };
559
+ return {
560
+ kind: "libCall",
561
+ fn: "crypto.randomIntCb",
562
+ args: [min, max, minGiven, callback],
563
+ type: VOID,
564
+ loc,
565
+ };
566
+ }
567
+ if (bi.member === "randomUUID" && args.length > 0) {
568
+ if (args.length > 1 || args.some(ts.isSpreadElement))
569
+ lowerer.noLowering(`crypto.randomUUID with ${args.length} arguments`, expr, "randomUUID([options]) is supported");
570
+ return {
571
+ kind: "libCall",
572
+ fn: "crypto.randomUUIDOpts",
573
+ args: [dynArg(lowerer, args[0], loc)],
574
+ type: STRING,
575
+ loc,
576
+ };
577
+ }
578
+ if (bi.member === "createSecretKey") {
579
+ if (args.length < 1 || args.length > 2 || args.some(ts.isSpreadElement))
580
+ lowerer.noLowering(`crypto.createSecretKey with ${args.length} arguments`, expr, "createSecretKey(key[, encoding]) is supported");
581
+ return {
582
+ kind: "libCall",
583
+ fn: "crypto.createSecretKey",
584
+ args: [lowerer.lowerExprExpecting(args[0], DYN), dynArg(lowerer, args[1], loc)],
585
+ type: DYN,
586
+ loc,
587
+ };
588
+ }
589
+ if (bi.member === "generateKeySync") {
590
+ if (args.length < 1 || args.length > 2 || args.some(ts.isSpreadElement))
591
+ lowerer.noLowering(`crypto.generateKeySync with ${args.length} arguments`, expr, "generateKeySync(type, options) is supported");
592
+ return {
593
+ kind: "libCall",
594
+ fn: "crypto.generateKeySync",
595
+ args: [lowerer.lowerExprExpecting(args[0], DYN), dynArg(lowerer, args[1], loc)],
596
+ type: DYN,
597
+ loc,
598
+ };
599
+ }
600
+ if (bi.member === "generateKey") {
601
+ if (args.length < 1 || args.length > 3 || args.some(ts.isSpreadElement))
602
+ lowerer.noLowering(`crypto.generateKey with ${args.length} arguments`, expr, "generateKey(type, options, callback) is supported");
603
+ const isFunction = (node) => !!node && lowerer.mapTypeOf(lowerer.typeOf(node))?.kind === "func";
604
+ // Node takes a function in the options position as the callback, and
605
+ // checks the callback before the type and options.
606
+ const optionsNode = args.length === 2 && isFunction(args[1]) ? undefined : args[1];
607
+ const callbackNode = args.length === 2 && isFunction(args[1]) ? args[1] : args[2];
608
+ const callbackType = callbackNode ? lowerer.mapTypeOf(lowerer.typeOf(callbackNode)) : undefined;
609
+ const type = lowerer.lowerExprExpecting(args[0], DYN);
610
+ const options = dynArg(lowerer, optionsNode, loc);
611
+ if (callbackType?.kind !== "func" && callbackType?.kind !== "dyn") {
612
+ const got = callbackNode
613
+ ? lowerer.lowerExprExpecting(callbackNode, DYN)
614
+ : dynUndefinedExpr(loc);
615
+ return {
616
+ kind: "seqExpr",
617
+ stmts: [
618
+ { kind: "exprStmt", expr: type, loc },
619
+ { kind: "exprStmt", expr: options, loc },
620
+ ],
621
+ result: {
622
+ kind: "libCall",
623
+ fn: "error.argTypeThrow",
624
+ args: [
625
+ { kind: "strLit", value: "callback", type: STRING, loc },
626
+ { kind: "strLit", value: "of type function", type: STRING, loc },
627
+ got,
628
+ ],
629
+ type: VOID,
630
+ loc,
631
+ },
632
+ type: VOID,
633
+ loc,
634
+ };
635
+ }
636
+ const callback = errorFirstCallback(lowerer, callbackNode, "crypto.generateKey", () => false, "KeyObject");
637
+ return {
638
+ kind: "libCall",
639
+ fn: "crypto.generateKeyCb",
640
+ args: [type, options, callback],
641
+ type: VOID,
642
+ loc,
643
+ };
644
+ }
645
+ if (bi.member === "randomUUIDv7") {
646
+ if (args.length > 1 || args.some(ts.isSpreadElement))
647
+ lowerer.noLowering(`crypto.randomUUIDv7 with ${args.length} arguments`, expr, "randomUUIDv7([options]) is supported");
648
+ return {
649
+ kind: "libCall",
650
+ fn: "crypto.randomUUIDv7",
651
+ args: [dynArg(lowerer, args[0], loc)],
652
+ type: STRING,
653
+ loc,
654
+ };
353
655
  }
354
656
  if (bi.member === "pbkdf2Sync") {
355
657
  if (args.length !== 5) {
@@ -365,7 +667,7 @@ export function lowerCryptoModuleCall(lowerer, expr, bi, loc) {
365
667
  salt,
366
668
  lowerer.lowerExprExpecting(args[2], F64),
367
669
  lowerer.lowerExprExpecting(args[3], F64),
368
- cryptoAlgorithm(lowerer, args[4], "crypto.pbkdf2Sync"),
670
+ cryptoAlgorithm(lowerer, args[4]),
369
671
  ],
370
672
  type: BYTES_U8,
371
673
  loc,
@@ -392,6 +694,89 @@ export function lowerCryptoModuleCall(lowerer, expr, bi, loc) {
392
694
  loc,
393
695
  };
394
696
  }
697
+ /** The implemented cipher names and OpenSSL's aliases for them,
698
+ * lower-cased (scr_cipher.c's table). */
699
+ const IMPLEMENTED_CIPHERS = new Set([
700
+ "aes-128-cbc",
701
+ "aes-192-cbc",
702
+ "aes-256-cbc",
703
+ "aes128",
704
+ "aes192",
705
+ "aes256",
706
+ "aes-128-ctr",
707
+ "aes-192-ctr",
708
+ "aes-256-ctr",
709
+ "aes-128-gcm",
710
+ "aes-192-gcm",
711
+ "aes-256-gcm",
712
+ "id-aes128-gcm",
713
+ "id-aes192-gcm",
714
+ "id-aes256-gcm",
715
+ "chacha20-poly1305",
716
+ ]);
717
+ const SUPPORTED_CIPHERS_HINT = "the supported ciphers are aes-128-cbc, aes-192-cbc, aes-256-cbc, aes-128-ctr, aes-192-ctr, " +
718
+ "aes-256-ctr, aes-128-gcm, aes-192-gcm, aes-256-gcm, and chacha20-poly1305";
719
+ /** A literal cipher name that Node knows but the runtime does not
720
+ * implement is refused at compile time. Unknown literal names keep Node's
721
+ * runtime ERR_CRYPTO_UNKNOWN_CIPHER. */
722
+ function checkCipherName(lowerer, node, use) {
723
+ const type = lowerer.typeOf(node);
724
+ if (!type.isStringLiteralType())
725
+ return;
726
+ const name = type.value.toLowerCase();
727
+ if (IMPLEMENTED_CIPHERS.has(name) || !CRYPTO_CIPHERS.includes(name))
728
+ return;
729
+ lowerer.noLowering(`${use} with cipher '${type.value}'`, node, SUPPORTED_CIPHERS_HINT);
730
+ }
731
+ /** Whether a checker type is node:crypto's Cipheriv/Decipheriv family. */
732
+ export function isCipherType(lowerer, type) {
733
+ const symbol = type.getAliasSymbol() ?? type.getSymbol();
734
+ return (!!symbol &&
735
+ CIPHER_TYPE_NAMES.has(symbol.name) &&
736
+ lowerer.checker.declarationsOf(symbol).some((d) => lowerer.isStdlibFile(d.getSourceFile())));
737
+ }
738
+ const CIPHER_METHODS = new Set([
739
+ "update",
740
+ "final",
741
+ "setAAD",
742
+ "setAutoPadding",
743
+ "getAuthTag",
744
+ "setAuthTag",
745
+ ]);
746
+ /** V8's spelling of a callee in "is not a function" messages: call
747
+ * arguments render as "(...)". */
748
+ function v8CalleeText(node) {
749
+ if (ts.isPropertyAccessExpression(node))
750
+ return `${v8CalleeText(node.expression)}.${node.name.text}`;
751
+ if (ts.isCallExpression(node))
752
+ return `${v8CalleeText(node.expression)}(...)`;
753
+ return node.getText();
754
+ }
755
+ /** Calls on native Cipheriv/Decipheriv handles dispatch through the
756
+ * handle's methods with checked-dynamic arguments. The stream.Transform
757
+ * members the classes inherit are refused. */
758
+ export function lowerCipherMethodCall(lowerer, call, access) {
759
+ if (call.questionDotToken || access.questionDotToken)
760
+ return null;
761
+ if (!isCipherType(lowerer, lowerer.typeOf(access.expression)))
762
+ return null;
763
+ const name = access.name.text;
764
+ if (!CIPHER_METHODS.has(name)) {
765
+ lowerer.noLowering(`Cipheriv/Decipheriv.${name}`, call, "update(), final(), setAAD(), setAutoPadding(), getAuthTag(), and setAuthTag() are supported; cipher streams are not");
766
+ }
767
+ if (call.arguments.some(ts.isSpreadElement))
768
+ lowerer.noLowering(`Cipheriv/Decipheriv.${name} with spread arguments`, call);
769
+ const loc = locOf(call);
770
+ return {
771
+ kind: "dynInvoke",
772
+ recv: lowerer.lowerExprExpecting(access.expression, DYN),
773
+ method: name,
774
+ calleeName: v8CalleeText(access),
775
+ args: call.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
776
+ type: DYN,
777
+ loc,
778
+ };
779
+ }
395
780
  /** Calls on native crypto.Hash/Hmac handles. The handle survives locals,
396
781
  * aliases, loops, and returns; update() retains and returns the receiver,
397
782
  * digest() finalizes it, and Hash.copy() snapshots the incremental state. */
@@ -406,106 +791,126 @@ export function lowerCryptoHashMethodCall(lowerer, call, access) {
406
791
  const name = access.name.text;
407
792
  const loc = locOf(call);
408
793
  const receiver = () => lowerer.lowerExprExpecting(access.expression, receiverType);
794
+ const hash = receiverType.kind === "cryptoHash";
795
+ const label = hash ? "Hash" : "Hmac";
796
+ if (call.arguments.some(ts.isSpreadElement))
797
+ lowerer.noLowering(`${label}.${name} with spread arguments`, call);
409
798
  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");
799
+ if (call.arguments.length < 1 || call.arguments.length > 2) {
800
+ lowerer.noLowering(`${label}.update with ${call.arguments.length} arguments`, call, "update(data[, inputEncoding]) is supported");
414
801
  }
802
+ const target = receiver();
415
803
  const dataNode = call.arguments[0];
804
+ const encodingNode = call.arguments[1];
416
805
  const dataType = lowerer.mapTypeOf(lowerer.typeOf(dataNode));
417
806
  // Indexed reads can retain optional storage after a nullish fallback
418
807
  // or narrowing. Use the proven argument type through a checked coercion.
419
808
  const data = dataType?.kind === "string" || dataType?.kind === "bytes"
420
809
  ? lowerer.lowerExprExpecting(dataNode, dataType)
421
810
  : 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
- }
811
+ const prefix = hash ? "crypto.hashUpdate" : "crypto.hmacUpdate";
812
+ const encodingType = encodingNode ? lowerer.mapTypeOf(lowerer.typeOf(encodingNode)) : undefined;
813
+ if (data.type.kind === "bytes" && encodingNode === undefined) {
427
814
  return {
428
815
  kind: "libCall",
429
816
  fn: `${prefix}Bytes`,
430
- args: [receiver(), data],
817
+ args: [target, cryptoByteView(lowerer, dataNode, data)],
431
818
  type: receiverType,
432
819
  loc,
433
820
  };
434
821
  }
435
822
  if (data.type.kind === "string") {
436
- const encodingNode = call.arguments[1];
437
- if (encodingNode === undefined) {
823
+ const literal = encodingNode ? stringLiteralValues(lowerer.typeOf(encodingNode)) : undefined;
824
+ const utf8 = encodingNode === undefined ||
825
+ (literal?.length === 1 && cryptoEncodingName(literal[0]) === "utf8");
826
+ if (utf8) {
827
+ if (encodingNode)
828
+ lowerer.lowerExprExpecting(encodingNode, STRING);
438
829
  return {
439
830
  kind: "libCall",
440
831
  fn: `${prefix}Str`,
441
- args: [receiver(), data],
832
+ args: [target, data],
442
833
  type: receiverType,
443
834
  loc,
444
835
  };
445
836
  }
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);
837
+ if (encodingType?.kind === "string") {
453
838
  return {
454
839
  kind: "libCall",
455
- fn: `${prefix}Str`,
456
- args: [receiver(), data],
840
+ fn: `${prefix}Enc`,
841
+ args: [target, data, lowerer.lowerExprExpecting(encodingNode, STRING)],
457
842
  type: receiverType,
458
843
  loc,
459
844
  };
460
845
  }
461
- const encoded = {
846
+ }
847
+ // Other data and encodings take Node's checks at run time: views and
848
+ // strings hash, anything else throws ERR_INVALID_ARG_TYPE.
849
+ return {
850
+ kind: "libCall",
851
+ fn: `${prefix}Dyn`,
852
+ args: [target, lowerer.coerceInto(dataNode, data, DYN), dynArg(lowerer, encodingNode, loc)],
853
+ type: receiverType,
854
+ loc,
855
+ };
856
+ }
857
+ if (name === "digest") {
858
+ if (call.arguments.length > 1) {
859
+ lowerer.noLowering(`${label}.digest with ${call.arguments.length} arguments`, call, "digest([outputEncoding]) is supported");
860
+ }
861
+ const encodingNode = call.arguments[0];
862
+ if (encodingNode === undefined) {
863
+ return {
462
864
  kind: "libCall",
463
- fn: "buffer.fromStr",
464
- args: [data, lowerer.lowerExprExpecting(encodingNode, STRING)],
865
+ fn: hash ? "crypto.hashDigestBuffer" : "crypto.hmacDigestBuffer",
866
+ args: [receiver()],
465
867
  type: BYTES_U8,
466
868
  loc,
467
869
  };
870
+ }
871
+ if (isStringDigestEncoding(lowerer, encodingNode, false)) {
468
872
  return {
469
873
  kind: "libCall",
470
- fn: `${prefix}Bytes`,
471
- args: [receiver(), encoded],
472
- type: receiverType,
874
+ fn: hash ? "crypto.hashDigestString" : "crypto.hmacDigestString",
875
+ args: [receiver(), lowerer.lowerExprExpecting(encodingNode, STRING)],
876
+ type: STRING,
473
877
  loc,
474
878
  };
475
879
  }
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');
880
+ // Node returns a Buffer for a falsy or unknown encoding. A literal
881
+ // whose Buffer result the declared string type cannot hold is refused.
882
+ const literal = stringLiteralValues(lowerer.typeOf(encodingNode));
883
+ const declared = lowerer.mapTypeOf(lowerer.typeOf(call));
884
+ if (literal && declared?.kind === "string") {
885
+ 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
886
  }
482
- if (call.arguments.length === 0) {
887
+ return {
888
+ kind: "libCall",
889
+ fn: hash ? "crypto.hashDigestDyn" : "crypto.hmacDigestDyn",
890
+ args: [receiver(), lowerer.lowerExprExpecting(encodingNode, DYN)],
891
+ type: DYN,
892
+ loc,
893
+ };
894
+ }
895
+ if (name === "copy" && hash) {
896
+ if (call.arguments.length > 1)
897
+ lowerer.noLowering(`Hash.copy with ${call.arguments.length} arguments`, call, "copy([options]) is supported");
898
+ if (call.arguments.length === 0)
483
899
  return {
484
900
  kind: "libCall",
485
- fn: receiverType.kind === "cryptoHash"
486
- ? "crypto.hashDigestBuffer"
487
- : "crypto.hmacDigestBuffer",
901
+ fn: "crypto.hashCopy",
488
902
  args: [receiver()],
489
- type: BYTES_U8,
903
+ type: CRYPTOHASH_T,
490
904
  loc,
491
905
  };
492
- }
493
906
  return {
494
907
  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,
908
+ fn: "crypto.hashCopyOpts",
909
+ args: [receiver(), lowerer.lowerExprExpecting(call.arguments[0], DYN)],
910
+ type: CRYPTOHASH_T,
501
911
  loc,
502
912
  };
503
913
  }
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
914
  lowerer.noLowering(`${receiverType.kind === "cryptoHash" ? "Hash" : "Hmac"}.${name}`, call, receiverType.kind === "cryptoHash"
510
915
  ? "update(), digest(), and copy() are supported"
511
916
  : "update() and digest() are supported", lowerer.checker.getSymbolAtLocation(access.name));