xbintsc 0.3.87 → 0.5.20

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 (458) hide show
  1. package/AGENTS.md +23 -11
  2. package/README.md +11 -9
  3. package/README.zh-CN.md +7 -7
  4. package/dist/src/binder/declarations.js +14 -3
  5. package/dist/src/binder/declarations.js.map +1 -1
  6. package/dist/src/cli/hints.js +7 -1
  7. package/dist/src/cli/hints.js.map +1 -1
  8. package/dist/src/cli/main.js +115 -15
  9. package/dist/src/cli/main.js.map +1 -1
  10. package/dist/src/cli/watch.d.ts +25 -0
  11. package/dist/src/cli/watch.js +93 -0
  12. package/dist/src/cli/watch.js.map +1 -0
  13. package/dist/src/codegen/generator/calls/access.js +17 -4
  14. package/dist/src/codegen/generator/calls/access.js.map +1 -1
  15. package/dist/src/codegen/generator/calls/closures.js +13 -1
  16. package/dist/src/codegen/generator/calls/closures.js.map +1 -1
  17. package/dist/src/codegen/generator/calls/invocation.js +4 -3
  18. package/dist/src/codegen/generator/calls/invocation.js.map +1 -1
  19. package/dist/src/codegen/generator/context.d.ts +8 -0
  20. package/dist/src/codegen/generator/context.js +22 -3
  21. package/dist/src/codegen/generator/context.js.map +1 -1
  22. package/dist/src/codegen/generator/expressions/operators.js +17 -15
  23. package/dist/src/codegen/generator/expressions/operators.js.map +1 -1
  24. package/dist/src/codegen/generator/expressions/primary.js +11 -1
  25. package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
  26. package/dist/src/codegen/generator/module.d.ts +0 -1
  27. package/dist/src/codegen/generator/module.js +10 -17
  28. package/dist/src/codegen/generator/module.js.map +1 -1
  29. package/dist/src/codegen/generator/numeric.d.ts +6 -3
  30. package/dist/src/codegen/generator/numeric.js +54 -11
  31. package/dist/src/codegen/generator/numeric.js.map +1 -1
  32. package/dist/src/codegen/generator/state.js +27 -0
  33. package/dist/src/codegen/generator/state.js.map +1 -1
  34. package/dist/src/codegen/generator/statements/control-flow.js +2 -7
  35. package/dist/src/codegen/generator/statements/control-flow.js.map +1 -1
  36. package/dist/src/codegen/generator/statements/loops.js +48 -16
  37. package/dist/src/codegen/generator/statements/loops.js.map +1 -1
  38. package/dist/src/codegen/generator/tables.d.ts +9 -0
  39. package/dist/src/codegen/generator/tables.js +100 -3
  40. package/dist/src/codegen/generator/tables.js.map +1 -1
  41. package/dist/src/diagnostics/diagnostic.d.ts +3 -1
  42. package/dist/src/diagnostics/diagnostic.js +23 -3
  43. package/dist/src/diagnostics/diagnostic.js.map +1 -1
  44. package/dist/src/driver/app-artifacts.d.ts +42 -0
  45. package/dist/src/driver/app-artifacts.js +53 -0
  46. package/dist/src/driver/app-artifacts.js.map +1 -0
  47. package/dist/src/driver/build-key.d.ts +29 -0
  48. package/dist/src/driver/build-key.js +35 -0
  49. package/dist/src/driver/build-key.js.map +1 -0
  50. package/dist/src/driver/bundler/graph.js +61 -12
  51. package/dist/src/driver/bundler/graph.js.map +1 -1
  52. package/dist/src/driver/bundler/merge.js +7 -1
  53. package/dist/src/driver/bundler/merge.js.map +1 -1
  54. package/dist/src/driver/compiler.d.ts +10 -67
  55. package/dist/src/driver/compiler.js +94 -230
  56. package/dist/src/driver/compiler.js.map +1 -1
  57. package/dist/src/driver/config.d.ts +3 -0
  58. package/dist/src/driver/config.js +8 -0
  59. package/dist/src/driver/config.js.map +1 -1
  60. package/dist/src/driver/frontend.d.ts +37 -0
  61. package/dist/src/driver/frontend.js +92 -0
  62. package/dist/src/driver/frontend.js.map +1 -0
  63. package/dist/src/driver/index.d.ts +1 -1
  64. package/dist/src/driver/index.js.map +1 -1
  65. package/dist/src/driver/options.d.ts +64 -0
  66. package/dist/src/driver/options.js +9 -0
  67. package/dist/src/driver/options.js.map +1 -0
  68. package/dist/src/driver/runtime-objects.d.ts +38 -0
  69. package/dist/src/driver/runtime-objects.js +111 -0
  70. package/dist/src/driver/runtime-objects.js.map +1 -0
  71. package/dist/src/driver/toolchain-provider.d.ts +4 -0
  72. package/dist/src/driver/toolchain-provider.js +4 -0
  73. package/dist/src/driver/toolchain-provider.js.map +1 -1
  74. package/dist/src/driver/toolchain.d.ts +32 -1
  75. package/dist/src/driver/toolchain.js +115 -11
  76. package/dist/src/driver/toolchain.js.map +1 -1
  77. package/dist/src/driver/version.d.ts +12 -0
  78. package/dist/src/driver/version.js +13 -0
  79. package/dist/src/driver/version.js.map +1 -0
  80. package/dist/src/driver/win-icon.d.ts +7 -9
  81. package/dist/src/driver/win-icon.js +37 -35
  82. package/dist/src/driver/win-icon.js.map +1 -1
  83. package/dist/src/parser/declarations/classes.js +5 -0
  84. package/dist/src/parser/declarations/classes.js.map +1 -1
  85. package/dist/src/parser/declarations/functions.js +13 -1
  86. package/dist/src/parser/declarations/functions.js.map +1 -1
  87. package/dist/src/parser/modules.js +8 -3
  88. package/dist/src/parser/modules.js.map +1 -1
  89. package/dist/src/parser/parser.d.ts +1 -0
  90. package/dist/src/parser/parser.js +23 -0
  91. package/dist/src/parser/parser.js.map +1 -1
  92. package/dist/tests/cli/check.test.d.ts +6 -0
  93. package/dist/tests/cli/check.test.js +68 -0
  94. package/dist/tests/cli/check.test.js.map +1 -0
  95. package/dist/tests/cli/main.test.js +19 -0
  96. package/dist/tests/cli/main.test.js.map +1 -1
  97. package/dist/tests/cli/watch.test.d.ts +6 -0
  98. package/dist/tests/cli/watch.test.js +72 -0
  99. package/dist/tests/cli/watch.test.js.map +1 -0
  100. package/dist/tests/codegen/closures.test.js +8 -0
  101. package/dist/tests/codegen/closures.test.js.map +1 -1
  102. package/dist/tests/codegen/expressions.test.js +15 -3
  103. package/dist/tests/codegen/expressions.test.js.map +1 -1
  104. package/dist/tests/codegen/llvm.test.js +16 -0
  105. package/dist/tests/codegen/llvm.test.js.map +1 -1
  106. package/dist/tests/diagnostics/diagnostic.test.js +8 -0
  107. package/dist/tests/diagnostics/diagnostic.test.js.map +1 -1
  108. package/dist/tests/docs/structure.test.d.ts +1 -0
  109. package/dist/tests/docs/structure.test.js +92 -0
  110. package/dist/tests/docs/structure.test.js.map +1 -0
  111. package/dist/tests/driver/compiler.test.js +6 -0
  112. package/dist/tests/driver/compiler.test.js.map +1 -1
  113. package/dist/tests/driver/config.test.js +9 -0
  114. package/dist/tests/driver/config.test.js.map +1 -1
  115. package/dist/tests/driver/icon.test.js +19 -32
  116. package/dist/tests/driver/icon.test.js.map +1 -1
  117. package/dist/tests/driver/invalid-input.test.d.ts +10 -0
  118. package/dist/tests/driver/invalid-input.test.js +29 -0
  119. package/dist/tests/driver/invalid-input.test.js.map +1 -0
  120. package/dist/tests/driver/modules.test.js +42 -3
  121. package/dist/tests/driver/modules.test.js.map +1 -1
  122. package/dist/tests/driver/toolchain-provider.test.js +27 -1
  123. package/dist/tests/driver/toolchain-provider.test.js.map +1 -1
  124. package/dist/tests/driver/toolchain.test.js +60 -2
  125. package/dist/tests/driver/toolchain.test.js.map +1 -1
  126. package/dist/tests/e2e/array-buffer.test.d.ts +5 -0
  127. package/dist/tests/e2e/array-buffer.test.js +38 -0
  128. package/dist/tests/e2e/array-buffer.test.js.map +1 -0
  129. package/dist/tests/e2e/array-from-iterables.test.d.ts +7 -0
  130. package/dist/tests/e2e/array-from-iterables.test.js +34 -0
  131. package/dist/tests/e2e/array-from-iterables.test.js.map +1 -0
  132. package/dist/tests/e2e/array-symbol-iterator.test.d.ts +8 -0
  133. package/dist/tests/e2e/array-symbol-iterator.test.js +42 -0
  134. package/dist/tests/e2e/array-symbol-iterator.test.js.map +1 -0
  135. package/dist/tests/e2e/async-await.test.d.ts +10 -0
  136. package/dist/tests/e2e/async-await.test.js +247 -0
  137. package/dist/tests/e2e/async-await.test.js.map +1 -0
  138. package/dist/tests/e2e/async-generators.test.d.ts +1 -0
  139. package/dist/tests/e2e/async-generators.test.js +154 -0
  140. package/dist/tests/e2e/async-generators.test.js.map +1 -0
  141. package/dist/tests/e2e/await-ordering.test.d.ts +5 -0
  142. package/dist/tests/e2e/await-ordering.test.js +37 -0
  143. package/dist/tests/e2e/await-ordering.test.js.map +1 -0
  144. package/dist/tests/e2e/compile-builtins.test.js +1 -1
  145. package/dist/tests/e2e/compile-modules.test.js +7 -0
  146. package/dist/tests/e2e/compile-modules.test.js.map +1 -1
  147. package/dist/tests/e2e/date-parse.test.d.ts +8 -0
  148. package/dist/tests/e2e/date-parse.test.js +38 -0
  149. package/dist/tests/e2e/date-parse.test.js.map +1 -0
  150. package/dist/tests/e2e/default-anonymous-exports.test.d.ts +7 -0
  151. package/dist/tests/e2e/default-anonymous-exports.test.js +23 -0
  152. package/dist/tests/e2e/default-anonymous-exports.test.js.map +1 -0
  153. package/dist/tests/e2e/globals-microtask.test.d.ts +9 -0
  154. package/dist/tests/e2e/globals-microtask.test.js +37 -0
  155. package/dist/tests/e2e/globals-microtask.test.js.map +1 -0
  156. package/dist/tests/e2e/gui-media.test.js +8 -1
  157. package/dist/tests/e2e/gui-media.test.js.map +1 -1
  158. package/dist/tests/e2e/inspect-builtins.test.d.ts +10 -0
  159. package/dist/tests/e2e/inspect-builtins.test.js +43 -0
  160. package/dist/tests/e2e/inspect-builtins.test.js.map +1 -0
  161. package/dist/tests/e2e/json-builtin-objects.test.d.ts +9 -0
  162. package/dist/tests/e2e/json-builtin-objects.test.js +23 -0
  163. package/dist/tests/e2e/json-builtin-objects.test.js.map +1 -0
  164. package/dist/tests/e2e/json-circular.test.d.ts +6 -0
  165. package/dist/tests/e2e/json-circular.test.js +43 -0
  166. package/dist/tests/e2e/json-circular.test.js.map +1 -0
  167. package/dist/tests/e2e/json-parse-reviver.test.d.ts +6 -0
  168. package/dist/tests/e2e/json-parse-reviver.test.js +29 -0
  169. package/dist/tests/e2e/json-parse-reviver.test.js.map +1 -0
  170. package/dist/tests/e2e/json-stringify-replacer.test.d.ts +6 -0
  171. package/dist/tests/e2e/json-stringify-replacer.test.js +27 -0
  172. package/dist/tests/e2e/json-stringify-replacer.test.js.map +1 -0
  173. package/dist/tests/e2e/json-stringify-space.test.d.ts +6 -0
  174. package/dist/tests/e2e/json-stringify-space.test.js +23 -0
  175. package/dist/tests/e2e/json-stringify-space.test.js.map +1 -0
  176. package/dist/tests/e2e/method-dispatch-errors.test.d.ts +9 -0
  177. package/dist/tests/e2e/method-dispatch-errors.test.js +38 -0
  178. package/dist/tests/e2e/method-dispatch-errors.test.js.map +1 -0
  179. package/dist/tests/e2e/native-extensions.test.js +1 -1
  180. package/dist/tests/e2e/native-extensions.test.js.map +1 -1
  181. package/dist/tests/e2e/promise-with-resolvers.test.d.ts +5 -0
  182. package/dist/tests/e2e/promise-with-resolvers.test.js +20 -0
  183. package/dist/tests/e2e/promise-with-resolvers.test.js.map +1 -0
  184. package/dist/tests/e2e/property-descriptors.test.d.ts +5 -0
  185. package/dist/tests/e2e/property-descriptors.test.js +25 -0
  186. package/dist/tests/e2e/property-descriptors.test.js.map +1 -0
  187. package/dist/tests/e2e/property-ic.test.d.ts +1 -0
  188. package/dist/tests/e2e/property-ic.test.js +55 -0
  189. package/dist/tests/e2e/property-ic.test.js.map +1 -0
  190. package/dist/tests/e2e/runtime-coverage-globals.test.js +46 -0
  191. package/dist/tests/e2e/runtime-coverage-globals.test.js.map +1 -1
  192. package/dist/tests/e2e/runtime-errors.test.d.ts +10 -0
  193. package/dist/tests/e2e/runtime-errors.test.js +52 -0
  194. package/dist/tests/e2e/runtime-errors.test.js.map +1 -0
  195. package/dist/tests/e2e/string-utf16.test.d.ts +6 -0
  196. package/dist/tests/e2e/string-utf16.test.js +133 -0
  197. package/dist/tests/e2e/string-utf16.test.js.map +1 -0
  198. package/dist/tests/e2e/structured-clone.test.d.ts +6 -0
  199. package/dist/tests/e2e/structured-clone.test.js +49 -0
  200. package/dist/tests/e2e/structured-clone.test.js.map +1 -0
  201. package/dist/tests/e2e/text-codec.test.d.ts +6 -0
  202. package/dist/tests/e2e/text-codec.test.js +24 -0
  203. package/dist/tests/e2e/text-codec.test.js.map +1 -0
  204. package/dist/tests/e2e/typed-array-views.test.d.ts +6 -0
  205. package/dist/tests/e2e/typed-array-views.test.js +39 -0
  206. package/dist/tests/e2e/typed-array-views.test.js.map +1 -0
  207. package/dist/tests/e2e/url-search-params.test.d.ts +5 -0
  208. package/dist/tests/e2e/url-search-params.test.js +30 -0
  209. package/dist/tests/e2e/url-search-params.test.js.map +1 -0
  210. package/dist/tests/e2e/weak-collections.test.d.ts +1 -0
  211. package/dist/tests/e2e/weak-collections.test.js +88 -0
  212. package/dist/tests/e2e/weak-collections.test.js.map +1 -0
  213. package/dist/tests/parser/declarations.test.js +12 -0
  214. package/dist/tests/parser/declarations.test.js.map +1 -1
  215. package/dist/tests/parser/module-syntax.test.js +9 -0
  216. package/dist/tests/parser/module-syntax.test.js.map +1 -1
  217. package/dist/tests/parser/parser.test.js +7 -0
  218. package/dist/tests/parser/parser.test.js.map +1 -1
  219. package/dist/tests/version.test.js +5 -1
  220. package/dist/tests/version.test.js.map +1 -1
  221. package/doc/ai/README.md +4 -3
  222. package/doc/ai/cli.md +41 -0
  223. package/doc/ai/contributing.md +26 -21
  224. package/doc/ai/extensions.md +12 -9
  225. package/doc/ai/language-support.md +26 -19
  226. package/doc/ai/troubleshooting.md +15 -12
  227. package/doc/ai/zh-CN/README.md +3 -2
  228. package/doc/ai/zh-CN/cli.md +35 -0
  229. package/doc/ai/zh-CN/contributing.md +19 -18
  230. package/doc/ai/zh-CN/extensions.md +10 -7
  231. package/doc/ai/zh-CN/language-support.md +26 -20
  232. package/doc/ai/zh-CN/troubleshooting.md +12 -10
  233. package/doc/gui/build.md +13 -4
  234. package/doc/gui/known-issues.md +9 -5
  235. package/doc/gui/rendering.md +3 -1
  236. package/doc/gui.md +4 -3
  237. package/doc/icon.md +5 -4
  238. package/doc/implemented/async.md +38 -0
  239. package/doc/implemented/binder.md +13 -0
  240. package/doc/implemented/cli.md +47 -0
  241. package/doc/implemented/codegen.md +33 -0
  242. package/doc/implemented/collections.md +26 -0
  243. package/doc/implemented/driver.md +19 -0
  244. package/doc/implemented/extensions.md +19 -0
  245. package/doc/implemented/fetch.md +12 -0
  246. package/doc/implemented/lexer.md +23 -0
  247. package/doc/implemented/modules.md +28 -0
  248. package/doc/implemented/node/assert.md +17 -0
  249. package/doc/implemented/node/buffer.md +29 -0
  250. package/doc/implemented/node/child-process.md +29 -0
  251. package/doc/implemented/node/crypto.md +9 -0
  252. package/doc/implemented/node/dgram.md +15 -0
  253. package/doc/implemented/node/events.md +37 -0
  254. package/doc/implemented/node/fs-promises.md +38 -0
  255. package/doc/implemented/node/fs.md +112 -0
  256. package/doc/implemented/node/http.md +21 -0
  257. package/doc/implemented/node/net.md +17 -0
  258. package/doc/implemented/node/os.md +22 -0
  259. package/doc/implemented/node/path.md +33 -0
  260. package/doc/implemented/node/process.md +23 -0
  261. package/doc/implemented/node/querystring.md +20 -0
  262. package/doc/implemented/node/stream-promises.md +8 -0
  263. package/doc/implemented/node/stream.md +19 -0
  264. package/doc/implemented/node/test.md +10 -0
  265. package/doc/implemented/node/url.md +8 -0
  266. package/doc/implemented/node/util.md +25 -0
  267. package/doc/implemented/node/worker-threads.md +10 -0
  268. package/doc/implemented/node/zlib.md +8 -0
  269. package/doc/implemented/node.md +48 -0
  270. package/doc/implemented/operators.md +38 -0
  271. package/doc/implemented/parser.md +58 -0
  272. package/doc/implemented/pipeline.md +28 -0
  273. package/doc/implemented/runtime-core.md +32 -0
  274. package/doc/implemented/stdlib.md +78 -0
  275. package/doc/implemented/strings.md +27 -0
  276. package/doc/implemented/tests.md +10 -0
  277. package/doc/implemented/typed-arrays.md +26 -0
  278. package/doc/implemented/value-model.md +18 -0
  279. package/doc/implemented.md +54 -352
  280. package/doc/node-implemented.md +3 -585
  281. package/doc/node-unimplemented.md +3 -164
  282. package/doc/requirements.md +23 -8
  283. package/doc/unimplemented/classes.md +22 -0
  284. package/doc/unimplemented/deviations.md +27 -0
  285. package/doc/unimplemented/expressions.md +26 -0
  286. package/doc/unimplemented/functions.md +21 -0
  287. package/doc/unimplemented/modules.md +22 -0
  288. package/doc/unimplemented/node/async.md +17 -0
  289. package/doc/unimplemented/node/bun.md +9 -0
  290. package/doc/unimplemented/node/fs-promises.md +16 -0
  291. package/doc/unimplemented/node/fs.md +31 -0
  292. package/doc/unimplemented/node/globals.md +23 -0
  293. package/doc/unimplemented/node/modules.md +21 -0
  294. package/doc/unimplemented/node.md +21 -0
  295. package/doc/unimplemented/statements.md +18 -0
  296. package/doc/unimplemented/stdlib.md +54 -0
  297. package/doc/unimplemented/toolchain.md +14 -0
  298. package/doc/unimplemented/types.md +12 -0
  299. package/doc/unimplemented.md +18 -274
  300. package/doc/xbintsc.config.schema.json +12 -0
  301. package/doc/zh-CN/gui/build.md +11 -3
  302. package/doc/zh-CN/gui/known-issues.md +9 -4
  303. package/doc/zh-CN/gui/rendering.md +2 -1
  304. package/doc/zh-CN/gui.md +3 -2
  305. package/doc/zh-CN/icon.md +5 -4
  306. package/doc/zh-CN/implemented/async.md +38 -0
  307. package/doc/zh-CN/implemented/binder.md +13 -0
  308. package/doc/zh-CN/implemented/cli.md +46 -0
  309. package/doc/zh-CN/implemented/codegen.md +33 -0
  310. package/doc/zh-CN/implemented/collections.md +26 -0
  311. package/doc/zh-CN/implemented/driver.md +19 -0
  312. package/doc/zh-CN/implemented/extensions.md +19 -0
  313. package/doc/zh-CN/implemented/fetch.md +12 -0
  314. package/doc/zh-CN/implemented/lexer.md +23 -0
  315. package/doc/zh-CN/implemented/modules.md +28 -0
  316. package/doc/zh-CN/implemented/node/assert.md +17 -0
  317. package/doc/zh-CN/implemented/node/buffer.md +25 -0
  318. package/doc/zh-CN/implemented/node/child-process.md +27 -0
  319. package/doc/zh-CN/implemented/node/crypto.md +9 -0
  320. package/doc/zh-CN/implemented/node/dgram.md +15 -0
  321. package/doc/zh-CN/implemented/node/events.md +36 -0
  322. package/doc/zh-CN/implemented/node/fs-promises.md +27 -0
  323. package/doc/zh-CN/implemented/node/fs.md +105 -0
  324. package/doc/zh-CN/implemented/node/http.md +17 -0
  325. package/doc/zh-CN/implemented/node/net.md +17 -0
  326. package/doc/zh-CN/implemented/node/os.md +21 -0
  327. package/doc/zh-CN/implemented/node/path.md +26 -0
  328. package/doc/zh-CN/implemented/node/process.md +23 -0
  329. package/doc/zh-CN/implemented/node/querystring.md +20 -0
  330. package/doc/zh-CN/implemented/node/stream-promises.md +8 -0
  331. package/doc/zh-CN/implemented/node/stream.md +15 -0
  332. package/doc/zh-CN/implemented/node/test.md +10 -0
  333. package/doc/zh-CN/implemented/node/url.md +8 -0
  334. package/doc/zh-CN/implemented/node/util.md +25 -0
  335. package/doc/zh-CN/implemented/node/worker-threads.md +9 -0
  336. package/doc/zh-CN/implemented/node/zlib.md +8 -0
  337. package/doc/zh-CN/implemented/node.md +45 -0
  338. package/doc/zh-CN/implemented/operators.md +38 -0
  339. package/doc/zh-CN/implemented/parser.md +58 -0
  340. package/doc/zh-CN/implemented/pipeline.md +25 -0
  341. package/doc/zh-CN/implemented/runtime-core.md +31 -0
  342. package/doc/zh-CN/implemented/stdlib.md +76 -0
  343. package/doc/zh-CN/implemented/strings.md +27 -0
  344. package/doc/zh-CN/implemented/tests.md +10 -0
  345. package/doc/zh-CN/implemented/typed-arrays.md +26 -0
  346. package/doc/zh-CN/implemented/value-model.md +18 -0
  347. package/doc/zh-CN/implemented.md +50 -347
  348. package/doc/zh-CN/node-implemented.md +4 -531
  349. package/doc/zh-CN/node-unimplemented.md +4 -139
  350. package/doc/zh-CN/plan-require-node-modules.md +4 -4
  351. package/doc/zh-CN/requirements.md +20 -6
  352. package/doc/zh-CN/unimplemented/classes.md +22 -0
  353. package/doc/zh-CN/unimplemented/deviations.md +24 -0
  354. package/doc/zh-CN/unimplemented/expressions.md +24 -0
  355. package/doc/zh-CN/unimplemented/functions.md +21 -0
  356. package/doc/zh-CN/unimplemented/modules.md +19 -0
  357. package/doc/zh-CN/unimplemented/node/async.md +17 -0
  358. package/doc/zh-CN/unimplemented/node/bun.md +8 -0
  359. package/doc/zh-CN/unimplemented/node/fs-promises.md +12 -0
  360. package/doc/zh-CN/unimplemented/node/fs.md +24 -0
  361. package/doc/zh-CN/unimplemented/node/globals.md +14 -0
  362. package/doc/zh-CN/unimplemented/node/modules.md +15 -0
  363. package/doc/zh-CN/unimplemented/node.md +18 -0
  364. package/doc/zh-CN/unimplemented/statements.md +15 -0
  365. package/doc/zh-CN/unimplemented/stdlib.md +54 -0
  366. package/doc/zh-CN/unimplemented/toolchain.md +14 -0
  367. package/doc/zh-CN/unimplemented/types.md +11 -0
  368. package/doc/zh-CN/unimplemented.md +14 -236
  369. package/llms.txt +32 -4
  370. package/package.json +1 -1
  371. package/runtime/ext_gui/renderer_shaders.h +2 -2
  372. package/runtime/ext_gui/stb_image.h +1 -17
  373. package/runtime/ext_node/child_process/child_process.c +173 -73
  374. package/runtime/rt.h +47 -0
  375. package/runtime/rt_internal.h +205 -10
  376. package/runtime/xt_alloc.c +49 -7
  377. package/runtime/xt_array_buffer.c +284 -0
  378. package/runtime/xt_async.c +222 -0
  379. package/runtime/xt_bigint/helpers.inc +3 -3
  380. package/runtime/xt_builtins.c +59 -51
  381. package/runtime/xt_constructors.c +399 -0
  382. package/runtime/xt_containers/access.inc +195 -14
  383. package/runtime/xt_containers/arrays.inc +26 -2
  384. package/runtime/xt_containers/objects.inc +226 -5
  385. package/runtime/xt_containers/shapes.inc +71 -0
  386. package/runtime/xt_containers.c +1 -0
  387. package/runtime/xt_coroutine.c +229 -0
  388. package/runtime/xt_generator.c +325 -167
  389. package/runtime/xt_io/inspect.inc +147 -2
  390. package/runtime/xt_loop.c +35 -4
  391. package/runtime/xt_performance.c +37 -0
  392. package/runtime/xt_promise.c +125 -18
  393. package/runtime/xt_stdlib/arrays.inc +1 -1
  394. package/runtime/xt_stdlib/dispatch.inc +64 -13
  395. package/runtime/xt_stdlib/strings.inc +74 -17
  396. package/runtime/xt_stdlib2/array-statics.inc +28 -3
  397. package/runtime/xt_stdlib2/arrays.inc +5 -3
  398. package/runtime/xt_stdlib2/container.inc +5 -0
  399. package/runtime/xt_stdlib2/date.inc +111 -3
  400. package/runtime/xt_stdlib2/error.inc +35 -0
  401. package/runtime/xt_stdlib2/json.inc +353 -33
  402. package/runtime/xt_stdlib2/number-string-statics.inc +24 -15
  403. package/runtime/xt_stdlib2/objects.inc +123 -1
  404. package/runtime/xt_stdlib2/regexp-match.inc +2 -2
  405. package/runtime/xt_stdlib2/set.inc +7 -1
  406. package/runtime/xt_stdlib2/strings.inc +70 -40
  407. package/runtime/xt_structured_clone.c +159 -0
  408. package/runtime/xt_symbol.c +2 -2
  409. package/runtime/xt_text_codec.c +69 -0
  410. package/runtime/xt_typed_array/construction.inc +78 -7
  411. package/runtime/xt_typed_array/elements.inc +159 -0
  412. package/runtime/xt_typed_array/methods.inc +21 -5
  413. package/runtime/xt_typed_array.c +11 -10
  414. package/runtime/xt_url.c +375 -0
  415. package/runtime/xt_values/arithmetic.inc +2 -2
  416. package/runtime/xt_values/constructors.inc +8 -0
  417. package/runtime/xt_values/conversions.inc +1 -1
  418. package/runtime/xt_values/strings.inc +19 -3
  419. package/runtime/xt_values/utf16.inc +340 -0
  420. package/runtime/xt_values.c +1 -0
  421. package/runtime/xt_weak.c +281 -0
  422. package/scripts/build-gui.ts +133 -60
  423. package/scripts/check-version.ts +3 -3
  424. package/src/binder/declarations.ts +14 -3
  425. package/src/cli/hints.ts +8 -1
  426. package/src/cli/main.ts +119 -18
  427. package/src/cli/watch.ts +101 -0
  428. package/src/codegen/generator/calls/access.ts +17 -4
  429. package/src/codegen/generator/calls/closures.ts +12 -1
  430. package/src/codegen/generator/calls/invocation.ts +4 -3
  431. package/src/codegen/generator/context.ts +23 -3
  432. package/src/codegen/generator/expressions/operators.ts +27 -13
  433. package/src/codegen/generator/expressions/primary.ts +10 -1
  434. package/src/codegen/generator/module.ts +10 -19
  435. package/src/codegen/generator/numeric.ts +85 -11
  436. package/src/codegen/generator/state.ts +27 -0
  437. package/src/codegen/generator/statements/control-flow.ts +2 -6
  438. package/src/codegen/generator/statements/loops.ts +50 -16
  439. package/src/codegen/generator/tables.ts +110 -3
  440. package/src/diagnostics/diagnostic.ts +23 -3
  441. package/src/driver/app-artifacts.ts +77 -0
  442. package/src/driver/build-key.ts +55 -0
  443. package/src/driver/bundler/graph.ts +63 -13
  444. package/src/driver/bundler/merge.ts +4 -1
  445. package/src/driver/compiler.ts +93 -324
  446. package/src/driver/config.ts +11 -0
  447. package/src/driver/frontend.ts +120 -0
  448. package/src/driver/index.ts +0 -1
  449. package/src/driver/options.ts +70 -0
  450. package/src/driver/runtime-objects.ts +133 -0
  451. package/src/driver/toolchain-provider.ts +4 -0
  452. package/src/driver/toolchain.ts +154 -10
  453. package/src/driver/version.ts +12 -0
  454. package/src/driver/win-icon.ts +36 -36
  455. package/src/parser/declarations/classes.ts +4 -0
  456. package/src/parser/declarations/functions.ts +12 -1
  457. package/src/parser/modules.ts +8 -4
  458. package/src/parser/parser.ts +28 -0
