@scriptc/cli-darwin-x64 0.0.0 → 0.2.0

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 (960) hide show
  1. package/dist/LICENSE +202 -0
  2. package/dist/THIRD_PARTY_NOTICES +4 -0
  3. package/dist/bin/scriptc +0 -0
  4. package/dist/bin/scriptc.json +21 -0
  5. package/dist/lib/declarations/scriptc-node-fallback.d.ts +3847 -0
  6. package/dist/lib/declarations/scriptc-overrides.d.ts +92 -0
  7. package/dist/lib/declarations/scriptc.d.ts +98 -0
  8. package/dist/lib/llvm/LICENSE +1 -0
  9. package/dist/lib/llvm/SCRIPTC_LICENSE +1 -0
  10. package/dist/lib/llvm/THIRD_PARTY_NOTICES +1 -0
  11. package/dist/lib/llvm/bin/scriptc-llvm-codegen +0 -0
  12. package/dist/lib/llvm/package.json +35 -0
  13. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_array.o +0 -0
  14. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_assert.o +0 -0
  15. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_async.o +0 -0
  16. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_async_dyn.o +0 -0
  17. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_bigint.o +0 -0
  18. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_bigint_assert.o +0 -0
  19. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_bytes.o +0 -0
  20. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_bytes_io.o +0 -0
  21. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_child.o +0 -0
  22. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_closure.o +0 -0
  23. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_console.o +0 -0
  24. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_console_native.o +0 -0
  25. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_copying.o +0 -0
  26. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_crypto_async.o +0 -0
  27. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_cycle.o +0 -0
  28. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_dc.o +0 -0
  29. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_dgram.o +0 -0
  30. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_dyn_handle.o +0 -0
  31. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_dyn_invoke.o +0 -0
  32. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_error.o +0 -0
  33. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_events.o +0 -0
  34. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_events_emitter.o +0 -0
  35. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_exception.o +0 -0
  36. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_fetch.o +0 -0
  37. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_ffi.o +0 -0
  38. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_ffi_queue.o +0 -0
  39. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_file_handle.o +0 -0
  40. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_grapheme.o +0 -0
  41. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_http.o +0 -0
  42. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_http2.o +0 -0
  43. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_inspect.o +0 -0
  44. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_json.o +0 -0
  45. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_lib.o +0 -0
  46. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_loop_epoll.o +0 -0
  47. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_loop_kqueue.o +0 -0
  48. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_loop_wsapoll.o +0 -0
  49. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_map.o +0 -0
  50. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_net.o +0 -0
  51. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_node_builtin.o +0 -0
  52. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_number.o +0 -0
  53. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_object.o +0 -0
  54. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_path.o +0 -0
  55. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_qs.o +0 -0
  56. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_readline.o +0 -0
  57. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_regex.o +0 -0
  58. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_stream.o +0 -0
  59. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_string.o +0 -0
  60. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_symbol.o +0 -0
  61. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_test.o +0 -0
  62. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_tls.o +0 -0
  63. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_tls_ca.o +0 -0
  64. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_union.o +0 -0
  65. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_url.o +0 -0
  66. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_url_params.o +0 -0
  67. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_util.o +0 -0
  68. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_watch.o +0 -0
  69. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_zlib.o +0 -0
  70. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_array.o +0 -0
  71. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_assert.o +0 -0
  72. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_async.o +0 -0
  73. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_async_dyn.o +0 -0
  74. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_bigint.o +0 -0
  75. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_bigint_assert.o +0 -0
  76. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_bytes.o +0 -0
  77. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_bytes_io.o +0 -0
  78. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_child.o +0 -0
  79. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_closure.o +0 -0
  80. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_console.o +0 -0
  81. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_console_native.o +0 -0
  82. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_copying.o +0 -0
  83. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_crypto_async.o +0 -0
  84. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_cycle.o +0 -0
  85. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_dc.o +0 -0
  86. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_dgram.o +0 -0
  87. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_dyn_handle.o +0 -0
  88. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_dyn_invoke.o +0 -0
  89. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_error.o +0 -0
  90. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_events.o +0 -0
  91. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_events_emitter.o +0 -0
  92. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_exception.o +0 -0
  93. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_fetch.o +0 -0
  94. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_ffi.o +0 -0
  95. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_ffi_queue.o +0 -0
  96. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_file_handle.o +0 -0
  97. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_grapheme.o +0 -0
  98. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_http.o +0 -0
  99. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_http2.o +0 -0
  100. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_inspect.o +0 -0
  101. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_inspect_island.o +0 -0
  102. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_island.o +0 -0
  103. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_json.o +0 -0
  104. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_lib.o +0 -0
  105. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_loop_epoll.o +0 -0
  106. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_loop_kqueue.o +0 -0
  107. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_loop_wsapoll.o +0 -0
  108. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_map.o +0 -0
  109. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_net.o +0 -0
  110. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_net_island.o +0 -0
  111. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_node_builtin.o +0 -0
  112. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_number.o +0 -0
  113. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_object.o +0 -0
  114. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_path.o +0 -0
  115. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_qs.o +0 -0
  116. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_readline.o +0 -0
  117. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_regex.o +0 -0
  118. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_stream.o +0 -0
  119. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_string.o +0 -0
  120. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_symbol.o +0 -0
  121. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_test.o +0 -0
  122. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_tls.o +0 -0
  123. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_tls_ca.o +0 -0
  124. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_union.o +0 -0
  125. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_url.o +0 -0
  126. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_url_params.o +0 -0
  127. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_util.o +0 -0
  128. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_watch.o +0 -0
  129. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_web.o +0 -0
  130. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_zlib.o +0 -0
  131. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_zlib_island.o +0 -0
  132. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic-text-decoder-legacy/scr_bytes.o +0 -0
  133. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  134. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_array.o +0 -0
  135. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_assert.o +0 -0
  136. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_bigint.o +0 -0
  137. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_bigint_assert.o +0 -0
  138. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_bytes.o +0 -0
  139. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_bytes_io.o +0 -0
  140. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_closure.o +0 -0
  141. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_console.o +0 -0
  142. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_console_native.o +0 -0
  143. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_copying.o +0 -0
  144. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_cycle.o +0 -0
  145. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_dyn_handle.o +0 -0
  146. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_dyn_invoke.o +0 -0
  147. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_error.o +0 -0
  148. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_events_emitter.o +0 -0
  149. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_exception.o +0 -0
  150. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_grapheme.o +0 -0
  151. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_inspect.o +0 -0
  152. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_json.o +0 -0
  153. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_lib.o +0 -0
  154. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_library.o +0 -0
  155. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_map.o +0 -0
  156. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_node_builtin.o +0 -0
  157. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_number.o +0 -0
  158. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_object.o +0 -0
  159. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_path.o +0 -0
  160. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_regex.o +0 -0
  161. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_string.o +0 -0
  162. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_symbol.o +0 -0
  163. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_union.o +0 -0
  164. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_url.o +0 -0
  165. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_url_params.o +0 -0
  166. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_zlib.o +0 -0
  167. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  168. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_array.o +0 -0
  169. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_assert.o +0 -0
  170. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_bigint.o +0 -0
  171. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_bigint_assert.o +0 -0
  172. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_bytes.o +0 -0
  173. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_bytes_io.o +0 -0
  174. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_closure.o +0 -0
  175. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_console.o +0 -0
  176. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_console_native.o +0 -0
  177. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_copying.o +0 -0
  178. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_cycle.o +0 -0
  179. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_dyn_handle.o +0 -0
  180. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_dyn_invoke.o +0 -0
  181. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_error.o +0 -0
  182. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_events_emitter.o +0 -0
  183. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_exception.o +0 -0
  184. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_grapheme.o +0 -0
  185. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_inspect.o +0 -0
  186. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_json.o +0 -0
  187. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_lib.o +0 -0
  188. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_library.o +0 -0
  189. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_map.o +0 -0
  190. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_node_builtin.o +0 -0
  191. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_number.o +0 -0
  192. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_object.o +0 -0
  193. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_path.o +0 -0
  194. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_regex.o +0 -0
  195. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_string.o +0 -0
  196. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_symbol.o +0 -0
  197. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_union.o +0 -0
  198. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_url.o +0 -0
  199. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_url_params.o +0 -0
  200. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_zlib.o +0 -0
  201. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  202. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_array.o +0 -0
  203. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_assert.o +0 -0
  204. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_bigint.o +0 -0
  205. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_bigint_assert.o +0 -0
  206. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_bytes.o +0 -0
  207. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_bytes_io.o +0 -0
  208. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_closure.o +0 -0
  209. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_console.o +0 -0
  210. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_console_native.o +0 -0
  211. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_copying.o +0 -0
  212. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_cycle.o +0 -0
  213. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_dyn_handle.o +0 -0
  214. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_dyn_invoke.o +0 -0
  215. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_error.o +0 -0
  216. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_events_emitter.o +0 -0
  217. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_exception.o +0 -0
  218. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_grapheme.o +0 -0
  219. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_inspect.o +0 -0
  220. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_json.o +0 -0
  221. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_lib.o +0 -0
  222. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_library.o +0 -0
  223. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_map.o +0 -0
  224. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_node_builtin.o +0 -0
  225. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_number.o +0 -0
  226. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_object.o +0 -0
  227. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_path.o +0 -0
  228. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_regex.o +0 -0
  229. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_string.o +0 -0
  230. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_symbol.o +0 -0
  231. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_union.o +0 -0
  232. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_url.o +0 -0
  233. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_url_params.o +0 -0
  234. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_zlib.o +0 -0
  235. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  236. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_array.o +0 -0
  237. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_assert.o +0 -0
  238. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_bigint.o +0 -0
  239. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_bigint_assert.o +0 -0
  240. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_bytes.o +0 -0
  241. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_bytes_io.o +0 -0
  242. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_closure.o +0 -0
  243. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_console.o +0 -0
  244. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_console_native.o +0 -0
  245. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_copying.o +0 -0
  246. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_cycle.o +0 -0
  247. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_dyn_handle.o +0 -0
  248. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_dyn_invoke.o +0 -0
  249. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_error.o +0 -0
  250. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_events_emitter.o +0 -0
  251. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_exception.o +0 -0
  252. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_grapheme.o +0 -0
  253. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_inspect.o +0 -0
  254. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_json.o +0 -0
  255. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_lib.o +0 -0
  256. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_library.o +0 -0
  257. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_map.o +0 -0
  258. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_node_builtin.o +0 -0
  259. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_number.o +0 -0
  260. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_object.o +0 -0
  261. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_path.o +0 -0
  262. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_regex.o +0 -0
  263. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_string.o +0 -0
  264. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_symbol.o +0 -0
  265. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_union.o +0 -0
  266. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_url.o +0 -0
  267. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_url_params.o +0 -0
  268. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_zlib.o +0 -0
  269. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  270. package/dist/lib/runtime-darwin-x64/artifacts/licenses/mbedtls.txt +553 -0
  271. package/dist/lib/runtime-darwin-x64/artifacts/licenses/quickjs-ng.txt +24 -0
  272. package/dist/lib/runtime-darwin-x64/artifacts/licenses/ryu.txt +23 -0
  273. package/dist/lib/runtime-darwin-x64/artifacts/licenses/scriptc-runtime.txt +202 -0
  274. package/dist/lib/runtime-darwin-x64/artifacts/licenses/unicode.txt +39 -0
  275. package/dist/lib/runtime-darwin-x64/artifacts/licenses/zlib.txt +22 -0
  276. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_array.o +0 -0
  277. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_assert.o +0 -0
  278. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_async.o +0 -0
  279. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_async_dyn.o +0 -0
  280. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_bigint.o +0 -0
  281. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_bigint_assert.o +0 -0
  282. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_bytes.o +0 -0
  283. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_bytes_io.o +0 -0
  284. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_child.o +0 -0
  285. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_closure.o +0 -0
  286. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_console.o +0 -0
  287. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_console_native.o +0 -0
  288. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_copying.o +0 -0
  289. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_crypto_async.o +0 -0
  290. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_cycle.o +0 -0
  291. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_dc.o +0 -0
  292. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_dgram.o +0 -0
  293. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_dyn_handle.o +0 -0
  294. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_dyn_invoke.o +0 -0
  295. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_error.o +0 -0
  296. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_events.o +0 -0
  297. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_events_emitter.o +0 -0
  298. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_exception.o +0 -0
  299. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_fetch.o +0 -0
  300. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_ffi.o +0 -0
  301. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_ffi_queue.o +0 -0
  302. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_file_handle.o +0 -0
  303. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_grapheme.o +0 -0
  304. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_http.o +0 -0
  305. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_http2.o +0 -0
  306. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_inspect.o +0 -0
  307. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_json.o +0 -0
  308. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_lib.o +0 -0
  309. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_loop_epoll.o +0 -0
  310. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_loop_kqueue.o +0 -0
  311. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_loop_wsapoll.o +0 -0
  312. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_map.o +0 -0
  313. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_net.o +0 -0
  314. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_node_builtin.o +0 -0
  315. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_number.o +0 -0
  316. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_object.o +0 -0
  317. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_path.o +0 -0
  318. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_qs.o +0 -0
  319. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_readline.o +0 -0
  320. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_regex.o +0 -0
  321. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_stream.o +0 -0
  322. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_string.o +0 -0
  323. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_symbol.o +0 -0
  324. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_test.o +0 -0
  325. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_tls.o +0 -0
  326. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_tls_ca.o +0 -0
  327. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_union.o +0 -0
  328. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_url.o +0 -0
  329. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_url_params.o +0 -0
  330. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_util.o +0 -0
  331. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_watch.o +0 -0
  332. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_zlib.o +0 -0
  333. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_array.o +0 -0
  334. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_assert.o +0 -0
  335. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_async.o +0 -0
  336. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_async_dyn.o +0 -0
  337. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_bigint.o +0 -0
  338. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_bigint_assert.o +0 -0
  339. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_bytes.o +0 -0
  340. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_bytes_io.o +0 -0
  341. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_child.o +0 -0
  342. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_closure.o +0 -0
  343. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_console.o +0 -0
  344. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_console_native.o +0 -0
  345. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_copying.o +0 -0
  346. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_crypto_async.o +0 -0
  347. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_cycle.o +0 -0
  348. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_dc.o +0 -0
  349. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_dgram.o +0 -0
  350. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_dyn_handle.o +0 -0
  351. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_dyn_invoke.o +0 -0
  352. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_error.o +0 -0
  353. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_events.o +0 -0
  354. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_events_emitter.o +0 -0
  355. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_exception.o +0 -0
  356. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_fetch.o +0 -0
  357. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_ffi.o +0 -0
  358. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_ffi_queue.o +0 -0
  359. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_file_handle.o +0 -0
  360. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_grapheme.o +0 -0
  361. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_http.o +0 -0
  362. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_http2.o +0 -0
  363. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_inspect.o +0 -0
  364. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_inspect_island.o +0 -0
  365. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_island.o +0 -0
  366. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_json.o +0 -0
  367. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_lib.o +0 -0
  368. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_loop_epoll.o +0 -0
  369. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_loop_kqueue.o +0 -0
  370. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_loop_wsapoll.o +0 -0
  371. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_map.o +0 -0
  372. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_net.o +0 -0
  373. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_net_island.o +0 -0
  374. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_node_builtin.o +0 -0
  375. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_number.o +0 -0
  376. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_object.o +0 -0
  377. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_path.o +0 -0
  378. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_qs.o +0 -0
  379. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_readline.o +0 -0
  380. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_regex.o +0 -0
  381. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_stream.o +0 -0
  382. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_string.o +0 -0
  383. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_symbol.o +0 -0
  384. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_test.o +0 -0
  385. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_tls.o +0 -0
  386. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_tls_ca.o +0 -0
  387. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_union.o +0 -0
  388. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_url.o +0 -0
  389. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_url_params.o +0 -0
  390. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_util.o +0 -0
  391. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_watch.o +0 -0
  392. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_web.o +0 -0
  393. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_zlib.o +0 -0
  394. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_zlib_island.o +0 -0
  395. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic-text-decoder-legacy/scr_bytes.o +0 -0
  396. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  397. package/dist/lib/runtime-darwin-x64/artifacts/vendor/libregexp/libscriptc-libregexp.a +0 -0
  398. package/dist/lib/runtime-darwin-x64/artifacts/vendor/mbedtls/libscriptc-mbedtls.a +0 -0
  399. package/dist/lib/runtime-darwin-x64/artifacts/vendor/quickjs/libscriptc-quickjs.a +0 -0
  400. package/dist/lib/runtime-darwin-x64/artifacts/vendor/zlib/libscriptc-zlib.a +0 -0
  401. package/dist/lib/runtime-darwin-x64/package.json +24 -0
  402. package/dist/lib/runtime-darwin-x64/runtime-pack.json +5758 -0
  403. package/dist/lib/runtime-sources/LICENSE +202 -0
  404. package/dist/lib/runtime-sources/package.json +22 -0
  405. package/dist/lib/runtime-sources/src/scr_array.c +1444 -0
  406. package/dist/lib/runtime-sources/src/scr_assert.c +1537 -0
  407. package/dist/lib/runtime-sources/src/scr_async.c +3920 -0
  408. package/dist/lib/runtime-sources/src/scr_async.test.c +134 -0
  409. package/dist/lib/runtime-sources/src/scr_async.test.ts +34 -0
  410. package/dist/lib/runtime-sources/src/scr_async_dyn.c +803 -0
  411. package/dist/lib/runtime-sources/src/scr_bigint.c +890 -0
  412. package/dist/lib/runtime-sources/src/scr_bigint_assert.c +22 -0
  413. package/dist/lib/runtime-sources/src/scr_bytes.c +2518 -0
  414. package/dist/lib/runtime-sources/src/scr_bytes_io.c +755 -0
  415. package/dist/lib/runtime-sources/src/scr_child.c +5808 -0
  416. package/dist/lib/runtime-sources/src/scr_closure.c +213 -0
  417. package/dist/lib/runtime-sources/src/scr_console.c +259 -0
  418. package/dist/lib/runtime-sources/src/scr_console_native.c +95 -0
  419. package/dist/lib/runtime-sources/src/scr_copying.c +146 -0
  420. package/dist/lib/runtime-sources/src/scr_crypto_async.c +24 -0
  421. package/dist/lib/runtime-sources/src/scr_cycle.c +565 -0
  422. package/dist/lib/runtime-sources/src/scr_dc.c +814 -0
  423. package/dist/lib/runtime-sources/src/scr_dgram.c +1182 -0
  424. package/dist/lib/runtime-sources/src/scr_dyn_handle.c +96 -0
  425. package/dist/lib/runtime-sources/src/scr_dyn_invoke.c +1626 -0
  426. package/dist/lib/runtime-sources/src/scr_error.c +372 -0
  427. package/dist/lib/runtime-sources/src/scr_events.c +1222 -0
  428. package/dist/lib/runtime-sources/src/scr_events_emitter.c +842 -0
  429. package/dist/lib/runtime-sources/src/scr_exception.c +468 -0
  430. package/dist/lib/runtime-sources/src/scr_fetch.c +7215 -0
  431. package/dist/lib/runtime-sources/src/scr_fetch_curl.c +666 -0
  432. package/dist/lib/runtime-sources/src/scr_ffi.c +143 -0
  433. package/dist/lib/runtime-sources/src/scr_ffi_queue.c +379 -0
  434. package/dist/lib/runtime-sources/src/scr_file_handle.c +562 -0
  435. package/dist/lib/runtime-sources/src/scr_grapheme.c +203 -0
  436. package/dist/lib/runtime-sources/src/scr_grapheme_data.h +842 -0
  437. package/dist/lib/runtime-sources/src/scr_http.c +5808 -0
  438. package/dist/lib/runtime-sources/src/scr_http2.c +3243 -0
  439. package/dist/lib/runtime-sources/src/scr_inspect.c +923 -0
  440. package/dist/lib/runtime-sources/src/scr_inspect_island.c +51 -0
  441. package/dist/lib/runtime-sources/src/scr_island.c +9987 -0
  442. package/dist/lib/runtime-sources/src/scr_island_manifest.h +153 -0
  443. package/dist/lib/runtime-sources/src/scr_json.c +7928 -0
  444. package/dist/lib/runtime-sources/src/scr_json.test.c +182 -0
  445. package/dist/lib/runtime-sources/src/scr_json.test.ts +33 -0
  446. package/dist/lib/runtime-sources/src/scr_lib.c +6304 -0
  447. package/dist/lib/runtime-sources/src/scr_library.c +444 -0
  448. package/dist/lib/runtime-sources/src/scr_loop_epoll.c +241 -0
  449. package/dist/lib/runtime-sources/src/scr_loop_kqueue.c +121 -0
  450. package/dist/lib/runtime-sources/src/scr_loop_wsapoll.c +208 -0
  451. package/dist/lib/runtime-sources/src/scr_map.c +705 -0
  452. package/dist/lib/runtime-sources/src/scr_musl.c +438 -0
  453. package/dist/lib/runtime-sources/src/scr_net.c +3708 -0
  454. package/dist/lib/runtime-sources/src/scr_net_island.c +458 -0
  455. package/dist/lib/runtime-sources/src/scr_node_builtin.c +281 -0
  456. package/dist/lib/runtime-sources/src/scr_number.c +192 -0
  457. package/dist/lib/runtime-sources/src/scr_object.c +80 -0
  458. package/dist/lib/runtime-sources/src/scr_path.c +1281 -0
  459. package/dist/lib/runtime-sources/src/scr_platform.h +119 -0
  460. package/dist/lib/runtime-sources/src/scr_qs.c +496 -0
  461. package/dist/lib/runtime-sources/src/scr_readline.c +288 -0
  462. package/dist/lib/runtime-sources/src/scr_regex.c +1274 -0
  463. package/dist/lib/runtime-sources/src/scr_runtime.h +7207 -0
  464. package/dist/lib/runtime-sources/src/scr_stream.c +3149 -0
  465. package/dist/lib/runtime-sources/src/scr_string.c +1849 -0
  466. package/dist/lib/runtime-sources/src/scr_symbol.c +234 -0
  467. package/dist/lib/runtime-sources/src/scr_test.c +662 -0
  468. package/dist/lib/runtime-sources/src/scr_text_decoder_data.h +7389 -0
  469. package/dist/lib/runtime-sources/src/scr_tls.c +1806 -0
  470. package/dist/lib/runtime-sources/src/scr_tls_ca.c +433 -0
  471. package/dist/lib/runtime-sources/src/scr_union.c +105 -0
  472. package/dist/lib/runtime-sources/src/scr_url.c +1231 -0
  473. package/dist/lib/runtime-sources/src/scr_url_internal.h +29 -0
  474. package/dist/lib/runtime-sources/src/scr_url_params.c +526 -0
  475. package/dist/lib/runtime-sources/src/scr_util.c +984 -0
  476. package/dist/lib/runtime-sources/src/scr_watch.c +568 -0
  477. package/dist/lib/runtime-sources/src/scr_web.c +1854 -0
  478. package/dist/lib/runtime-sources/src/scr_win.c +231 -0
  479. package/dist/lib/runtime-sources/src/scr_win_stats.h +23 -0
  480. package/dist/lib/runtime-sources/src/scr_zlib.c +358 -0
  481. package/dist/lib/runtime-sources/src/scr_zlib_island.c +15 -0
  482. package/dist/lib/runtime-sources/vendor/README.md +60 -0
  483. package/dist/lib/runtime-sources/vendor/curl/COPYRIGHT +534 -0
  484. package/dist/lib/runtime-sources/vendor/curl/include/curl/curl.h +3214 -0
  485. package/dist/lib/runtime-sources/vendor/curl/include/curl/curlver.h +79 -0
  486. package/dist/lib/runtime-sources/vendor/curl/include/curl/easy.h +125 -0
  487. package/dist/lib/runtime-sources/vendor/curl/include/curl/header.h +74 -0
  488. package/dist/lib/runtime-sources/vendor/curl/include/curl/mprintf.h +52 -0
  489. package/dist/lib/runtime-sources/vendor/curl/include/curl/multi.h +460 -0
  490. package/dist/lib/runtime-sources/vendor/curl/include/curl/options.h +70 -0
  491. package/dist/lib/runtime-sources/vendor/curl/include/curl/stdcheaders.h +35 -0
  492. package/dist/lib/runtime-sources/vendor/curl/include/curl/system.h +508 -0
  493. package/dist/lib/runtime-sources/vendor/curl/include/curl/typecheck-gcc.h +716 -0
  494. package/dist/lib/runtime-sources/vendor/curl/include/curl/urlapi.h +149 -0
  495. package/dist/lib/runtime-sources/vendor/curl/include/curl/websockets.h +84 -0
  496. package/dist/lib/runtime-sources/vendor/mbedtls/LICENSE +553 -0
  497. package/dist/lib/runtime-sources/vendor/mbedtls/include/CMakeLists.txt +22 -0
  498. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/aes.h +631 -0
  499. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/aria.h +343 -0
  500. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/asn1.h +642 -0
  501. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/asn1write.h +390 -0
  502. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/base64.h +82 -0
  503. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/bignum.h +1088 -0
  504. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/block_cipher.h +76 -0
  505. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/build_info.h +194 -0
  506. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/camellia.h +305 -0
  507. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ccm.h +526 -0
  508. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/chacha20.h +209 -0
  509. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/chachapoly.h +351 -0
  510. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/check_config.h +1149 -0
  511. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/cipher.h +1250 -0
  512. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/cmac.h +246 -0
  513. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/compat-2.x.h +46 -0
  514. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/config_adjust_legacy_crypto.h +578 -0
  515. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/config_adjust_legacy_from_psa.h +873 -0
  516. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/config_adjust_psa_from_legacy.h +359 -0
  517. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/config_adjust_psa_superset_legacy.h +145 -0
  518. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/config_adjust_ssl.h +91 -0
  519. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/config_adjust_x509.h +35 -0
  520. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/config_psa.h +61 -0
  521. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/constant_time.h +36 -0
  522. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ctr_drbg.h +596 -0
  523. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/debug.h +156 -0
  524. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/des.h +385 -0
  525. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/dhm.h +972 -0
  526. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ecdh.h +455 -0
  527. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ecdsa.h +674 -0
  528. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ecjpake.h +298 -0
  529. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ecp.h +1517 -0
  530. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/entropy.h +274 -0
  531. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/error.h +201 -0
  532. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/gcm.h +387 -0
  533. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/hkdf.h +124 -0
  534. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/hmac_drbg.h +434 -0
  535. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/lms.h +440 -0
  536. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/mbedtls_config.h +4446 -0
  537. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/md.h +526 -0
  538. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/md5.h +190 -0
  539. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/memory_buffer_alloc.h +142 -0
  540. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/net_sockets.h +299 -0
  541. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/nist_kw.h +166 -0
  542. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/oid.h +727 -0
  543. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/pem.h +160 -0
  544. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/pk.h +1303 -0
  545. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/pkcs12.h +186 -0
  546. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/pkcs5.h +198 -0
  547. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/pkcs7.h +252 -0
  548. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/platform.h +516 -0
  549. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/platform_time.h +79 -0
  550. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/platform_util.h +247 -0
  551. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/poly1305.h +168 -0
  552. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/private_access.h +20 -0
  553. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/psa_util.h +207 -0
  554. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ripemd160.h +136 -0
  555. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/rsa.h +1170 -0
  556. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/sha1.h +219 -0
  557. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/sha256.h +200 -0
  558. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/sha3.h +172 -0
  559. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/sha512.h +208 -0
  560. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ssl.h +5887 -0
  561. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ssl_cache.h +187 -0
  562. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ssl_ciphersuites.h +482 -0
  563. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ssl_cookie.h +106 -0
  564. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ssl_ticket.h +199 -0
  565. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/threading.h +167 -0
  566. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/timing.h +94 -0
  567. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/version.h +78 -0
  568. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/x509.h +500 -0
  569. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/x509_crl.h +184 -0
  570. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/x509_crt.h +1208 -0
  571. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/x509_csr.h +382 -0
  572. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/build_info.h +20 -0
  573. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto.h +4998 -0
  574. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_adjust_auto_enabled.h +31 -0
  575. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_adjust_config_dependencies.h +51 -0
  576. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_adjust_config_key_pair_types.h +101 -0
  577. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_adjust_config_synonyms.h +49 -0
  578. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_builtin_composites.h +214 -0
  579. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_builtin_key_derivation.h +118 -0
  580. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_builtin_primitives.h +114 -0
  581. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_compat.h +230 -0
  582. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_config.h +145 -0
  583. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_driver_common.h +44 -0
  584. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_driver_contexts_composites.h +151 -0
  585. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_driver_contexts_key_derivation.h +52 -0
  586. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_driver_contexts_primitives.h +105 -0
  587. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_extra.h +2145 -0
  588. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_legacy.h +88 -0
  589. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_platform.h +102 -0
  590. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_se_driver.h +1383 -0
  591. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_sizes.h +1319 -0
  592. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_struct.h +527 -0
  593. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_types.h +508 -0
  594. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_values.h +2782 -0
  595. package/dist/lib/runtime-sources/vendor/mbedtls/library/aes.c +2294 -0
  596. package/dist/lib/runtime-sources/vendor/mbedtls/library/aesce.c +624 -0
  597. package/dist/lib/runtime-sources/vendor/mbedtls/library/aesce.h +136 -0
  598. package/dist/lib/runtime-sources/vendor/mbedtls/library/aesni.c +846 -0
  599. package/dist/lib/runtime-sources/vendor/mbedtls/library/aesni.h +162 -0
  600. package/dist/lib/runtime-sources/vendor/mbedtls/library/alignment.h +704 -0
  601. package/dist/lib/runtime-sources/vendor/mbedtls/library/aria.c +969 -0
  602. package/dist/lib/runtime-sources/vendor/mbedtls/library/asn1parse.c +468 -0
  603. package/dist/lib/runtime-sources/vendor/mbedtls/library/asn1write.c +440 -0
  604. package/dist/lib/runtime-sources/vendor/mbedtls/library/base64.c +322 -0
  605. package/dist/lib/runtime-sources/vendor/mbedtls/library/base64_internal.h +45 -0
  606. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum.c +2583 -0
  607. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum_core.c +1240 -0
  608. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum_core.h +872 -0
  609. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum_core_invasive.h +38 -0
  610. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum_internal.h +122 -0
  611. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum_mod.c +394 -0
  612. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum_mod.h +452 -0
  613. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum_mod_raw.c +276 -0
  614. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum_mod_raw.h +416 -0
  615. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum_mod_raw_invasive.h +34 -0
  616. package/dist/lib/runtime-sources/vendor/mbedtls/library/block_cipher.c +207 -0
  617. package/dist/lib/runtime-sources/vendor/mbedtls/library/block_cipher_internal.h +99 -0
  618. package/dist/lib/runtime-sources/vendor/mbedtls/library/bn_mul.h +1094 -0
  619. package/dist/lib/runtime-sources/vendor/mbedtls/library/camellia.c +1058 -0
  620. package/dist/lib/runtime-sources/vendor/mbedtls/library/ccm.c +777 -0
  621. package/dist/lib/runtime-sources/vendor/mbedtls/library/chacha20.c +563 -0
  622. package/dist/lib/runtime-sources/vendor/mbedtls/library/chacha20_internal.h +23 -0
  623. package/dist/lib/runtime-sources/vendor/mbedtls/library/chachapoly.c +487 -0
  624. package/dist/lib/runtime-sources/vendor/mbedtls/library/check_crypto_config.h +136 -0
  625. package/dist/lib/runtime-sources/vendor/mbedtls/library/cipher.c +1712 -0
  626. package/dist/lib/runtime-sources/vendor/mbedtls/library/cipher_invasive.h +28 -0
  627. package/dist/lib/runtime-sources/vendor/mbedtls/library/cipher_wrap.c +2482 -0
  628. package/dist/lib/runtime-sources/vendor/mbedtls/library/cipher_wrap.h +178 -0
  629. package/dist/lib/runtime-sources/vendor/mbedtls/library/cmac.c +1067 -0
  630. package/dist/lib/runtime-sources/vendor/mbedtls/library/common.h +487 -0
  631. package/dist/lib/runtime-sources/vendor/mbedtls/library/constant_time.c +247 -0
  632. package/dist/lib/runtime-sources/vendor/mbedtls/library/constant_time_impl.h +541 -0
  633. package/dist/lib/runtime-sources/vendor/mbedtls/library/constant_time_internal.h +579 -0
  634. package/dist/lib/runtime-sources/vendor/mbedtls/library/ctr.h +35 -0
  635. package/dist/lib/runtime-sources/vendor/mbedtls/library/ctr_drbg.c +1016 -0
  636. package/dist/lib/runtime-sources/vendor/mbedtls/library/debug.c +475 -0
  637. package/dist/lib/runtime-sources/vendor/mbedtls/library/debug_internal.h +185 -0
  638. package/dist/lib/runtime-sources/vendor/mbedtls/library/des.c +1042 -0
  639. package/dist/lib/runtime-sources/vendor/mbedtls/library/dhm.c +700 -0
  640. package/dist/lib/runtime-sources/vendor/mbedtls/library/ecdh.c +696 -0
  641. package/dist/lib/runtime-sources/vendor/mbedtls/library/ecdsa.c +858 -0
  642. package/dist/lib/runtime-sources/vendor/mbedtls/library/ecjpake.c +1216 -0
  643. package/dist/lib/runtime-sources/vendor/mbedtls/library/ecp.c +3674 -0
  644. package/dist/lib/runtime-sources/vendor/mbedtls/library/ecp_curves.c +6125 -0
  645. package/dist/lib/runtime-sources/vendor/mbedtls/library/ecp_curves_new.c +9 -0
  646. package/dist/lib/runtime-sources/vendor/mbedtls/library/ecp_internal_alt.h +287 -0
  647. package/dist/lib/runtime-sources/vendor/mbedtls/library/ecp_invasive.h +305 -0
  648. package/dist/lib/runtime-sources/vendor/mbedtls/library/entropy.c +680 -0
  649. package/dist/lib/runtime-sources/vendor/mbedtls/library/entropy_poll.c +233 -0
  650. package/dist/lib/runtime-sources/vendor/mbedtls/library/entropy_poll.h +64 -0
  651. package/dist/lib/runtime-sources/vendor/mbedtls/library/error.c +878 -0
  652. package/dist/lib/runtime-sources/vendor/mbedtls/library/gcm.c +1330 -0
  653. package/dist/lib/runtime-sources/vendor/mbedtls/library/hkdf.c +161 -0
  654. package/dist/lib/runtime-sources/vendor/mbedtls/library/hmac_drbg.c +633 -0
  655. package/dist/lib/runtime-sources/vendor/mbedtls/library/lmots.c +789 -0
  656. package/dist/lib/runtime-sources/vendor/mbedtls/library/lmots.h +288 -0
  657. package/dist/lib/runtime-sources/vendor/mbedtls/library/lms.c +778 -0
  658. package/dist/lib/runtime-sources/vendor/mbedtls/library/md.c +1108 -0
  659. package/dist/lib/runtime-sources/vendor/mbedtls/library/md5.c +426 -0
  660. package/dist/lib/runtime-sources/vendor/mbedtls/library/md_psa.h +26 -0
  661. package/dist/lib/runtime-sources/vendor/mbedtls/library/md_wrap.h +46 -0
  662. package/dist/lib/runtime-sources/vendor/mbedtls/library/memory_buffer_alloc.c +751 -0
  663. package/dist/lib/runtime-sources/vendor/mbedtls/library/mps_common.h +181 -0
  664. package/dist/lib/runtime-sources/vendor/mbedtls/library/mps_error.h +89 -0
  665. package/dist/lib/runtime-sources/vendor/mbedtls/library/mps_reader.c +538 -0
  666. package/dist/lib/runtime-sources/vendor/mbedtls/library/mps_reader.h +366 -0
  667. package/dist/lib/runtime-sources/vendor/mbedtls/library/mps_trace.c +112 -0
  668. package/dist/lib/runtime-sources/vendor/mbedtls/library/mps_trace.h +154 -0
  669. package/dist/lib/runtime-sources/vendor/mbedtls/library/net_sockets.c +694 -0
  670. package/dist/lib/runtime-sources/vendor/mbedtls/library/nist_kw.c +729 -0
  671. package/dist/lib/runtime-sources/vendor/mbedtls/library/oid.c +1166 -0
  672. package/dist/lib/runtime-sources/vendor/mbedtls/library/padlock.c +157 -0
  673. package/dist/lib/runtime-sources/vendor/mbedtls/library/padlock.h +111 -0
  674. package/dist/lib/runtime-sources/vendor/mbedtls/library/pem.c +554 -0
  675. package/dist/lib/runtime-sources/vendor/mbedtls/library/pk.c +1602 -0
  676. package/dist/lib/runtime-sources/vendor/mbedtls/library/pk_ecc.c +261 -0
  677. package/dist/lib/runtime-sources/vendor/mbedtls/library/pk_internal.h +241 -0
  678. package/dist/lib/runtime-sources/vendor/mbedtls/library/pk_wrap.c +1618 -0
  679. package/dist/lib/runtime-sources/vendor/mbedtls/library/pk_wrap.h +138 -0
  680. package/dist/lib/runtime-sources/vendor/mbedtls/library/pkcs12.c +437 -0
  681. package/dist/lib/runtime-sources/vendor/mbedtls/library/pkcs5.c +500 -0
  682. package/dist/lib/runtime-sources/vendor/mbedtls/library/pkcs7.c +787 -0
  683. package/dist/lib/runtime-sources/vendor/mbedtls/library/pkparse.c +1392 -0
  684. package/dist/lib/runtime-sources/vendor/mbedtls/library/pkwrite.c +631 -0
  685. package/dist/lib/runtime-sources/vendor/mbedtls/library/pkwrite.h +121 -0
  686. package/dist/lib/runtime-sources/vendor/mbedtls/library/platform.c +402 -0
  687. package/dist/lib/runtime-sources/vendor/mbedtls/library/platform_util.c +258 -0
  688. package/dist/lib/runtime-sources/vendor/mbedtls/library/poly1305.c +492 -0
  689. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto.c +9532 -0
  690. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_aead.c +646 -0
  691. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_aead.h +499 -0
  692. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_cipher.c +747 -0
  693. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_cipher.h +316 -0
  694. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_client.c +22 -0
  695. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_core.h +983 -0
  696. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_core_common.h +52 -0
  697. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_driver_wrappers.h +2896 -0
  698. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.c +256 -0
  699. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.h +31 -0
  700. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_ecp.c +594 -0
  701. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_ecp.h +267 -0
  702. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_ffdh.c +361 -0
  703. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_ffdh.h +131 -0
  704. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_hash.c +470 -0
  705. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_hash.h +211 -0
  706. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_invasive.h +92 -0
  707. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_its.h +131 -0
  708. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_mac.c +505 -0
  709. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_mac.h +264 -0
  710. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_pake.c +571 -0
  711. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_pake.h +159 -0
  712. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_random.c +181 -0
  713. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_random.h +72 -0
  714. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_random_impl.h +200 -0
  715. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_rsa.c +714 -0
  716. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_rsa.h +321 -0
  717. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_se.c +373 -0
  718. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_se.h +192 -0
  719. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_slot_management.c +1137 -0
  720. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_slot_management.h +344 -0
  721. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_storage.c +481 -0
  722. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_storage.h +392 -0
  723. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_its_file.c +254 -0
  724. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_util.c +614 -0
  725. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_util_internal.h +100 -0
  726. package/dist/lib/runtime-sources/vendor/mbedtls/library/ripemd160.c +490 -0
  727. package/dist/lib/runtime-sources/vendor/mbedtls/library/rsa.c +3121 -0
  728. package/dist/lib/runtime-sources/vendor/mbedtls/library/rsa_alt_helpers.c +455 -0
  729. package/dist/lib/runtime-sources/vendor/mbedtls/library/rsa_alt_helpers.h +209 -0
  730. package/dist/lib/runtime-sources/vendor/mbedtls/library/rsa_internal.h +188 -0
  731. package/dist/lib/runtime-sources/vendor/mbedtls/library/sha1.c +480 -0
  732. package/dist/lib/runtime-sources/vendor/mbedtls/library/sha256.c +983 -0
  733. package/dist/lib/runtime-sources/vendor/mbedtls/library/sha3.c +721 -0
  734. package/dist/lib/runtime-sources/vendor/mbedtls/library/sha512.c +1115 -0
  735. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_cache.c +410 -0
  736. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_ciphersuites.c +2050 -0
  737. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_ciphersuites_internal.h +154 -0
  738. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_client.c +1023 -0
  739. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_client.h +22 -0
  740. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_cookie.c +384 -0
  741. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_debug_helpers.h +85 -0
  742. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_debug_helpers_generated.c +251 -0
  743. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_misc.h +3198 -0
  744. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_msg.c +6619 -0
  745. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_ticket.c +556 -0
  746. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_tls.c +10234 -0
  747. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_tls12_client.c +3688 -0
  748. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_tls12_server.c +4311 -0
  749. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_tls13_client.c +3208 -0
  750. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_tls13_generic.c +1793 -0
  751. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_tls13_invasive.h +23 -0
  752. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_tls13_keys.c +1918 -0
  753. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_tls13_keys.h +668 -0
  754. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_tls13_server.c +3624 -0
  755. package/dist/lib/runtime-sources/vendor/mbedtls/library/threading.c +193 -0
  756. package/dist/lib/runtime-sources/vendor/mbedtls/library/threading_internal.h +28 -0
  757. package/dist/lib/runtime-sources/vendor/mbedtls/library/timing.c +152 -0
  758. package/dist/lib/runtime-sources/vendor/mbedtls/library/version.c +32 -0
  759. package/dist/lib/runtime-sources/vendor/mbedtls/library/version_features.c +856 -0
  760. package/dist/lib/runtime-sources/vendor/mbedtls/library/x509.c +1776 -0
  761. package/dist/lib/runtime-sources/vendor/mbedtls/library/x509_create.c +570 -0
  762. package/dist/lib/runtime-sources/vendor/mbedtls/library/x509_crl.c +708 -0
  763. package/dist/lib/runtime-sources/vendor/mbedtls/library/x509_crt.c +3311 -0
  764. package/dist/lib/runtime-sources/vendor/mbedtls/library/x509_csr.c +648 -0
  765. package/dist/lib/runtime-sources/vendor/mbedtls/library/x509_internal.h +101 -0
  766. package/dist/lib/runtime-sources/vendor/mbedtls/library/x509write.c +174 -0
  767. package/dist/lib/runtime-sources/vendor/mbedtls/library/x509write_crt.c +688 -0
  768. package/dist/lib/runtime-sources/vendor/mbedtls/library/x509write_csr.c +336 -0
  769. package/dist/lib/runtime-sources/vendor/quickjs-ng/CMakeLists.txt +566 -0
  770. package/dist/lib/runtime-sources/vendor/quickjs-ng/LICENSE +24 -0
  771. package/dist/lib/runtime-sources/vendor/quickjs-ng/README.md +24 -0
  772. package/dist/lib/runtime-sources/vendor/quickjs-ng/api-test.c +1195 -0
  773. package/dist/lib/runtime-sources/vendor/quickjs-ng/builtin-array-fromasync.h +119 -0
  774. package/dist/lib/runtime-sources/vendor/quickjs-ng/builtin-iterator-zip-keyed.h +332 -0
  775. package/dist/lib/runtime-sources/vendor/quickjs-ng/builtin-iterator-zip.h +337 -0
  776. package/dist/lib/runtime-sources/vendor/quickjs-ng/cutils.h +1998 -0
  777. package/dist/lib/runtime-sources/vendor/quickjs-ng/dtoa.c +1619 -0
  778. package/dist/lib/runtime-sources/vendor/quickjs-ng/dtoa.h +87 -0
  779. package/dist/lib/runtime-sources/vendor/quickjs-ng/gen/function_source.c +81 -0
  780. package/dist/lib/runtime-sources/vendor/quickjs-ng/gen/hello.c +53 -0
  781. package/dist/lib/runtime-sources/vendor/quickjs-ng/gen/hello_module.c +106 -0
  782. package/dist/lib/runtime-sources/vendor/quickjs-ng/gen/repl.c +3036 -0
  783. package/dist/lib/runtime-sources/vendor/quickjs-ng/gen/standalone.c +323 -0
  784. package/dist/lib/runtime-sources/vendor/quickjs-ng/gen/test_fib.c +81 -0
  785. package/dist/lib/runtime-sources/vendor/quickjs-ng/libregexp-opcode.h +73 -0
  786. package/dist/lib/runtime-sources/vendor/quickjs-ng/libregexp.c +3474 -0
  787. package/dist/lib/runtime-sources/vendor/quickjs-ng/libregexp.h +101 -0
  788. package/dist/lib/runtime-sources/vendor/quickjs-ng/libunicode-table.h +5173 -0
  789. package/dist/lib/runtime-sources/vendor/quickjs-ng/libunicode.c +2069 -0
  790. package/dist/lib/runtime-sources/vendor/quickjs-ng/libunicode.h +172 -0
  791. package/dist/lib/runtime-sources/vendor/quickjs-ng/list.h +107 -0
  792. package/dist/lib/runtime-sources/vendor/quickjs-ng/lre-test.c +52 -0
  793. package/dist/lib/runtime-sources/vendor/quickjs-ng/qjs.c +762 -0
  794. package/dist/lib/runtime-sources/vendor/quickjs-ng/qjsc.c +673 -0
  795. package/dist/lib/runtime-sources/vendor/quickjs-ng/quickjs-atom.h +280 -0
  796. package/dist/lib/runtime-sources/vendor/quickjs-ng/quickjs-c-atomics.h +54 -0
  797. package/dist/lib/runtime-sources/vendor/quickjs-ng/quickjs-libc.c +5037 -0
  798. package/dist/lib/runtime-sources/vendor/quickjs-ng/quickjs-libc.h +87 -0
  799. package/dist/lib/runtime-sources/vendor/quickjs-ng/quickjs-opcode.h +377 -0
  800. package/dist/lib/runtime-sources/vendor/quickjs-ng/quickjs.c +64041 -0
  801. package/dist/lib/runtime-sources/vendor/quickjs-ng/quickjs.h +1447 -0
  802. package/dist/lib/runtime-sources/vendor/quickjs-ng/run-test262.c +2374 -0
  803. package/dist/lib/runtime-sources/vendor/quickjs-ng/unicode_gen.c +3121 -0
  804. package/dist/lib/runtime-sources/vendor/quickjs-ng/unicode_gen_def.h +310 -0
  805. package/dist/lib/runtime-sources/vendor/ryu/LICENSE-Boost +23 -0
  806. package/dist/lib/runtime-sources/vendor/ryu/common.h +114 -0
  807. package/dist/lib/runtime-sources/vendor/ryu/d2s.c +509 -0
  808. package/dist/lib/runtime-sources/vendor/ryu/d2s_full_table.h +367 -0
  809. package/dist/lib/runtime-sources/vendor/ryu/d2s_intrinsics.h +357 -0
  810. package/dist/lib/runtime-sources/vendor/ryu/d2s_small_table.h +186 -0
  811. package/dist/lib/runtime-sources/vendor/ryu/digit_table.h +35 -0
  812. package/dist/lib/runtime-sources/vendor/ryu/ryu.h +46 -0
  813. package/dist/lib/runtime-sources/vendor/unicode/LICENSE +39 -0
  814. package/dist/lib/runtime-sources/vendor/zlib/LICENSE +22 -0
  815. package/dist/lib/runtime-sources/vendor/zlib/adler32.c +164 -0
  816. package/dist/lib/runtime-sources/vendor/zlib/compress.c +75 -0
  817. package/dist/lib/runtime-sources/vendor/zlib/crc32.c +1049 -0
  818. package/dist/lib/runtime-sources/vendor/zlib/crc32.h +9446 -0
  819. package/dist/lib/runtime-sources/vendor/zlib/deflate.c +2139 -0
  820. package/dist/lib/runtime-sources/vendor/zlib/deflate.h +377 -0
  821. package/dist/lib/runtime-sources/vendor/zlib/gzclose.c +23 -0
  822. package/dist/lib/runtime-sources/vendor/zlib/gzguts.h +214 -0
  823. package/dist/lib/runtime-sources/vendor/zlib/gzlib.c +582 -0
  824. package/dist/lib/runtime-sources/vendor/zlib/gzread.c +602 -0
  825. package/dist/lib/runtime-sources/vendor/zlib/gzwrite.c +631 -0
  826. package/dist/lib/runtime-sources/vendor/zlib/infback.c +628 -0
  827. package/dist/lib/runtime-sources/vendor/zlib/inffast.c +320 -0
  828. package/dist/lib/runtime-sources/vendor/zlib/inffast.h +11 -0
  829. package/dist/lib/runtime-sources/vendor/zlib/inffixed.h +94 -0
  830. package/dist/lib/runtime-sources/vendor/zlib/inflate.c +1526 -0
  831. package/dist/lib/runtime-sources/vendor/zlib/inflate.h +126 -0
  832. package/dist/lib/runtime-sources/vendor/zlib/inftrees.c +299 -0
  833. package/dist/lib/runtime-sources/vendor/zlib/inftrees.h +62 -0
  834. package/dist/lib/runtime-sources/vendor/zlib/trees.c +1117 -0
  835. package/dist/lib/runtime-sources/vendor/zlib/trees.h +128 -0
  836. package/dist/lib/runtime-sources/vendor/zlib/uncompr.c +85 -0
  837. package/dist/lib/runtime-sources/vendor/zlib/zconf.h +543 -0
  838. package/dist/lib/runtime-sources/vendor/zlib/zlib.h +1938 -0
  839. package/dist/lib/runtime-sources/vendor/zlib/zutil.c +299 -0
  840. package/dist/lib/runtime-sources/vendor/zlib/zutil.h +254 -0
  841. package/dist/lib/scriptc-comptime +0 -0
  842. package/dist/lib/typescript/LICENSE +55 -0
  843. package/dist/lib/typescript/NOTICE.txt +436 -0
  844. package/dist/lib/typescript/lib/lib.d.ts +20 -0
  845. package/dist/lib/typescript/lib/lib.decorators.d.ts +382 -0
  846. package/dist/lib/typescript/lib/lib.decorators.legacy.d.ts +20 -0
  847. package/dist/lib/typescript/lib/lib.dom.asynciterable.d.ts +18 -0
  848. package/dist/lib/typescript/lib/lib.dom.d.ts +45125 -0
  849. package/dist/lib/typescript/lib/lib.dom.iterable.d.ts +18 -0
  850. package/dist/lib/typescript/lib/lib.es2015.collection.d.ts +159 -0
  851. package/dist/lib/typescript/lib/lib.es2015.core.d.ts +595 -0
  852. package/dist/lib/typescript/lib/lib.es2015.d.ts +26 -0
  853. package/dist/lib/typescript/lib/lib.es2015.generator.d.ts +75 -0
  854. package/dist/lib/typescript/lib/lib.es2015.iterable.d.ts +603 -0
  855. package/dist/lib/typescript/lib/lib.es2015.promise.d.ts +79 -0
  856. package/dist/lib/typescript/lib/lib.es2015.proxy.d.ts +126 -0
  857. package/dist/lib/typescript/lib/lib.es2015.reflect.d.ts +142 -0
  858. package/dist/lib/typescript/lib/lib.es2015.symbol.d.ts +44 -0
  859. package/dist/lib/typescript/lib/lib.es2015.symbol.wellknown.d.ts +324 -0
  860. package/dist/lib/typescript/lib/lib.es2016.array.include.d.ts +114 -0
  861. package/dist/lib/typescript/lib/lib.es2016.d.ts +19 -0
  862. package/dist/lib/typescript/lib/lib.es2016.full.d.ts +21 -0
  863. package/dist/lib/typescript/lib/lib.es2016.intl.d.ts +29 -0
  864. package/dist/lib/typescript/lib/lib.es2017.arraybuffer.d.ts +19 -0
  865. package/dist/lib/typescript/lib/lib.es2017.d.ts +24 -0
  866. package/dist/lib/typescript/lib/lib.es2017.date.d.ts +29 -0
  867. package/dist/lib/typescript/lib/lib.es2017.full.d.ts +21 -0
  868. package/dist/lib/typescript/lib/lib.es2017.intl.d.ts +42 -0
  869. package/dist/lib/typescript/lib/lib.es2017.object.d.ts +47 -0
  870. package/dist/lib/typescript/lib/lib.es2017.sharedmemory.d.ts +133 -0
  871. package/dist/lib/typescript/lib/lib.es2017.string.d.ts +47 -0
  872. package/dist/lib/typescript/lib/lib.es2017.typedarrays.d.ts +51 -0
  873. package/dist/lib/typescript/lib/lib.es2018.asyncgenerator.d.ts +75 -0
  874. package/dist/lib/typescript/lib/lib.es2018.asynciterable.d.ts +51 -0
  875. package/dist/lib/typescript/lib/lib.es2018.d.ts +22 -0
  876. package/dist/lib/typescript/lib/lib.es2018.full.d.ts +22 -0
  877. package/dist/lib/typescript/lib/lib.es2018.intl.d.ts +81 -0
  878. package/dist/lib/typescript/lib/lib.es2018.promise.d.ts +28 -0
  879. package/dist/lib/typescript/lib/lib.es2018.regexp.d.ts +35 -0
  880. package/dist/lib/typescript/lib/lib.es2019.array.d.ts +77 -0
  881. package/dist/lib/typescript/lib/lib.es2019.d.ts +22 -0
  882. package/dist/lib/typescript/lib/lib.es2019.full.d.ts +22 -0
  883. package/dist/lib/typescript/lib/lib.es2019.intl.d.ts +21 -0
  884. package/dist/lib/typescript/lib/lib.es2019.object.d.ts +31 -0
  885. package/dist/lib/typescript/lib/lib.es2019.string.d.ts +35 -0
  886. package/dist/lib/typescript/lib/lib.es2019.symbol.d.ts +22 -0
  887. package/dist/lib/typescript/lib/lib.es2020.bigint.d.ts +763 -0
  888. package/dist/lib/typescript/lib/lib.es2020.d.ts +25 -0
  889. package/dist/lib/typescript/lib/lib.es2020.date.d.ts +40 -0
  890. package/dist/lib/typescript/lib/lib.es2020.full.d.ts +22 -0
  891. package/dist/lib/typescript/lib/lib.es2020.intl.d.ts +472 -0
  892. package/dist/lib/typescript/lib/lib.es2020.number.d.ts +26 -0
  893. package/dist/lib/typescript/lib/lib.es2020.promise.d.ts +45 -0
  894. package/dist/lib/typescript/lib/lib.es2020.sharedmemory.d.ts +97 -0
  895. package/dist/lib/typescript/lib/lib.es2020.string.d.ts +42 -0
  896. package/dist/lib/typescript/lib/lib.es2020.symbol.wellknown.d.ts +39 -0
  897. package/dist/lib/typescript/lib/lib.es2021.d.ts +21 -0
  898. package/dist/lib/typescript/lib/lib.es2021.full.d.ts +22 -0
  899. package/dist/lib/typescript/lib/lib.es2021.intl.d.ts +164 -0
  900. package/dist/lib/typescript/lib/lib.es2021.promise.d.ts +46 -0
  901. package/dist/lib/typescript/lib/lib.es2021.string.d.ts +31 -0
  902. package/dist/lib/typescript/lib/lib.es2021.weakref.d.ts +76 -0
  903. package/dist/lib/typescript/lib/lib.es2022.array.d.ts +119 -0
  904. package/dist/lib/typescript/lib/lib.es2022.d.ts +23 -0
  905. package/dist/lib/typescript/lib/lib.es2022.error.d.ts +73 -0
  906. package/dist/lib/typescript/lib/lib.es2022.full.d.ts +22 -0
  907. package/dist/lib/typescript/lib/lib.es2022.intl.d.ts +143 -0
  908. package/dist/lib/typescript/lib/lib.es2022.object.d.ts +24 -0
  909. package/dist/lib/typescript/lib/lib.es2022.regexp.d.ts +37 -0
  910. package/dist/lib/typescript/lib/lib.es2022.string.d.ts +23 -0
  911. package/dist/lib/typescript/lib/lib.es2023.array.d.ts +922 -0
  912. package/dist/lib/typescript/lib/lib.es2023.collection.d.ts +19 -0
  913. package/dist/lib/typescript/lib/lib.es2023.d.ts +20 -0
  914. package/dist/lib/typescript/lib/lib.es2023.full.d.ts +22 -0
  915. package/dist/lib/typescript/lib/lib.es2023.intl.d.ts +62 -0
  916. package/dist/lib/typescript/lib/lib.es2024.arraybuffer.d.ts +63 -0
  917. package/dist/lib/typescript/lib/lib.es2024.collection.d.ts +27 -0
  918. package/dist/lib/typescript/lib/lib.es2024.d.ts +24 -0
  919. package/dist/lib/typescript/lib/lib.es2024.full.d.ts +22 -0
  920. package/dist/lib/typescript/lib/lib.es2024.object.d.ts +27 -0
  921. package/dist/lib/typescript/lib/lib.es2024.promise.d.ts +33 -0
  922. package/dist/lib/typescript/lib/lib.es2024.regexp.d.ts +23 -0
  923. package/dist/lib/typescript/lib/lib.es2024.sharedmemory.d.ts +66 -0
  924. package/dist/lib/typescript/lib/lib.es2024.string.d.ts +27 -0
  925. package/dist/lib/typescript/lib/lib.es2025.collection.d.ts +94 -0
  926. package/dist/lib/typescript/lib/lib.es2025.d.ts +23 -0
  927. package/dist/lib/typescript/lib/lib.es2025.float16.d.ts +443 -0
  928. package/dist/lib/typescript/lib/lib.es2025.full.d.ts +22 -0
  929. package/dist/lib/typescript/lib/lib.es2025.intl.d.ts +200 -0
  930. package/dist/lib/typescript/lib/lib.es2025.iterator.d.ts +146 -0
  931. package/dist/lib/typescript/lib/lib.es2025.promise.d.ts +32 -0
  932. package/dist/lib/typescript/lib/lib.es2025.regexp.d.ts +30 -0
  933. package/dist/lib/typescript/lib/lib.es5.d.ts +4599 -0
  934. package/dist/lib/typescript/lib/lib.es6.d.ts +21 -0
  935. package/dist/lib/typescript/lib/lib.esnext.array.d.ts +33 -0
  936. package/dist/lib/typescript/lib/lib.esnext.collection.d.ts +47 -0
  937. package/dist/lib/typescript/lib/lib.esnext.d.ts +27 -0
  938. package/dist/lib/typescript/lib/lib.esnext.date.d.ts +21 -0
  939. package/dist/lib/typescript/lib/lib.esnext.decorators.d.ts +26 -0
  940. package/dist/lib/typescript/lib/lib.esnext.disposable.d.ts +191 -0
  941. package/dist/lib/typescript/lib/lib.esnext.error.d.ts +22 -0
  942. package/dist/lib/typescript/lib/lib.esnext.full.d.ts +22 -0
  943. package/dist/lib/typescript/lib/lib.esnext.intl.d.ts +107 -0
  944. package/dist/lib/typescript/lib/lib.esnext.sharedmemory.d.ts +23 -0
  945. package/dist/lib/typescript/lib/lib.esnext.temporal.d.ts +485 -0
  946. package/dist/lib/typescript/lib/lib.esnext.typedarrays.d.ts +90 -0
  947. package/dist/lib/typescript/lib/lib.scripthost.d.ts +320 -0
  948. package/dist/lib/typescript/lib/lib.webworker.asynciterable.d.ts +18 -0
  949. package/dist/lib/typescript/lib/lib.webworker.d.ts +15606 -0
  950. package/dist/lib/typescript/lib/lib.webworker.importscripts.d.ts +21 -0
  951. package/dist/lib/typescript/lib/lib.webworker.iterable.d.ts +18 -0
  952. package/dist/lib/typescript/lib/tsc +0 -0
  953. package/dist/lib/typescript/package.json +45 -0
  954. package/dist/lib/wasi/cli/wasi-paths.js +41 -0
  955. package/dist/lib/wasi/cli/wasi-runner.js +28 -0
  956. package/dist/lib/wasi/package.json +1 -0
  957. package/dist/lib/wasi/wasi-paths.js +25 -0
  958. package/package.json +22 -6
  959. package/README.md +0 -3
  960. package/index.js +0 -2
