xbintsc 0.5.6 → 0.5.21

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 (490) hide show
  1. package/AGENTS.md +20 -10
  2. package/README.md +8 -7
  3. package/README.zh-CN.md +6 -6
  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 +11 -2
  14. package/dist/src/codegen/generator/calls/access.js.map +1 -1
  15. package/dist/src/codegen/generator/calls/closures.js +12 -4
  16. package/dist/src/codegen/generator/calls/closures.js.map +1 -1
  17. package/dist/src/codegen/generator/context.d.ts +8 -0
  18. package/dist/src/codegen/generator/context.js +22 -3
  19. package/dist/src/codegen/generator/context.js.map +1 -1
  20. package/dist/src/codegen/generator/expressions/operators.js +17 -15
  21. package/dist/src/codegen/generator/expressions/operators.js.map +1 -1
  22. package/dist/src/codegen/generator/expressions/primary.js +5 -0
  23. package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
  24. package/dist/src/codegen/generator/module.js +0 -7
  25. package/dist/src/codegen/generator/module.js.map +1 -1
  26. package/dist/src/codegen/generator/numeric.d.ts +6 -3
  27. package/dist/src/codegen/generator/numeric.js +54 -11
  28. package/dist/src/codegen/generator/numeric.js.map +1 -1
  29. package/dist/src/codegen/generator/state.js +23 -0
  30. package/dist/src/codegen/generator/state.js.map +1 -1
  31. package/dist/src/codegen/generator/statements/control-flow.js +1 -4
  32. package/dist/src/codegen/generator/statements/control-flow.js.map +1 -1
  33. package/dist/src/codegen/generator/statements/loops.js +48 -16
  34. package/dist/src/codegen/generator/statements/loops.js.map +1 -1
  35. package/dist/src/codegen/generator/tables.js +26 -1
  36. package/dist/src/codegen/generator/tables.js.map +1 -1
  37. package/dist/src/diagnostics/diagnostic.d.ts +3 -1
  38. package/dist/src/diagnostics/diagnostic.js +23 -3
  39. package/dist/src/diagnostics/diagnostic.js.map +1 -1
  40. package/dist/src/driver/app-artifacts.d.ts +42 -0
  41. package/dist/src/driver/app-artifacts.js +53 -0
  42. package/dist/src/driver/app-artifacts.js.map +1 -0
  43. package/dist/src/driver/build-key.d.ts +29 -0
  44. package/dist/src/driver/build-key.js +35 -0
  45. package/dist/src/driver/build-key.js.map +1 -0
  46. package/dist/src/driver/bundler/graph.js +61 -12
  47. package/dist/src/driver/bundler/graph.js.map +1 -1
  48. package/dist/src/driver/bundler/merge.js +7 -1
  49. package/dist/src/driver/bundler/merge.js.map +1 -1
  50. package/dist/src/driver/compiler.d.ts +10 -67
  51. package/dist/src/driver/compiler.js +95 -234
  52. package/dist/src/driver/compiler.js.map +1 -1
  53. package/dist/src/driver/config.d.ts +3 -0
  54. package/dist/src/driver/config.js +8 -0
  55. package/dist/src/driver/config.js.map +1 -1
  56. package/dist/src/driver/frontend.d.ts +37 -0
  57. package/dist/src/driver/frontend.js +92 -0
  58. package/dist/src/driver/frontend.js.map +1 -0
  59. package/dist/src/driver/index.d.ts +1 -1
  60. package/dist/src/driver/index.js.map +1 -1
  61. package/dist/src/driver/options.d.ts +64 -0
  62. package/dist/src/driver/options.js +9 -0
  63. package/dist/src/driver/options.js.map +1 -0
  64. package/dist/src/driver/runtime-objects.d.ts +38 -0
  65. package/dist/src/driver/runtime-objects.js +112 -0
  66. package/dist/src/driver/runtime-objects.js.map +1 -0
  67. package/dist/src/driver/toolchain-provider.d.ts +4 -0
  68. package/dist/src/driver/toolchain-provider.js +4 -0
  69. package/dist/src/driver/toolchain-provider.js.map +1 -1
  70. package/dist/src/driver/toolchain.d.ts +32 -1
  71. package/dist/src/driver/toolchain.js +115 -11
  72. package/dist/src/driver/toolchain.js.map +1 -1
  73. package/dist/src/driver/version.d.ts +12 -0
  74. package/dist/src/driver/version.js +13 -0
  75. package/dist/src/driver/version.js.map +1 -0
  76. package/dist/src/driver/win-icon.d.ts +7 -9
  77. package/dist/src/driver/win-icon.js +37 -35
  78. package/dist/src/driver/win-icon.js.map +1 -1
  79. package/dist/src/extensions/node/fs/index.d.ts +4 -3
  80. package/dist/src/extensions/node/fs/index.js +12 -3
  81. package/dist/src/extensions/node/fs/index.js.map +1 -1
  82. package/dist/src/extensions/node/fs-promises/index.d.ts +5 -5
  83. package/dist/src/extensions/node/fs-promises/index.js +15 -6
  84. package/dist/src/extensions/node/fs-promises/index.js.map +1 -1
  85. package/dist/src/parser/declarations/classes.js +5 -0
  86. package/dist/src/parser/declarations/classes.js.map +1 -1
  87. package/dist/src/parser/declarations/functions.js +13 -1
  88. package/dist/src/parser/declarations/functions.js.map +1 -1
  89. package/dist/src/parser/modules.js +8 -3
  90. package/dist/src/parser/modules.js.map +1 -1
  91. package/dist/src/parser/parser.d.ts +1 -0
  92. package/dist/src/parser/parser.js +23 -0
  93. package/dist/src/parser/parser.js.map +1 -1
  94. package/dist/tests/cli/check.test.d.ts +6 -0
  95. package/dist/tests/cli/check.test.js +68 -0
  96. package/dist/tests/cli/check.test.js.map +1 -0
  97. package/dist/tests/cli/main.test.js +19 -0
  98. package/dist/tests/cli/main.test.js.map +1 -1
  99. package/dist/tests/cli/watch.test.d.ts +6 -0
  100. package/dist/tests/cli/watch.test.js +72 -0
  101. package/dist/tests/cli/watch.test.js.map +1 -0
  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.js +1 -1
  136. package/dist/tests/e2e/async-fs.test.d.ts +9 -0
  137. package/dist/tests/e2e/async-fs.test.js +119 -0
  138. package/dist/tests/e2e/async-fs.test.js.map +1 -0
  139. package/dist/tests/e2e/async-generators.test.d.ts +1 -0
  140. package/dist/tests/e2e/async-generators.test.js +154 -0
  141. package/dist/tests/e2e/async-generators.test.js.map +1 -0
  142. package/dist/tests/e2e/await-ordering.test.d.ts +5 -0
  143. package/dist/tests/e2e/await-ordering.test.js +37 -0
  144. package/dist/tests/e2e/await-ordering.test.js.map +1 -0
  145. package/dist/tests/e2e/compile-builtins.test.js +1 -1
  146. package/dist/tests/e2e/compile-modules.test.js +7 -0
  147. package/dist/tests/e2e/compile-modules.test.js.map +1 -1
  148. package/dist/tests/e2e/date-parse.test.d.ts +8 -0
  149. package/dist/tests/e2e/date-parse.test.js +38 -0
  150. package/dist/tests/e2e/date-parse.test.js.map +1 -0
  151. package/dist/tests/e2e/default-anonymous-exports.test.d.ts +7 -0
  152. package/dist/tests/e2e/default-anonymous-exports.test.js +23 -0
  153. package/dist/tests/e2e/default-anonymous-exports.test.js.map +1 -0
  154. package/dist/tests/e2e/fetch.test.js +24 -0
  155. package/dist/tests/e2e/fetch.test.js.map +1 -1
  156. package/dist/tests/e2e/globals-microtask.test.d.ts +9 -0
  157. package/dist/tests/e2e/globals-microtask.test.js +37 -0
  158. package/dist/tests/e2e/globals-microtask.test.js.map +1 -0
  159. package/dist/tests/e2e/gui-inline-svg.test.d.ts +11 -0
  160. package/dist/tests/e2e/gui-inline-svg.test.js +160 -0
  161. package/dist/tests/e2e/gui-inline-svg.test.js.map +1 -0
  162. package/dist/tests/e2e/gui-media.test.js +8 -1
  163. package/dist/tests/e2e/gui-media.test.js.map +1 -1
  164. package/dist/tests/e2e/inspect-builtins.test.d.ts +10 -0
  165. package/dist/tests/e2e/inspect-builtins.test.js +43 -0
  166. package/dist/tests/e2e/inspect-builtins.test.js.map +1 -0
  167. package/dist/tests/e2e/json-builtin-objects.test.d.ts +9 -0
  168. package/dist/tests/e2e/json-builtin-objects.test.js +23 -0
  169. package/dist/tests/e2e/json-builtin-objects.test.js.map +1 -0
  170. package/dist/tests/e2e/json-circular.test.d.ts +6 -0
  171. package/dist/tests/e2e/json-circular.test.js +43 -0
  172. package/dist/tests/e2e/json-circular.test.js.map +1 -0
  173. package/dist/tests/e2e/json-parse-reviver.test.d.ts +6 -0
  174. package/dist/tests/e2e/json-parse-reviver.test.js +29 -0
  175. package/dist/tests/e2e/json-parse-reviver.test.js.map +1 -0
  176. package/dist/tests/e2e/json-stringify-replacer.test.d.ts +6 -0
  177. package/dist/tests/e2e/json-stringify-replacer.test.js +27 -0
  178. package/dist/tests/e2e/json-stringify-replacer.test.js.map +1 -0
  179. package/dist/tests/e2e/json-stringify-space.test.d.ts +6 -0
  180. package/dist/tests/e2e/json-stringify-space.test.js +23 -0
  181. package/dist/tests/e2e/json-stringify-space.test.js.map +1 -0
  182. package/dist/tests/e2e/method-dispatch-errors.test.d.ts +9 -0
  183. package/dist/tests/e2e/method-dispatch-errors.test.js +38 -0
  184. package/dist/tests/e2e/method-dispatch-errors.test.js.map +1 -0
  185. package/dist/tests/e2e/native-extensions.test.js +1 -1
  186. package/dist/tests/e2e/native-extensions.test.js.map +1 -1
  187. package/dist/tests/e2e/promise-with-resolvers.test.d.ts +5 -0
  188. package/dist/tests/e2e/promise-with-resolvers.test.js +20 -0
  189. package/dist/tests/e2e/promise-with-resolvers.test.js.map +1 -0
  190. package/dist/tests/e2e/property-descriptors.test.d.ts +5 -0
  191. package/dist/tests/e2e/property-descriptors.test.js +25 -0
  192. package/dist/tests/e2e/property-descriptors.test.js.map +1 -0
  193. package/dist/tests/e2e/property-ic.test.d.ts +1 -0
  194. package/dist/tests/e2e/property-ic.test.js +55 -0
  195. package/dist/tests/e2e/property-ic.test.js.map +1 -0
  196. package/dist/tests/e2e/runtime-errors.test.d.ts +10 -0
  197. package/dist/tests/e2e/runtime-errors.test.js +52 -0
  198. package/dist/tests/e2e/runtime-errors.test.js.map +1 -0
  199. package/dist/tests/e2e/structured-clone.test.d.ts +6 -0
  200. package/dist/tests/e2e/structured-clone.test.js +49 -0
  201. package/dist/tests/e2e/structured-clone.test.js.map +1 -0
  202. package/dist/tests/e2e/text-codec.test.d.ts +6 -0
  203. package/dist/tests/e2e/text-codec.test.js +24 -0
  204. package/dist/tests/e2e/text-codec.test.js.map +1 -0
  205. package/dist/tests/e2e/typed-array-views.test.d.ts +6 -0
  206. package/dist/tests/e2e/typed-array-views.test.js +39 -0
  207. package/dist/tests/e2e/typed-array-views.test.js.map +1 -0
  208. package/dist/tests/e2e/url-search-params.test.d.ts +5 -0
  209. package/dist/tests/e2e/url-search-params.test.js +30 -0
  210. package/dist/tests/e2e/url-search-params.test.js.map +1 -0
  211. package/dist/tests/e2e/weak-collections.test.d.ts +1 -0
  212. package/dist/tests/e2e/weak-collections.test.js +88 -0
  213. package/dist/tests/e2e/weak-collections.test.js.map +1 -0
  214. package/dist/tests/parser/declarations.test.js +12 -0
  215. package/dist/tests/parser/declarations.test.js.map +1 -1
  216. package/dist/tests/parser/module-syntax.test.js +9 -0
  217. package/dist/tests/parser/module-syntax.test.js.map +1 -1
  218. package/dist/tests/parser/parser.test.js +7 -0
  219. package/dist/tests/parser/parser.test.js.map +1 -1
  220. package/dist/tests/version.test.js +5 -1
  221. package/dist/tests/version.test.js.map +1 -1
  222. package/doc/ai/README.md +4 -3
  223. package/doc/ai/cli.md +41 -0
  224. package/doc/ai/contributing.md +20 -16
  225. package/doc/ai/extensions.md +13 -10
  226. package/doc/ai/language-support.md +19 -14
  227. package/doc/ai/troubleshooting.md +11 -9
  228. package/doc/ai/zh-CN/README.md +3 -2
  229. package/doc/ai/zh-CN/cli.md +35 -0
  230. package/doc/ai/zh-CN/contributing.md +16 -15
  231. package/doc/ai/zh-CN/extensions.md +12 -9
  232. package/doc/ai/zh-CN/language-support.md +19 -15
  233. package/doc/ai/zh-CN/troubleshooting.md +9 -8
  234. package/doc/gui/api.md +8 -0
  235. package/doc/gui/build.md +13 -4
  236. package/doc/gui/known-issues.md +19 -14
  237. package/doc/gui/media.md +32 -3
  238. package/doc/gui/rendering.md +3 -1
  239. package/doc/gui.md +28 -5
  240. package/doc/icon.md +5 -4
  241. package/doc/implemented/async.md +51 -0
  242. package/doc/implemented/binder.md +13 -0
  243. package/doc/implemented/cli.md +47 -0
  244. package/doc/implemented/codegen.md +33 -0
  245. package/doc/implemented/collections.md +26 -0
  246. package/doc/implemented/driver.md +19 -0
  247. package/doc/implemented/extensions.md +19 -0
  248. package/doc/implemented/fetch.md +44 -0
  249. package/doc/implemented/lexer.md +23 -0
  250. package/doc/implemented/modules.md +28 -0
  251. package/doc/implemented/node/assert.md +17 -0
  252. package/doc/implemented/node/buffer.md +29 -0
  253. package/doc/implemented/node/child-process.md +29 -0
  254. package/doc/implemented/node/crypto.md +9 -0
  255. package/doc/implemented/node/dgram.md +15 -0
  256. package/doc/implemented/node/events.md +37 -0
  257. package/doc/implemented/node/fs-promises.md +49 -0
  258. package/doc/implemented/node/fs.md +112 -0
  259. package/doc/implemented/node/http.md +21 -0
  260. package/doc/implemented/node/net.md +17 -0
  261. package/doc/implemented/node/os.md +22 -0
  262. package/doc/implemented/node/path.md +33 -0
  263. package/doc/implemented/node/process.md +23 -0
  264. package/doc/implemented/node/querystring.md +20 -0
  265. package/doc/implemented/node/stream-promises.md +8 -0
  266. package/doc/implemented/node/stream.md +19 -0
  267. package/doc/implemented/node/test.md +10 -0
  268. package/doc/implemented/node/url.md +8 -0
  269. package/doc/implemented/node/util.md +25 -0
  270. package/doc/implemented/node/worker-threads.md +10 -0
  271. package/doc/implemented/node/zlib.md +8 -0
  272. package/doc/implemented/node.md +48 -0
  273. package/doc/implemented/operators.md +38 -0
  274. package/doc/implemented/parser.md +58 -0
  275. package/doc/implemented/pipeline.md +28 -0
  276. package/doc/implemented/runtime-core.md +32 -0
  277. package/doc/implemented/stdlib.md +78 -0
  278. package/doc/implemented/strings.md +27 -0
  279. package/doc/implemented/tests.md +10 -0
  280. package/doc/implemented/typed-arrays.md +26 -0
  281. package/doc/implemented/value-model.md +18 -0
  282. package/doc/implemented.md +54 -355
  283. package/doc/node-implemented.md +3 -585
  284. package/doc/node-unimplemented.md +3 -164
  285. package/doc/requirements.md +23 -8
  286. package/doc/unimplemented/classes.md +22 -0
  287. package/doc/unimplemented/deviations.md +27 -0
  288. package/doc/unimplemented/expressions.md +26 -0
  289. package/doc/unimplemented/functions.md +21 -0
  290. package/doc/unimplemented/modules.md +22 -0
  291. package/doc/unimplemented/node/async.md +20 -0
  292. package/doc/unimplemented/node/bun.md +9 -0
  293. package/doc/unimplemented/node/fs-promises.md +20 -0
  294. package/doc/unimplemented/node/fs.md +30 -0
  295. package/doc/unimplemented/node/globals.md +23 -0
  296. package/doc/unimplemented/node/modules.md +21 -0
  297. package/doc/unimplemented/node.md +21 -0
  298. package/doc/unimplemented/statements.md +18 -0
  299. package/doc/unimplemented/stdlib.md +54 -0
  300. package/doc/unimplemented/toolchain.md +14 -0
  301. package/doc/unimplemented/types.md +12 -0
  302. package/doc/unimplemented.md +18 -275
  303. package/doc/xbintsc.config.schema.json +12 -0
  304. package/doc/zh-CN/gui/api.md +7 -0
  305. package/doc/zh-CN/gui/build.md +11 -3
  306. package/doc/zh-CN/gui/known-issues.md +17 -11
  307. package/doc/zh-CN/gui/media.md +26 -2
  308. package/doc/zh-CN/gui/rendering.md +2 -1
  309. package/doc/zh-CN/gui.md +21 -3
  310. package/doc/zh-CN/icon.md +5 -4
  311. package/doc/zh-CN/implemented/async.md +49 -0
  312. package/doc/zh-CN/implemented/binder.md +13 -0
  313. package/doc/zh-CN/implemented/cli.md +46 -0
  314. package/doc/zh-CN/implemented/codegen.md +33 -0
  315. package/doc/zh-CN/implemented/collections.md +26 -0
  316. package/doc/zh-CN/implemented/driver.md +19 -0
  317. package/doc/zh-CN/implemented/extensions.md +19 -0
  318. package/doc/zh-CN/implemented/fetch.md +31 -0
  319. package/doc/zh-CN/implemented/lexer.md +23 -0
  320. package/doc/zh-CN/implemented/modules.md +28 -0
  321. package/doc/zh-CN/implemented/node/assert.md +17 -0
  322. package/doc/zh-CN/implemented/node/buffer.md +25 -0
  323. package/doc/zh-CN/implemented/node/child-process.md +27 -0
  324. package/doc/zh-CN/implemented/node/crypto.md +9 -0
  325. package/doc/zh-CN/implemented/node/dgram.md +15 -0
  326. package/doc/zh-CN/implemented/node/events.md +36 -0
  327. package/doc/zh-CN/implemented/node/fs-promises.md +30 -0
  328. package/doc/zh-CN/implemented/node/fs.md +105 -0
  329. package/doc/zh-CN/implemented/node/http.md +17 -0
  330. package/doc/zh-CN/implemented/node/net.md +17 -0
  331. package/doc/zh-CN/implemented/node/os.md +21 -0
  332. package/doc/zh-CN/implemented/node/path.md +26 -0
  333. package/doc/zh-CN/implemented/node/process.md +23 -0
  334. package/doc/zh-CN/implemented/node/querystring.md +20 -0
  335. package/doc/zh-CN/implemented/node/stream-promises.md +8 -0
  336. package/doc/zh-CN/implemented/node/stream.md +15 -0
  337. package/doc/zh-CN/implemented/node/test.md +10 -0
  338. package/doc/zh-CN/implemented/node/url.md +8 -0
  339. package/doc/zh-CN/implemented/node/util.md +25 -0
  340. package/doc/zh-CN/implemented/node/worker-threads.md +9 -0
  341. package/doc/zh-CN/implemented/node/zlib.md +8 -0
  342. package/doc/zh-CN/implemented/node.md +45 -0
  343. package/doc/zh-CN/implemented/operators.md +38 -0
  344. package/doc/zh-CN/implemented/parser.md +58 -0
  345. package/doc/zh-CN/implemented/pipeline.md +25 -0
  346. package/doc/zh-CN/implemented/runtime-core.md +31 -0
  347. package/doc/zh-CN/implemented/stdlib.md +76 -0
  348. package/doc/zh-CN/implemented/strings.md +27 -0
  349. package/doc/zh-CN/implemented/tests.md +10 -0
  350. package/doc/zh-CN/implemented/typed-arrays.md +26 -0
  351. package/doc/zh-CN/implemented/value-model.md +18 -0
  352. package/doc/zh-CN/implemented.md +50 -350
  353. package/doc/zh-CN/node-implemented.md +4 -531
  354. package/doc/zh-CN/node-unimplemented.md +4 -139
  355. package/doc/zh-CN/plan-require-node-modules.md +4 -4
  356. package/doc/zh-CN/requirements.md +20 -6
  357. package/doc/zh-CN/unimplemented/classes.md +22 -0
  358. package/doc/zh-CN/unimplemented/deviations.md +24 -0
  359. package/doc/zh-CN/unimplemented/expressions.md +24 -0
  360. package/doc/zh-CN/unimplemented/functions.md +21 -0
  361. package/doc/zh-CN/unimplemented/modules.md +19 -0
  362. package/doc/zh-CN/unimplemented/node/async.md +20 -0
  363. package/doc/zh-CN/unimplemented/node/bun.md +8 -0
  364. package/doc/zh-CN/unimplemented/node/fs-promises.md +12 -0
  365. package/doc/zh-CN/unimplemented/node/fs.md +24 -0
  366. package/doc/zh-CN/unimplemented/node/globals.md +14 -0
  367. package/doc/zh-CN/unimplemented/node/modules.md +15 -0
  368. package/doc/zh-CN/unimplemented/node.md +18 -0
  369. package/doc/zh-CN/unimplemented/statements.md +15 -0
  370. package/doc/zh-CN/unimplemented/stdlib.md +54 -0
  371. package/doc/zh-CN/unimplemented/toolchain.md +14 -0
  372. package/doc/zh-CN/unimplemented/types.md +11 -0
  373. package/doc/zh-CN/unimplemented.md +14 -237
  374. package/llms.txt +32 -4
  375. package/package.json +1 -1
  376. package/runtime/ext_gui/inline_svg.cpp +219 -0
  377. package/runtime/ext_gui/inline_svg.h +41 -0
  378. package/runtime/ext_gui/layout.cpp +18 -0
  379. package/runtime/ext_gui/layout.h +7 -0
  380. package/runtime/ext_gui/layout_flow.cpp +4 -3
  381. package/runtime/ext_gui/paint.cpp +14 -0
  382. package/runtime/ext_gui/paint.h +5 -1
  383. package/runtime/ext_gui/renderer_image.cpp +53 -25
  384. package/runtime/ext_gui/renderer_shaders.h +2 -2
  385. package/runtime/ext_gui/stb_image.h +1 -17
  386. package/runtime/ext_gui/style_ua.cpp +3 -0
  387. package/runtime/ext_gui/svg.cpp +122 -39
  388. package/runtime/ext_gui/svg.h +14 -3
  389. package/runtime/ext_gui/window.cpp +28 -0
  390. package/runtime/ext_node/child_process/child_process.c +173 -73
  391. package/runtime/ext_node/fs/async_api.c +314 -0
  392. package/runtime/ext_node/fs/async_complete.c +99 -0
  393. package/runtime/ext_node/fs/async_fh.c +206 -0
  394. package/runtime/ext_node/fs/async_job.c +81 -0
  395. package/runtime/ext_node/fs/async_job.h +132 -0
  396. package/runtime/ext_node/fs/async_worker.c +534 -0
  397. package/runtime/ext_node/fs/async_worker_dir.c +439 -0
  398. package/runtime/ext_node/fs/async_worker_dir.h +33 -0
  399. package/runtime/ext_node/fs/async_worker_fd.c +74 -0
  400. package/runtime/ext_node/fs/dir.c +60 -15
  401. package/runtime/ext_node/fs/fs_common.h +9 -0
  402. package/runtime/ext_node/fs/fs_ops.c +18 -29
  403. package/runtime/ext_node/fs/parts/builtins.inc +34 -0
  404. package/runtime/ext_node/fs/parts/platform.inc +66 -0
  405. package/runtime/ext_node/fs/promises.c +44 -234
  406. package/runtime/rt.h +15 -0
  407. package/runtime/rt_internal.h +108 -0
  408. package/runtime/xt_alloc.c +43 -7
  409. package/runtime/xt_array_buffer.c +284 -0
  410. package/runtime/xt_async.c +46 -21
  411. package/runtime/xt_async_io.c +333 -0
  412. package/runtime/xt_async_io.h +47 -0
  413. package/runtime/xt_bigint/helpers.inc +3 -3
  414. package/runtime/xt_builtins.c +21 -17
  415. package/runtime/xt_constructors.c +12 -2
  416. package/runtime/xt_containers/access.inc +148 -3
  417. package/runtime/xt_containers/objects.inc +26 -2
  418. package/runtime/xt_containers/shapes.inc +71 -0
  419. package/runtime/xt_containers.c +1 -0
  420. package/runtime/xt_coroutine.c +17 -0
  421. package/runtime/xt_fetch/async.inc +295 -0
  422. package/runtime/xt_fetch/request.inc +6 -183
  423. package/runtime/xt_fetch/socket.inc +5 -4
  424. package/runtime/xt_fetch.c +6 -4
  425. package/runtime/xt_generator.c +299 -10
  426. package/runtime/xt_io/inspect.inc +112 -0
  427. package/runtime/xt_loop.c +79 -7
  428. package/runtime/xt_performance.c +37 -0
  429. package/runtime/xt_promise.c +63 -1
  430. package/runtime/xt_stdlib/arrays.inc +1 -1
  431. package/runtime/xt_stdlib/dispatch.inc +46 -11
  432. package/runtime/xt_stdlib/strings.inc +1 -1
  433. package/runtime/xt_stdlib2/array-statics.inc +25 -0
  434. package/runtime/xt_stdlib2/arrays.inc +5 -3
  435. package/runtime/xt_stdlib2/container.inc +5 -0
  436. package/runtime/xt_stdlib2/date.inc +111 -3
  437. package/runtime/xt_stdlib2/error.inc +24 -0
  438. package/runtime/xt_stdlib2/json.inc +310 -19
  439. package/runtime/xt_stdlib2/number-string-statics.inc +1 -1
  440. package/runtime/xt_stdlib2/objects.inc +122 -0
  441. package/runtime/xt_stdlib2/set.inc +1 -1
  442. package/runtime/xt_structured_clone.c +159 -0
  443. package/runtime/xt_symbol.c +2 -2
  444. package/runtime/xt_text_codec.c +69 -0
  445. package/runtime/xt_typed_array/construction.inc +35 -5
  446. package/runtime/xt_typed_array/elements.inc +159 -0
  447. package/runtime/xt_typed_array/methods.inc +21 -5
  448. package/runtime/xt_typed_array.c +7 -10
  449. package/runtime/xt_url.c +375 -0
  450. package/runtime/xt_values/arithmetic.inc +2 -2
  451. package/runtime/xt_values/conversions.inc +1 -1
  452. package/runtime/xt_weak.c +281 -0
  453. package/scripts/build-gui.ts +133 -60
  454. package/scripts/check-version.ts +3 -3
  455. package/src/binder/declarations.ts +14 -3
  456. package/src/cli/hints.ts +8 -1
  457. package/src/cli/main.ts +119 -18
  458. package/src/cli/watch.ts +101 -0
  459. package/src/codegen/generator/calls/access.ts +10 -2
  460. package/src/codegen/generator/calls/closures.ts +12 -4
  461. package/src/codegen/generator/context.ts +23 -3
  462. package/src/codegen/generator/expressions/operators.ts +27 -13
  463. package/src/codegen/generator/expressions/primary.ts +4 -0
  464. package/src/codegen/generator/module.ts +0 -7
  465. package/src/codegen/generator/numeric.ts +85 -11
  466. package/src/codegen/generator/state.ts +23 -0
  467. package/src/codegen/generator/statements/control-flow.ts +1 -4
  468. package/src/codegen/generator/statements/loops.ts +50 -16
  469. package/src/codegen/generator/tables.ts +26 -1
  470. package/src/diagnostics/diagnostic.ts +23 -3
  471. package/src/driver/app-artifacts.ts +77 -0
  472. package/src/driver/build-key.ts +55 -0
  473. package/src/driver/bundler/graph.ts +63 -13
  474. package/src/driver/bundler/merge.ts +4 -1
  475. package/src/driver/compiler.ts +94 -328
  476. package/src/driver/config.ts +11 -0
  477. package/src/driver/frontend.ts +120 -0
  478. package/src/driver/index.ts +0 -1
  479. package/src/driver/options.ts +70 -0
  480. package/src/driver/runtime-objects.ts +134 -0
  481. package/src/driver/toolchain-provider.ts +4 -0
  482. package/src/driver/toolchain.ts +154 -10
  483. package/src/driver/version.ts +12 -0
  484. package/src/driver/win-icon.ts +36 -36
  485. package/src/extensions/node/fs/index.ts +12 -3
  486. package/src/extensions/node/fs-promises/index.ts +15 -6
  487. package/src/parser/declarations/classes.ts +4 -0
  488. package/src/parser/declarations/functions.ts +12 -1
  489. package/src/parser/modules.ts +8 -4
  490. package/src/parser/parser.ts +28 -0
