@scriptc/compiler 0.1.2 → 0.1.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 (206) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +258 -64
  2. package/dist/backend/c/async.d.ts +30 -0
  3. package/dist/backend/c/async.js +224 -0
  4. package/dist/backend/c/async.js.map +1 -1
  5. package/dist/backend/c/c-emitter.d.ts +13 -0
  6. package/dist/backend/c/c-emitter.js +28 -9
  7. package/dist/backend/c/c-emitter.js.map +1 -1
  8. package/dist/backend/c/exprs.d.ts +8 -1
  9. package/dist/backend/c/exprs.js +445 -60
  10. package/dist/backend/c/exprs.js.map +1 -1
  11. package/dist/backend/c/shapes.js +15 -13
  12. package/dist/backend/c/shapes.js.map +1 -1
  13. package/dist/backend/c/types.d.ts +4 -0
  14. package/dist/backend/c/types.js +20 -1
  15. package/dist/backend/c/types.js.map +1 -1
  16. package/dist/backend/c/types.test.js +8 -1
  17. package/dist/backend/c/types.test.js.map +1 -1
  18. package/dist/backend/c/walkers.js +32 -11
  19. package/dist/backend/c/walkers.js.map +1 -1
  20. package/dist/backend/json-literal.d.ts +7 -0
  21. package/dist/backend/json-literal.js +17 -0
  22. package/dist/backend/json-literal.js.map +1 -0
  23. package/dist/backend/json-literal.test.d.ts +1 -0
  24. package/dist/backend/json-literal.test.js +17 -0
  25. package/dist/backend/json-literal.test.js.map +1 -0
  26. package/dist/backend/link-plan.d.ts +2 -1
  27. package/dist/backend/link-plan.js +6 -1
  28. package/dist/backend/link-plan.js.map +1 -1
  29. package/dist/backend/llvm/classes.js +8 -7
  30. package/dist/backend/llvm/classes.js.map +1 -1
  31. package/dist/backend/llvm/common.d.ts +4 -0
  32. package/dist/backend/llvm/common.js +6 -0
  33. package/dist/backend/llvm/common.js.map +1 -1
  34. package/dist/backend/llvm/common.test.d.ts +1 -0
  35. package/dist/backend/llvm/common.test.js +9 -0
  36. package/dist/backend/llvm/common.test.js.map +1 -0
  37. package/dist/backend/llvm/dyn.d.ts +4 -0
  38. package/dist/backend/llvm/dyn.js +24 -13
  39. package/dist/backend/llvm/dyn.js.map +1 -1
  40. package/dist/backend/llvm/emitter.js +54 -12
  41. package/dist/backend/llvm/emitter.js.map +1 -1
  42. package/dist/backend/llvm/expr-bytes.d.ts +1 -1
  43. package/dist/backend/llvm/expr-bytes.js +8 -8
  44. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  45. package/dist/backend/llvm/expr-callbacks.d.ts +9 -0
  46. package/dist/backend/llvm/expr-callbacks.js +125 -0
  47. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  48. package/dist/backend/llvm/expr-context.d.ts +18 -2
  49. package/dist/backend/llvm/expr-dispatch.js +1 -0
  50. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  51. package/dist/backend/llvm/expr-dynamic.js +9 -0
  52. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  53. package/dist/backend/llvm/expr-primitives.d.ts +1 -1
  54. package/dist/backend/llvm/expr-primitives.js +38 -9
  55. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  56. package/dist/backend/llvm/expr-primitives.test.d.ts +1 -0
  57. package/dist/backend/llvm/expr-primitives.test.js +38 -0
  58. package/dist/backend/llvm/expr-primitives.test.js.map +1 -0
  59. package/dist/backend/llvm/expr-records.js +3 -3
  60. package/dist/backend/llvm/expr-records.js.map +1 -1
  61. package/dist/backend/llvm/expr-stream-bridges.js +2 -1
  62. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  63. package/dist/backend/llvm/expr-stream-callbacks.d.ts +6 -0
  64. package/dist/backend/llvm/expr-stream-callbacks.js +122 -0
  65. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  66. package/dist/backend/llvm/lib-dispatch.js +22 -0
  67. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  68. package/dist/backend/llvm/lib-filesystem.js +68 -10
  69. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  70. package/dist/backend/llvm/lib-network.js +18 -2
  71. package/dist/backend/llvm/lib-network.js.map +1 -1
  72. package/dist/backend/llvm/lib-process.js +206 -11
  73. package/dist/backend/llvm/lib-process.js.map +1 -1
  74. package/dist/backend/llvm/lib-shared.js +82 -0
  75. package/dist/backend/llvm/lib-shared.js.map +1 -1
  76. package/dist/backend/llvm/lib-stream.js +23 -0
  77. package/dist/backend/llvm/lib-stream.js.map +1 -1
  78. package/dist/backend/llvm/shapes.js +10 -8
  79. package/dist/backend/llvm/shapes.js.map +1 -1
  80. package/dist/backend/llvm/walkers.js +7 -5
  81. package/dist/backend/llvm/walkers.js.map +1 -1
  82. package/dist/backend/native-link-info.d.ts +2 -1
  83. package/dist/backend/native-link-info.js +4 -0
  84. package/dist/backend/native-link-info.js.map +1 -1
  85. package/dist/backend/native-link-info.test.js +24 -1
  86. package/dist/backend/native-link-info.test.js.map +1 -1
  87. package/dist/backend/native-toolchain.d.ts +11 -6
  88. package/dist/backend/native-toolchain.js +30 -13
  89. package/dist/backend/native-toolchain.js.map +1 -1
  90. package/dist/backend/native-toolchain.test.js +36 -1
  91. package/dist/backend/native-toolchain.test.js.map +1 -1
  92. package/dist/backend/runtime-pack-targets.test.js +1 -1
  93. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  94. package/dist/backend/runtime-pack.test.js +29 -10
  95. package/dist/backend/runtime-pack.test.js.map +1 -1
  96. package/dist/backend/targets.d.ts +9 -0
  97. package/dist/backend/targets.js +22 -0
  98. package/dist/backend/targets.js.map +1 -1
  99. package/dist/backend/targets.test.js +13 -1
  100. package/dist/backend/targets.test.js.map +1 -1
  101. package/dist/coverage/surface-manifest.js +9 -0
  102. package/dist/coverage/surface-manifest.js.map +1 -1
  103. package/dist/diagnostics/diagnostic.js +4 -4
  104. package/dist/diagnostics/diagnostic.js.map +1 -1
  105. package/dist/executable/executable-cache.d.ts +3 -0
  106. package/dist/executable/executable-cache.js +4 -0
  107. package/dist/executable/executable-cache.js.map +1 -1
  108. package/dist/executable/executable-cache.test.js +1 -0
  109. package/dist/executable/executable-cache.test.js.map +1 -1
  110. package/dist/frontend/fork-target.d.ts +17 -0
  111. package/dist/frontend/fork-target.js +256 -0
  112. package/dist/frontend/fork-target.js.map +1 -0
  113. package/dist/frontend/lowering/abstract-equality.d.ts +6 -0
  114. package/dist/frontend/lowering/abstract-equality.js +250 -0
  115. package/dist/frontend/lowering/abstract-equality.js.map +1 -0
  116. package/dist/frontend/lowering/containers/bytes.d.ts +0 -4
  117. package/dist/frontend/lowering/containers/bytes.js +112 -28
  118. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  119. package/dist/frontend/lowering/lower-assert.js +87 -12
  120. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  121. package/dist/frontend/lowering/lower-builtins.d.ts +72 -44
  122. package/dist/frontend/lowering/lower-builtins.js +1323 -165
  123. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  124. package/dist/frontend/lowering/lower-calls.d.ts +37 -27
  125. package/dist/frontend/lowering/lower-calls.js +682 -132
  126. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  127. package/dist/frontend/lowering/lower-classes.js +39 -8
  128. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  129. package/dist/frontend/lowering/lower-containers.js +162 -8
  130. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  131. package/dist/frontend/lowering/lower-event-emitter.js +212 -21
  132. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  133. package/dist/frontend/lowering/lower-exprs.js +238 -87
  134. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  135. package/dist/frontend/lowering/lower-inspect.d.ts +4 -0
  136. package/dist/frontend/lowering/lower-inspect.js +8 -1
  137. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  138. package/dist/frontend/lowering/lower-island.d.ts +6 -3
  139. package/dist/frontend/lowering/lower-island.js +165 -6
  140. package/dist/frontend/lowering/lower-island.js.map +1 -1
  141. package/dist/frontend/lowering/lower-modules.d.ts +6 -0
  142. package/dist/frontend/lowering/lower-modules.js +192 -38
  143. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  144. package/dist/frontend/lowering/lower-namespaces.js +7 -0
  145. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  146. package/dist/frontend/lowering/lower-server.d.ts +1 -1
  147. package/dist/frontend/lowering/lower-server.js +130 -27
  148. package/dist/frontend/lowering/lower-server.js.map +1 -1
  149. package/dist/frontend/lowering/lower-stmts.d.ts +5 -4
  150. package/dist/frontend/lowering/lower-stmts.js +141 -21
  151. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  152. package/dist/frontend/lowering/lower-stream.d.ts +3 -0
  153. package/dist/frontend/lowering/lower-stream.js +7 -0
  154. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  155. package/dist/frontend/lowering/lowerer.d.ts +90 -13
  156. package/dist/frontend/lowering/lowerer.js +416 -76
  157. package/dist/frontend/lowering/lowerer.js.map +1 -1
  158. package/dist/frontend/lowering/surfaces.d.ts +31 -3
  159. package/dist/frontend/lowering/surfaces.js +173 -90
  160. package/dist/frontend/lowering/surfaces.js.map +1 -1
  161. package/dist/frontend/npm-static-declarations.d.ts +4 -0
  162. package/dist/frontend/npm-static-declarations.js +83 -14
  163. package/dist/frontend/npm-static-declarations.js.map +1 -1
  164. package/dist/frontend/npm-static-declarations.test.js +33 -2
  165. package/dist/frontend/npm-static-declarations.test.js.map +1 -1
  166. package/dist/frontend/npm-static.js +6 -5
  167. package/dist/frontend/npm-static.js.map +1 -1
  168. package/dist/frontend/npm.d.ts +15 -3
  169. package/dist/frontend/npm.js +80 -8
  170. package/dist/frontend/npm.js.map +1 -1
  171. package/dist/frontend/npm.test.js +76 -9
  172. package/dist/frontend/npm.test.js.map +1 -1
  173. package/dist/frontend/program.js +110 -12
  174. package/dist/frontend/program.js.map +1 -1
  175. package/dist/frontend/resolve.d.ts +28 -7
  176. package/dist/frontend/resolve.js +90 -26
  177. package/dist/frontend/resolve.js.map +1 -1
  178. package/dist/frontend/resolve.test.js +21 -1
  179. package/dist/frontend/resolve.test.js.map +1 -1
  180. package/dist/frontend/type-mapper.d.ts +5 -0
  181. package/dist/frontend/type-mapper.js +115 -33
  182. package/dist/frontend/type-mapper.js.map +1 -1
  183. package/dist/index.d.ts +5 -0
  184. package/dist/index.js +30 -3
  185. package/dist/index.js.map +1 -1
  186. package/dist/ir/analysis.js +1 -0
  187. package/dist/ir/analysis.js.map +1 -1
  188. package/dist/ir/ir.d.ts +155 -66
  189. package/dist/ir/ir.js +143 -6
  190. package/dist/ir/ir.js.map +1 -1
  191. package/dist/ir/ir.test.js +14 -1
  192. package/dist/ir/ir.test.js.map +1 -1
  193. package/dist/ir/serialize.d.ts +1 -1
  194. package/dist/ir/serialize.js +1 -1
  195. package/dist/ir/serialize.js.map +1 -1
  196. package/dist/ir/validate.js +242 -18
  197. package/dist/ir/validate.js.map +1 -1
  198. package/dist/library/int-infer.test.js +4 -4
  199. package/dist/library/int-infer.test.js.map +1 -1
  200. package/dist/library/library-cache.d.ts +1 -0
  201. package/dist/library/library-cache.js +1 -0
  202. package/dist/library/library-cache.js.map +1 -1
  203. package/dist/library/library-cache.test.js +18 -5
  204. package/dist/library/library-cache.test.js.map +1 -1
  205. package/package.json +17 -17
  206. package/surface-manifest.json +163 -54