@@ -0,0 +1,3920 @@
1
+ /* Async runtime: stackful fibers, promises, and a dependency-free event
2
+ * loop (microtask queue + timer min-heap).
3
+ *
4
+ * Model (see docs/ir.md):
5
+ * - An async function's body is ordinary compiled C, run on its own fiber
6
+ * (dedicated ucontext stack). Calling it runs the body EAGERLY until
7
+ * the first suspension (JS's synchronous-prefix rule), then control
8
+ * returns to the spawner with a +1 promise.
9
+ * - `await` on a pending promise parks the fiber on the promise's waiter
10
+ * list and switches back to whoever resumed it. Fulfillment moves waiters
11
+ * to the microtask queue (microtasks run before timers, like Node).
12
+ * - Each fiber carries its own exception cell (scr_exc_swap_cell) so a
13
+ * pending exception can't leak across concurrent execution contexts. A
14
+ * throw escaping an async body rejects its promise; awaiting a rejected
15
+ * promise re-throws into the awaiter.
16
+ * - Loop exhaustion with still-suspended fibers exits normally (Node's
17
+ * behavior); those stacks are deliberately not unwound, and the RC audit
18
+ * downgrades to a note in that case.
19
+ */
20
+ #define _XOPEN_SOURCE 700
21
+ /* Anonymous mappings alongside the XSI ucontext API on Darwin and glibc. */
22
+ #ifndef _DARWIN_C_SOURCE
23
+ #define _DARWIN_C_SOURCE 1
24
+ #endif
25
+ #ifndef _DEFAULT_SOURCE
26
+ #define _DEFAULT_SOURCE 1
27
+ #endif
28
+ #include "scr_runtime.h"
29
+
30
+ #include <errno.h>
31
+ #include <fcntl.h>
32
+ #include <stdio.h>
33
+ #include <stdlib.h>
34
+ #include <string.h>
35
+ #include <time.h>
36
+ #ifdef _WIN32
37
+ /* Windows arm: fibers come from the Win32 Fibers API (CreateFiberEx /
38
+ * SwitchToFiber — the direct ucontext analog: cooperatively scheduled,
39
+ * same thread, own stack); the idle sleep is nanosleep (mingw-w64 ships
40
+ * it, over Sleep). poll(2) has no Windows arm — see the sleep seam in
41
+ * scr_loop_run: the poller-backed units (net/dgram/watch) are not built
42
+ * for win32 targets (native-toolchain.ts gates them), so their fds never appear; the
43
+ * events unit DOES cross-compile (scr_events.c's win32 arm) and is
44
+ * served by a capped nanosleep — dispatch at the next turn's top, the
45
+ * cap bounding signal/stdin latency instead of a pollable wake fd. */
46
+ #include <windows.h>
47
+ #elif defined(__wasi__)
48
+ #include <poll.h>
49
+ #else
50
+ #include <poll.h>
51
+ #include <pthread.h>
52
+ #include <signal.h>
53
+ #include <sys/mman.h>
54
+ #include <ucontext.h>
55
+ #include <unistd.h>
56
+ #endif
57
+
58
+ #ifdef __wasi__
59
+ /* WASI Preview 1 has no process-spawn capability. The child unit is not
60
+ * linked for this target, but the generic loop keeps its quiescence hooks;
61
+ * their empty implementation makes the absence explicit at link time
62
+ * without weakening async/timer support. */
63
+ bool scr_children_pending(void) { return false; }
64
+ bool scr_children_ready(void) { return false; }
65
+ bool scr_children_reffed_pending(void) { return false; }
66
+ bool scr_children_failed_pending(void) { return false; }
67
+ void scr_children_poll(void) {}
68
+ int scr_children_wake_fd(void) { return -1; }
69
+ bool scr_children_wait(double max_wait_ms) {
70
+ (void)max_wait_ms;
71
+ return false;
72
+ }
73
+ void scr_children_teardown(void) {}
74
+ #endif
75
+
76
+ #if defined(__has_feature)
77
+ #if __has_feature(address_sanitizer)
78
+ #define SCR_ASAN_FIBERS 1
79
+ void __sanitizer_start_switch_fiber(void **fake_stack_save, const void *bottom, size_t size);
80
+ void __sanitizer_finish_switch_fiber(void *fake_stack_save, const void **bottom_old, size_t *size_old);
81
+ #endif
82
+ #endif
83
+
84
+ /* ASan inflates stack frames severalfold (unoptimized locals + redzones),
85
+ * so the sanitized lane gets proportionally bigger fiber stacks — same
86
+ * headroom DISCIPLINE, instrumented scale. Keep the island's stack budget
87
+ * (scr_island.c) at half of whichever size is active. 8MB under ASan is
88
+ * the measured need: an engine call costs 64–96KB there, and a real
89
+ * embedded graph entered FROM A FIBER (a commander action awaiting
90
+ * generateText — zod parses inside promise chains) nests dozens of engine
91
+ * frames; native POSIX stacks are mapped and committed lazily, so idle
92
+ * fibers pay address space, not RSS. */
93
+ #ifdef SCR_ASAN_FIBERS
94
+ #define SCR_FIBER_STACK (8 * 1024 * 1024)
95
+ #else
96
+ #define SCR_FIBER_STACK (256 * 1024)
97
+ #endif
98
+
99
+ #if !defined(_WIN32) && !defined(__wasi__)
100
+ /* Keep stacks out of malloc's size classes. Reuse a bounded number during
101
+ * a burst of promise/generator work, then unmap the spares before the loop
102
+ * sleeps. This avoids both heap fragmentation and per-call mmap overhead.
103
+ * The sanitizer lane unmaps every finished stack immediately. */
104
+ #ifndef SCR_ASAN_FIBERS
105
+ #define SCR_FIBER_SPARES 4
106
+ static SCR_TL void *scr_fiber_spares[SCR_FIBER_SPARES];
107
+ static SCR_TL size_t scr_fiber_nspares;
108
+ static SCR_TL bool scr_fiber_cleanup_registered;
109
+ #endif
110
+
111
+ static void scr_fiber_stacks_clear(void) {
112
+ #ifndef SCR_ASAN_FIBERS
113
+ while (scr_fiber_nspares > 0) {
114
+ (void)munmap(scr_fiber_spares[--scr_fiber_nspares], SCR_FIBER_STACK);
115
+ scr_fiber_spares[scr_fiber_nspares] = NULL;
116
+ }
117
+ #endif
118
+ }
119
+
120
+ static void *scr_fiber_stack_new(void) {
121
+ #ifndef SCR_ASAN_FIBERS
122
+ if (scr_fiber_nspares > 0) {
123
+ void *stack = scr_fiber_spares[--scr_fiber_nspares];
124
+ scr_fiber_spares[scr_fiber_nspares] = NULL;
125
+ return stack;
126
+ }
127
+ if (!scr_fiber_cleanup_registered) {
128
+ scr_fiber_cleanup_registered = true;
129
+ scr_atexit(scr_fiber_stacks_clear);
130
+ }
131
+ #endif
132
+ void *stack = mmap(NULL, SCR_FIBER_STACK, PROT_READ | PROT_WRITE,
133
+ MAP_PRIVATE | MAP_ANON, -1, 0);
134
+ if (stack == MAP_FAILED) scr_trap("scriptc: out of memory\n");
135
+ return stack;
136
+ }
137
+
138
+ static void scr_fiber_stack_free(void *stack) {
139
+ if (!stack) return;
140
+ #ifndef SCR_ASAN_FIBERS
141
+ if (scr_fiber_nspares < SCR_FIBER_SPARES) {
142
+ scr_fiber_spares[scr_fiber_nspares++] = stack;
143
+ return;
144
+ }
145
+ #endif
146
+ (void)munmap(stack, SCR_FIBER_STACK);
147
+ }
148
+ #endif
149
+
150
+ /* ── promises ─────────────────────────────────────────────────────────── */
151
+
152
+ enum { SCR_PROM_PENDING = 0, SCR_PROM_FULFILLED = 1, SCR_PROM_REJECTED = 2 };
153
+
154
+ typedef struct ScrFiber ScrFiber;
155
+
156
+ struct ScrPromise {
157
+ size_t rc;
158
+ int state;
159
+ bool top_level_handled; /* uncaughtException handled entry evaluation */
160
+ /* Payload (fulfillment value or rejection reason), ScrExcCell-style.
161
+ * trace_fn is non-NULL iff the REF payload type carries a cycle header
162
+ * (a promise settled with a cycle-capable value can be a cycle member —
163
+ * e.g. a closure that captures a box holding this very promise). */
164
+ ScrExcKind payload_kind; /* NONE = void fulfillment */
165
+ double f64;
166
+ bool b;
167
+ void *payload;
168
+ void *(*retain_fn)(void *);
169
+ void (*release_fn)(void *);
170
+ ScrTraceFn trace_fn;
171
+ /* Fibers parked on this promise. */
172
+ ScrFiber **waiters;
173
+ size_t nwaiters, waiters_cap;
174
+ /* Combinator callbacks (Promise.race / Promise.all): at settle,
175
+ * fulfilled promises run adapt(dst, this) — an emitted adapter
176
+ * converting the payload into the destination's inner type — and
177
+ * rejections copy raw (reasons are dynamically tagged). Each entry owns
178
+ * a reference on its dst. Promise.all entries carry the shared
179
+ * countdown state (`all` non-NULL, `all_idx` the entry's INPUT index);
180
+ * race entries leave both zeroed and keep the adapt dispatch. */
181
+ struct ScrPromiseCbWaiter {
182
+ void (*adapt)(ScrPromise *dst, ScrPromise *src);
183
+ ScrPromise *dst;
184
+ struct ScrAllState *all;
185
+ size_t all_idx;
186
+ } *cbs;
187
+ size_t ncbs, cbs_cap;
188
+ /* Unhandled-rejection tracking: set when rejected, cleared on await. */
189
+ bool rejection_observed;
190
+ /* Set when the checkpoint report delivered THIS promise to
191
+ * 'unhandledRejection' listeners — a handler attached after that is
192
+ * Node's 'rejectionHandled' moment (scr_prom_observe below). */
193
+ bool reported_unhandled;
194
+ };
195
+
196
+ #ifdef SCR_RC_AUDIT
197
+ static long scr_live_promises = 0;
198
+ long scr_promise_live_count(void) { return scr_live_promises; }
199
+ #endif
200
+
201
+ /* ── Promise.all shared state ─────────────────────────────────────────
202
+ * One per Promise.all call: the values array filled per INPUT index as
203
+ * entries fulfill, the countdown of fulfillments still missing, and the
204
+ * per-element-kind store helper. The state holds +1 on `values` (NULL for
205
+ * void-element all) and is itself refcounted by the entries that still
206
+ * point at it (parked cb waiters plus the builder while it subscribes);
207
+ * the RESULT promise is NOT held here — each parked entry's cb.dst is the
208
+ * retained result, so promise teardown paths need no all-specific
209
+ * destination handling. */
210
+ typedef struct ScrAllState {
211
+ size_t rc;
212
+ size_t remaining;
213
+ ScrArr *values;
214
+ void (*store)(ScrArr *a, double i, ScrPromise *src);
215
+ } ScrAllState;
216
+
217
+ static void scr_promise_all_state_release(ScrAllState *st) {
218
+ if (--st->rc == 0) {
219
+ if (st->values) scr_arr_release(st->values);
220
+ free(st);
221
+ }
222
+ }
223
+
224
+ static void scr_oom(void) {
225
+ fputs("scriptc: out of memory\n", stderr);
226
+ abort();
227
+ }
228
+
229
+ static void scr_promise_trace(void *o, ScrTraceVisit visit, void *ctx) {
230
+ ScrPromise *p = (ScrPromise *)o;
231
+ /* Waiters are fibers (not refcounted objects) — the settled payload and
232
+ * the combinator destinations are the strong references this promise
233
+ * owns (destination promises are cycle-headered). */
234
+ if ((p->payload_kind == SCR_EXC_REF || p->payload_kind == SCR_EXC_OBJ ||
235
+ p->payload_kind == SCR_EXC_PRIMITIVE_REF) &&
236
+ p->trace_fn) {
237
+ visit(p->payload, ctx);
238
+ }
239
+ for (size_t i = 0; i < p->ncbs; i++) visit(p->cbs[i].dst, ctx);
240
+ }
241
+
242
+ /* Teardown for the collector: release the payload only when the trace does
243
+ * NOT visit it (the complement — see the contract in scr_runtime.h). The
244
+ * cb destinations are always visited, so only the array frees here. */
245
+ static void scr_promise_gcfree(void *o) {
246
+ ScrPromise *p = (ScrPromise *)o;
247
+ if (p->payload_kind == SCR_EXC_STR) {
248
+ scr_str_release((ScrStr *)p->payload);
249
+ } else if ((p->payload_kind == SCR_EXC_REF || p->payload_kind == SCR_EXC_OBJ ||
250
+ p->payload_kind == SCR_EXC_PRIMITIVE_REF) &&
251
+ p->payload && !p->trace_fn) {
252
+ p->release_fn(p->payload);
253
+ }
254
+ /* Parked Promise.all states are NOT traced children (their values array
255
+ * is reachable only through them) — release like the untraced payload
256
+ * above; the cb destinations stay untouched (trace visits them). */
257
+ for (size_t i = 0; i < p->ncbs; i++) {
258
+ if (p->cbs[i].all) scr_promise_all_state_release(p->cbs[i].all);
259
+ }
260
+ free(p->waiters);
261
+ free(p->cbs);
262
+ #ifdef SCR_RC_AUDIT
263
+ scr_live_promises--;
264
+ #endif
265
+ scr_cyc_free(p);
266
+ }
267
+
268
+ ScrPromise *scr_promise_new(void) {
269
+ ScrPromise *p = scr_cyc_alloc(sizeof *p, &scr_promise_trace, &scr_promise_gcfree);
270
+ p->rc = 1;
271
+ #ifdef SCR_RC_AUDIT
272
+ scr_live_promises++;
273
+ #endif
274
+ return p;
275
+ }
276
+
277
+ /* The 'rejectionHandled' hook (scr_async_dyn.c installs it at listener
278
+ * registration — the scr_urj_deliver_fn pattern, so listener-free
279
+ * binaries keep their size class): called when a promise the checkpoint
280
+ * report already delivered as unhandled gains a handler. */
281
+ void (*scr_rjh_notify_fn)(ScrPromise *p) = NULL;
282
+
283
+ /* Every handler attach funnels here: mark the rejection observed, and
284
+ * fire Node's 'rejectionHandled' when the attach arrived AFTER the
285
+ * report delivered this promise to 'unhandledRejection' listeners (the
286
+ * model's one late-handling window — earlier handling keeps the promise
287
+ * out of the report entirely). The flag clears on the first attach, so
288
+ * one report fires at most one 'rejectionHandled' — Node's pairing. */
289
+ static void scr_prom_observe(ScrPromise *p) {
290
+ p->rejection_observed = true;
291
+ if (p->reported_unhandled) {
292
+ p->reported_unhandled = false;
293
+ if (scr_rjh_notify_fn != NULL) scr_rjh_notify_fn(p);
294
+ }
295
+ }
296
+
297
+ /* The attach-time handled mark (scr_async_dyn.c's dyn then/catch with a
298
+ * rejection handler, plus the module loader's ownership of every module
299
+ * evaluation promise): Node marks a promise handled at ATTACH, including
300
+ * while it is still pending, not when a later reaction runs. The pending
301
+ * mark is essential for a module dependency whose importer aborts while
302
+ * evaluating a later sibling — the loader still owns that dependency's
303
+ * eventual rejection, so it must never surface as an unrelated unhandled
304
+ * rejection. */
305
+ void scr_promise_mark_handled(ScrPromise *p) {
306
+ scr_prom_observe(p);
307
+ }
308
+
309
+ ScrPromise *scr_promise_retain(ScrPromise *p) {
310
+ if (p && p->rc != SIZE_MAX) {
311
+ p->rc++;
312
+ scr_cyc_mark_live(p);
313
+ }
314
+ return p;
315
+ }
316
+
317
+ static void scr_promise_release_payload(ScrPromise *p) {
318
+ if (p->payload_kind == SCR_EXC_STR) scr_str_release((ScrStr *)p->payload);
319
+ else if ((p->payload_kind == SCR_EXC_REF || p->payload_kind == SCR_EXC_OBJ ||
320
+ p->payload_kind == SCR_EXC_PRIMITIVE_REF) &&
321
+ p->payload) p->release_fn(p->payload);
322
+ p->payload_kind = SCR_EXC_NONE;
323
+ p->payload = NULL;
324
+ }
325
+
326
+ void scr_promise_release(ScrPromise *p) {
327
+ if (!p || p->rc == SIZE_MAX) return;
328
+ if (--p->rc == 0) {
329
+ scr_cyc_on_dead(p);
330
+ scr_promise_release_payload(p);
331
+ free(p->waiters);
332
+ for (size_t i = 0; i < p->ncbs; i++) {
333
+ scr_promise_release(p->cbs[i].dst);
334
+ if (p->cbs[i].all) scr_promise_all_state_release(p->cbs[i].all);
335
+ }
336
+ free(p->cbs);
337
+ #ifdef SCR_RC_AUDIT
338
+ scr_live_promises--;
339
+ #endif
340
+ scr_cyc_free(p);
341
+ } else {
342
+ scr_cyc_on_release(p); /* possible cycle root; may collect — p is done */
343
+ }
344
+ }
345
+
346
+ void *scr_promise_retain_v(void *p) { return scr_promise_retain((ScrPromise *)p); }
347
+ void scr_promise_release_v(void *p) { scr_promise_release((ScrPromise *)p); }
348
+ void scr_promise_trace_v(void *p, ScrTraceVisit visit, void *ctx) {
349
+ scr_promise_trace(p, visit, ctx);
350
+ }
351
+
352
+ /* ── fibers and the scheduler ─────────────────────────────────────────── */
353
+
354
+ /* One saved execution context. POSIX: a ucontext_t (swapcontext saves the
355
+ * outgoing context INTO the `from` slot). Windows: the fiber HANDLE —
356
+ * SwitchToFiber saves the outgoing state inside the fiber object itself,
357
+ * so the slot only needs to name the destination; `from` is unused. */
358
+ #ifdef _WIN32
359
+ typedef void *ScrCtx;
360
+ #elif defined(__wasi__)
361
+ typedef unsigned char ScrCtx;
362
+ #else
363
+ typedef ucontext_t ScrCtx;
364
+ #endif
365
+
366
+ struct ScrFiber {
367
+ ScrCtx ctx;
368
+ /* wasm32 uses LLVM's stackless switched-coroutine frame instead of a
369
+ * native saved stack. The compiler emits these two generic wrappers in
370
+ * every WASI module. */
371
+ void *coro;
372
+ ScrCtx *return_to; /* whoever resumed us last (spawner or the loop) */
373
+ char *stack; /* POSIX only; Windows fibers own their stack (NULL) */
374
+ ScrPromise *promise; /* the promise this fiber settles (owned +1); NULL
375
+ * for generator fibers (gen non-NULL instead) */
376
+ ScrGen *gen; /* the generator this fiber runs (borrowed — the
377
+ * ScrGen owns the fiber, never the reverse) */
378
+ ScrExcCell exc;
379
+ /* AsyncLocalStorage context (owned; NULL = empty). Inherited from the
380
+ * SPAWNER at spawn (Node's init-time capture), swapped active with the
381
+ * fiber (the exc-cell pattern) so run()'s window rides awaits. */
382
+ ScrAlsCtx *als;
383
+ bool done;
384
+ /* Trampoline args: the spawn wrapper stores a pointer to a stack-local
385
+ * argpack; the trampoline copies it out before the spawner resumes. */
386
+ void *argpack;
387
+ void (*entry)(ScrFiber *self, void *argpack);
388
+ /* queueMicrotask entries: a stackless pseudo-fiber — the READY queue's
389
+ * FIFO IS the microtask queue, so a closure rides it as a fiber-shaped
390
+ * envelope and scr_resume_fiber runs it on the main stack (a throw is
391
+ * an UNCAUGHT exception, like Node's queueMicrotask, never a
392
+ * rejection). Owned; NULL on real fibers. */
393
+ ScrClosure *micro_cb;
394
+ /* Async-generator settlement jobs: stackless READY-queue envelopes.
395
+ * The retained generator is pumped on the main stack. */
396
+ ScrGen *gen_job;
397
+ #ifdef SCR_ASAN_FIBERS
398
+ void *fake_stack;
399
+ #endif
400
+ };
401
+
402
+ /* ── AsyncLocalStorage (node:async_hooks) ─────────────────────────────
403
+ * Stores are process-lived ids; the CONTEXT is an immutable refcounted
404
+ * snapshot of (store id → dyn value) entries. One ACTIVE SLOT pointer
405
+ * (the exc-cell pattern): main owns a static slot, every fiber owns its
406
+ * own field, scr_switch repoints the active slot — so run()'s window
407
+ * rides the fiber across awaits, and a spawned fiber INHERITS the
408
+ * spawner's snapshot (Node's init-time capture through AsyncResource).
409
+ * Snapshots are immutable: enter builds a fresh one (entries retained),
410
+ * restore swaps the previous back — timer capture retains pointers. */
411
+
412
+ /* The ScrAlsCtx layout and the API over it live in scr_runtime.h /
413
+ * scr_async_dyn.c (gated — the size-class stance); this always-linked
414
+ * core keeps only what the fiber machinery itself touches: the active
415
+ * slot, the snapshot RC pair, and the switch/spawn/destroy wiring. */
416
+ static ScrAlsCtx *scr_als_main_slot = NULL;
417
+ ScrAlsCtx **scr_als_active = &scr_als_main_slot;
418
+
419
+ ScrAlsCtx *scr_als_ctx_retain(ScrAlsCtx *c) {
420
+ if (c) c->rc++;
421
+ return c;
422
+ }
423
+
424
+ void scr_als_ctx_release(ScrAlsCtx *c) {
425
+ if (!c || --c->rc != 0) return;
426
+ for (size_t i = 0; i < c->len; i++) scr_dyn_release(c->entries[i].value);
427
+ free(c);
428
+ }
429
+
430
+
431
+
432
+ static ScrCtx scr_loop_ctx; /* the main stack (scheduler home) */
433
+ static ScrFiber *scr_current = NULL;
434
+ static long scr_fibers_live = 0;
435
+ static long scr_fibers_abandoned = 0;
436
+
437
+ long scr_abandoned_fiber_count(void) { return scr_fibers_abandoned; }
438
+
439
+ /* True while executing on an async fiber (vs the main stack). The island
440
+ * sizes its engine stack budget per stack: fibers are small and fixed,
441
+ * the main stack is the process's megabytes (scr_island.c isl_entry). */
442
+ bool scr_on_fiber(void) { return scr_current != NULL; }
443
+ void *scr_fiber_self(void) { return scr_current; }
444
+
445
+ #ifdef __wasi__
446
+ extern void scr_wasi_coro_resume(void *handle);
447
+ extern void scr_wasi_coro_destroy(void *handle);
448
+
449
+ void scr_wasi_coro_started(void *handle) {
450
+ if (scr_current == NULL) {
451
+ fputs("scriptc: internal error: coroutine started outside a fiber\n", stderr);
452
+ abort();
453
+ }
454
+ scr_current->coro = handle;
455
+ }
456
+ #endif
457
+
458
+ /* Microtask queue: ready fibers, FIFO. */
459
+ static ScrFiber **scr_ready = NULL;
460
+ static size_t scr_ready_head = 0, scr_ready_len = 0, scr_ready_cap = 0;
461
+
462
+ static void scr_ready_push(ScrFiber *f) {
463
+ if (scr_ready_head + scr_ready_len == scr_ready_cap) {
464
+ if (scr_ready_len > 0) {
465
+ memmove(scr_ready, scr_ready + scr_ready_head, scr_ready_len * sizeof *scr_ready);
466
+ }
467
+ scr_ready_head = 0;
468
+ if (scr_ready_len == scr_ready_cap) {
469
+ scr_ready_cap = scr_ready_cap ? scr_ready_cap * 2 : 16;
470
+ scr_ready = realloc(scr_ready, scr_ready_cap * sizeof *scr_ready);
471
+ if (!scr_ready) scr_oom();
472
+ }
473
+ }
474
+ scr_ready[scr_ready_head + scr_ready_len++] = f;
475
+ }
476
+
477
+ static void scr_async_gen_job(ScrGen *g);
478
+ static void scr_async_gen_resume_ready(ScrGen *g);
479
+
480
+ /* Timer min-heap, FIFO tiebreak via sequence numbers. `id` is nonzero only
481
+ * for setInterval entries (the clearInterval handle; setTimeout has no
482
+ * clear surface, so plain timeouts never need one) and `repeat_ms` is the
483
+ * interval's period — a fired interval re-enters the heap with a fresh
484
+ * deadline and seq, so ties against later timers stay FIFO like Node's. */
485
+ typedef struct {
486
+ double deadline_ms;
487
+ unsigned long seq;
488
+ ScrClosure *cb; /* owned */
489
+ double repeat_ms;
490
+ unsigned long id;
491
+ bool reffed; /* keeps the loop alive; unref() clears it (Node semantics) */
492
+ double delay_ms; /* the original delay — refresh() re-arms to now + this */
493
+ } ScrTimer;
494
+
495
+ static ScrTimer *scr_timers = NULL;
496
+ static size_t scr_ntimers = 0, scr_timers_cap = 0;
497
+ static unsigned long scr_timer_seq = 0;
498
+ /* REF'd armed timers — the loop's timer-liveness count (an unref'd timer
499
+ * sits in the heap and still FIRES if the loop runs for other reasons, but
500
+ * does not by itself keep the loop alive). Kept in sync by push/pop/remove
501
+ * and by ref/unref. */
502
+ static size_t scr_reffed_timers = 0;
503
+
504
+ /* Exported: the island's timer machinery (scr_web.c) shares this clock so
505
+ * its deadlines are comparable with the loop's. */
506
+ double scr_now_ms(void) {
507
+ struct timespec ts;
508
+ clock_gettime(CLOCK_MONOTONIC, &ts);
509
+ return (double)ts.tv_sec * 1000.0 + (double)ts.tv_nsec / 1e6;
510
+ }
511
+
512
+ static bool scr_timer_before(const ScrTimer *a, const ScrTimer *b) {
513
+ if (a->deadline_ms != b->deadline_ms) return a->deadline_ms < b->deadline_ms;
514
+ return a->seq < b->seq;
515
+ }
516
+
517
+ static void scr_timer_push(ScrTimer t) {
518
+ if (scr_ntimers == scr_timers_cap) {
519
+ scr_timers_cap = scr_timers_cap ? scr_timers_cap * 2 : 16;
520
+ scr_timers = realloc(scr_timers, scr_timers_cap * sizeof *scr_timers);
521
+ if (!scr_timers) scr_oom();
522
+ }
523
+ if (t.reffed) scr_reffed_timers++;
524
+ size_t i = scr_ntimers++;
525
+ scr_timers[i] = t;
526
+ while (i > 0) {
527
+ size_t parent = (i - 1) / 2;
528
+ if (!scr_timer_before(&scr_timers[i], &scr_timers[parent])) break;
529
+ ScrTimer tmp = scr_timers[i];
530
+ scr_timers[i] = scr_timers[parent];
531
+ scr_timers[parent] = tmp;
532
+ i = parent;
533
+ }
534
+ }
535
+
536
+ static ScrTimer scr_timer_pop(void) {
537
+ ScrTimer top = scr_timers[0];
538
+ if (top.reffed && scr_reffed_timers > 0) scr_reffed_timers--;
539
+ scr_timers[0] = scr_timers[--scr_ntimers];
540
+ size_t i = 0;
541
+ for (;;) {
542
+ size_t l = 2 * i + 1, r = 2 * i + 2, min = i;
543
+ if (l < scr_ntimers && scr_timer_before(&scr_timers[l], &scr_timers[min])) min = l;
544
+ if (r < scr_ntimers && scr_timer_before(&scr_timers[r], &scr_timers[min])) min = r;
545
+ if (min == i) break;
546
+ ScrTimer tmp = scr_timers[i];
547
+ scr_timers[i] = scr_timers[min];
548
+ scr_timers[min] = tmp;
549
+ i = min;
550
+ }
551
+ return top;
552
+ }
553
+
554
+ /* Node's delay coercion (lib/internal/timers.js): NaN/negative/sub-ms
555
+ * clamp to 1, the delay TRUNCATES to integer milliseconds (setTimeout(cb,
556
+ * 1.8) and setTimeout(cb, 1.1) both land in the 1ms bucket, so a batch of
557
+ * fractional delays fires in REGISTRATION order — test-timers-non-integer-
558
+ * delay's contract), and anything past TIMEOUT_MAX (2^31-1) becomes 1. */
559
+ static double scr_timer_coerce_ms(double ms) {
560
+ if (!(ms >= 1)) return 1;
561
+ if (ms > 2147483647.0) return 1; /* past TIMEOUT_MAX (also +Infinity) */
562
+ return (double)(unsigned long long)ms; /* trunc: positive, finite, in range */
563
+ }
564
+
565
+ void scr_set_timeout(ScrClosure *cb, double ms) {
566
+ ms = scr_timer_coerce_ms(ms);
567
+ ScrTimer t = {scr_now_ms() + ms, scr_timer_seq++, cb /* ownership moves in */, 0, 0, true, ms};
568
+ scr_timer_push(t);
569
+ }
570
+
571
+ /* ── setInterval / clearInterval ─────────────────────────────────────
572
+ * Intervals ride the same heap: the entry carries its period and a
573
+ * nonzero id (the compiled handle — Node's Timeout object reduced to the
574
+ * number the fallback declarations promise). A live interval keeps the
575
+ * loop alive exactly because it sits in the heap; clearInterval removes
576
+ * the entry EAGERLY (a lazily-cancelled entry would hold the loop open
577
+ * until its deadline — an interval cleared at t=0 with a one-hour period
578
+ * must let the program exit NOW, like Node). Clearing the interval whose
579
+ * callback is currently running (the self-clearing spinner pattern) is
580
+ * handled by the firing pair below: the entry is out of the heap while
581
+ * its callback runs, so the run loop re-pushes it only if the callback
582
+ * did not clear it. */
583
+
584
+ static unsigned long scr_interval_next_id = 1;
585
+ static unsigned long scr_firing_id = 0; /* interval currently running */
586
+ static bool scr_firing_cleared = false;
587
+ static bool scr_firing_reffed = true; /* the running interval's ref state */
588
+ static bool scr_firing_refresh = false; /* refresh() called mid-callback */
589
+
590
+ /* Removes heap entry i (swap-with-last, then sift whichever way the moved
591
+ * entry needs). */
592
+ static void scr_timer_remove_at(size_t i) {
593
+ if (scr_timers[i].reffed && scr_reffed_timers > 0) scr_reffed_timers--;
594
+ scr_timers[i] = scr_timers[--scr_ntimers];
595
+ if (i >= scr_ntimers) return;
596
+ /* Sift up if the moved entry beats its parent, else sift down. */
597
+ while (i > 0) {
598
+ size_t parent = (i - 1) / 2;
599
+ if (!scr_timer_before(&scr_timers[i], &scr_timers[parent])) break;
600
+ ScrTimer tmp = scr_timers[i];
601
+ scr_timers[i] = scr_timers[parent];
602
+ scr_timers[parent] = tmp;
603
+ i = parent;
604
+ }
605
+ for (;;) {
606
+ size_t l = 2 * i + 1, r = 2 * i + 2, min = i;
607
+ if (l < scr_ntimers && scr_timer_before(&scr_timers[l], &scr_timers[min])) min = l;
608
+ if (r < scr_ntimers && scr_timer_before(&scr_timers[r], &scr_timers[min])) min = r;
609
+ if (min == i) break;
610
+ ScrTimer tmp = scr_timers[i];
611
+ scr_timers[i] = scr_timers[min];
612
+ scr_timers[min] = tmp;
613
+ i = min;
614
+ }
615
+ }
616
+
617
+ double scr_set_interval(ScrClosure *cb, double ms) {
618
+ ms = scr_timer_coerce_ms(ms); /* Node's clamp-and-trunc, like setTimeout */
619
+ unsigned long id = scr_interval_next_id++;
620
+ ScrTimer t = {scr_now_ms() + ms, scr_timer_seq++, cb /* ownership moves in */, ms, id, true, ms};
621
+ scr_timer_push(t);
622
+ return (double)id;
623
+ }
624
+
625
+ /* A one-shot timer WITH a clear handle — the island's setTimeout (its
626
+ * clearTimeout must cancel, unlike the static surface's clear-less
627
+ * setTimeout). Rides the interval id space so scr_clear_interval serves
628
+ * both; repeat_ms 0 keeps it one-shot at the firing site. */
629
+ double scr_set_timeout_handle(ScrClosure *cb, double ms) {
630
+ ms = scr_timer_coerce_ms(ms);
631
+ unsigned long id = scr_interval_next_id++;
632
+ ScrTimer t = {scr_now_ms() + ms, scr_timer_seq++, cb /* ownership moves in */, 0, id, true, ms};
633
+ scr_timer_push(t);
634
+ return (double)id;
635
+ }
636
+
637
+ /* process.env-style timer ref bookkeeping: unref() drops a timer from the
638
+ * loop's liveness count (it still fires if the loop runs on), ref() puts
639
+ * it back. Node-exact for the static timer surface; NaN/0/absent handles
640
+ * are tolerated (never a handle). The one-shot setTimeout with NO clear
641
+ * handle (id 0) cannot be unref'd by id — the compiler routes .unref()
642
+ * only over handle-returning timers, so id 0 never reaches here. */
643
+ static ScrTimer *scr_timer_find(unsigned long id) {
644
+ for (size_t i = 0; i < scr_ntimers; i++) {
645
+ if (scr_timers[i].id == id) return &scr_timers[i];
646
+ }
647
+ return NULL;
648
+ }
649
+
650
+ void scr_timer_unref(double handle) {
651
+ if (!(handle >= 1)) return;
652
+ unsigned long id = (unsigned long)handle;
653
+ if (id == scr_firing_id) {
654
+ /* Firing interval unref'ing itself: the re-arm carries the flag. */
655
+ scr_firing_reffed = false;
656
+ return;
657
+ }
658
+ ScrTimer *t = scr_timer_find(id);
659
+ if (t && t->reffed) {
660
+ t->reffed = false;
661
+ if (scr_reffed_timers > 0) scr_reffed_timers--;
662
+ }
663
+ }
664
+
665
+ void scr_timer_ref(double handle) {
666
+ if (!(handle >= 1)) return;
667
+ unsigned long id = (unsigned long)handle;
668
+ if (id == scr_firing_id) {
669
+ scr_firing_reffed = true;
670
+ return;
671
+ }
672
+ ScrTimer *t = scr_timer_find(id);
673
+ if (t && !t->reffed) {
674
+ t->reffed = true;
675
+ scr_reffed_timers++;
676
+ }
677
+ }
678
+
679
+ /* refresh(): re-arm to now + the original delay — Node's Timeout.refresh.
680
+ * A HEAP entry (armed timeout or interval between ticks) re-enters the
681
+ * heap with a fresh deadline and seq (FIFO against later same-deadline
682
+ * timers, like a brand-new timer); the timer whose callback is RUNNING
683
+ * sets the firing flag and the loop re-arms the one-shot after the
684
+ * callback returns (the interval re-arm already does). A one-shot that
685
+ * fired on an earlier turn is gone — its closure released — so refresh
686
+ * of a dead handle is a tolerated no-op (SEMANTICS: Node re-activates
687
+ * even a fired Timeout; the compiled handle cannot). */
688
+ void scr_timer_refresh(double handle) {
689
+ if (!(handle >= 1)) return;
690
+ unsigned long id = (unsigned long)handle;
691
+ if (id == scr_firing_id) {
692
+ scr_firing_refresh = true;
693
+ return;
694
+ }
695
+ for (size_t i = 0; i < scr_ntimers; i++) {
696
+ if (scr_timers[i].id == id) {
697
+ ScrTimer t = scr_timers[i];
698
+ scr_timer_remove_at(i);
699
+ t.deadline_ms = scr_now_ms() + t.delay_ms;
700
+ t.seq = scr_timer_seq++;
701
+ scr_timer_push(t);
702
+ return;
703
+ }
704
+ }
705
+ }
706
+
707
+ /* hasRef(): true iff the handle names a live, still-reffed timer. */
708
+ bool scr_timer_has_ref(double handle) {
709
+ if (!(handle >= 1)) return false;
710
+ unsigned long id = (unsigned long)handle;
711
+ if (id == scr_firing_id) return scr_firing_reffed;
712
+ ScrTimer *t = scr_timer_find(id);
713
+ return t != NULL && t->reffed;
714
+ }
715
+
716
+ /* ── process.getActiveResourcesInfo (the loop's own bookkeeping) ──────
717
+ * 'Timeout' per armed heap timer — plus the firing, uncleared one (Node
718
+ * counts a Timeout as active while its callback runs, until clearTimeout
719
+ * drops it) — and 'Immediate' per queued, unfired immediate (a FIRED
720
+ * immediate no longer counts, Node's current answer inside the
721
+ * callback). Resource kinds this runtime does not model as loop handles
722
+ * (TCP wraps, FS requests, ...) are absent — SEMANTICS.md names the
723
+ * divergence. Result +1. */
724
+ static size_t scr_pending_immediates; /* defined below with the queue */
725
+ ScrArr *scr_active_resources(void) {
726
+ ScrArr *arr = scr_arr_new(SCR_ELEM_STR, 8);
727
+ size_t timeouts = scr_ntimers + ((scr_firing_id != 0 && !scr_firing_cleared) ? 1 : 0);
728
+ for (size_t i = 0; i < timeouts; i++) scr_arr_push_ref(arr, scr_str_new("Timeout", 7));
729
+ for (size_t i = 0; i < scr_pending_immediates; i++) scr_arr_push_ref(arr, scr_str_new("Immediate", 9));
730
+ return arr;
731
+ }
732
+
733
+ /* ── process.nextTick (the user tick queue) ───────────────────────────
734
+ * A FIFO of user callbacks drained BEFORE promise jobs at every loop
735
+ * checkpoint, to joint exhaustion with them — Node's tick-then-microtask
736
+ * order. Pending ticks are always-ready work: the loop neither sleeps
737
+ * nor exits while any exist. Ticks scheduled from 'exit' listeners (or
738
+ * left queued on the uncaught paths) never run — the teardown releases
739
+ * them, like Node dropping the queue at exit. */
740
+ typedef struct ScrNtick {
741
+ ScrClosure *cb; /* owned; NULL for a raw C-hook entry */
742
+ ScrFsRenameFn error_cb; /* process-write success adapter, or NULL */
743
+ void (*raw)(void); /* hook when cb == NULL (stream markers) */
744
+ struct ScrNtick *next;
745
+ } ScrNtick;
746
+
747
+ static ScrNtick *scr_nt_head = NULL;
748
+ static ScrNtick *scr_nt_tail = NULL;
749
+
750
+ /* Public: releases every queued tick without running it — the loop-exit
751
+ * teardown below AND the exit-listener runner (scr_events.c) both call
752
+ * it, because 'exit' listeners run AFTER the loop's teardown and may
753
+ * enqueue ticks that must never run (Node) yet must not leak. */
754
+
755
+ void scr_next_tick(ScrClosure *cb /*moves*/) {
756
+ ScrNtick *t = calloc(1, sizeof *t);
757
+ if (!t) scr_oom();
758
+ t->cb = cb;
759
+ if (scr_nt_tail) scr_nt_tail->next = t;
760
+ else scr_nt_head = t;
761
+ scr_nt_tail = t;
762
+ }
763
+
764
+ /* stdout/stderr write completions are Node nextTicks too, but their
765
+ * callback receives the success `null` argument. Reuse the error-first
766
+ * adapter ABI also used by fs.rename: emitted adapters construct the
767
+ * program's Error | null union, and NULL selects its null arm. */
768
+ void scr_process_write_callback(ScrClosure *cb /*moves*/, ScrFsRenameFn fn) {
769
+ ScrNtick *t = calloc(1, sizeof *t);
770
+ if (!t) scr_oom();
771
+ t->cb = cb;
772
+ t->error_cb = fn;
773
+ if (scr_nt_tail) scr_nt_tail->next = t;
774
+ else scr_nt_head = t;
775
+ scr_nt_tail = t;
776
+ }
777
+
778
+ /* A RAW C-hook tick: the stream unit enqueues one marker per deferred
779
+ * stream emission so those emissions interleave with user nextTicks in
780
+ * true FIFO order — in Node they ARE nextTicks (resume_, emitReadable_,
781
+ * endReadableNT, ...). The hook dispatches exactly one stream tick;
782
+ * teardown just drops markers (the stream queue owns its entries). */
783
+ void scr_next_tick_raw(void (*fn)(void)) {
784
+ ScrNtick *t = calloc(1, sizeof *t);
785
+ if (!t) scr_oom();
786
+ t->raw = fn;
787
+ if (scr_nt_tail) scr_nt_tail->next = t;
788
+ else scr_nt_head = t;
789
+ scr_nt_tail = t;
790
+ }
791
+
792
+ void scr_nticks_teardown(void) {
793
+ while (scr_nt_head != NULL) {
794
+ ScrNtick *t = scr_nt_head;
795
+ scr_nt_head = t->next;
796
+ if (t->cb) scr_closure_release(t->cb);
797
+ free(t);
798
+ }
799
+ scr_nt_tail = NULL;
800
+ }
801
+
802
+ /* Releases every armed timer — the island teardown calls this before the
803
+ * engine dies so closures holding engine callbacks free first and the
804
+ * counting allocator's zero-live audit holds (the loop only exits with
805
+ * entries still armed on the uncaught/unhandled paths). */
806
+ static void scr_immediates_teardown(void);
807
+ void scr_timers_teardown(void) {
808
+ for (size_t i = 0; i < scr_ntimers; i++) scr_closure_release(scr_timers[i].cb);
809
+ scr_ntimers = 0;
810
+ scr_reffed_timers = 0;
811
+ scr_immediates_teardown();
812
+ scr_nticks_teardown();
813
+ }
814
+
815
+ void scr_clear_interval(double handle) {
816
+ if (!(handle >= 1)) return; /* NaN/0/negative: never a handle; Node tolerates */
817
+ unsigned long id = (unsigned long)handle;
818
+ if (id == scr_firing_id) {
819
+ scr_firing_cleared = true; /* the run loop drops the callback */
820
+ return;
821
+ }
822
+ for (size_t i = 0; i < scr_ntimers; i++) {
823
+ if (scr_timers[i].id == id) {
824
+ scr_closure_release(scr_timers[i].cb);
825
+ scr_timer_remove_at(i);
826
+ return;
827
+ }
828
+ }
829
+ }
830
+
831
+ /* ── immediates (Node's check phase) ──────────────────────────────────
832
+ * setImmediate callbacks run once per loop turn, AFTER due timers, in
833
+ * FIFO order — and immediates queued while the phase runs wait for the
834
+ * NEXT turn (the phase snapshots its end index). The queue is an
835
+ * append-only array with a head cursor; clearImmediate NULLs the slot in
836
+ * place (order and indices stay stable mid-phase). Ids ride their own
837
+ * space — clearTimeout of an Immediate is a no-op, like Node. */
838
+ typedef struct {
839
+ unsigned long id;
840
+ ScrClosure *cb; /* owned; NULL once fired or cleared */
841
+ bool reffed; /* keeps the loop alive; unref() clears it (Node semantics) */
842
+ } ScrImmediate;
843
+
844
+ static ScrImmediate *scr_immediates = NULL;
845
+ static size_t scr_nimmediates = 0, scr_immediates_head = 0, scr_immediates_cap = 0;
846
+ static unsigned long scr_immediate_seq = 0;
847
+ /* Pending (queued, uncleared) immediates and the reffed subset — the
848
+ * loop's no-sleep signal and liveness count respectively. */
849
+ static size_t scr_pending_immediates = 0;
850
+ static size_t scr_reffed_immediates = 0;
851
+
852
+ double scr_set_immediate(ScrClosure *cb) {
853
+ if (scr_nimmediates == scr_immediates_cap) {
854
+ scr_immediates_cap = scr_immediates_cap ? scr_immediates_cap * 2 : 16;
855
+ scr_immediates = realloc(scr_immediates, scr_immediates_cap * sizeof *scr_immediates);
856
+ if (!scr_immediates) scr_oom();
857
+ }
858
+ unsigned long id = ++scr_immediate_seq;
859
+ scr_immediates[scr_nimmediates].id = id;
860
+ scr_immediates[scr_nimmediates].cb = cb; /* ownership moves in */
861
+ scr_immediates[scr_nimmediates].reffed = true;
862
+ scr_nimmediates++;
863
+ scr_pending_immediates++;
864
+ scr_reffed_immediates++;
865
+ return (double)id;
866
+ }
867
+
868
+ static ScrImmediate *scr_immediate_find(unsigned long id) {
869
+ for (size_t i = scr_immediates_head; i < scr_nimmediates; i++) {
870
+ if (scr_immediates[i].id == id && scr_immediates[i].cb != NULL) return &scr_immediates[i];
871
+ }
872
+ return NULL;
873
+ }
874
+
875
+ void scr_clear_immediate(double handle) {
876
+ if (!(handle >= 1)) return; /* NaN/0/negative: never a handle; Node tolerates */
877
+ ScrImmediate *im = scr_immediate_find((unsigned long)handle);
878
+ if (im == NULL) return; /* already fired/cleared: no-op, like Node */
879
+ scr_closure_release(im->cb);
880
+ im->cb = NULL;
881
+ if (scr_pending_immediates > 0) scr_pending_immediates--;
882
+ if (im->reffed) {
883
+ im->reffed = false;
884
+ if (scr_reffed_immediates > 0) scr_reffed_immediates--;
885
+ }
886
+ }
887
+
888
+ /* Immediate.unref()/ref()/hasRef(): the Timeout trio's exact story over
889
+ * the immediate queue. A fired or cleared handle is a tolerated no-op
890
+ * (Node's Immediate methods on a dead handle do nothing). */
891
+ void scr_immediate_unref(double handle) {
892
+ if (!(handle >= 1)) return;
893
+ ScrImmediate *im = scr_immediate_find((unsigned long)handle);
894
+ if (im && im->reffed) {
895
+ im->reffed = false;
896
+ if (scr_reffed_immediates > 0) scr_reffed_immediates--;
897
+ }
898
+ }
899
+
900
+ void scr_immediate_ref(double handle) {
901
+ if (!(handle >= 1)) return;
902
+ ScrImmediate *im = scr_immediate_find((unsigned long)handle);
903
+ if (im && !im->reffed) {
904
+ im->reffed = true;
905
+ scr_reffed_immediates++;
906
+ }
907
+ }
908
+
909
+ bool scr_immediate_has_ref(double handle) {
910
+ if (!(handle >= 1)) return false;
911
+ ScrImmediate *im = scr_immediate_find((unsigned long)handle);
912
+ return im != NULL && im->reffed;
913
+ }
914
+
915
+ /* The teardown sweep's immediate arm (called from scr_timers_teardown):
916
+ * unref'd immediates left queued at normal loop exit never fire (Node),
917
+ * so their closures release here or the RC audit counts them as leaks. */
918
+ static void scr_immediates_teardown(void) {
919
+ for (size_t i = scr_immediates_head; i < scr_nimmediates; i++) {
920
+ if (scr_immediates[i].cb != NULL) scr_closure_release(scr_immediates[i].cb);
921
+ }
922
+ scr_nimmediates = 0;
923
+ scr_immediates_head = 0;
924
+ scr_pending_immediates = 0;
925
+ scr_reffed_immediates = 0;
926
+ }
927
+
928
+ /* Unhandled rejections: rejected promises retained here until observed. */
929
+ static ScrPromise **scr_maybe_unhandled = NULL;
930
+ static size_t scr_nunhandled = 0, scr_unhandled_cap = 0;
931
+
932
+ static void scr_track_rejection(ScrPromise *p) {
933
+ if (scr_nunhandled == scr_unhandled_cap) {
934
+ scr_unhandled_cap = scr_unhandled_cap ? scr_unhandled_cap * 2 : 8;
935
+ scr_maybe_unhandled = realloc(scr_maybe_unhandled, scr_unhandled_cap * sizeof *scr_maybe_unhandled);
936
+ if (!scr_maybe_unhandled) scr_oom();
937
+ }
938
+ scr_maybe_unhandled[scr_nunhandled++] = scr_promise_retain(p);
939
+ }
940
+
941
+ /* ── context switching (ASan-annotated) ───────────────────────────────── */
942
+
943
+ #ifdef SCR_ASAN_FIBERS
944
+ static void *scr_main_fake_stack; /* fake-stack slot for the main context */
945
+ #endif
946
+
947
+ #ifdef _WIN32
948
+ /* The current context's handle, converting the main thread to a fiber on
949
+ * first need (SwitchToFiber requires the caller BE a fiber; the runtime is
950
+ * single-threaded, so one lazy conversion covers the process). Also the
951
+ * loop-home keeper: whenever main is the caller this IS scr_loop_ctx's
952
+ * value — assigned at the conversion so parked fibers can always switch
953
+ * back to it. */
954
+ static void *scr_win_self(void) {
955
+ static bool converted = false;
956
+ if (!converted) {
957
+ scr_loop_ctx = ConvertThreadToFiber(NULL);
958
+ if (scr_loop_ctx == NULL) {
959
+ fputs("scriptc: ConvertThreadToFiber failed\n", stderr);
960
+ abort();
961
+ }
962
+ converted = true;
963
+ }
964
+ return GetCurrentFiber();
965
+ }
966
+ #endif
967
+
968
+ static void scr_switch(ScrCtx *from, ScrCtx *to, ScrFiber *to_fiber) {
969
+ #ifdef SCR_ASAN_FIBERS
970
+ ScrFiber *from_fiber = scr_current;
971
+ #endif
972
+ scr_current = to_fiber;
973
+ scr_exc_swap_cell(to_fiber ? &to_fiber->exc : NULL);
974
+ scr_als_active = to_fiber ? &to_fiber->als : &scr_als_main_slot;
975
+ #ifdef _WIN32
976
+ /* SwitchToFiber snapshots the outgoing fiber's state inside its own
977
+ * fiber object — `from` has nothing to record. */
978
+ (void)from;
979
+ SwitchToFiber(*to);
980
+ #elif defined(__wasi__)
981
+ (void)from;
982
+ (void)to;
983
+ scr_trap("scriptc: internal error: native stack switch reached on WASI\n");
984
+ #elif defined(SCR_ASAN_FIBERS)
985
+ void **save = from_fiber ? &from_fiber->fake_stack : &scr_main_fake_stack;
986
+ const void *bottom = to_fiber ? to_fiber->stack : NULL;
987
+ size_t size = to_fiber ? SCR_FIBER_STACK : 0;
988
+ __sanitizer_start_switch_fiber(save, bottom, size);
989
+ swapcontext(from, to);
990
+ const void *old_bottom;
991
+ size_t old_size;
992
+ __sanitizer_finish_switch_fiber(
993
+ scr_current ? scr_current->fake_stack : scr_main_fake_stack, &old_bottom, &old_size);
994
+ #else
995
+ swapcontext(from, to);
996
+ #endif
997
+ }
998
+
999
+ static void scr_promise_settle_wake(ScrPromise *p);
1000
+
1001
+ /* Copies src's settlement into a still-pending dst (payload RETAINED —
1002
+ * src can settle other destinations and still be awaited) and wakes dst's
1003
+ * waiters. A rejection consumed this way counts as HANDLED on src (a
1004
+ * combinator attached a handler, like Node's race). The Promise.race
1005
+ * same-inner-type adapter and the rejection path both land here. */
1006
+ static void scr_promise_settle_from(ScrPromise *dst, ScrPromise *src) {
1007
+ if (dst->state == SCR_PROM_PENDING) {
1008
+ dst->state = src->state;
1009
+ dst->payload_kind = src->payload_kind;
1010
+ dst->f64 = src->f64;
1011
+ dst->b = src->b;
1012
+ dst->retain_fn = src->retain_fn;
1013
+ dst->release_fn = src->release_fn;
1014
+ dst->trace_fn = src->trace_fn;
1015
+ dst->payload = NULL;
1016
+ if (src->payload_kind == SCR_EXC_STR && src->payload) {
1017
+ dst->payload = scr_str_retain((ScrStr *)src->payload);
1018
+ } else if ((src->payload_kind == SCR_EXC_REF || src->payload_kind == SCR_EXC_OBJ ||
1019
+ src->payload_kind == SCR_EXC_PRIMITIVE_REF) &&
1020
+ src->payload) {
1021
+ dst->payload = src->retain_fn(src->payload);
1022
+ }
1023
+ scr_promise_settle_wake(dst);
1024
+ }
1025
+ if (src->state == SCR_PROM_REJECTED) scr_prom_observe(src);
1026
+ }
1027
+
1028
+ /* The emitted same-type Promise.race adapter (see raceAdapterFor). */
1029
+ void scr_promise_adapt_copy(ScrPromise *dst, ScrPromise *src) {
1030
+ scr_promise_settle_from(dst, src);
1031
+ }
1032
+
1033
+ /* One Promise.all entry settling: a fulfillment stores its payload into
1034
+ * the values array at the entry's INPUT index (input order regardless of
1035
+ * settlement order) and the LAST missing fulfillment fulfills the result
1036
+ * with the array (void-element all fulfills void); a rejection copies raw
1037
+ * into the result — the first one in SETTLEMENT order wins through the
1038
+ * destination's own pending check, and later ones still count as HANDLED
1039
+ * on their entries (settle_from marks them observed), exactly Node's
1040
+ * subscribe-to-everything behavior. */
1041
+ static void scr_promise_all_settle(ScrAllState *st, ScrPromise *result, size_t idx,
1042
+ ScrPromise *src) {
1043
+ if (src->state == SCR_PROM_FULFILLED) {
1044
+ if (st->store) st->store(st->values, (double)idx, src);
1045
+ if (--st->remaining == 0 && result->state == SCR_PROM_PENDING) {
1046
+ if (st->values) {
1047
+ scr_promise_fulfill_ref(result, scr_arr_retain(st->values), scr_arr_retain_v,
1048
+ scr_arr_release_v,
1049
+ st->values->elem_trace ? scr_arr_trace_v : NULL);
1050
+ } else {
1051
+ scr_promise_fulfill_void(result);
1052
+ }
1053
+ }
1054
+ } else {
1055
+ scr_promise_settle_from(result, src);
1056
+ }
1057
+ }
1058
+
1059
+ /* Settle helpers wake waiters into the microtask queue and run the
1060
+ * combinator callbacks: adapters for fulfillments (they convert the
1061
+ * payload to the destination's inner type), the raw copy for rejections
1062
+ * (reasons are dynamically tagged). first-settle-wins rides the
1063
+ * destination's own pending check. Promise.all entries dispatch through
1064
+ * their shared countdown state instead of the adapt pair. */
1065
+ static void scr_promise_settle_wake(ScrPromise *p) {
1066
+ for (size_t i = 0; i < p->nwaiters; i++) scr_ready_push(p->waiters[i]);
1067
+ p->nwaiters = 0;
1068
+ for (size_t i = 0; i < p->ncbs; i++) {
1069
+ if (p->cbs[i].all) {
1070
+ scr_promise_all_settle(p->cbs[i].all, p->cbs[i].dst, p->cbs[i].all_idx, p);
1071
+ scr_promise_all_state_release(p->cbs[i].all);
1072
+ } else if (p->state == SCR_PROM_FULFILLED) {
1073
+ p->cbs[i].adapt(p->cbs[i].dst, p);
1074
+ } else {
1075
+ scr_promise_settle_from(p->cbs[i].dst, p);
1076
+ }
1077
+ scr_promise_release(p->cbs[i].dst);
1078
+ }
1079
+ p->ncbs = 0;
1080
+ if (p->state == SCR_PROM_REJECTED) scr_track_rejection(p);
1081
+ }
1082
+
1083
+ /* ── Promise.race ─────────────────────────────────────────────────────
1084
+ * The compiler emits: a fresh result promise, then one race_add per
1085
+ * entry. A settled entry settles the result immediately (first add
1086
+ * wins); pending entries park a callback waiter that fires inside the
1087
+ * entry's settle. Fibers awaiting the result still wake through the
1088
+ * microtask queue. Losing entries keep their own settlements (payloads
1089
+ * are retained, not moved). */
1090
+
1091
+ void scr_promise_race_add(ScrPromise *race, ScrPromise *in,
1092
+ void (*adapt)(ScrPromise *dst, ScrPromise *src)) {
1093
+ if (in->state != SCR_PROM_PENDING) {
1094
+ if (in->state == SCR_PROM_FULFILLED) adapt(race, in);
1095
+ else scr_promise_settle_from(race, in);
1096
+ return;
1097
+ }
1098
+ if (in->ncbs == in->cbs_cap) {
1099
+ in->cbs_cap = in->cbs_cap ? in->cbs_cap * 2 : 4;
1100
+ in->cbs = realloc(in->cbs, in->cbs_cap * sizeof *in->cbs);
1101
+ if (!in->cbs) scr_oom();
1102
+ }
1103
+ in->cbs[in->ncbs].adapt = adapt;
1104
+ in->cbs[in->ncbs].dst = scr_promise_retain(race);
1105
+ in->cbs[in->ncbs].all = NULL;
1106
+ in->cbs[in->ncbs].all_idx = 0;
1107
+ in->ncbs++;
1108
+ }
1109
+
1110
+ /* ── Promise.all ──────────────────────────────────────────────────────
1111
+ * BORROWS the entries array `ps` and the pre-capacity values array
1112
+ * `values` (NULL for void elements), retains what it keeps, and returns
1113
+ * the result promise +1. `values` arrives EMPTY with cap >= ps->len (the
1114
+ * emitted construction passes the length) and is pre-sized here: every
1115
+ * slot's zero bits are the per-kind placeholder (0.0 / false / NULL),
1116
+ * legal to overwrite through the store helpers and to release. Entries
1117
+ * already settled settle inline (a rejection settles the result NOW —
1118
+ * first rejection in settlement order — and later rejected entries are
1119
+ * still marked handled); pending entries park a countdown waiter. The
1120
+ * empty array fulfills immediately (awaiters take the settled-await
1121
+ * microtask hop, like Node's one-tick resolve). */
1122
+ ScrPromise *scr_promise_all(ScrArr *ps, ScrArr *values,
1123
+ void (*store)(ScrArr *a, double i, ScrPromise *src)) {
1124
+ size_t n = ps->len;
1125
+ ScrPromise *result = scr_promise_new();
1126
+ if (values && n > 0) {
1127
+ /* Pre-size as holes. Promise settlement writes the present slots through
1128
+ * the normal setters; this also remains safe when n is sparse-sized and
1129
+ * the array intentionally has no dense allocation. */
1130
+ scr_arr_set_len(values, (double)n);
1131
+ }
1132
+ ScrAllState *st = malloc(sizeof *st);
1133
+ if (!st) scr_oom();
1134
+ st->rc = 1; /* the builder's reference, dropped at the end */
1135
+ st->remaining = n;
1136
+ st->values = values ? scr_arr_retain(values) : NULL;
1137
+ st->store = store;
1138
+ for (size_t i = 0; i < n; i++) {
1139
+ ScrPromise *in = (ScrPromise *)scr_arr_get_ref(ps, (double)i); /* +1 */
1140
+ if (in->state != SCR_PROM_PENDING) {
1141
+ scr_promise_all_settle(st, result, i, in);
1142
+ } else {
1143
+ if (in->ncbs == in->cbs_cap) {
1144
+ in->cbs_cap = in->cbs_cap ? in->cbs_cap * 2 : 4;
1145
+ in->cbs = realloc(in->cbs, in->cbs_cap * sizeof *in->cbs);
1146
+ if (!in->cbs) scr_oom();
1147
+ }
1148
+ in->cbs[in->ncbs].adapt = NULL;
1149
+ in->cbs[in->ncbs].dst = scr_promise_retain(result);
1150
+ in->cbs[in->ncbs].all = st;
1151
+ in->cbs[in->ncbs].all_idx = i;
1152
+ in->ncbs++;
1153
+ st->rc++;
1154
+ }
1155
+ scr_promise_release(in);
1156
+ }
1157
+ /* n == 0, or every entry was already fulfilled inline. */
1158
+ if (st->remaining == 0 && result->state == SCR_PROM_PENDING) {
1159
+ if (st->values) {
1160
+ scr_promise_fulfill_ref(result, scr_arr_retain(st->values), scr_arr_retain_v,
1161
+ scr_arr_release_v,
1162
+ st->values->elem_trace ? scr_arr_trace_v : NULL);
1163
+ } else {
1164
+ scr_promise_fulfill_void(result);
1165
+ }
1166
+ }
1167
+ scr_promise_all_state_release(st);
1168
+ return result;
1169
+ }
1170
+
1171
+ /* Per-element-kind store helpers for the emitted Promise.all: write the
1172
+ * entry's fulfillment payload into the values array at its input index.
1173
+ * The payload accessors return retained/by-value (losing a reference is
1174
+ * impossible: set_* takes ownership and releases the zero placeholder). */
1175
+ void scr_promise_all_store_f64(ScrArr *a, double i, ScrPromise *src) {
1176
+ scr_arr_set_f64(a, i, scr_promise_payload_f64(src));
1177
+ }
1178
+ void scr_promise_all_store_bool(ScrArr *a, double i, ScrPromise *src) {
1179
+ scr_arr_set_bool(a, i, scr_promise_payload_bool(src));
1180
+ }
1181
+ void scr_promise_all_store_str(ScrArr *a, double i, ScrPromise *src) {
1182
+ scr_arr_set_ref(a, i, scr_promise_payload_str(src));
1183
+ }
1184
+ void scr_promise_all_store_ref(ScrArr *a, double i, ScrPromise *src) {
1185
+ scr_arr_set_ref(a, i, scr_promise_payload_ref(src));
1186
+ }
1187
+
1188
+ /* Fulfillment payload accessors for the emitted race adapters — all
1189
+ * retained/by-value (the source keeps its settlement). */
1190
+ double scr_promise_payload_f64(ScrPromise *p) { return p->f64; }
1191
+ bool scr_promise_payload_bool(ScrPromise *p) { return p->b; }
1192
+ ScrStr *scr_promise_payload_str(ScrPromise *p) {
1193
+ return scr_str_retain((ScrStr *)p->payload);
1194
+ }
1195
+ /* Thin views for the gated dyn-async TU (scr_async_dyn.c): the payload
1196
+ * KIND, whether a REF payload is a dyn value (the dyn adapters), and the
1197
+ * settled-await primitive (park/hop + rejection re-throw; true =
1198
+ * fulfilled). */
1199
+ static bool scr_await_settled(ScrPromise *p); /* defined with the await family */
1200
+ int scr_promise_payload_kind(const ScrPromise *p) { return (int)p->payload_kind; }
1201
+ bool scr_promise_payload_is_dyn(const ScrPromise *p) { return p->retain_fn == scr_dyn_retain_v; }
1202
+ double scr_promise_payload_num(const ScrPromise *p) { return p->f64; }
1203
+ bool scr_promise_payload_flag(const ScrPromise *p) { return p->b; }
1204
+ bool scr_promise_await_settled(ScrPromise *p) { return scr_await_settled(p); }
1205
+ void scr_promise_payload_release(const ScrPromise *p, void *v) { p->release_fn(v); }
1206
+
1207
+ void *scr_promise_payload_ref(ScrPromise *p) {
1208
+ return p->payload ? p->retain_fn(p->payload) : NULL;
1209
+ }
1210
+
1211
+ /* MOVES a pending exception out of `cell` into `p` as its rejection payload
1212
+ * (the cell resets to NONE). Shared by fiber completion and the new-Promise
1213
+ * executor runners; callers wake waiters themselves. */
1214
+ static void scr_promise_reject_from_cell(ScrPromise *p, ScrExcCell *cell) {
1215
+ p->state = SCR_PROM_REJECTED;
1216
+ p->payload_kind = cell->kind;
1217
+ p->f64 = cell->f64;
1218
+ p->b = cell->b;
1219
+ p->payload = cell->payload;
1220
+ p->retain_fn = cell->retain_fn;
1221
+ p->release_fn = cell->release_fn;
1222
+ p->trace_fn = cell->trace_fn;
1223
+ cell->kind = SCR_EXC_NONE;
1224
+ cell->payload = NULL;
1225
+ cell->trace_fn = NULL;
1226
+ }
1227
+
1228
+ static void scr_fiber_finish(ScrFiber *self) {
1229
+ if (self->gen != NULL) {
1230
+ /* Generator completion: the emitted trampoline already stored the
1231
+ * completion value (or consumed the GENRET sentinel); a real body
1232
+ * exception stays pending in this fiber's cell — the consumer-side
1233
+ * resume moves it into the resumer's cell. No promise to settle. */
1234
+ self->done = true;
1235
+ return;
1236
+ }
1237
+ ScrPromise *p = self->promise;
1238
+ if (scr_exc_pending()) {
1239
+ /* The body's exception escaped: the promise rejects with the payload
1240
+ * (moved from the fiber's cell into the promise). */
1241
+ scr_promise_reject_from_cell(p, &self->exc);
1242
+ }
1243
+ /* Fulfillment payload was stored by the trampoline before finishing. */
1244
+ scr_promise_settle_wake(p);
1245
+ self->done = true;
1246
+ }
1247
+
1248
+ #ifdef _WIN32
1249
+ static void CALLBACK scr_trampoline(void *param) {
1250
+ (void)param;
1251
+ #else
1252
+ static void scr_trampoline(void) {
1253
+ #endif
1254
+ #ifdef SCR_ASAN_FIBERS
1255
+ const void *ob;
1256
+ size_t os;
1257
+ __sanitizer_finish_switch_fiber(scr_current->fake_stack, &ob, &os);
1258
+ #endif
1259
+ ScrFiber *self = scr_current;
1260
+ self->entry(self, self->argpack);
1261
+ scr_fiber_finish(self);
1262
+ /* Dead fiber: hop back to whoever resumed us. The loop frees us. */
1263
+ scr_switch(&self->ctx, self->return_to, NULL);
1264
+ /* unreachable */
1265
+ }
1266
+
1267
+ #if !defined(_WIN32) && !defined(__wasi__)
1268
+ /* Apple Silicon's makecontext clears all of uc_stack before installing the
1269
+ * initial registers. Passing the whole mapping eagerly commits 256 KiB
1270
+ * (8 MiB under ASan) per call, defeating the lazy allocation above. Its
1271
+ * zero-argument startup frame only needs the top of the downward-growing
1272
+ * stack. Initialize that window, then publish the FULL stack bounds before
1273
+ * any execution or sanitizer switch. The stack top and saved SP are the
1274
+ * same as when initializing the full mapping; ordinary calls can still
1275
+ * use all of SCR_FIBER_STACK.
1276
+ * See libplatform/src/ucontext/generic/makecontext.c's arm64 implementation. */
1277
+ static void scr_fiber_context_init(ScrFiber *f) {
1278
+ f->stack = scr_fiber_stack_new();
1279
+ if (getcontext(&f->ctx) != 0) scr_trap("scriptc: getcontext failed\n");
1280
+ f->ctx.uc_stack.ss_sp = f->stack;
1281
+ f->ctx.uc_stack.ss_size = SCR_FIBER_STACK;
1282
+ f->ctx.uc_stack.ss_flags = 0;
1283
+ f->ctx.uc_link = NULL;
1284
+ #if defined(__APPLE__) && defined(__aarch64__)
1285
+ const size_t bootstrap = 16 * 1024;
1286
+ f->ctx.uc_stack.ss_sp = f->stack + SCR_FIBER_STACK - bootstrap;
1287
+ f->ctx.uc_stack.ss_size = bootstrap;
1288
+ #endif
1289
+ makecontext(&f->ctx, scr_trampoline, 0);
1290
+ f->ctx.uc_stack.ss_sp = f->stack;
1291
+ f->ctx.uc_stack.ss_size = SCR_FIBER_STACK;
1292
+ }
1293
+ #endif
1294
+
1295
+ /* Frees a finished fiber's execution resources (the promise release and
1296
+ * bookkeeping stay at the call sites). Windows: DeleteFiber tears down the
1297
+ * fiber object and its stack — legal here because a finished fiber has
1298
+ * switched away and can never be current again. */
1299
+ static void scr_fiber_destroy(ScrFiber *f) {
1300
+ #ifdef _WIN32
1301
+ DeleteFiber(f->ctx);
1302
+ #elif defined(__wasi__)
1303
+ if (f->coro != NULL) scr_wasi_coro_destroy(f->coro);
1304
+ #endif
1305
+ scr_als_ctx_release(f->als);
1306
+ #if !defined(_WIN32) && !defined(__wasi__)
1307
+ scr_fiber_stack_free(f->stack);
1308
+ #else
1309
+ free(f->stack);
1310
+ #endif
1311
+ free(f);
1312
+ }
1313
+
1314
+ /* Spawns and EAGERLY runs an async body until its first suspension (JS's
1315
+ * synchronous-prefix rule). Returns the fiber's promise, +1. */
1316
+ ScrPromise *scr_async_spawn(void (*entry)(ScrFiber *, void *), void *argpack) {
1317
+ ScrFiber *f = calloc(1, sizeof *f);
1318
+ if (!f) scr_oom();
1319
+ f->promise = scr_promise_new();
1320
+ f->entry = entry;
1321
+ f->argpack = argpack;
1322
+ /* AsyncLocalStorage: the child runs in the SPAWNER's context (Node's
1323
+ * init-time capture); snapshots are immutable, so a retain suffices. */
1324
+ f->als = scr_als_ctx_retain(*scr_als_active);
1325
+ scr_fibers_live++;
1326
+
1327
+ #ifdef _WIN32
1328
+ /* Commit one page initially; Windows commits further pages as the stack
1329
+ * grows. Keep the executable's stack reserve, as with CreateFiber,
1330
+ * without committing SCR_FIBER_STACK for every idle fiber. */
1331
+ ScrCtx here = scr_win_self();
1332
+ f->ctx = CreateFiberEx(4096, 0, 0, scr_trampoline, NULL);
1333
+ if (f->ctx == NULL) scr_oom();
1334
+ #elif defined(__wasi__)
1335
+ ScrFiber *spawner = scr_current;
1336
+ scr_current = f;
1337
+ scr_exc_swap_cell(&f->exc);
1338
+ scr_als_active = &f->als;
1339
+ entry(f, argpack); /* eager prefix; returns at suspend/final suspend */
1340
+ scr_current = spawner;
1341
+ scr_exc_swap_cell(spawner ? &spawner->exc : NULL);
1342
+ scr_als_active = spawner ? &spawner->als : &scr_als_main_slot;
1343
+ ScrPromise *result = scr_promise_retain(f->promise);
1344
+ if (f->done) {
1345
+ scr_promise_release(f->promise);
1346
+ scr_fiber_destroy(f);
1347
+ scr_fibers_live--;
1348
+ }
1349
+ return result;
1350
+ #else
1351
+ scr_fiber_context_init(f);
1352
+
1353
+ ucontext_t here;
1354
+ #endif
1355
+ #ifndef __wasi__
1356
+ f->return_to = &here;
1357
+ ScrFiber *spawner = scr_current;
1358
+ scr_switch(&here, &f->ctx, f);
1359
+ /* back: the fiber suspended or finished. The switch back targeted NULL
1360
+ * (the child doesn't know who spawned it), which pointed both the current
1361
+ * fiber AND the exception machinery at main — restore the spawner's cell
1362
+ * too, or a fiber that eagerly spawned another keeps throwing/catching
1363
+ * against main's cell and completes with its own cell empty (a phantom
1364
+ * `undefined` rejection while the real payload leaks). */
1365
+ scr_current = spawner;
1366
+ scr_exc_swap_cell(spawner ? &spawner->exc : NULL);
1367
+ scr_als_active = spawner ? &spawner->als : &scr_als_main_slot;
1368
+ ScrPromise *result = scr_promise_retain(f->promise);
1369
+ if (f->done) {
1370
+ scr_promise_release(f->promise);
1371
+ scr_fiber_destroy(f);
1372
+ scr_fibers_live--;
1373
+ }
1374
+ return result;
1375
+ #endif
1376
+ }
1377
+
1378
+ /* A runtime-authored C continuation whose first operation awaits one known
1379
+ * dependency. Native fibers can park normally. wasm32 has no resumable C
1380
+ * stack, so queue the fiber only after the dependency settles; the entry's
1381
+ * await then extracts the result without attempting a stack switch. The
1382
+ * READY queue supplies the settled-await microtask hop in both cases. */
1383
+ ScrPromise *scr_async_spawn_after(ScrPromise *dependency,
1384
+ void (*entry)(ScrFiber *, void *),
1385
+ void *argpack) {
1386
+ #ifndef __wasi__
1387
+ (void)dependency;
1388
+ return scr_async_spawn(entry, argpack);
1389
+ #else
1390
+ ScrFiber *f = calloc(1, sizeof *f);
1391
+ if (!f) scr_oom();
1392
+ f->promise = scr_promise_new();
1393
+ f->entry = entry;
1394
+ f->argpack = argpack;
1395
+ f->als = scr_als_ctx_retain(*scr_als_active);
1396
+ scr_fibers_live++;
1397
+
1398
+ if (dependency->state == SCR_PROM_PENDING) {
1399
+ if (dependency->nwaiters == dependency->waiters_cap) {
1400
+ dependency->waiters_cap = dependency->waiters_cap ? dependency->waiters_cap * 2 : 4;
1401
+ dependency->waiters = realloc(
1402
+ dependency->waiters, dependency->waiters_cap * sizeof *dependency->waiters);
1403
+ if (!dependency->waiters) scr_oom();
1404
+ }
1405
+ dependency->waiters[dependency->nwaiters++] = f;
1406
+ } else {
1407
+ scr_ready_push(f);
1408
+ }
1409
+ return scr_promise_retain(f->promise);
1410
+ #endif
1411
+ }
1412
+
1413
+ /* Parks the current fiber on `p` until it settles. Only fibers await. */
1414
+ static void scr_await_park(ScrPromise *p) {
1415
+ ScrFiber *self = scr_current;
1416
+ if (!self) {
1417
+ fputs("scriptc: internal error: await outside an async function\n", stderr);
1418
+ abort();
1419
+ }
1420
+ if (p->nwaiters == p->waiters_cap) {
1421
+ p->waiters_cap = p->waiters_cap ? p->waiters_cap * 2 : 4;
1422
+ p->waiters = realloc(p->waiters, p->waiters_cap * sizeof *p->waiters);
1423
+ if (!p->waiters) scr_oom();
1424
+ }
1425
+ p->waiters[p->nwaiters++] = self;
1426
+ scr_switch(&self->ctx, self->return_to, NULL);
1427
+ /* Resumed by the loop: return_to must now point at the loop's context. */
1428
+ }
1429
+
1430
+ #ifdef __wasi__
1431
+ /* The emitted coroutine suspends immediately after these preparation
1432
+ * calls. Settled promises still queue one ready turn; pending promises own
1433
+ * the continuation through their waiter list. */
1434
+ void scr_wasi_await_prepare(ScrFiber *self, ScrPromise *p) {
1435
+ if (p->state == SCR_PROM_PENDING) {
1436
+ if (p->nwaiters == p->waiters_cap) {
1437
+ p->waiters_cap = p->waiters_cap ? p->waiters_cap * 2 : 4;
1438
+ p->waiters = realloc(p->waiters, p->waiters_cap * sizeof *p->waiters);
1439
+ if (!p->waiters) scr_oom();
1440
+ }
1441
+ p->waiters[p->nwaiters++] = self;
1442
+ } else {
1443
+ scr_ready_push(self);
1444
+ }
1445
+ }
1446
+
1447
+ void scr_wasi_await_hop_prepare(ScrFiber *self) { scr_ready_push(self); }
1448
+
1449
+ bool scr_wasi_module_await_prepare(ScrFiber *self, ScrPromise *p) {
1450
+ if (p->state != SCR_PROM_PENDING) return false;
1451
+ scr_wasi_await_prepare(self, p);
1452
+ return true;
1453
+ }
1454
+
1455
+ void scr_wasi_async_finish(ScrFiber *self) { scr_fiber_finish(self); }
1456
+
1457
+ void scr_wasi_gen_finish(ScrFiber *self) {
1458
+ if (scr_exc_genret_pending()) {
1459
+ scr_exc_clear();
1460
+ scr_gen_ret_to_out(self->gen);
1461
+ }
1462
+ scr_fiber_finish(self);
1463
+ }
1464
+ #endif
1465
+
1466
+ /* One microtask hop: park the current fiber on the READY queue itself and
1467
+ * yield. JS's `await` ALWAYS suspends — even on an already-settled promise
1468
+ * the continuation runs as a microtask — so without this hop an awaiter of
1469
+ * a settled promise would continue synchronously inside the spawner,
1470
+ * observably earlier than Node (corpus 1428 pins the ordering). */
1471
+ static void scr_await_yield(void) {
1472
+ ScrFiber *self = scr_current;
1473
+ if (!self) {
1474
+ fputs("scriptc: internal error: await outside an async function\n", stderr);
1475
+ abort();
1476
+ }
1477
+ scr_ready_push(self);
1478
+ scr_switch(&self->ctx, self->return_to, NULL);
1479
+ }
1480
+
1481
+ /* The emitted promise-or-absent await's unit arm (`await u` where u holds
1482
+ * undefined/null): JS awaits non-thenables through exactly one microtask
1483
+ * turn — the same hop a settled promise takes. */
1484
+ void scr_await_hop(void) { scr_await_yield(); }
1485
+
1486
+ /* Copies a rejection into the active execution context's exception cell.
1487
+ * The payload is RETAINED, not moved — a promise can be awaited more than
1488
+ * once, and the executable's top-level completion probe consumes the same
1489
+ * settlement from the main stack after the loop drains. */
1490
+ static void scr_promise_rethrow(ScrPromise *p) {
1491
+ switch (p->payload_kind) {
1492
+ case SCR_EXC_F64: scr_throw_f64(p->f64); break;
1493
+ case SCR_EXC_BOOL: scr_throw_bool(p->b); break;
1494
+ case SCR_EXC_STR: scr_throw_str(scr_str_retain((ScrStr *)p->payload)); break;
1495
+ case SCR_EXC_REF: scr_throw_ref(p->retain_fn(p->payload), p->retain_fn, p->release_fn, p->trace_fn); break;
1496
+ case SCR_EXC_PRIMITIVE_REF: scr_throw_primitive_ref(p->retain_fn(p->payload), p->retain_fn, p->release_fn, p->trace_fn); break;
1497
+ case SCR_EXC_OBJ: scr_throw_obj(p->retain_fn(p->payload), p->retain_fn, p->release_fn, p->trace_fn); break;
1498
+ case SCR_EXC_NONE:
1499
+ case SCR_EXC_GENRET: /* unreachable: the sentinel never settles a promise */
1500
+ scr_throw_str(scr_str_new("undefined", 9));
1501
+ break;
1502
+ }
1503
+ }
1504
+
1505
+ /* Await result extraction. Rejection re-throws into the awaiter. */
1506
+ static bool scr_await_settled(ScrPromise *p) {
1507
+ #ifdef __wasi__
1508
+ if (p->state == SCR_PROM_PENDING) {
1509
+ fputs("scriptc: internal error: resumed before awaited promise settled\n", stderr);
1510
+ abort();
1511
+ }
1512
+ #else
1513
+ if (p->state != SCR_PROM_PENDING) scr_await_yield();
1514
+ while (p->state == SCR_PROM_PENDING) scr_await_park(p);
1515
+ #endif
1516
+ scr_prom_observe(p);
1517
+ if (p->state == SCR_PROM_REJECTED) {
1518
+ scr_promise_rethrow(p);
1519
+ return false;
1520
+ }
1521
+ return true;
1522
+ }
1523
+
1524
+ double scr_await_f64(ScrPromise *p) {
1525
+ return scr_await_settled(p) ? p->f64 : 0;
1526
+ }
1527
+ bool scr_await_bool(ScrPromise *p) {
1528
+ return scr_await_settled(p) ? p->b : false;
1529
+ }
1530
+ void *scr_await_ref(ScrPromise *p) {
1531
+ return scr_await_settled(p) && p->payload ? p->retain_fn(p->payload) : NULL;
1532
+ }
1533
+ void scr_await_void(ScrPromise *p) { scr_await_settled(p); }
1534
+
1535
+ /* ECMAScript's INTERNAL module-dependency wait. Unlike a user-authored
1536
+ * await, an already-completed dependency does not introduce a promise-job
1537
+ * hop: the evaluator continues synchronously into the importer. A pending
1538
+ * dependency still parks this module fiber, and rejection propagates into
1539
+ * it exactly like an ordinary await. */
1540
+ void scr_module_await(ScrPromise *p) {
1541
+ #ifndef __wasi__
1542
+ while (p->state == SCR_PROM_PENDING) scr_await_park(p);
1543
+ #endif
1544
+ scr_prom_observe(p);
1545
+ if (p->state == SCR_PROM_REJECTED) scr_promise_rethrow(p);
1546
+ }
1547
+
1548
+ int scr_promise_finish_top_level(ScrPromise *p) {
1549
+ if (p->state == SCR_PROM_PENDING) {
1550
+ /* ECMAScript module evaluation is still pending, but Node's ref'd
1551
+ * event-loop work is exhausted. Node exits with its dedicated
1552
+ * unsettled-top-level-await status. */
1553
+ scr_exit_code_note(13);
1554
+ return 13;
1555
+ }
1556
+ scr_prom_observe(p);
1557
+ return p->state == SCR_PROM_REJECTED && !p->top_level_handled ? 1 : 0;
1558
+ }
1559
+
1560
+ void scr_promise_rethrow_top_level(ScrPromise *p) {
1561
+ if (p->state == SCR_PROM_REJECTED) scr_promise_rethrow(p);
1562
+ }
1563
+
1564
+
1565
+
1566
+
1567
+
1568
+ /* Fulfillment storers, called by the compiled trampolines / resolve thunks. */
1569
+ void scr_promise_fulfill_f64(ScrPromise *p, double v) {
1570
+ if (p->state != SCR_PROM_PENDING) return; /* first settle wins */
1571
+ p->state = SCR_PROM_FULFILLED;
1572
+ p->payload_kind = SCR_EXC_F64;
1573
+ p->f64 = v;
1574
+ scr_promise_settle_wake(p);
1575
+ }
1576
+ void scr_promise_fulfill_bool(ScrPromise *p, bool v) {
1577
+ if (p->state != SCR_PROM_PENDING) return;
1578
+ p->state = SCR_PROM_FULFILLED;
1579
+ p->payload_kind = SCR_EXC_BOOL;
1580
+ p->b = v;
1581
+ scr_promise_settle_wake(p);
1582
+ }
1583
+ void scr_promise_fulfill_ref(ScrPromise *p, void *v, void *(*retain)(void *), void (*release)(void *), ScrTraceFn trace) {
1584
+ if (p->state != SCR_PROM_PENDING) {
1585
+ if (release) release(v); /* value was +1 for us; drop it */
1586
+ return;
1587
+ }
1588
+ p->state = SCR_PROM_FULFILLED;
1589
+ p->payload_kind = v ? SCR_EXC_REF : SCR_EXC_NONE;
1590
+ p->payload = v;
1591
+ p->retain_fn = retain;
1592
+ p->release_fn = release;
1593
+ p->trace_fn = trace;
1594
+ scr_promise_settle_wake(p);
1595
+ }
1596
+ void scr_promise_fulfill_void(ScrPromise *p) {
1597
+ if (p->state != SCR_PROM_PENDING) return;
1598
+ p->state = SCR_PROM_FULFILLED;
1599
+ p->payload_kind = SCR_EXC_NONE;
1600
+ scr_promise_settle_wake(p);
1601
+ }
1602
+
1603
+ /* String payloads ride the STR kind so awaits type them precisely. */
1604
+ void scr_promise_fulfill_str(ScrPromise *p, ScrStr *v) {
1605
+ if (p->state != SCR_PROM_PENDING) {
1606
+ scr_str_release(v);
1607
+ return;
1608
+ }
1609
+ p->state = SCR_PROM_FULFILLED;
1610
+ p->payload_kind = SCR_EXC_STR;
1611
+ p->payload = v; /* ownership moves in */
1612
+ p->retain_fn = (void *(*)(void *))scr_str_retain;
1613
+ p->release_fn = (void (*)(void *))scr_str_release;
1614
+ scr_promise_settle_wake(p);
1615
+ }
1616
+ ScrStr *scr_await_str(ScrPromise *p) {
1617
+ return scr_await_settled(p) && p->payload ? scr_str_retain((ScrStr *)p->payload) : NULL;
1618
+ }
1619
+
1620
+ /* REJECTS `p` with the exception pending in the ACTIVE cell (moved out —
1621
+ * the cell resets, so the caller returns to the engine/loop with a clean
1622
+ * cell) and wakes waiters; the rejection enters the unhandled ledger like
1623
+ * any other. The island → static promise bridge's rejection half: its
1624
+ * settle callback converts the engine reason into a pending exception
1625
+ * (the exception bridge's one conversion), then lands it here. A no-op
1626
+ * with nothing pending; an already-settled `p` just clears the cell
1627
+ * (first settle wins, like resolve-then-throw). */
1628
+ void scr_promise_reject_pending(ScrPromise *p) {
1629
+ if (!scr_exc_pending()) return;
1630
+ if (p->state == SCR_PROM_PENDING) {
1631
+ scr_promise_reject_from_cell(p, scr_exc_current_cell());
1632
+ scr_promise_settle_wake(p);
1633
+ } else {
1634
+ scr_exc_clear();
1635
+ }
1636
+ }
1637
+
1638
+ /* ── settled-promise minting (the fs/promises bridge) ─────────────────
1639
+ * The promise-returning stdlib functions run their syscall SYNCHRONOUSLY
1640
+ * (the documented non-interleaving divergence, SEMANTICS.md) and wrap the
1641
+ * outcome here: a pending exception in the active cell becomes the
1642
+ * promise's REJECTION (moved out of the cell — the caller's pending check
1643
+ * then sees a clean cell, exactly like Node where fs/promises failures
1644
+ * reject instead of throwing), anything else fulfills with the payload.
1645
+ * The rejected case still enters the unhandled-rejection ledger, so a
1646
+ * never-awaited failure reports at exit like any other rejection. */
1647
+
1648
+ static ScrPromise *scr_promise_settled_common(void) {
1649
+ if (!scr_exc_pending()) return NULL;
1650
+ ScrPromise *p = scr_promise_new();
1651
+ scr_promise_reject_from_cell(p, scr_exc_current_cell());
1652
+ scr_promise_settle_wake(p); /* no waiters yet; enters the ledger */
1653
+ return p;
1654
+ }
1655
+
1656
+ ScrPromise *scr_promise_settled_str(ScrStr *v) {
1657
+ ScrPromise *rejected = scr_promise_settled_common();
1658
+ if (rejected) {
1659
+ scr_str_release(v); /* NULL-tolerant; the op returned a dummy */
1660
+ return rejected;
1661
+ }
1662
+ ScrPromise *p = scr_promise_new();
1663
+ scr_promise_fulfill_str(p, v); /* moves in */
1664
+ return p;
1665
+ }
1666
+
1667
+ ScrPromise *scr_promise_settled_void(void) {
1668
+ ScrPromise *rejected = scr_promise_settled_common();
1669
+ if (rejected) return rejected;
1670
+ ScrPromise *p = scr_promise_new();
1671
+ scr_promise_fulfill_void(p);
1672
+ return p;
1673
+ }
1674
+
1675
+ ScrPromise *scr_promise_settled_ref(void *v, void *(*retain)(void *), void (*release)(void *),
1676
+ ScrTraceFn trace) {
1677
+ ScrPromise *rejected = scr_promise_settled_common();
1678
+ if (rejected) {
1679
+ if (v && release) release(v);
1680
+ return rejected;
1681
+ }
1682
+ ScrPromise *p = scr_promise_new();
1683
+ scr_promise_fulfill_ref(p, v, retain, release, trace); /* moves in */
1684
+ return p;
1685
+ }
1686
+
1687
+ /* ── fs/promises ─────────────────────────────────────────────────────
1688
+ * The promise forms run the SAME sync operations and mint an already-
1689
+ * settled promise (scr_promise_settled_*): success fulfills, a pending
1690
+ * exception moves in as the rejection — catchable at the await, like
1691
+ * Node. DOCUMENTED DIVERGENCE (SEMANTICS.md): the syscall blocks the
1692
+ * event loop, so I/O never interleaves with timers or other fibers —
1693
+ * observable only in concurrent code, not in the sequential await
1694
+ * chains CLIs are made of. */
1695
+
1696
+ ScrPromise *scr_fsp_read_file(ScrStr *path) {
1697
+ return scr_promise_settled_str(scr_fs_read_file(path));
1698
+ }
1699
+
1700
+ ScrPromise *scr_fsp_write_file(ScrStr *path, ScrStr *data) {
1701
+ scr_fs_write_file(path, data);
1702
+ return scr_promise_settled_void();
1703
+ }
1704
+
1705
+ ScrPromise *scr_fsp_write_file_mode(ScrStr *path, ScrStr *data, double mode) {
1706
+ scr_fs_write_file_mode(path, data, mode);
1707
+ return scr_promise_settled_void();
1708
+ }
1709
+
1710
+ ScrPromise *scr_fsp_mkdir(ScrStr *path) {
1711
+ scr_fs_mkdir(path);
1712
+ return scr_promise_settled_void();
1713
+ }
1714
+
1715
+ ScrPromise *scr_fsp_mkdir_mode(ScrStr *path, double mode) {
1716
+ scr_fs_mkdir_mode(path, mode);
1717
+ return scr_promise_settled_void();
1718
+ }
1719
+
1720
+ ScrPromise *scr_fsp_mkdir_recursive(ScrStr *path) {
1721
+ scr_fs_mkdir_recursive(path);
1722
+ return scr_promise_settled_void();
1723
+ }
1724
+
1725
+ ScrPromise *scr_fsp_mkdir_recursive_mode(ScrStr *path, double mode) {
1726
+ scr_fs_mkdir_recursive_mode(path, mode);
1727
+ return scr_promise_settled_void();
1728
+ }
1729
+
1730
+ ScrPromise *scr_fsp_unlink(ScrStr *path) {
1731
+ scr_fs_unlink(path);
1732
+ return scr_promise_settled_void();
1733
+ }
1734
+
1735
+ ScrPromise *scr_fsp_chmod(ScrStr *path, double mode) {
1736
+ scr_fs_chmod(path, mode);
1737
+ return scr_promise_settled_void();
1738
+ }
1739
+
1740
+ ScrPromise *scr_fsp_readdir(ScrStr *path) {
1741
+ ScrArr *names = scr_fs_readdir(path);
1742
+ return scr_promise_settled_ref(names, &scr_arr_retain_v, &scr_arr_release_v, NULL);
1743
+ }
1744
+
1745
+ ScrPromise *scr_fsp_rm(ScrStr *path) {
1746
+ scr_fs_rm(path);
1747
+ return scr_promise_settled_void();
1748
+ }
1749
+
1750
+ ScrPromise *scr_fsp_stat(ScrStr *path) {
1751
+ ScrStats *st = scr_fs_stat(path);
1752
+ return scr_promise_settled_ref(st, &scr_stats_retain_v, &scr_stats_release_v, NULL);
1753
+ }
1754
+
1755
+ ScrPromise *scr_fsp_realpath(ScrStr *path) {
1756
+ return scr_promise_settled_str(scr_fs_realpath_promise(path));
1757
+ }
1758
+
1759
+ ScrPromise *scr_fsp_lstat(ScrStr *path) {
1760
+ ScrStats *st = scr_fs_lstat(path);
1761
+ return scr_promise_settled_ref(st, &scr_stats_retain_v, &scr_stats_release_v, NULL);
1762
+ }
1763
+
1764
+ ScrPromise *scr_fsp_rename(ScrStr *oldpath, ScrStr *newpath) {
1765
+ scr_fs_rename(oldpath, newpath);
1766
+ return scr_promise_settled_void();
1767
+ }
1768
+
1769
+ /* Shared native work queue, initially introduced by fs.rename and also used
1770
+ * by node:zlib's callback codecs. Work starts immediately on a native worker,
1771
+ * matching libuv's key contract while JS/main is synchronously occupied.
1772
+ * Error/Buffer construction, callback invocation, and every RC mutation stay
1773
+ * on the main runtime thread when a later loop turn observes completion.
1774
+ *
1775
+ * A compact operation queue is also the liveness handle: an outstanding
1776
+ * callback-style request keeps the loop alive. Four persistent workers mirror
1777
+ * libuv's default pool size without creating one OS thread per request. A
1778
+ * platform mutex publishes each result before the loop removes it from the
1779
+ * completion queue. */
1780
+ #if !defined(SCR_LIB) && !defined(__wasi__)
1781
+ typedef struct ScrFsRenameOp {
1782
+ bool generic;
1783
+ bool ran;
1784
+ void *payload;
1785
+ ScrWorkFn work;
1786
+ ScrWorkFn after;
1787
+ ScrWorkFn destroy;
1788
+ ScrStr *oldpath;
1789
+ ScrStr *newpath;
1790
+ ScrClosure *cb;
1791
+ ScrFsRenameFn fn;
1792
+ int error;
1793
+ struct ScrFsRenameOp *next;
1794
+ } ScrFsRenameOp;
1795
+
1796
+ static ScrFsRenameOp *scr_fs_rename_work = NULL;
1797
+ static ScrFsRenameOp **scr_fs_rename_work_tail = &scr_fs_rename_work;
1798
+ static ScrFsRenameOp *scr_fs_rename_done = NULL;
1799
+ static ScrFsRenameOp **scr_fs_rename_done_tail = &scr_fs_rename_done;
1800
+ static size_t scr_fs_rename_pending_count = 0;
1801
+ static size_t scr_fs_rename_worker_count = 0;
1802
+ static bool scr_fs_rename_stopping = false;
1803
+ static bool scr_fs_rename_shutdown_registered = false;
1804
+
1805
+ #ifdef _WIN32
1806
+ static HANDLE scr_fs_rename_workers[4];
1807
+ static SRWLOCK scr_fs_rename_lock = SRWLOCK_INIT;
1808
+ static CONDITION_VARIABLE scr_fs_rename_cond = CONDITION_VARIABLE_INIT;
1809
+ static void scr_fs_rename_lock_enter(void) { AcquireSRWLockExclusive(&scr_fs_rename_lock); }
1810
+ static void scr_fs_rename_lock_leave(void) { ReleaseSRWLockExclusive(&scr_fs_rename_lock); }
1811
+ static void scr_fs_rename_wait(void) {
1812
+ (void)SleepConditionVariableSRW(&scr_fs_rename_cond, &scr_fs_rename_lock, INFINITE, 0);
1813
+ }
1814
+ static void scr_fs_rename_signal(void) { WakeConditionVariable(&scr_fs_rename_cond); }
1815
+ static void scr_fs_rename_broadcast(void) { WakeAllConditionVariable(&scr_fs_rename_cond); }
1816
+ #else
1817
+ static pthread_t scr_fs_rename_workers[4];
1818
+ static pthread_mutex_t scr_fs_rename_lock = PTHREAD_MUTEX_INITIALIZER;
1819
+ static pthread_cond_t scr_fs_rename_cond = PTHREAD_COND_INITIALIZER;
1820
+ static void scr_fs_rename_lock_enter(void) { (void)pthread_mutex_lock(&scr_fs_rename_lock); }
1821
+ static void scr_fs_rename_lock_leave(void) { (void)pthread_mutex_unlock(&scr_fs_rename_lock); }
1822
+ static void scr_fs_rename_wait(void) {
1823
+ (void)pthread_cond_wait(&scr_fs_rename_cond, &scr_fs_rename_lock);
1824
+ }
1825
+ static void scr_fs_rename_signal(void) { (void)pthread_cond_signal(&scr_fs_rename_cond); }
1826
+ static void scr_fs_rename_broadcast(void) { (void)pthread_cond_broadcast(&scr_fs_rename_cond); }
1827
+ #endif
1828
+
1829
+ static void scr_fs_rename_op_release(ScrFsRenameOp *op) {
1830
+ if (op->generic) {
1831
+ op->destroy(op->payload);
1832
+ free(op);
1833
+ return;
1834
+ }
1835
+ scr_str_release(op->oldpath);
1836
+ scr_str_release(op->newpath);
1837
+ scr_closure_release(op->cb);
1838
+ free(op);
1839
+ }
1840
+
1841
+ static void scr_fs_rename_worker_loop(void) {
1842
+ for (;;) {
1843
+ scr_fs_rename_lock_enter();
1844
+ while (scr_fs_rename_work == NULL && !scr_fs_rename_stopping) scr_fs_rename_wait();
1845
+ if (scr_fs_rename_stopping) {
1846
+ scr_fs_rename_lock_leave();
1847
+ return;
1848
+ }
1849
+ ScrFsRenameOp *op = scr_fs_rename_work;
1850
+ scr_fs_rename_work = op->next;
1851
+ if (scr_fs_rename_work == NULL) scr_fs_rename_work_tail = &scr_fs_rename_work;
1852
+ scr_fs_rename_lock_leave();
1853
+
1854
+ if (op->generic) op->work(op->payload);
1855
+ else op->error = scr_fs_rename_raw(op->oldpath, op->newpath);
1856
+ op->ran = true;
1857
+
1858
+ scr_fs_rename_lock_enter();
1859
+ op->next = NULL;
1860
+ *scr_fs_rename_done_tail = op;
1861
+ scr_fs_rename_done_tail = &op->next;
1862
+ scr_fs_rename_lock_leave();
1863
+ }
1864
+ }
1865
+
1866
+ #ifdef _WIN32
1867
+ static DWORD WINAPI scr_fs_rename_worker(LPVOID payload) {
1868
+ (void)payload;
1869
+ scr_fs_rename_worker_loop();
1870
+ return 0;
1871
+ }
1872
+ #else
1873
+ static void *scr_fs_rename_worker(void *payload) {
1874
+ (void)payload;
1875
+ scr_fs_rename_worker_loop();
1876
+ return NULL;
1877
+ }
1878
+ #endif
1879
+
1880
+ /* Runs before the ordinary runtime atexit cleanup/audit (it is registered
1881
+ * lazily by the first rename request, after scr_init/scr_lib_init). Fatal
1882
+ * top-level or callback exceptions can stop the loop with requests still in
1883
+ * flight; join the workers before releasing their retained path/callback
1884
+ * payloads so sanitized builds keep the program's real exit verdict. */
1885
+ static void scr_fs_renames_shutdown(void) {
1886
+ scr_fs_rename_lock_enter();
1887
+ scr_fs_rename_stopping = true;
1888
+ scr_fs_rename_broadcast();
1889
+ scr_fs_rename_lock_leave();
1890
+
1891
+ for (size_t i = 0; i < scr_fs_rename_worker_count; i++) {
1892
+ #ifdef _WIN32
1893
+ (void)WaitForSingleObject(scr_fs_rename_workers[i], INFINITE);
1894
+ CloseHandle(scr_fs_rename_workers[i]);
1895
+ #else
1896
+ (void)pthread_join(scr_fs_rename_workers[i], NULL);
1897
+ #endif
1898
+ }
1899
+
1900
+ scr_fs_rename_lock_enter();
1901
+ ScrFsRenameOp *work = scr_fs_rename_work;
1902
+ ScrFsRenameOp *done = scr_fs_rename_done;
1903
+ scr_fs_rename_work = NULL;
1904
+ scr_fs_rename_work_tail = &scr_fs_rename_work;
1905
+ scr_fs_rename_done = NULL;
1906
+ scr_fs_rename_done_tail = &scr_fs_rename_done;
1907
+ scr_fs_rename_pending_count = 0;
1908
+ scr_fs_rename_lock_leave();
1909
+ while (work != NULL) {
1910
+ ScrFsRenameOp *next = work->next;
1911
+ scr_fs_rename_op_release(work);
1912
+ work = next;
1913
+ }
1914
+ while (done != NULL) {
1915
+ ScrFsRenameOp *next = done->next;
1916
+ scr_fs_rename_op_release(done);
1917
+ done = next;
1918
+ }
1919
+ }
1920
+
1921
+ static bool scr_fs_renames_pending(void) { return scr_fs_rename_pending_count != 0; }
1922
+
1923
+ static bool scr_fs_renames_dispatch(void) {
1924
+ scr_fs_rename_lock_enter();
1925
+ ScrFsRenameOp *op = scr_fs_rename_done;
1926
+ if (op != NULL) {
1927
+ scr_fs_rename_done = op->next;
1928
+ if (scr_fs_rename_done == NULL) scr_fs_rename_done_tail = &scr_fs_rename_done;
1929
+ }
1930
+ scr_fs_rename_lock_leave();
1931
+ if (op == NULL) return false;
1932
+ scr_fs_rename_pending_count--;
1933
+ if (op->generic) {
1934
+ if (!op->ran) op->work(op->payload);
1935
+ op->after(op->payload);
1936
+ scr_fs_rename_op_release(op);
1937
+ return true;
1938
+ }
1939
+ ScrCaught *caught = NULL;
1940
+ ScrError *err = NULL;
1941
+ if (op->error != 0) {
1942
+ scr_fs_rename_error(op->error, op->oldpath, op->newpath);
1943
+ caught = scr_exc_take();
1944
+ if (caught && caught->kind == SCR_EXC_OBJ && scr_error_is(caught->payload)) {
1945
+ err = (ScrError *)caught->payload;
1946
+ }
1947
+ }
1948
+ op->fn(op->cb, err);
1949
+ scr_caught_release(caught);
1950
+ scr_fs_rename_op_release(op);
1951
+ return true;
1952
+ }
1953
+
1954
+ static void scr_work_submit_op(ScrFsRenameOp *op) {
1955
+ if (!scr_fs_rename_shutdown_registered) {
1956
+ if (atexit(scr_fs_renames_shutdown) != 0) {
1957
+ scr_trap("scriptc: could not register worker cleanup\n");
1958
+ }
1959
+ scr_fs_rename_shutdown_registered = true;
1960
+ }
1961
+ scr_fs_rename_pending_count++;
1962
+ scr_fs_rename_lock_enter();
1963
+ *scr_fs_rename_work_tail = op;
1964
+ scr_fs_rename_work_tail = &op->next;
1965
+ int create_error = 0;
1966
+ if (scr_fs_rename_worker_count < 4) {
1967
+ #ifdef _WIN32
1968
+ HANDLE worker = CreateThread(NULL, 0, scr_fs_rename_worker, NULL, 0, NULL);
1969
+ if (worker != NULL) {
1970
+ scr_fs_rename_workers[scr_fs_rename_worker_count] = worker;
1971
+ scr_fs_rename_worker_count++;
1972
+ } else {
1973
+ create_error = EAGAIN;
1974
+ }
1975
+ #else
1976
+ pthread_t worker;
1977
+ create_error = pthread_create(&worker, NULL, scr_fs_rename_worker, NULL);
1978
+ if (create_error == 0) {
1979
+ scr_fs_rename_workers[scr_fs_rename_worker_count] = worker;
1980
+ scr_fs_rename_worker_count++;
1981
+ }
1982
+ #endif
1983
+ }
1984
+ if (create_error != 0 && scr_fs_rename_worker_count == 0) {
1985
+ /* Submission failure remains asynchronous. Rename preserves its
1986
+ * resource error; generic work falls back to the main loop turn. */
1987
+ while (scr_fs_rename_work != NULL) {
1988
+ ScrFsRenameOp *failed = scr_fs_rename_work;
1989
+ scr_fs_rename_work = failed->next;
1990
+ failed->error = create_error;
1991
+ failed->ran = !failed->generic;
1992
+ failed->next = NULL;
1993
+ *scr_fs_rename_done_tail = failed;
1994
+ scr_fs_rename_done_tail = &failed->next;
1995
+ }
1996
+ scr_fs_rename_work_tail = &scr_fs_rename_work;
1997
+ } else {
1998
+ scr_fs_rename_signal();
1999
+ }
2000
+ scr_fs_rename_lock_leave();
2001
+ }
2002
+ #elif defined(__wasi__)
2003
+ /* WASI Preview 1 has no threads, but rename itself is available. Queue the
2004
+ * request and perform it on the next loop turn so callback timing remains
2005
+ * asynchronous and the request remains a liveness handle. */
2006
+ typedef struct ScrFsRenameOp {
2007
+ bool generic;
2008
+ void *payload;
2009
+ ScrWorkFn work;
2010
+ ScrWorkFn after;
2011
+ ScrWorkFn destroy;
2012
+ ScrStr *oldpath;
2013
+ ScrStr *newpath;
2014
+ ScrClosure *cb;
2015
+ ScrFsRenameFn fn;
2016
+ struct ScrFsRenameOp *next;
2017
+ } ScrFsRenameOp;
2018
+
2019
+ static ScrFsRenameOp *scr_fs_rename_done = NULL;
2020
+ static ScrFsRenameOp **scr_fs_rename_done_tail = &scr_fs_rename_done;
2021
+ static size_t scr_fs_rename_pending_count = 0;
2022
+
2023
+ static bool scr_fs_renames_pending(void) { return scr_fs_rename_pending_count != 0; }
2024
+
2025
+ static bool scr_fs_renames_dispatch(void) {
2026
+ ScrFsRenameOp *op = scr_fs_rename_done;
2027
+ if (op == NULL) return false;
2028
+ scr_fs_rename_done = op->next;
2029
+ if (scr_fs_rename_done == NULL) scr_fs_rename_done_tail = &scr_fs_rename_done;
2030
+ scr_fs_rename_pending_count--;
2031
+
2032
+ if (op->generic) {
2033
+ op->work(op->payload);
2034
+ op->after(op->payload);
2035
+ op->destroy(op->payload);
2036
+ free(op);
2037
+ return true;
2038
+ }
2039
+
2040
+ int error = scr_fs_rename_raw(op->oldpath, op->newpath);
2041
+ ScrCaught *caught = NULL;
2042
+ ScrError *err = NULL;
2043
+ if (error != 0) {
2044
+ scr_fs_rename_error(error, op->oldpath, op->newpath);
2045
+ caught = scr_exc_take();
2046
+ if (caught && caught->kind == SCR_EXC_OBJ && scr_error_is(caught->payload)) {
2047
+ err = (ScrError *)caught->payload;
2048
+ }
2049
+ }
2050
+ op->fn(op->cb, err);
2051
+ scr_caught_release(caught);
2052
+ scr_str_release(op->oldpath);
2053
+ scr_str_release(op->newpath);
2054
+ scr_closure_release(op->cb);
2055
+ free(op);
2056
+ return true;
2057
+ }
2058
+ #else
2059
+ static bool scr_fs_renames_pending(void) { return false; }
2060
+ static bool scr_fs_renames_dispatch(void) { return false; }
2061
+ #endif
2062
+
2063
+ void scr_fs_rename_async(ScrStr *oldpath, ScrStr *newpath,
2064
+ ScrClosure *cb, ScrFsRenameFn fn) {
2065
+ #if defined(SCR_LIB)
2066
+ (void)oldpath; (void)newpath; (void)fn;
2067
+ scr_closure_release(cb);
2068
+ scr_trap("scriptc: callback-style fs.rename is not supported by this target\n");
2069
+ #elif defined(__wasi__)
2070
+ ScrFsRenameOp *op = calloc(1, sizeof *op);
2071
+ if (!op) scr_trap("scriptc: out of memory\n");
2072
+ op->oldpath = scr_str_retain(oldpath);
2073
+ op->newpath = scr_str_retain(newpath);
2074
+ op->cb = cb;
2075
+ op->fn = fn;
2076
+ *scr_fs_rename_done_tail = op;
2077
+ scr_fs_rename_done_tail = &op->next;
2078
+ scr_fs_rename_pending_count++;
2079
+ #else
2080
+ ScrFsRenameOp *op = calloc(1, sizeof *op);
2081
+ if (!op) scr_trap("scriptc: out of memory\n");
2082
+ op->oldpath = scr_str_retain(oldpath);
2083
+ op->newpath = scr_str_retain(newpath);
2084
+ op->cb = cb;
2085
+ op->fn = fn;
2086
+ scr_work_submit_op(op);
2087
+ #endif
2088
+ }
2089
+
2090
+ void scr_work_submit(void *payload, ScrWorkFn work, ScrWorkFn after,
2091
+ ScrWorkFn destroy) {
2092
+ #if defined(SCR_LIB)
2093
+ (void)work; (void)after;
2094
+ destroy(payload);
2095
+ scr_trap("scriptc: native worker jobs are not supported by this target\n");
2096
+ #elif defined(__wasi__)
2097
+ ScrFsRenameOp *op = calloc(1, sizeof *op);
2098
+ if (!op) scr_trap("scriptc: out of memory\n");
2099
+ op->generic = true;
2100
+ op->payload = payload;
2101
+ op->work = work;
2102
+ op->after = after;
2103
+ op->destroy = destroy;
2104
+ *scr_fs_rename_done_tail = op;
2105
+ scr_fs_rename_done_tail = &op->next;
2106
+ scr_fs_rename_pending_count++;
2107
+ #else
2108
+ ScrFsRenameOp *op = calloc(1, sizeof *op);
2109
+ if (!op) scr_trap("scriptc: out of memory\n");
2110
+ op->generic = true;
2111
+ op->payload = payload;
2112
+ op->work = work;
2113
+ op->after = after;
2114
+ op->destroy = destroy;
2115
+ scr_work_submit_op(op);
2116
+ #endif
2117
+ }
2118
+
2119
+ void scr_fs_rename_thunk0(ScrClosure *cb, ScrError *err) {
2120
+ (void)err;
2121
+ ((void (*)(ScrClosure *))cb->fn)(cb);
2122
+ }
2123
+
2124
+ /* Callback-style crypto completions. The operation validates and computes
2125
+ * before enqueueing; delivery is a later macrotask, never synchronous with
2126
+ * the API call. The queue owns both references and transfers the Buffer to
2127
+ * the emitted callback adapter. */
2128
+ typedef struct ScrCryptoBytesOp {
2129
+ ScrBytes *value;
2130
+ ScrClosure *cb;
2131
+ ScrCryptoBytesFn fn;
2132
+ struct ScrCryptoBytesOp *next;
2133
+ } ScrCryptoBytesOp;
2134
+
2135
+ static ScrCryptoBytesOp *scr_crypto_bytes_head = NULL;
2136
+ static ScrCryptoBytesOp **scr_crypto_bytes_tail = &scr_crypto_bytes_head;
2137
+ static size_t scr_crypto_bytes_pending_count = 0;
2138
+ static bool scr_crypto_bytes_cleanup_registered = false;
2139
+
2140
+ static void scr_crypto_bytes_shutdown(void) {
2141
+ while (scr_crypto_bytes_head != NULL) {
2142
+ ScrCryptoBytesOp *op = scr_crypto_bytes_head;
2143
+ scr_crypto_bytes_head = op->next;
2144
+ scr_bytes_release(op->value);
2145
+ scr_closure_release(op->cb);
2146
+ free(op);
2147
+ }
2148
+ scr_crypto_bytes_tail = &scr_crypto_bytes_head;
2149
+ scr_crypto_bytes_pending_count = 0;
2150
+ }
2151
+
2152
+ static bool scr_crypto_bytes_pending(void) {
2153
+ return scr_crypto_bytes_pending_count != 0;
2154
+ }
2155
+
2156
+ static bool scr_crypto_bytes_dispatch(void) {
2157
+ ScrCryptoBytesOp *op = scr_crypto_bytes_head;
2158
+ if (op == NULL) return false;
2159
+ scr_crypto_bytes_head = op->next;
2160
+ if (scr_crypto_bytes_head == NULL) scr_crypto_bytes_tail = &scr_crypto_bytes_head;
2161
+ scr_crypto_bytes_pending_count--;
2162
+ op->fn(op->cb, op->value); /* adapter consumes value */
2163
+ scr_closure_release(op->cb);
2164
+ free(op);
2165
+ return true;
2166
+ }
2167
+
2168
+ void scr_crypto_defer_bytes(ScrBytes *value, ScrClosure *cb, ScrCryptoBytesFn fn) {
2169
+ if (!scr_crypto_bytes_cleanup_registered) {
2170
+ if (atexit(scr_crypto_bytes_shutdown) != 0) {
2171
+ scr_bytes_release(value);
2172
+ scr_closure_release(cb);
2173
+ scr_trap("scriptc: could not register crypto callback cleanup\n");
2174
+ }
2175
+ scr_crypto_bytes_cleanup_registered = true;
2176
+ }
2177
+ ScrCryptoBytesOp *op = malloc(sizeof *op);
2178
+ if (!op) {
2179
+ scr_bytes_release(value);
2180
+ scr_closure_release(cb);
2181
+ scr_trap("scriptc: out of memory\n");
2182
+ }
2183
+ op->value = value;
2184
+ op->cb = cb;
2185
+ op->fn = fn;
2186
+ op->next = NULL;
2187
+ *scr_crypto_bytes_tail = op;
2188
+ scr_crypto_bytes_tail = &op->next;
2189
+ scr_crypto_bytes_pending_count++;
2190
+ }
2191
+
2192
+ /* ── node:timers/promises ────────────────────────────────────────────
2193
+ * The promisified pair: a PENDING void promise a one-shot heap timer
2194
+ * (setTimeout) or the immediate queue (setImmediate) fulfills — the
2195
+ * resolve closure is scr_make_resolve's void thunk, so settlement wakes
2196
+ * awaiting fibers exactly like every other promise, and the armed
2197
+ * timer/immediate keeps the loop alive until it fires (Node: an awaited
2198
+ * timers/promises sleep holds the process open). Neither throws; the
2199
+ * delay rides scr_set_timeout's own Node-exact coercion (clamp to 1,
2200
+ * truncate). */
2201
+
2202
+ ScrPromise *scr_tp_set_timeout(double ms) {
2203
+ ScrPromise *p = scr_promise_new();
2204
+ scr_set_timeout(scr_make_resolve(p, 3 /* void */), ms);
2205
+ return p;
2206
+ }
2207
+
2208
+ ScrPromise *scr_tp_set_immediate(void) {
2209
+ ScrPromise *p = scr_promise_new();
2210
+ scr_set_immediate(scr_make_resolve(p, 3 /* void */));
2211
+ return p;
2212
+ }
2213
+
2214
+ /* ── setImmediate as a first-class dyn value ─────────────────────────
2215
+ * The global passed AS A FUNCTION VALUE into untyped code (the Node-suite
2216
+ * traceCallback shape: `channel.traceCallback(setImmediate, 0, ctx, null,
2217
+ * cb)`). The minted dyn callable schedules its own immediate that calls
2218
+ * args[0] with the remaining arguments (Node's setImmediate(cb, ...args)
2219
+ * contract) and answers undefined (the Immediate handle object has no dyn
2220
+ * story — clearImmediate over this value is not modeled). A non-function
2221
+ * first argument throws Node's ERR_INVALID_ARG_TYPE synchronously. */
2222
+
2223
+ static void scr_imm_dyn_fire(ScrClosure *c) {
2224
+ ScrDyn *fn = (ScrDyn *)scr_box_get_ref(c->caps[0]);
2225
+ ScrDyn *args = (ScrDyn *)scr_box_get_ref(c->caps[1]);
2226
+ ScrDyn *r = scr_dyn_call(fn, args->v.arr.items, args->v.arr.len, "immediate callback");
2227
+ if (r != NULL) scr_dyn_release(r);
2228
+ scr_dyn_release(fn);
2229
+ scr_dyn_release(args);
2230
+ }
2231
+
2232
+ static ScrDyn *scr_imm_dyn_thunk(ScrClosure *clo, ScrDyn *const *args, size_t argc) {
2233
+ (void)clo;
2234
+ if (argc == 0 || args[0]->kind != SCR_DYN_FUNC) {
2235
+ static const char msg[] = "The \"callback\" argument must be of type function.";
2236
+ scr_throw_error_msg_code(SCR_ERR_TYPE, msg, sizeof msg - 1, "ERR_INVALID_ARG_TYPE");
2237
+ return NULL;
2238
+ }
2239
+ ScrDyn *rest = scr_dyn_new_arr();
2240
+ for (size_t i = 1; i < argc; i++) scr_dyn_arr_push(rest, scr_dyn_retain(args[i]));
2241
+ ScrClosure *c = scr_closure_new((void *)scr_imm_dyn_fire, 2);
2242
+ c->caps[0] = scr_box_new_obj(scr_dyn_retain_v, scr_dyn_release_v, NULL);
2243
+ scr_box_set_ref(c->caps[0], scr_dyn_retain(args[0]));
2244
+ c->caps[1] = scr_box_new_obj(scr_dyn_retain_v, scr_dyn_release_v, NULL);
2245
+ scr_box_set_ref(c->caps[1], rest); /* moves */
2246
+ scr_set_immediate(c);
2247
+ return scr_dyn_retain(scr_dyn_undefined());
2248
+ }
2249
+
2250
+ ScrDyn *scr_set_immediate_dyn_value(void) {
2251
+ return scr_dyn_new_func(scr_closure_new((void *)scr_imm_dyn_thunk, 0), scr_imm_dyn_thunk,
2252
+ 1, "(cb,...)", "setImmediate");
2253
+ }
2254
+
2255
+ /* ── queueMicrotask ──────────────────────────────────────────────────
2256
+ * The READY queue's FIFO is the microtask queue (promise continuations
2257
+ * ride it as parked fibers), so a queueMicrotask callback enters the SAME
2258
+ * queue as a stackless envelope — one order across both producers, like
2259
+ * V8's single microtask queue. scr_resume_fiber runs the closure on the
2260
+ * main stack; a throw is an uncaught exception (Node's queueMicrotask),
2261
+ * never a rejection. */
2262
+ void scr_queue_microtask(ScrClosure *cb) {
2263
+ ScrFiber *f = calloc(1, sizeof *f);
2264
+ if (!f) scr_oom();
2265
+ f->micro_cb = cb; /* ownership moves in */
2266
+ scr_ready_push(f);
2267
+ }
2268
+
2269
+ /* The checked-dynamic argument form (JS files — common.mustCall wrappers
2270
+ * and the suite's invalid-input probes): a non-function throws Node's
2271
+ * ERR_INVALID_ARG_TYPE synchronously; a function value is called with
2272
+ * zero arguments (Node passes none — extra queueMicrotask arguments are
2273
+ * ignored). */
2274
+ static void scr_micro_dyn_fire(ScrClosure *c) {
2275
+ ScrDyn *fn = (ScrDyn *)scr_box_get_ref(c->caps[0]);
2276
+ ScrDyn *r = scr_dyn_call(fn, NULL, 0, "queueMicrotask callback");
2277
+ if (r != NULL) scr_dyn_release(r);
2278
+ scr_dyn_release(fn);
2279
+ }
2280
+
2281
+ void scr_queue_microtask_dyn(const ScrDyn *cb) {
2282
+ if (cb->kind != SCR_DYN_FUNC) {
2283
+ static const char msg[] = "The \"callback\" argument must be of type function.";
2284
+ scr_throw_error_msg_code(SCR_ERR_TYPE, msg, sizeof msg - 1, "ERR_INVALID_ARG_TYPE");
2285
+ return;
2286
+ }
2287
+ ScrClosure *c = scr_closure_new((void *)scr_micro_dyn_fire, 1);
2288
+ c->caps[0] = scr_box_new_obj(scr_dyn_retain_v, scr_dyn_release_v, NULL);
2289
+ scr_box_set_ref(c->caps[0], scr_dyn_retain((ScrDyn *)cb));
2290
+ scr_queue_microtask(c);
2291
+ }
2292
+
2293
+ /* ── the event hooks (scr_events.c) ──────────────────────────────────
2294
+ * Process signal/exit events and the piped-stdin surface live in
2295
+ * scr_events.c, which links ONLY into binaries whose IR uses those
2296
+ * surfaces (the io-hook precedent, gated like scr_regex/scr_fetch):
2297
+ * scr_events_install() fills these slots before %main. Event-free
2298
+ * builds keep every slot NULL and the loop is byte-identical in
2299
+ * behavior. The scr_lib.c hooks live in scr_lib.c and the abnormal-exit
2300
+ * code hint in scr_exception.c, so each unit stays self-contained (the
2301
+ * runtime C tests link them separately). */
2302
+
2303
+ static bool (*scr_events_pending_fn)(void) = NULL; /* keeps the loop alive */
2304
+ static bool (*scr_events_watching_fn)(void) = NULL; /* wants the poll sleep */
2305
+ static void (*scr_events_dispatch_fn)(void) = NULL; /* fire due listeners */
2306
+ static int (*scr_events_pollfds_fn)(int out[2]) = NULL;
2307
+
2308
+ void scr_loop_set_events(bool (*pending)(void), bool (*watching)(void),
2309
+ void (*dispatch)(void), int (*pollfds)(int out[2])) {
2310
+ scr_events_pending_fn = pending;
2311
+ scr_events_watching_fn = watching;
2312
+ scr_events_dispatch_fn = dispatch;
2313
+ scr_events_pollfds_fn = pollfds;
2314
+ }
2315
+
2316
+ /* ── the event loop ───────────────────────────────────────────────────── */
2317
+
2318
+ static void scr_resume_fiber(ScrFiber *f) {
2319
+ if (f->gen_job != NULL) {
2320
+ ScrGen *g = f->gen_job;
2321
+ free(f);
2322
+ scr_async_gen_job(g);
2323
+ scr_gen_release(g);
2324
+ return;
2325
+ }
2326
+ /* A queueMicrotask envelope: run the closure on the main stack, no
2327
+ * context switch. A throw leaves the exception cell pending — every
2328
+ * drain site returns to main's uncaught report, Node's queueMicrotask
2329
+ * semantics (uncaughtException, never an unhandled rejection). */
2330
+ if (f->micro_cb != NULL) {
2331
+ ScrClosure *cb = f->micro_cb;
2332
+ free(f);
2333
+ ((void (*)(ScrClosure *))cb->fn)(cb);
2334
+ scr_closure_release(cb);
2335
+ return;
2336
+ }
2337
+ if (f->gen != NULL) {
2338
+ scr_async_gen_resume_ready(f->gen);
2339
+ return;
2340
+ }
2341
+ #ifdef _WIN32
2342
+ /* The loop runs on the main stack; make sure scr_loop_ctx names its
2343
+ * fiber handle (a no-op after the first conversion). */
2344
+ (void)scr_win_self();
2345
+ #endif
2346
+ f->return_to = &scr_loop_ctx;
2347
+ #ifdef __wasi__
2348
+ scr_current = f;
2349
+ scr_exc_swap_cell(&f->exc);
2350
+ scr_als_active = &f->als;
2351
+ if (f->coro != NULL) {
2352
+ scr_wasi_coro_resume(f->coro);
2353
+ } else {
2354
+ /* scr_async_spawn_after's runtime C continuation. Its dependency is
2355
+ * settled, so the entry can extract through scr_await_* without a
2356
+ * stack switch and then completes in this turn. */
2357
+ f->entry(f, f->argpack);
2358
+ scr_fiber_finish(f);
2359
+ }
2360
+ scr_current = NULL;
2361
+ scr_exc_swap_cell(NULL);
2362
+ scr_als_active = &scr_als_main_slot;
2363
+ #else
2364
+ scr_switch(&scr_loop_ctx, &f->ctx, f);
2365
+ #endif
2366
+ if (f->done) {
2367
+ scr_promise_release(f->promise);
2368
+ scr_fiber_destroy(f);
2369
+ scr_fibers_live--;
2370
+ }
2371
+ }
2372
+
2373
+ /* Reap granularity while children are pending on the POLLING fallback:
2374
+ * the loop polls waitpid(WNOHANG) at least this often instead of sleeping
2375
+ * to the next timer deadline. The primary path has no cap — the sleep
2376
+ * waits on the child watch (scr_children_wait — kqueue NOTE_EXIT on BSD,
2377
+ * pidfd epoll on Linux, the timer deadline riding the wait timeout) and a
2378
+ * child's exit wakes it immediately. The fallback covers platforms with
2379
+ * neither backend, children whose exit watch could not be armed, and
2380
+ * turns where the io poll takes the sleep (curl's fds can't join it). */
2381
+ #define SCR_CHILD_POLL_MS 1.0
2382
+
2383
+ /* Sleep cap while only external io is pending (no timer models its
2384
+ * wakeup): the io poll sleeps on REAL fds inside this window (a fetch
2385
+ * transfer's sockets wake it early), so a generous cap costs nothing. */
2386
+ #define SCR_IO_POLL_MS 1000.0
2387
+
2388
+ /* Sleep cap while signal handlers or stdin consumers are pending AND the
2389
+ * io poll owns the sleep (curl's fd wait retries on EINTR and can't watch
2390
+ * the wake pipe): bounded signal/stdin latency during a fetch at 20
2391
+ * wakeups/second. The dedicated poll(2) sleep needs no cap — it waits on
2392
+ * the wake pipe and fd 0 directly. */
2393
+ #define SCR_SIGNAL_POLL_MS 50.0
2394
+
2395
+ /* The external io hook (scr_runtime.h): the dynamic island registers
2396
+ * engine-job draining + fetch transfer polling here. Static builds never
2397
+ * set it — both slots stay NULL and the loop is byte-identical in
2398
+ * behavior. */
2399
+ static bool (*scr_io_pending_fn)(void) = NULL;
2400
+ static void (*scr_io_poll_fn)(double max_wait_ms) = NULL;
2401
+
2402
+ void scr_loop_set_io(bool (*pending)(void), void (*poll)(double)) {
2403
+ scr_io_pending_fn = pending;
2404
+ scr_io_poll_fn = poll;
2405
+ }
2406
+
2407
+ /* The island's earliest armed timer deadline (HUGE_VAL when none): caps
2408
+ * the sleep below so an armed AbortSignal.timeout fires on time while
2409
+ * the loop waits on socket readiness — without keeping the loop alive by
2410
+ * itself (the liveness test never consults it, Node's unref'd timer). */
2411
+ static double (*scr_island_deadline_fn)(void) = NULL;
2412
+
2413
+ void scr_loop_set_island_deadline(double (*fn)(void)) { scr_island_deadline_fn = fn; }
2414
+
2415
+ /* The net hook (scr_net.c, when linked — the events-hook shape):
2416
+ * `pending` keeps the loop alive while servers/sockets are live,
2417
+ * `dispatch` fires at every turn top, and `pollfd` is the unit's poller
2418
+ * fd for the idle poll(2) sleep (readable while events are pending —
2419
+ * kqueue and epoll fds both behave this way).
2420
+ * Net-free builds keep every slot NULL and the loop is byte-identical. */
2421
+ static bool (*scr_net_pending_fn)(void) = NULL;
2422
+ static void (*scr_net_dispatch_fn)(void) = NULL;
2423
+ static int (*scr_net_pollfd_fn)(void) = NULL;
2424
+
2425
+ void scr_loop_set_net(bool (*pending)(void), void (*dispatch)(void), int (*pollfd)(void)) {
2426
+ scr_net_pending_fn = pending;
2427
+ scr_net_dispatch_fn = dispatch;
2428
+ scr_net_pollfd_fn = pollfd;
2429
+ }
2430
+
2431
+ /* The dgram hook (scr_dgram.c, when linked) — the net hook's exact shape:
2432
+ * one more set of nullable slots, byte-identical loop behavior when
2433
+ * unset. */
2434
+ static bool (*scr_dgram_pending_fn)(void) = NULL;
2435
+ static void (*scr_dgram_dispatch_fn)(void) = NULL;
2436
+ static int (*scr_dgram_pollfd_fn)(void) = NULL;
2437
+
2438
+ void scr_loop_set_dgram(bool (*pending)(void), void (*dispatch)(void), int (*pollfd)(void)) {
2439
+ scr_dgram_pending_fn = pending;
2440
+ scr_dgram_dispatch_fn = dispatch;
2441
+ scr_dgram_pollfd_fn = pollfd;
2442
+ }
2443
+
2444
+ /* The fs.watch hook (scr_watch.c, when linked) — the net hook's exact
2445
+ * shape: one more set of nullable slots, byte-identical loop behavior
2446
+ * when unset. */
2447
+ static bool (*scr_watch_pending_fn)(void) = NULL;
2448
+ static void (*scr_watch_dispatch_fn)(void) = NULL;
2449
+ static int (*scr_watch_pollfd_fn)(void) = NULL;
2450
+
2451
+ void scr_loop_set_watch(bool (*pending)(void), void (*dispatch)(void), int (*pollfd)(void)) {
2452
+ scr_watch_pending_fn = pending;
2453
+ scr_watch_dispatch_fn = dispatch;
2454
+ scr_watch_pollfd_fn = pollfd;
2455
+ }
2456
+
2457
+ /* The foreign-FFI queue hook (scr_ffi.c when a format-5 descriptor exists).
2458
+ * Its pending count includes live registrations (reffed by default) and
2459
+ * queued deliveries; dispatch runs exactly one callback per loop turn. */
2460
+ static bool (*scr_ffi_pending_fn)(void) = NULL;
2461
+ static bool (*scr_ffi_dispatch_fn)(void) = NULL;
2462
+ static int (*scr_ffi_pollfd_fn)(void) = NULL;
2463
+ static void (*scr_ffi_stop_fn)(void) = NULL;
2464
+
2465
+ void scr_loop_set_ffi(bool (*pending)(void), bool (*dispatch)(void),
2466
+ int (*pollfd)(void), void (*stop)(void)) {
2467
+ scr_ffi_pending_fn = pending;
2468
+ scr_ffi_dispatch_fn = dispatch;
2469
+ scr_ffi_pollfd_fn = pollfd;
2470
+ scr_ffi_stop_fn = stop;
2471
+ }
2472
+
2473
+ /* The stream hook (scr_stream.c, when linked): `pending` keeps the loop
2474
+ * alive while deferred stream ticks exist, `dispatch` drains them at the
2475
+ * TOP of every turn — before the events/net stations, the closest
2476
+ * placement to Node's process.nextTick (whose stream emissions these
2477
+ * are). No poller fd: ticks are pure CPU work, always ready. */
2478
+ static bool (*scr_stream_pending_fn)(void) = NULL;
2479
+ static void (*scr_stream_dispatch_fn)(void) = NULL;
2480
+
2481
+ void scr_loop_set_stream(bool (*pending)(void), void (*dispatch)(void)) {
2482
+ scr_stream_pending_fn = pending;
2483
+ scr_stream_dispatch_fn = dispatch;
2484
+ }
2485
+
2486
+ /* Dispatch hooks yield between event batches when fibers are already
2487
+ * queued, so promise jobs interleave with event delivery (Node's
2488
+ * microtask checkpoints between macrotasks). */
2489
+ bool scr_loop_has_ready(void) { return scr_ready_len > 0; }
2490
+
2491
+ static bool scr_loop_run_pass(ScrPromise *top_level, bool first_checkpoint) {
2492
+ /* The FIRST checkpoint after the synchronous main body runs promise
2493
+ * jobs BEFORE the first tick drain: Node's main-module evaluation is
2494
+ * itself awaited (the runMain continuation is a microtask queued after
2495
+ * the body's own), so microtasks scheduled during the body beat ticks
2496
+ * scheduled during the body exactly once, at startup — differentially
2497
+ * pinned. Every later checkpoint drains ticks first. */
2498
+ bool rejection_failed = false;
2499
+ for (;;) {
2500
+ if (top_level != NULL && top_level->state == SCR_PROM_REJECTED) break;
2501
+ /* process.nextTick callbacks BEFORE promise jobs (Node's checkpoint
2502
+ * order): the tick queue to exhaustion, then the microtask queue to
2503
+ * exhaustion, and back while either has work — a microtask's
2504
+ * nextTick runs before the turn proceeds, but never preempts the
2505
+ * microtask queue mid-drain (V8 drains it fully). A tick's uncaught
2506
+ * throw ends the loop like any listener's (main reports it). */
2507
+ if (!first_checkpoint) {
2508
+ while (scr_nt_head != NULL) {
2509
+ ScrNtick *t = scr_nt_head;
2510
+ scr_nt_head = t->next;
2511
+ if (scr_nt_head == NULL) scr_nt_tail = NULL;
2512
+ ScrClosure *cb = t->cb;
2513
+ ScrFsRenameFn error_cb = t->error_cb;
2514
+ void (*raw)(void) = t->raw;
2515
+ free(t);
2516
+ if (cb) {
2517
+ if (error_cb) error_cb(cb, NULL);
2518
+ else ((void (*)(ScrClosure *))cb->fn)(cb);
2519
+ scr_closure_release(cb);
2520
+ } else {
2521
+ raw(); /* one stream tick, FIFO with the user ticks around it */
2522
+ }
2523
+ if (scr_exc_pending()) return false;
2524
+ }
2525
+ }
2526
+ /* Microtasks to exhaustion (Node: promise jobs before timers). */
2527
+ while (scr_ready_len > 0) {
2528
+ ScrFiber *f = scr_ready[scr_ready_head++];
2529
+ scr_ready_len--;
2530
+ scr_resume_fiber(f);
2531
+ }
2532
+ first_checkpoint = false;
2533
+ /* The ESM loader observes a rejected entry evaluation at a promise-job
2534
+ * checkpoint and terminates before later ref'd timers or I/O can run.
2535
+ * Wait until this checkpoint's ready queue is drained — the root's
2536
+ * rejection handler is itself promise-job ordered — then leave through
2537
+ * the normal teardown below. A fulfilled root deliberately does not
2538
+ * stop the loop. */
2539
+ if (top_level != NULL && top_level->state == SCR_PROM_REJECTED) break;
2540
+ if (scr_nt_head != NULL) continue;
2541
+ /* Node decides unhandled rejections at the END of each complete
2542
+ * nextTick/microtask checkpoint, before advancing to timers or I/O.
2543
+ * A rejected executable module root wins over OTHER rejections from
2544
+ * this same checkpoint (the root check above); rejections from an
2545
+ * earlier checkpoint have already delivered here. Handled listeners
2546
+ * may enqueue more jobs or ref'd work, so return to the checkpoint
2547
+ * head instead of declaring the loop exhausted underneath them. */
2548
+ if (scr_report_unhandled_rejections()) {
2549
+ rejection_failed = true;
2550
+ break;
2551
+ }
2552
+ if (scr_ready_len > 0 || scr_nt_head != NULL || scr_nunhandled > 0) continue;
2553
+ /* Quiescent between turns (microtasks drained, nothing running):
2554
+ * collect any cycles the turn left behind. One SCHEDULED pass — almost
2555
+ * always a nursery one, sized to the turn's own garbage. A full sweep
2556
+ * here would walk the whole live heap every turn, which is precisely
2557
+ * what the generations exist to avoid. No-op on an empty buffer. */
2558
+ scr_cyc_collect_scheduled();
2559
+ /* Completed callback-style worker jobs are delivered on the main
2560
+ * runtime thread. A worker may have finished while synchronous user code
2561
+ * occupied that thread. Deliver exactly one completion per checkpoint:
2562
+ * Node drains nextTicks and microtasks after each native callback before
2563
+ * invoking the next ready callback. */
2564
+ if (scr_fs_renames_pending()) {
2565
+ bool dispatched = scr_fs_renames_dispatch();
2566
+ if (scr_exc_pending()) return false;
2567
+ if (dispatched) continue;
2568
+ }
2569
+ if (scr_crypto_bytes_pending()) {
2570
+ bool dispatched = scr_crypto_bytes_dispatch();
2571
+ if (scr_exc_pending()) return false;
2572
+ if (dispatched) continue;
2573
+ }
2574
+ /* Foreign native callbacks are macrotasks. Deliver one, then restart at
2575
+ * the microtask checkpoint before considering the next queued post. */
2576
+ if (scr_ffi_dispatch_fn != NULL && scr_ffi_dispatch_fn()) {
2577
+ if (scr_exc_pending()) return false;
2578
+ if (scr_ready_len > 0 || scr_nt_head != NULL || scr_nunhandled > 0) continue;
2579
+ }
2580
+ /* Stream tick dispatch (scr_stream.c, when linked): the deferred
2581
+ * next-tick emissions ('data' flow kicks, 'readable'/'end'/'finish'/
2582
+ * 'drain'/'error'/'close') fire now, FIRST — the nextTick station.
2583
+ * Listeners may enqueue microtasks or more ticks — restart the turn
2584
+ * so those drain first. */
2585
+ if (scr_stream_dispatch_fn != NULL) {
2586
+ scr_stream_dispatch_fn();
2587
+ if (scr_exc_pending()) return false; /* uncaught throw in a listener */
2588
+ if (scr_ready_len > 0) continue;
2589
+ if (scr_stream_pending_fn != NULL && scr_stream_pending_fn()) continue;
2590
+ }
2591
+ /* Event dispatch (scr_events.c, when linked): watched signals
2592
+ * delivered since the last turn fire their listeners now (macrotasks,
2593
+ * like timers), then stdin — while a consumer exists, probe fd 0 and
2594
+ * deliver one arrived chunk / the EOF events. Both may enqueue
2595
+ * microtasks — restart the turn so those drain first. */
2596
+ if (scr_events_dispatch_fn != NULL) {
2597
+ scr_events_dispatch_fn();
2598
+ if (scr_exc_pending()) return false; /* uncaught throw in a listener */
2599
+ if (scr_ready_len > 0) continue;
2600
+ }
2601
+ /* Net dispatch (scr_net.c, when linked): accepts, arrived data,
2602
+ * connect completions, and the deferred listening/error/close emits
2603
+ * fire now (macrotasks, like the events hook). Callbacks may enqueue
2604
+ * microtasks — restart the turn so those drain first. */
2605
+ if (scr_net_dispatch_fn != NULL) {
2606
+ scr_net_dispatch_fn();
2607
+ if (scr_exc_pending()) return false; /* uncaught throw in a listener */
2608
+ if (scr_ready_len > 0) continue;
2609
+ }
2610
+ /* Dgram dispatch (scr_dgram.c, when linked): arrived datagrams and
2611
+ * the deferred listening/connect/error/close emits (plus pending
2612
+ * dns.lookup callbacks) fire now — the net hook's exact station. */
2613
+ if (scr_dgram_dispatch_fn != NULL) {
2614
+ scr_dgram_dispatch_fn();
2615
+ if (scr_exc_pending()) return false; /* uncaught throw in a listener */
2616
+ if (scr_ready_len > 0) continue;
2617
+ }
2618
+ /* Watch dispatch (scr_watch.c, when linked): file events queued on
2619
+ * the unit's event backend fire their FSWatcher listeners now — the
2620
+ * net hook's exact station. */
2621
+ if (scr_watch_dispatch_fn != NULL) {
2622
+ scr_watch_dispatch_fn();
2623
+ if (scr_exc_pending()) return false; /* uncaught throw in a listener */
2624
+ if (scr_ready_len > 0) continue;
2625
+ }
2626
+ /* Reap spawned children and fire their listeners (before timers,
2627
+ * like Node's nextTick-ish spawn-failure "error"). A callback may
2628
+ * enqueue microtasks or spawn again — restart the turn if so.
2629
+ * EXCEPT when ONLY unref'd children remain: Node's liveness check
2630
+ * precedes any further poll/reap, so once nothing reffed holds the
2631
+ * loop their pending exits are DROPPED at loop exit — never
2632
+ * delivered. Without this gate the kill-then-exit shape (a timer's
2633
+ * last act kills an unref'd child) would race machine timing: a
2634
+ * death landing before this sweep fired its 'exit' where Node
2635
+ * deterministically never does. The teardown below releases the
2636
+ * undelivered listeners, so the RC audit stays clean. */
2637
+ if (scr_children_pending()) {
2638
+ bool held =
2639
+ scr_reffed_timers > 0 || scr_reffed_immediates > 0 || scr_children_reffed_pending() ||
2640
+ /* spawn failures settle regardless: their 'error' is a
2641
+ * next-tick event, delivered even on an unref'd child */
2642
+ scr_children_failed_pending() ||
2643
+ (scr_io_pending_fn != NULL && scr_io_pending_fn()) ||
2644
+ (scr_events_pending_fn != NULL && scr_events_pending_fn()) ||
2645
+ (scr_net_pending_fn != NULL && scr_net_pending_fn()) ||
2646
+ (scr_dgram_pending_fn != NULL && scr_dgram_pending_fn()) ||
2647
+ (scr_watch_pending_fn != NULL && scr_watch_pending_fn()) ||
2648
+ (scr_ffi_pending_fn != NULL && scr_ffi_pending_fn()) ||
2649
+ scr_fs_renames_pending() || scr_crypto_bytes_pending();
2650
+ if (held) {
2651
+ scr_children_poll();
2652
+ if (scr_exc_pending()) return false; /* uncaught throw in a listener */
2653
+ if (scr_ready_len > 0) continue;
2654
+ }
2655
+ }
2656
+ /* Deferred stream ticks are always-ready work: never sleep or exit
2657
+ * while any exist (the dispatch above drains them, so reaching here
2658
+ * with ticks pending means a dispatch station enqueued more). User
2659
+ * nextTicks enqueued by a station listener are the same story. */
2660
+ if (scr_stream_pending_fn != NULL && scr_stream_pending_fn()) continue;
2661
+ if (scr_nt_head != NULL) continue;
2662
+ bool kids = scr_children_pending();
2663
+ bool io = scr_io_pending_fn != NULL && scr_io_pending_fn();
2664
+ bool events = scr_events_pending_fn != NULL && scr_events_pending_fn();
2665
+ bool net = scr_net_pending_fn != NULL && scr_net_pending_fn();
2666
+ bool dgram = scr_dgram_pending_fn != NULL && scr_dgram_pending_fn();
2667
+ bool watch = scr_watch_pending_fn != NULL && scr_watch_pending_fn();
2668
+ bool ffi = scr_ffi_pending_fn != NULL && scr_ffi_pending_fn();
2669
+ bool renames = scr_fs_renames_pending();
2670
+ bool crypto = scr_crypto_bytes_pending();
2671
+ /* Timer liveness counts only REF'd timers: an unref'd timer stays in
2672
+ * the heap (and fires if the loop runs on for other reasons) but does
2673
+ * not by itself keep the process alive — Node's unref semantics.
2674
+ * Children follow the same rule: an unref'd child is still REAPED
2675
+ * while the loop runs (kids drives the sweeps and sleeps above) but
2676
+ * only reffed ones keep the process alive. */
2677
+ if (scr_reffed_timers == 0 && scr_reffed_immediates == 0 && !scr_children_reffed_pending() && !io && !events && !net && !dgram && !watch && !ffi && !renames && !crypto) break;
2678
+ /* Sleep to the earliest deadline, then run every due timer (each may
2679
+ * enqueue microtasks, which the next iteration drains first). Who
2680
+ * sleeps depends on what is pending:
2681
+ * - external io: the io POLL takes the sleep — it waits on real fds
2682
+ * up to the deadline (socket readiness wakes it early) and makes
2683
+ * progress (engine jobs, arrived response data) before timers run.
2684
+ * A child's exit can't wake curl's fds, so children re-impose the
2685
+ * reap-granularity cap on this path.
2686
+ * - signals watched or stdin consumed: poll(2) takes the sleep — the
2687
+ * wake pipe, fd 0, and the child watch's fd together, so any of
2688
+ * them ends it immediately (details at the branch).
2689
+ * - children only: the sleep waits on the child watch — the exit
2690
+ * wakeup and the timer deadline together via the wait timeout — so a
2691
+ * child's exit ends the sleep immediately and the next turn's reap
2692
+ * pass fires its listeners. scr_children_wait declines when it
2693
+ * can't wake for every pending child; the ~1ms polling cap is the
2694
+ * fallback.
2695
+ * - timers only: plain nanosleep to the deadline. */
2696
+ double now = scr_now_ms();
2697
+ double due = scr_ntimers > 0 ? scr_timers[0].deadline_ms : now + SCR_IO_POLL_MS;
2698
+ /* The worker pool has no platform poll handle yet. Bound the idle
2699
+ * wait exactly like the portable child fallback so completion is noticed
2700
+ * promptly even when another poller owns the sleep. */
2701
+ if (renames && due > now + SCR_CHILD_POLL_MS) due = now + SCR_CHILD_POLL_MS;
2702
+ /* An armed island timer (AbortSignal.timeout) caps the sleep: it must
2703
+ * fire on time even while the poller waits on socket readiness. */
2704
+ if (scr_island_deadline_fn != NULL) {
2705
+ double isl_due = scr_island_deadline_fn();
2706
+ if (isl_due < due) due = isl_due;
2707
+ }
2708
+ /* Pending immediates are always-ready work: no sleep — run due timers
2709
+ * (Node's timers phase precedes check), then the check phase below. */
2710
+ if (scr_pending_immediates > 0) due = now;
2711
+ /* Child polling can drain a pipe into the IPC queue after its dispatch
2712
+ * station has run. Completed sends and disconnects can also become ready
2713
+ * during that turn. No fd will wake us for this userspace work: return to
2714
+ * dispatch without sleeping, still allowing due timers and immediates. */
2715
+ if (scr_children_ready()) due = now;
2716
+ #if !defined(_WIN32) && !defined(__wasi__)
2717
+ if (due > now) scr_fiber_stacks_clear();
2718
+ #endif
2719
+ bool evw = scr_events_watching_fn != NULL && scr_events_watching_fn();
2720
+ if (io) {
2721
+ if (kids && due > now + SCR_CHILD_POLL_MS) due = now + SCR_CHILD_POLL_MS;
2722
+ /* Signals/stdin/net can't wake curl's fd wait (and its poll retries
2723
+ * on EINTR), so they re-impose a coarser cap — bounded Ctrl-C and
2724
+ * socket latency during a fetch, without the reap-granularity
2725
+ * cost. */
2726
+ else if ((evw || net || dgram || watch || ffi) && due > now + SCR_SIGNAL_POLL_MS) due = now + SCR_SIGNAL_POLL_MS;
2727
+ scr_io_poll_fn(due > now ? due - now : 0);
2728
+ now = scr_now_ms();
2729
+ if (scr_ready_len > 0) continue; /* io callbacks woke fibers */
2730
+ } else if (evw || net || dgram || watch || ffi) {
2731
+ #if defined(_WIN32) || defined(__wasi__)
2732
+ /* The win32 arm, and WASI hosts whose poll_oneoff adapters do not
2733
+ * reliably wake for a closed inherited stdin pipe: the sleep is a capped nanosleep and
2734
+ * the next turn's dispatch does the work — signal flags (set by the
2735
+ * CRT handler on msvcrt's console-ctrl thread) and the stdin probe
2736
+ * at SCR_SIGNAL_POLL_MS granularity (scr_events.c), socket/dgram
2737
+ * readiness at the child-reap cap (scr_loop_wsapoll.c's zero-timeout
2738
+ * WSAPoll drains at dispatch; ~1ms keeps loopback exchanges inside
2739
+ * the granularity Node's IOCP-woken loop delivers, where 50ms could
2740
+ * reorder a socket emit past a short timer). When the caps ever
2741
+ * show up in a profile, the upgrade is a real waitable arm —
2742
+ * WaitForMultipleObjects over WSAEVENTs, or IOCP. */
2743
+ if (evw && due > now + SCR_SIGNAL_POLL_MS) due = now + SCR_SIGNAL_POLL_MS;
2744
+ if ((net || dgram || watch) && due > now + SCR_CHILD_POLL_MS) due = now + SCR_CHILD_POLL_MS;
2745
+ if (ffi && due > now + SCR_CHILD_POLL_MS) due = now + SCR_CHILD_POLL_MS;
2746
+ if (kids && due > now + SCR_CHILD_POLL_MS) due = now + SCR_CHILD_POLL_MS;
2747
+ if (due > now) {
2748
+ double wait = due - now;
2749
+ struct timespec ts = {(time_t)(wait / 1000.0), (long)((wait - (double)((time_t)(wait / 1000.0)) * 1000.0) * 1e6)};
2750
+ nanosleep(&ts, NULL);
2751
+ }
2752
+ now = scr_now_ms();
2753
+ #else
2754
+ /* poll(2) takes the sleep: the events unit's fds — the signal wake
2755
+ * pipe (a signal delivered BEFORE the poll entered still has its
2756
+ * byte in the pipe — no lost-wakeup race) and fd 0 while stdin has
2757
+ * a consumer — plus the child watch's fd when it can represent
2758
+ * every pending child (kqueue and epoll fds poll readable when
2759
+ * events are pending); unrepresentable children keep the ~1ms reap cap
2760
+ * instead. Dispatch happens at the next turn's top — the poll only
2761
+ * decides how long to sleep. */
2762
+ struct pollfd fds[7];
2763
+ int nfds = 0;
2764
+ int evfds[2];
2765
+ int nev = evw && scr_events_pollfds_fn != NULL ? scr_events_pollfds_fn(evfds) : 0;
2766
+ for (int i = 0; i < nev; i++) {
2767
+ fds[nfds].fd = evfds[i];
2768
+ fds[nfds].events = POLLIN;
2769
+ fds[nfds++].revents = 0;
2770
+ }
2771
+ if (net) {
2772
+ /* The net unit's poller fd: readable while socket events are
2773
+ * pending, so arrived data/accepts end the sleep immediately.
2774
+ * Dispatch (which also DRAINS the poller) happens at the next
2775
+ * turn's top — the poll only decides how long to sleep. */
2776
+ int nfd = scr_net_pollfd_fn != NULL ? scr_net_pollfd_fn() : -1;
2777
+ if (nfd >= 0) {
2778
+ fds[nfds].fd = nfd;
2779
+ fds[nfds].events = POLLIN;
2780
+ fds[nfds++].revents = 0;
2781
+ } else if (due > now + SCR_SIGNAL_POLL_MS) {
2782
+ due = now + SCR_SIGNAL_POLL_MS;
2783
+ }
2784
+ }
2785
+ if (dgram) {
2786
+ /* The dgram unit's poller fd — the net slot's exact story. */
2787
+ int dfd = scr_dgram_pollfd_fn != NULL ? scr_dgram_pollfd_fn() : -1;
2788
+ if (dfd >= 0) {
2789
+ fds[nfds].fd = dfd;
2790
+ fds[nfds].events = POLLIN;
2791
+ fds[nfds++].revents = 0;
2792
+ } else if (due > now + SCR_SIGNAL_POLL_MS) {
2793
+ due = now + SCR_SIGNAL_POLL_MS;
2794
+ }
2795
+ }
2796
+ if (watch) {
2797
+ /* The watch unit's event fd — the net slot's exact story. */
2798
+ int wfd = scr_watch_pollfd_fn != NULL ? scr_watch_pollfd_fn() : -1;
2799
+ if (wfd >= 0) {
2800
+ fds[nfds].fd = wfd;
2801
+ fds[nfds].events = POLLIN;
2802
+ fds[nfds++].revents = 0;
2803
+ } else if (due > now + SCR_SIGNAL_POLL_MS) {
2804
+ due = now + SCR_SIGNAL_POLL_MS;
2805
+ }
2806
+ }
2807
+ if (ffi) {
2808
+ int ffd = scr_ffi_pollfd_fn != NULL ? scr_ffi_pollfd_fn() : -1;
2809
+ if (ffd >= 0) {
2810
+ fds[nfds].fd = ffd;
2811
+ fds[nfds].events = POLLIN;
2812
+ fds[nfds++].revents = 0;
2813
+ } else if (due > now + SCR_CHILD_POLL_MS) {
2814
+ due = now + SCR_CHILD_POLL_MS;
2815
+ }
2816
+ }
2817
+ if (kids) {
2818
+ int cfd = scr_children_wake_fd();
2819
+ if (cfd >= 0) {
2820
+ fds[nfds].fd = cfd;
2821
+ fds[nfds].events = POLLIN;
2822
+ fds[nfds++].revents = 0;
2823
+ } else if (due > now + SCR_CHILD_POLL_MS) {
2824
+ due = now + SCR_CHILD_POLL_MS;
2825
+ }
2826
+ }
2827
+ double wait = due > now ? due - now : 0;
2828
+ if (wait > 1e9) wait = 1e9; /* poll takes int ms */
2829
+ (void)poll(fds, (nfds_t)nfds, (int)(wait + 0.999));
2830
+ /* Consume queued child-exit events NOW (zero-timeout drain) — an
2831
+ * unconsumed event keeps the kqueue fd readable and would turn the
2832
+ * next poll into a busy spin while other children still run. The
2833
+ * WNOHANG sweep at the next turn's top stays the reaper. */
2834
+ if (kids) (void)scr_children_wait(0);
2835
+ now = scr_now_ms();
2836
+ #endif /* !_WIN32 && !__wasi__ */
2837
+ } else if (kids && scr_children_wait(due > now ? due - now : 0)) {
2838
+ now = scr_now_ms(); /* woke early on an exit, or hit the deadline */
2839
+ } else {
2840
+ if (kids && due > now + SCR_CHILD_POLL_MS) due = now + SCR_CHILD_POLL_MS;
2841
+ if (due > now) {
2842
+ double wait = due - now;
2843
+ struct timespec ts = {(time_t)(wait / 1000.0), (long)((wait - (double)((time_t)(wait / 1000.0)) * 1000.0) * 1e6)};
2844
+ nanosleep(&ts, NULL);
2845
+ now = due;
2846
+ }
2847
+ }
2848
+ while (scr_ntimers > 0 && scr_timers[0].deadline_ms <= now) {
2849
+ ScrTimer t = scr_timer_pop();
2850
+ /* Timer callbacks are plain sync closures, run on the main stack.
2851
+ * An interval entry is OUT of the heap while its callback runs;
2852
+ * clearInterval(its own id) from inside sets the firing flag and
2853
+ * the re-arm below drops it instead. A throw kills the interval
2854
+ * with the program (Node: the uncaught exception ends the process
2855
+ * before any rescheduled tick could run). */
2856
+ if (t.id != 0) {
2857
+ scr_firing_id = t.id;
2858
+ scr_firing_cleared = false;
2859
+ scr_firing_reffed = t.reffed; /* unref/ref during the callback lands here */
2860
+ scr_firing_refresh = false;
2861
+ }
2862
+ ((void (*)(ScrClosure *))t.cb->fn)(t.cb);
2863
+ if (t.id != 0 && t.repeat_ms > 0 && !scr_firing_cleared) {
2864
+ /* Re-arm relative to the post-callback clock (libuv's uv_timer
2865
+ * repeat behavior: no catch-up bursts after a slow callback). The
2866
+ * ref state carries across ticks (a self-unref'd interval stays
2867
+ * unref'd). */
2868
+ ScrTimer again = {scr_now_ms() + t.repeat_ms, scr_timer_seq++, t.cb, t.repeat_ms, t.id, scr_firing_reffed, t.delay_ms};
2869
+ scr_timer_push(again);
2870
+ } else if (t.id != 0 && scr_firing_refresh && !scr_firing_cleared) {
2871
+ /* refresh() from inside the one-shot's own callback: re-arm to
2872
+ * now + the original delay, ref state carried (Node's
2873
+ * Timeout.refresh — the timer fires again). */
2874
+ ScrTimer again = {scr_now_ms() + t.delay_ms, scr_timer_seq++, t.cb, 0, t.id, scr_firing_reffed, t.delay_ms};
2875
+ scr_timer_push(again);
2876
+ } else {
2877
+ scr_closure_release(t.cb);
2878
+ }
2879
+ scr_firing_id = 0;
2880
+ if (scr_exc_pending()) return false; /* uncaught throw in a callback: main handles it */
2881
+ if (scr_ready_len > 0) break; /* drain microtasks before more timers */
2882
+ }
2883
+ /* The check phase: immediates queued BEFORE this phase started run
2884
+ * now, FIFO; ones a callback queues wait for the next turn (the end
2885
+ * snapshot — Node's once-per-turn rule, so a setImmediate chain can't
2886
+ * starve the loop). Cleared slots (cb NULL) skip. Microtasks drain
2887
+ * between callbacks, like Node's inter-macrotask checkpoints; a woken
2888
+ * fiber restarts the turn first (the timer loop's break above), so the
2889
+ * phase only runs on a drained queue. */
2890
+ if (scr_ready_len == 0 && scr_pending_immediates > 0) {
2891
+ size_t end = scr_nimmediates;
2892
+ while (scr_immediates_head < end) {
2893
+ size_t i = scr_immediates_head++;
2894
+ ScrClosure *cb = scr_immediates[i].cb;
2895
+ if (cb == NULL) continue; /* cleared */
2896
+ scr_immediates[i].cb = NULL; /* fired: clear/ref/unref on this id no-op now */
2897
+ if (scr_pending_immediates > 0) scr_pending_immediates--;
2898
+ if (scr_immediates[i].reffed) {
2899
+ scr_immediates[i].reffed = false;
2900
+ if (scr_reffed_immediates > 0) scr_reffed_immediates--;
2901
+ }
2902
+ ((void (*)(ScrClosure *))cb->fn)(cb);
2903
+ scr_closure_release(cb);
2904
+ if (scr_exc_pending()) return false; /* uncaught throw: main handles it */
2905
+ while (scr_ready_len > 0) {
2906
+ ScrFiber *f = scr_ready[scr_ready_head++];
2907
+ scr_ready_len--;
2908
+ scr_resume_fiber(f);
2909
+ }
2910
+ if (top_level != NULL && top_level->state == SCR_PROM_REJECTED) break;
2911
+ }
2912
+ /* Fully drained: reset the cursor so the array reuses its slots. */
2913
+ if (scr_immediates_head == scr_nimmediates) {
2914
+ scr_immediates_head = 0;
2915
+ scr_nimmediates = 0;
2916
+ }
2917
+ }
2918
+ }
2919
+ return rejection_failed;
2920
+ }
2921
+
2922
+ bool scr_loop_run(ScrPromise *top_level) {
2923
+ bool first_checkpoint = true;
2924
+ bool rejection_failed;
2925
+ for (;;) {
2926
+ rejection_failed = scr_loop_run_pass(top_level && !top_level->top_level_handled ? top_level : NULL, first_checkpoint);
2927
+ first_checkpoint = false;
2928
+ if (scr_exc_pending()) {
2929
+ if (scr_exc_handle_uncaught(false)) continue;
2930
+ break; /* main reports the original or handler-thrown exception */
2931
+ }
2932
+ if (rejection_failed) break;
2933
+ if (top_level && top_level->state == SCR_PROM_REJECTED && !top_level->top_level_handled) {
2934
+ scr_promise_rethrow(top_level);
2935
+ if (scr_exc_handle_uncaught(true)) {
2936
+ top_level->top_level_handled = true;
2937
+ scr_prom_observe(top_level);
2938
+ continue;
2939
+ }
2940
+ scr_discard_unhandled_rejections();
2941
+ break;
2942
+ }
2943
+ break;
2944
+ }
2945
+ /* Exit can now leave UNREF'd timers armed in the heap (ordinary
2946
+ * exhaustion, a fatal module root, or an unhandled rejection). They
2947
+ * never fire, so release their closures here or the RC audit counts
2948
+ * them as leaks. Uncaught callback throws still return above for main
2949
+ * to report through the existing exceptional teardown path. */
2950
+ scr_timers_teardown();
2951
+ /* No reffed foreign registration or queued invocation remains at ordinary
2952
+ * exhaustion. Disarm posting before exit listeners/global teardown so a
2953
+ * straggling native thread becomes a safe silent drop. */
2954
+ if (scr_ffi_stop_fn != NULL) scr_ffi_stop_fn();
2955
+ /* Retained native FFI registrations are deliberately NOT torn down
2956
+ * here: process 'exit' listeners run after the loop returns (inline in
2957
+ * main, before any atexit handler) and may legitimately release a
2958
+ * registration or pump a native library one last time — exactly like
2959
+ * the process.exit() path, where the ledger is also still intact. On
2960
+ * returns that reach atexit, the sweep scr_ffi_retain registered (LIFO
2961
+ * before the RC audit) then drops the ledger's references. It does NOT
2962
+ * run on process.exit(): scr_process_exit ends in _Exit, skipping every
2963
+ * atexit handler — the sweep and the RC audit alike — and leaves the
2964
+ * ledger to the OS. */
2965
+ /* Unref'd children the loop never reaped: release the
2966
+ * registry's references (their listeners never fire — the process is
2967
+ * exiting, Node's behavior; the OS reparents the children). */
2968
+ scr_children_teardown();
2969
+ scr_fibers_abandoned = scr_fibers_live;
2970
+ scr_note_abandoned_fibers(scr_fibers_abandoned);
2971
+ return rejection_failed;
2972
+ }
2973
+
2974
+ /* The island's half of the unhandled-rejection report (scr_island.c
2975
+ * registers it at engine boot): called with print=true when the static
2976
+ * ledger below reported nothing — one report, one voice, like Node's
2977
+ * first-unhandled-rejection death. Returns whether the island had any.
2978
+ * Static builds never set it. */
2979
+ static bool (*scr_island_rejections_fn)(bool print) = NULL;
2980
+ static int (*scr_island_jobs_drain_fn)(void) = NULL;
2981
+
2982
+ void scr_loop_set_island_rejections(bool (*fn)(bool print),
2983
+ int (*drain_jobs)(void)) {
2984
+ scr_island_rejections_fn = fn;
2985
+ scr_island_jobs_drain_fn = drain_jobs;
2986
+ }
2987
+
2988
+ /* ── process.on('unhandledRejection') ─────────────────────────────────
2989
+ * Dyn listeners are called per never-observed rejection at the completed
2990
+ * nextTick/microtask checkpoint. A registered listener suppresses the
2991
+ * default report and exit 1, exactly Node's handled-event contract. */
2992
+
2993
+ /* The unhandled-rejection LISTENER hook (scr_async_dyn.c installs it at
2994
+ * registration — the loop-hook pattern, so listener-free binaries keep
2995
+ * their size class): called per never-observed rejection; false = a
2996
+ * listener threw (the uncaught crash path). */
2997
+ bool (*scr_urj_deliver_fn)(ScrPromise *p) = NULL;
2998
+
2999
+ /* Unhandled rejections at a completed nextTick/microtask checkpoint:
3000
+ * Node prints an error and exits 1 when no listener handles the event.
3001
+ * Snapshot the ledger: a listener can reject another promise, but that
3002
+ * new rejection belongs to the NEXT checkpoint rather than this report. */
3003
+ bool scr_report_unhandled_rejections(void) {
3004
+ /* Static fibers drain before engine jobs in this runtime's documented
3005
+ * island ordering. Complete BOTH halves of that microtask checkpoint
3006
+ * before deciding either rejection ledger; engine reactions can attach
3007
+ * a handler to a rejection that would otherwise look unhandled here.
3008
+ * A host callback can wake a static fiber/tick, in which case the loop
3009
+ * must drain that work before reporting too. */
3010
+ if (scr_island_jobs_drain_fn != NULL) {
3011
+ scr_island_jobs_drain_fn();
3012
+ if (scr_ready_len > 0 || scr_nt_head != NULL) return false;
3013
+ }
3014
+ bool any = false;
3015
+ bool crashed = false;
3016
+ size_t report_count = scr_nunhandled;
3017
+ for (size_t i = 0; i < report_count; i++) {
3018
+ ScrPromise *p = scr_maybe_unhandled[i];
3019
+ if (p->state == SCR_PROM_REJECTED && !p->rejection_observed && !crashed) {
3020
+ if (scr_urj_deliver_fn != NULL) {
3021
+ /* Listener dispatch (scr_async_dyn.c installed the hook at
3022
+ * registration): the event handles it, like Node — per entry,
3023
+ * no report, exit 0. A listener throw is the uncaught crash.
3024
+ * reported_unhandled arms the 'rejectionHandled' window: a
3025
+ * handler the listener itself attaches fires the sibling event
3026
+ * (scr_prom_observe). */
3027
+ p->rejection_observed = true;
3028
+ p->reported_unhandled = true;
3029
+ if (!scr_urj_deliver_fn(p) && !scr_exc_handle_uncaught(false)) crashed = true;
3030
+ } else if (scr_uncaught_exception_hook != NULL) {
3031
+ scr_promise_rethrow(p);
3032
+ if (scr_exc_handle_uncaught(true)) {
3033
+ p->rejection_observed = true;
3034
+ p->reported_unhandled = true;
3035
+ } else {
3036
+ crashed = true;
3037
+ }
3038
+ } else if (!any) {
3039
+ any = true;
3040
+ fflush(stdout);
3041
+ fputs("Unhandled promise rejection: ", stderr);
3042
+ switch (p->payload_kind) {
3043
+ case SCR_EXC_F64: {
3044
+ char buf[32];
3045
+ scr_f64_to_str(p->f64, buf);
3046
+ fputs(buf, stderr);
3047
+ break;
3048
+ }
3049
+ case SCR_EXC_BOOL: fputs(p->b ? "true" : "false", stderr); break;
3050
+ case SCR_EXC_STR: fputs(((ScrStr *)p->payload)->data, stderr); break;
3051
+ case SCR_EXC_OBJ:
3052
+ /* Error rejections render "name: message", like the uncaught path. */
3053
+ if (scr_error_is(p->payload)) {
3054
+ ScrStr *s = scr_error_to_string((ScrError *)p->payload);
3055
+ fwrite(s->data, 1, s->len, stderr);
3056
+ scr_str_release(s);
3057
+ break;
3058
+ }
3059
+ /* fall through */
3060
+ default: fputs("[object]", stderr); break;
3061
+ }
3062
+ fputc('\n', stderr);
3063
+ }
3064
+ }
3065
+ scr_promise_release(p);
3066
+ }
3067
+ size_t remaining = scr_nunhandled - report_count;
3068
+ if (remaining > 0) {
3069
+ memmove(scr_maybe_unhandled, scr_maybe_unhandled + report_count,
3070
+ remaining * sizeof *scr_maybe_unhandled);
3071
+ }
3072
+ scr_nunhandled = remaining;
3073
+ if (crashed) {
3074
+ scr_exc_print_uncaught();
3075
+ return true;
3076
+ }
3077
+ if (scr_island_rejections_fn != NULL) {
3078
+ bool island = scr_island_rejections_fn(!any);
3079
+ any = any || island;
3080
+ }
3081
+ /* main returns 1 on a reported rejection — the 'exit' listeners (atexit)
3082
+ * must see that code, like Node's. */
3083
+ if (any) scr_exit_code_note(1);
3084
+ return any;
3085
+ }
3086
+
3087
+ /* A fatal executable-module rejection suppresses unrelated rejections
3088
+ * created in the SAME checkpoint. Drop their retained ledger references
3089
+ * without delivering process events or a competing default report. */
3090
+ void scr_discard_unhandled_rejections(void) {
3091
+ for (size_t i = 0; i < scr_nunhandled; i++) {
3092
+ scr_promise_release(scr_maybe_unhandled[i]);
3093
+ }
3094
+ scr_nunhandled = 0;
3095
+ }
3096
+
3097
+ /* ── new Promise(executor) ────────────────────────────────────────────── */
3098
+
3099
+ /* resolve closures: caps[0] is a box whose slot holds the promise (+1). */
3100
+ static ScrPromise *scr_resolve_target(ScrClosure *self) {
3101
+ return (ScrPromise *)scr_box_get_ref(self->caps[0]);
3102
+ }
3103
+ static void scr_resolve_thunk_f64(ScrClosure *self, double v) {
3104
+ ScrPromise *p = scr_resolve_target(self);
3105
+ scr_promise_fulfill_f64(p, v);
3106
+ scr_promise_release(p);
3107
+ }
3108
+ static void scr_resolve_thunk_bool(ScrClosure *self, bool v) {
3109
+ ScrPromise *p = scr_resolve_target(self);
3110
+ scr_promise_fulfill_bool(p, v);
3111
+ scr_promise_release(p);
3112
+ }
3113
+ static void scr_resolve_thunk_str(ScrClosure *self, ScrStr *v) {
3114
+ ScrPromise *p = scr_resolve_target(self);
3115
+ scr_promise_fulfill_str(p, v); /* callee owns its params: moves in */
3116
+ scr_promise_release(p);
3117
+ }
3118
+ static void scr_resolve_thunk_void(ScrClosure *self) {
3119
+ ScrPromise *p = scr_resolve_target(self);
3120
+ scr_promise_fulfill_void(p);
3121
+ scr_promise_release(p);
3122
+ }
3123
+ /* Ref payloads: emitted code passes the concrete retain/release via a
3124
+ * second box slot? Keep simple: ref resolve thunks are monomorphized by the
3125
+ * EMITTER (it knows the arm type) — it emits a tiny static thunk calling
3126
+ * scr_promise_fulfill_ref with the concrete helpers, wrapped over caps[0].
3127
+ * The runtime provides only the scalar/str/void thunks. */
3128
+
3129
+ ScrClosure *scr_make_resolve(ScrPromise *p, int kind /*0 f64,1 bool,2 str,3 void*/) {
3130
+ void *fns[4] = {(void *)&scr_resolve_thunk_f64, (void *)&scr_resolve_thunk_bool,
3131
+ (void *)&scr_resolve_thunk_str, (void *)&scr_resolve_thunk_void};
3132
+ ScrClosure *c = scr_closure_new(fns[kind], 1);
3133
+ ScrBox *b = scr_box_new_obj(scr_promise_retain_v, scr_promise_release_v,
3134
+ scr_promise_trace_v);
3135
+ scr_box_set_ref(b, scr_promise_retain(p));
3136
+ c->caps[0] = b;
3137
+ return c;
3138
+ }
3139
+
3140
+ /* Emitted ref-kind resolve thunks call this. */
3141
+ void scr_resolve_ref_impl(ScrClosure *self, void *v, void *(*retain)(void *), void (*release)(void *), ScrTraceFn trace) {
3142
+ ScrPromise *p = scr_resolve_target(self);
3143
+ scr_promise_fulfill_ref(p, v, retain, release, trace);
3144
+ scr_promise_release(p);
3145
+ }
3146
+
3147
+ /* ── emitter support ──────────────────────────────────────────────────── */
3148
+
3149
+ ScrPromise *scr_fiber_promise(ScrFiber *f) { return f->promise; }
3150
+
3151
+ /* Generalized resolve construction: `fn` is an emitted thunk with closure
3152
+ * calling convention (self, value) that forwards to scr_resolve_ref_impl
3153
+ * with the concrete RC helpers. */
3154
+ ScrClosure *scr_make_resolve_fn(ScrPromise *p, void *fn) {
3155
+ ScrClosure *c = scr_closure_new(fn, 1);
3156
+ ScrBox *b = scr_box_new_obj(scr_promise_retain_v, scr_promise_release_v,
3157
+ scr_promise_trace_v);
3158
+ scr_box_set_ref(b, scr_promise_retain(p));
3159
+ c->caps[0] = b;
3160
+ return c;
3161
+ }
3162
+
3163
+ /* ── reject closures (new Promise((resolve, reject) => ...)) ──────────
3164
+ * Mirror of the resolve closures: caps[0] is a box whose slot holds the
3165
+ * promise (+1). The reason is always an Error-hierarchy instance (the
3166
+ * frontend pins the reject parameter to `(reason: Error) => void`), and it
3167
+ * stores as SCR_EXC_OBJ — exactly the thrown-Error representation — so an
3168
+ * await rethrows it, catch-side instanceof answers, and the uncaught
3169
+ * printer prints "name: message". First settle wins, exactly JS: reject
3170
+ * after any settle (resolve-then-reject, double reject) releases the
3171
+ * reason and does nothing. The closure calling convention makes the thunk
3172
+ * own its param, like every compiled callee. */
3173
+ static void scr_reject_thunk(ScrClosure *self, ScrError *reason) {
3174
+ ScrPromise *p = scr_resolve_target(self);
3175
+ if (p->state != SCR_PROM_PENDING) {
3176
+ scr_error_release(reason);
3177
+ } else {
3178
+ p->state = SCR_PROM_REJECTED;
3179
+ p->payload_kind = SCR_EXC_OBJ;
3180
+ p->payload = reason; /* ownership moves in */
3181
+ p->retain_fn = scr_error_retain_v;
3182
+ p->release_fn = scr_error_release_v;
3183
+ p->trace_fn = scr_error_trace_arg();
3184
+ scr_promise_settle_wake(p);
3185
+ }
3186
+ scr_promise_release(p);
3187
+ }
3188
+
3189
+ ScrClosure *scr_make_reject(ScrPromise *p) {
3190
+ ScrClosure *c = scr_closure_new((void *)&scr_reject_thunk, 1);
3191
+ ScrBox *b = scr_box_new_obj(scr_promise_retain_v, scr_promise_release_v,
3192
+ scr_promise_trace_v);
3193
+ scr_box_set_ref(b, scr_promise_retain(p));
3194
+ c->caps[0] = b;
3195
+ return c;
3196
+ }
3197
+
3198
+ /* Shared executor epilogue: an escaping throw rejects a still-pending
3199
+ * promise (payload moved out of the active exception cell); a throw after
3200
+ * the promise settled is swallowed, like resolve-then-throw in JS. */
3201
+ static void scr_executor_check_throw(ScrPromise *p) {
3202
+ if (!scr_exc_pending()) return;
3203
+ if (p->state == SCR_PROM_PENDING) {
3204
+ scr_promise_reject_from_cell(p, scr_exc_current_cell());
3205
+ scr_promise_settle_wake(p);
3206
+ } else {
3207
+ scr_exc_clear();
3208
+ }
3209
+ }
3210
+
3211
+ /* Runs a `new Promise(executor)` executor synchronously; an escaping throw
3212
+ * rejects the promise (JS-exact). Borrows `p` and `exec`; `resolve`
3213
+ * ownership moves INTO the executor call (compiled callees own and finally
3214
+ * release their params). */
3215
+ void scr_promise_run_executor(ScrPromise *p, ScrClosure *exec, ScrClosure *resolve) {
3216
+ ((void (*)(ScrClosure *, ScrClosure *))exec->fn)(exec, resolve);
3217
+ scr_executor_check_throw(p);
3218
+ }
3219
+
3220
+ /* Zero-param executor (`new Promise(() => {})`): nothing can ever resolve —
3221
+ * a deliberately-forever-pending promise. Borrows both. */
3222
+ void scr_promise_run_executor0(ScrPromise *p, ScrClosure *exec) {
3223
+ ((void (*)(ScrClosure *))exec->fn)(exec);
3224
+ scr_executor_check_throw(p);
3225
+ }
3226
+
3227
+ /* Two-param executor (`new Promise((resolve, reject) => ...)`): same as
3228
+ * scr_promise_run_executor with the reject closure's +1 also moving into
3229
+ * the call. */
3230
+ void scr_promise_run_executor2(ScrPromise *p, ScrClosure *exec, ScrClosure *resolve,
3231
+ ScrClosure *reject) {
3232
+ ((void (*)(ScrClosure *, ScrClosure *, ScrClosure *))exec->fn)(exec, resolve, reject);
3233
+ scr_executor_check_throw(p);
3234
+ }
3235
+
3236
+ /* ── sync generators (function*) ──────────────────────────────────────
3237
+ * Contract in scr_runtime.h. The fiber machinery above is the engine:
3238
+ * scr_switch is a synchronous coroutine hop, so generators need no event
3239
+ * loop — .next() from the main stack (or any fiber) blocks until the
3240
+ * yield. */
3241
+
3242
+ enum {
3243
+ SCR_GEN_UNSTARTED = 0,
3244
+ SCR_GEN_SUSPENDED,
3245
+ SCR_GEN_AWAITING,
3246
+ SCR_GEN_RUNNING,
3247
+ SCR_GEN_DONE
3248
+ };
3249
+
3250
+ /* One type-erased value slot: the exception cell's payload technique,
3251
+ * with only the release entry point (takes MOVE — nothing here retains). */
3252
+ typedef struct {
3253
+ ScrExcKind kind; /* NONE / F64 / BOOL / REF (strings ride REF) */
3254
+ double f64;
3255
+ bool b;
3256
+ void *payload;
3257
+ void (*release_fn)(void *);
3258
+ } ScrGenSlot;
3259
+
3260
+ enum { SCR_AG_NEXT = 0, SCR_AG_RETURN, SCR_AG_THROW };
3261
+
3262
+ typedef struct ScrAsyncGenRequest {
3263
+ int mode;
3264
+ ScrGenSlot arg;
3265
+ ScrExcCell thrown;
3266
+ ScrPromise *promise; /* owned until this request settles */
3267
+ struct ScrAsyncGenRequest *next;
3268
+ } ScrAsyncGenRequest;
3269
+
3270
+ static void scr_gen_slot_reset(ScrGenSlot *s) {
3271
+ if (s->kind == SCR_EXC_REF && s->payload != NULL) s->release_fn(s->payload);
3272
+ s->kind = SCR_EXC_NONE;
3273
+ s->payload = NULL;
3274
+ s->release_fn = NULL;
3275
+ }
3276
+
3277
+ static void scr_gen_exc_reset(ScrExcCell *cell) {
3278
+ if (cell->kind == SCR_EXC_STR) {
3279
+ scr_str_release((ScrStr *)cell->payload);
3280
+ } else if (cell->kind == SCR_EXC_REF || cell->kind == SCR_EXC_OBJ ||
3281
+ cell->kind == SCR_EXC_PRIMITIVE_REF) {
3282
+ cell->release_fn(cell->payload);
3283
+ }
3284
+ ScrStackFrame *stack = cell->stack;
3285
+ memset(cell, 0, sizeof *cell);
3286
+ cell->stack = stack;
3287
+ }
3288
+
3289
+ static void scr_gen_exc_move(ScrExcCell *dst, ScrExcCell *src) {
3290
+ scr_gen_exc_reset(dst);
3291
+ ScrStackFrame *dst_stack = dst->stack;
3292
+ ScrStackFrame *src_stack = src->stack;
3293
+ *dst = *src;
3294
+ dst->stack = dst_stack;
3295
+ memset(src, 0, sizeof *src);
3296
+ src->stack = src_stack;
3297
+ }
3298
+
3299
+ struct ScrGen {
3300
+ size_t rc;
3301
+ ScrFiber *fiber; /* NULL once torn down (done, or unstarted release) */
3302
+ int state;
3303
+ ScrGenSlot out; /* yielded value / completion value */
3304
+ ScrGenSlot in; /* the .next(v) argument */
3305
+ ScrGenSlot ret; /* a parked .return(v) value */
3306
+ /* The never-started teardown: drops the packed (already-retained)
3307
+ * arguments the spawn wrapper built. Emitted per generator function. */
3308
+ void (*drop_args)(void *);
3309
+ bool is_async;
3310
+ void (*settle_async)(ScrGen *, ScrPromise *);
3311
+ ScrAsyncGenRequest *requests_head;
3312
+ ScrAsyncGenRequest *requests_tail;
3313
+ ScrPromise *active_request;
3314
+ ScrExcCell async_error;
3315
+ bool settle_queued;
3316
+ bool success_hop_done;
3317
+ };
3318
+
3319
+ static ScrGen *scr_gen_new_common(void (*entry)(ScrFiber *, void *), void *argpack,
3320
+ void (*drop_args)(void *),
3321
+ void (*settle_async)(ScrGen *, ScrPromise *)) {
3322
+ ScrGen *g = calloc(1, sizeof *g);
3323
+ if (!g) scr_oom();
3324
+ g->rc = 1;
3325
+ g->state = SCR_GEN_UNSTARTED;
3326
+ g->drop_args = drop_args;
3327
+ g->is_async = settle_async != NULL;
3328
+ g->settle_async = settle_async;
3329
+ scr_obj_alloc_note();
3330
+
3331
+ ScrFiber *f = calloc(1, sizeof *f);
3332
+ if (!f) scr_oom();
3333
+ f->gen = g;
3334
+ f->entry = entry;
3335
+ f->argpack = argpack; /* owned by the fiber start; drop_args if never started */
3336
+ /* AsyncLocalStorage: generator bodies run in their CREATOR's context
3337
+ * (the spawn-inheritance stance; resumes swap it active like any
3338
+ * fiber switch). */
3339
+ f->als = scr_als_ctx_retain(*scr_als_active);
3340
+ scr_fibers_live++;
3341
+ #ifdef _WIN32
3342
+ f->ctx = CreateFiberEx(4096, 0, 0, scr_trampoline, NULL);
3343
+ if (f->ctx == NULL) scr_oom();
3344
+ #elif defined(__wasi__)
3345
+ f->ctx = 0;
3346
+ #else
3347
+ scr_fiber_context_init(f);
3348
+ #endif
3349
+ g->fiber = f;
3350
+ return g;
3351
+ }
3352
+
3353
+ ScrGen *scr_gen_new(void (*entry)(ScrFiber *, void *), void *argpack,
3354
+ void (*drop_args)(void *)) {
3355
+ return scr_gen_new_common(entry, argpack, drop_args, NULL);
3356
+ }
3357
+
3358
+ ScrGen *scr_async_gen_new(void (*entry)(ScrFiber *, void *), void *argpack,
3359
+ void (*drop_args)(void *),
3360
+ void (*settle)(ScrGen *, ScrPromise *)) {
3361
+ return scr_gen_new_common(entry, argpack, drop_args, settle);
3362
+ }
3363
+
3364
+ ScrGen *scr_gen_retain(ScrGen *g) {
3365
+ if (g) g->rc++;
3366
+ return g;
3367
+ }
3368
+
3369
+ void scr_gen_release(ScrGen *g) {
3370
+ if (!g || --g->rc != 0) return;
3371
+ scr_gen_slot_reset(&g->out);
3372
+ scr_gen_slot_reset(&g->in);
3373
+ scr_gen_slot_reset(&g->ret);
3374
+ scr_gen_exc_reset(&g->async_error);
3375
+ if (g->fiber != NULL) {
3376
+ if (g->state == SCR_GEN_UNSTARTED) {
3377
+ /* Never ran: nothing on the stack owns anything — clean teardown.
3378
+ * The packed arguments (+1 each) drop through the emitted helper. */
3379
+ if (g->drop_args != NULL) g->drop_args(g->fiber->argpack);
3380
+ else free(g->fiber->argpack);
3381
+ scr_fiber_destroy(g->fiber);
3382
+ scr_fibers_live--;
3383
+ } else {
3384
+ /* Suspended: the stack holds live locals — unwinding would run user
3385
+ * finally blocks Node's GC never runs, so the fiber is deliberately
3386
+ * ABANDONED (it stays in the live count; a program that drops a
3387
+ * suspended generator gets the abandoned-fiber audit note, the
3388
+ * loop-exhaustion story). The fiber's back-pointer clears so a
3389
+ * dangling resume can never reach the freed ScrGen. */
3390
+ g->fiber->gen = NULL;
3391
+ }
3392
+ }
3393
+ scr_obj_free_note();
3394
+ free(g);
3395
+ }
3396
+
3397
+ void *scr_gen_retain_v(void *g) { return scr_gen_retain((ScrGen *)g); }
3398
+ void scr_gen_release_v(void *g) { scr_gen_release((ScrGen *)g); }
3399
+
3400
+ bool scr_gen_done(ScrGen *g) { return g->state == SCR_GEN_DONE; }
3401
+ ScrGen *scr_gen_of_fiber(ScrFiber *f) { return f->gen; }
3402
+
3403
+ /* Slot setters (release the previous occupant; payloads MOVE in). */
3404
+ static void scr_gen_slot_f64(ScrGenSlot *s, double v) {
3405
+ scr_gen_slot_reset(s);
3406
+ s->kind = SCR_EXC_F64;
3407
+ s->f64 = v;
3408
+ }
3409
+ static void scr_gen_slot_bool(ScrGenSlot *s, bool v) {
3410
+ scr_gen_slot_reset(s);
3411
+ s->kind = SCR_EXC_BOOL;
3412
+ s->b = v;
3413
+ }
3414
+ static void scr_gen_slot_ref(ScrGenSlot *s, void *v, void (*release)(void *)) {
3415
+ scr_gen_slot_reset(s);
3416
+ s->kind = SCR_EXC_REF;
3417
+ s->payload = v;
3418
+ s->release_fn = release;
3419
+ }
3420
+
3421
+ void scr_gen_in_f64(ScrGen *g, double v) { scr_gen_slot_f64(&g->in, v); }
3422
+ void scr_gen_in_bool(ScrGen *g, bool v) { scr_gen_slot_bool(&g->in, v); }
3423
+ void scr_gen_in_ref(ScrGen *g, void *v, void (*release)(void *)) {
3424
+ scr_gen_slot_ref(&g->in, v, release);
3425
+ }
3426
+ void scr_gen_in_none(ScrGen *g) { scr_gen_slot_reset(&g->in); }
3427
+
3428
+ void scr_gen_ret_f64(ScrGen *g, double v) { scr_gen_slot_f64(&g->ret, v); }
3429
+ void scr_gen_ret_bool(ScrGen *g, bool v) { scr_gen_slot_bool(&g->ret, v); }
3430
+ void scr_gen_ret_ref(ScrGen *g, void *v, void (*release)(void *)) {
3431
+ scr_gen_slot_ref(&g->ret, v, release);
3432
+ }
3433
+ void scr_gen_ret_none(ScrGen *g) { scr_gen_slot_reset(&g->ret); }
3434
+
3435
+ void scr_gen_out_f64(ScrGen *g, double v) { scr_gen_slot_f64(&g->out, v); }
3436
+ void scr_gen_out_bool(ScrGen *g, bool v) { scr_gen_slot_bool(&g->out, v); }
3437
+ void scr_gen_out_ref(ScrGen *g, void *v, void (*release)(void *)) {
3438
+ scr_gen_slot_ref(&g->out, v, release);
3439
+ }
3440
+
3441
+ /* Takes MOVE the slot's value out (the slot resets — a done generator's
3442
+ * later resumes answer NONE, JS's undefined). */
3443
+ static double scr_gen_slot_take_f64(ScrGenSlot *s) {
3444
+ double v = s->kind == SCR_EXC_F64 ? s->f64 : 0;
3445
+ s->kind = SCR_EXC_NONE;
3446
+ return v;
3447
+ }
3448
+ static bool scr_gen_slot_take_bool(ScrGenSlot *s) {
3449
+ bool v = s->kind == SCR_EXC_BOOL ? s->b : false;
3450
+ s->kind = SCR_EXC_NONE;
3451
+ return v;
3452
+ }
3453
+ static void *scr_gen_slot_take_ref(ScrGenSlot *s) {
3454
+ void *v = s->kind == SCR_EXC_REF ? s->payload : NULL;
3455
+ s->kind = SCR_EXC_NONE;
3456
+ s->payload = NULL;
3457
+ s->release_fn = NULL;
3458
+ return v;
3459
+ }
3460
+
3461
+ bool scr_gen_out_has(ScrGen *g) { return g->out.kind != SCR_EXC_NONE; }
3462
+ double scr_gen_take_out_f64(ScrGen *g) { return scr_gen_slot_take_f64(&g->out); }
3463
+ bool scr_gen_take_out_bool(ScrGen *g) { return scr_gen_slot_take_bool(&g->out); }
3464
+ void *scr_gen_take_out_ref(ScrGen *g) { return scr_gen_slot_take_ref(&g->out); }
3465
+
3466
+ /* The running fiber's generator — the body-side helpers' anchor. */
3467
+ static ScrGen *scr_gen_self(void) {
3468
+ ScrGen *g = scr_current != NULL ? scr_current->gen : NULL;
3469
+ if (g == NULL) {
3470
+ fputs("scriptc: internal error: yield outside a generator\n", stderr);
3471
+ abort();
3472
+ }
3473
+ return g;
3474
+ }
3475
+
3476
+ double scr_gen_take_in_f64(void) { return scr_gen_slot_take_f64(&scr_gen_self()->in); }
3477
+ bool scr_gen_take_in_bool(void) { return scr_gen_slot_take_bool(&scr_gen_self()->in); }
3478
+ void *scr_gen_take_in_ref(void) { return scr_gen_slot_take_ref(&scr_gen_self()->in); }
3479
+
3480
+ ScrDyn *scr_gen_delegate_resume(ScrDyn *(*next_ref)(void *),
3481
+ ScrDyn *(*return_ref)(void *),
3482
+ ScrDyn *(*caught_ref)(const ScrCaught *)) {
3483
+ ScrGen *g = scr_gen_self();
3484
+ ScrExcCell *cell = scr_exc_current_cell();
3485
+ int mode = cell->kind == SCR_EXC_GENRET ? 1 : cell->kind != SCR_EXC_NONE ? 2 : 0;
3486
+ ScrDyn *value;
3487
+ if (mode == 2) {
3488
+ ScrCaught *caught = scr_exc_take();
3489
+ value = caught_ref(caught);
3490
+ scr_caught_release(caught);
3491
+ } else {
3492
+ if (mode == 1) scr_exc_clear();
3493
+ ScrGenSlot *slot = mode == 1 ? &g->ret : &g->in;
3494
+ ScrDyn *(*convert)(void *) = mode == 1 ? return_ref : next_ref;
3495
+ switch (slot->kind) {
3496
+ case SCR_EXC_F64: value = scr_dyn_new_num(slot->f64); break;
3497
+ case SCR_EXC_BOOL: value = scr_dyn_new_bool(slot->b); break;
3498
+ case SCR_EXC_REF: value = convert(slot->payload); break;
3499
+ default: value = scr_dyn_retain(scr_dyn_undefined()); break;
3500
+ }
3501
+ scr_gen_slot_reset(slot);
3502
+ }
3503
+ if (scr_exc_pending()) {
3504
+ scr_dyn_release(value);
3505
+ return NULL;
3506
+ }
3507
+ ScrDyn *result = scr_dyn_new_obj();
3508
+ ScrDyn *kind = scr_dyn_new_num(mode);
3509
+ scr_dyn_obj_set(result, "kind", 4, kind);
3510
+ scr_dyn_obj_set(result, "value", 5, value);
3511
+ /* Object insertion takes ownership of both completion fields. */
3512
+ return result;
3513
+ }
3514
+
3515
+ /* yield: park the value in OUT and hop back to the resumer. Control
3516
+ * returns here at the next resume — possibly with an injected .throw
3517
+ * payload or the GENRET sentinel pending (the emitted check handles it). */
3518
+ static void scr_gen_yield_switch(void) {
3519
+ ScrFiber *self = scr_current;
3520
+ scr_switch(&self->ctx, self->return_to, NULL);
3521
+ }
3522
+ void scr_gen_yield_f64(double v) {
3523
+ scr_gen_slot_f64(&scr_gen_self()->out, v);
3524
+ scr_gen_yield_switch();
3525
+ }
3526
+ void scr_gen_yield_bool(bool v) {
3527
+ scr_gen_slot_bool(&scr_gen_self()->out, v);
3528
+ scr_gen_yield_switch();
3529
+ }
3530
+ void scr_gen_yield_ref(void *v, void (*release)(void *)) {
3531
+ scr_gen_slot_ref(&scr_gen_self()->out, v, release);
3532
+ scr_gen_yield_switch();
3533
+ }
3534
+
3535
+ void scr_async_gen_hop_done(void) {
3536
+ ScrGen *g = scr_gen_self();
3537
+ if (!g->is_async) {
3538
+ fputs("scriptc: internal error: async-generator hop on sync generator\n", stderr);
3539
+ abort();
3540
+ }
3541
+ g->success_hop_done = true;
3542
+ }
3543
+
3544
+ bool scr_exc_genret_pending(void) {
3545
+ return scr_exc_current_cell()->kind == SCR_EXC_GENRET;
3546
+ }
3547
+
3548
+ void scr_gen_ret_to_out(ScrGen *g) {
3549
+ scr_gen_slot_reset(&g->out);
3550
+ g->out = g->ret;
3551
+ g->ret.kind = SCR_EXC_NONE;
3552
+ g->ret.payload = NULL;
3553
+ g->ret.release_fn = NULL;
3554
+ }
3555
+
3556
+ /* The consumer→fiber hop shared by every resume mode: switches in, and on
3557
+ * the way back moves a pending body exception into the RESUMER's cell
3558
+ * (synchronous propagation — the await-rethrow analog) and tears down a
3559
+ * finished fiber. The gen is retained across the hop so a body that
3560
+ * releases the consumer's last reference cannot free it mid-run. */
3561
+ static void scr_gen_switch_in(ScrGen *g) {
3562
+ ScrFiber *f = g->fiber;
3563
+ scr_gen_retain(g);
3564
+ g->state = SCR_GEN_RUNNING;
3565
+ #ifdef _WIN32
3566
+ ScrCtx here = scr_win_self();
3567
+ #elif defined(__wasi__)
3568
+ ScrCtx here = 0;
3569
+ #else
3570
+ ucontext_t here;
3571
+ #endif
3572
+ f->return_to = &here;
3573
+ ScrFiber *me = scr_current;
3574
+ #ifdef __wasi__
3575
+ scr_current = f;
3576
+ scr_exc_swap_cell(&f->exc);
3577
+ scr_als_active = &f->als;
3578
+ if (f->coro == NULL) f->entry(f, f->argpack);
3579
+ else scr_wasi_coro_resume(f->coro);
3580
+ scr_current = me;
3581
+ scr_exc_swap_cell(me != NULL ? &me->exc : NULL);
3582
+ scr_als_active = me != NULL ? &me->als : &scr_als_main_slot;
3583
+ #else
3584
+ scr_switch(&here, &f->ctx, f);
3585
+ /* Back on the consumer: restore identity + the consumer's cell (the
3586
+ * yield/finish switch targeted NULL — main's cell). */
3587
+ scr_current = me;
3588
+ scr_exc_swap_cell(me != NULL ? &me->exc : NULL);
3589
+ #endif
3590
+ if (f->done) {
3591
+ g->state = SCR_GEN_DONE;
3592
+ if (f->exc.kind != SCR_EXC_NONE) {
3593
+ if (g->is_async) {
3594
+ /* Async-generator failures reject the active request; they never
3595
+ * throw synchronously from next/return/throw. */
3596
+ scr_gen_exc_move(&g->async_error, &f->exc);
3597
+ } else {
3598
+ /* The sync body's exception escapes at the resume site. */
3599
+ ScrExcCell *mine = scr_exc_current_cell();
3600
+ scr_gen_exc_move(mine, &f->exc);
3601
+ }
3602
+ }
3603
+ scr_fiber_destroy(f);
3604
+ g->fiber = NULL;
3605
+ scr_fibers_live--;
3606
+ } else {
3607
+ /* An async generator can return to its resumer because it yielded OR
3608
+ * because await parked it. OUT distinguishes the two. */
3609
+ g->state = g->is_async && !scr_gen_out_has(g)
3610
+ ? SCR_GEN_AWAITING
3611
+ : SCR_GEN_SUSPENDED;
3612
+ }
3613
+ scr_gen_release(g);
3614
+ }
3615
+
3616
+ void scr_gen_resume(ScrGen *g) {
3617
+ switch (g->state) {
3618
+ case SCR_GEN_RUNNING: {
3619
+ static const char sc_m[] = "Generator is already running";
3620
+ scr_throw_error_msg(SCR_ERR_TYPE, sc_m, sizeof sc_m - 1);
3621
+ return;
3622
+ }
3623
+ case SCR_GEN_DONE:
3624
+ /* next() on a done generator: { value: undefined, done: true } —
3625
+ * OUT is NONE (the completing resume took it). */
3626
+ return;
3627
+ default:
3628
+ scr_gen_switch_in(g);
3629
+ }
3630
+ }
3631
+
3632
+ void scr_gen_resume_return(ScrGen *g) {
3633
+ switch (g->state) {
3634
+ case SCR_GEN_RUNNING: {
3635
+ static const char sc_m[] = "Generator is already running";
3636
+ scr_throw_error_msg(SCR_ERR_TYPE, sc_m, sizeof sc_m - 1);
3637
+ return;
3638
+ }
3639
+ case SCR_GEN_DONE:
3640
+ scr_gen_ret_to_out(g);
3641
+ return;
3642
+ case SCR_GEN_UNSTARTED:
3643
+ /* The body never runs: tear the fiber down cleanly (drop the packed
3644
+ * arguments) and complete with the parked value. */
3645
+ if (g->drop_args != NULL) g->drop_args(g->fiber->argpack);
3646
+ else free(g->fiber->argpack);
3647
+ scr_fiber_destroy(g->fiber);
3648
+ g->fiber = NULL;
3649
+ scr_fibers_live--;
3650
+ g->state = SCR_GEN_DONE;
3651
+ scr_gen_ret_to_out(g);
3652
+ return;
3653
+ default:
3654
+ /* Suspended at a yield: inject the sentinel (an earlier .return whose
3655
+ * unwind a finally-yield parked leaves it already set) and resume. */
3656
+ if (g->fiber->exc.kind == SCR_EXC_NONE) g->fiber->exc.kind = SCR_EXC_GENRET;
3657
+ scr_gen_switch_in(g);
3658
+ }
3659
+ }
3660
+
3661
+ void scr_gen_resume_throw(ScrGen *g) {
3662
+ switch (g->state) {
3663
+ case SCR_GEN_RUNNING: {
3664
+ /* Replace the parked payload with Node's reentrancy TypeError. */
3665
+ static const char sc_m[] = "Generator is already running";
3666
+ scr_throw_error_msg(SCR_ERR_TYPE, sc_m, sizeof sc_m - 1);
3667
+ return;
3668
+ }
3669
+ case SCR_GEN_DONE:
3670
+ /* .throw on a done generator: it stays done; the payload stays
3671
+ * pending in the caller — the call site's check rethrows it. */
3672
+ return;
3673
+ case SCR_GEN_UNSTARTED:
3674
+ /* The body never runs; the generator becomes done and the payload
3675
+ * stays pending in the caller (probed Node behavior). */
3676
+ if (g->drop_args != NULL) g->drop_args(g->fiber->argpack);
3677
+ else free(g->fiber->argpack);
3678
+ scr_fiber_destroy(g->fiber);
3679
+ g->fiber = NULL;
3680
+ scr_fibers_live--;
3681
+ g->state = SCR_GEN_DONE;
3682
+ return;
3683
+ default: {
3684
+ /* Move the caller's pending payload into the fiber's cell (an
3685
+ * earlier sentinel parked by a finally-yield is replaced — the
3686
+ * injected throw wins, like a throw inside that finally). */
3687
+ ScrExcCell *mine = scr_exc_current_cell();
3688
+ ScrExcCell *dst = &g->fiber->exc;
3689
+ dst->kind = mine->kind;
3690
+ dst->f64 = mine->f64;
3691
+ dst->b = mine->b;
3692
+ dst->payload = mine->payload;
3693
+ dst->retain_fn = mine->retain_fn;
3694
+ dst->release_fn = mine->release_fn;
3695
+ dst->trace_fn = mine->trace_fn;
3696
+ mine->kind = SCR_EXC_NONE;
3697
+ mine->payload = NULL;
3698
+ mine->trace_fn = NULL;
3699
+ scr_gen_switch_in(g);
3700
+ }
3701
+ }
3702
+ }
3703
+
3704
+ /* ── async generators ────────────────────────────────────────────────
3705
+ * The body is the same suspended generator fiber, now allowed to await.
3706
+ * Each resume request owns a promise and a retained generator. The first
3707
+ * idle request starts synchronously; successful yield/return settlement
3708
+ * takes AsyncGeneratorYield's Await hop (the emitter marks a yielded
3709
+ * promise whose await already supplied it), while thrown completions reject
3710
+ * immediately. Requests queued behind an active one begin in that
3711
+ * settlement continuation, preserving Node's ordering. */
3712
+
3713
+ static void scr_async_gen_start_queued(ScrGen *g);
3714
+
3715
+ static void scr_async_gen_schedule_settle(ScrGen *g) {
3716
+ if (g->settle_queued) return;
3717
+ ScrFiber *job = calloc(1, sizeof *job);
3718
+ if (!job) scr_oom();
3719
+ job->gen_job = scr_gen_retain(g);
3720
+ g->settle_queued = true;
3721
+ scr_ready_push(job);
3722
+ }
3723
+
3724
+ static void scr_async_gen_finish_active(ScrGen *g, bool rejected) {
3725
+ ScrPromise *p = g->active_request;
3726
+ if (p == NULL) {
3727
+ fputs("scriptc: internal error: async generator settled without a request\n", stderr);
3728
+ abort();
3729
+ }
3730
+ g->active_request = NULL;
3731
+ if (rejected) {
3732
+ scr_promise_reject_from_cell(p, &g->async_error);
3733
+ scr_promise_settle_wake(p);
3734
+ } else {
3735
+ g->settle_async(g, p);
3736
+ }
3737
+ scr_promise_release(p);
3738
+ /* Every queued request retains its generator until settlement. */
3739
+ scr_gen_release(g);
3740
+ }
3741
+
3742
+ static void scr_async_gen_capture_caller_error(ScrGen *g) {
3743
+ ScrExcCell *cell = scr_exc_current_cell();
3744
+ if (cell->kind != SCR_EXC_NONE) scr_gen_exc_move(&g->async_error, cell);
3745
+ }
3746
+
3747
+ static void scr_async_gen_run_active(ScrGen *g, ScrAsyncGenRequest *req) {
3748
+ const bool was_done = g->state == SCR_GEN_DONE;
3749
+ if (req->mode == SCR_AG_NEXT) {
3750
+ scr_gen_slot_reset(&g->in);
3751
+ g->in = req->arg;
3752
+ memset(&req->arg, 0, sizeof req->arg);
3753
+ scr_gen_resume(g);
3754
+ } else if (req->mode == SCR_AG_RETURN) {
3755
+ scr_gen_slot_reset(&g->ret);
3756
+ g->ret = req->arg;
3757
+ memset(&req->arg, 0, sizeof req->arg);
3758
+ scr_gen_resume_return(g);
3759
+ } else {
3760
+ scr_gen_exc_move(scr_exc_current_cell(), &req->thrown);
3761
+ scr_gen_resume_throw(g);
3762
+ }
3763
+ scr_async_gen_capture_caller_error(g);
3764
+
3765
+ if (g->async_error.kind != SCR_EXC_NONE) {
3766
+ scr_async_gen_finish_active(g, true);
3767
+ return;
3768
+ }
3769
+ if (g->state == SCR_GEN_AWAITING) return;
3770
+
3771
+ /* next() on an already-completed generator produces its undefined done
3772
+ * result immediately. Yield, body return, and return(value) all pass
3773
+ * through AsyncGeneratorYield's successful Await step. */
3774
+ if (was_done && req->mode == SCR_AG_NEXT) {
3775
+ scr_async_gen_finish_active(g, false);
3776
+ } else if (g->success_hop_done) {
3777
+ g->success_hop_done = false;
3778
+ scr_async_gen_finish_active(g, false);
3779
+ } else {
3780
+ scr_async_gen_schedule_settle(g);
3781
+ }
3782
+ }
3783
+
3784
+ static void scr_async_gen_start_queued(ScrGen *g) {
3785
+ /* Keep the object alive while an immediately-settled request releases
3786
+ * its own retain and the loop inspects the next queue node. */
3787
+ scr_gen_retain(g);
3788
+ while (g->active_request == NULL && g->requests_head != NULL) {
3789
+ ScrAsyncGenRequest *req = g->requests_head;
3790
+ g->requests_head = req->next;
3791
+ if (g->requests_head == NULL) g->requests_tail = NULL;
3792
+ g->active_request = req->promise; /* request ownership transfers */
3793
+ scr_async_gen_run_active(g, req);
3794
+ scr_gen_slot_reset(&req->arg);
3795
+ scr_gen_exc_reset(&req->thrown);
3796
+ free(req);
3797
+ /* Awaiting or deferred successful settlement keeps this request
3798
+ * active. Immediate done/error settlement cleared it and can consume
3799
+ * the next queued request in this same turn. */
3800
+ if (g->active_request != NULL) break;
3801
+ }
3802
+ scr_gen_release(g);
3803
+ }
3804
+
3805
+ static ScrPromise *scr_async_gen_enqueue(ScrGen *g, int mode,
3806
+ ScrGenSlot *arg,
3807
+ ScrExcCell *thrown) {
3808
+ if (!g->is_async || g->settle_async == NULL) {
3809
+ fputs("scriptc: internal error: async resume of a sync generator\n", stderr);
3810
+ abort();
3811
+ }
3812
+ ScrAsyncGenRequest *req = calloc(1, sizeof *req);
3813
+ if (!req) scr_oom();
3814
+ req->mode = mode;
3815
+ if (arg != NULL) {
3816
+ req->arg = *arg;
3817
+ memset(arg, 0, sizeof *arg);
3818
+ }
3819
+ if (thrown != NULL) scr_gen_exc_move(&req->thrown, thrown);
3820
+ req->promise = scr_promise_new();
3821
+ /* The request owns the original promise reference and one generator
3822
+ * reference; the caller receives a second promise reference. */
3823
+ ScrPromise *result = scr_promise_retain(req->promise);
3824
+ scr_gen_retain(g);
3825
+ if (g->requests_tail != NULL) g->requests_tail->next = req;
3826
+ else g->requests_head = req;
3827
+ g->requests_tail = req;
3828
+ if (g->active_request == NULL && !g->settle_queued) {
3829
+ scr_async_gen_start_queued(g);
3830
+ }
3831
+ return result;
3832
+ }
3833
+
3834
+ ScrPromise *scr_async_gen_next_none(ScrGen *g) {
3835
+ ScrGenSlot arg = {0};
3836
+ return scr_async_gen_enqueue(g, SCR_AG_NEXT, &arg, NULL);
3837
+ }
3838
+
3839
+ ScrPromise *scr_async_gen_next_f64(ScrGen *g, double value) {
3840
+ ScrGenSlot arg = {0};
3841
+ scr_gen_slot_f64(&arg, value);
3842
+ return scr_async_gen_enqueue(g, SCR_AG_NEXT, &arg, NULL);
3843
+ }
3844
+
3845
+ ScrPromise *scr_async_gen_next_bool(ScrGen *g, bool value) {
3846
+ ScrGenSlot arg = {0};
3847
+ scr_gen_slot_bool(&arg, value);
3848
+ return scr_async_gen_enqueue(g, SCR_AG_NEXT, &arg, NULL);
3849
+ }
3850
+
3851
+ ScrPromise *scr_async_gen_next_ref(ScrGen *g, void *value,
3852
+ void (*release)(void *)) {
3853
+ ScrGenSlot arg = {0};
3854
+ scr_gen_slot_ref(&arg, value, release);
3855
+ return scr_async_gen_enqueue(g, SCR_AG_NEXT, &arg, NULL);
3856
+ }
3857
+
3858
+ ScrPromise *scr_async_gen_return_none(ScrGen *g) {
3859
+ ScrGenSlot arg = {0};
3860
+ return scr_async_gen_enqueue(g, SCR_AG_RETURN, &arg, NULL);
3861
+ }
3862
+
3863
+ ScrPromise *scr_async_gen_return_f64(ScrGen *g, double value) {
3864
+ ScrGenSlot arg = {0};
3865
+ scr_gen_slot_f64(&arg, value);
3866
+ return scr_async_gen_enqueue(g, SCR_AG_RETURN, &arg, NULL);
3867
+ }
3868
+
3869
+ ScrPromise *scr_async_gen_return_bool(ScrGen *g, bool value) {
3870
+ ScrGenSlot arg = {0};
3871
+ scr_gen_slot_bool(&arg, value);
3872
+ return scr_async_gen_enqueue(g, SCR_AG_RETURN, &arg, NULL);
3873
+ }
3874
+
3875
+ ScrPromise *scr_async_gen_return_ref(ScrGen *g, void *value,
3876
+ void (*release)(void *)) {
3877
+ ScrGenSlot arg = {0};
3878
+ scr_gen_slot_ref(&arg, value, release);
3879
+ return scr_async_gen_enqueue(g, SCR_AG_RETURN, &arg, NULL);
3880
+ }
3881
+
3882
+ ScrPromise *scr_async_gen_throw(ScrGen *g) {
3883
+ ScrExcCell thrown = {0};
3884
+ scr_gen_exc_move(&thrown, scr_exc_current_cell());
3885
+ return scr_async_gen_enqueue(g, SCR_AG_THROW, NULL, &thrown);
3886
+ }
3887
+
3888
+ static void scr_async_gen_job(ScrGen *g) {
3889
+ g->settle_queued = false;
3890
+ if (g->active_request == NULL || g->async_error.kind != SCR_EXC_NONE) {
3891
+ fputs("scriptc: internal error: invalid async generator settlement job\n", stderr);
3892
+ abort();
3893
+ }
3894
+ scr_async_gen_finish_active(g, false);
3895
+ scr_async_gen_start_queued(g);
3896
+ }
3897
+
3898
+ static void scr_async_gen_resume_ready(ScrGen *g) {
3899
+ if (!g->is_async || g->active_request == NULL) {
3900
+ fputs("scriptc: internal error: async generator resumed without a request\n", stderr);
3901
+ abort();
3902
+ }
3903
+ /* The active request normally owns the generator. Keep an independent
3904
+ * reference across settlement, which releases that request ownership. */
3905
+ scr_gen_retain(g);
3906
+ scr_gen_switch_in(g);
3907
+ if (g->async_error.kind != SCR_EXC_NONE) {
3908
+ scr_async_gen_finish_active(g, true);
3909
+ scr_async_gen_start_queued(g);
3910
+ } else if (g->state != SCR_GEN_AWAITING) {
3911
+ if (g->success_hop_done) {
3912
+ g->success_hop_done = false;
3913
+ scr_async_gen_finish_active(g, false);
3914
+ scr_async_gen_start_queued(g);
3915
+ } else {
3916
+ scr_async_gen_schedule_settle(g);
3917
+ }
3918
+ }
3919
+ scr_gen_release(g);
3920
+ }