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
package/runtime/xt_loop.c CHANGED
@@ -33,6 +33,10 @@
33
33
 
34
34
  #define XT_LOOP_MAX_WATCHERS 1024
35
35
 
36
+ /* Fallback wait bound while offloaded I/O is outstanding; the completion
37
+ * channel normally wakes `select` immediately. */
38
+ #define XT_ASYNC_POLL_MS 10
39
+
36
40
  typedef struct {
37
41
  int fd;
38
42
  int events;
@@ -88,8 +92,23 @@ static int64_t xt_loop_now_ms(void) {
88
92
  #endif
89
93
  }
90
94
 
91
- static void xt_loop_sleep_ms(int ms) {
92
- if (ms <= 0) return;
95
+ /* Fractional monotonic milliseconds for `performance.now()`. Kept separate from
96
+ * xt_loop_now_ms(), which only needs whole milliseconds for timer deadlines. */
97
+ double xt_monotonic_ms(void) {
98
+ #if defined(_WIN32)
99
+ static LARGE_INTEGER frequency;
100
+ if (frequency.QuadPart == 0) QueryPerformanceFrequency(&frequency);
101
+ LARGE_INTEGER counter;
102
+ QueryPerformanceCounter(&counter);
103
+ return (double)counter.QuadPart * 1000.0 / (double)frequency.QuadPart;
104
+ #else
105
+ struct timespec ts;
106
+ clock_gettime(CLOCK_MONOTONIC, &ts);
107
+ return (double)ts.tv_sec * 1000.0 + (double)ts.tv_nsec / 1000000.0;
108
+ #endif
109
+ }
110
+
111
+ static void xt_loop_sleep_ms(int ms) { if (ms <= 0) return;
93
112
  #if defined(_WIN32)
94
113
  Sleep((DWORD)ms);
95
114
  #else
@@ -228,7 +247,7 @@ static void xt_timer_run_due(void) {
228
247
  xt_value xt_set_timeout(int32_t argc, xt_value *argv) {
229
248
  xt_value callback = xt_arg_at(argc, argv, 0);
230
249
  if (!XT_IS_FUNCTION(callback)) {
231
- xt_throw(xt_string_from_cstr("TypeError: The \"callback\" argument must be of type function"));
250
+ xt_throw(xt_error_from_message("TypeError: The \"callback\" argument must be of type function"));
232
251
  return XT_UNDEFINED;
233
252
  }
234
253
  int64_t delay = xt_timer_delay_arg(xt_arg_at(argc, argv, 1));
@@ -240,7 +259,7 @@ xt_value xt_set_timeout(int32_t argc, xt_value *argv) {
240
259
  xt_value xt_set_interval(int32_t argc, xt_value *argv) {
241
260
  xt_value callback = xt_arg_at(argc, argv, 0);
242
261
  if (!XT_IS_FUNCTION(callback)) {
243
- xt_throw(xt_string_from_cstr("TypeError: The \"callback\" argument must be of type function"));
262
+ xt_throw(xt_error_from_message("TypeError: The \"callback\" argument must be of type function"));
244
263
  return XT_UNDEFINED;
245
264
  }
246
265
  int64_t delay = xt_timer_delay_arg(xt_arg_at(argc, argv, 1));
@@ -263,6 +282,27 @@ xt_value xt_clear_interval(int32_t argc, xt_value *argv) {
263
282
  return XT_UNDEFINED;
264
283
  }
265
284
 
285
+ xt_value xt_set_immediate(int32_t argc, xt_value *argv) {
286
+ xt_value callback = xt_arg_at(argc, argv, 0);
287
+ if (!XT_IS_FUNCTION(callback)) {
288
+ xt_value message = xt_string_from_cstr("The \"callback\" argument must be of type function");
289
+ xt_throw(xt_type_error_ctor(1, &message));
290
+ return XT_UNDEFINED;
291
+ }
292
+ int32_t extra = argc > 1 ? argc - 1 : 0;
293
+ uint64_t id = xt_timer_add(callback, 0, 0, extra, extra > 0 ? argv + 1 : NULL);
294
+ return xt_number((double)id);
295
+ }
296
+
297
+ xt_value xt_clear_immediate(int32_t argc, xt_value *argv) {
298
+ return xt_clear_timeout(argc, argv);
299
+ }
300
+
301
+ /* Reset to 1 while the reactor is dispatching handlers. Reusing a removed slot
302
+ * mid-dispatch would make the new watcher observe the current `fd_set`, so a
303
+ * registration from inside a callback appends instead. */
304
+ static int xt_loop_dispatching = 0;
305
+
266
306
  int xt_loop_add(int fd, int events, xt_io_handler handler, void *userdata) {
267
307
  if (fd < 0 || !handler) return -1;
268
308
  xt_loop_gc_register();
@@ -273,6 +313,21 @@ int xt_loop_add(int fd, int events, xt_io_handler handler, void *userdata) {
273
313
  existing->userdata = userdata;
274
314
  return 0;
275
315
  }
316
+ /* Reuse a slot left by a removed watcher (the async pool toggles its wakeup
317
+ * descriptor on and off, and sockets are opened and closed repeatedly). */
318
+ if (!xt_loop_dispatching) {
319
+ for (int i = 0; i < xt_loop_watcher_count; i++) {
320
+ xt_loop_watcher *slot = &xt_loop_watchers[i];
321
+ if (slot->active) continue;
322
+ slot->fd = fd;
323
+ slot->events = events;
324
+ slot->handler = handler;
325
+ slot->userdata = userdata;
326
+ slot->active = 1;
327
+ xt_loop_active_count++;
328
+ return 0;
329
+ }
330
+ }
276
331
  if (xt_loop_watcher_count >= XT_LOOP_MAX_WATCHERS) return -1;
277
332
  xt_loop_watcher *watcher = &xt_loop_watchers[xt_loop_watcher_count++];
278
333
  watcher->fd = fd;
@@ -306,7 +361,8 @@ void xt_loop_set_main(xt_main_loop_fn fn) { xt_loop_main = fn; }
306
361
  int xt_loop_poll(int timeout_ms) {
307
362
  int has_fds = xt_loop_active_count > 0;
308
363
  int64_t next_due = xt_timer_next_due();
309
- if (!has_fds && next_due < 0) {
364
+ int async_pending = xt_async_pending() > 0;
365
+ if (!has_fds && next_due < 0 && !async_pending) {
310
366
  xt_drain_microtasks();
311
367
  return 0;
312
368
  }
@@ -319,11 +375,15 @@ int xt_loop_poll(int timeout_ms) {
319
375
  if (delta > 100000000) delta = 100000000;
320
376
  if (wait_ms < 0 || delta < (int64_t)wait_ms) wait_ms = (int)delta;
321
377
  }
378
+ /* The completion channel normally wakes `select` immediately; polling every
379
+ * few milliseconds keeps progress even if it could not be registered. */
380
+ if (async_pending && (wait_ms < 0 || wait_ms > XT_ASYNC_POLL_MS)) wait_ms = XT_ASYNC_POLL_MS;
322
381
 
323
382
  /* Timers only: sleep, then run whatever is due. */
324
383
  if (!has_fds) {
325
384
  xt_loop_sleep_ms(wait_ms);
326
385
  xt_timer_run_due();
386
+ xt_async_poll();
327
387
  xt_drain_microtasks();
328
388
  return (int)(xt_loop_active_count + xt_timer_active_count());
329
389
  }
@@ -341,7 +401,9 @@ int xt_loop_poll(int timeout_ms) {
341
401
  if (watcher->fd > maxFd) maxFd = watcher->fd;
342
402
  }
343
403
  if (maxFd < 0) {
404
+ xt_loop_sleep_ms(wait_ms);
344
405
  xt_timer_run_due();
406
+ xt_async_poll();
345
407
  xt_drain_microtasks();
346
408
  return (int)(xt_loop_active_count + xt_timer_active_count());
347
409
  }
@@ -359,7 +421,13 @@ int xt_loop_poll(int timeout_ms) {
359
421
 
360
422
  if (ready > 0) {
361
423
  /* Collect the ready watchers first: handlers may add/remove descriptors. */
362
- for (int i = 0; i < xt_loop_watcher_count; i++) {
424
+ int previousDispatching = xt_loop_dispatching;
425
+ xt_loop_dispatching = 1;
426
+ /* Snapshot the table: a handler may register a new descriptor, and it must
427
+ * wait for the next iteration rather than being tested against this
428
+ * iteration's `fd_set`. */
429
+ int dispatchCount = xt_loop_watcher_count;
430
+ for (int i = 0; i < dispatchCount; i++) {
363
431
  xt_loop_watcher *watcher = &xt_loop_watchers[i];
364
432
  if (!watcher->active) continue;
365
433
  int events = 0;
@@ -367,9 +435,11 @@ int xt_loop_poll(int timeout_ms) {
367
435
  if ((watcher->events & XT_IO_WRITE) && FD_ISSET(watcher->fd, &writeSet)) events |= XT_IO_WRITE;
368
436
  if (events) watcher->handler(watcher->userdata, events);
369
437
  }
438
+ xt_loop_dispatching = previousDispatching;
370
439
  }
371
440
 
372
441
  xt_timer_run_due();
442
+ xt_async_poll();
373
443
  xt_drain_microtasks();
374
444
  return (int)(xt_loop_active_count + xt_timer_active_count());
375
445
  }
@@ -386,4 +456,6 @@ void xt_run_event_loop(void) {
386
456
  }
387
457
  }
388
458
 
389
- int xt_loop_has_work(void) { return xt_loop_active_count > 0 || xt_timer_active_count() > 0; }
459
+ int xt_loop_has_work(void) {
460
+ return xt_loop_active_count > 0 || xt_timer_active_count() > 0 || xt_async_pending() > 0;
461
+ }
@@ -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
+ }
@@ -199,6 +199,23 @@ void xt_drain_microtasks(void) {
199
199
 
200
200
  xt_value xt_promise_create(void) { return xt_promise_value(xt_promise_new()); }
201
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
+
202
219
  void xt_promise_fulfill(xt_value promise, xt_value value) {
203
220
  xt_promise *target = xt_as_promise(promise);
204
221
  if (target) xt_promise_resolve_into(target, value);
@@ -287,9 +304,34 @@ xt_value xt_promise_reject(xt_value value) {
287
304
  return xt_promise_value(promise);
288
305
  }
289
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
+
290
321
  xt_value xt_promise_static(xt_value name, int32_t argc, xt_value *argv) {
291
322
  const char *fn = xt_string_data(name);
292
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
+ }
293
335
  if (strcmp(fn, "resolve") == 0) return xt_promise_resolve(xt_arg_at(argc, argv, 0));
294
336
  if (strcmp(fn, "reject") == 0) return xt_promise_reject(xt_arg_at(argc, argv, 0));
295
337
  if (strcmp(fn, "all") == 0 || strcmp(fn, "allSettled") == 0 || strcmp(fn, "race") == 0 || strcmp(fn, "any") == 0) {
@@ -321,7 +363,12 @@ xt_value xt_promise_static(xt_value name, int32_t argc, xt_value *argv) {
321
363
  xt_promise_settle(result, XT_PROMISE_REJECTED, inner->value);
322
364
  return xt_promise_value(result);
323
365
  }
324
- 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
+ }
325
372
  if (strcmp(fn, "any") == 0 || strcmp(fn, "race") == 0) {
326
373
  xt_promise_settle(result, XT_PROMISE_FULFILLED, settled);
327
374
  return xt_promise_value(result);
@@ -386,3 +433,18 @@ xt_value xt_promise_method(xt_value target, const char *method, int32_t argc, xt
386
433
  *handled = 0;
387
434
  return XT_UNDEFINED;
388
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++) {
@@ -1,5 +1,16 @@
1
1
  /* -- method dispatch ------------------------------------------------------ */
2
2
 
3
+ /* A method that no built-in table recognises must throw, exactly like a
4
+ * missing property called as a function in JavaScript. Returning `undefined`
5
+ * made typos and unimplemented APIs (e.g. `"x".normalize()`) fail silently. */
6
+ static _Noreturn void xt_throw_no_method(const char *type, const char *method) {
7
+ char message[256];
8
+ snprintf(message, sizeof(message), "TypeError: %s has no callable method '%s'", type, method);
9
+ xt_value argument = xt_string_from_cstr(message);
10
+ xt_throw(xt_type_error_ctor(1, &argument));
11
+ abort();
12
+ }
13
+
3
14
  static xt_value xt_array_method(xt_value target, const char *method, int32_t argc, xt_value *argv, int *handled) {
4
15
  *handled = 1;
5
16
  if (strcmp(method, "push") == 0) {
@@ -92,7 +103,7 @@ static xt_value xt_method_value_invoke(xt_value thisValue, xt_value env, int32_t
92
103
  snprintf(message, sizeof(message),
93
104
  "TypeError: Cannot read properties of undefined (reading '%s')",
94
105
  method ? method : "method");
95
- xt_throw(xt_string_from_cstr(message));
106
+ xt_throw(xt_error_from_message(message));
96
107
  }
97
108
  return xt_call_method(thisValue, name, argc, argv);
98
109
  }
@@ -159,6 +170,18 @@ static const xt_method_spec XT_SET_METHODS[] = {
159
170
  {"entries", 0}, {"forEach", 1},
160
171
  };
161
172
 
173
+ static const xt_method_spec XT_WEAKMAP_METHODS[] = {
174
+ {"get", 1}, {"set", 2}, {"has", 1}, {"delete", 1},
175
+ };
176
+
177
+ static const xt_method_spec XT_WEAKSET_METHODS[] = {
178
+ {"add", 1}, {"has", 1}, {"delete", 1},
179
+ };
180
+
181
+ static const xt_method_spec XT_WEAKREF_METHODS[] = {
182
+ {"deref", 0},
183
+ };
184
+
162
185
  static const xt_method_spec XT_REGEXP_METHODS[] = {
163
186
  {"test", 1}, {"exec", 1}, {"toString", 0},
164
187
  };
@@ -215,6 +238,12 @@ xt_value xt_method_value(xt_value target, xt_value name) {
215
238
  known = xt_method_lookup(XT_MAP_METHODS, XT_NAME_COUNT(XT_MAP_METHODS), method, &arity);
216
239
  } else if (kind == XT_OBJECT_KIND_SET) {
217
240
  known = xt_method_lookup(XT_SET_METHODS, XT_NAME_COUNT(XT_SET_METHODS), method, &arity);
241
+ } else if (kind == XT_OBJECT_KIND_WEAK_MAP) {
242
+ known = xt_method_lookup(XT_WEAKMAP_METHODS, XT_NAME_COUNT(XT_WEAKMAP_METHODS), method, &arity);
243
+ } else if (kind == XT_OBJECT_KIND_WEAK_SET) {
244
+ known = xt_method_lookup(XT_WEAKSET_METHODS, XT_NAME_COUNT(XT_WEAKSET_METHODS), method, &arity);
245
+ } else if (kind == XT_OBJECT_KIND_WEAK_REF) {
246
+ known = xt_method_lookup(XT_WEAKREF_METHODS, XT_NAME_COUNT(XT_WEAKREF_METHODS), method, &arity);
218
247
  } else if (kind == XT_OBJECT_KIND_REGEXP) {
219
248
  known = xt_method_lookup(XT_REGEXP_METHODS, XT_NAME_COUNT(XT_REGEXP_METHODS), method, &arity);
220
249
  } else if (kind == XT_OBJECT_KIND_PROMISE) {
@@ -240,7 +269,7 @@ xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *
240
269
  * resolve it as an ordinary property and call it with `target` as `this`. */
241
270
  if (xt_is_symbol(name)) {
242
271
  if (target == XT_UNDEFINED || target == XT_NULL) {
243
- xt_throw(xt_string_from_cstr("TypeError: Cannot read properties of null (reading a Symbol)"));
272
+ xt_throw(xt_error_from_message("TypeError: Cannot read properties of null (reading a Symbol)"));
244
273
  }
245
274
  xt_value fn = xt_get(target, name);
246
275
  if (XT_IS_FUNCTION(fn)) return xt_call_with_this(fn, target, argc, argv);
@@ -253,7 +282,7 @@ xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *
253
282
  * `target` as `this`, instead of silently returning undefined. */
254
283
  xt_value fn = xt_get(target, name);
255
284
  if (XT_IS_FUNCTION(fn)) return xt_call_with_this(fn, target, argc, argv);
256
- xt_throw(xt_string_from_cstr("TypeError: value at computed index is not a function"));
285
+ xt_throw(xt_error_from_message("TypeError: value at computed index is not a function"));
257
286
  return XT_UNDEFINED;
258
287
  }
259
288
  if (target == XT_UNDEFINED || target == XT_NULL) {
@@ -261,13 +290,13 @@ xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *
261
290
  char message[256];
262
291
  snprintf(message, sizeof(message),
263
292
  "TypeError: Cannot read properties of %s (reading '%s')", base, method);
264
- xt_throw(xt_string_from_cstr(message));
293
+ xt_throw(xt_error_from_message(message));
265
294
  }
266
295
  int handled = 0;
267
296
  if (xt_is_symbol(target)) {
268
297
  if (strcmp(method, "toString") == 0) return xt_symbol_to_string(target);
269
298
  if (strcmp(method, "valueOf") == 0) return target;
270
- return XT_UNDEFINED;
299
+ xt_throw_no_method("symbol", method);
271
300
  }
272
301
  if (XT_IS_OBJECT(target)) {
273
302
  xt_object *obj = (xt_object *)XT_GET_PTR(target);
@@ -303,7 +332,7 @@ xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *
303
332
  {
304
333
  char message[256];
305
334
  snprintf(message, sizeof(message), "TypeError: object has no callable method '%s'", method);
306
- xt_throw(xt_string_from_cstr(message));
335
+ xt_throw(xt_error_from_message(message));
307
336
  }
308
337
  return XT_UNDEFINED;
309
338
  }
@@ -360,32 +389,38 @@ xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *
360
389
  {
361
390
  char message[256];
362
391
  snprintf(message, sizeof(message), "TypeError: function has no callable method '%s'", method);
363
- xt_throw(xt_string_from_cstr(message));
392
+ xt_throw(xt_error_from_message(message));
364
393
  }
365
394
  return XT_UNDEFINED;
366
395
  }
367
396
  if (XT_IS_ARRAY(target)) {
368
397
  xt_value result = xt_ext_array_method(target, method, argc, argv, &handled);
369
398
  if (handled) return result;
370
- return xt_array_method(target, method, argc, argv, &handled);
399
+ result = xt_array_method(target, method, argc, argv, &handled);
400
+ if (handled) return result;
401
+ xt_throw_no_method("array", method);
371
402
  }
372
403
  if (XT_IS_STRING(target)) {
373
404
  xt_value result = xt_ext_string_method(target, method, argc, argv, &handled);
374
405
  if (handled) return result;
375
- return xt_string_method(target, method, argc, argv, &handled);
406
+ result = xt_string_method(target, method, argc, argv, &handled);
407
+ if (handled) return result;
408
+ xt_throw_no_method("string", method);
376
409
  }
377
410
  if (XT_IS_BIGINT(target)) {
378
411
  xt_value result = xt_bigint_method(target, method, argc, argv, &handled);
379
412
  if (handled) return result;
413
+ xt_throw_no_method("bigint", method);
380
414
  }
381
415
  if (XT_IS_NUMBER(target)) {
382
416
  xt_value result = xt_ext_number_method(target, method, argc, argv, &handled);
383
417
  if (handled) return result;
418
+ xt_throw_no_method("number", method);
384
419
  }
385
420
  if (target == XT_TRUE || target == XT_FALSE) {
386
421
  if (strcmp(method, "toString") == 0) return target == XT_TRUE ? xt_string_from_cstr("true") : xt_string_from_cstr("false");
387
422
  if (strcmp(method, "valueOf") == 0) return target;
388
- return XT_UNDEFINED;
423
+ xt_throw_no_method("boolean", method);
389
424
  }
390
- return XT_UNDEFINED;
425
+ xt_throw_no_method("value", method);
391
426
  }
@@ -190,7 +190,7 @@ static xt_value xt_string_repeat(xt_value value, xt_value countValue) {
190
190
  if (!s) return value;
191
191
  int32_t count = xt_to_int32(countValue);
192
192
  if (count < 0) {
193
- xt_throw(xt_string_from_cstr("RangeError: Invalid count value"));
193
+ xt_throw(xt_error_from_message("RangeError: Invalid count value"));
194
194
  return XT_UNDEFINED;
195
195
  }
196
196
  xt_string *out = xt_string_alloc((size_t)s->length * (size_t)count);
@@ -1,5 +1,16 @@
1
1
  /* -- Array statics -------------------------------------------------------- */
2
2
 
3
+ /* True when `Array.from` should consume the value through the iteration
4
+ * protocol instead of the array-like `length` path. Typed arrays stay on the
5
+ * length path because their indexed properties already work that way. */
6
+ static int xt_array_from_is_iterable(xt_value value) {
7
+ if (xt_is_map(value) || xt_is_set(value) || xt_is_generator(value)) return 1;
8
+ if (XT_IS_OBJECT(value) && xt_typed_array_kind_of(value) < 0) {
9
+ return XT_IS_FUNCTION(xt_object_get(value, xt_symbol_well_known("iterator")));
10
+ }
11
+ return 0;
12
+ }
13
+
3
14
  xt_value xt_array_static(xt_value name, int32_t argc, xt_value *argv) {
4
15
  const char *fn = xt_string_data(name);
5
16
  if (!fn) return XT_UNDEFINED;
@@ -24,6 +35,20 @@ xt_value xt_array_static(xt_value name, int32_t argc, xt_value *argv) {
24
35
  if (XT_IS_FUNCTION(mapper)) { xt_value args[2] = {item, xt_number((double)i)}; item = xt_closure_call(mapper, 2, args); }
25
36
  xt_array_push(out, item);
26
37
  }
38
+ } else if (xt_array_from_is_iterable(source)) {
39
+ /* Map, Set, generators, iterator objects and custom `[Symbol.iterator]`
40
+ * values do not expose a `length`; walk their `next()` protocol instead
41
+ * of silently producing an empty array. */
42
+ xt_value iterator = xt_iter_open(source);
43
+ for (uint32_t i = 0;; i++) {
44
+ if (!xt_truthy(xt_iter_has(iterator, xt_number((double)i)))) break;
45
+ xt_value item = xt_iter_value(iterator, xt_number((double)i));
46
+ if (XT_IS_FUNCTION(mapper)) {
47
+ xt_value args[2] = {item, xt_number((double)i)};
48
+ item = xt_closure_call(mapper, 2, args);
49
+ }
50
+ xt_array_push(out, item);
51
+ }
27
52
  } else {
28
53
  double length = xt_to_number(xt_get(source, xt_string_from_cstr("length")));
29
54
  for (int32_t i = 0; i < (int32_t)length; i++) {
@@ -85,7 +85,7 @@ static xt_value xt_array_sort(xt_value value, xt_value fn) {
85
85
  int hasFn = XT_IS_FUNCTION(fn);
86
86
  xt_value *scratch = (xt_value *)malloc(sizeof(xt_value) * array->length);
87
87
  if (!scratch) {
88
- xt_throw(xt_string_from_cstr("RangeError: out of memory in Array.prototype.sort"));
88
+ xt_throw(xt_error_from_message("RangeError: out of memory in Array.prototype.sort"));
89
89
  return value;
90
90
  }
91
91
  xt_array_merge_sort(array->items, scratch, array->length, fn, hasFn);
@@ -225,7 +225,9 @@ static xt_value xt_array_with(xt_value value, xt_value indexValue, xt_value newV
225
225
  int32_t index = xt_to_int32(indexValue);
226
226
  if (index < 0) index += (int32_t)array->length;
227
227
  if (index < 0 || index >= (int32_t)array->length) {
228
- xt_throw(xt_add(xt_string_from_cstr("RangeError: Invalid index : "), xt_to_string(indexValue)));
228
+ xt_value message =
229
+ xt_add(xt_string_from_cstr("RangeError: Invalid index : "), xt_to_string(indexValue));
230
+ xt_throw(xt_error_from_message(xt_string_data(message)));
229
231
  return copy;
230
232
  }
231
233
  array->items[index] = newValue;
@@ -266,7 +268,7 @@ xt_value xt_ext_array_method(xt_value target, const char *method, int32_t argc,
266
268
  xt_value acc;
267
269
  if (argc >= 2) acc = argv[1];
268
270
  else if (array->length > 0) acc = array->items[i--];
269
- else { xt_throw(xt_string_from_cstr("TypeError: Reduce of empty array with no initial value")); return XT_UNDEFINED; }
271
+ else { xt_throw(xt_error_from_message("TypeError: Reduce of empty array with no initial value")); return XT_UNDEFINED; }
270
272
  for (; i >= 0; i--) {
271
273
  xt_value args[4] = {acc, array->items[i], xt_number((double)i), target};
272
274
  acc = xt_closure_call(fn, 4, args);
@@ -2,6 +2,11 @@ xt_value xt_ext_container_method(xt_value target, const char *method, int32_t ar
2
2
  xt_object *obj = (xt_object *)XT_GET_PTR(target);
3
3
  if (obj->header.kind == XT_OBJECT_KIND_MAP) return xt_map_method(target, method, argc, argv, handled);
4
4
  if (obj->header.kind == XT_OBJECT_KIND_SET) return xt_set_method(target, method, argc, argv, handled);
5
+ if (obj->header.kind == XT_OBJECT_KIND_WEAK_MAP ||
6
+ obj->header.kind == XT_OBJECT_KIND_WEAK_SET ||
7
+ obj->header.kind == XT_OBJECT_KIND_WEAK_REF) {
8
+ return xt_weak_method(target, method, argc, argv, handled);
9
+ }
5
10
  if (obj->header.kind == XT_OBJECT_KIND_DATE) return xt_date_method(target, method, argc, argv, handled);
6
11
  if (obj->header.kind == XT_OBJECT_KIND_REGEXP) {
7
12
  xt_regexp *regexp = (xt_regexp *)obj;