@@ -59,6 +59,10 @@
59
59
  #define XT_OBJECT_KIND_GENERATOR 13
60
60
  #define XT_OBJECT_KIND_ITERATOR 14
61
61
  #define XT_OBJECT_KIND_ASYNC 15
62
+ #define XT_OBJECT_KIND_ASYNC_ITERATOR 16
63
+ #define XT_OBJECT_KIND_WEAK_MAP 17
64
+ #define XT_OBJECT_KIND_WEAK_SET 18
65
+ #define XT_OBJECT_KIND_WEAK_REF 19
62
66
 
63
67
  /* Common header for every heap object. `flags` bit 0 is the collector's mark
64
68
  * bit; it is cleared on every surviving object at the end of a sweep. */
@@ -111,11 +115,24 @@ typedef struct {
111
115
  xt_value setter;
112
116
  } xt_property;
113
117
 
118
+ /* Hidden-class descriptor for ordinary objects. Shapes are interned by their
119
+ * (parent, key) transition and never freed, so an object's shape pointer is a
120
+ * stable layout identity. Shape keys are rooted by a collector provider in
121
+ * xt_containers/shapes.inc. */
122
+ typedef struct xt_shape {
123
+ xt_value key;
124
+ uint32_t count;
125
+ struct xt_shape *parent;
126
+ struct xt_shape *next; /* hash-bucket chain */
127
+ struct xt_shape *all_next; /* every shape, for the GC root provider */
128
+ } xt_shape;
129
+
114
130
  typedef struct {
115
131
  xt_header header;
116
132
  uint32_t count;
117
133
  uint32_t capacity;
118
134
  xt_property *properties;
135
+ xt_shape *shape;
119
136
  xt_value prototype;
120
137
  uint8_t frozen;
121
138
  uint8_t is_array_base;
@@ -155,6 +172,9 @@ typedef struct {
155
172
  /* Set on `async` function objects: calling the closure starts a coroutine
156
173
  * (see xt_async.c) and immediately returns the promise it resolves. */
157
174
  uint8_t is_async;
175
+ /* Set on `async function*` objects. `is_generator` is also set, but the call
176
+ * path checks this flag first so the generator is created in async mode. */
177
+ uint8_t is_async_generator;
158
178
  /* Non-NULL for the first-class value of a built-in constructor ("Array",
159
179
  * "Map", ...). It lets property access resolve the constructor's statics
160
180
  * (`const A = Array; A.isArray(x)`). Points at a static string. */
@@ -217,12 +237,26 @@ void xt_gc_scan_region(const void *base, size_t bytes);
217
237
 
218
238
  /* Kind-specific hooks for allocations with separately allocated sub-objects.
219
239
  * Implemented by the translation unit that owns the representation. */
240
+ /* Weak-reference processing. `xt_weak_gc_process_once` marks values whose
241
+ * WeakMap key is already marked and returns 1 when it marked anything (the
242
+ * caller repeats until the ephemeron fixed point). `xt_weak_gc_clear` empties
243
+ * WeakRefs whose target stayed unmarked, and `xt_weak_gc_compact` drops dead
244
+ * WeakMap/WeakSet entries. */
245
+ int xt_weak_gc_process_once(void);
246
+ void xt_weak_gc_clear(void);
247
+ void xt_weak_gc_compact(void);
248
+ /* Mark-state queries used by the weak-reference pass. */
249
+ int xt_gc_value_is_marked(xt_value value);
250
+ /* Iterate every allocation (used by the weak-reference pass). */
251
+ xt_header *xt_gc_heap_head(void);
252
+
220
253
  void xt_promise_gc_trace(xt_header *header);
221
254
  void xt_promise_gc_release(xt_header *header);
222
255
  void xt_generator_gc_trace(xt_header *header);
223
256
  void xt_generator_gc_release(xt_header *header);
224
257
  void xt_async_gc_trace(xt_header *header);
225
258
  void xt_async_gc_release(xt_header *header);
259
+ void xt_async_iterator_gc_trace(xt_header *header);
226
260
 
227
261
  /* Stackful coroutines (xt_coroutine.c). A coroutine owns a private C stack and
228
262
  * switches to it with `ucontext`/fibers; `enter` runs until the body calls
@@ -232,6 +266,9 @@ typedef struct xt_coroutine xt_coroutine;
232
266
  xt_coroutine *xt_coroutine_create(void (*entry)(void *), void *arg);
233
267
  void xt_coroutine_enter(xt_coroutine *co);
234
268
  void xt_coroutine_leave(xt_coroutine *co);
269
+ /* The coroutine whose body is currently executing, or NULL on the main stack. */
270
+ xt_coroutine *xt_coroutine_current(void);
271
+ int xt_coroutine_is_current(xt_coroutine *co);
235
272
  void xt_coroutine_gc_trace(xt_coroutine *co);
236
273
  void xt_coroutine_release(xt_coroutine *co);
237
274
 
@@ -320,6 +357,11 @@ void xt_array_reserve(xt_array *array, uint32_t needed);
320
357
  /* Object helpers used by the standard library. */
321
358
  xt_object *xt_as_object(xt_value value);
322
359
  xt_property *xt_object_find_property(xt_object *obj, xt_value key);
360
+ /* Hidden-class helpers. `xt_object_shape_changed` rebuilds the shape after a
361
+ * property was inserted out of order or deleted. `xt_shape_empty` stays local
362
+ * to xt_containers.c, which is why it has no prototype here. */
363
+ xt_shape *xt_shape_transition(xt_shape *parent, xt_value key);
364
+ void xt_object_shape_changed(xt_object *obj);
323
365
 
324
366
  /* Property keys are either strings or symbols. */
325
367
  xt_value xt_to_property_key(xt_value key);
@@ -347,6 +389,14 @@ xt_value xt_regexp_split(xt_value value, xt_value regexp, xt_value limit);
347
389
  xt_value xt_regexp_get_property(xt_value regexp, xt_value key);
348
390
  int32_t xt_map_size(xt_value value);
349
391
  int32_t xt_set_size(xt_value value);
392
+ /* WeakMap / WeakSet / WeakRef (xt_weak.c). */
393
+ int xt_is_weak_map(xt_value value);
394
+ int xt_is_weak_set(xt_value value);
395
+ int xt_is_weak_ref(xt_value value);
396
+ xt_value xt_weak_map_ctor(int32_t argc, xt_value *argv);
397
+ xt_value xt_weak_set_ctor(int32_t argc, xt_value *argv);
398
+ xt_value xt_weak_ref_ctor(int32_t argc, xt_value *argv);
399
+ xt_value xt_weak_method(xt_value target, const char *method, int32_t argc, xt_value *argv, int *handled);
350
400
  /* `for...of` iteration: dispatch over arrays, strings, Maps and Sets. */
351
401
  xt_value xt_iter_length(xt_value value);
352
402
  xt_value xt_iter_value(xt_value value, xt_value index);
@@ -357,6 +407,9 @@ xt_value xt_iter_has(xt_value value, xt_value index);
357
407
  * protocols, or a wrapper around `value[Symbol.iterator]()` otherwise. */
358
408
  xt_value xt_iter_open(xt_value value);
359
409
 
410
+ /* Monotonic clock in fractional milliseconds (xt_loop.c), for `performance.now`. */
411
+ double xt_monotonic_ms(void);
412
+
360
413
  /* Stackful generators (xt_generator.c). */
361
414
  int xt_is_generator(xt_value value);
362
415
  xt_value xt_generator_new(xt_value function, xt_value thisValue, int32_t argc, xt_value *argv);
@@ -367,6 +420,18 @@ xt_value xt_yield(xt_value value);
367
420
  xt_value xt_yield_star(xt_value delegate);
368
421
  int xt_generator_has_next(xt_value generator);
369
422
  xt_value xt_generator_iter_value(xt_value generator);
423
+ /* Async-generator support. `xt_generator_await` handles an `await` inside an
424
+ * async generator and returns 1; it returns 0 when no async generator is
425
+ * running (ordinary/async code handles the await itself). */
426
+ int xt_generator_await(xt_value value, xt_value *result);
427
+ void xt_generator_wake(void *generator, xt_value value, int rejected);
428
+ int xt_is_async_generator(xt_value value);
429
+ /* `[Symbol.asyncIterator]()` for a generator object. */
430
+ xt_value xt_async_iterator_method(void);
431
+ /* `for await...of`: resolve the async iteration protocol once, then pull one
432
+ * step per call. Both return a promise for the step object. */
433
+ xt_value xt_async_iter_open(xt_value value);
434
+ xt_value xt_async_iter_next(xt_value iterator);
370
435
 
371
436
  /* Async coroutines (xt_async.c). Calling an `async` function runs its body on
372
437
  * a coroutine that suspends at a pending `await` and resumes when the awaited
@@ -387,6 +452,8 @@ int xt_promise_state_of(xt_value value);
387
452
  xt_value xt_promise_value_of(xt_value value);
388
453
  /* Register a coroutine to resume when `promise` settles (it must be pending). */
389
454
  void xt_promise_add_async_waiter(xt_value promise, void *async);
455
+ /* Queue a microtask that resumes `async` with an already settled value. */
456
+ void xt_promise_queue_async_wake(void *async, xt_value settled, int rejected);
390
457
 
391
458
  /* Exception-frame plumbing shared with the generator runtime. The struct is
392
459
  * public so a coroutine can `_setjmp` its own boundary directly (a `setjmp`
@@ -448,6 +515,29 @@ typedef struct {
448
515
  uint32_t capacity;
449
516
  } xt_set_object;
450
517
 
518
+ /* Weak collections. Keys (WeakMap/WeakSet) and the target of a WeakRef are
519
+ * deliberately not traced by the collector: `xt_weak_gc_*` in xt_weak.c
520
+ * implements the ephemeron fixed point and clears unreachable refs. */
521
+ typedef struct {
522
+ xt_header header;
523
+ xt_value *keys;
524
+ xt_value *values;
525
+ uint32_t count;
526
+ uint32_t capacity;
527
+ } xt_weak_map;
528
+
529
+ typedef struct {
530
+ xt_header header;
531
+ xt_value *values;
532
+ uint32_t count;
533
+ uint32_t capacity;
534
+ } xt_weak_set;
535
+
536
+ typedef struct {
537
+ xt_header header;
538
+ xt_value target;
539
+ } xt_weak_ref;
540
+
451
541
  typedef struct {
452
542
  xt_header header;
453
543
  double time;
@@ -468,6 +558,9 @@ xt_value xt_ext_object_method(xt_value target, const char *method, int32_t argc,
468
558
 
469
559
  /* Error family helpers (xt_stdlib2.c). */
470
560
  xt_value xt_error_to_string(xt_value error);
561
+ /* Turn an internal "TypeError: message" / "RangeError: message" string into a
562
+ * real Error-family value so `catch` observes an Error, not a string. */
563
+ xt_value xt_error_from_message(const char *message);
471
564
  xt_value xt_aggregate_error_ctor(int32_t argc, xt_value *argv);
472
565
  xt_value xt_ext_container_method(xt_value target, const char *method, int32_t argc, xt_value *argv, int *handled);
473
566
  xt_value xt_promise_method(xt_value target, const char *method, int32_t argc, xt_value *argv, int *handled);
@@ -482,5 +575,20 @@ xt_value xt_arg_at(int32_t argc, xt_value *argv, int32_t index);
482
575
  /* Typed arrays (xt_typed_array.c). */
483
576
  int xt_typed_array_kind_of(xt_value value);
484
577
  double xt_typed_array_coerce(int kind, double value);
578
+ /* Buffer-backed element access; the array must be a typed-array value. */
579
+ xt_value xt_typed_array_read(xt_value array, uint32_t index);
580
+ void xt_typed_array_write(xt_value array, uint32_t index, xt_value value);
581
+ xt_value xt_typed_array_buffer_of(xt_value array);
582
+ uint32_t xt_typed_array_byte_offset_of(xt_value array);
583
+ const char *xt_typed_array_name_of(int kind);
584
+
585
+ /* ArrayBuffer helpers (xt_array_buffer.c). */
586
+ int xt_is_array_buffer(xt_value value);
587
+ uint32_t xt_array_buffer_byte_length(xt_value value);
588
+ uint8_t xt_array_buffer_get_byte(xt_value buffer, uint32_t index);
589
+ void xt_array_buffer_set_byte(xt_value buffer, uint32_t index, uint8_t value);
590
+ xt_value xt_array_buffer_ctor(int32_t argc, xt_value *argv);
591
+
592
+ #include "xt_async_io.h"
485
593
 
486
594
  #endif /* XT_RT_INTERNAL_H */
@@ -303,6 +303,17 @@ void xt_gc_mark_value(xt_value value) {
303
303
  }
304
304
  }
305
305
 
306
+ int xt_gc_value_is_marked(xt_value value) {
307
+ if (!(XT_IS_STRING(value) || XT_IS_OBJECT(value) || XT_IS_ARRAY(value) ||
308
+ XT_IS_FUNCTION(value) || XT_IS_BIGINT(value))) {
309
+ return 0;
310
+ }
311
+ xt_header *header = xt_gc_table_lookup((uintptr_t)XT_GET_PTR(value));
312
+ return header != NULL && (header->flags & XT_GC_MARK) != 0;
313
+ }
314
+
315
+ xt_header *xt_gc_heap_head(void) { return g_heap_head; }
316
+
306
317
  void xt_gc_scan_region(const void *base, size_t bytes) {
307
318
  if (!base) return;
308
319
  const uint64_t *words = (const uint64_t *)base;
@@ -392,6 +403,15 @@ static void xt_gc_process(xt_header *header) {
392
403
  case XT_OBJECT_KIND_ASYNC:
393
404
  xt_async_gc_trace(header);
394
405
  return;
406
+ case XT_OBJECT_KIND_ASYNC_ITERATOR:
407
+ xt_async_iterator_gc_trace(header);
408
+ return;
409
+ case XT_OBJECT_KIND_WEAK_MAP:
410
+ case XT_OBJECT_KIND_WEAK_SET:
411
+ case XT_OBJECT_KIND_WEAK_REF:
412
+ /* Weak references are not traced; `xt_weak_gc_*` owns the ephemeron
413
+ * fixed point after the ordinary mark phase. */
414
+ return;
395
415
  default:
396
416
  /* Symbols, regexps, iterators and any future kind whose references live
397
417
  * inline: the payload scan covers them. */
@@ -429,6 +449,13 @@ static void xt_gc_release(xt_header *header) {
429
449
  case XT_OBJECT_KIND_SET:
430
450
  free(((xt_set_object *)header)->values);
431
451
  break;
452
+ case XT_OBJECT_KIND_WEAK_MAP:
453
+ free(((xt_weak_map *)header)->keys);
454
+ free(((xt_weak_map *)header)->values);
455
+ break;
456
+ case XT_OBJECT_KIND_WEAK_SET:
457
+ free(((xt_weak_set *)header)->values);
458
+ break;
432
459
  case XT_OBJECT_KIND_PROMISE:
433
460
  xt_promise_gc_release(header);
434
461
  break;
@@ -478,16 +505,25 @@ void xt_gc_collect(void) {
478
505
 
479
506
  xt_gc_table_build();
480
507
  xt_gc_mark_roots();
481
- while (g_gray_count > 0) {
482
- xt_header *header = g_gray[--g_gray_count];
483
- xt_gc_process(header);
508
+ /* Ephemeron fixed point: a WeakMap value is reachable only when its key is
509
+ * reachable. Marking a value can reach further keys, so repeat until a pass
510
+ * marks nothing new. WeakRefs are cleared only after this settles, because
511
+ * an ephemeron may still keep their target alive. */
512
+ for (;;) {
513
+ while (g_gray_count > 0) {
514
+ xt_header *header = g_gray[--g_gray_count];
515
+ xt_gc_process(header);
516
+ }
517
+ if (!xt_weak_gc_process_once()) break;
484
518
  }
519
+ xt_weak_gc_clear();
520
+ xt_weak_gc_compact();
485
521
 
486
522
  xt_header **link = &g_heap_head;
487
523
  xt_header *header = g_heap_head;
488
- size_t live_by_kind[16];
489
- size_t bytes_by_kind[16];
490
- for (int i = 0; i < 16; i++) {
524
+ size_t live_by_kind[32];
525
+ size_t bytes_by_kind[32];
526
+ for (int i = 0; i < 32; i++) {
491
527
  live_by_kind[i] = 0;
492
528
  bytes_by_kind[i] = 0;
493
529
  }
@@ -497,7 +533,7 @@ void xt_gc_collect(void) {
497
533
  header->flags &= (uint8_t)~XT_GC_MARK;
498
534
  link = &header->gc_next;
499
535
  if (trace) {
500
- size_t kind = header->kind < 16 ? header->kind : 0;
536
+ size_t kind = header->kind < 32 ? header->kind : 0;
501
537
  live_by_kind[kind]++;
502
538
  bytes_by_kind[kind] += header->size;
503
539
  }
@@ -0,0 +1,284 @@
1
+ /*
2
+ * xbintsc runtime — ArrayBuffer and DataView.
3
+ *
4
+ * An ArrayBuffer is a plain object holding its bytes as an array of numbers
5
+ * under a private symbol, plus a public `byteLength`. A DataView is another
6
+ * plain object that points at the buffer and exposes the get/set accessors;
7
+ * every accessor assembles the bytes explicitly, so the default big-endian
8
+ * order and the optional `littleEndian` argument follow ECMAScript.
9
+ *
10
+ * Keeping both as ordinary objects means the garbage collector, property
11
+ * lookup and the rest of the runtime need no new object kind. Typed arrays
12
+ * are buffer-backed views over this object and share its bytes; `new
13
+ * Uint8Array(buffer, offset, length)`, `.buffer` and `subarray` are handled by
14
+ * xt_typed_array.c.
15
+ */
16
+
17
+ #include "rt_internal.h"
18
+
19
+ #include <math.h>
20
+ #include <stdlib.h>
21
+ #include <string.h>
22
+
23
+ static xt_value xt_ab_data_key_value = XT_UNDEFINED;
24
+
25
+ static xt_value xt_ab_data_key(void) {
26
+ /* A symbol key keeps the backing bytes out of Object.keys / JSON.stringify,
27
+ * like the platform's internal [[ArrayBufferData]] slot. */
28
+ if (!xt_is_symbol(xt_ab_data_key_value)) {
29
+ xt_ab_data_key_value = xt_symbol_new(xt_string_from_cstr("__arrayBufferData"));
30
+ xt_gc_add_root(&xt_ab_data_key_value);
31
+ }
32
+ return xt_ab_data_key_value;
33
+ }
34
+
35
+ static xt_value xt_ab_data(xt_value buffer) { if (!XT_IS_OBJECT(buffer)) return XT_UNDEFINED;
36
+ return xt_object_get(buffer, xt_ab_data_key());
37
+ }
38
+
39
+ static int xt_ab_is_buffer(xt_value value) {
40
+ return XT_IS_ARRAY(xt_ab_data(value));
41
+ }
42
+
43
+ static xt_value xt_ab_new(uint32_t length) {
44
+ xt_value buffer = xt_object_new();
45
+ xt_object_set(buffer, xt_string_from_cstr("byteLength"), xt_number((double)length));
46
+ xt_value data = xt_array_new(0, NULL);
47
+ for (uint32_t i = 0; i < length; i++) xt_array_push(data, xt_number(0));
48
+ xt_object_set(buffer, xt_ab_data_key(), data);
49
+ return buffer;
50
+ }
51
+
52
+ static xt_value xt_ab_slice(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv);
53
+ static void xt_ab_install(xt_value object, const char *name, void *fn);
54
+
55
+ xt_value xt_array_buffer_ctor(int32_t argc, xt_value *argv) {
56
+ double length = xt_to_number(xt_arg_at(argc, argv, 0));
57
+ if (!(length >= 0) || length > 4294967295.0) length = 0;
58
+ xt_value buffer = xt_ab_new((uint32_t)length);
59
+ xt_ab_install(buffer, "slice", (void *)xt_ab_slice);
60
+ return buffer;
61
+ }
62
+
63
+ int xt_is_array_buffer(xt_value value) { return xt_ab_is_buffer(value); }
64
+
65
+ uint32_t xt_array_buffer_byte_length(xt_value value) {
66
+ if (!xt_ab_is_buffer(value)) return 0;
67
+ return (uint32_t)xt_to_number(xt_get(value, xt_string_from_cstr("byteLength")));
68
+ }
69
+
70
+ uint8_t xt_array_buffer_get_byte(xt_value buffer, uint32_t index) {
71
+ xt_value data = xt_ab_data(buffer);
72
+ if (!XT_IS_ARRAY(data)) return 0;
73
+ return (uint8_t)xt_to_int32(xt_get(data, xt_number((double)index)));
74
+ }
75
+
76
+ void xt_array_buffer_set_byte(xt_value buffer, uint32_t index, uint8_t value) {
77
+ xt_value data = xt_ab_data(buffer);
78
+ if (!XT_IS_ARRAY(data)) return;
79
+ xt_set(data, xt_number((double)index), xt_number((double)value));
80
+ }
81
+
82
+ static xt_value xt_ab_slice(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
83
+ (void)env;
84
+ xt_value data = xt_ab_data(thisValue);
85
+ if (!XT_IS_ARRAY(data)) return xt_ab_new(0);
86
+ int32_t length = xt_to_int32(xt_array_length(data));
87
+ int32_t start = argc > 0 && argv[0] != XT_UNDEFINED ? xt_to_int32(argv[0]) : 0;
88
+ int32_t end = argc > 1 && argv[1] != XT_UNDEFINED ? xt_to_int32(argv[1]) : length;
89
+ if (start < 0) start += length;
90
+ if (end < 0) end += length;
91
+ if (start < 0) start = 0;
92
+ if (end > length) end = length;
93
+ if (end < start) end = start;
94
+ xt_value result = xt_ab_new(0);
95
+ xt_ab_install(result, "slice", (void *)xt_ab_slice);
96
+ xt_value source = xt_ab_data(result);
97
+ for (int32_t i = start; i < end; i++) xt_array_push(source, xt_get(data, xt_number((double)i)));
98
+ xt_object_set(result, xt_string_from_cstr("byteLength"), xt_number((double)(end - start)));
99
+ return result;
100
+ }
101
+
102
+ static void xt_ab_install(xt_value object, const char *name, void *fn) {
103
+ xt_object_set(object, xt_string_from_cstr(name), xt_closure_new(fn, 0, NULL));
104
+ }
105
+
106
+ xt_value xt_array_buffer_static(xt_value name, int32_t argc, xt_value *argv) {
107
+ const char *method = xt_string_data(name);
108
+ if (!method) return XT_UNDEFINED;
109
+ if (strcmp(method, "isView") == 0) {
110
+ xt_value value = xt_arg_at(argc, argv, 0);
111
+ if (xt_typed_array_kind_of(value) >= 0) return XT_TRUE;
112
+ if (!XT_IS_OBJECT(value)) return XT_FALSE;
113
+ if (((xt_object *)XT_GET_PTR(value))->header.kind != XT_OBJECT_KIND_OBJECT) return XT_FALSE;
114
+ xt_value buffer = xt_object_get(value, xt_string_from_cstr("buffer"));
115
+ return xt_bool(xt_ab_is_buffer(buffer) &&
116
+ xt_object_get(value, xt_string_from_cstr("byteLength")) != XT_UNDEFINED);
117
+ }
118
+ return XT_UNDEFINED;
119
+ }
120
+
121
+ /* -- DataView ------------------------------------------------------------- */
122
+
123
+ enum {
124
+ XT_DV_U8,
125
+ XT_DV_I8,
126
+ XT_DV_U16,
127
+ XT_DV_I16,
128
+ XT_DV_U32,
129
+ XT_DV_I32,
130
+ XT_DV_F32,
131
+ XT_DV_F64,
132
+ };
133
+
134
+ static uint32_t xt_dv_width(int kind) {
135
+ switch (kind) {
136
+ case XT_DV_U8:
137
+ case XT_DV_I8:
138
+ return 1;
139
+ case XT_DV_U16:
140
+ case XT_DV_I16:
141
+ return 2;
142
+ case XT_DV_U32:
143
+ case XT_DV_I32:
144
+ case XT_DV_F32:
145
+ return 4;
146
+ default:
147
+ return 8;
148
+ }
149
+ }
150
+
151
+ static int xt_dv_signed(int kind) {
152
+ return kind == XT_DV_I8 || kind == XT_DV_I16 || kind == XT_DV_I32;
153
+ }
154
+
155
+ static xt_value xt_dv_data(xt_value view) {
156
+ return xt_ab_data(xt_get(view, xt_string_from_cstr("buffer")));
157
+ }
158
+
159
+ static uint32_t xt_dv_offset(xt_value view) {
160
+ return (uint32_t)xt_to_number(xt_get(view, xt_string_from_cstr("byteOffset")));
161
+ }
162
+
163
+ static uint32_t xt_dv_length(xt_value view) {
164
+ return (uint32_t)xt_to_number(xt_get(view, xt_string_from_cstr("byteLength")));
165
+ }
166
+
167
+ static int xt_dv_check(xt_value view, xt_value indexValue, uint32_t width, uint32_t *out) {
168
+ double raw = xt_to_number(indexValue);
169
+ if (!(raw >= 0)) raw = -1;
170
+ int64_t index = (int64_t)raw;
171
+ if (index < 0 || (uint64_t)index + width > xt_dv_length(view)) {
172
+ xt_value message = xt_string_from_cstr("Offset is outside the bounds of the DataView");
173
+ xt_throw(xt_range_error_ctor(1, &message));
174
+ }
175
+ *out = xt_dv_offset(view) + (uint32_t)index;
176
+ return 1;
177
+ }
178
+
179
+ static uint64_t xt_dv_read_bits(xt_value view, uint32_t offset, uint32_t width, int little) {
180
+ xt_value data = xt_dv_data(view);
181
+ uint64_t value = 0;
182
+ for (uint32_t i = 0; i < width; i++) {
183
+ uint32_t index = little ? offset + width - 1 - i : offset + i;
184
+ uint64_t byte = (uint64_t)xt_to_number(xt_get(data, xt_number((double)index)));
185
+ value = (value << 8) | (byte & 0xff);
186
+ }
187
+ return value;
188
+ }
189
+
190
+ static void xt_dv_write_bits(xt_value view, uint32_t offset, uint32_t width, uint64_t value,
191
+ int little) {
192
+ xt_value data = xt_dv_data(view);
193
+ for (uint32_t i = 0; i < width; i++) {
194
+ uint32_t shift = little ? i * 8 : (width - 1 - i) * 8;
195
+ uint32_t index = offset + i;
196
+ xt_set(data, xt_number((double)index), xt_number((double)((value >> shift) & 0xff)));
197
+ }
198
+ }
199
+
200
+ static xt_value xt_dv_method(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
201
+ int kind = (int)xt_to_number(xt_closure_env(env, 0));
202
+ int setter = (int)xt_to_number(xt_closure_env(env, 1));
203
+ uint32_t width = xt_dv_width(kind);
204
+ uint32_t offset = 0;
205
+ xt_dv_check(thisValue, xt_arg_at(argc, argv, 0), width, &offset);
206
+ int little = argc > (setter ? 2 : 1) && xt_truthy(xt_arg_at(argc, argv, setter ? 2 : 1));
207
+ if (setter) {
208
+ double value = xt_to_number(xt_arg_at(argc, argv, 1));
209
+ uint64_t bits;
210
+ if (kind == XT_DV_F32) {
211
+ float narrowed = (float)value;
212
+ uint32_t raw;
213
+ memcpy(&raw, &narrowed, sizeof(raw));
214
+ bits = raw;
215
+ } else if (kind == XT_DV_F64) {
216
+ double raw = value;
217
+ memcpy(&bits, &raw, sizeof(bits));
218
+ } else if (kind == XT_DV_I8) {
219
+ bits = (uint64_t)(uint8_t)(int8_t)xt_to_int32(xt_number(value));
220
+ } else if (kind == XT_DV_I16) {
221
+ bits = (uint64_t)(uint16_t)(int16_t)xt_to_int32(xt_number(value));
222
+ } else if (kind == XT_DV_I32) {
223
+ bits = (uint64_t)(uint32_t)(int32_t)xt_to_int32(xt_number(value));
224
+ } else {
225
+ bits = (uint64_t)(uint32_t)xt_to_int32(xt_number(value));
226
+ }
227
+ xt_dv_write_bits(thisValue, offset, width, bits, little);
228
+ return XT_UNDEFINED;
229
+ }
230
+ uint64_t bits = xt_dv_read_bits(thisValue, offset, width, little);
231
+ if (kind == XT_DV_F32) {
232
+ uint32_t raw = (uint32_t)bits;
233
+ float value;
234
+ memcpy(&value, &raw, sizeof(value));
235
+ return xt_number((double)value);
236
+ }
237
+ if (kind == XT_DV_F64) {
238
+ double value;
239
+ memcpy(&value, &bits, sizeof(value));
240
+ return xt_number(value);
241
+ }
242
+ if (xt_dv_signed(kind)) {
243
+ int64_t signedValue = (int64_t)bits;
244
+ if (width < 8) {
245
+ uint64_t signBit = 1ULL << (width * 8 - 1);
246
+ if (bits & signBit) signedValue = (int64_t)(bits | (~0ULL << (width * 8)));
247
+ }
248
+ return xt_number((double)signedValue);
249
+ }
250
+ return xt_number((double)bits);
251
+ }
252
+
253
+ xt_value xt_data_view_ctor(int32_t argc, xt_value *argv) {
254
+ xt_value buffer = xt_arg_at(argc, argv, 0);
255
+ if (!xt_ab_is_buffer(buffer)) {
256
+ xt_value message = xt_string_from_cstr("First argument to DataView constructor must be an ArrayBuffer");
257
+ xt_throw(xt_type_error_ctor(1, &message));
258
+ }
259
+ uint32_t bufferLength = (uint32_t)xt_to_number(xt_get(buffer, xt_string_from_cstr("byteLength")));
260
+ double rawOffset = argc > 1 ? xt_to_number(argv[1]) : 0;
261
+ uint32_t offset = rawOffset > 0 ? (uint32_t)rawOffset : 0;
262
+ double rawLength = argc > 2 && argv[2] != XT_UNDEFINED ? xt_to_number(argv[2]) : (double)(bufferLength - offset);
263
+ uint32_t length = rawLength > 0 ? (uint32_t)rawLength : 0;
264
+ if (offset > bufferLength || length > bufferLength - offset) {
265
+ xt_value message = xt_string_from_cstr("Invalid DataView length");
266
+ xt_throw(xt_range_error_ctor(1, &message));
267
+ }
268
+ xt_value view = xt_object_new();
269
+ xt_object_set(view, xt_string_from_cstr("buffer"), buffer);
270
+ xt_object_set(view, xt_string_from_cstr("byteOffset"), xt_number((double)offset));
271
+ xt_object_set(view, xt_string_from_cstr("byteLength"), xt_number((double)length));
272
+ static const char *const getters[] = {"getUint8", "getInt8", "getUint16", "getInt16",
273
+ "getUint32", "getInt32", "getFloat32", "getFloat64"};
274
+ static const char *const setters[] = {"setUint8", "setInt8", "setUint16", "setInt16",
275
+ "setUint32", "setInt32", "setFloat32", "setFloat64"};
276
+ for (int kind = 0; kind < 8; kind++) {
277
+ for (int isSetter = 0; isSetter < 2; isSetter++) {
278
+ xt_value environment[2] = {xt_number((double)kind), xt_number((double)isSetter)};
279
+ xt_value closure = xt_closure_new((void *)xt_dv_method, 2, environment);
280
+ xt_object_set(view, xt_string_from_cstr(isSetter ? setters[kind] : getters[kind]), closure);
281
+ }
282
+ }
283
+ return view;
284
+ }
@@ -11,10 +11,10 @@
11
11
  * a real C stack, `try`/`finally`, loops and locals all survive the suspension
12
12
  * without a state-machine transform.
13
13
  *
14
- * `await` on an already-settled value keeps the historical fast path: it
15
- * returns (or throws) synchronously instead of forcing a microtask turn. This
16
- * makes the common "await a synchronous builtin" case cheap and preserves the
17
- * existing ordering guarantees.
14
+ * `await` always yields: even a non-promise or an already-settled promise
15
+ * queues a microtask before the body resumes, matching the specification's
16
+ * interleaving with pending `.then` callbacks. (Top-level `await`, with no
17
+ * coroutine to suspend, still blocks on the event loop.)
18
18
  */
19
19
 
20
20
  #include "rt_internal.h"
@@ -103,32 +103,50 @@ xt_value xt_async_call(xt_value function, xt_value thisValue, int32_t argc, xt_v
103
103
  }
104
104
 
105
105
  void xt_async_wake(void *asyncPointer, xt_value value, int rejected) {
106
+ if (!asyncPointer) return;
107
+ /* Async generators park the same kind of waiter, but their completion sends
108
+ * a promise to the current `.next()` request instead of settling a single
109
+ * `async` promise. */
110
+ if (((xt_header *)asyncPointer)->kind == XT_OBJECT_KIND_GENERATOR) {
111
+ xt_generator_wake(asyncPointer, value, rejected);
112
+ return;
113
+ }
106
114
  xt_async *async = (xt_async *)asyncPointer;
107
- if (!async || async->done || !async->coroutine) return;
115
+ if (async->done || !async->coroutine) return;
108
116
  async->resume_value = value;
109
117
  async->await_threw = rejected;
110
118
  xt_async_resume(async);
111
119
  }
112
120
 
113
- /* `await value`: unwrap promises, suspending the running async coroutine when
114
- * the promise is still pending. */
121
+ /* `await value`: every await yields once. A settled promise (or a plain value)
122
+ * queues a microtask before resuming, so an await always interleaves with
123
+ * pending `.then` callbacks exactly like the specification. */
115
124
  xt_value xt_await(xt_value value) {
116
- int state = xt_promise_state_of(value);
117
- if (state < 0) return value;
118
- if (state == XT_PROMISE_REJECTED) {
119
- xt_throw(xt_promise_value_of(value));
120
- return XT_UNDEFINED;
121
- }
122
- if (state == XT_PROMISE_FULFILLED) return xt_promise_value_of(value);
125
+ /* An `await` inside an async generator suspends that generator's coroutine
126
+ * while leaving the current `.next()` promise pending. */
127
+ xt_value generatorResult;
128
+ if (xt_generator_await(value, &generatorResult)) return generatorResult;
123
129
 
130
+ int state = xt_promise_state_of(value);
124
131
  xt_async *async = g_active_async;
125
- if (async && async->coroutine) {
126
- async->await_threw = 0;
127
- async->resume_value = XT_UNDEFINED;
128
- xt_promise_add_async_waiter(value, async);
129
- xt_coroutine_leave(async->coroutine);
130
- /* The waiter resumed us. A rejection is rethrown inside the coroutine so
131
- * its own `try`/`catch` and `finally` see it. */
132
+ if (async && async->coroutine && xt_coroutine_is_current(async->coroutine)) {
133
+ if (state == XT_PROMISE_PENDING) {
134
+ async->await_threw = 0;
135
+ async->resume_value = XT_UNDEFINED;
136
+ xt_promise_add_async_waiter(value, async);
137
+ xt_coroutine_leave(async->coroutine);
138
+ } else {
139
+ int rejected = state == XT_PROMISE_REJECTED;
140
+ xt_value settled = (state == XT_PROMISE_FULFILLED || rejected)
141
+ ? xt_promise_value_of(value)
142
+ : value;
143
+ async->await_threw = rejected;
144
+ async->resume_value = settled;
145
+ xt_promise_queue_async_wake(async, settled, rejected);
146
+ xt_coroutine_leave(async->coroutine);
147
+ }
148
+ /* The waiter/queued microtask resumed us. A rejection is rethrown inside
149
+ * the coroutine so its own `try`/`catch` and `finally` see it. */
132
150
  if (async->await_threw) {
133
151
  async->await_threw = 0;
134
152
  xt_throw(async->resume_value);
@@ -137,6 +155,13 @@ xt_value xt_await(xt_value value) {
137
155
  return async->resume_value;
138
156
  }
139
157
 
158
+ if (state < 0) return value;
159
+ if (state == XT_PROMISE_REJECTED) {
160
+ xt_throw(xt_promise_value_of(value));
161
+ return XT_UNDEFINED;
162
+ }
163
+ if (state == XT_PROMISE_FULFILLED) return xt_promise_value_of(value);
164
+
140
165
  /* No coroutine to suspend (top-level `await`, or `await` reached outside an
141
166
  * async function): block on the reactor until the promise settles, exactly
142
167
  * like a synchronous embedder waiting for the event loop. The loop returns