@@ -2,15 +2,36 @@
2
2
  /* Output and inspection */
3
3
  /* ------------------------------------------------------------------------- */
4
4
 
5
+ /* Write UTF-8 bytes, turning a lone surrogate half (WTF-8) into U+FFFD. Node's
6
+ * terminal encoding does the same, so `console.log("😀"[0])` prints one
7
+ * replacement character instead of emitting invalid UTF-8. */
8
+ static void xt_print_utf8(FILE *out, const char *bytes, size_t length) {
9
+ size_t offset = 0;
10
+ while (offset < length) {
11
+ unsigned char c = (unsigned char)bytes[offset];
12
+ if (c == 0xED && offset + 2 < length) {
13
+ unsigned char second = (unsigned char)bytes[offset + 1];
14
+ unsigned char third = (unsigned char)bytes[offset + 2];
15
+ if (second >= 0xA0 && second <= 0xBF && third >= 0x80 && third <= 0xBF) {
16
+ fwrite("\xEF\xBF\xBD", 1, 3, out);
17
+ offset += 3;
18
+ continue;
19
+ }
20
+ }
21
+ fputc((int)c, out);
22
+ offset++;
23
+ }
24
+ }
25
+
5
26
  static void xt_print_value(xt_value v, FILE *out) {
6
27
  if (XT_IS_STRING(v)) {
7
28
  xt_string *s = xt_as_string(v);
8
- fwrite(xt_string_bytes(s), 1, s->length, out);
29
+ xt_print_utf8(out, xt_string_bytes(s), s->length);
9
30
  return;
10
31
  }
11
32
  xt_value text = xt_to_string(v);
12
33
  xt_string *s = xt_as_string(text);
13
- fwrite(xt_string_bytes(s), 1, s->length, out);
34
+ xt_print_utf8(out, xt_string_bytes(s), s->length);
14
35
  }
