@scriptc/compiler 0.1.1 → 0.1.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 (279) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +104 -31
  2. package/ambient/scriptc.d.ts +2 -1
  3. package/dist/backend/build-cache.js.map +1 -1
  4. package/dist/backend/c/async.d.ts +5 -0
  5. package/dist/backend/c/async.js +81 -2
  6. package/dist/backend/c/async.js.map +1 -1
  7. package/dist/backend/c/c-emitter.d.ts +25 -10
  8. package/dist/backend/c/c-emitter.js +74 -22
  9. package/dist/backend/c/c-emitter.js.map +1 -1
  10. package/dist/backend/c/exprs.d.ts +8 -1
  11. package/dist/backend/c/exprs.js +371 -18
  12. package/dist/backend/c/exprs.js.map +1 -1
  13. package/dist/backend/c/island.js.map +1 -1
  14. package/dist/backend/c/may-throw.js.map +1 -1
  15. package/dist/backend/c/shapes.js +15 -13
  16. package/dist/backend/c/shapes.js.map +1 -1
  17. package/dist/backend/c/stmts.d.ts +3 -5
  18. package/dist/backend/c/stmts.js +58 -17
  19. package/dist/backend/c/stmts.js.map +1 -1
  20. package/dist/backend/c/types.d.ts +4 -0
  21. package/dist/backend/c/types.js +18 -1
  22. package/dist/backend/c/types.js.map +1 -1
  23. package/dist/backend/c/types.test.js +8 -1
  24. package/dist/backend/c/types.test.js.map +1 -1
  25. package/dist/backend/c/walkers.js +63 -16
  26. package/dist/backend/c/walkers.js.map +1 -1
  27. package/dist/backend/external-c.js.map +1 -1
  28. package/dist/backend/json-literal.d.ts +7 -0
  29. package/dist/backend/json-literal.js +17 -0
  30. package/dist/backend/json-literal.js.map +1 -0
  31. package/dist/backend/json-literal.test.d.ts +1 -0
  32. package/dist/backend/json-literal.test.js +17 -0
  33. package/dist/backend/json-literal.test.js.map +1 -0
  34. package/dist/backend/link-plan.d.ts +1 -1
  35. package/dist/backend/link-plan.js +5 -1
  36. package/dist/backend/link-plan.js.map +1 -1
  37. package/dist/backend/linker.js.map +1 -1
  38. package/dist/backend/llvm/blocks.js.map +1 -1
  39. package/dist/backend/llvm/classes.js +8 -7
  40. package/dist/backend/llvm/classes.js.map +1 -1
  41. package/dist/backend/llvm/common.d.ts +4 -0
  42. package/dist/backend/llvm/common.js +6 -0
  43. package/dist/backend/llvm/common.js.map +1 -1
  44. package/dist/backend/llvm/common.test.d.ts +1 -0
  45. package/dist/backend/llvm/common.test.js +9 -0
  46. package/dist/backend/llvm/common.test.js.map +1 -0
  47. package/dist/backend/llvm/dyn.d.ts +4 -0
  48. package/dist/backend/llvm/dyn.js +80 -16
  49. package/dist/backend/llvm/dyn.js.map +1 -1
  50. package/dist/backend/llvm/emitter.js +132 -25
  51. package/dist/backend/llvm/emitter.js.map +1 -1
  52. package/dist/backend/llvm/expr-async.js +85 -3
  53. package/dist/backend/llvm/expr-async.js.map +1 -1
  54. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  55. package/dist/backend/llvm/expr-calls.js.map +1 -1
  56. package/dist/backend/llvm/expr-containers.js.map +1 -1
  57. package/dist/backend/llvm/expr-context.d.ts +5 -0
  58. package/dist/backend/llvm/expr-control.js.map +1 -1
  59. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  60. package/dist/backend/llvm/expr-dynamic.js +15 -3
  61. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  62. package/dist/backend/llvm/expr-island.js.map +1 -1
  63. package/dist/backend/llvm/expr-primitives.js +8 -0
  64. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  65. package/dist/backend/llvm/expr-records.js +3 -3
  66. package/dist/backend/llvm/expr-records.js.map +1 -1
  67. package/dist/backend/llvm/expr-stream-bridges.js +222 -10
  68. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  69. package/dist/backend/llvm/expr-stream-callbacks.d.ts +3 -0
  70. package/dist/backend/llvm/expr-stream-callbacks.js +53 -0
  71. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  72. package/dist/backend/llvm/lib-dispatch.js +24 -0
  73. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  74. package/dist/backend/llvm/lib-process.js +50 -5
  75. package/dist/backend/llvm/lib-process.js.map +1 -1
  76. package/dist/backend/llvm/lib-shared.js +64 -0
  77. package/dist/backend/llvm/lib-shared.js.map +1 -1
  78. package/dist/backend/llvm/lib-stream.js +6 -3
  79. package/dist/backend/llvm/lib-stream.js.map +1 -1
  80. package/dist/backend/llvm/shapes.js +10 -8
  81. package/dist/backend/llvm/shapes.js.map +1 -1
  82. package/dist/backend/llvm/split.js.map +1 -1
  83. package/dist/backend/llvm/unsupported.js.map +1 -1
  84. package/dist/backend/llvm/walkers.js +7 -5
  85. package/dist/backend/llvm/walkers.js.map +1 -1
  86. package/dist/backend/native-codegen.js.map +1 -1
  87. package/dist/backend/native-codegen.test.js +2 -0
  88. package/dist/backend/native-codegen.test.js.map +1 -1
  89. package/dist/backend/native-link-info.d.ts +2 -1
  90. package/dist/backend/native-link-info.js +4 -0
  91. package/dist/backend/native-link-info.js.map +1 -1
  92. package/dist/backend/native-link-info.test.js +24 -1
  93. package/dist/backend/native-link-info.test.js.map +1 -1
  94. package/dist/backend/native-toolchain.d.ts +8 -6
  95. package/dist/backend/native-toolchain.js +28 -13
  96. package/dist/backend/native-toolchain.js.map +1 -1
  97. package/dist/backend/native-toolchain.test.js +36 -1
  98. package/dist/backend/native-toolchain.test.js.map +1 -1
  99. package/dist/backend/runtime-pack-targets.test.js +1 -1
  100. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  101. package/dist/backend/runtime-pack.js.map +1 -1
  102. package/dist/backend/runtime-pack.test.js +1 -0
  103. package/dist/backend/runtime-pack.test.js.map +1 -1
  104. package/dist/backend/targets.d.ts +5 -0
  105. package/dist/backend/targets.js +9 -0
  106. package/dist/backend/targets.js.map +1 -1
  107. package/dist/backend/targets.test.js +6 -1
  108. package/dist/backend/targets.test.js.map +1 -1
  109. package/dist/backend/vendor-archives.js.map +1 -1
  110. package/dist/compat/fetch-profile.js +4 -2
  111. package/dist/compat/fetch-profile.js.map +1 -1
  112. package/dist/coverage/report.js.map +1 -1
  113. package/dist/coverage/surface-manifest.js +13 -0
  114. package/dist/coverage/surface-manifest.js.map +1 -1
  115. package/dist/diagnostics/diagnostic.d.ts +6 -5
  116. package/dist/diagnostics/diagnostic.js +10 -9
  117. package/dist/diagnostics/diagnostic.js.map +1 -1
  118. package/dist/diagnostics/render.js.map +1 -1
  119. package/dist/executable/executable-cache.d.ts +1 -0
  120. package/dist/executable/executable-cache.js +1 -0
  121. package/dist/executable/executable-cache.js.map +1 -1
  122. package/dist/executable/executable-cache.test.js +1 -0
  123. package/dist/executable/executable-cache.test.js.map +1 -1
  124. package/dist/ffi/ffi-manifest.js.map +1 -1
  125. package/dist/frontend/cjs-lexer.js.map +1 -1
  126. package/dist/frontend/dts-paths.js.map +1 -1
  127. package/dist/frontend/input-tracker.d.ts +10 -0
  128. package/dist/frontend/input-tracker.js +26 -3
  129. package/dist/frontend/input-tracker.js.map +1 -1
  130. package/dist/frontend/input-tracker.test.js +8 -1
  131. package/dist/frontend/input-tracker.test.js.map +1 -1
  132. package/dist/frontend/lib-contract.js.map +1 -1
  133. package/dist/frontend/lowering/array-values.d.ts +4 -0
  134. package/dist/frontend/lowering/array-values.js +18 -2
  135. package/dist/frontend/lowering/array-values.js.map +1 -1
  136. package/dist/frontend/lowering/callback-arg.js.map +1 -1
  137. package/dist/frontend/lowering/containers/bytes.d.ts +31 -0
  138. package/dist/frontend/lowering/containers/bytes.js +1105 -0
  139. package/dist/frontend/lowering/containers/bytes.js.map +1 -0
  140. package/dist/frontend/lowering/containers/string-and-regexp.d.ts +17 -0
  141. package/dist/frontend/lowering/containers/string-and-regexp.js +345 -0
  142. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -0
  143. package/dist/frontend/lowering/expressions/evaluation-safety.d.ts +13 -0
  144. package/dist/frontend/lowering/expressions/evaluation-safety.js +76 -0
  145. package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -0
  146. package/dist/frontend/lowering/expressions/object-literals.d.ts +44 -0
  147. package/dist/frontend/lowering/expressions/object-literals.js +1815 -0
  148. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -0
  149. package/dist/frontend/lowering/expressions/optional-chains.d.ts +31 -0
  150. package/dist/frontend/lowering/expressions/optional-chains.js +382 -0
  151. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -0
  152. package/dist/frontend/lowering/expressions/try-lower-expression.d.ts +7 -0
  153. package/dist/frontend/lowering/expressions/try-lower-expression.js +26 -0
  154. package/dist/frontend/lowering/expressions/try-lower-expression.js.map +1 -0
  155. package/dist/frontend/lowering/lib-boundary.js +7 -2
  156. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  157. package/dist/frontend/lowering/lower-assert.js +16 -10
  158. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  159. package/dist/frontend/lowering/lower-async-iteration.d.ts +7 -0
  160. package/dist/frontend/lowering/lower-async-iteration.js +657 -0
  161. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -0
  162. package/dist/frontend/lowering/lower-builtins.d.ts +40 -21
  163. package/dist/frontend/lowering/lower-builtins.js +611 -115
  164. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  165. package/dist/frontend/lowering/lower-calls.d.ts +21 -10
  166. package/dist/frontend/lowering/lower-calls.js +516 -75
  167. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  168. package/dist/frontend/lowering/lower-classes.d.ts +7 -13
  169. package/dist/frontend/lowering/lower-classes.js +128 -35
  170. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  171. package/dist/frontend/lowering/lower-comptime.js.map +1 -1
  172. package/dist/frontend/lowering/lower-containers.d.ts +1 -47
  173. package/dist/frontend/lowering/lower-containers.js +147 -1475
  174. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  175. package/dist/frontend/lowering/lower-event-emitter.js +51 -5
  176. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  177. package/dist/frontend/lowering/lower-exprs.d.ts +0 -78
  178. package/dist/frontend/lowering/lower-exprs.js +503 -2353
  179. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  180. package/dist/frontend/lowering/lower-generators.d.ts +18 -3
  181. package/dist/frontend/lowering/lower-generators.js +145 -9
  182. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  183. package/dist/frontend/lowering/lower-inspect.js +10 -3
  184. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  185. package/dist/frontend/lowering/lower-island.d.ts +6 -0
  186. package/dist/frontend/lowering/lower-island.js +37 -5
  187. package/dist/frontend/lowering/lower-island.js.map +1 -1
  188. package/dist/frontend/lowering/lower-modules.js +60 -15
  189. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  190. package/dist/frontend/lowering/lower-node-module.d.ts +18 -0
  191. package/dist/frontend/lowering/lower-node-module.js +302 -0
  192. package/dist/frontend/lowering/lower-node-module.js.map +1 -0
  193. package/dist/frontend/lowering/lower-server.js +1 -1
  194. package/dist/frontend/lowering/lower-server.js.map +1 -1
  195. package/dist/frontend/lowering/lower-stmts.d.ts +10 -28
  196. package/dist/frontend/lowering/lower-stmts.js +542 -259
  197. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  198. package/dist/frontend/lowering/lower-stream.js +4 -4
  199. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  200. package/dist/frontend/lowering/lowerer.d.ts +41 -38
  201. package/dist/frontend/lowering/lowerer.js +148 -62
  202. package/dist/frontend/lowering/lowerer.js.map +1 -1
  203. package/dist/frontend/lowering/optional-arguments.d.ts +9 -0
  204. package/dist/frontend/lowering/optional-arguments.js +57 -0
  205. package/dist/frontend/lowering/optional-arguments.js.map +1 -0
  206. package/dist/frontend/lowering/surfaces.d.ts +5 -3
  207. package/dist/frontend/lowering/surfaces.js +33 -13
  208. package/dist/frontend/lowering/surfaces.js.map +1 -1
  209. package/dist/frontend/npm-static-declarations.d.ts +35 -0
  210. package/dist/frontend/npm-static-declarations.js +519 -0
  211. package/dist/frontend/npm-static-declarations.js.map +1 -0
  212. package/dist/frontend/npm-static-declarations.test.d.ts +1 -0
  213. package/dist/frontend/npm-static-declarations.test.js +132 -0
  214. package/dist/frontend/npm-static-declarations.test.js.map +1 -0
  215. package/dist/frontend/npm-static.d.ts +2 -0
  216. package/dist/frontend/npm-static.js +26 -10
  217. package/dist/frontend/npm-static.js.map +1 -1
  218. package/dist/frontend/npm.d.ts +60 -0
  219. package/dist/frontend/npm.js +38 -4
  220. package/dist/frontend/npm.js.map +1 -1
  221. package/dist/frontend/npm.test.d.ts +1 -0
  222. package/dist/frontend/npm.test.js +50 -0
  223. package/dist/frontend/npm.test.js.map +1 -0
  224. package/dist/frontend/program.d.ts +3 -2
  225. package/dist/frontend/program.js +513 -70
  226. package/dist/frontend/program.js.map +1 -1
  227. package/dist/frontend/resolve.d.ts +26 -3
  228. package/dist/frontend/resolve.js +166 -29
  229. package/dist/frontend/resolve.js.map +1 -1
  230. package/dist/frontend/resolve.test.js +24 -1
  231. package/dist/frontend/resolve.test.js.map +1 -1
  232. package/dist/frontend/runtime-resolve.d.ts +22 -0
  233. package/dist/frontend/runtime-resolve.js +101 -0
  234. package/dist/frontend/runtime-resolve.js.map +1 -0
  235. package/dist/frontend/runtime-resolve.test.d.ts +1 -0
  236. package/dist/frontend/runtime-resolve.test.js +18 -0
  237. package/dist/frontend/runtime-resolve.test.js.map +1 -0
  238. package/dist/frontend/ts7/adapter.js +12 -13
  239. package/dist/frontend/ts7/adapter.js.map +1 -1
  240. package/dist/frontend/ts7/ast.js.map +1 -1
  241. package/dist/frontend/ts7/census-check.js +3 -3
  242. package/dist/frontend/ts7/census-check.js.map +1 -1
  243. package/dist/frontend/ts7/checker.d.ts +3 -0
  244. package/dist/frontend/ts7/checker.js +12 -3
  245. package/dist/frontend/ts7/checker.js.map +1 -1
  246. package/dist/frontend/ts7/enums.js.map +1 -1
  247. package/dist/frontend/ts7/program-adapter.js +42 -3
  248. package/dist/frontend/ts7/program-adapter.js.map +1 -1
  249. package/dist/frontend/type-mapper.js +171 -16
  250. package/dist/frontend/type-mapper.js.map +1 -1
  251. package/dist/index.js +11 -5
  252. package/dist/index.js.map +1 -1
  253. package/dist/ir/analysis.js +1 -0
  254. package/dist/ir/analysis.js.map +1 -1
  255. package/dist/ir/ir.d.ts +125 -52
  256. package/dist/ir/ir.js +136 -7
  257. package/dist/ir/ir.js.map +1 -1
  258. package/dist/ir/serialize.d.ts +1 -1
  259. package/dist/ir/serialize.js +1 -1
  260. package/dist/ir/validate.js +120 -63
  261. package/dist/ir/validate.js.map +1 -1
  262. package/dist/library/cache-primitives.js.map +1 -1
  263. package/dist/library/cache-reset.test.js.map +1 -1
  264. package/dist/library/compiler-self-identity.js.map +1 -1
  265. package/dist/library/int-infer.js.map +1 -1
  266. package/dist/library/int-infer.test.js +4 -4
  267. package/dist/library/int-infer.test.js.map +1 -1
  268. package/dist/library/library-cache.d.ts +1 -0
  269. package/dist/library/library-cache.js +1 -0
  270. package/dist/library/library-cache.js.map +1 -1
  271. package/dist/library/library-cache.test.js +18 -5
  272. package/dist/library/library-cache.test.js.map +1 -1
  273. package/dist/library/library-profile.js.map +1 -1
  274. package/dist/library/sidecar-validate.js.map +1 -1
  275. package/dist/library/sidecar.js.map +1 -1
  276. package/dist/startup-cache.js.map +1 -1
  277. package/dist/wasi-paths.js.map +1 -1
  278. package/package.json +18 -18
  279. package/surface-manifest.json +91 -20
