@scriptc/compiler 0.0.36 → 0.1.2

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 (256) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +52 -22
  2. package/ambient/scriptc-overrides.d.ts +0 -7
  3. package/ambient/scriptc.d.ts +3 -2
  4. package/dist/backend/build-cache.js.map +1 -1
  5. package/dist/backend/c/async.js +24 -2
  6. package/dist/backend/c/async.js.map +1 -1
  7. package/dist/backend/c/c-emitter.d.ts +22 -10
  8. package/dist/backend/c/c-emitter.js +60 -15
  9. package/dist/backend/c/c-emitter.js.map +1 -1
  10. package/dist/backend/c/exprs.js +289 -55
  11. package/dist/backend/c/exprs.js.map +1 -1
  12. package/dist/backend/c/island.js.map +1 -1
  13. package/dist/backend/c/may-throw.js +3 -0
  14. package/dist/backend/c/may-throw.js.map +1 -1
  15. package/dist/backend/c/stmts.d.ts +3 -5
  16. package/dist/backend/c/stmts.js +76 -17
  17. package/dist/backend/c/stmts.js.map +1 -1
  18. package/dist/backend/c/types.js.map +1 -1
  19. package/dist/backend/c/walkers.js +36 -12
  20. package/dist/backend/c/walkers.js.map +1 -1
  21. package/dist/backend/external-c.d.ts +33 -0
  22. package/dist/backend/external-c.js +51 -0
  23. package/dist/backend/external-c.js.map +1 -0
  24. package/dist/backend/link-plan.d.ts +37 -0
  25. package/dist/backend/link-plan.js +26 -0
  26. package/dist/backend/link-plan.js.map +1 -0
  27. package/dist/backend/linker.d.ts +22 -0
  28. package/dist/backend/linker.js +236 -0
  29. package/dist/backend/linker.js.map +1 -0
  30. package/dist/backend/llvm/blocks.js.map +1 -1
  31. package/dist/backend/llvm/dyn.js +63 -3
  32. package/dist/backend/llvm/dyn.js.map +1 -1
  33. package/dist/backend/llvm/emitter.js +132 -26
  34. package/dist/backend/llvm/emitter.js.map +1 -1
  35. package/dist/backend/llvm/expr-async.js +85 -3
  36. package/dist/backend/llvm/expr-async.js.map +1 -1
  37. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  38. package/dist/backend/llvm/expr-calls.js.map +1 -1
  39. package/dist/backend/llvm/expr-containers.js +68 -54
  40. package/dist/backend/llvm/expr-containers.js.map +1 -1
  41. package/dist/backend/llvm/expr-context.d.ts +2 -1
  42. package/dist/backend/llvm/expr-control.js.map +1 -1
  43. package/dist/backend/llvm/expr-dispatch.js +2 -0
  44. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  45. package/dist/backend/llvm/expr-dynamic.js +6 -3
  46. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  47. package/dist/backend/llvm/expr-island.js.map +1 -1
  48. package/dist/backend/llvm/expr-primitives.d.ts +1 -1
  49. package/dist/backend/llvm/expr-primitives.js +20 -0
  50. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  51. package/dist/backend/llvm/expr-records.js.map +1 -1
  52. package/dist/backend/llvm/expr-stream-bridges.js +245 -10
  53. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  54. package/dist/backend/llvm/lib-dispatch.js +2 -0
  55. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  56. package/dist/backend/llvm/lib-shared.js +18 -0
  57. package/dist/backend/llvm/lib-shared.js.map +1 -1
  58. package/dist/backend/llvm/lib-stream.js +6 -3
  59. package/dist/backend/llvm/lib-stream.js.map +1 -1
  60. package/dist/backend/llvm/split.js.map +1 -1
  61. package/dist/backend/llvm/unsupported.js.map +1 -1
  62. package/dist/backend/llvm/walkers.js +31 -4
  63. package/dist/backend/llvm/walkers.js.map +1 -1
  64. package/dist/backend/native-codegen.d.ts +8 -1
  65. package/dist/backend/native-codegen.js +39 -25
  66. package/dist/backend/native-codegen.js.map +1 -1
  67. package/dist/backend/native-codegen.test.js +44 -4
  68. package/dist/backend/native-codegen.test.js.map +1 -1
  69. package/dist/backend/native-link-info.d.ts +1 -1
  70. package/dist/backend/native-link-info.js +42 -18
  71. package/dist/backend/native-link-info.js.map +1 -1
  72. package/dist/backend/native-toolchain.js.map +1 -1
  73. package/dist/backend/native-toolchain.test.js +5 -1
  74. package/dist/backend/native-toolchain.test.js.map +1 -1
  75. package/dist/backend/runtime-pack-targets.test.d.ts +1 -0
  76. package/dist/backend/runtime-pack-targets.test.js +54 -0
  77. package/dist/backend/runtime-pack-targets.test.js.map +1 -0
  78. package/dist/backend/runtime-pack.d.ts +5 -30
  79. package/dist/backend/runtime-pack.js +46 -141
  80. package/dist/backend/runtime-pack.js.map +1 -1
  81. package/dist/backend/runtime-pack.test.js +49 -14
  82. package/dist/backend/runtime-pack.test.js.map +1 -1
  83. package/dist/backend/targets.d.ts +63 -17
  84. package/dist/backend/targets.js +251 -35
  85. package/dist/backend/targets.js.map +1 -1
  86. package/dist/backend/targets.test.js +27 -5
  87. package/dist/backend/targets.test.js.map +1 -1
  88. package/dist/backend/vendor-archives.js.map +1 -1
  89. package/dist/compat/fetch-profile.js +4 -2
  90. package/dist/compat/fetch-profile.js.map +1 -1
  91. package/dist/coverage/report.js.map +1 -1
  92. package/dist/coverage/surface-manifest.js +22 -1
  93. package/dist/coverage/surface-manifest.js.map +1 -1
  94. package/dist/diagnostics/diagnostic.d.ts +6 -5
  95. package/dist/diagnostics/diagnostic.js +7 -6
  96. package/dist/diagnostics/diagnostic.js.map +1 -1
  97. package/dist/diagnostics/render.js.map +1 -1
  98. package/dist/ffi/ffi-manifest.js.map +1 -1
  99. package/dist/frontend/cjs-lexer.js.map +1 -1
  100. package/dist/frontend/dts-paths.js.map +1 -1
  101. package/dist/frontend/input-tracker.d.ts +10 -0
  102. package/dist/frontend/input-tracker.js +26 -3
  103. package/dist/frontend/input-tracker.js.map +1 -1
  104. package/dist/frontend/input-tracker.test.js +8 -1
  105. package/dist/frontend/input-tracker.test.js.map +1 -1
  106. package/dist/frontend/lib-contract.js.map +1 -1
  107. package/dist/frontend/lowering/array-values.d.ts +12 -0
  108. package/dist/frontend/lowering/array-values.js +76 -0
  109. package/dist/frontend/lowering/array-values.js.map +1 -0
  110. package/dist/frontend/lowering/callback-arg.js.map +1 -1
  111. package/dist/frontend/lowering/containers/bytes.d.ts +35 -0
  112. package/dist/frontend/lowering/containers/bytes.js +1021 -0
  113. package/dist/frontend/lowering/containers/bytes.js.map +1 -0
  114. package/dist/frontend/lowering/containers/string-and-regexp.d.ts +17 -0
  115. package/dist/frontend/lowering/containers/string-and-regexp.js +345 -0
  116. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -0
  117. package/dist/frontend/lowering/expressions/evaluation-safety.d.ts +13 -0
  118. package/dist/frontend/lowering/expressions/evaluation-safety.js +76 -0
  119. package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -0
  120. package/dist/frontend/lowering/expressions/object-literals.d.ts +44 -0
  121. package/dist/frontend/lowering/expressions/object-literals.js +1815 -0
  122. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -0
  123. package/dist/frontend/lowering/expressions/optional-chains.d.ts +31 -0
  124. package/dist/frontend/lowering/expressions/optional-chains.js +382 -0
  125. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -0
  126. package/dist/frontend/lowering/expressions/try-lower-expression.d.ts +7 -0
  127. package/dist/frontend/lowering/expressions/try-lower-expression.js +26 -0
  128. package/dist/frontend/lowering/expressions/try-lower-expression.js.map +1 -0
  129. package/dist/frontend/lowering/lib-boundary.js +7 -2
  130. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  131. package/dist/frontend/lowering/lower-array-sort.d.ts +22 -0
  132. package/dist/frontend/lowering/lower-array-sort.js +619 -0
  133. package/dist/frontend/lowering/lower-array-sort.js.map +1 -0
  134. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  135. package/dist/frontend/lowering/lower-async-iteration.d.ts +7 -0
  136. package/dist/frontend/lowering/lower-async-iteration.js +657 -0
  137. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -0
  138. package/dist/frontend/lowering/lower-builtins.d.ts +18 -0
  139. package/dist/frontend/lowering/lower-builtins.js +379 -48
  140. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  141. package/dist/frontend/lowering/lower-calls.d.ts +16 -8
  142. package/dist/frontend/lowering/lower-calls.js +667 -91
  143. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  144. package/dist/frontend/lowering/lower-classes.d.ts +7 -13
  145. package/dist/frontend/lowering/lower-classes.js +128 -35
  146. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  147. package/dist/frontend/lowering/lower-comptime.js.map +1 -1
  148. package/dist/frontend/lowering/lower-containers.d.ts +1 -47
  149. package/dist/frontend/lowering/lower-containers.js +779 -2038
  150. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  151. package/dist/frontend/lowering/lower-event-emitter.js +51 -5
  152. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  153. package/dist/frontend/lowering/lower-exprs.d.ts +4 -78
  154. package/dist/frontend/lowering/lower-exprs.js +1128 -2409
  155. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  156. package/dist/frontend/lowering/lower-generators.d.ts +18 -3
  157. package/dist/frontend/lowering/lower-generators.js +145 -9
  158. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  159. package/dist/frontend/lowering/lower-inspect.js +50 -36
  160. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  161. package/dist/frontend/lowering/lower-island.d.ts +11 -4
  162. package/dist/frontend/lowering/lower-island.js +47 -10
  163. package/dist/frontend/lowering/lower-island.js.map +1 -1
  164. package/dist/frontend/lowering/lower-modules.js +52 -15
  165. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  166. package/dist/frontend/lowering/lower-node-module.d.ts +18 -0
  167. package/dist/frontend/lowering/lower-node-module.js +302 -0
  168. package/dist/frontend/lowering/lower-node-module.js.map +1 -0
  169. package/dist/frontend/lowering/lower-server.js +11 -1
  170. package/dist/frontend/lowering/lower-server.js.map +1 -1
  171. package/dist/frontend/lowering/lower-stmts.d.ts +5 -24
  172. package/dist/frontend/lowering/lower-stmts.js +811 -314
  173. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  174. package/dist/frontend/lowering/lower-stream.js +4 -4
  175. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  176. package/dist/frontend/lowering/lowerer.d.ts +109 -34
  177. package/dist/frontend/lowering/lowerer.js +1225 -62
  178. package/dist/frontend/lowering/lowerer.js.map +1 -1
  179. package/dist/frontend/lowering/optional-arguments.d.ts +9 -0
  180. package/dist/frontend/lowering/optional-arguments.js +57 -0
  181. package/dist/frontend/lowering/optional-arguments.js.map +1 -0
  182. package/dist/frontend/lowering/surfaces.d.ts +10 -2
  183. package/dist/frontend/lowering/surfaces.js +15 -3
  184. package/dist/frontend/lowering/surfaces.js.map +1 -1
  185. package/dist/frontend/npm-static-declarations.d.ts +35 -0
  186. package/dist/frontend/npm-static-declarations.js +506 -0
  187. package/dist/frontend/npm-static-declarations.js.map +1 -0
  188. package/dist/frontend/npm-static-declarations.test.d.ts +1 -0
  189. package/dist/frontend/npm-static-declarations.test.js +122 -0
  190. package/dist/frontend/npm-static-declarations.test.js.map +1 -0
  191. package/dist/frontend/npm-static.d.ts +2 -0
  192. package/dist/frontend/npm-static.js +26 -10
  193. package/dist/frontend/npm-static.js.map +1 -1
  194. package/dist/frontend/npm.d.ts +60 -0
  195. package/dist/frontend/npm.js +38 -4
  196. package/dist/frontend/npm.js.map +1 -1
  197. package/dist/frontend/npm.test.d.ts +1 -0
  198. package/dist/frontend/npm.test.js +50 -0
  199. package/dist/frontend/npm.test.js.map +1 -0
  200. package/dist/frontend/program.d.ts +3 -2
  201. package/dist/frontend/program.js +495 -68
  202. package/dist/frontend/program.js.map +1 -1
  203. package/dist/frontend/resolve.d.ts +10 -2
  204. package/dist/frontend/resolve.js +90 -14
  205. package/dist/frontend/resolve.js.map +1 -1
  206. package/dist/frontend/resolve.test.js +4 -1
  207. package/dist/frontend/resolve.test.js.map +1 -1
  208. package/dist/frontend/runtime-resolve.d.ts +22 -0
  209. package/dist/frontend/runtime-resolve.js +101 -0
  210. package/dist/frontend/runtime-resolve.js.map +1 -0
  211. package/dist/frontend/runtime-resolve.test.d.ts +1 -0
  212. package/dist/frontend/runtime-resolve.test.js +18 -0
  213. package/dist/frontend/runtime-resolve.test.js.map +1 -0
  214. package/dist/frontend/ts7/adapter.js +12 -13
  215. package/dist/frontend/ts7/adapter.js.map +1 -1
  216. package/dist/frontend/ts7/ast.js.map +1 -1
  217. package/dist/frontend/ts7/census-check.js +3 -3
  218. package/dist/frontend/ts7/census-check.js.map +1 -1
  219. package/dist/frontend/ts7/checker.d.ts +3 -0
  220. package/dist/frontend/ts7/checker.js +12 -3
  221. package/dist/frontend/ts7/checker.js.map +1 -1
  222. package/dist/frontend/ts7/enums.js.map +1 -1
  223. package/dist/frontend/ts7/program-adapter.js +42 -3
  224. package/dist/frontend/ts7/program-adapter.js.map +1 -1
  225. package/dist/frontend/type-mapper.js +120 -7
  226. package/dist/frontend/type-mapper.js.map +1 -1
  227. package/dist/index.d.ts +3 -3
  228. package/dist/index.js +50 -28
  229. package/dist/index.js.map +1 -1
  230. package/dist/ir/analysis.js.map +1 -1
  231. package/dist/ir/ir.d.ts +125 -41
  232. package/dist/ir/ir.js +82 -31
  233. package/dist/ir/ir.js.map +1 -1
  234. package/dist/ir/serialize.d.ts +1 -1
  235. package/dist/ir/serialize.js +1 -1
  236. package/dist/ir/validate.js +127 -95
  237. package/dist/ir/validate.js.map +1 -1
  238. package/dist/library/cache-primitives.js.map +1 -1
  239. package/dist/library/cache-reset.test.js.map +1 -1
  240. package/dist/library/compiler-self-identity.js.map +1 -1
  241. package/dist/library/fence-eval.js +3 -1
  242. package/dist/library/fence-eval.js.map +1 -1
  243. package/dist/library/int-infer.js +12 -1
  244. package/dist/library/int-infer.js.map +1 -1
  245. package/dist/library/int-infer.test.js +4 -4
  246. package/dist/library/int-infer.test.js.map +1 -1
  247. package/dist/library/library-cache.test.js +5 -5
  248. package/dist/library/library-profile.js.map +1 -1
  249. package/dist/library/sidecar-validate.js.map +1 -1
  250. package/dist/library/sidecar.js.map +1 -1
  251. package/dist/startup-cache.d.ts +9 -1
  252. package/dist/startup-cache.js +16 -1
  253. package/dist/startup-cache.js.map +1 -1
  254. package/dist/wasi-paths.js.map +1 -1
  255. package/package.json +18 -5
  256. package/surface-manifest.json +64 -8