15
36
 
16
37
  void xt_print(xt_value v) { xt_print_value(v, stdout); }
@@ -83,6 +104,18 @@ static void xt_inspect_string(xt_string *s, FILE *out) {
83
104
  default:
84
105
  if (c == (unsigned char)quote) { fputc('\\', out); fputc(c, out); }
85
106
  else if (c < 0x20) fprintf(out, "\\x%02x", c);
107
+ else if (c == 0xED && i + 2 < s->length) {
108
+ unsigned char second = (unsigned char)bytes[i + 1];
109
+ unsigned char third = (unsigned char)bytes[i + 2];
110
+ if (second >= 0xA0 && second <= 0xBF && third >= 0x80 && third <= 0xBF) {
111
+ unsigned code = ((unsigned)(c & 0x0F) << 12) | ((unsigned)(second & 0x3F) << 6) |
112
+ (unsigned)(third & 0x3F);
113
+ fprintf(out, "\\u%04x", code);
114
+ i += 2;
115
+ } else {
116
+ fputc(c, out);
117
+ }
118
+ }
86
119
  else fputc(c, out);
87
120
  }
88
121
  }
@@ -146,8 +179,120 @@ static void xt_inspect(xt_value v, FILE *out, int nested) {
146
179
  xt_inspect_pop();
147
180
  return;
148
181
  }
