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
@@ -4,11 +4,111 @@ int xt_is_date(xt_value value) {
4
4
  return XT_IS_OBJECT(value) && ((xt_object *)XT_GET_PTR(value))->header.kind == XT_OBJECT_KIND_DATE;
5
5
  }
6
6
 
7
+ /* Parse `YYYY-MM-DD`, optionally followed by `T`/space and
8
+ * `HH:MM[:SS[.mmm]]`, then `Z`, `+HH:MM`/`-HH:MM` (or the HHMM spelling).
9
+ * A date-only value is UTC; a date-time without an offset is local time, which
10
+ * is what ECMAScript specifies. Returns milliseconds since the epoch, or NaN
11
+ * for anything outside this subset. */
12
+ static int xt_date_digits(const char *text, int count, int *out) {
13
+ int value = 0;
14
+ for (int i = 0; i < count; i++) {
15
+ if (text[i] < '0' || text[i] > '9') return 0;
16
+ value = value * 10 + (text[i] - '0');
17
+ }
18
+ *out = value;
19
+ return 1;
20
+ }
21
+
22
+ static double xt_date_parse_text(const char *text) {
23
+ size_t length = strlen(text);
24
+ size_t i = 0;
25
+ int year = 0, month = 0, day = 0;
26
+ if (length < 10 || !xt_date_digits(text, 4, &year) || text[4] != '-' ||
27
+ !xt_date_digits(text + 5, 2, &month) || text[7] != '-' ||
28
+ !xt_date_digits(text + 8, 2, &day)) {
29
+ return NAN;
30
+ }
31
+ i = 10;
32
+ int hour = 0, minute = 0, second = 0, millis = 0;
33
+ int hasTime = 0;
34
+ if (i < length && (text[i] == 'T' || text[i] == ' ')) {
35
+ hasTime = 1;
36
+ i++;
37
+ if (i + 5 > length || !xt_date_digits(text + i, 2, &hour) || text[i + 2] != ':' ||
38
+ !xt_date_digits(text + i + 3, 2, &minute)) {
39
+ return NAN;
40
+ }
41
+ i += 5;
42
+ if (i + 3 <= length && text[i] == ':') {
43
+ if (!xt_date_digits(text + i + 1, 2, &second)) return NAN;
44
+ i += 3;
45
+ }
46
+ if (i + 4 <= length && text[i] == '.') {
47
+ if (!xt_date_digits(text + i + 1, 3, &millis)) return NAN;
48
+ i += 4;
49
+ }
50
+ }
51
+ int utc = !hasTime;
52
+ int offsetSeconds = 0;
53
+ if (i < length) {
54
+ if (text[i] == 'Z') {
55
+ utc = 1;
56
+ i++;
57
+ } else if (text[i] == '+' || text[i] == '-') {
58
+ int sign = text[i] == '-' ? -1 : 1;
59
+ i++;
60
+ int offsetHour = 0, offsetMinute = 0;
61
+ if (i + 5 <= length && xt_date_digits(text + i, 2, &offsetHour) && text[i + 2] == ':' &&
62
+ xt_date_digits(text + i + 3, 2, &offsetMinute)) {
63
+ i += 5;
64
+ } else if (i + 4 <= length && xt_date_digits(text + i, 2, &offsetHour) &&
65
+ xt_date_digits(text + i + 2, 2, &offsetMinute)) {
66
+ i += 4;
67
+ } else {
68
+ return NAN;
69
+ }
70
+ if (offsetHour > 23 || offsetMinute > 59) return NAN;
71
+ offsetSeconds = sign * (offsetHour * 3600 + offsetMinute * 60);
72
+ utc = 1;
73
+ } else {
74
+ return NAN;
75
+ }
76
+ }
77
+ if (i != length) return NAN;
78
+ if (month < 1 || month > 12 || day < 1 || day > 31 ||
79
+ hour > 23 || minute > 59 || second > 59) {
80
+ return NAN;
81
+ }
82
+ struct tm tm;
83
+ memset(&tm, 0, sizeof(tm));
84
+ tm.tm_year = year - 1900;
85
+ tm.tm_mon = month - 1;
86
+ tm.tm_mday = day;
87
+ tm.tm_hour = hour;
88
+ tm.tm_min = minute;
89
+ tm.tm_sec = second;
90
+ time_t seconds;
91
+ if (utc) {
92
+ seconds = xt_timegm(&tm);
93
+ } else {
94
+ tm.tm_isdst = -1;
95
+ seconds = mktime(&tm);
96
+ if (seconds == (time_t)-1) return NAN;
97
+ }
98
+ if (utc && offsetSeconds != 0) seconds -= offsetSeconds;
99
+ return (double)seconds * 1000.0 + (double)millis;
100
+ }
101
+
7
102
  xt_value xt_date_ctor(int32_t argc, xt_value *argv) {
8
103
  xt_date *date = (xt_date *)xt_alloc(sizeof(xt_date), XT_OBJECT_KIND_DATE);
9
104
  if (argc == 0) date->time = (double)time(NULL) * 1000.0;
10
- else if (argc == 1) date->time = XT_IS_STRING(argv[0]) ? 0.0 : xt_to_number(argv[0]);
11
- else {
105
+ else if (argc == 1) {
106
+ if (XT_IS_STRING(argv[0])) {
107
+ date->time = xt_date_parse_text(xt_string_data(argv[0]));
108
+ } else {
109
+ date->time = xt_to_number(argv[0]);
110
+ }
111
+ } else {
12
112
  struct tm tm;
13
113
  memset(&tm, 0, sizeof(tm));
14
114
  tm.tm_year = xt_to_int32(argv[0]) - 1900;
@@ -27,7 +127,11 @@ xt_value xt_date_static(xt_value name, int32_t argc, xt_value *argv) {
27
127
  const char *fn = xt_string_data(name);
28
128
  if (!fn) return XT_UNDEFINED;
29
129
  if (strcmp(fn, "now") == 0) return xt_number((double)time(NULL) * 1000.0);
30
- if (strcmp(fn, "parse") == 0) return xt_number(0);
130
+ if (strcmp(fn, "parse") == 0) {
131
+ xt_value input = xt_arg_at(argc, argv, 0);
132
+ if (!XT_IS_STRING(input)) return xt_number(NAN);
133
+ return xt_number(xt_date_parse_text(xt_string_data(input)));
134
+ }
31
135
  if (strcmp(fn, "UTC") == 0) {
32
136
  struct tm tm;
33
137
  memset(&tm, 0, sizeof(tm));
@@ -68,6 +172,10 @@ static xt_value xt_date_method(xt_value target, const char *method, int32_t argc
68
172
  if (strcmp(name, "getSeconds") == 0) return xt_number(tm.tm_sec);
69
173
  if (strcmp(name, "getMilliseconds") == 0) return xt_number(fmod(date->time, 1000.0));
70
174
  if (strcmp(method, "toISOString") == 0) {
175
+ if (isnan(date->time)) {
176
+ xt_value message = xt_string_from_cstr("Invalid time value");
177
+ xt_throw(xt_range_error_ctor(1, &message));
178
+ }
71
179
  char buffer[64];
72
180
  snprintf(buffer, sizeof(buffer), "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", tm.tm_year + 1900, tm.tm_mon + 1,
73
181
  tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, (int)fmod(date->time, 1000.0));
@@ -112,6 +112,30 @@ xt_value xt_error_constructor(xt_value nameValue) {
112
112
  return closure;
113
113
  }
114
114
 
115
+ /* Build the value thrown by the runtime for an internal "Name: message"
116
+ * string. JavaScript code can observe anything thrown, so internal failures
117
+ * must be real Error instances (`instanceof Error`, `.name`, `.message`,
118
+ * `.stack`), exactly like `new TypeError("...")`; a bare string would make
119
+ * `catch` blocks silently misbehave. User `throw` expressions never go
120
+ * through this helper. */
121
+ xt_value xt_error_from_message(const char *message) {
122
+ const char *separator = strstr(message, ": ");
123
+ if (separator != NULL) {
124
+ size_t nameLength = (size_t)(separator - message);
125
+ char name[24];
126
+ if (nameLength > 0 && nameLength < sizeof(name)) {
127
+ memcpy(name, message, nameLength);
128
+ name[nameLength] = '\0';
129
+ if (xt_error_is_family(name)) {
130
+ xt_value argument = xt_string_from_cstr(separator + 2);
131
+ return xt_make_error(name, 1, &argument);
132
+ }
133
+ }
134
+ }
135
+ xt_value argument = xt_string_from_cstr(message);
136
+ return xt_make_error("Error", 1, &argument);
137
+ }
138
+
115
139
  xt_value xt_error_to_string(xt_value error) {
116
140
  xt_value name = xt_object_get(error, xt_string_from_cstr("name"));
117
141
  xt_value message = xt_object_get(error, xt_string_from_cstr("message"));
@@ -133,50 +133,152 @@ static xt_value xt_json_parse_value(xt_json_cursor *c) {
133
133
  return xt_json_parse_number(c);
134
134
  }
135
135
 
136
+ /* Reviver walk: rebuild each container bottom-up, then pass the value to the
137
+ * user callback with its holder as `this`. Returning undefined deletes an
138
+ * object property / array element, exactly like the specification. */
139
+ static xt_value xt_json_revive(xt_value holder, xt_value key, xt_value reviver) {
140
+ xt_value value = xt_get(holder, key);
141
+ if (XT_IS_ARRAY(value)) {
142
+ xt_array *array = xt_as_array(value);
143
+ for (uint32_t i = 0; i < array->length; i++) {
144
+ /* Reviver keys are strings even for array indices. */
145
+ char keyBuffer[16];
146
+ snprintf(keyBuffer, sizeof(keyBuffer), "%u", i);
147
+ xt_value index = xt_string_from_cstr(keyBuffer);
148
+ xt_value updated = xt_json_revive(value, index, reviver);
149
+ if (updated == XT_UNDEFINED) xt_delete(value, index);
150
+ else xt_set(value, index, updated);
151
+ }
152
+ } else if (XT_IS_OBJECT(value)) {
153
+ xt_value keys = xt_object_keys(value);
154
+ xt_array *list = xt_as_array(keys);
155
+ if (list) {
156
+ for (uint32_t i = 0; i < list->length; i++) {
157
+ xt_value childKey = list->items[i];
158
+ xt_value updated = xt_json_revive(value, childKey, reviver);
159
+ if (updated == XT_UNDEFINED) xt_delete(value, childKey);
160
+ else xt_object_set(value, childKey, updated);
161
+ }
162
+ }
163
+ }
164
+ xt_value args[2] = {key, value};
165
+ return xt_call_with_this(reviver, holder, 2, args);
166
+ }
167
+
136
168
  xt_value xt_json_parse(int32_t argc, xt_value *argv) {
137
169
  xt_value input = xt_to_string(xt_arg_at(argc, argv, 0));
138
170
  xt_string *s = xt_as_string(input);
139
171
  if (!s) return XT_UNDEFINED;
140
172
  xt_json_cursor cursor = {xt_string_bytes(s), s->length, 0};
141
- return xt_json_parse_value(&cursor);
173
+ xt_value parsed = xt_json_parse_value(&cursor);
174
+ xt_value reviver = xt_arg_at(argc, argv, 1);
175
+ if (!XT_IS_FUNCTION(reviver)) return parsed;
176
+ xt_value holder = xt_object_new();
177
+ xt_object_set(holder, xt_string_from_cstr(""), parsed);
178
+ return xt_json_revive(holder, xt_string_from_cstr(""), reviver);
142
179
  }
143
180
 
144
- static void xt_json_stringify_value(xt_value value, int indent, int depth, xt_value *out);
181
+ static void xt_json_stringify_value(xt_value value, xt_value indent, int depth, xt_value *out);
145
182
 
146
- static void xt_json_indent(xt_value *out, int indent, int depth) {
147
- if (indent <= 0) return;
183
+ /* The indentation unit for the `space` argument: up to 10 spaces for a
184
+ * number, or the first 10 UTF-16 code units of a string (any characters,
185
+ * not just spaces), matching JSON.stringify. An empty string means compact. */
186
+ static xt_value xt_json_space_unit(xt_value space) {
187
+ if (XT_IS_NUMBER(space)) {
188
+ int count = xt_to_int32(space);
189
+ if (count < 0) count = 0;
190
+ if (count > 10) count = 10;
191
+ char spaces[10];
192
+ memset(spaces, ' ', (size_t)count);
193
+ return xt_string_new(spaces, (size_t)count);
194
+ }
195
+ if (XT_IS_STRING(space)) {
196
+ xt_string *s = xt_as_string(space);
197
+ const char *bytes = xt_string_bytes(s);
198
+ size_t offset = 0;
199
+ size_t end = 0;
200
+ uint32_t units = 0;
201
+ while (offset < s->length && units < 10) {
202
+ size_t width = 0;
203
+ uint32_t code = xt_utf8_decode(bytes + offset, s->length - offset, &width);
204
+ units += code >= 0x10000 ? 2 : 1;
205
+ offset += width;
206
+ if (units <= 10) end = offset;
207
+ }
208
+ return xt_string_new(bytes, end);
209
+ }
210
+ return xt_string_from_cstr("");
211
+ }
212
+
213
+ static int xt_json_indented(xt_value unit) {
214
+ return XT_IS_STRING(unit) && xt_as_string(unit)->length > 0;
215
+ }
216
+
217
+ static void xt_json_indent(xt_value *out, xt_value unit, int depth) {
218
+ if (!xt_json_indented(unit)) return;
148
219
  *out = xt_add(*out, xt_string_from_cstr("\n"));
149
- for (int i = 0; i < indent * depth; i++) *out = xt_add(*out, xt_string_from_cstr(" "));
220
+ for (int i = 0; i < depth; i++) *out = xt_add(*out, unit);
221
+ }
222
+
223
+ /* Containers on the current serialization path. A repeated pointer is a cycle;
224
+ * serializing it would recurse until the native stack overflowed (a hard crash,
225
+ * not the TypeError the platform throws). */
226
+ static xt_value *xt_json_path = NULL;
227
+ static uint32_t xt_json_path_count = 0;
228
+ static uint32_t xt_json_path_capacity = 0;
229
+
230
+ static void xt_json_enter(xt_value value) {
231
+ for (uint32_t i = 0; i < xt_json_path_count; i++) {
232
+ if (xt_json_path[i] == value) {
233
+ xt_value message = xt_string_from_cstr("Converting circular structure to JSON");
234
+ xt_throw(xt_type_error_ctor(1, &message));
235
+ }
236
+ }
237
+ if (xt_json_path_count >= xt_json_path_capacity) {
238
+ uint32_t capacity = xt_json_path_capacity == 0 ? 16 : xt_json_path_capacity * 2;
239
+ xt_value *path = (xt_value *)realloc(xt_json_path, sizeof(xt_value) * capacity);
240
+ if (!path) abort();
241
+ xt_json_path = path;
242
+ xt_json_path_capacity = capacity;
243
+ }
244
+ xt_json_path[xt_json_path_count++] = value;
245
+ }
246
+
247
+ static void xt_json_leave(void) {
248
+ if (xt_json_path_count > 0) xt_json_path_count--;
150
249
  }
151
250
 
152
- static void xt_json_stringify_array(xt_value value, int indent, int depth, xt_value *out) {
251
+ static void xt_json_stringify_array(xt_value value, xt_value indent, int depth, xt_value *out) {
153
252
  xt_array *array = xt_as_array(value);
154
253
  if (!array || array->length == 0) { *out = xt_add(*out, xt_string_from_cstr("[]")); return; }
155
254
  *out = xt_add(*out, xt_string_from_cstr("["));
255
+ xt_json_enter(value);
156
256
  for (uint32_t i = 0; i < array->length; i++) {
157
257
  if (i > 0) *out = xt_add(*out, xt_string_from_cstr(","));
158
258
  xt_json_indent(out, indent, depth + 1);
159
259
  xt_json_stringify_value(array->items[i], indent, depth + 1, out);
160
260
  }
161
261
  xt_json_indent(out, indent, depth);
262
+ xt_json_leave();
162
263
  *out = xt_add(*out, xt_string_from_cstr("]"));
163
264
  }
164
265
 
165
- static void xt_json_stringify_object(xt_value value, int indent, int depth, xt_value *out) {
266
+ static void xt_json_stringify_object(xt_value value, xt_value indent, int depth, xt_value *out) {
166
267
  xt_value keys = xt_object_keys(value);
167
268
  xt_array *array = xt_as_array(keys);
168
269
  if (!array) { *out = xt_add(*out, xt_string_from_cstr("{}")); return; }
169
270
  int any = 0;
170
271
  for (uint32_t i = 0; i < array->length; i++) {
171
- xt_value item = xt_object_get(value, array->items[i]);
272
+ xt_value item = xt_get(value, array->items[i]);
172
273
  if (item != XT_UNDEFINED && !XT_IS_FUNCTION(item) && !xt_is_symbol(item)) { any = 1; break; }
173
274
  }
174
275
  if (!any) { *out = xt_add(*out, xt_string_from_cstr("{}")); return; }
175
276
  *out = xt_add(*out, xt_string_from_cstr("{"));
277
+ xt_json_enter(value);
176
278
  int written = 0;
177
279
  for (uint32_t i = 0; i < array->length; i++) {
178
280
  xt_value key = array->items[i];
179
- xt_value item = xt_object_get(value, key);
281
+ xt_value item = xt_get(value, key);
180
282
  /* `undefined`, functions and symbols are omitted from objects. */
181
283
  if (item == XT_UNDEFINED || XT_IS_FUNCTION(item) || xt_is_symbol(item)) continue;
182
284
  if (written > 0) *out = xt_add(*out, xt_string_from_cstr(","));
@@ -185,20 +287,21 @@ static void xt_json_stringify_object(xt_value value, int indent, int depth, xt_v
185
287
  *out = xt_add(*out, xt_string_from_cstr("\""));
186
288
  *out = xt_add(*out, key);
187
289
  *out = xt_add(*out, xt_string_from_cstr("\":"));
188
- if (indent > 0) *out = xt_add(*out, xt_string_from_cstr(" "));
290
+ if (xt_json_indented(indent)) *out = xt_add(*out, xt_string_from_cstr(" "));
189
291
  xt_json_stringify_value(item, indent, depth + 1, out);
190
292
  }
191
293
  xt_json_indent(out, indent, depth);
294
+ xt_json_leave();
192
295
  *out = xt_add(*out, xt_string_from_cstr("}"));
193
296
  }
194
297
 
195
- static void xt_json_stringify_value(xt_value value, int indent, int depth, xt_value *out) {
298
+ static void xt_json_stringify_value(xt_value value, xt_value indent, int depth, xt_value *out) {
196
299
  if (value == XT_UNDEFINED || value == XT_NULL || XT_IS_FUNCTION(value) || xt_is_symbol(value)) {
197
300
  *out = xt_add(*out, xt_string_from_cstr("null"));
198
301
  return;
199
302
  }
200
303
  if (XT_IS_BIGINT(value)) {
201
- xt_throw(xt_string_from_cstr("TypeError: Do not know how to serialize a BigInt"));
304
+ xt_throw(xt_error_from_message("TypeError: Do not know how to serialize a BigInt"));
202
305
  return;
203
306
  }
204
307
  if (XT_IS_BOOL(value)) { *out = xt_add(*out, value == XT_TRUE ? xt_string_from_cstr("true") : xt_string_from_cstr("false")); return; }
@@ -237,19 +340,207 @@ static void xt_json_stringify_value(xt_value value, int indent, int depth, xt_va
237
340
  return;
238
341
  }
239
342
  if (XT_IS_ARRAY(value)) { xt_json_stringify_array(value, indent, depth, out); return; }
240
- if (XT_IS_OBJECT(value)) { xt_json_stringify_object(value, indent, depth, out); return; }
343
+ if (XT_IS_OBJECT(value)) {
344
+ /* Map/Set/Date/RegExp/Promise/generators are not property-bag objects;
345
+ * handing them to xt_json_stringify_object reads their fields as a property
346
+ * table and crashed with an access violation. JSON sees no enumerable own
347
+ * properties on the first group and calls Date.prototype.toJSON. */
348
+ xt_object *object = (xt_object *)XT_GET_PTR(value);
349
+ switch (object->header.kind) {
350
+ case XT_OBJECT_KIND_MAP:
351
+ case XT_OBJECT_KIND_SET:
352
+ case XT_OBJECT_KIND_REGEXP:
353
+ case XT_OBJECT_KIND_PROMISE:
354
+ case XT_OBJECT_KIND_GENERATOR:
355
+ case XT_OBJECT_KIND_ITERATOR:
356
+ case XT_OBJECT_KIND_ASYNC:
357
+ *out = xt_add(*out, xt_string_from_cstr("{}"));
358
+ return;
359
+ case XT_OBJECT_KIND_DATE: {
360
+ xt_value time = xt_call_method(value, xt_string_from_cstr("getTime"), 0, NULL);
361
+ if (isnan(xt_to_number(time))) {
362
+ *out = xt_add(*out, xt_string_from_cstr("null"));
363
+ return;
364
+ }
365
+ xt_value text = xt_call_method(value, xt_string_from_cstr("toJSON"), 0, NULL);
366
+ xt_json_stringify_value(text, indent, depth, out);
367
+ return;
368
+ }
369
+ default:
370
+ break;
371
+ }
372
+ xt_json_stringify_object(value, indent, depth, out);
373
+ return;
374
+ }
241
375
  *out = xt_add(*out, xt_string_from_cstr("null"));
242
376
  }
243
377
 
378
+ /* -- replacer-aware stringify -------------------------------------------- */
379
+ /*
380
+ * The replacer overload needs the holder and key of every value, so it gets a
381
+ * separate walk instead of complicating the fast path. It also calls `toJSON`
382
+ * and filters object keys through an array replacer.
383
+ */
384
+ typedef struct {
385
+ xt_value replacer;
386
+ xt_value indent;
387
+ xt_value *path;
388
+ uint32_t path_count;
389
+ uint32_t path_capacity;
390
+ } xt_json_replacer_context;
391
+
392
+ static void xt_json_replacer_enter(xt_json_replacer_context *ctx, xt_value value) {
393
+ for (uint32_t i = 0; i < ctx->path_count; i++) {
394
+ if (ctx->path[i] == value) {
395
+ xt_value message = xt_string_from_cstr("Converting circular structure to JSON");
396
+ xt_throw(xt_type_error_ctor(1, &message));
397
+ }
398
+ }
399
+ if (ctx->path_count >= ctx->path_capacity) {
400
+ uint32_t capacity = ctx->path_capacity == 0 ? 16 : ctx->path_capacity * 2;
401
+ xt_value *path = (xt_value *)realloc(ctx->path, sizeof(xt_value) * capacity);
402
+ if (!path) abort();
403
+ ctx->path = path;
404
+ ctx->path_capacity = capacity;
405
+ }
406
+ ctx->path[ctx->path_count++] = value;
407
+ }
408
+
409
+ static void xt_json_replacer_leave(xt_json_replacer_context *ctx) {
410
+ if (ctx->path_count > 0) ctx->path_count--;
411
+ }
412
+
413
+ static void xt_json_replacer_indent(xt_json_replacer_context *ctx, int depth, xt_value *out) {
414
+ xt_json_indent(out, ctx->indent, depth);
415
+ }
416
+
417
+ static int xt_json_replacer_allows(xt_value replacer, xt_value key) {
418
+ if (!XT_IS_ARRAY(replacer)) return 1;
419
+ xt_array *allowed = xt_as_array(replacer);
420
+ for (uint32_t i = 0; i < allowed->length; i++) {
421
+ xt_value item = allowed->items[i];
422
+ if (!XT_IS_STRING(item) && !XT_IS_NUMBER(item)) continue;
423
+ xt_value text = xt_to_string(item);
424
+ xt_string *a = xt_as_string(text);
425
+ xt_string *b = xt_as_string(key);
426
+ if (a && b && xt_string_equals(a, b)) return 1;
427
+ }
428
+ return 0;
429
+ }
430
+
431
+ static int xt_json_replacer_write(xt_json_replacer_context *ctx, xt_value holder, xt_value key,
432
+ int depth, xt_value *out);
433
+
434
+ static int xt_json_replacer_container(xt_json_replacer_context *ctx, xt_value value, int depth,
435
+ xt_value *out) {
436
+ xt_json_replacer_enter(ctx, value);
437
+ if (XT_IS_ARRAY(value)) {
438
+ xt_array *array = xt_as_array(value);
439
+ *out = xt_add(*out, xt_string_from_cstr("["));
440
+ for (uint32_t i = 0; i < array->length; i++) {
441
+ if (i > 0) *out = xt_add(*out, xt_string_from_cstr(","));
442
+ xt_json_replacer_indent(ctx, depth + 1, out);
443
+ char keyBuffer[16];
444
+ snprintf(keyBuffer, sizeof(keyBuffer), "%u", i);
445
+ xt_value temporary = xt_string_from_cstr("");
446
+ int wrote = xt_json_replacer_write(ctx, value, xt_string_from_cstr(keyBuffer), depth + 1,
447
+ &temporary);
448
+ *out = xt_add(*out, wrote ? temporary : xt_string_from_cstr("null"));
449
+ }
450
+ xt_json_replacer_indent(ctx, depth, out);
451
+ xt_json_replacer_leave(ctx);
452
+ *out = xt_add(*out, xt_string_from_cstr("]"));
453
+ return 1;
454
+ }
455
+
456
+ xt_value keys = xt_object_keys(value);
457
+ xt_array *list = xt_as_array(keys);
458
+ *out = xt_add(*out, xt_string_from_cstr("{"));
459
+ int written = 0;
460
+ if (list) {
461
+ for (uint32_t i = 0; i < list->length; i++) {
462
+ xt_value childKey = list->items[i];
463
+ if (!xt_json_replacer_allows(ctx->replacer, childKey)) continue;
464
+ xt_value temporary = xt_string_from_cstr("");
465
+ int wrote = xt_json_replacer_write(ctx, value, childKey, depth + 1, &temporary);
466
+ if (!wrote) continue;
467
+ if (written > 0) *out = xt_add(*out, xt_string_from_cstr(","));
468
+ written++;
469
+ xt_json_replacer_indent(ctx, depth + 1, out);
470
+ *out = xt_add(*out, xt_string_from_cstr("\""));
471
+ *out = xt_add(*out, childKey);
472
+ *out = xt_add(*out, xt_string_from_cstr("\":"));
473
+ if (xt_json_indented(ctx->indent)) *out = xt_add(*out, xt_string_from_cstr(" "));
474
+ *out = xt_add(*out, temporary);
475
+ }
476
+ }
477
+ xt_json_replacer_indent(ctx, depth, out);
478
+ xt_json_replacer_leave(ctx);
479
+ *out = xt_add(*out, xt_string_from_cstr("}"));
480
+ return 1;
481
+ }
482
+
483
+ static int xt_json_replacer_write(xt_json_replacer_context *ctx, xt_value holder, xt_value key,
484
+ int depth, xt_value *out) {
485
+ xt_value value = xt_get(holder, key);
486
+ if (XT_IS_FUNCTION(ctx->replacer)) {
487
+ xt_value args[2] = {key, value};
488
+ value = xt_call_with_this(ctx->replacer, holder, 2, args);
489
+ }
490
+ if (xt_is_date(value)) {
491
+ value = xt_call_method(value, xt_string_from_cstr("toJSON"), 1, &key);
492
+ } else if (XT_IS_ARRAY(value) ||
493
+ (XT_IS_OBJECT(value) &&
494
+ (((xt_object *)XT_GET_PTR(value))->header.kind == XT_OBJECT_KIND_OBJECT ||
495
+ ((xt_object *)XT_GET_PTR(value))->header.kind == XT_OBJECT_KIND_ERROR))) {
496
+ xt_value toJSON = XT_IS_ARRAY(value) ? xt_get(value, xt_string_from_cstr("toJSON"))
497
+ : xt_object_get(value, xt_string_from_cstr("toJSON"));
498
+ if (XT_IS_FUNCTION(toJSON)) {
499
+ xt_value args[1] = {key};
500
+ value = xt_call_with_this(toJSON, value, 1, args);
501
+ }
502
+ }
503
+ if (value == XT_UNDEFINED || XT_IS_FUNCTION(value) || xt_is_symbol(value)) return 0;
504
+ if (XT_IS_BIGINT(value)) {
505
+ xt_value message = xt_string_from_cstr("Do not know how to serialize a BigInt");
506
+ xt_throw(xt_type_error_ctor(1, &message));
507
+ }
508
+ if (XT_IS_ARRAY(value)) return xt_json_replacer_container(ctx, value, depth, out);
509
+ if (XT_IS_OBJECT(value)) {
510
+ int kind = ((xt_object *)XT_GET_PTR(value))->header.kind;
511
+ if (kind == XT_OBJECT_KIND_MAP || kind == XT_OBJECT_KIND_SET ||
512
+ kind == XT_OBJECT_KIND_REGEXP || kind == XT_OBJECT_KIND_PROMISE ||
513
+ kind == XT_OBJECT_KIND_GENERATOR || kind == XT_OBJECT_KIND_ITERATOR ||
514
+ kind == XT_OBJECT_KIND_ASYNC) {
515
+ *out = xt_add(*out, xt_string_from_cstr("{}"));
516
+ return 1;
517
+ }
518
+ return xt_json_replacer_container(ctx, value, depth, out);
519
+ }
520
+ xt_json_stringify_value(value, ctx->indent, depth, out);
521
+ return 1;
522
+ }
523
+
244
524
  xt_value xt_json_stringify(int32_t argc, xt_value *argv) {
245
- int indent = 0;
246
- xt_value space = xt_arg_at(argc, argv, 1);
247
- if (XT_IS_NUMBER(space)) indent = xt_to_int32(space);
248
- else if (XT_IS_STRING(space)) indent = (int)xt_string_utf16_length((xt_string *)XT_GET_PTR(space));
249
- if (indent < 0) indent = 0;
250
- if (indent > 10) indent = 10;
251
525
  xt_value value = xt_arg_at(argc, argv, 0);
252
526
  if (value == XT_UNDEFINED || XT_IS_FUNCTION(value) || xt_is_symbol(value)) return XT_UNDEFINED;
527
+ /* Signature: stringify(value, replacer, space). The replacer is argv[1] and
528
+ * the indentation is argv[2]; reading argv[1] as `space` silently ignored
529
+ * `JSON.stringify(value, null, 2)`. */
530
+ xt_value indent = xt_json_space_unit(xt_arg_at(argc, argv, 2));
531
+ xt_value replacer = xt_arg_at(argc, argv, 1);
532
+ if (XT_IS_FUNCTION(replacer) || XT_IS_ARRAY(replacer)) {
533
+ xt_json_replacer_context context = {replacer, indent, NULL, 0, 0};
534
+ xt_value wrapper = xt_object_new();
535
+ xt_object_set(wrapper, xt_string_from_cstr(""), value);
536
+ xt_value out = xt_string_from_cstr("");
537
+ int wrote = xt_json_replacer_write(&context, wrapper, xt_string_from_cstr(""), 0, &out);
538
+ free(context.path);
539
+ return wrote ? out : XT_UNDEFINED;
540
+ }
541
+ /* A caught circular-structure error longjmps past xt_json_leave; start every
542
+ * top-level serialization with a clean path. */
543
+ xt_json_path_count = 0;
253
544
  xt_value out = xt_string_from_cstr("");
254
545
  xt_json_stringify_value(value, indent, 0, &out);
255
546
  return out;
@@ -60,7 +60,7 @@ xt_value xt_string_static(xt_value name, int32_t argc, xt_value *argv) {
60
60
  int32_t code = xt_to_int32(argv[i]);
61
61
  if (code < 0 || code > 0x10FFFF) {
62
62
  free(out);
63
- xt_throw(xt_string_from_cstr("RangeError: Invalid code point"));
63
+ xt_throw(xt_error_from_message("RangeError: Invalid code point"));
64
64
  return XT_UNDEFINED;
65
65
  }
66
66
  length += xt_utf8_encode((uint32_t)code, out + length);