@@ -1,5 +1,5 @@
1
1
  import { InternalCompilerError } from "../../errors.js";
2
- import { arrayOf, BOOL, BYTES_U8, bytesOf, canMarshalFuncIntoIsland, CHILDSTREAM_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";
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";
@@ -205,7 +205,7 @@ function streamTypedRefAdapter(emitter, t, ctx, preferredSnapshot) {
205
205
  }
206
206
  /** One per-type capsule adapter for Web API arguments whose JavaScript
207
207
  * contract preserves the exact input reference. */
208
- function liveDynRefAdapter(emitter, t) {
208
+ export function liveDynRefAdapter(emitter, t) {
209
209
  const key = typeKey(t);
210
210
  const existing = emitter.liveDynRefAdapters.get(key);
211
211
  if (existing)
@@ -547,6 +547,10 @@ function emitLiteralExpr(emitter, e) {
547
547
  const sym = emitter.internLiteral(e.value);
548
548
  return emitter.newTemp(e.type, retainCallC(e.type, `(ScrStr *)&${sym}`));
549
549
  }
550
+ case "moduleNsRef": {
551
+ const sym = emitter.internLiteral(`module:${e.moduleId}`);
552
+ return emitter.newTemp(e.type, retainCallC(e.type, `(ScrStr *)&${sym}`));
553
+ }
550
554
  case "unitLit":
551
555
  // unitLits are consumed inline by the unionWrap case (a unit arm is
552
556
  // tag-only); one reaching the generic dispatch escaped its wrap.
@@ -4016,6 +4020,11 @@ function emitDynamicLibCall(state) {
4016
4020
  // +1 string or NULL with the exception pending (user
4017
4021
  // toString/valueOf throws propagate). Borrows the dyn.
4018
4022
  return finish(`scr_dyn_string_coerce_js(${arg(0)})`);
4023
+ case "dyn.toNumberCoerce":
4024
+ // JS ToNumber (number-hint valueOf/toString protocol). A
4025
+ // thrown hook leaves the exception pending; the may-throw
4026
+ // epilogue abandons the NaN dummy.
4027
+ return finish(`scr_dyn_number_coerce(${arg(0)})`);
4019
4028
  case "global.undefRead":
4020
4029
  // A declare-d const nothing defines: Node's catchable
4021
4030
  // ReferenceError at the access (always throws — the typed
@@ -4103,22 +4112,28 @@ function emitFilesystemLibCall(state) {
4103
4112
  return finish(`scr_fs_rmdir(${arg(0)})`);
4104
4113
  case "fs.readdirSync":
4105
4114
  return finish(`scr_fs_readdir(${arg(0)})`);
4106
- case "fs.readdirTypesSync": {
4115
+ case "fs.readdirTypesSync":
4116
+ case "fsp.readdirTypes": {
4107
4117
  // Dirent rows assembled inline from one scandir snapshot
4108
4118
  // (scr_lib.c) — the os.networkInterfaces pattern, flat. The
4109
4119
  // frontend/validator pinned the shape ({%dtype, name,
4110
- // parentPath}); lookups here only guard emitter bugs. The
4111
- // snapshot call throws Node's scandir error (may-throw seed
4112
- // set) and answers NULL then, so the pending check runs
4113
- // before any allocation.
4114
- if (e.type.kind !== "array" || e.type.elem.kind !== "record") {
4115
- throw new InternalCompilerError("emitter bug: readdirTypesSync result is not a record array");
4116
- }
4117
- const recT = e.type.elem;
4120
+ // parentPath}); lookups here only guard emitter bugs. The sync
4121
+ // form checks the snapshot's scandir error immediately. The
4122
+ // promise form lets NULL flow through the null-tolerant count/
4123
+ // free accessors, builds an empty dummy array, and moves it to
4124
+ // settled_ref: the pending exception becomes the rejection and
4125
+ // settled_ref releases that dummy.
4126
+ const promiseForm = e.fn === "fsp.readdirTypes";
4127
+ const arrayT = promiseForm && e.type.kind === "promise" ? e.type.inner : e.type;
4128
+ if (arrayT.kind !== "array" || arrayT.elem.kind !== "record") {
4129
+ throw new InternalCompilerError(`emitter bug: ${e.fn} result is not a Dirent record array`);
4130
+ }
4131
+ const recT = arrayT.elem;
4118
4132
  const snap = `sc_t${emitter.tempCounter++}`;
4119
4133
  emitter.line(`ScrScandir *${snap} = scr_fs_scandir(${arg(0)});${emitter.srcComment(e.loc)}`);
4120
- emitter.emitPendingCheck();
4121
- const out = emitter.newTemp(e.type, emitter.arrNewC(recT, `scr_fs_scandir_count(${snap})`));
4134
+ if (!promiseForm)
4135
+ emitter.emitPendingCheck();
4136
+ const out = emitter.newTemp(arrayT, emitter.arrNewC(recT, `scr_fs_scandir_count(${snap})`));
4122
4137
  const i = `sc_t${emitter.tempCounter++}`;
4123
4138
  const n = `sc_t${emitter.tempCounter++}`;
4124
4139
  emitter.line(`for (size_t ${i} = 0, ${n} = scr_fs_scandir_count(${snap}); ${i} < ${n}; ${i}++) {`);
@@ -4132,6 +4147,11 @@ function emitFilesystemLibCall(state) {
4132
4147
  emitter.indent--;
4133
4148
  emitter.line(`}`);
4134
4149
  emitter.line(`scr_fs_scandir_free(${snap});`);
4150
+ if (promiseForm) {
4151
+ const rc = vAdapters(arrayT);
4152
+ emitter.moveTemp(out); // promise fulfillment owns the result array
4153
+ return finish(`scr_promise_settled_ref(${out.name}, &${rc.retain}, &${rc.release}, ${emitter.traceArgC(arrayT)})`);
4154
+ }
4135
4155
  return out;
4136
4156
  }
4137
4157
  // Stats (scr_lib.c): statSync throws like the other sync fs
@@ -4140,6 +4160,16 @@ function emitFilesystemLibCall(state) {
4140
4160
  // Throws Node-shaped fs errors (may-throw seed set); the fd
4141
4161
  // comes back as f64.
4142
4162
  return finish(`scr_fs_open(${arg(0)}, ${arg(1)})`);
4163
+ case "fs.openNumericSync":
4164
+ return finish(`scr_fs_open_numeric(${arg(0)}, ${arg(1)}, ${arg(2)})`);
4165
+ case "fs.fstatSync":
4166
+ return finish(`scr_fs_fstat(${arg(0)})`);
4167
+ case "fs.fchmodSync":
4168
+ return finish(`scr_fs_fchmod(${arg(0)}, ${arg(1)})`);
4169
+ case "fs.fsyncSync":
4170
+ return finish(`scr_fs_fsync(${arg(0)})`);
4171
+ case "fs.linkSync":
4172
+ return finish(`scr_fs_link(${arg(0)}, ${arg(1)})`);
4143
4173
  case "fs.readSync":
4144
4174
  return finish(`scr_fs_read_sync(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)})`);
4145
4175
  case "fs.writeSync":
@@ -4182,12 +4212,18 @@ function emitFilesystemLibCall(state) {
4182
4212
  return finish(`scr_stats_atime_ms(${arg(0)})`);
4183
4213
  case "stats.mtimeMs":
4184
4214
  return finish(`scr_stats_mtime_ms(${arg(0)})`);
4215
+ case "stats.ctimeMs":
4216
+ return finish(`scr_stats_ctime_ms(${arg(0)})`);
4185
4217
  case "stats.isFile":
4186
4218
  return finish(`scr_stats_is_file(${arg(0)})`);
4187
4219
  case "stats.isDirectory":
4188
4220
  return finish(`scr_stats_is_dir(${arg(0)})`);
4189
4221
  case "stats.size":
4190
4222
  return finish(`scr_stats_size(${arg(0)})`);
4223
+ case "stats.dev":
4224
+ return finish(`scr_stats_dev(${arg(0)})`);
4225
+ case "stats.ino":
4226
+ return finish(`scr_stats_ino(${arg(0)})`);
4191
4227
  case "fs.toUnixTimestamp":
4192
4228
  return finish(`scr_fs_to_unix_timestamp(${arg(0)})`);
4193
4229
  // The fs argument-validation ladders: the always-throw Chk
@@ -4246,6 +4282,43 @@ function emitFilesystemLibCall(state) {
4246
4282
  return finish(`scr_zlib_deflate(${arg(0)})`);
4247
4283
  case "zlib.inflateSync":
4248
4284
  return finish(`scr_zlib_inflate(${arg(0)})`);
4285
+ case "zlib.deflateRawSync":
4286
+ return finish(`scr_zlib_deflate_mode(${arg(0)}, 1.0, -1.0)`);
4287
+ case "zlib.inflateRawSync":
4288
+ return finish(`scr_zlib_inflate_mode(${arg(0)}, 1.0)`);
4289
+ case "zlib.gzipSync":
4290
+ return finish(`scr_zlib_deflate_mode(${arg(0)}, 2.0, -1.0)`);
4291
+ case "zlib.gunzipSync":
4292
+ return finish(`scr_zlib_inflate_mode(${arg(0)}, 2.0)`);
4293
+ case "zlib.unzipSync":
4294
+ return finish(`scr_zlib_inflate_mode(${arg(0)}, 3.0)`);
4295
+ case "zlib.crc32":
4296
+ return finish(`scr_zlib_crc32(${arg(0)}, ${arg(1)})`);
4297
+ case "zlib.deflateCb":
4298
+ case "zlib.inflateCb":
4299
+ case "zlib.deflateRawCb":
4300
+ case "zlib.inflateRawCb":
4301
+ case "zlib.gzipCb":
4302
+ case "zlib.gunzipCb":
4303
+ case "zlib.unzipCb": {
4304
+ emitter.usesTimers = true;
4305
+ const cbT = e.args[1].type;
4306
+ if (cbT.kind !== "func")
4307
+ throw new InternalCompilerError("emitter bug: zlib callback not a func");
4308
+ const callback = args[1];
4309
+ emitter.moveTemp(callback);
4310
+ const adapter = emitter.zlibBytesThunkFor(cbT);
4311
+ const compressing = fn === "zlib.deflateCb" || fn === "zlib.deflateRawCb" || fn === "zlib.gzipCb";
4312
+ const mode = fn === "zlib.deflateRawCb" || fn === "zlib.inflateRawCb"
4313
+ ? 1
4314
+ : fn === "zlib.gzipCb" || fn === "zlib.gunzipCb"
4315
+ ? 2
4316
+ : fn === "zlib.unzipCb"
4317
+ ? 3
4318
+ : 0;
4319
+ emitter.line(`scr_zlib_codec_async(${arg(0)}, ${mode}.0, ${compressing ? "true" : "false"}, ${callback.name}, &${adapter});${emitter.srcComment(e.loc)}`);
4320
+ return { name: "", type: e.type };
4321
+ }
4249
4322
  case "fsp.readFile":
4250
4323
  return finish(`scr_fsp_read_file(${arg(0)})`);
4251
4324
  case "fsp.writeFile":
@@ -4272,6 +4345,10 @@ function emitFilesystemLibCall(state) {
4272
4345
  return finish(`scr_fsp_rm(${arg(0)})`);
4273
4346
  case "fsp.stat":
4274
4347
  return finish(`scr_fsp_stat(${arg(0)})`);
4348
+ case "fsp.realpath":
4349
+ return finish(`scr_fsp_realpath(${arg(0)})`);
4350
+ case "fsp.lstat":
4351
+ return finish(`scr_fsp_lstat(${arg(0)})`);
4275
4352
  case "fsp.open":
4276
4353
  return finish(`scr_fsp_open(${arg(0)}, ${arg(1)}, ${arg(2)})`);
4277
4354
  case "fileHandle.fd":
@@ -4535,10 +4612,18 @@ function emitPathUrlLibCall(state) {
4535
4612
  return finish(`scr_url_new(${arg(0)})`);
4536
4613
  case "url.protocol":
4537
4614
  return finish(`scr_url_protocol(${arg(0)})`);
4615
+ case "url.origin":
4616
+ return finish(`scr_url_origin(${arg(0)})`);
4617
+ case "url.username":
4618
+ return finish(`scr_url_username(${arg(0)})`);
4619
+ case "url.password":
4620
+ return finish(`scr_url_password(${arg(0)})`);
4538
4621
  case "url.host":
4539
4622
  return finish(`scr_url_host(${arg(0)})`);
4540
4623
  case "url.hostname":
4541
4624
  return finish(`scr_url_hostname(${arg(0)})`);
4625
+ case "url.port":
4626
+ return finish(`scr_url_port(${arg(0)})`);
4542
4627
  case "url.pathname":
4543
4628
  return finish(`scr_url_pathname(${arg(0)})`);
4544
4629
  case "url.href":
@@ -4572,6 +4657,8 @@ function emitPathUrlLibCall(state) {
4572
4657
  return finish(`scr_url_search_params(${arg(0)})`);
4573
4658
  case "url.search":
4574
4659
  return finish(`scr_url_search(${arg(0)})`);
4660
+ case "url.hash":
4661
+ return finish(`scr_url_hash(${arg(0)})`);
4575
4662
  case "sp.get": {
4576
4663
  // `string | null` — the sym.desc pattern with a null arm: the
4577
4664
  // runtime answers a +1 string or NULL.
@@ -4764,6 +4851,64 @@ function emitPrimitiveLibCall(state) {
4764
4851
  return finish(`scr_sym_for(${arg(0)})`);
4765
4852
  case "sym.toString":
4766
4853
  return finish(`scr_sym_to_string(${arg(0)})`);
4854
+ case "bigint.parse":
4855
+ return finish(`scr_bigint_parse(${arg(0)})`);
4856
+ case "bigint.fromF64":
4857
+ return finish(`scr_bigint_from_f64(${arg(0)})`);
4858
+ case "bigint.neg":
4859
+ return finish(`scr_bigint_neg(${arg(0)})`);
4860
+ case "bigint.not":
4861
+ return finish(`scr_bigint_not(${arg(0)})`);
4862
+ case "bigint.add":
4863
+ return finish(`scr_bigint_add(${arg(0)}, ${arg(1)})`);
4864
+ case "bigint.sub":
4865
+ return finish(`scr_bigint_sub(${arg(0)}, ${arg(1)})`);
4866
+ case "bigint.mul":
4867
+ return finish(`scr_bigint_mul(${arg(0)}, ${arg(1)})`);
4868
+ case "bigint.div":
4869
+ return finish(`scr_bigint_div(${arg(0)}, ${arg(1)})`);
4870
+ case "bigint.mod":
4871
+ return finish(`scr_bigint_mod(${arg(0)}, ${arg(1)})`);
4872
+ case "bigint.pow":
4873
+ return finish(`scr_bigint_pow(${arg(0)}, ${arg(1)})`);
4874
+ case "bigint.and":
4875
+ return finish(`scr_bigint_and(${arg(0)}, ${arg(1)})`);
4876
+ case "bigint.or":
4877
+ return finish(`scr_bigint_or(${arg(0)}, ${arg(1)})`);
4878
+ case "bigint.xor":
4879
+ return finish(`scr_bigint_xor(${arg(0)}, ${arg(1)})`);
4880
+ case "bigint.shl":
4881
+ return finish(`scr_bigint_shl(${arg(0)}, ${arg(1)})`);
4882
+ case "bigint.shr":
4883
+ return finish(`scr_bigint_shr(${arg(0)}, ${arg(1)})`);
4884
+ case "bigint.eq":
4885
+ return finish(`scr_bigint_eq(${arg(0)}, ${arg(1)})`);
4886
+ case "bigint.eqString":
4887
+ return finish(`scr_bigint_eq_string(${arg(0)}, ${arg(1)})`);
4888
+ case "bigint.cmp":
4889
+ return finish(`scr_bigint_cmp_f64(${arg(0)}, ${arg(1)})`);
4890
+ case "bigint.cmpNumber":
4891
+ return finish(`scr_bigint_cmp_number(${arg(0)}, ${arg(1)})`);
4892
+ case "bigint.truthy":
4893
+ return finish(`scr_bigint_truthy(${arg(0)})`);
4894
+ case "bigint.toString":
4895
+ return finish(`scr_bigint_to_string(${arg(0)}, ${arg(1)})`);
4896
+ case "bigint.inspect":
4897
+ return finish(`scr_bigint_inspect(${arg(0)})`);
4898
+ case "bigint.toF64":
4899
+ return finish(`scr_bigint_to_f64(${arg(0)})`);
4900
+ case "bigint.asUintN":
4901
+ return finish(`scr_bigint_as_uint_n(${arg(0)}, ${arg(1)})`);
4902
+ case "bigint.asIntN":
4903
+ return finish(`scr_bigint_as_int_n(${arg(0)}, ${arg(1)})`);
4904
+ case "bigint.bufferRead":
4905
+ return finish(`scr_bigint_buffer_read(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)})`);
4906
+ case "bigint.bufferWrite":
4907
+ return finish(`scr_bigint_buffer_write(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)})`);
4908
+ case "bigint.dataViewGet":
4909
+ return finish(`scr_bigint_dataview_get(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)})`);
4910
+ case "bigint.dataViewSet":
4911
+ return finish(`scr_bigint_dataview_set(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)})`);
4767
4912
  case "sym.desc":
4768
4913
  case "sym.keyFor": {
4769
4914
  // `string | undefined` — the child.stdout pattern with a
@@ -4812,6 +4957,7 @@ function emitPrimitiveLibCall(state) {
4812
4957
  // +1 string, or Node's "Invalid time value" RangeError
4813
4958
  // (may-throw seed set).
4814
4959
  return finish(`scr_date_to_iso(${arg(0)})`);
4960
+ case "date.parse":
4815
4961
  case "date.parseGetTime":
4816
4962
  // The bounded date-string parse (X509 validity + ECMA format);
4817
4963
  // NaN elsewhere. Never throws.
@@ -4893,7 +5039,7 @@ function emitUtilLibCall(state) {
4893
5039
  }
4894
5040
  }
4895
5041
  function emitCryptoBytesLibCall(state) {
4896
- const { e, arg, finish } = state;
5042
+ const { e, emitter, args, arg, finish } = state;
4897
5043
  const fn = e.fn;
4898
5044
  switch (fn) {
4899
5045
  case "crypto.x509Fingerprint":
@@ -4928,6 +5074,56 @@ function emitCryptoBytesLibCall(state) {
4928
5074
  return finish(`scr_crypto_hash_digest_str(${arg(0)}, ${arg(1)}, ${arg(2)})`);
4929
5075
  case "crypto.hashDigestBytes":
4930
5076
  return finish(`scr_crypto_hash_digest_bytes(${arg(0)}, ${arg(1)}, ${arg(2)})`);
5077
+ case "crypto.hashNew":
5078
+ return finish(`scr_crypto_hash_new(${arg(0)})`);
5079
+ case "crypto.hmacNewStr":
5080
+ return finish(`scr_crypto_hmac_new_str(${arg(0)}, ${arg(1)})`);
5081
+ case "crypto.hmacNewBytes":
5082
+ return finish(`scr_crypto_hmac_new_bytes(${arg(0)}, ${arg(1)})`);
5083
+ case "crypto.hashUpdateStr":
5084
+ case "crypto.hmacUpdateStr":
5085
+ return finish(`scr_crypto_hash_update_str(${arg(0)}, ${arg(1)})`);
5086
+ case "crypto.hashUpdateBytes":
5087
+ case "crypto.hmacUpdateBytes":
5088
+ return finish(`scr_crypto_hash_update_bytes(${arg(0)}, ${arg(1)})`);
5089
+ case "crypto.hashCopy":
5090
+ return finish(`scr_crypto_hash_copy(${arg(0)})`);
5091
+ case "crypto.hashDigestString":
5092
+ case "crypto.hmacDigestString":
5093
+ return finish(`scr_crypto_hash_digest_string(${arg(0)}, ${arg(1)})`);
5094
+ case "crypto.hashDigestBuffer":
5095
+ case "crypto.hmacDigestBuffer":
5096
+ return finish(`scr_crypto_hash_digest_buffer(${arg(0)})`);
5097
+ case "crypto.timingSafeEqual":
5098
+ return finish(`scr_crypto_timing_safe_equal(${arg(0)}, ${arg(1)})`);
5099
+ case "crypto.randomFill":
5100
+ return finish(`scr_crypto_random_fill(${arg(0)}, ${arg(1)}, ${arg(2)})`);
5101
+ case "crypto.randomFillRest":
5102
+ return finish(`scr_crypto_random_fill_rest(${arg(0)}, ${arg(1)})`);
5103
+ case "crypto.randomInt":
5104
+ return finish(`scr_crypto_random_int(${arg(0)}, ${arg(1)})`);
5105
+ case "crypto.pbkdf2":
5106
+ return finish(`scr_crypto_pbkdf2(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)})`);
5107
+ case "crypto.randomBytesCb":
5108
+ case "crypto.pbkdf2Cb": {
5109
+ emitter.usesTimers = true;
5110
+ const cbIndex = fn === "crypto.randomBytesCb" ? 1 : 5;
5111
+ const cbT = e.args[cbIndex].type;
5112
+ if (cbT.kind !== "func")
5113
+ throw new InternalCompilerError("emitter bug: crypto callback not a func");
5114
+ const callback = args[cbIndex];
5115
+ emitter.moveTemp(callback);
5116
+ const adapter = emitter.cryptoBytesThunkFor(cbT);
5117
+ if (fn === "crypto.randomBytesCb") {
5118
+ emitter.line(`scr_crypto_random_bytes_async(${arg(0)}, ${callback.name}, &${adapter});${emitter.srcComment(e.loc)}`);
5119
+ }
5120
+ else {
5121
+ emitter.line(`scr_crypto_pbkdf2_async(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${callback.name}, &${adapter});${emitter.srcComment(e.loc)}`);
5122
+ }
5123
+ if (MAY_THROW_LIB_FNS.has(fn))
5124
+ emitter.emitPendingCheck();
5125
+ return { name: "", type: e.type };
5126
+ }
4931
5127
  // The Buffer statics (scr_bytes.c): fromStr decodes Node-
4932
5128
  // leniently (never throws), concat copies its borrowed list.
4933
5129
  case "buffer.fromStr":
@@ -5066,26 +5262,59 @@ function emitChildProcessLibCall(state) {
5066
5262
  const absent = emitter.unitInstanceRef(e.type.unionId, unitTag);
5067
5263
  return emitter.newTemp(e.type, `${has}(${arg(0)}) ? ${present} : ${absent}`);
5068
5264
  }
5265
+ case "child.stdin":
5069
5266
  case "child.stdout":
5070
5267
  case "child.stderr": {
5071
- // `Readable | null` — the child.pid pattern with a REF arm:
5072
- // the runtime answers a +1 stream handle or NULL (not piped).
5268
+ // `Writable | null` / `Readable | null` — the child.pid
5269
+ // pattern with a REF arm: the runtime answers a +1 stream
5270
+ // handle or NULL (not piped).
5073
5271
  if (e.type.kind !== "union") {
5074
5272
  throw new InternalCompilerError(`emitter bug: ${e.fn} result is not a union`);
5075
5273
  }
5076
5274
  const def = emitter.unionsById.get(e.type.unionId);
5077
- const streamTag = def ? def.arms.findIndex((a) => a.kind === "childStream") : -1;
5275
+ const writer = e.fn === "child.stdin";
5276
+ const streamTag = def ? def.arms.findIndex((a) => a.kind === (writer ? "childWriter" : "childStream")) : -1;
5078
5277
  const nullTag = def ? def.arms.findIndex((a) => a.kind === "nullT") : -1;
5079
5278
  if (streamTag < 0 || nullTag < 0) {
5080
5279
  throw new InternalCompilerError(`emitter bug: ${e.fn} union lacks its arms`);
5081
5280
  }
5082
- const get = e.fn === "child.stdout" ? "scr_child_stdout" : "scr_child_stderr";
5083
- const raw = emitter.newTemp(CHILDSTREAM_T, `${get}(${arg(0)})`);
5281
+ const get = writer ? "scr_child_stdin" : e.fn === "child.stdout" ? "scr_child_stdout" : "scr_child_stderr";
5282
+ const rawType = writer ? CHILDWRITER_T : CHILDSTREAM_T;
5283
+ const raw = emitter.newTemp(rawType, `${get}(${arg(0)})`);
5084
5284
  emitter.moveTemp(raw); // ownership passes into the union arm below
5085
- const present = `scr_union_new_ref(${streamTag}, ${raw.name}, &scr_child_stream_retain_v, &scr_child_stream_release_v, NULL)`;
5285
+ const stem = writer ? "scr_child_writer" : "scr_child_stream";
5286
+ const present = `scr_union_new_ref(${streamTag}, ${raw.name}, &${stem}_retain_v, &${stem}_release_v, NULL)`;
5086
5287
  const absent = emitter.unitInstanceRef(e.type.unionId, nullTag);
5087
5288
  return emitter.newTemp(e.type, `${raw.name} != NULL ? ${present} : ${absent}`);
5088
5289
  }
5290
+ case "writer.writeString":
5291
+ return finish(`scr_child_writer_write_string(${arg(0)}, ${arg(1)})`);
5292
+ case "writer.writeBytes":
5293
+ return finish(`scr_child_writer_write_bytes(${arg(0)}, ${arg(1)})`);
5294
+ case "writer.end":
5295
+ return finish(`scr_child_writer_end(${arg(0)})`);
5296
+ case "writer.destroy":
5297
+ return finish(`scr_child_writer_destroy(${arg(0)})`);
5298
+ case "writer.writable":
5299
+ return finish(`scr_child_writer_writable(${arg(0)})`);
5300
+ case "writer.onDrain":
5301
+ case "writer.onFinish": {
5302
+ const cb = args[1];
5303
+ emitter.moveTemp(cb);
5304
+ const fnName = fn === "writer.onDrain" ? "scr_child_writer_on_drain" : "scr_child_writer_on_finish";
5305
+ emitter.line(`${fnName}(${arg(0)}, ${cb.name}, ${arg(2)});${emitter.srcComment(e.loc)}`);
5306
+ return { name: "", type: e.type };
5307
+ }
5308
+ case "writer.onError": {
5309
+ const cbT = e.args[1].type;
5310
+ if (cbT.kind !== "func")
5311
+ throw new InternalCompilerError("emitter bug: writer.onError callback not a func");
5312
+ const cb = args[1];
5313
+ emitter.moveTemp(cb);
5314
+ const adapter = cbT.params.length === 0 ? "scr_child_err_thunk0" : "scr_child_err_thunk_error";
5315
+ emitter.line(`scr_child_writer_on_error(${arg(0)}, ${cb.name}, &${adapter}, ${arg(2)});${emitter.srcComment(e.loc)}`);
5316
+ return { name: "", type: e.type };
5317
+ }
5089
5318
  case "procStream.write":
5090
5319
  // The receiver IS the fd scalar; dispatches onto the exact
5091
5320
  // promptly-submitted stdout/stderr paths (ordering identical).
@@ -5105,20 +5334,37 @@ function emitChildProcessLibCall(state) {
5105
5334
  case "cp.spawn":
5106
5335
  emitter.usesTimers = true; // the loop must run to reap the child
5107
5336
  return finish(`scr_spawn(${arg(0)}, ${arg(1)})`);
5337
+ case "cp.fork":
5338
+ emitter.usesTimers = true;
5339
+ return finish(`scr_fork(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)}, ${arg(6)}, ${arg(7)})`);
5108
5340
  case "cp.spawnOpts":
5109
5341
  // The options form: per-slot stdio (ignore/inherit/fd — the
5110
5342
  // fds dup2 into the child), detached (setsid), env
5111
5343
  // replacement, cwd. Same loop/reap story as cp.spawn.
5112
5344
  emitter.usesTimers = true;
5113
- return finish(`scr_spawn_opts(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)}, ${arg(6)}, ${arg(7)}, ${arg(8)}, ${arg(9)}, ${arg(10)})`);
5114
- case "child.onExit": {
5345
+ return finish(`scr_spawn_opts(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)}, ${arg(6)}, ${arg(7)}, ${arg(8)}, ${arg(9)}, ${arg(10)}, ${arg(11)})`);
5346
+ case "cp.execFile": {
5347
+ const callbackArg = e.args[2];
5348
+ const cb = args[2];
5349
+ if (!callbackArg || !cb)
5350
+ throw new InternalCompilerError("emitter bug: execFile callback missing");
5351
+ const cbT = callbackArg.type;
5352
+ if (cbT.kind !== "func")
5353
+ throw new InternalCompilerError("emitter bug: execFile callback not a func");
5354
+ emitter.moveTemp(cb);
5355
+ const adapter = emitter.execFileThunkFor(cbT);
5356
+ emitter.usesTimers = true;
5357
+ return finish(`scr_exec_file(${arg(0)}, ${arg(1)}, ${cb.name}, &${adapter})`);
5358
+ }
5359
+ case "child.onExit":
5360
+ case "child.onClose": {
5115
5361
  // The callback MOVES into the child's registry; the third
5116
5362
  // ingredient is the ADAPTER — emitted per callback shape,
5117
5363
  // because the `number | null` union's tags are program data
5118
5364
  // (a zero-param listener gets the runtime's ignoring thunk).
5119
5365
  const cbT = e.args[1].type;
5120
5366
  if (cbT.kind !== "func")
5121
- throw new InternalCompilerError("emitter bug: child.onExit callback not a func");
5367
+ throw new InternalCompilerError(`emitter bug: ${e.fn} callback not a func`);
5122
5368
  const cb = args[1];
5123
5369
  emitter.moveTemp(cb);
5124
5370
  const adapter = cbT.params.length === 0
@@ -5126,7 +5372,7 @@ function emitChildProcessLibCall(state) {
5126
5372
  : cbT.params.length === 1
5127
5373
  ? emitter.childExitThunkFor(cbT.params[0])
5128
5374
  : emitter.childExitSignalThunkFor(cbT.params[0], cbT.params[1]);
5129
- emitter.line(`scr_child_on_exit(${arg(0)}, ${cb.name}, &${adapter});${emitter.srcComment(e.loc)}`);
5375
+ emitter.line(`${e.fn === "child.onClose" ? "scr_child_on_close" : "scr_child_on_exit"}(${arg(0)}, ${cb.name}, &${adapter});${emitter.srcComment(e.loc)}`);
5130
5376
  return { name: "", type: e.type };
5131
5377
  }
5132
5378
  case "child.onError": {
@@ -5141,6 +5387,43 @@ function emitChildProcessLibCall(state) {
5141
5387
  emitter.line(`scr_child_on_error(${arg(0)}, ${cb.name}, &${adapter});${emitter.srcComment(e.loc)}`);
5142
5388
  return { name: "", type: e.type };
5143
5389
  }
5390
+ case "child.connected":
5391
+ return finish(`scr_child_ipc_connected(${arg(0)})`);
5392
+ case "child.send":
5393
+ emitter.usesTimers = true;
5394
+ return finish(`scr_child_ipc_send(${arg(0)}, ${arg(1)})`);
5395
+ case "child.sendCb": {
5396
+ const cbT = e.args[2].type;
5397
+ if (cbT.kind !== "func")
5398
+ throw new InternalCompilerError("emitter bug: child.send callback not a func");
5399
+ const cb = args[2];
5400
+ emitter.moveTemp(cb);
5401
+ emitter.usesTimers = true;
5402
+ return finish(`scr_child_ipc_send_cb(${arg(0)}, ${arg(1)}, ${cb.name}, &${emitter.ipcSendThunkFor(cbT)})`);
5403
+ }
5404
+ case "child.disconnect":
5405
+ emitter.usesTimers = true;
5406
+ return finish(`scr_child_ipc_disconnect(${arg(0)})`);
5407
+ case "child.onMessage": {
5408
+ const cbT = e.args[1].type;
5409
+ if (cbT.kind !== "func")
5410
+ throw new InternalCompilerError("emitter bug: child message listener not a func");
5411
+ const cb = args[1];
5412
+ emitter.moveTemp(cb);
5413
+ emitter.usesTimers = true;
5414
+ emitter.line(`scr_child_ipc_on_message(${arg(0)}, ${cb.name}, &${emitter.ipcMessageThunkFor(cbT)}, ${arg(2)});${emitter.srcComment(e.loc)}`);
5415
+ return { name: "", type: e.type };
5416
+ }
5417
+ case "child.onDisconnect": {
5418
+ const cbT = e.args[1].type;
5419
+ if (cbT.kind !== "func")
5420
+ throw new InternalCompilerError("emitter bug: child disconnect listener not a func");
5421
+ const cb = args[1];
5422
+ emitter.moveTemp(cb);
5423
+ emitter.usesTimers = true;
5424
+ emitter.line(`scr_child_ipc_on_disconnect(${arg(0)}, ${cb.name}, ${arg(2)});${emitter.srcComment(e.loc)}`);
5425
+ return { name: "", type: e.type };
5426
+ }
5144
5427
  default:
5145
5428
  throw new InternalCompilerError(`emitter bug: childProcess libCall dispatch for ${fn}`);
5146
5429
  }
@@ -5718,7 +6001,8 @@ function emitHttpLibCall(state) {
5718
6001
  return finish(`scr_http_req_aborted_flag(${arg(0)})`);
5719
6002
  case "http.reqComplete":
5720
6003
  return finish(`scr_http_req_complete(${arg(0)})`);
5721
- case "http.reqHeader": {
6004
+ case "http.reqHeader":
6005
+ case "http.reqTrailer": {
5722
6006
  // string|undefined, type-directed exactly like process.envGet:
5723
6007
  // the runtime answers +1 or NULL; NULL takes the undefined arm.
5724
6008
  if (e.type.kind !== "union")
@@ -5729,12 +6013,29 @@ function emitHttpLibCall(state) {
5729
6013
  if (strTag < 0 || undefTag < 0) {
5730
6014
  throw new InternalCompilerError("emitter bug: http.reqHeader union lacks its arms");
5731
6015
  }
5732
- const s = emitter.newTemp(STRING, `scr_http_req_header(${arg(0)}, ${arg(1)})`);
6016
+ const entry = e.fn === "http.reqHeader" ? "scr_http_req_header" : "scr_http_req_trailer";
6017
+ const s = emitter.newTemp(STRING, `${entry}(${arg(0)}, ${arg(1)})`);
5733
6018
  emitter.moveTemp(s); // moves into the box when present; NULL otherwise
5734
6019
  const present = `scr_union_new_ref(${strTag}, ${s.name}, &scr_str_retain_v, &scr_str_release_v, NULL)`;
5735
6020
  const absent = emitter.unitInstanceRef(e.type.unionId, undefTag);
5736
6021
  return emitter.newTemp(e.type, `${s.name} ? ${present} : ${absent}`);
5737
6022
  }
6023
+ case "http.reqHeaderValues":
6024
+ case "http.reqTrailerValues": {
6025
+ if (e.type.kind !== "union")
6026
+ throw new InternalCompilerError("emitter bug: distinct header result is not a union");
6027
+ const def = emitter.unionsById.get(e.type.unionId);
6028
+ const arrTag = def ? def.arms.findIndex((a) => a.kind === "array") : -1;
6029
+ const undefTag = undefinedArmTag(e.type, emitter.unionsById);
6030
+ if (arrTag < 0 || undefTag < 0)
6031
+ throw new InternalCompilerError("emitter bug: distinct header union lacks its arms");
6032
+ const entry = e.fn === "http.reqHeaderValues" ? "scr_http_req_header_values" : "scr_http_req_trailer_values";
6033
+ const values = emitter.newTemp(arrayOf(STRING), `${entry}(${arg(0)}, ${arg(1)})`);
6034
+ emitter.moveTemp(values);
6035
+ const present = `scr_union_new_ref(${arrTag}, ${values.name}, &scr_arr_retain_v, &scr_arr_release_v, NULL)`;
6036
+ const absent = emitter.unitInstanceRef(e.type.unionId, undefTag);
6037
+ return emitter.newTemp(e.type, `${values.name} ? ${present} : ${absent}`);
6038
+ }
5738
6039
  case "http.reqOnData": {
5739
6040
  const cbT = e.args[1].type;
5740
6041
  if (cbT.kind !== "func")
@@ -5758,34 +6059,36 @@ function emitHttpLibCall(state) {
5758
6059
  emitter.line(`scr_http_res_set_header(${arg(0)}, ${arg(1)}, ${arg(2)});${emitter.srcComment(e.loc)}`);
5759
6060
  return { name: "", type: e.type };
5760
6061
  case "http.resWriteHead":
5761
- emitter.line(`scr_http_res_write_head(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
5762
- return { name: "", type: e.type };
6062
+ return finish(`scr_http_res_write_head(${arg(0)}, ${arg(1)})`);
5763
6063
  case "http.resWriteHeadN":
5764
- emitter.line(`scr_http_res_write_head_n(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)});${emitter.srcComment(e.loc)}`);
5765
- return { name: "", type: e.type };
6064
+ return finish(`scr_http_res_write_head_n(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)})`);
5766
6065
  case "http.resWrite":
5767
- emitter.line(`scr_http_res_write_str(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
5768
- return { name: "", type: e.type };
6066
+ return finish(`scr_http_res_write_str(${arg(0)}, ${arg(1)})`);
5769
6067
  case "http.resWriteBytes":
5770
- emitter.line(`scr_http_res_write_bytes(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
5771
- return { name: "", type: e.type };
6068
+ return finish(`scr_http_res_write_bytes(${arg(0)}, ${arg(1)})`);
5772
6069
  case "http.resEnd":
5773
- emitter.line(`scr_http_res_end(${arg(0)});${emitter.srcComment(e.loc)}`);
5774
- return { name: "", type: e.type };
6070
+ return finish(`scr_http_res_end(${arg(0)})`);
5775
6071
  case "http.resEndStr":
5776
- emitter.line(`scr_http_res_end_str(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
5777
- return { name: "", type: e.type };
6072
+ return finish(`scr_http_res_end_str(${arg(0)}, ${arg(1)})`);
5778
6073
  case "http.resEndBytes":
5779
- emitter.line(`scr_http_res_end_bytes(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
5780
- return { name: "", type: e.type };
6074
+ return finish(`scr_http_res_end_bytes(${arg(0)}, ${arg(1)})`);
5781
6075
  case "http.resWriteDyn":
5782
- emitter.line(`scr_http_res_write_dynv(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
5783
- return { name: "", type: e.type };
6076
+ return finish(`scr_http_res_write_dynv(${arg(0)}, ${arg(1)})`);
5784
6077
  case "http.resEndDyn":
5785
- emitter.line(`scr_http_res_end_dynv(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
5786
- return { name: "", type: e.type };
6078
+ return finish(`scr_http_res_end_dynv(${arg(0)}, ${arg(1)})`);
5787
6079
  case "http.resHeadersSent":
5788
6080
  return finish(`scr_http_res_headers_sent(${arg(0)})`);
6081
+ case "http.resFlushHeaders":
6082
+ return finish(`scr_http_res_flush_headers(${arg(0)})`);
6083
+ case "http.resAddTrailers":
6084
+ return finish(`scr_http_res_add_trailers(${arg(0)}, ${arg(1)})`);
6085
+ case "http.resCork":
6086
+ emitter.line(`scr_http_res_cork(${arg(0)});${emitter.srcComment(e.loc)}`);
6087
+ return { name: "", type: e.type };
6088
+ case "http.resUncork":
6089
+ return finish(`scr_http_res_uncork(${arg(0)})`);
6090
+ case "http.resWritableCorked":
6091
+ return finish(`scr_http_res_writable_corked(${arg(0)})`);
5789
6092
  // The server-surface member follow-ups.
5790
6093
  case "http.reqStatusCode": {
5791
6094
  // number | undefined, type-directed like process.columns: the
@@ -5822,8 +6125,12 @@ function emitHttpLibCall(state) {
5822
6125
  return finish(`scr_http_req_h2_stream_or_throw(${arg(0)}, ${arg(1)})`);
5823
6126
  case "http.reqRawHeaders":
5824
6127
  return finish(`scr_http_req_raw_headers(${arg(0)})`);
6128
+ case "http.reqRawTrailers":
6129
+ return finish(`scr_http_req_raw_trailers(${arg(0)})`);
5825
6130
  case "http.reqHeaderPairs":
5826
6131
  return finish(`scr_http_req_header_pairs(${arg(0)})`);
6132
+ case "http.reqTrailerPairs":
6133
+ return finish(`scr_http_req_trailer_pairs(${arg(0)})`);
5827
6134
  case "http.reqStatusMessage": {
5828
6135
  // string | undefined: a reason phrase on client responses,
5829
6136
  // NULL (the undefined arm) on server requests — the
@@ -5935,6 +6242,9 @@ function emitHttpLibCall(state) {
5935
6242
  case "http.serverJoinDupHeaders":
5936
6243
  emitter.line(`scr_http_server_join_duplicate_headers(${arg(0)});${emitter.srcComment(e.loc)}`);
5937
6244
  return { name: "", type: e.type };
6245
+ case "http.serverAllowMissingHostHeader":
6246
+ emitter.line(`scr_http_server_allow_missing_host_header(${arg(0)});${emitter.srcComment(e.loc)}`);
6247
+ return { name: "", type: e.type };
5938
6248
  case "http.serverTimeoutGet":
5939
6249
  return finish(`scr_net_server_timeout_get(${arg(0)}, ${arg(1)})`);
5940
6250
  case "http.serverTimeoutSet":
@@ -5980,8 +6290,7 @@ function emitHttpLibCall(state) {
5980
6290
  return { name: "", type: e.type };
5981
6291
  }
5982
6292
  case "http.resWriteHeadPairs":
5983
- emitter.line(`scr_http_res_write_head_pairs(${arg(0)}, ${arg(1)}, ${arg(2)});${emitter.srcComment(e.loc)}`);
5984
- return { name: "", type: e.type };
6293
+ return finish(`scr_http_res_write_head_pairs(${arg(0)}, ${arg(1)}, ${arg(2)})`);
5985
6294
  case "http.resWriteHeadDyn":
5986
6295
  return finish(`scr_http_res_write_head_dyn(${arg(0)}, ${arg(1)}, ${arg(2)})`);
5987
6296
  case "http.reqSetEncoding":
@@ -6154,26 +6463,30 @@ function emitHttpLibCall(state) {
6154
6463
  return finish(`(${arg(0)} ? scr_https_request(${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)}, ${arg(6)}, ${arg(7)}, ${arg(8)}, (const char *)${arg(9)}->data, ${arg(9)}->len, ${cbExpr}, ${adapter}) : scr_http_request_ex(${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)}, ${arg(6)}, ${arg(7)}, ${cbExpr}, ${adapter}, 80, NULL, NULL))`);
6155
6464
  }
6156
6465
  case "http.clientWrite":
6157
- emitter.line(`scr_http_client_write_str(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
6158
- return { name: "", type: e.type };
6466
+ return finish(`scr_http_client_write_str(${arg(0)}, ${arg(1)})`);
6159
6467
  case "http.clientWriteBytes":
6160
- emitter.line(`scr_http_client_write_bytes(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
6161
- return { name: "", type: e.type };
6468
+ return finish(`scr_http_client_write_bytes(${arg(0)}, ${arg(1)})`);
6162
6469
  case "http.clientEnd":
6163
- emitter.line(`scr_http_client_end(${arg(0)});${emitter.srcComment(e.loc)}`);
6164
- return { name: "", type: e.type };
6470
+ return finish(`scr_http_client_end(${arg(0)})`);
6165
6471
  case "http.clientEndStr":
6166
- emitter.line(`scr_http_client_end_str(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
6167
- return { name: "", type: e.type };
6472
+ return finish(`scr_http_client_end_str(${arg(0)}, ${arg(1)})`);
6168
6473
  case "http.clientEndBytes":
6169
- emitter.line(`scr_http_client_end_bytes(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
6170
- return { name: "", type: e.type };
6474
+ return finish(`scr_http_client_end_bytes(${arg(0)}, ${arg(1)})`);
6171
6475
  case "http.clientWriteDyn":
6172
- emitter.line(`scr_http_client_write_dynv(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
6173
- return { name: "", type: e.type };
6476
+ return finish(`scr_http_client_write_dynv(${arg(0)}, ${arg(1)})`);
6174
6477
  case "http.clientEndDyn":
6175
- emitter.line(`scr_http_client_end_dynv(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
6176
- return { name: "", type: e.type };
6478
+ return finish(`scr_http_client_end_dynv(${arg(0)}, ${arg(1)})`);
6479
+ case "http.clientFlushHeaders":
6480
+ return finish(`scr_http_client_flush_headers(${arg(0)})`);
6481
+ case "http.clientAddTrailers":
6482
+ return finish(`scr_http_client_add_trailers(${arg(0)}, ${arg(1)})`);
6483
+ case "http.clientCork":
6484
+ emitter.line(`scr_http_client_cork(${arg(0)});${emitter.srcComment(e.loc)}`);
6485
+ return { name: "", type: e.type };
6486
+ case "http.clientUncork":
6487
+ return finish(`scr_http_client_uncork(${arg(0)})`);
6488
+ case "http.clientWritableCorked":
6489
+ return finish(`scr_http_client_writable_corked(${arg(0)})`);
6177
6490
  case "http.clientDestroy":
6178
6491
  emitter.line(`scr_http_client_destroy(${arg(0)});${emitter.srcComment(e.loc)}`);
6179
6492
  return { name: "", type: e.type };
@@ -6987,6 +7300,45 @@ function emitProcessLibCall(state) {
6987
7300
  return finish(`scr_process_getgid()`);
6988
7301
  case "process.execPath":
6989
7302
  return finish(`scr_process_exec_path()`);
7303
+ case "process.forkTarget":
7304
+ return finish(`scr_process_fork_target(${arg(0)})`);
7305
+ case "process.connected":
7306
+ return finish(`scr_process_ipc_connected()`);
7307
+ case "process.send":
7308
+ emitter.usesTimers = true;
7309
+ return finish(`scr_process_ipc_send(${arg(0)})`);
7310
+ case "process.sendCb": {
7311
+ const cbT = e.args[1].type;
7312
+ if (cbT.kind !== "func")
7313
+ throw new InternalCompilerError("emitter bug: process.send callback not a func");
7314
+ const cb = args[1];
7315
+ emitter.moveTemp(cb);
7316
+ emitter.usesTimers = true;
7317
+ return finish(`scr_process_ipc_send_cb(${arg(0)}, ${cb.name}, &${emitter.ipcSendThunkFor(cbT)})`);
7318
+ }
7319
+ case "process.disconnect":
7320
+ emitter.usesTimers = true;
7321
+ return finish(`scr_process_ipc_disconnect()`);
7322
+ case "process.onMessage": {
7323
+ const cbT = e.args[0].type;
7324
+ if (cbT.kind !== "func")
7325
+ throw new InternalCompilerError("emitter bug: process message listener not a func");
7326
+ const cb = args[0];
7327
+ emitter.moveTemp(cb);
7328
+ emitter.usesTimers = true;
7329
+ emitter.line(`scr_process_ipc_on_message(${cb.name}, &${emitter.ipcMessageThunkFor(cbT)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
7330
+ return { name: "", type: e.type };
7331
+ }
7332
+ case "process.onDisconnect": {
7333
+ const cbT = e.args[0].type;
7334
+ if (cbT.kind !== "func")
7335
+ throw new InternalCompilerError("emitter bug: process disconnect listener not a func");
7336
+ const cb = args[0];
7337
+ emitter.moveTemp(cb);
7338
+ emitter.usesTimers = true;
7339
+ emitter.line(`scr_process_ipc_on_disconnect(${cb.name}, ${arg(1)});${emitter.srcComment(e.loc)}`);
7340
+ return { name: "", type: e.type };
7341
+ }
6990
7342
  case "process.arch":
6991
7343
  return finish(`scr_process_arch()`);
6992
7344
  case "process.versionsNode":
@@ -7010,6 +7362,10 @@ function emitProcessLibCall(state) {
7010
7362
  // Flushes stdout and _Exit()s — never returns (exit handlers,
7011
7363
  // including the RC audit, deliberately do not run).
7012
7364
  return finish(`scr_process_exit(${arg(0)})`);
7365
+ case "process.setExitCode":
7366
+ return finish(`scr_process_set_exit_code(${arg(0)})`);
7367
+ case "process.currentExitCode":
7368
+ return finish(`scr_process_exit_code_or_zero()`);
7013
7369
  case "process.nextTick": {
7014
7370
  // The tick queue owns the callback until the drain fires it;
7015
7371
  // ticks run before promise jobs at every loop checkpoint and
@@ -7223,6 +7579,8 @@ function emitErrorsEventsLibCall(state) {
7223
7579
  const dynThunk = emitter.emitterInvokeThunkFor(adT);
7224
7580
  return finish(`(${cType(e.type).trim()})scr_emitter_on_dyn((ScrEmitter *)${arg(0)}, ${arg(1)}, ${arg(2)}, ${adapter.name}, &${dynThunk}, ${arg(4)}, ${arg(5)})`);
7225
7581
  }
7582
+ case "emitter.onFlex":
7583
+ return finish(`(${cType(e.type).trim()})scr_emitter_on_flex((ScrEmitter *)${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)})`);
7226
7584
  case "emitter.onData": {
7227
7585
  // The stream-'data' registration: same runtime entry as
7228
7586
  // emitter.on, but the DATA invoke thunk (the two-slot payload
@@ -7262,6 +7620,13 @@ function emitErrorsEventsLibCall(state) {
7262
7620
  // C variadic tail, every argument borrowed (the invoke
7263
7621
  // adapters retain each callee's +1). May-throw (listeners).
7264
7622
  return finish(`scr_emitter_emit((ScrEmitter *)${arg(0)}, ${arg(1)}${e.args.slice(2).map((_, i) => `, ${arg(i + 2)}`).join("")})`);
7623
+ case "emitter.emitFlex": {
7624
+ const count = e.args.length - 2;
7625
+ const payload = count === 0
7626
+ ? "NULL"
7627
+ : `(ScrDyn *const[]){${e.args.slice(2).map((_, i) => arg(i + 2)).join(", ")}}`;
7628
+ return finish(`scr_emitter_emit_flex((ScrEmitter *)${arg(0)}, ${arg(1)}, ${payload}, ${count})`);
7629
+ }
7265
7630
  case "emitter.emitError":
7266
7631
  // emit('error', err): unhandled ⇒ the runtime throws the
7267
7632
  // payload through the exception cell (may-throw seed).
@@ -7340,12 +7705,25 @@ function emitStreamLibCall(state) {
7340
7705
  emitter.line(`scr_child_stream_on_data(${arg(0)}, ${cb.name}, &${adapter}, ${arg(2)});${emitter.srcComment(e.loc)}`);
7341
7706
  return { name: "", type: e.type };
7342
7707
  }
7708
+ case "stream.onDataStr": {
7709
+ emitter.usesTimers = true;
7710
+ const cbT = e.args[1].type;
7711
+ if (cbT.kind !== "func" || cbT.params[0]?.kind !== "string") {
7712
+ throw new InternalCompilerError("emitter bug: stream.onDataStr callback not a string func");
7713
+ }
7714
+ const cb = args[1];
7715
+ emitter.moveTemp(cb);
7716
+ emitter.line(`scr_child_stream_on_data_str(${arg(0)}, ${cb.name}, &scr_child_stream_thunk_str, ${arg(2)});${emitter.srcComment(e.loc)}`);
7717
+ return { name: "", type: e.type };
7718
+ }
7343
7719
  case "stream.onEnd": {
7344
7720
  const cb = args[1];
7345
7721
  emitter.moveTemp(cb);
7346
7722
  emitter.line(`scr_child_stream_on_end(${arg(0)}, ${cb.name}, ${arg(2)});${emitter.srcComment(e.loc)}`);
7347
7723
  return { name: "", type: e.type };
7348
7724
  }
7725
+ case "stream.childSetEncoding":
7726
+ return finish(`scr_child_stream_set_encoding(${arg(0)}, ${arg(1)})`);
7349
7727
  // node:stream (scr_stream.c — linked exactly when these appear,
7350
7728
  // moduleUsesStream). Receivers reinterpret to the shared
7351
7729
  // ScrStream layout (the ScrEmitter prefix plus the stream-state
@@ -7742,6 +8120,8 @@ function emitAssertInspectLibCall(state) {
7742
8120
  return finish(`scr_assert_ok(${arg(0)}, ${arg(1)})`);
7743
8121
  case "assert.eqF64":
7744
8122
  return finish(`scr_assert_eq_f64(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`);
8123
+ case "assert.eqBigInt":
8124
+ return finish(`scr_assert_eq_bigint(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`);
7745
8125
  case "assert.eqStr":
7746
8126
  return finish(`scr_assert_eq_str(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`);
7747
8127
  case "assert.eqBool":
@@ -7754,6 +8134,8 @@ function emitAssertInspectLibCall(state) {
7754
8134
  // The quartet over checked-dynamic operands: SameValue /
7755
8135
  // dyn-walk deep equality, assertion_error.js messages.
7756
8136
  return finish(`scr_assert_eq_dyn(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`);
8137
+ case "assert.looseResult":
8138
+ return finish(`scr_assert_loose_result(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`);
7757
8139
  case "assert.deepResult":
7758
8140
  return finish(`scr_assert_deep_result(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)})`);
7759
8141
  case "assert.deqEnter":
@@ -7960,6 +8342,7 @@ function emitLibCallExpr(emitter, e) {
7960
8342
  case "regexp":
7961
8343
  case "intl":
7962
8344
  case "sym":
8345
+ case "bigint":
7963
8346
  case "perf":
7964
8347
  case "number":
7965
8348
  case "date":
@@ -7976,6 +8359,7 @@ function emitLibCallExpr(emitter, e) {
7976
8359
  case "cp":
7977
8360
  case "spawnRes":
7978
8361
  case "child":
8362
+ case "writer":
7979
8363
  case "procStream":
7980
8364
  return emitChildProcessLibCall(state);
7981
8365
  case "net":
@@ -8032,6 +8416,7 @@ export function emitExpr(emitter, e) {
8032
8416
  case "numLit":
8033
8417
  case "boolLit":
8034
8418
  case "strLit":
8419
+ case "moduleNsRef":
8035
8420
  case "unitLit":
8036
8421
  case "varRef":
8037
8422
  return emitLiteralExpr(emitter, e);