@scriptc/compiler 0.3.3 → 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 (213) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +713 -26
  2. package/dist/backend/cycle-mutability.d.ts +5 -0
  3. package/dist/backend/cycle-mutability.js +62 -3
  4. package/dist/backend/cycle-mutability.js.map +1 -1
  5. package/dist/backend/executable-features.js +1 -0
  6. package/dist/backend/executable-features.js.map +1 -1
  7. package/dist/backend/library-pack.js +1 -0
  8. package/dist/backend/library-pack.js.map +1 -1
  9. package/dist/backend/llvm/call-lifetimes.d.ts +5 -1
  10. package/dist/backend/llvm/call-lifetimes.js +11 -3
  11. package/dist/backend/llvm/call-lifetimes.js.map +1 -1
  12. package/dist/backend/llvm/call-lifetimes.test.js +31 -1
  13. package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
  14. package/dist/backend/llvm/common.d.ts +5 -0
  15. package/dist/backend/llvm/common.js +7 -0
  16. package/dist/backend/llvm/common.js.map +1 -1
  17. package/dist/backend/llvm/dense-array-access.js +2 -2
  18. package/dist/backend/llvm/dense-array-access.js.map +1 -1
  19. package/dist/backend/llvm/dyn.d.ts +40 -1
  20. package/dist/backend/llvm/dyn.js +178 -27
  21. package/dist/backend/llvm/dyn.js.map +1 -1
  22. package/dist/backend/llvm/emitter.d.ts +12 -0
  23. package/dist/backend/llvm/emitter.js +164 -27
  24. package/dist/backend/llvm/emitter.js.map +1 -1
  25. package/dist/backend/llvm/expr-bytes.d.ts +9 -0
  26. package/dist/backend/llvm/expr-bytes.js +158 -63
  27. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  28. package/dist/backend/llvm/expr-calls.d.ts +3 -1
  29. package/dist/backend/llvm/expr-calls.js +49 -1
  30. package/dist/backend/llvm/expr-calls.js.map +1 -1
  31. package/dist/backend/llvm/expr-containers.js +16 -5
  32. package/dist/backend/llvm/expr-containers.js.map +1 -1
  33. package/dist/backend/llvm/intern-tables.test.d.ts +1 -0
  34. package/dist/backend/llvm/intern-tables.test.js +77 -0
  35. package/dist/backend/llvm/intern-tables.test.js.map +1 -0
  36. package/dist/backend/llvm/lib-datagram.js +10 -0
  37. package/dist/backend/llvm/lib-datagram.js.map +1 -1
  38. package/dist/backend/llvm/lib-dispatch.js +92 -1
  39. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  40. package/dist/backend/llvm/lib-filesystem.js +51 -0
  41. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  42. package/dist/backend/llvm/lib-network.js +16 -0
  43. package/dist/backend/llvm/lib-network.js.map +1 -1
  44. package/dist/backend/llvm/lib-shared.d.ts +5 -0
  45. package/dist/backend/llvm/lib-shared.js +80 -1
  46. package/dist/backend/llvm/lib-shared.js.map +1 -1
  47. package/dist/backend/llvm/lib-stream.js +87 -0
  48. package/dist/backend/llvm/lib-stream.js.map +1 -1
  49. package/dist/backend/llvm/lib-test.js +9 -0
  50. package/dist/backend/llvm/lib-test.js.map +1 -1
  51. package/dist/backend/llvm/map-number-lookup.d.ts +4 -0
  52. package/dist/backend/llvm/map-number-lookup.js +22 -0
  53. package/dist/backend/llvm/map-number-lookup.js.map +1 -1
  54. package/dist/backend/llvm/map-number-lookup.test.js +56 -0
  55. package/dist/backend/llvm/map-number-lookup.test.js.map +1 -1
  56. package/dist/backend/llvm/map-read-lifetimes.d.ts +9 -0
  57. package/dist/backend/llvm/map-read-lifetimes.js +89 -1
  58. package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
  59. package/dist/backend/llvm/map-read-lifetimes.test.js +129 -1
  60. package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -1
  61. package/dist/backend/llvm/publish.d.ts +5 -0
  62. package/dist/backend/llvm/publish.js +22 -3
  63. package/dist/backend/llvm/publish.js.map +1 -1
  64. package/dist/backend/llvm/reference-writes.js +5 -2
  65. package/dist/backend/llvm/reference-writes.js.map +1 -1
  66. package/dist/backend/llvm/regions.d.ts +4 -1
  67. package/dist/backend/llvm/regions.js +12 -3
  68. package/dist/backend/llvm/regions.js.map +1 -1
  69. package/dist/backend/llvm/string-reads.js +2 -2
  70. package/dist/backend/llvm/string-reads.js.map +1 -1
  71. package/dist/backend/llvm/string-slices.js +2 -2
  72. package/dist/backend/llvm/string-slices.js.map +1 -1
  73. package/dist/backend/may-throw.js +4 -0
  74. package/dist/backend/may-throw.js.map +1 -1
  75. package/dist/backend/native/contracts.d.ts +3 -0
  76. package/dist/backend/native/executable.js +13 -5
  77. package/dist/backend/native/executable.js.map +1 -1
  78. package/dist/backend/native/runtime-inputs.d.ts +1 -1
  79. package/dist/backend/native/runtime-inputs.js +1 -0
  80. package/dist/backend/native/runtime-inputs.js.map +1 -1
  81. package/dist/backend/native-codegen-core.d.ts +4 -4
  82. package/dist/backend/native-codegen-core.js +4 -6
  83. package/dist/backend/native-codegen-core.js.map +1 -1
  84. package/dist/backend/native-codegen.test.js +7 -8
  85. package/dist/backend/native-codegen.test.js.map +1 -1
  86. package/dist/backend/native-link-info-core.d.ts +3 -0
  87. package/dist/backend/native-link-info-core.js.map +1 -1
  88. package/dist/backend/publication.js +3 -1
  89. package/dist/backend/publication.js.map +1 -1
  90. package/dist/backend/runtime-pack-targets.test.js +1 -0
  91. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  92. package/dist/backend/runtime-pack.test.js +1 -0
  93. package/dist/backend/runtime-pack.test.js.map +1 -1
  94. package/dist/backend/target-diagnostics.js +7 -0
  95. package/dist/backend/target-diagnostics.js.map +1 -1
  96. package/dist/backend/warm-cache.js +1 -0
  97. package/dist/backend/warm-cache.js.map +1 -1
  98. package/dist/executable/executable-cache.d.ts +1 -0
  99. package/dist/executable/executable-cache.js +1 -0
  100. package/dist/executable/executable-cache.js.map +1 -1
  101. package/dist/executable/executable-cache.test.js +1 -0
  102. package/dist/executable/executable-cache.test.js.map +1 -1
  103. package/dist/frontend/experimental-import.d.ts +5 -1
  104. package/dist/frontend/experimental-import.js +28 -3
  105. package/dist/frontend/experimental-import.js.map +1 -1
  106. package/dist/frontend/lowering/assert-instances.d.ts +38 -0
  107. package/dist/frontend/lowering/assert-instances.js +269 -0
  108. package/dist/frontend/lowering/assert-instances.js.map +1 -0
  109. package/dist/frontend/lowering/builtins/compression.d.ts +18 -0
  110. package/dist/frontend/lowering/builtins/compression.js +175 -2
  111. package/dist/frontend/lowering/builtins/compression.js.map +1 -1
  112. package/dist/frontend/lowering/builtins/constants.js +7 -2
  113. package/dist/frontend/lowering/builtins/constants.js.map +1 -1
  114. package/dist/frontend/lowering/builtins/crypto.d.ts +6 -0
  115. package/dist/frontend/lowering/builtins/crypto.js +111 -1
  116. package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
  117. package/dist/frontend/lowering/builtins/errors.js +23 -0
  118. package/dist/frontend/lowering/builtins/errors.js.map +1 -1
  119. package/dist/frontend/lowering/builtins/timers.d.ts +3 -0
  120. package/dist/frontend/lowering/builtins/timers.js +109 -23
  121. package/dist/frontend/lowering/builtins/timers.js.map +1 -1
  122. package/dist/frontend/lowering/call-signatures.js +6 -0
  123. package/dist/frontend/lowering/call-signatures.js.map +1 -1
  124. package/dist/frontend/lowering/class-dynamic-dispatch.js +66 -12
  125. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  126. package/dist/frontend/lowering/intern-tables.d.ts +13 -0
  127. package/dist/frontend/lowering/intern-tables.js +536 -0
  128. package/dist/frontend/lowering/intern-tables.js.map +1 -0
  129. package/dist/frontend/lowering/lower-assert.js +700 -61
  130. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  131. package/dist/frontend/lowering/lower-async-iteration.js +11 -2
  132. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
  133. package/dist/frontend/lowering/lower-calls.js +17 -3
  134. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  135. package/dist/frontend/lowering/lower-classes.d.ts +3 -0
  136. package/dist/frontend/lowering/lower-classes.js +36 -0
  137. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  138. package/dist/frontend/lowering/lower-dgram.js +77 -52
  139. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  140. package/dist/frontend/lowering/lower-exprs.js +12 -0
  141. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  142. package/dist/frontend/lowering/lower-inspect.d.ts +6 -0
  143. package/dist/frontend/lowering/lower-inspect.js +112 -39
  144. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  145. package/dist/frontend/lowering/lower-mock.d.ts +11 -0
  146. package/dist/frontend/lowering/lower-mock.js +504 -0
  147. package/dist/frontend/lowering/lower-mock.js.map +1 -0
  148. package/dist/frontend/lowering/lower-modules.js +7 -0
  149. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  150. package/dist/frontend/lowering/lower-server.d.ts +3 -0
  151. package/dist/frontend/lowering/lower-server.js +380 -30
  152. package/dist/frontend/lowering/lower-server.js.map +1 -1
  153. package/dist/frontend/lowering/lower-stmts.js +23 -2
  154. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  155. package/dist/frontend/lowering/lower-stream.d.ts +10 -6
  156. package/dist/frontend/lowering/lower-stream.js +786 -27
  157. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  158. package/dist/frontend/lowering/lower-test.js +86 -8
  159. package/dist/frontend/lowering/lower-test.js.map +1 -1
  160. package/dist/frontend/lowering/lowerer.d.ts +22 -0
  161. package/dist/frontend/lowering/lowerer.js +72 -7
  162. package/dist/frontend/lowering/lowerer.js.map +1 -1
  163. package/dist/frontend/lowering/pairs-snapshot.d.ts +6 -0
  164. package/dist/frontend/lowering/pairs-snapshot.js +49 -0
  165. package/dist/frontend/lowering/pairs-snapshot.js.map +1 -1
  166. package/dist/frontend/lowering/surfaces.d.ts +4 -0
  167. package/dist/frontend/lowering/surfaces.js +61 -15
  168. package/dist/frontend/lowering/surfaces.js.map +1 -1
  169. package/dist/frontend/lowering/zlib-constants.d.ts +1 -0
  170. package/dist/frontend/lowering/zlib-constants.js +181 -0
  171. package/dist/frontend/lowering/zlib-constants.js.map +1 -0
  172. package/dist/frontend/mock-shapes.d.ts +10 -0
  173. package/dist/frontend/mock-shapes.js +76 -0
  174. package/dist/frontend/mock-shapes.js.map +1 -0
  175. package/dist/frontend/pipeline.js +5 -3
  176. package/dist/frontend/pipeline.js.map +1 -1
  177. package/dist/frontend/program.js +6 -1
  178. package/dist/frontend/program.js.map +1 -1
  179. package/dist/frontend/resolve.d.ts +4 -0
  180. package/dist/frontend/resolve.js +14 -0
  181. package/dist/frontend/resolve.js.map +1 -1
  182. package/dist/frontend/tsc-codes.js +1 -0
  183. package/dist/frontend/tsc-codes.js.map +1 -1
  184. package/dist/frontend/type-mapper.d.ts +5 -0
  185. package/dist/frontend/type-mapper.js +102 -9
  186. package/dist/frontend/type-mapper.js.map +1 -1
  187. package/dist/index.js +2 -1
  188. package/dist/index.js.map +1 -1
  189. package/dist/ir/builtin-effects.js +36 -0
  190. package/dist/ir/builtin-effects.js.map +1 -1
  191. package/dist/ir/builtin-signatures.d.ts +1 -1
  192. package/dist/ir/builtin-signatures.js +147 -8
  193. package/dist/ir/builtin-signatures.js.map +1 -1
  194. package/dist/ir/ir.d.ts +20 -1
  195. package/dist/ir/ir.js +17 -0
  196. package/dist/ir/ir.js.map +1 -1
  197. package/dist/ir/runtime-features.d.ts +1 -0
  198. package/dist/ir/runtime-features.js +29 -2
  199. package/dist/ir/runtime-features.js.map +1 -1
  200. package/dist/ir/validate.js +195 -5
  201. package/dist/ir/validate.js.map +1 -1
  202. package/dist/library/ir-policy.js +1 -0
  203. package/dist/library/ir-policy.js.map +1 -1
  204. package/dist/native/cli.js +1 -0
  205. package/dist/native/cli.js.map +1 -1
  206. package/dist/native/compiler.js +1 -3
  207. package/dist/native/compiler.js.map +1 -1
  208. package/dist/native/prepare.js +1 -0
  209. package/dist/native/prepare.js.map +1 -1
  210. package/dist/native/sanitizer.test.js +1 -0
  211. package/dist/native/sanitizer.test.js.map +1 -1
  212. package/package.json +20 -20
  213. package/surface-manifest.json +869 -48