@@ -64,7 +64,7 @@ import { InternalCompilerError } from "../../errors.js";
64
64
  import { deflateRawSync } from "node:zlib";
65
65
  import { endsWithJump, matchStringSelfConcat } from "../../ir/analysis.js";
66
66
  import { emitLibraryIdentityLines } from "../library-identity-markers.js";
67
- import { CAUGHT, ffiCallbackType, isFfiContextParam, isRefCounted, isUnitType, moduleEmbedsBuiltin, moduleEmbedsCompressedNpm, moduleUsesDynInvoke, moduleUsesFetch, moduleUsesFsWatch, moduleUsesHttpServer, moduleUsesNet, moduleUsesNodeTest, moduleUsesProcessEvents, moduleUsesStream, moduleUsesTls, moduleUsesTlsCa, NPM_COMPRESS_MIN, POINTER_KINDS, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, VOID } from "../../ir/ir.js";
67
+ import { CAUGHT, ffiCallbackType, isFfiContextParam, isRefCounted, isUnitType, moduleEmbedsBuiltin, moduleEmbedsCompressedNpm, moduleUsesChildProcess, moduleUsesDynInvoke, moduleUsesFetch, moduleUsesFsWatch, moduleUsesHttpServer, moduleUsesNet, moduleUsesNodeTest, moduleUsesProcessEvents, moduleUsesStream, moduleUsesTls, moduleUsesTlsCa, NPM_COMPRESS_MIN, POINTER_KINDS, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, typeKey, VOID } from "../../ir/ir.js";
68
68
  import { matchIntegerBytesForLoop } from "../../ir/integer-loops.js";