@@ -1,5 +1,5 @@
1
1
  import { InternalCompilerError } from "../../errors.js";
2
- import { arrayOf, BOOL, BYTES_U8, bytesOf, canMarshalFuncIntoIsland, CHILDSTREAM_T, DYN, F64, islandPromisePayloadTag, isFfiCallbackParam, isFfiContextParam, isFfiReleaseParam, isRefCounted, isUnitType, MAY_THROW_LIB_FNS, RUNTIME_ERROR_CLASSES, STRING, typeEquals, typeKey } from "../../ir/ir.js";
2
+ import { arrayOf, BOOL, BYTES_U8, bytesOf, canMarshalFuncIntoIsland, CHILDSTREAM_T, CHILDWRITER_T, DYN, F64, islandPromisePayloadTag, isClassOwnEnumerableFieldName, isDynTypedRefType, isFfiCallbackParam, isFfiContextParam, isFfiReleaseParam, isRefCounted, isUnitType, MAY_THROW_LIB_FNS, RUNTIME_ERROR_CLASSES, STRING, typeEquals, typeKey } from "../../ir/ir.js";
3
3
  import { boxAccess, BYTES_NUM_KIND_C, BYTES_NUM_VAR_C, bytesElemKindC, cDecl, cFnPtrCast, cNumberLiteral, cStringLiteral, cType, DV_GET_KIND_C, DV_SET_KIND_C, elemAccess, mapKeyAccess, mapKeyKindC, mapValKindC, releaseCallC, retainCallC, vAdapters } from "./types.js";