@@ -3461,6 +3461,45 @@ function validateFunction(fn, functions, ffiByName, classes, records, recordVali
3461
3461
  err(`${e.name} has type ${e.name === "region.create" ? "f64" : "void"}`, e.loc);
3462
3462
  return;
3463
3463
  }
3464
+ if (e.name === "itable.open" ||
3465
+ e.name === "itable.find" ||
3466
+ e.name === "itable.insert" ||
3467
+ e.name === "itable.value" ||
3468
+ e.name === "itable.size") {
3469
+ for (const a of e.args)
3470
+ checkExpr(a);
3471
+ const [first, key, value] = e.args;
3472
+ const arity = {
3473
+ "itable.open": 2,
3474
+ "itable.find": 2,
3475
+ "itable.insert": 3,
3476
+ "itable.value": 1,
3477
+ "itable.size": 1,
3478
+ }[e.name];
3479
+ if (e.args.length !== arity)
3480
+ err(`${e.name} takes ${arity} arguments`, e.loc);
3481
+ else if (e.name === "itable.open") {
3482
+ if (first.type.kind !== "string" || key.type.kind !== "f64")
3483
+ err("itable.open takes a string name and an f64 key kind", e.loc);
3484
+ }
3485
+ else if (first.type.kind !== "f64")
3486
+ err(`${e.name} handle must be f64`, e.loc);
3487
+ else if ((e.name === "itable.find" || e.name === "itable.insert") &&
3488
+ key.type.kind !== "string" &&
3489
+ key.type.kind !== "f64" &&
3490
+ !(key.type.kind === "array" &&
3491
+ (key.type.elem.kind === "f64" || key.type.elem.kind === "string")))
3492
+ err(`${e.name} key must be string, f64, or an array of either`, e.loc);
3493
+ else if (e.name === "itable.insert" && !isSupportedMapValue(value.type))
3494
+ err(`itable.insert value ${typeKey(value.type)} is not a table value type`, e.loc);
3495
+ if (e.name === "itable.value") {
3496
+ if (!isSupportedMapValue(e.type))
3497
+ err(`itable.value type ${typeKey(e.type)} is not a table value type`, e.loc);
3498
+ }
3499
+ else if (e.type.kind !== "f64")
3500
+ err(`${e.name} has type f64`, e.loc);
3501
+ return;
3502
+ }
3464
3503
  if (e.name === "threads.publish") {
3465
3504
  if (e.args.length !== 1)
3466
3505
  err("threads.publish takes exactly one argument", e.loc);
@@ -3633,6 +3672,10 @@ function validateFunction(fn, functions, ffiByName, classes, records, recordVali
3633
3672
  e.fn === "passthrough.initDyn" ||
3634
3673
  e.fn === "stream.pipeline" ||
3635
3674
  e.fn === "stream.pipelineDyn" ||
3675
+ e.fn === "stream.compose" ||
3676
+ e.fn === "stream.pipelineStages" ||
3677
+ e.fn === "stream.pipelineStagesDyn" ||
3678
+ e.fn === "sp.pipelineStages" ||
3636
3679
  e.fn === "sp.pipeline" ||
3637
3680
  e.fn === "sp.pipelineOpts" ||
3638
3681
  e.fn === "sp.pipelineOptsSignal" ||
@@ -3694,6 +3737,13 @@ function validateFunction(fn, functions, ffiByName, classes, records, recordVali
3694
3737
  }
3695
3738
  }
3696
3739
  function checkLibValueCall(e) {
3740
+ if (e.fn === "tp.setTimeoutValue" || e.fn === "tp.setImmediateValue") {
3741
+ const value = e.args[e.fn === "tp.setTimeoutValue" ? 1 : 0];
3742
+ if (value?.type.kind !== "promise" || !typeEquals(e.type, value.type)) {
3743
+ err(`libCall ${e.fn} must be the value's promise type`, e.loc);
3744
+ }
3745
+ return true;
3746
+ }
3697
3747
  if (e.fn === "fileHandle.read" ||
3698
3748
  e.fn === "fileHandle.writeBytes" ||
3699
3749
  e.fn === "fileHandle.writeStr" ||
@@ -4744,7 +4794,9 @@ function validateFunction(fn, functions, ffiByName, classes, records, recordVali
4744
4794
  }
4745
4795
  return true;
4746
4796
  }
4747
- if (e.fn === "assert.refEqBytes" || e.fn === "assert.bytesDeepEq") {
4797
+ if (e.fn === "assert.refEqBytes" ||
4798
+ e.fn === "assert.bytesDeepEq" ||
4799
+ e.fn === "assert.looseBytesEq") {
4748
4800
  // Both value slots: ONE static bytes type (the frontend's
4749
4801
  // same-static-type gate — a u8/u32 mix would memcmp garbage).
4750
4802
  const a = e.args[0]?.type;
@@ -4783,6 +4835,26 @@ function validateFunction(fn, functions, ffiByName, classes, records, recordVali
4783
4835
  return false;
4784
4836
  }
4785
4837
  function checkLibStreamCall(e, fixedArgs, result) {
4838
+ if (e.fn.startsWith("zlib.stream")) {
4839
+ // The zlib stream classes: streamNew answers a runtime Transform;
4840
+ // the members take one as their receiver, and the Cb forms end in
4841
+ // the () => void callback.
4842
+ const isTransform = (t) => t?.kind === "object" && t.className === "%Transform";
4843
+ if (e.fn === "zlib.streamNew") {
4844
+ if (!isTransform(e.type))
4845
+ err(`libCall ${e.fn} must return a %Transform`, e.loc);
4846
+ return true;
4847
+ }
4848
+ if (!isTransform(e.args[0]?.type)) {
4849
+ err(`libCall ${e.fn} receiver must be a %Transform`, e.loc);
4850
+ }
4851
+ if (e.fn.endsWith("Cb") && e.args[e.args.length - 1]?.type.kind !== "func") {
4852
+ err(`libCall ${e.fn} callback must be a func`, e.loc);
4853
+ }
4854
+ if (!typeEquals(e.type, result))
4855
+ err(`libCall ${e.fn} result type mismatch`, e.loc);
4856
+ return true;
4857
+ }
4786
4858
  if (e.fn.startsWith("readable.") ||
4787
4859
  e.fn.startsWith("writable.") ||
4788
4860
  e.fn.startsWith("duplex.") ||
@@ -4797,6 +4869,10 @@ function validateFunction(fn, functions, ffiByName, classes, records, recordVali
4797
4869
  e.fn === "stream.finishedDyn" ||
4798
4870
  e.fn === "stream.pipeline" ||
4799
4871
  e.fn === "stream.pipelineDyn" ||
4872
+ e.fn === "stream.compose" ||
4873
+ e.fn === "stream.pipelineStages" ||
4874
+ e.fn === "stream.pipelineStagesDyn" ||
4875
+ e.fn === "sp.pipelineStages" ||
4800
4876
  e.fn === "stream.addAbortSignal" ||
4801
4877
  e.fn === "stream.addAbortSignalFn" ||
4802
4878
  e.fn === "stream.finishedOpts" ||
@@ -4886,6 +4962,80 @@ function validateFunction(fn, functions, ffiByName, classes, records, recordVali
4886
4962
  }
4887
4963
  return true;
4888
4964
  }
4965
+ if (e.fn === "stream.compose") {
4966
+ // (count, s1..sn) → a Duplex (n >= 2), or the lone stream.
4967
+ const count = e.args[0];
4968
+ const n = count?.kind === "numLit" ? count.value : -1;
4969
+ if (n < 1 || e.args.length !== n + 1) {
4970
+ err(`libCall ${e.fn} count/arity mismatch`, e.loc);
4971
+ return true;
4972
+ }
4973
+ for (let i = 1; i <= n; i++) {
4974
+ if (!isStreamObject(e.args[i]?.type)) {
4975
+ err(`libCall ${e.fn} stage ${i} must be a stream-hierarchy object`, e.loc);
4976
+ }
4977
+ }
4978
+ if (!isStreamObject(e.type))
4979
+ err(`libCall ${e.fn} must return a stream`, e.loc);
4980
+ return true;
4981
+ }
4982
+ if (e.fn === "stream.pipelineStages" ||
4983
+ e.fn === "stream.pipelineStagesDyn" ||
4984
+ e.fn === "sp.pipelineStages") {
4985
+ // (n, at, k, flags, mask, s1..sn, stage1..stagek, (next, read,
4986
+ // return)?, box?, (signal, abort)?[, cb]): flags bit 0 a source
4987
+ // function, bits 1-2 the destination, bits 3/4/5 the groups.
4988
+ const [n, at, k, flags] = e.args
4989
+ .slice(0, 4)
4990
+ .map((a) => (a?.kind === "numLit" ? a.value : -1));
4991
+ const source = (flags & 1) !== 0;
4992
+ const destKind = (flags >> 1) & 3;
4993
+ const groups = (flags & 8 ? 3 : 0) + (flags & 16 ? 1 : 0) + (flags & 32 ? 2 : 0);
4994
+ const cbArgs = e.fn === "sp.pipelineStages" ? 0 : 1;
4995
+ if (flags < 0 ||
4996
+ n < 0 ||
4997
+ k < 1 ||
4998
+ (source ? at !== 0 : at < 1) ||
4999
+ (destKind === 0 ? at + 0 >= n : at !== n) ||
5000
+ n + k < 2 ||
5001
+ e.args.length !== 5 + n + k + groups + cbArgs) {
5002
+ err(`libCall ${e.fn} count/arity mismatch`, e.loc);
5003
+ return true;
5004
+ }
5005
+ for (let i = 5; i < 5 + n; i++) {
5006
+ if (!isStreamObject(e.args[i]?.type)) {
5007
+ err(`libCall ${e.fn} stage ${i - 5} must be a stream-hierarchy object`, e.loc);
5008
+ }
5009
+ }
5010
+ let at2 = 5 + n;
5011
+ for (let i = at2; i < at2 + k; i++) {
5012
+ if (e.args[i]?.type.kind !== "func")
5013
+ err(`libCall ${e.fn} stage function ${i} must be a func`, e.loc);
5014
+ }
5015
+ at2 += k;
5016
+ const helpers = (flags & 8 ? 3 : 0) + (flags & 16 ? 1 : 0);
5017
+ for (let i = at2; i < at2 + helpers; i++) {
5018
+ if (e.args[i]?.type.kind !== "func")
5019
+ err(`libCall ${e.fn} helper ${i} must be a func`, e.loc);
5020
+ }
5021
+ at2 += helpers;
5022
+ if (flags & 32) {
5023
+ if (e.args[at2]?.type.kind !== "dyn" || e.args[at2 + 1]?.type.kind !== "func")
5024
+ err(`libCall ${e.fn} signal and abort must be a dyn and a func`, e.loc);
5025
+ }
5026
+ if (cbArgs) {
5027
+ const cbK = e.args[e.args.length - 1]?.type.kind;
5028
+ if (e.fn === "stream.pipelineStages" ? cbK !== "func" : cbK !== "dyn") {
5029
+ err(`libCall ${e.fn} callback has the wrong kind`, e.loc);
5030
+ }
5031
+ if (!isStreamObject(e.type))
5032
+ err(`libCall ${e.fn} must return a stream`, e.loc);
5033
+ }
5034
+ else if (e.type.kind !== "promise") {
5035
+ err(`libCall ${e.fn} must return a promise`, e.loc);
5036
+ }
5037
+ return true;
5038
+ }
4889
5039
  if (e.fn === "stream.pipeline" || e.fn === "stream.pipelineDyn") {
4890
5040
  // (count, s1..sn, cb) → the destination's type.
4891
5041
  const count = e.args[0];
@@ -4908,10 +5058,50 @@ function validateFunction(fn, functions, ffiByName, classes, records, recordVali
4908
5058
  }
4909
5059
  return true;
4910
5060
  }
4911
- if (e.fn === "readable.fromArr") {
4912
- // No receiver: the seed array leads; the result is the class.
4913
- if (e.args[0]?.type.kind !== "array" || !isStreamObject(e.type)) {
4914
- err(`libCall readable.fromArr must take an array and return a stream class`, e.loc);
5061
+ if (e.fn === "readable.opMap" ||
5062
+ e.fn === "readable.opFilter" ||
5063
+ e.fn === "readable.opFlatMap" ||
5064
+ e.fn === "readable.opDrop" ||
5065
+ e.fn === "readable.opTake") {
5066
+ if (!isStreamObject(e.args[0]?.type) || !isStreamObject(e.type)) {
5067
+ err(`libCall ${e.fn} must take a stream and return a stream class`, e.loc);
5068
+ }
5069
+ return true;
5070
+ }
5071
+ if (e.fn === "readable.opReduce") {
5072
+ const inner = e.type.kind === "promise" ? e.type.inner : null;
5073
+ const kind = e.args[5]?.kind === "numLit" ? e.args[5].value : -1;
5074
+ const want = [DYN, F64, BOOL, STRING][kind];
5075
+ if (!isStreamObject(e.args[0]?.type) || !inner || !want || !typeEquals(inner, want)) {
5076
+ err(`libCall readable.opReduce must return the promise its kind names`, e.loc);
5077
+ }
5078
+ return true;
5079
+ }
5080
+ if (e.fn === "readable.fromDone") {
5081
+ if (e.args.length !== 0 || e.type.kind !== "dyn")
5082
+ err(`libCall ${e.fn} takes no arguments`, e.loc);
5083
+ return true;
5084
+ }
5085
+ if (e.fn === "readable.fromGen" || e.fn === "readable.fromAsyncGen") {
5086
+ const g = e.args[0]?.type;
5087
+ const helpers = e.fn === "readable.fromGen" ? 3 : 4;
5088
+ if (g?.kind !== "generator" ||
5089
+ (g.async === true) !== (e.fn === "readable.fromAsyncGen") ||
5090
+ !e.args.slice(1, 1 + helpers).every((a) => a.kind === "closure") ||
5091
+ e.args[1 + helpers]?.kind !== "numLit" ||
5092
+ !isStreamObject(e.type)) {
5093
+ err(`libCall ${e.fn} must take a generator, its helpers and the flags`, e.loc);
5094
+ }
5095
+ return true;
5096
+ }
5097
+ if (e.fn === "readable.fromArr" || e.fn === "readable.fromDyn") {
5098
+ // No receiver: the source leads; the result is the class.
5099
+ const src = e.fn === "readable.fromArr" ? "array" : "dyn";
5100
+ if (e.args[0]?.type.kind !== src || !isStreamObject(e.type)) {
5101
+ err(`libCall ${e.fn} must take a ${src} source and return a stream class`, e.loc);
5102
+ }
5103
+ if (e.fn === "readable.fromArr" && e.args[1]?.kind !== "numLit") {
5104
+ err(`libCall readable.fromArr flags must be a number literal`, e.loc);
4915
5105
  }
4916
5106
  return true;
4917
5107
  }