69
69
  import { allocateFfiCallbackAdapters, hasForeignFfiCallback, hasRetainedFfiCallback } from "../ffi-callbacks.js";
70
70
  import { RUNTIME_ABI_MARKER } from "../runtime-abi.js";
@@ -202,8 +202,8 @@ class LlEmitter {
202
202
  /** ReadableStream.from adapters keep typed arrays by reference and box
203
203
  * one current element per pull. */
204
204
  streamFromArrayAdapters = new Map();
205
- /** Identity-preserving static→dyn capsules used by Web APIs whose values
206
- * remain directly observable (stream chunks and AbortSignal reasons). */
205
+ /** Identity-preserving static→dyn capsules for program classes and Web
206
+ * APIs whose values remain directly observable. */
207
207
  liveDynRefAdapters = new Map();
208
208
  /** Runtime-arm dispatchers for live union values. */
209
209
  liveDynUnionRefAdapters = new Map();
@@ -256,8 +256,8 @@ class LlEmitter {
256
256
  * `tryDepth` snapshots tryStack.length at region entry: a throw inside
257
257
  * a pending-return finally copy propagates OUT of the completing try
258
258
  * (past its own catch), so the copies emit under the truncated stack.
259
- * break/continue never cross a finally (frontend fence + validator
260
- * backstop), so return and the two tryCatch paths are the only copies. */
259
+ * break/continue use the same region snapshots through
260
+ * emitFinallysForJump. */
261
261
  finallyStack = [];
262
262
  /** Enclosing try contexts, innermost last — the compile-time unwind
263
263
  * targets (CEmitter.tryStack): a pending check or `throw` inside a try
@@ -692,6 +692,7 @@ class LlEmitter {
692
692
  // BEFORE the global releases (the C emitter's runExitListeners
693
693
  // ordering — the atexit half becomes an idempotent no-op).
694
694
  const usesEvents = moduleUsesProcessEvents(this.mod);
695
+ const usesChildProcess = moduleUsesChildProcess(this.mod);
695
696
  const usesFsWatch = moduleUsesFsWatch(this.mod);
696
697
  // Stream-surface programs fill the loop's stream hook (the deferred
697
698
  // next-tick emissions) and the emitter's post-registration flow kick
@@ -724,6 +725,8 @@ class LlEmitter {
724
725
  // Declared NOW — the extern block flushes before main assembles.
725
726
  if (usesEvents)
726
727
  this.declare(`declare void @scr_events_install()`);
728
+ if (usesChildProcess)
729
+ this.declare(`declare void @scr_child_dyn_install()`);
727
730
  if (usesFsWatch)
728
731
  this.declare(`declare void @scr_watch_install()`);
729
732
  if (this.ffiHasForeignCallback)
@@ -901,11 +904,10 @@ class LlEmitter {
901
904
  `%ScrClosure = type { ${this.sizeType}, ptr, ${this.sizeType}, ptr }`,
902
905
  `%ScrFfiTable = type { ptr, ${this.sizeType}, ${this.sizeType}, ptr, i8, ptr, ptr, ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, ptr, ptr }`,
903
906
  `%ScrRegex = type { ${this.sizeType}, ptr, ptr, ptr }`,
904
- // ScrArr mirror { rc, len, cap, elem(i32+pad), elem_retain,
905
- // elem_release, elem_trace, data } — the immortal tagged-template
906
- // strings objects lay out through it (nothing GEPs into live heap
907
- // arrays; those stay behind the runtime's own entry points).
908
- `%ScrArr = type { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, i32, ptr, ptr, ptr, ptr }`,
907
+ // ScrArr mirrors scr_runtime.h field-for-field. Live dynamic stream
908
+ // commits swap its mutable dense, sparse, presence, and property
909
+ // storage while preserving the target object's identity.
910
+ `%ScrArr = type { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, i32, ptr, ptr, ptr, ptr, ptr, ptr, ${this.sizeType}, ${this.sizeType}, ptr, ${this.sizeType}, ${this.sizeType} }`,
909
911
  // The runtime error prefix { rc, vt, name, message, code } and the
910
912
  // class-object shape { rc, pre, post, ctor, name } — field reads on
911
913
  // builtin errors and classval loads GEP through these.
@@ -984,9 +986,13 @@ class LlEmitter {
984
986
  // One immortal ScrArr per tagged-template site: a [N x ptr] data
985
987
  // global of interned cooked-string literals, and the ScrArr header
986
988
  // over it (rc == SIZE_MAX, len == cap, SCR_ELEM_STR = 2, no REF
987
- // entry points). Reads retain immortal strings — a no-op.
989
+ // entry points). Every dense slot is present; reads retain immortal
990
+ // strings — a no-op.
988
991
  const n = inst.slots.length;
989
- out.push(`@${inst.sym}_data = internal constant [${n} x ptr] [ ${inst.slots.map((s) => `ptr ${s}`).join(", ")} ]`, `@${inst.sym} = internal global %ScrArr { ${this.sizeType} -1, ${this.sizeType} ${n}, ${this.sizeType} ${n}, i32 2, ptr null, ptr null, ptr null, ptr @${inst.sym}_data }`);
992
+ const present = n === 0
993
+ ? "zeroinitializer"
994
+ : `[ ${inst.slots.map(() => "i8 1").join(", ")} ]`;
995
+ out.push(`@${inst.sym}_data = internal constant [${n} x ptr] [ ${inst.slots.map((s) => `ptr ${s}`).join(", ")} ]`, `@${inst.sym}_present = internal constant [${n} x i8] ${present}`, `@${inst.sym} = internal global %ScrArr { ${this.sizeType} -1, ${this.sizeType} ${n}, ${this.sizeType} ${n}, i32 2, ptr null, ptr null, ptr null, ptr @${inst.sym}_data, ptr @${inst.sym}_present, ptr null, ${this.sizeType} 0, ${this.sizeType} 0, ptr null, ${this.sizeType} 0, ${this.sizeType} 0 }`);
990
996
  }
991
997
  if (this.templateStringsInstances.size > 0)
992
998
  out.push(``);
@@ -1111,7 +1117,7 @@ class LlEmitter {
1111
1117
  // Event-surface programs (signal/exit listeners) fill the loop's
1112
1118
  // nullable event hooks before %main — scr_events.c links only when
1113
1119
  // this line is emitted (native-toolchain.ts gates on the same predicate).
1114
- ...(usesEvents ? [` call void @scr_events_install()`] : []),
1120
+ ...(usesEvents ? [` call void @scr_events_install()`] : []), ...(usesChildProcess ? [` call void @scr_child_dyn_install()`] : []),
1115
1121
  // fs.watch programs fill the loop's watch hooks the same way —
1116
1122
  // scr_watch.c links only when this line is emitted.
1117
1123
  ...(usesFsWatch ? [` call void @scr_watch_install()`] : []), ...(this.ffiHasForeignCallback ? [` call void @scr_ffi_install()`] : []), ...(snapshotsTlsCa ? [` call void @scr_tls_ca_install()`] : []), ...(usesFetch ? [` call void @scr_fetch_install()`] : []), ...(embedsZlib ? [` call void @scr_zlib_island_install()`] : []), ...(embedsNet ? [` call void @scr_net_island_install()`] : []), ...(usesNet ? [` call void @scr_net_install()`, ` call void @scr_net_dyn_install()`] : []), ...(usesHttp ? [` call void @scr_http_dyn_install()`] : []), ...(usesStream ? [` call void @scr_stream_install()`] : []), ` call void @scr_lib_init(i32 %argc, ptr %argv)`, ...(usesIsland
@@ -1534,7 +1540,7 @@ class LlEmitter {
1534
1540
  out.push(`define void @scr_wasi_coro_resume(ptr %handle) ${FN_ATTRS} {`, `entry:`, ` call void @llvm.coro.resume(ptr %handle)`, ` ret void`, `}`, `define void @scr_wasi_coro_destroy(ptr %handle) ${FN_ATTRS} {`, `entry:`, ` call void @llvm.coro.destroy(ptr %handle)`, ` ret void`, `}`, ``);
1535
1541
  }
1536
1542
  for (const fn of this.mod.functions) {
1537
- if (fn.async !== true)
1543
+ if (fn.async !== true || fn.generator !== undefined)
1538
1544
  continue;
1539
1545
  const { definitions, ret, tr, spawnParams, argPackLines } = this.emitArgPackAndTrampolinePrologue(fn);
1540
1546
  out.push(...definitions);
@@ -1705,6 +1711,27 @@ class LlEmitter {
1705
1711
  tr.push(` br label %done`, `done:`, ` ret void`, `}`, ``);
1706
1712
  }
1707
1713
  out.push(...tr);
1714
+ let settleAsync = null;
1715
+ if (fn.async) {
1716
+ this.declare(`declare ptr @scr_async_gen_new(ptr, ptr, ptr, ptr)`);
1717
+ const genT = {
1718
+ kind: "generator",
1719
+ async: true,
1720
+ yieldT: fn.generator.yieldT,
1721
+ retT: ret,
1722
+ nextT: fn.generator.nextT,
1723
+ };
1724
+ const resultT = fn.generator.resultType;
1725
+ const build = this.genResultThunkFor(genT, resultT);
1726
+ settleAsync = `${build}_async`;
1727
+ const settleKey = `ags:${typeKey(genT)}`;
1728
+ if (!this.resolveThunks.has(settleKey)) {
1729
+ this.resolveThunks.set(settleKey, settleAsync);
1730
+ const adapters = vAdapters(this, resultT);
1731
+ this.resolveThunkDefs.push(`define internal void @${settleAsync}(ptr %g, ptr %p) ${FN_ATTRS} {`, `entry:`, ` %r = call ptr @${build}(ptr %g)`, ` call void @scr_promise_fulfill_ref(ptr %p, ptr %r, ptr ${adapters.retain}, ptr ${adapters.release}, ptr ${traceArg(this, resultT)})`, ` ret void`, `}`, ``);
1732
+ }
1733
+ this.declare(`declare void @scr_promise_fulfill_ref(ptr, ptr, ptr, ptr, ptr)`);
1734
+ }
1708
1735
  // The never-started teardown: drop the packed (+1) arguments.
1709
1736
  const dr = [
1710
1737
  `define internal void @${mangleGenDrop(fn.name)}(ptr %ap) ${FN_ATTRS} {`,
@@ -1736,7 +1763,9 @@ class LlEmitter {
1736
1763
  `entry:`,
1737
1764
  ...argPackLines,
1738
1765
  ];
1739
- sp.push(` %gg = call ptr @scr_gen_new(ptr @${mangleTrampoline(fn.name)}, ptr %ap, ptr @${mangleGenDrop(fn.name)})`, ` ret ptr %gg`, `}`, ``);
1766
+ sp.push(settleAsync === null
1767
+ ? ` %gg = call ptr @scr_gen_new(ptr @${mangleTrampoline(fn.name)}, ptr %ap, ptr @${mangleGenDrop(fn.name)})`
1768
+ : ` %gg = call ptr @scr_async_gen_new(ptr @${mangleTrampoline(fn.name)}, ptr %ap, ptr @${mangleGenDrop(fn.name)}, ptr @${settleAsync})`, ` ret ptr %gg`, `}`, ``);
1740
1769
  out.push(...sp);
1741
1770
  }
1742
1771
  return out;
@@ -1864,6 +1893,34 @@ class LlEmitter {
1864
1893
  for (let i = this.scopes.length - 1; i >= scopeDepth; i--)
1865
1894
  this.releaseScope(this.scopes[i]);
1866
1895
  }
1896
+ /** Run the finally regions an abrupt loop/block jump crosses, then
1897
+ * release to the already-resolved target. This is the return path's
1898
+ * completion walk without a parked result value. */
1899
+ emitFinallysForJump(finallyDepth, frameDepth, scopeDepth) {
1900
+ if (this.finallyStack.length <= finallyDepth) {
1901
+ this.releaseForJump(frameDepth, scopeDepth);
1902
+ return;
1903
+ }
1904
+ const savedFrames = this.frames;
1905
+ const savedScopes = this.scopes;
1906
+ const savedFinally = this.finallyStack;
1907
+ const savedTry = this.tryStack;
1908
+ for (let i = savedFinally.length - 1; i >= finallyDepth && !this.B.isTerminated(); i--) {
1909
+ const fin = savedFinally[i];
1910
+ this.releaseForJump(fin.frameDepth, fin.scopeDepth);
1911
+ this.frames = this.frames.slice(0, fin.frameDepth);
1912
+ this.scopes = this.scopes.slice(0, fin.scopeDepth);
1913
+ this.finallyStack = savedFinally.slice(0, i);
1914
+ this.tryStack = savedTry.slice(0, fin.tryDepth);
1915
+ this.emitBlock(fin.body);
1916
+ }
1917
+ if (!this.B.isTerminated())
1918
+ this.releaseForJump(frameDepth, scopeDepth);
1919
+ this.frames = savedFrames;
1920
+ this.scopes = savedScopes;
1921
+ this.finallyStack = savedFinally;
1922
+ this.tryStack = savedTry;
1923
+ }
1867
1924
  /** THE unwind path at a point where an exception is pending: release
1868
1925
  * everything between here and the innermost try handler — or the whole
1869
1926
  * function — and branch to the handler / return a dummy value (never
@@ -2359,10 +2416,10 @@ class LlEmitter {
2359
2416
  * fiber and returns the generator object) — CEmitter.callTargetC. */
2360
2417
  callTarget(fnName) {
2361
2418
  const fn = this.fnByName.get(fnName);
2362
- if (fn?.async === true)
2363
- return mangleAsyncSpawn(fnName);
2364
2419
  if (fn?.generator !== undefined)
2365
2420
  return mangleGenSpawn(fnName);
2421
+ if (fn?.async === true)
2422
+ return mangleAsyncSpawn(fnName);
2366
2423
  return mangleFunction(fnName);
2367
2424
  }
2368
2425
  /** Queue the current wasm coroutine and suspend it. The runtime decides
@@ -2492,7 +2549,7 @@ class LlEmitter {
2492
2549
  B.line(`call void @scr_wasi_coro_started(ptr ${handle})`);
2493
2550
  B.line(`${self} = call ptr @scr_fiber_self()`);
2494
2551
  this.currentWasiCoro = {
2495
- kind: fn.async === true ? "async" : "generator",
2552
+ kind: fn.generator !== undefined ? "generator" : "async",
2496
2553
  id,
2497
2554
  handle,
2498
2555
  self,
@@ -2740,6 +2797,30 @@ class LlEmitter {
2740
2797
  B.line(`call void @scr_arr_set_${acc}(ptr ${arr.name}, double ${idx.name}, ${argTy} ${v.name})`);
2741
2798
  break;
2742
2799
  }
2800
+ case "arraySetLength": {
2801
+ const arr = this.emitExpr(s.arr);
2802
+ const length = this.emitExpr(s.length);
2803
+ if (s.arr.type.kind !== "array")
2804
+ throw new InternalCompilerError("llvm emitter bug: arraySetLength on non-array");
2805
+ this.declare(`declare void @scr_arr_set_len(ptr, double)`);
2806
+ B.line(`call void @scr_arr_set_len(ptr ${arr.name}, double ${length.name})`);
2807
+ this.emitPendingCheck();
2808
+ break;
2809
+ }
2810
+ case "arraySetUndefined":
2811
+ case "arrayDelete": {
2812
+ const arr = this.emitExpr(s.arr);
2813
+ const idx = this.emitExpr(s.index);
2814
+ if (s.arr.type.kind !== "array")
2815
+ throw new InternalCompilerError(`llvm emitter bug: ${s.kind} on non-array`);
2816
+ const fn = s.kind === "arraySetUndefined" ? "scr_arr_set_undefined" : "scr_arr_delete";
2817
+ this.declare(`declare ${s.kind === "arrayDelete" ? "zeroext i1" : "void"} @${fn}(ptr, double)`);
2818
+ if (s.kind === "arrayDelete")
2819
+ B.line(`call zeroext i1 @${fn}(ptr ${arr.name}, double ${idx.name})`);
2820
+ else
2821
+ B.line(`call void @${fn}(ptr ${arr.name}, double ${idx.name})`);
2822
+ break;
2823
+ }
2743
2824
  case "bytesSet": {
2744
2825
  // Typed-array element write: same evaluation order as arraySet;
2745
2826
  // the value is a scalar (the kind-specific inline path coerces
@@ -2937,6 +3018,7 @@ class LlEmitter {
2937
3018
  labels: s.labels,
2938
3019
  frameDepth: this.frames.length,
2939
3020
  scopeDepth: this.scopes.length,
3021
+ finallyDepth: this.finallyStack.length,
2940
3022
  });
2941
3023
  this.emitBlock(s.body);
2942
3024
  this.jumpTargets.pop();
@@ -2976,6 +3058,7 @@ class LlEmitter {
2976
3058
  ...(s.labels !== undefined && { labels: s.labels }),
2977
3059
  frameDepth: this.frames.length,
2978
3060
  scopeDepth: this.scopes.length,
3061
+ finallyDepth: this.finallyStack.length,
2979
3062
  });
2980
3063
  this.emitBlock(s.body);
2981
3064
  this.jumpTargets.pop();
@@ -2997,6 +3080,7 @@ class LlEmitter {
2997
3080
  ...(s.labels !== undefined && { labels: s.labels }),
2998
3081
  frameDepth: this.frames.length,
2999
3082
  scopeDepth: this.scopes.length,
3083
+ finallyDepth: this.finallyStack.length,
3000
3084
  });
3001
3085
  this.emitBlock(s.body);
3002
3086
  this.jumpTargets.pop();
@@ -3058,6 +3142,7 @@ class LlEmitter {
3058
3142
  ...(s.labels !== undefined && { labels: s.labels }),
3059
3143
  frameDepth: this.frames.length,
3060
3144
  scopeDepth: this.scopes.length,
3145
+ finallyDepth: this.finallyStack.length,
3061
3146
  });
3062
3147
  this.emitBlock(s.body);
3063
3148
  this.jumpTargets.pop();
@@ -3129,6 +3214,7 @@ class LlEmitter {
3129
3214
  ...(s.labels !== undefined && { labels: s.labels }),
3130
3215
  frameDepth: this.frames.length,
3131
3216
  scopeDepth: this.scopes.length,
3217
+ finallyDepth: this.finallyStack.length,
3132
3218
  });
3133
3219
  // The loop variable is a fresh const per iteration: its scope opens
3134
3220
  // here, holds the (for ref elements: owned +1) current element, and
@@ -3189,8 +3275,9 @@ class LlEmitter {
3189
3275
  }
3190
3276
  if (!target)
3191
3277
  throw new InternalCompilerError("llvm emitter bug: break target not found");
3192
- this.releaseForJump(target.frameDepth, target.scopeDepth);
3193
- B.terminate(`br label %${target.brkLabel}`);
3278
+ this.emitFinallysForJump(target.finallyDepth, target.frameDepth, target.scopeDepth);
3279
+ if (!B.isTerminated())
3280
+ B.terminate(`br label %${target.brkLabel}`);
3194
3281
  break;
3195
3282
  }
3196
3283
  case "continue": {
@@ -3206,8 +3293,9 @@ class LlEmitter {
3206
3293
  }
3207
3294
  if (!target || target.contLabel === null)
3208
3295
  throw new InternalCompilerError("llvm emitter bug: continue target not found");
3209
- this.releaseForJump(target.frameDepth, target.scopeDepth);
3210
- B.terminate(`br label %${target.contLabel}`);
3296
+ this.emitFinallysForJump(target.finallyDepth, target.frameDepth, target.scopeDepth);
3297
+ if (!B.isTerminated())
3298
+ B.terminate(`br label %${target.contLabel}`);
3211
3299
  break;
3212
3300
  }
3213
3301
  case "return": {
@@ -3342,10 +3430,9 @@ class LlEmitter {
3342
3430
  * <unwind> stash (it unwinds through the synthetic
3343
3431
  * try.e: scope entry) — JS's semantics exactly
3344
3432
  *
3345
- * Returns inside tryBody/catchBody ride the finallyStack (inline copies
3346
- * at the return site — see `return`); break/continue never cross a
3347
- * finally and no jump leaves a finally body (frontend fence + validator
3348
- * backstop). */
3433
+ * Abrupt completions inside tryBody/catchBody ride the finallyStack:
3434
+ * returns inline copies at the return site, while break/continue use the
3435
+ * shared region walk before branching to their resolved target. */
3349
3436
  emitTryCatch(s) {
3350
3437
  const B = this.B;
3351
3438
  const hasCatch = s.catchBody !== null;
@@ -3444,11 +3531,29 @@ class LlEmitter {
3444
3531
  B.line(`${stash} = call ptr @scr_exc_take() ; stash across finally`);
3445
3532
  B.line(`store ptr ${stash}, ptr ${stashSlot}`);
3446
3533
  this.scopes.push([{ slot: stashSlot, type: CAUGHT }]);
3534
+ const suppressHandler = s.suppressFinallyErrors
3535
+ ? {
3536
+ label: B.newLabel("try.fs"),
3537
+ used: false,
3538
+ frameDepth: this.frames.length,
3539
+ scopeDepth: this.scopes.length,
3540
+ }
3541
+ : null;
3542
+ if (suppressHandler)
3543
+ this.tryStack.push(suppressHandler);
3447
3544
  this.emitBlock(s.finallyBody);
3545
+ if (suppressHandler)
3546
+ this.tryStack.pop();
3448
3547
  this.scopes.pop(); // normal completion keeps the stash for the re-raise
3449
3548
  B.line(`call void @scr_rethrow(ptr ${stash})`);
3450
3549
  B.line(`call void @scr_caught_release(ptr ${stash})`);
3451
3550
  this.emitUnwind();
3551
+ if (suppressHandler?.used) {
3552
+ B.startBlock(suppressHandler.label);
3553
+ this.declare(`declare void @scr_exc_suppress(ptr)`);
3554
+ B.line(`call void @scr_exc_suppress(ptr ${stash}) ; consumes stash`);
3555
+ this.emitUnwind();
3556
+ }
3452
3557
  }
3453
3558
  B.startBlock(endLabel);
3454
3559
  }
@@ -3519,6 +3624,7 @@ class LlEmitter {
3519
3624
  ...(s.labels !== undefined && { labels: s.labels }),
3520
3625
  frameDepth: this.frames.length,
3521
3626
  scopeDepth: this.scopes.length,
3627
+ finallyDepth: this.finallyStack.length,
3522
3628
  });
3523
3629
  const scope = [];
3524
3630
  this.scopes.push(scope);