4
4
  import { mangleClassNew, mangleClassRetain, mangleClassStruct, mangleField, mangleFnClosure, mangleFunction, mangleGlobal, mangleLocal, mangleRecordClone, mangleRecordNew, mangleRecordStruct, mangleVtStruct } from "../mangle.js";
5
5
  import { OVERFLOW_MEMBER } from "./shapes.js";
@@ -20,6 +20,23 @@ function streamTypedRefCommitAdapter(emitter, t, snapshot, defs) {
20
20
  defs.push(`static void ${commit}(void *sc_p, const ScrDyn *sc_d) {`, ` ScrArr *sc_target = (ScrArr *)sc_p;`, ` ScrArr *sc_next = ${emitter.dynCheckHelper(t)}(sc_d, NULL);`, ` if (!sc_next) return;`, ` size_t sc_target_len = sc_target->len;`, ` size_t sc_target_cap = sc_target->cap;`, ` uint64_t *sc_target_data = sc_target->data;`, ` uint8_t *sc_target_present = sc_target->present;`, ` ScrArrSparseSlot *sc_target_sparse = sc_target->sparse;`, ` size_t sc_target_sparse_len = sc_target->sparse_len;`, ` size_t sc_target_sparse_cap = sc_target->sparse_cap;`, ` ScrArrProp *sc_target_props = sc_target->props;`, ` size_t sc_target_prop_len = sc_target->prop_len;`, ` size_t sc_target_prop_cap = sc_target->prop_cap;`, ` sc_target->len = sc_next->len;`, ` sc_target->cap = sc_next->cap;`, ` sc_target->data = sc_next->data;`, ` sc_target->present = sc_next->present;`, ` sc_target->sparse = sc_next->sparse;`, ` sc_target->sparse_len = sc_next->sparse_len;`, ` sc_target->sparse_cap = sc_next->sparse_cap;`, ` sc_target->props = sc_next->props;`, ` sc_target->prop_len = sc_next->prop_len;`, ` sc_target->prop_cap = sc_next->prop_cap;`, ` sc_next->len = sc_target_len;`, ` sc_next->cap = sc_target_cap;`, ` sc_next->data = sc_target_data;`, ` sc_next->present = sc_target_present;`, ` sc_next->sparse = sc_target_sparse;`, ` sc_next->sparse_len = sc_target_sparse_len;`, ` sc_next->sparse_cap = sc_target_sparse_cap;`, ` sc_next->props = sc_target_props;`, ` sc_next->prop_len = sc_target_prop_len;`, ` sc_next->prop_cap = sc_target_prop_cap;`, ` scr_arr_release(sc_next);`, `}`, ``);
21
21
  return `&${commit}`;
22
22
  }