182
+ int typedKind = xt_typed_array_kind_of(v);
183
+ if (typedKind >= 0) {
184
+ const char *name = xt_typed_array_name_of(typedKind);
185
+ uint32_t length = (uint32_t)xt_to_number(xt_get(v, xt_string_from_cstr("length")));
186
+ fprintf(out, "%s(%u) [", name ? name : "TypedArray", length);
187
+ for (uint32_t i = 0; i < length; i++) {
188
+ fputs(i == 0 ? " " : ", ", out);
189
+ xt_inspect(xt_typed_array_read(v, i), out, 1);
190
+ }
191
+ if (length > 0) fputc(' ', out);
192
+ fputc(']', out);
193
+ return;
194
+ }
149
195
  if (XT_IS_OBJECT(v)) {
150
196
  xt_object *obj = (xt_object *)XT_GET_PTR(v);
197
+ /* Map, Set, Date, RegExp, Promise, generators and iterators are heap
198
+ * objects with their own struct layouts, so treating them as `xt_object`
199
+ * and reading `count`/`properties` reads unrelated memory (it used to
200
+ * crash on a non-empty Map). Format each kind from its real fields. */
201
+ switch (obj->header.kind) {
202
+ case XT_OBJECT_KIND_MAP: {
203
+ xt_map *map = (xt_map *)obj;
204
+ int seenMap = xt_inspect_seen(map);
205
+ if (seenMap > 0) {
206
+ fprintf(out, "[Circular *%d]", seenMap);
207
+ return;
208
+ }
209
+ if (xt_inspect_depth >= XT_INSPECT_MAX_DEPTH) {
210
+ fputs("[Map]", out);
211
+ return;
212
+ }
213
+ xt_inspect_push(map);
214
+ fprintf(out, "Map(%u) {", map->count);
215
+ for (uint32_t i = 0; i < map->count; i++) {
216
+ fputs(i == 0 ? " " : ", ", out);
217
+ xt_inspect(map->keys[i], out, 1);
218
+ fputs(" => ", out);
219
+ xt_inspect(map->values[i], out, 1);
220
+ }
221
+ if (map->count > 0) fputc(' ', out);
222
+ fputc('}', out);
223
+ xt_inspect_pop();
224
+ return;
225
+ }
226
+ case XT_OBJECT_KIND_SET: {
227
+ xt_set_object *set = (xt_set_object *)obj;
228
+ int seenSet = xt_inspect_seen(set);
229
+ if (seenSet > 0) {
230
+ fprintf(out, "[Circular *%d]", seenSet);
231
+ return;
232
+ }
233
+ if (xt_inspect_depth >= XT_INSPECT_MAX_DEPTH) {
234
+ fputs("[Set]", out);
235
+ return;
236
+ }
237
+ xt_inspect_push(set);
238
+ fprintf(out, "Set(%u) {", set->count);
239
+ for (uint32_t i = 0; i < set->count; i++) {
240
+ fputs(i == 0 ? " " : ", ", out);
241
+ xt_inspect(set->values[i], out, 1);
242
+ }
243
+ if (set->count > 0) fputc(' ', out);
244
+ fputc('}', out);
245
+ xt_inspect_pop();
246
+ return;
247
+ }
248
+ case XT_OBJECT_KIND_DATE: {
249
+ /* `Date.prototype.toISOString` is the representation Node prints. */
250
+ xt_value text = xt_call_method(v, xt_string_from_cstr("toISOString"), 0, NULL);
251
+ xt_inspect(text, out, 0);
252
+ return;
253
+ }
254
+ case XT_OBJECT_KIND_REGEXP: {
255
+ xt_regexp *regexp = (xt_regexp *)obj;
256
+ fputc('/', out);
257
+ xt_inspect(regexp->source, out, 0);
258
+ fputc('/', out);
259
+ xt_inspect(regexp->flags, out, 0);
260
+ return;
261
+ }
262
+ case XT_OBJECT_KIND_PROMISE: {
263
+ int state = xt_promise_state_of(v);
264
+ fputs("Promise { ", out);
265
+ if (state == XT_PROMISE_PENDING) {
266
+ fputs("<pending>", out);
267
+ } else {
268
+ if (state == XT_PROMISE_REJECTED) fputs("<rejected> ", out);
269
+ xt_inspect(xt_promise_value_of(v), out, 1);
270
+ }
271
+ fputs(" }", out);
272
+ return;
273
+ }
274
+ case XT_OBJECT_KIND_WEAK_MAP:
275
+ fputs("WeakMap { <items unknown> }", out);
276
+ return;
277
+ case XT_OBJECT_KIND_WEAK_SET:
278
+ fputs("WeakSet { <items unknown> }", out);
279
+ return;
280
+ case XT_OBJECT_KIND_WEAK_REF:
281
+ fputs("WeakRef {}", out);
282
+ return;
283
+ case XT_OBJECT_KIND_GENERATOR:
284
+ fputs("Object [Generator] {}", out);
285
+ return;
286
+ case XT_OBJECT_KIND_ITERATOR:
287
+ case XT_OBJECT_KIND_ASYNC:
288
+ /* Internal helper objects have no useful user-visible shape. */
289
+ fputs("[object Object]", out);
290
+ return;
291
+ default:
292
+ /* XT_OBJECT_KIND_OBJECT and XT_OBJECT_KIND_ERROR share the property
293
+ * bag layout and fall through to the generic formatter below. */
294
+ break;
295
+ }
151
296
  int seen = xt_inspect_seen(obj);
152
297
  if (seen > 0) {
153
298
  fprintf(out, "[Circular *%d]", seen);
package/runtime/xt_loop.c CHANGED
@@ -88,8 +88,23 @@ static int64_t xt_loop_now_ms(void) {
88
88
  #endif
89
89
  }
90
90
 
91
- static void xt_loop_sleep_ms(int ms) {
92
- if (ms <= 0) return;
91
+ /* Fractional monotonic milliseconds for `performance.now()`. Kept separate from
92
+ * xt_loop_now_ms(), which only needs whole milliseconds for timer deadlines. */
93
+ double xt_monotonic_ms(void) {
94
+ #if defined(_WIN32)
95
+ static LARGE_INTEGER frequency;
96
+ if (frequency.QuadPart == 0) QueryPerformanceFrequency(&frequency);
97
+ LARGE_INTEGER counter;
98
+ QueryPerformanceCounter(&counter);
99
+ return (double)counter.QuadPart * 1000.0 / (double)frequency.QuadPart;
100
+ #else
101
+ struct timespec ts;
102
+ clock_gettime(CLOCK_MONOTONIC, &ts);
103
+ return (double)ts.tv_sec * 1000.0 + (double)ts.tv_nsec / 1000000.0;
104
+ #endif
105
+ }
106
+
107
+ static void xt_loop_sleep_ms(int ms) { if (ms <= 0) return;
93
108
  #if defined(_WIN32)
94
109
  Sleep((DWORD)ms);
95
110
  #else
@@ -228,7 +243,7 @@ static void xt_timer_run_due(void) {
228
243
  xt_value xt_set_timeout(int32_t argc, xt_value *argv) {
229
244
  xt_value callback = xt_arg_at(argc, argv, 0);
230
245
  if (!XT_IS_FUNCTION(callback)) {
231
- xt_throw(xt_string_from_cstr("TypeError: The \"callback\" argument must be of type function"));
246
+ xt_throw(xt_error_from_message("TypeError: The \"callback\" argument must be of type function"));
232
247
  return XT_UNDEFINED;
233
248
  }
234
249
  int64_t delay = xt_timer_delay_arg(xt_arg_at(argc, argv, 1));
@@ -240,7 +255,7 @@ xt_value xt_set_timeout(int32_t argc, xt_value *argv) {
240
255
  xt_value xt_set_interval(int32_t argc, xt_value *argv) {
241
256
  xt_value callback = xt_arg_at(argc, argv, 0);
242
257
  if (!XT_IS_FUNCTION(callback)) {
243
- xt_throw(xt_string_from_cstr("TypeError: The \"callback\" argument must be of type function"));
258
+ xt_throw(xt_error_from_message("TypeError: The \"callback\" argument must be of type function"));
244
259
  return XT_UNDEFINED;
245
260
  }
246
261
  int64_t delay = xt_timer_delay_arg(xt_arg_at(argc, argv, 1));
@@ -263,6 +278,22 @@ xt_value xt_clear_interval(int32_t argc, xt_value *argv) {
263
278
  return XT_UNDEFINED;
264
279
  }
265
280
 
281
+ xt_value xt_set_immediate(int32_t argc, xt_value *argv) {
282
+ xt_value callback = xt_arg_at(argc, argv, 0);
283
+ if (!XT_IS_FUNCTION(callback)) {
284
+ xt_value message = xt_string_from_cstr("The \"callback\" argument must be of type function");
285
+ xt_throw(xt_type_error_ctor(1, &message));
286
+ return XT_UNDEFINED;
287
+ }
288
+ int32_t extra = argc > 1 ? argc - 1 : 0;
289
+ uint64_t id = xt_timer_add(callback, 0, 0, extra, extra > 0 ? argv + 1 : NULL);
290
+ return xt_number((double)id);
291
+ }
292
+
293
+ xt_value xt_clear_immediate(int32_t argc, xt_value *argv) {
294
+ return xt_clear_timeout(argc, argv);
295
+ }
296
+
266
297
  int xt_loop_add(int fd, int events, xt_io_handler handler, void *userdata) {
267
298
  if (fd < 0 || !handler) return -1;
268
299
  xt_loop_gc_register();
@@ -0,0 +1,37 @@
1
+ /*
2
+ * xbintsc runtime — `performance.now()`.
3
+ *
4
+ * The namespace is dispatched two ways: `performance.now()` lowers to
5
+ * xt_performance_call(name, argc, argv), while reading the method as a value
6
+ * (`const now = performance.now`) goes through xt_performance_get(name), which
7
+ * returns a closure with the standard ABI. Both read the same monotonic clock.
8
+ */
9
+
10
+ #include "rt_internal.h"
11
+
12
+ #include <string.h>
13
+
14
+ static xt_value xt_performance_now_value(xt_value thisValue, xt_value env, int32_t argc,
15
+ xt_value *argv) {
16
+ (void)thisValue;
17
+ (void)env;
18
+ (void)argc;
19
+ (void)argv;
20
+ return xt_number(xt_monotonic_ms());
21
+ }
22
+
23
+ xt_value xt_performance_get(xt_value name) {
24
+ const char *key = xt_string_data(name);
25
+ if (key != NULL && strcmp(key, "now") == 0) {
26
+ return xt_closure_new((void *)xt_performance_now_value, 0, NULL);
27
+ }
28
+ return XT_UNDEFINED;
29
+ }
30
+
31
+ xt_value xt_performance_call(xt_value name, int32_t argc, xt_value *argv) {
32
+ (void)argc;
33
+ (void)argv;
34
+ const char *key = xt_string_data(name);
35
+ if (key != NULL && strcmp(key, "now") == 0) return xt_number(xt_monotonic_ms());
36
+ return XT_UNDEFINED;
37
+ }
@@ -1,10 +1,12 @@
1
1
  /*
2
- * xbintsc runtime — promises and async support.
2
+ * xbintsc runtime — promises and the microtask queue.
3
3
  *
4
- * There is no event loop in the runtime, so promises use a microtask queue
5
- * that the compiler drains when the program body finishes (and that `await`
6
- * drains on demand). This gives synchronous-looking `async`/`await` semantics
7
- * for the common case where every awaited value is already settled.
4
+ * Promise reactions are queued as microtasks and run when the program body
5
+ * finishes, by the event loop between callbacks, and on demand. `await` lives
6
+ * in `xt_async.c`: an `async` function runs on a coroutine, so awaiting a
7
+ * promise that is still pending suspends it and registers a waiter here. When
8
+ * the promise settles, the waiter becomes a microtask that resumes the
9
+ * coroutine. Everything is single-threaded and non-blocking.
8
10
  */
9
11
 
10
12
  #include "rt_internal.h"
@@ -12,10 +14,6 @@
12
14
  #include <stdlib.h>
13
15
  #include <string.h>
14
16
 
15
- #define XT_PROMISE_PENDING 0
16
- #define XT_PROMISE_FULFILLED 1
17
- #define XT_PROMISE_REJECTED 2
18
-
19
17
  typedef struct xt_promise xt_promise;
20
18
 
21
19
  typedef struct {
@@ -23,6 +21,9 @@ typedef struct {
23
21
  xt_value on_fulfilled;
24
22
  xt_value on_rejected;
25
23
  xt_promise *result;
24
+ /* Non-NULL for an `async` coroutine waiting on this promise. Such a reaction
25
+ * has no handlers: running it resumes the coroutine instead. */
26
+ void *async;
26
27
  } xt_reaction;
27
28
 
28
29
  struct xt_promise {
@@ -87,6 +88,7 @@ static void xt_promise_gc_scan_roots(void) {
87
88
  xt_gc_mark_value(reaction->on_fulfilled);
88
89
  xt_gc_mark_value(reaction->on_rejected);
89
90
  xt_gc_mark_header((xt_header *)reaction->result);
91
+ if (reaction->async) xt_gc_mark_header((xt_header *)reaction->async);
90
92
  }
91
93
  }
92
94
 
@@ -107,6 +109,7 @@ void xt_promise_gc_trace(xt_header *header) {
107
109
  xt_gc_mark_value(reaction->on_fulfilled);
108
110
  xt_gc_mark_value(reaction->on_rejected);
109
111
  xt_gc_mark_header((xt_header *)reaction->result);
112
+ if (reaction->async) xt_gc_mark_header((xt_header *)reaction->async);
110
113
  }
111
114
  }
112
115
 
@@ -133,6 +136,7 @@ static void xt_promise_resolve_into(xt_promise *result, xt_value value) {
133
136
  reaction->on_fulfilled = XT_UNDEFINED;
134
137
  reaction->on_rejected = XT_UNDEFINED;
135
138
  reaction->result = result;
139
+ reaction->async = NULL;
136
140
  if (other->reaction_count >= other->reaction_capacity) {
137
141
  other->reaction_capacity = other->reaction_capacity == 0 ? 4 : other->reaction_capacity * 2;
138
142
  other->reactions = (xt_reaction **)realloc(other->reactions, sizeof(xt_reaction *) * other->reaction_capacity);
@@ -156,6 +160,16 @@ static xt_value xt_promise_run_reactions(void) {
156
160
  while (xt_microtask_head < xt_microtask_count) {
157
161
  xt_reaction *reaction = xt_microtasks[xt_microtask_head++];
158
162
  xt_promise *promise = reaction->promise;
163
+ if (reaction->async) {
164
+ /* A suspended `async` coroutine: resume it with the settled value. It
165
+ * runs until it completes or awaits another pending promise. */
166
+ void *async = reaction->async;
167
+ int rejected = promise->state == XT_PROMISE_REJECTED;
168
+ xt_value settled = promise->value;
169
+ free(reaction);
170
+ xt_async_wake(async, settled, rejected);
171
+ continue;
172
+ }
159
173
  xt_value handler = promise->state == XT_PROMISE_FULFILLED ? reaction->on_fulfilled : reaction->on_rejected;
160
174
  if (XT_IS_FUNCTION(handler)) {
161
175
  xt_value arg = promise->value;
@@ -181,16 +195,63 @@ void xt_drain_microtasks(void) {
181
195
  }
182
196
  }
183
197
 
184
- xt_value xt_await(xt_value value) {
198
+ /* -- helpers used by the async coroutine runtime -------------------------- */
199
+
200
+ xt_value xt_promise_create(void) { return xt_promise_value(xt_promise_new()); }
201
+
202
+ /* Queue a microtask that resumes a suspended async coroutine with an already
203
+ * settled value. Reusing a reaction keeps FIFO order with pending `.then`
204
+ * callbacks (the specification always yields once per `await`). */
205
+ void xt_promise_queue_async_wake(void *asyncPointer, xt_value settled, int rejected) {
206
+ xt_promise *promise = xt_promise_new();
207
+ promise->state = rejected ? XT_PROMISE_REJECTED : XT_PROMISE_FULFILLED;
208
+ promise->value = settled;
209
+ xt_reaction *reaction = (xt_reaction *)malloc(sizeof(xt_reaction));
210
+ if (!reaction) abort();
211
+ reaction->promise = promise;
212
+ reaction->on_fulfilled = XT_UNDEFINED;
213
+ reaction->on_rejected = XT_UNDEFINED;
214
+ reaction->result = NULL;
215
+ reaction->async = asyncPointer;
216
+ xt_microtask_push(reaction);
217
+ }
218
+
219
+ void xt_promise_fulfill(xt_value promise, xt_value value) {
220
+ xt_promise *target = xt_as_promise(promise);
221
+ if (target) xt_promise_resolve_into(target, value);
222
+ }
223
+
224
+ void xt_promise_reject_value(xt_value promise, xt_value value) {
225
+ xt_promise *target = xt_as_promise(promise);
226
+ if (target) xt_promise_settle(target, XT_PROMISE_REJECTED, value);
227
+ }
228
+
229
+ int xt_promise_state_of(xt_value value) {
185
230
  xt_promise *promise = xt_as_promise(value);
186
- if (!promise) return value;
187
- int guard = 0;
188
- while (promise->state == XT_PROMISE_PENDING && guard++ < 100000) xt_drain_microtasks();
189
- if (promise->state == XT_PROMISE_REJECTED) {
190
- xt_throw(promise->value);
191
- return XT_UNDEFINED;
231
+ return promise ? promise->state : -1;
232
+ }
233
+
234
+ xt_value xt_promise_value_of(xt_value value) {
235
+ xt_promise *promise = xt_as_promise(value);
236
+ return promise ? promise->value : value;
237
+ }
238
+
239
+ void xt_promise_add_async_waiter(xt_value promiseValue, void *async) {
240
+ xt_promise *promise = xt_as_promise(promiseValue);
241
+ if (!promise || promise->state != XT_PROMISE_PENDING) return;
242
+ xt_reaction *reaction = (xt_reaction *)malloc(sizeof(xt_reaction));
243
+ if (!reaction) abort();
244
+ reaction->promise = promise;
245
+ reaction->on_fulfilled = XT_UNDEFINED;
246
+ reaction->on_rejected = XT_UNDEFINED;
247
+ reaction->result = NULL;
248
+ reaction->async = async;
249
+ if (promise->reaction_count >= promise->reaction_capacity) {
250
+ promise->reaction_capacity = promise->reaction_capacity == 0 ? 4 : promise->reaction_capacity * 2;
251
+ promise->reactions = (xt_reaction **)realloc(promise->reactions, sizeof(xt_reaction *) * promise->reaction_capacity);
252
+ if (!promise->reactions) abort();
192
253
  }
193
- return promise->value;
254
+ promise->reactions[promise->reaction_count++] = reaction;
194
255
  }
195
256
 
196
257
  /* -- C-callable resolve / reject ------------------------------------------ */
@@ -243,9 +304,34 @@ xt_value xt_promise_reject(xt_value value) {
243
304
  return xt_promise_value(promise);
244
305
  }
245
306
 
307
+ static xt_value xt_promise_with_resolvers_resolve(xt_value thisValue, xt_value env, int32_t argc,
308
+ xt_value *argv) {
309
+ (void)thisValue;
310
+ xt_promise_fulfill(xt_closure_env(env, 0), xt_arg_at(argc, argv, 0));
311
+ return XT_UNDEFINED;
312
+ }
313
+
314
+ static xt_value xt_promise_with_resolvers_reject(xt_value thisValue, xt_value env, int32_t argc,
315
+ xt_value *argv) {
316
+ (void)thisValue;
317
+ xt_promise_reject_value(xt_closure_env(env, 0), xt_arg_at(argc, argv, 0));
318
+ return XT_UNDEFINED;
319
+ }
320
+
246
321
  xt_value xt_promise_static(xt_value name, int32_t argc, xt_value *argv) {
247
322
  const char *fn = xt_string_data(name);
248
323
  if (!fn) return XT_UNDEFINED;
324
+ if (strcmp(fn, "withResolvers") == 0) {
325
+ xt_value promise = xt_promise_create();
326
+ xt_value environment[1] = {promise};
327
+ xt_value result = xt_object_new();
328
+ xt_object_set(result, xt_string_from_cstr("promise"), promise);
329
+ xt_object_set(result, xt_string_from_cstr("resolve"),
330
+ xt_closure_new((void *)xt_promise_with_resolvers_resolve, 1, environment));
331
+ xt_object_set(result, xt_string_from_cstr("reject"),
332
+ xt_closure_new((void *)xt_promise_with_resolvers_reject, 1, environment));
333
+ return result;
334
+ }
249
335
  if (strcmp(fn, "resolve") == 0) return xt_promise_resolve(xt_arg_at(argc, argv, 0));
250
336
  if (strcmp(fn, "reject") == 0) return xt_promise_reject(xt_arg_at(argc, argv, 0));
251
337
  if (strcmp(fn, "all") == 0 || strcmp(fn, "allSettled") == 0 || strcmp(fn, "race") == 0 || strcmp(fn, "any") == 0) {
@@ -277,7 +363,12 @@ xt_value xt_promise_static(xt_value name, int32_t argc, xt_value *argv) {
277
363
  xt_promise_settle(result, XT_PROMISE_REJECTED, inner->value);
278
364
  return xt_promise_value(result);
279
365
  }
280
- xt_value settled = xt_await(item);
366
+ xt_value settled;
367
+ if (xt_promise_state_of(item) == XT_PROMISE_FULFILLED) {
368
+ settled = xt_promise_value_of(item);
369
+ } else {
370
+ settled = xt_await(item);
371
+ }
281
372
  if (strcmp(fn, "any") == 0 || strcmp(fn, "race") == 0) {
282
373
  xt_promise_settle(result, XT_PROMISE_FULFILLED, settled);
283
374
  return xt_promise_value(result);
@@ -316,6 +407,7 @@ xt_value xt_promise_method(xt_value target, const char *method, int32_t argc, xt
316
407
  reaction->on_fulfilled = xt_arg_at(argc, argv, 0);
317
408
  reaction->on_rejected = xt_arg_at(argc, argv, 1);
318
409
  reaction->result = result;
410
+ reaction->async = NULL;
319
411
  if (promise->state == XT_PROMISE_PENDING) {
320
412
  if (promise->reaction_count >= promise->reaction_capacity) {
321
413
  promise->reaction_capacity = promise->reaction_capacity == 0 ? 4 : promise->reaction_capacity * 2;
@@ -341,3 +433,18 @@ xt_value xt_promise_method(xt_value target, const char *method, int32_t argc, xt
341
433
  *handled = 0;
342
434
  return XT_UNDEFINED;
343
435
  }
436
+
437
+ xt_value xt_queue_microtask(int32_t argc, xt_value *argv) {
438
+ xt_value callback = xt_arg_at(argc, argv, 0);
439
+ if (!XT_IS_FUNCTION(callback)) {
440
+ xt_value message = xt_string_from_cstr("The \"callback\" argument must be of type function");
441
+ xt_throw(xt_type_error_ctor(1, &message));
442
+ return XT_UNDEFINED;
443
+ }
444
+ /* Reuse the promise reaction queue: a settled promise's `then` callback is
445
+ * exactly a microtask, and it keeps FIFO order with pending `.then`s. */
446
+ xt_value promise = xt_promise_resolve(XT_UNDEFINED);
447
+ int handled = 0;
448
+ xt_promise_method(promise, "then", 1, &callback, &handled);
449
+ return XT_UNDEFINED;
450
+ }
@@ -150,7 +150,7 @@ static xt_value xt_array_reduce(xt_value value, xt_value fn, int32_t hasInitial,
150
150
  accumulator = array->items[0];
151
151
  i = 1;
152
152
  } else {
153
- xt_throw(xt_string_from_cstr("TypeError: Reduce of empty array with no initial value"));
153
+ xt_throw(xt_error_from_message("TypeError: Reduce of empty array with no initial value"));
154
154
  return XT_UNDEFINED;
155
155
  }
156
156
  for (; i < array->length; i++) {