23
+ if (isDynTypedRefType(t)) {
24
+ const meta = emitter.classMeta.get(t.className);
25
+ if (!meta) {
26
+ throw new InternalCompilerError(`emitter bug: typed-ref commit of unknown class ${t.className}`);
27
+ }
28
+ const commit = `${snapshot}_commit`;
29
+ emitter.walkerProtos.push(`static void ${commit}(void *sc_p, const ScrDyn *sc_d); /* commit unknown class ${typeKey(t)} */`);
30
+ defs.push(`static void ${commit}(void *sc_p, const ScrDyn *sc_d) {`, ` ${cDecl(t, "sc_target")} = (${cType(t).trim()})sc_p;`);
31
+ for (const field of meta.def.fields.filter((f) => isClassOwnEnumerableFieldName(f.name))) {
32
+ const member = mangleField(field.name);
33
+ const keyLit = cStringLiteral(Buffer.from(field.name, "utf8"));
34
+ const keyLen = Buffer.byteLength(field.name, "utf8");
35
+ defs.push(` {`, ` const ScrDyn *sc_member = scr_dyn_obj_get(sc_d, ${keyLit}, ${keyLen});`, ` ${cDecl(field.type, "sc_next")} = ${emitter.dynCheckHelper(field.type)}(sc_member ? sc_member : scr_dyn_undefined(), NULL);`, ` if (scr_exc_pending()) return;`, ` ${cDecl(field.type, "sc_old")} = sc_target->${member};`, ` sc_target->${member} = sc_next;`, ...(isRefCounted(field.type) ? [` ${releaseCallC(field.type, "sc_old")};`] : [" (void)sc_old;"]), ` }`);
36
+ }
37
+ defs.push(`}`, ``);
38
+ return `&${commit}`;
39
+ }
23
40
  if (t.kind !== "record")
24
41
  return "NULL";
25
42
  const shape = emitter.recordsById.get(t.shapeId);
@@ -39,6 +56,51 @@ function streamTypedRefCommitAdapter(emitter, t, snapshot, defs) {
39
56
  defs.push(` ${releaseCallC(t, "sc_next")};`, `}`, ``);
40
57
  return `&${commit}`;
41
58
  }
59
+ /** Boxes a union selected at runtime, preserving mutable/class arm identity
60
+ * while converting scalar and unit arms normally. It shares the enclosing
61
+ * adapter context so recursive class fields reuse the prototype already
62
+ * registered by streamTypedRefAdapter instead of recursing forever. */
63
+ function nestedTypedRefUnionAdapter(emitter, t, ctx) {
64
+ const key = typeKey(t);
65
+ const unions = (ctx.unions ??= new Map());
66
+ const existing = unions.get(key);
67
+ if (existing)
68
+ return existing;
69
+ const def = emitter.unionsById.get(t.unionId);
70
+ if (!def)
71
+ throw new InternalCompilerError(`emitter bug: typed-ref union ${t.unionId} is undeclared`);
72
+ const sym = `${ctx.prefix}_union_${unions.size}`;
73
+ unions.set(key, sym);
74
+ emitter.walkerProtos.push(`static ScrDyn *${sym}(ScrUnion *sc_u); /* typed-ref union ${key} */`);
75
+ const lines = [`static ScrDyn *${sym}(ScrUnion *sc_u) {`, ` switch (sc_u->tag) {`];
76
+ def.arms.forEach((arm, tag) => {
77
+ if (streamTypedRefEligible(arm) || isDynTypedRefType(arm)) {
78
+ const adapter = streamTypedRefAdapter(emitter, arm, ctx);
79
+ const rc = vAdapters(arm);
80
+ const armKey = typeKey(arm);
81
+ const keyLit = cStringLiteral(Buffer.from(armKey, "utf8"));
82
+ lines.push(` case ${tag}: return scr_dyn_new_typed_ref(scr_union_peek(sc_u), &${rc.retain}, &${rc.release}, ${keyLit}, ${Buffer.byteLength(armKey, "utf8")}, &${adapter.snapshot}, ${adapter.commit});`);
83
+ }
84
+ else if (arm.kind === "undefinedT") {
85
+ lines.push(` case ${tag}: return scr_dyn_retain(scr_dyn_undefined());`);
86
+ }
87
+ else if (arm.kind === "nullT") {
88
+ lines.push(` case ${tag}: return scr_dyn_new_null();`);
89
+ }
90
+ else if (arm.kind === "f64") {
91
+ lines.push(` case ${tag}: return scr_dyn_new_num(scr_union_get_f64(sc_u));`);
92
+ }
93
+ else if (arm.kind === "bool") {
94
+ lines.push(` case ${tag}: return scr_dyn_new_bool(scr_union_get_bool(sc_u));`);
95
+ }
96
+ else {
97
+ lines.push(` case ${tag}: return ${emitter.toDynHelper(arm)}((${cType(arm).trim()})scr_union_peek(sc_u));`);
98
+ }
99
+ });
100
+ lines.push(` default: scr_trap("scriptc: internal error: invalid union tag\\n");`, ` }`, `}`, ``);
101
+ ctx.defs.push(...lines);
102
+ return sym;
103
+ }
42
104
  /** Build the live dyn view of one typed stream value. Mutable reference
43
105
  * children are capsules of their own, so a write through `v.child.x` or
44
106
  * `v.items[0]` commits directly to that child's static source instead of
@@ -57,7 +119,11 @@ function streamTypedRefAdapter(emitter, t, ctx, preferredSnapshot) {
57
119
  emitter.walkerProtos.push(`static ScrDyn *${snapshot}(void *sc_p); /* materialize live stream value ${key} */`);
58
120
  adapter.commit = streamTypedRefCommitAdapter(emitter, t, snapshot, ctx.defs);
59
121
  const box = (child, expr) => {
60
- if (!streamTypedRefEligible(child)) {
122
+ if (child.kind === "union" &&
123
+ (emitter.unionsById.get(child.unionId)?.arms.some((arm) => streamTypedRefEligible(arm) || isDynTypedRefType(arm)) ?? false)) {
124
+ return `${nestedTypedRefUnionAdapter(emitter, child, ctx)}(${expr})`;
125
+ }
126
+ if (!streamTypedRefEligible(child) && !isDynTypedRefType(child)) {
61
127
  return `${emitter.toDynHelper(child)}(${expr})`;
62
128
  }
63
129
  const nested = streamTypedRefAdapter(emitter, child, ctx);
@@ -70,7 +136,19 @@ function streamTypedRefAdapter(emitter, t, ctx, preferredSnapshot) {
70
136
  `static ScrDyn *${snapshot}(void *sc_p) { /* materialize live stream value ${key} */`,
71
137
  ` ${cDecl(t, "v")} = (${cType(t).trim()})sc_p;`,
72
138
  ];
73
- if (t.kind === "record") {
139
+ if (isDynTypedRefType(t)) {
140
+ const meta = emitter.classMeta.get(t.className);
141
+ if (!meta) {
142
+ throw new InternalCompilerError(`emitter bug: typed-ref materialize of unknown class ${t.className}`);
143
+ }
144
+ lines.push(` ScrDyn *d = scr_dyn_new_obj();`);
145
+ for (const field of meta.def.fields.filter((f) => isClassOwnEnumerableFieldName(f.name))) {
146
+ const keyLit = cStringLiteral(Buffer.from(field.name, "utf8"));
147
+ lines.push(` scr_dyn_obj_set(d, ${keyLit}, ${Buffer.byteLength(field.name, "utf8")}, ${box(field.type, `v->${mangleField(field.name)}`)});`);
148
+ }
149
+ lines.push(` return d;`);
150
+ }
151
+ else if (t.kind === "record") {
74
152
  const shape = emitter.recordsById.get(t.shapeId);
75
153
  if (!shape) {
76
154
  throw new InternalCompilerError(`emitter bug: stream typed-ref materialize of unknown shape ${t.shapeId}`);
@@ -127,12 +205,12 @@ function streamTypedRefAdapter(emitter, t, ctx, preferredSnapshot) {
127
205
  }
128
206
  /** One per-type capsule adapter for Web API arguments whose JavaScript
129
207
  * contract preserves the exact input reference. */
130
- function liveDynRefAdapter(emitter, t) {
208
+ export function liveDynRefAdapter(emitter, t) {
131
209
  const key = typeKey(t);
132
210
  const existing = emitter.liveDynRefAdapters.get(key);
133
211
  if (existing)
134
212
  return existing;
135
- if (!streamTypedRefEligible(t)) {
213
+ if (!streamTypedRefEligible(t) && !isDynTypedRefType(t)) {
136
214
  throw new InternalCompilerError(`emitter bug: live dyn ref of ${key}`);
137
215
  }
138
216
  const prefix = `sc_ldr_${emitter.liveDynRefAdapters.size}`;
@@ -157,7 +235,7 @@ function liveDynUnionRefAdapter(emitter, t) {
157
235
  }
158
236
  const mutableArms = union.arms
159
237
  .map((arm, tag) => ({ arm, tag }))
160
- .filter(({ arm }) => streamTypedRefEligible(arm));
238
+ .filter(({ arm }) => streamTypedRefEligible(arm) || isDynTypedRefType(arm));
161
239
  if (mutableArms.length === 0) {
162
240
  throw new InternalCompilerError(`emitter bug: live dyn ref of immutable union ${key}`);
163
241
  }
@@ -179,7 +257,27 @@ function liveDynUnionRefAdapter(emitter, t) {
179
257
  const keyLit = cStringLiteral(Buffer.from(armKey, "utf8"));
180
258
  defs.push(` case ${tag}:`, ` return scr_dyn_new_typed_ref(scr_union_peek(sc_u), &${rc.retain}, &${rc.release}, ${keyLit}, ${Buffer.byteLength(armKey, "utf8")}, &${adapter.snapshot}, ${adapter.commit});`);
181
259
  }
182
- defs.push(` default:`, ` return ${emitter.toDynHelper(t)}(sc_u);`, ` }`, `}`, ``);
260
+ const mutableTags = new Set(mutableArms.map(({ tag }) => tag));
261
+ union.arms.forEach((arm, tag) => {
262
+ if (mutableTags.has(tag))
263
+ return;
264
+ if (arm.kind === "undefinedT") {
265
+ defs.push(` case ${tag}: return scr_dyn_retain(scr_dyn_undefined());`);
266
+ }
267
+ else if (arm.kind === "nullT") {
268
+ defs.push(` case ${tag}: return scr_dyn_new_null();`);
269
+ }
270
+ else if (arm.kind === "f64") {
271
+ defs.push(` case ${tag}: return scr_dyn_new_num(scr_union_get_f64(sc_u));`);
272
+ }
273
+ else if (arm.kind === "bool") {
274
+ defs.push(` case ${tag}: return scr_dyn_new_bool(scr_union_get_bool(sc_u));`);
275
+ }
276
+ else {
277
+ defs.push(` case ${tag}: return ${emitter.toDynHelper(arm)}((${cType(arm).trim()})scr_union_peek(sc_u));`);
278
+ }
279
+ });
280
+ defs.push(` default: scr_trap("scriptc: internal error: invalid union tag\\n");`, ` }`, `}`, ``);
183
281
  emitter.walkerDefs.push(...defs);
184
282
  return sym;
185
283
  }
@@ -2390,7 +2488,10 @@ function emitDynamicExpr(emitter, e) {
2390
2488
  : "scr_dyn_new_null()");
2391
2489
  }
2392
2490
  const v = emitter.emitExpr(e.value);
2393
- if (e.liveRef) {
2491
+ const identityRef = isDynTypedRefType(v.type) ||
2492
+ (v.type.kind === "union" &&
2493
+ (emitter.unionsById.get(v.type.unionId)?.arms.some(isDynTypedRefType) ?? false));
2494
+ if (e.liveRef || identityRef) {
2394
2495
  if (v.type.kind === "union") {
2395
2496
  const adapter = liveDynUnionRefAdapter(emitter, v.type);
2396
2497
  return emitter.newTemp(e.type, `${adapter}(${v.name})`);
@@ -3072,6 +3173,8 @@ function emitAsyncExpr(emitter, e) {
3072
3173
  throw new InternalCompilerError("emitter bug: yieldExpr with no operand (frontend fills undefined)");
3073
3174
  const v = emitter.emitExpr(e.value);
3074
3175
  const yt = e.value.type;
3176
+ if (e.awaited)
3177
+ emitter.line(`scr_async_gen_hop_done();`);
3075
3178
  if (yt.kind === "f64" || yt.kind === "date") {
3076
3179
  emitter.line(`scr_gen_yield_f64(${v.name});${emitter.srcComment(e.loc)}`);
3077
3180
  }
@@ -3105,8 +3208,9 @@ function emitAsyncExpr(emitter, e) {
3105
3208
  const genT = e.gen.type;
3106
3209
  if (genT.kind !== "generator")
3107
3210
  throw new InternalCompilerError("emitter bug: genResume on a non-generator");
3108
- if (e.type.kind !== "record")
3109
- throw new InternalCompilerError("emitter bug: genResume result is not a record");
3211
+ const resultT = genT.async ? (e.type.kind === "promise" ? e.type.inner : null) : e.type;
3212
+ if (resultT?.kind !== "record")
3213
+ throw new InternalCompilerError("emitter bug: genResume result is not an IteratorResult record");
3110
3214
  const g = emitter.emitExpr(e.gen); // borrowed for the calls below
3111
3215
  const sendArg = (store) => {
3112
3216
  const a = emitter.emitExpr(e.arg);
@@ -3114,6 +3218,76 @@ function emitAsyncExpr(emitter, e) {
3114
3218
  emitter.moveTemp(a); // the slot takes ownership
3115
3219
  emitter.line(store(a));
3116
3220
  };
3221
+ if (genT.async) {
3222
+ let call;
3223
+ if (e.mode === "next") {
3224
+ if (e.arg === null) {
3225
+ if (genT.nextT.kind === "dyn") {
3226
+ call = `scr_async_gen_next_ref(${g.name}, scr_dyn_retain(scr_dyn_undefined()), scr_dyn_release_v)`;
3227
+ }
3228
+ else {
3229
+ call = `scr_async_gen_next_none(${g.name})`;
3230
+ }
3231
+ }
3232
+ else {
3233
+ const a = emitter.emitExpr(e.arg);
3234
+ const t = e.arg.type;
3235
+ if (isRefCounted(t))
3236
+ emitter.moveTemp(a);
3237
+ call = t.kind === "f64" || t.kind === "date"
3238
+ ? `scr_async_gen_next_f64(${g.name}, ${a.name})`
3239
+ : t.kind === "bool"
3240
+ ? `scr_async_gen_next_bool(${g.name}, ${a.name})`
3241
+ : `scr_async_gen_next_ref(${g.name}, ${a.name}, ${vAdapters(t).release})`;
3242
+ }
3243
+ }
3244
+ else if (e.mode === "return") {
3245
+ if (e.arg === null) {
3246
+ call = `scr_async_gen_return_none(${g.name})`;
3247
+ }
3248
+ else {
3249
+ const a = emitter.emitExpr(e.arg);
3250
+ const t = e.arg.type;
3251
+ if (isRefCounted(t))
3252
+ emitter.moveTemp(a);
3253
+ call = t.kind === "f64" || t.kind === "date"
3254
+ ? `scr_async_gen_return_f64(${g.name}, ${a.name})`
3255
+ : t.kind === "bool"
3256
+ ? `scr_async_gen_return_bool(${g.name}, ${a.name})`
3257
+ : `scr_async_gen_return_ref(${g.name}, ${a.name}, ${vAdapters(t).release})`;
3258
+ }
3259
+ }
3260
+ else {
3261
+ if (e.arg === null)
3262
+ throw new InternalCompilerError("emitter bug: async genResume throw with no payload");
3263
+ const a = emitter.emitExpr(e.arg);
3264
+ const t = e.arg.type;
3265
+ if (isRefCounted(t))
3266
+ emitter.moveTemp(a);
3267
+ if (t.kind === "date") {
3268
+ throw new InternalCompilerError("emitter bug: Date async-generator throw reached backend");
3269
+ }
3270
+ else if (t.kind === "f64") {
3271
+ emitter.line(`scr_throw_f64(${a.name});${emitter.srcComment(e.loc)}`);
3272
+ }
3273
+ else if (t.kind === "bool") {
3274
+ emitter.line(`scr_throw_bool(${a.name});${emitter.srcComment(e.loc)}`);
3275
+ }
3276
+ else if (t.kind === "string") {
3277
+ emitter.line(`scr_throw_str(${a.name});${emitter.srcComment(e.loc)}`);
3278
+ }
3279
+ else if (t.kind === "object" && emitter.classMeta.get(t.className)?.hierarchy) {
3280
+ const rc = vAdapters(t);
3281
+ emitter.line(`scr_throw_obj(${a.name}, &${rc.retain}, &${rc.release}, ${emitter.traceArgC(t)});${emitter.srcComment(e.loc)}`);
3282
+ }
3283
+ else {
3284
+ const rc = vAdapters(t);
3285
+ emitter.line(`scr_throw_ref(${a.name}, &${rc.retain}, &${rc.release}, ${emitter.traceArgC(t)});${emitter.srcComment(e.loc)}`);
3286
+ }
3287
+ call = `scr_async_gen_throw(${g.name})`;
3288
+ }
3289
+ return emitter.newTemp(e.type, call);
3290
+ }
3117
3291
  if (e.mode === "next") {
3118
3292
  if (e.arg === null) {
3119
3293
  // Valueless resume: dyn channels read JS's undefined; unit
@@ -3178,7 +3352,7 @@ function emitAsyncExpr(emitter, e) {
3178
3352
  }
3179
3353
  emitter.line(`scr_gen_resume_throw(${g.name});`);
3180
3354
  }
3181
- const helper = genResultThunkFor(emitter, genT, e.type);
3355
+ const helper = genResultThunkFor(emitter, genT, resultT);
3182
3356
  // The record builds before the check so an unwind (a propagated
3183
3357
  // body exception) releases it as the frame's never-read dummy.
3184
3358
  return emitter.fallibleTemp(e.type, `${helper}(${g.name})`);
@@ -4590,6 +4764,62 @@ function emitPrimitiveLibCall(state) {
4590
4764
  return finish(`scr_sym_for(${arg(0)})`);
4591
4765
  case "sym.toString":
4592
4766
  return finish(`scr_sym_to_string(${arg(0)})`);
4767
+ case "bigint.parse":
4768
+ return finish(`scr_bigint_parse(${arg(0)})`);
4769
+ case "bigint.fromF64":
4770
+ return finish(`scr_bigint_from_f64(${arg(0)})`);
4771
+ case "bigint.neg":
4772
+ return finish(`scr_bigint_neg(${arg(0)})`);
4773
+ case "bigint.not":
4774
+ return finish(`scr_bigint_not(${arg(0)})`);
4775
+ case "bigint.add":
4776
+ return finish(`scr_bigint_add(${arg(0)}, ${arg(1)})`);
4777
+ case "bigint.sub":
4778
+ return finish(`scr_bigint_sub(${arg(0)}, ${arg(1)})`);
4779
+ case "bigint.mul":
4780
+ return finish(`scr_bigint_mul(${arg(0)}, ${arg(1)})`);
4781
+ case "bigint.div":
4782
+ return finish(`scr_bigint_div(${arg(0)}, ${arg(1)})`);
4783
+ case "bigint.mod":
4784
+ return finish(`scr_bigint_mod(${arg(0)}, ${arg(1)})`);
4785
+ case "bigint.pow":
4786
+ return finish(`scr_bigint_pow(${arg(0)}, ${arg(1)})`);
4787
+ case "bigint.and":
4788
+ return finish(`scr_bigint_and(${arg(0)}, ${arg(1)})`);
4789
+ case "bigint.or":
4790
+ return finish(`scr_bigint_or(${arg(0)}, ${arg(1)})`);
4791
+ case "bigint.xor":
4792
+ return finish(`scr_bigint_xor(${arg(0)}, ${arg(1)})`);
4793
+ case "bigint.shl":
4794
+ return finish(`scr_bigint_shl(${arg(0)}, ${arg(1)})`);
4795
+ case "bigint.shr":
4796
+ return finish(`scr_bigint_shr(${arg(0)}, ${arg(1)})`);
4797
+ case "bigint.eq":
4798
+ return finish(`scr_bigint_eq(${arg(0)}, ${arg(1)})`);
4799
+ case "bigint.cmp":
4800
+ return finish(`scr_bigint_cmp_f64(${arg(0)}, ${arg(1)})`);
4801
+ case "bigint.cmpNumber":
4802
+ return finish(`scr_bigint_cmp_number(${arg(0)}, ${arg(1)})`);
4803
+ case "bigint.truthy":
4804
+ return finish(`scr_bigint_truthy(${arg(0)})`);
4805
+ case "bigint.toString":
4806
+ return finish(`scr_bigint_to_string(${arg(0)}, ${arg(1)})`);
4807
+ case "bigint.inspect":
4808
+ return finish(`scr_bigint_inspect(${arg(0)})`);
4809
+ case "bigint.toF64":
4810
+ return finish(`scr_bigint_to_f64(${arg(0)})`);
4811
+ case "bigint.asUintN":
4812
+ return finish(`scr_bigint_as_uint_n(${arg(0)}, ${arg(1)})`);
4813
+ case "bigint.asIntN":
4814
+ return finish(`scr_bigint_as_int_n(${arg(0)}, ${arg(1)})`);
4815
+ case "bigint.bufferRead":
4816
+ return finish(`scr_bigint_buffer_read(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)})`);
4817
+ case "bigint.bufferWrite":
4818
+ return finish(`scr_bigint_buffer_write(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)})`);
4819
+ case "bigint.dataViewGet":
4820
+ return finish(`scr_bigint_dataview_get(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)})`);
4821
+ case "bigint.dataViewSet":
4822
+ return finish(`scr_bigint_dataview_set(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)})`);
4593
4823
  case "sym.desc":
4594
4824
  case "sym.keyFor": {
4595
4825
  // `string | undefined` — the child.stdout pattern with a
@@ -4719,7 +4949,7 @@ function emitUtilLibCall(state) {
4719
4949
  }
4720
4950
  }
4721
4951
  function emitCryptoBytesLibCall(state) {
4722
- const { e, arg, finish } = state;
4952
+ const { e, emitter, args, arg, finish } = state;
4723
4953
  const fn = e.fn;
4724
4954
  switch (fn) {
4725
4955
  case "crypto.x509Fingerprint":
@@ -4754,6 +4984,56 @@ function emitCryptoBytesLibCall(state) {
4754
4984
  return finish(`scr_crypto_hash_digest_str(${arg(0)}, ${arg(1)}, ${arg(2)})`);
4755
4985
  case "crypto.hashDigestBytes":
4756
4986
  return finish(`scr_crypto_hash_digest_bytes(${arg(0)}, ${arg(1)}, ${arg(2)})`);
4987
+ case "crypto.hashNew":
4988
+ return finish(`scr_crypto_hash_new(${arg(0)})`);
4989
+ case "crypto.hmacNewStr":
4990
+ return finish(`scr_crypto_hmac_new_str(${arg(0)}, ${arg(1)})`);
4991
+ case "crypto.hmacNewBytes":
4992
+ return finish(`scr_crypto_hmac_new_bytes(${arg(0)}, ${arg(1)})`);
4993
+ case "crypto.hashUpdateStr":
4994
+ case "crypto.hmacUpdateStr":
4995
+ return finish(`scr_crypto_hash_update_str(${arg(0)}, ${arg(1)})`);
4996
+ case "crypto.hashUpdateBytes":
4997
+ case "crypto.hmacUpdateBytes":
4998
+ return finish(`scr_crypto_hash_update_bytes(${arg(0)}, ${arg(1)})`);
4999
+ case "crypto.hashCopy":
5000
+ return finish(`scr_crypto_hash_copy(${arg(0)})`);
5001
+ case "crypto.hashDigestString":
5002
+ case "crypto.hmacDigestString":
5003
+ return finish(`scr_crypto_hash_digest_string(${arg(0)}, ${arg(1)})`);
5004
+ case "crypto.hashDigestBuffer":
5005
+ case "crypto.hmacDigestBuffer":
5006
+ return finish(`scr_crypto_hash_digest_buffer(${arg(0)})`);
5007
+ case "crypto.timingSafeEqual":
5008
+ return finish(`scr_crypto_timing_safe_equal(${arg(0)}, ${arg(1)})`);
5009
+ case "crypto.randomFill":
5010
+ return finish(`scr_crypto_random_fill(${arg(0)}, ${arg(1)}, ${arg(2)})`);
5011
+ case "crypto.randomFillRest":
5012
+ return finish(`scr_crypto_random_fill_rest(${arg(0)}, ${arg(1)})`);
5013
+ case "crypto.randomInt":
5014
+ return finish(`scr_crypto_random_int(${arg(0)}, ${arg(1)})`);
5015
+ case "crypto.pbkdf2":
5016
+ return finish(`scr_crypto_pbkdf2(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)})`);
5017
+ case "crypto.randomBytesCb":
5018
+ case "crypto.pbkdf2Cb": {
5019
+ emitter.usesTimers = true;
5020
+ const cbIndex = fn === "crypto.randomBytesCb" ? 1 : 5;
5021
+ const cbT = e.args[cbIndex].type;
5022
+ if (cbT.kind !== "func")
5023
+ throw new InternalCompilerError("emitter bug: crypto callback not a func");
5024
+ const callback = args[cbIndex];
5025
+ emitter.moveTemp(callback);
5026
+ const adapter = emitter.cryptoBytesThunkFor(cbT);
5027
+ if (fn === "crypto.randomBytesCb") {
5028
+ emitter.line(`scr_crypto_random_bytes_async(${arg(0)}, ${callback.name}, &${adapter});${emitter.srcComment(e.loc)}`);
5029
+ }
5030
+ else {
5031
+ emitter.line(`scr_crypto_pbkdf2_async(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${callback.name}, &${adapter});${emitter.srcComment(e.loc)}`);
5032
+ }
5033
+ if (MAY_THROW_LIB_FNS.has(fn))
5034
+ emitter.emitPendingCheck();
5035
+ return { name: "", type: e.type };
5036
+ }
4757
5037
  // The Buffer statics (scr_bytes.c): fromStr decodes Node-
4758
5038
  // leniently (never throws), concat copies its borrowed list.
4759
5039
  case "buffer.fromStr":
@@ -4892,26 +5172,59 @@ function emitChildProcessLibCall(state) {
4892
5172
  const absent = emitter.unitInstanceRef(e.type.unionId, unitTag);
4893
5173
  return emitter.newTemp(e.type, `${has}(${arg(0)}) ? ${present} : ${absent}`);
4894
5174
  }
5175
+ case "child.stdin":
4895
5176
  case "child.stdout":
4896
5177
  case "child.stderr": {
4897
- // `Readable | null` — the child.pid pattern with a REF arm:
4898
- // the runtime answers a +1 stream handle or NULL (not piped).
5178
+ // `Writable | null` / `Readable | null` — the child.pid
5179
+ // pattern with a REF arm: the runtime answers a +1 stream
5180
+ // handle or NULL (not piped).
4899
5181
  if (e.type.kind !== "union") {
4900
5182
  throw new InternalCompilerError(`emitter bug: ${e.fn} result is not a union`);
4901
5183
  }
4902
5184
  const def = emitter.unionsById.get(e.type.unionId);
4903
- const streamTag = def ? def.arms.findIndex((a) => a.kind === "childStream") : -1;
5185
+ const writer = e.fn === "child.stdin";
5186
+ const streamTag = def ? def.arms.findIndex((a) => a.kind === (writer ? "childWriter" : "childStream")) : -1;
4904
5187
  const nullTag = def ? def.arms.findIndex((a) => a.kind === "nullT") : -1;
4905
5188
  if (streamTag < 0 || nullTag < 0) {
4906
5189
  throw new InternalCompilerError(`emitter bug: ${e.fn} union lacks its arms`);
4907
5190
  }
4908
- const get = e.fn === "child.stdout" ? "scr_child_stdout" : "scr_child_stderr";
4909
- const raw = emitter.newTemp(CHILDSTREAM_T, `${get}(${arg(0)})`);
5191
+ const get = writer ? "scr_child_stdin" : e.fn === "child.stdout" ? "scr_child_stdout" : "scr_child_stderr";
5192
+ const rawType = writer ? CHILDWRITER_T : CHILDSTREAM_T;
5193
+ const raw = emitter.newTemp(rawType, `${get}(${arg(0)})`);
4910
5194
  emitter.moveTemp(raw); // ownership passes into the union arm below
4911
- const present = `scr_union_new_ref(${streamTag}, ${raw.name}, &scr_child_stream_retain_v, &scr_child_stream_release_v, NULL)`;
5195
+ const stem = writer ? "scr_child_writer" : "scr_child_stream";
5196
+ const present = `scr_union_new_ref(${streamTag}, ${raw.name}, &${stem}_retain_v, &${stem}_release_v, NULL)`;
4912
5197
  const absent = emitter.unitInstanceRef(e.type.unionId, nullTag);
4913
5198
  return emitter.newTemp(e.type, `${raw.name} != NULL ? ${present} : ${absent}`);
4914
5199
  }
5200
+ case "writer.writeString":
5201
+ return finish(`scr_child_writer_write_string(${arg(0)}, ${arg(1)})`);
5202
+ case "writer.writeBytes":
5203
+ return finish(`scr_child_writer_write_bytes(${arg(0)}, ${arg(1)})`);
5204
+ case "writer.end":
5205
+ return finish(`scr_child_writer_end(${arg(0)})`);
5206
+ case "writer.destroy":
5207
+ return finish(`scr_child_writer_destroy(${arg(0)})`);
5208
+ case "writer.writable":
5209
+ return finish(`scr_child_writer_writable(${arg(0)})`);
5210
+ case "writer.onDrain":
5211
+ case "writer.onFinish": {
5212
+ const cb = args[1];
5213
+ emitter.moveTemp(cb);
5214
+ const fnName = fn === "writer.onDrain" ? "scr_child_writer_on_drain" : "scr_child_writer_on_finish";
5215
+ emitter.line(`${fnName}(${arg(0)}, ${cb.name}, ${arg(2)});${emitter.srcComment(e.loc)}`);
5216
+ return { name: "", type: e.type };
5217
+ }
5218
+ case "writer.onError": {
5219
+ const cbT = e.args[1].type;
5220
+ if (cbT.kind !== "func")
5221
+ throw new InternalCompilerError("emitter bug: writer.onError callback not a func");
5222
+ const cb = args[1];
5223
+ emitter.moveTemp(cb);
5224
+ const adapter = cbT.params.length === 0 ? "scr_child_err_thunk0" : "scr_child_err_thunk_error";
5225
+ emitter.line(`scr_child_writer_on_error(${arg(0)}, ${cb.name}, &${adapter}, ${arg(2)});${emitter.srcComment(e.loc)}`);
5226
+ return { name: "", type: e.type };
5227
+ }
4915
5228
  case "procStream.write":
4916
5229
  // The receiver IS the fd scalar; dispatches onto the exact
4917
5230
  // promptly-submitted stdout/stderr paths (ordering identical).
@@ -6747,6 +7060,38 @@ function emitProcessLibCall(state) {
6747
7060
  return finish(`scr_process_getuid()`);
6748
7061
  case "process.uptime":
6749
7062
  return finish(`scr_process_uptime()`);
7063
+ case "module.registryInit":
7064
+ return finish(`scr_module_registry_init(${arg(0)})`);
7065
+ case "module.define":
7066
+ return finish(`scr_module_define(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`);
7067
+ case "module.enter":
7068
+ return finish(`scr_module_enter(${arg(0)})`);
7069
+ case "module.link":
7070
+ return finish(`scr_module_link(${arg(0)}, ${arg(1)})`);
7071
+ case "module.finish":
7072
+ return finish(`scr_module_finish(${arg(0)})`);
7073
+ case "module.fail":
7074
+ return finish(`scr_module_fail(${arg(0)})`);
7075
+ case "module.filename":
7076
+ return finish(`scr_module_filename(${arg(0)})`);
7077
+ case "module.id":
7078
+ return finish(`scr_module_id(${arg(0)})`);
7079
+ case "module.path":
7080
+ return finish(`scr_module_path(${arg(0)})`);
7081
+ case "module.paths":
7082
+ return finish(`scr_module_paths(${arg(0)})`);
7083
+ case "module.children":
7084
+ return finish(`scr_module_children(${arg(0)})`);
7085
+ case "module.parent":
7086
+ return finish(`scr_module_parent(${arg(0)})`);
7087
+ case "module.loaded":
7088
+ return finish(`scr_module_loaded(${arg(0)})`);
7089
+ case "module.cacheGet":
7090
+ return finish(`scr_module_cache_get(${arg(0)})`);
7091
+ case "module.cacheHas":
7092
+ return finish(`scr_module_cache_has(${arg(0)})`);
7093
+ case "module.cacheKeys":
7094
+ return finish(`scr_module_cache_keys()`);
6750
7095
  case "process.availableMemory":
6751
7096
  return finish(`scr_available_memory()`);
6752
7097
  case "process.constrainedMemory":
@@ -7492,6 +7837,9 @@ function emitStreamLibCall(state) {
7492
7837
  case "stream.destroyErr":
7493
7838
  emitter.usesTimers = true;
7494
7839
  return finish(`(${cType(e.type).trim()})scr_stream_destroy((ScrStream *)${arg(0)}, ${arg(1)})`);
7840
+ case "stream.iteratorClose":
7841
+ emitter.usesTimers = true;
7842
+ return finish(`(${cType(e.type).trim()})scr_stream_iterator_close((ScrStream *)${arg(0)})`);
7495
7843
  case "stream.prop": {
7496
7844
  // The property NAME is a compile-time literal; args[1]'s
7497
7845
  // emitted temp is unused (released with the statement's frame).
@@ -7533,6 +7881,8 @@ function emitAssertInspectLibCall(state) {
7533
7881
  return finish(`scr_assert_ok(${arg(0)}, ${arg(1)})`);
7534
7882
  case "assert.eqF64":
7535
7883
  return finish(`scr_assert_eq_f64(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`);
7884
+ case "assert.eqBigInt":
7885
+ return finish(`scr_assert_eq_bigint(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`);
7536
7886
  case "assert.eqStr":
7537
7887
  return finish(`scr_assert_eq_str(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`);
7538
7888
  case "assert.eqBool":
@@ -7751,6 +8101,7 @@ function emitLibCallExpr(emitter, e) {
7751
8101
  case "regexp":
7752
8102
  case "intl":
7753
8103
  case "sym":
8104
+ case "bigint":
7754
8105
  case "perf":
7755
8106
  case "number":
7756
8107
  case "date":
@@ -7767,6 +8118,7 @@ function emitLibCallExpr(emitter, e) {
7767
8118
  case "cp":
7768
8119
  case "spawnRes":
7769
8120
  case "child":
8121
+ case "writer":
7770
8122
  case "procStream":
7771
8123
  return emitChildProcessLibCall(state);
7772
8124
  case "net":
@@ -7791,6 +8143,7 @@ function emitLibCallExpr(emitter, e) {
7791
8143
  return emitAsyncContextLibCall(state);
7792
8144
  case "process":
7793
8145
  case "stdin":
8146
+ case "module":
7794
8147
  return emitProcessLibCall(state);
7795
8148
  case "error":
7796
8149
  case "regex":