xbintsc 0.5.6 → 0.5.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (436) hide show
  1. package/AGENTS.md +16 -8
  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 +94 -233
  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 +111 -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/parser/declarations/classes.js +5 -0
  80. package/dist/src/parser/declarations/classes.js.map +1 -1
  81. package/dist/src/parser/declarations/functions.js +13 -1
  82. package/dist/src/parser/declarations/functions.js.map +1 -1
  83. package/dist/src/parser/modules.js +8 -3
  84. package/dist/src/parser/modules.js.map +1 -1
  85. package/dist/src/parser/parser.d.ts +1 -0
  86. package/dist/src/parser/parser.js +23 -0
  87. package/dist/src/parser/parser.js.map +1 -1
  88. package/dist/tests/cli/check.test.d.ts +6 -0
  89. package/dist/tests/cli/check.test.js +68 -0
  90. package/dist/tests/cli/check.test.js.map +1 -0
  91. package/dist/tests/cli/main.test.js +19 -0
  92. package/dist/tests/cli/main.test.js.map +1 -1
  93. package/dist/tests/cli/watch.test.d.ts +6 -0
  94. package/dist/tests/cli/watch.test.js +72 -0
  95. package/dist/tests/cli/watch.test.js.map +1 -0
  96. package/dist/tests/codegen/expressions.test.js +15 -3
  97. package/dist/tests/codegen/expressions.test.js.map +1 -1
  98. package/dist/tests/codegen/llvm.test.js +16 -0
  99. package/dist/tests/codegen/llvm.test.js.map +1 -1
  100. package/dist/tests/diagnostics/diagnostic.test.js +8 -0
  101. package/dist/tests/diagnostics/diagnostic.test.js.map +1 -1
  102. package/dist/tests/docs/structure.test.d.ts +1 -0
  103. package/dist/tests/docs/structure.test.js +92 -0
  104. package/dist/tests/docs/structure.test.js.map +1 -0
  105. package/dist/tests/driver/compiler.test.js +6 -0
  106. package/dist/tests/driver/compiler.test.js.map +1 -1
  107. package/dist/tests/driver/config.test.js +9 -0
  108. package/dist/tests/driver/config.test.js.map +1 -1
  109. package/dist/tests/driver/icon.test.js +19 -32
  110. package/dist/tests/driver/icon.test.js.map +1 -1
  111. package/dist/tests/driver/invalid-input.test.d.ts +10 -0
  112. package/dist/tests/driver/invalid-input.test.js +29 -0
  113. package/dist/tests/driver/invalid-input.test.js.map +1 -0
  114. package/dist/tests/driver/modules.test.js +42 -3
  115. package/dist/tests/driver/modules.test.js.map +1 -1
  116. package/dist/tests/driver/toolchain-provider.test.js +27 -1
  117. package/dist/tests/driver/toolchain-provider.test.js.map +1 -1
  118. package/dist/tests/driver/toolchain.test.js +60 -2
  119. package/dist/tests/driver/toolchain.test.js.map +1 -1
  120. package/dist/tests/e2e/array-buffer.test.d.ts +5 -0
  121. package/dist/tests/e2e/array-buffer.test.js +38 -0
  122. package/dist/tests/e2e/array-buffer.test.js.map +1 -0
  123. package/dist/tests/e2e/array-from-iterables.test.d.ts +7 -0
  124. package/dist/tests/e2e/array-from-iterables.test.js +34 -0
  125. package/dist/tests/e2e/array-from-iterables.test.js.map +1 -0
  126. package/dist/tests/e2e/array-symbol-iterator.test.d.ts +8 -0
  127. package/dist/tests/e2e/array-symbol-iterator.test.js +42 -0
  128. package/dist/tests/e2e/array-symbol-iterator.test.js.map +1 -0
  129. package/dist/tests/e2e/async-generators.test.d.ts +1 -0
  130. package/dist/tests/e2e/async-generators.test.js +154 -0
  131. package/dist/tests/e2e/async-generators.test.js.map +1 -0
  132. package/dist/tests/e2e/await-ordering.test.d.ts +5 -0
  133. package/dist/tests/e2e/await-ordering.test.js +37 -0
  134. package/dist/tests/e2e/await-ordering.test.js.map +1 -0
  135. package/dist/tests/e2e/compile-builtins.test.js +1 -1
  136. package/dist/tests/e2e/compile-modules.test.js +7 -0
  137. package/dist/tests/e2e/compile-modules.test.js.map +1 -1
  138. package/dist/tests/e2e/date-parse.test.d.ts +8 -0
  139. package/dist/tests/e2e/date-parse.test.js +38 -0
  140. package/dist/tests/e2e/date-parse.test.js.map +1 -0
  141. package/dist/tests/e2e/default-anonymous-exports.test.d.ts +7 -0
  142. package/dist/tests/e2e/default-anonymous-exports.test.js +23 -0
  143. package/dist/tests/e2e/default-anonymous-exports.test.js.map +1 -0
  144. package/dist/tests/e2e/globals-microtask.test.d.ts +9 -0
  145. package/dist/tests/e2e/globals-microtask.test.js +37 -0
  146. package/dist/tests/e2e/globals-microtask.test.js.map +1 -0
  147. package/dist/tests/e2e/gui-media.test.js +8 -1
  148. package/dist/tests/e2e/gui-media.test.js.map +1 -1
  149. package/dist/tests/e2e/inspect-builtins.test.d.ts +10 -0
  150. package/dist/tests/e2e/inspect-builtins.test.js +43 -0
  151. package/dist/tests/e2e/inspect-builtins.test.js.map +1 -0
  152. package/dist/tests/e2e/json-builtin-objects.test.d.ts +9 -0
  153. package/dist/tests/e2e/json-builtin-objects.test.js +23 -0
  154. package/dist/tests/e2e/json-builtin-objects.test.js.map +1 -0
  155. package/dist/tests/e2e/json-circular.test.d.ts +6 -0
  156. package/dist/tests/e2e/json-circular.test.js +43 -0
  157. package/dist/tests/e2e/json-circular.test.js.map +1 -0
  158. package/dist/tests/e2e/json-parse-reviver.test.d.ts +6 -0
  159. package/dist/tests/e2e/json-parse-reviver.test.js +29 -0
  160. package/dist/tests/e2e/json-parse-reviver.test.js.map +1 -0
  161. package/dist/tests/e2e/json-stringify-replacer.test.d.ts +6 -0
  162. package/dist/tests/e2e/json-stringify-replacer.test.js +27 -0
  163. package/dist/tests/e2e/json-stringify-replacer.test.js.map +1 -0
  164. package/dist/tests/e2e/json-stringify-space.test.d.ts +6 -0
  165. package/dist/tests/e2e/json-stringify-space.test.js +23 -0
  166. package/dist/tests/e2e/json-stringify-space.test.js.map +1 -0
  167. package/dist/tests/e2e/method-dispatch-errors.test.d.ts +9 -0
  168. package/dist/tests/e2e/method-dispatch-errors.test.js +38 -0
  169. package/dist/tests/e2e/method-dispatch-errors.test.js.map +1 -0
  170. package/dist/tests/e2e/native-extensions.test.js +1 -1
  171. package/dist/tests/e2e/native-extensions.test.js.map +1 -1
  172. package/dist/tests/e2e/promise-with-resolvers.test.d.ts +5 -0
  173. package/dist/tests/e2e/promise-with-resolvers.test.js +20 -0
  174. package/dist/tests/e2e/promise-with-resolvers.test.js.map +1 -0
  175. package/dist/tests/e2e/property-descriptors.test.d.ts +5 -0
  176. package/dist/tests/e2e/property-descriptors.test.js +25 -0
  177. package/dist/tests/e2e/property-descriptors.test.js.map +1 -0
  178. package/dist/tests/e2e/property-ic.test.d.ts +1 -0
  179. package/dist/tests/e2e/property-ic.test.js +55 -0
  180. package/dist/tests/e2e/property-ic.test.js.map +1 -0
  181. package/dist/tests/e2e/runtime-errors.test.d.ts +10 -0
  182. package/dist/tests/e2e/runtime-errors.test.js +52 -0
  183. package/dist/tests/e2e/runtime-errors.test.js.map +1 -0
  184. package/dist/tests/e2e/structured-clone.test.d.ts +6 -0
  185. package/dist/tests/e2e/structured-clone.test.js +49 -0
  186. package/dist/tests/e2e/structured-clone.test.js.map +1 -0
  187. package/dist/tests/e2e/text-codec.test.d.ts +6 -0
  188. package/dist/tests/e2e/text-codec.test.js +24 -0
  189. package/dist/tests/e2e/text-codec.test.js.map +1 -0
  190. package/dist/tests/e2e/typed-array-views.test.d.ts +6 -0
  191. package/dist/tests/e2e/typed-array-views.test.js +39 -0
  192. package/dist/tests/e2e/typed-array-views.test.js.map +1 -0
  193. package/dist/tests/e2e/url-search-params.test.d.ts +5 -0
  194. package/dist/tests/e2e/url-search-params.test.js +30 -0
  195. package/dist/tests/e2e/url-search-params.test.js.map +1 -0
  196. package/dist/tests/e2e/weak-collections.test.d.ts +1 -0
  197. package/dist/tests/e2e/weak-collections.test.js +88 -0
  198. package/dist/tests/e2e/weak-collections.test.js.map +1 -0
  199. package/dist/tests/parser/declarations.test.js +12 -0
  200. package/dist/tests/parser/declarations.test.js.map +1 -1
  201. package/dist/tests/parser/module-syntax.test.js +9 -0
  202. package/dist/tests/parser/module-syntax.test.js.map +1 -1
  203. package/dist/tests/parser/parser.test.js +7 -0
  204. package/dist/tests/parser/parser.test.js.map +1 -1
  205. package/dist/tests/version.test.js +5 -1
  206. package/dist/tests/version.test.js.map +1 -1
  207. package/doc/ai/README.md +4 -3
  208. package/doc/ai/cli.md +41 -0
  209. package/doc/ai/contributing.md +18 -15
  210. package/doc/ai/extensions.md +9 -7
  211. package/doc/ai/language-support.md +17 -13
  212. package/doc/ai/troubleshooting.md +11 -9
  213. package/doc/ai/zh-CN/README.md +3 -2
  214. package/doc/ai/zh-CN/cli.md +35 -0
  215. package/doc/ai/zh-CN/contributing.md +15 -14
  216. package/doc/ai/zh-CN/extensions.md +8 -6
  217. package/doc/ai/zh-CN/language-support.md +17 -14
  218. package/doc/ai/zh-CN/troubleshooting.md +9 -8
  219. package/doc/gui/build.md +13 -4
  220. package/doc/gui/known-issues.md +9 -5
  221. package/doc/gui/rendering.md +3 -1
  222. package/doc/gui.md +4 -3
  223. package/doc/icon.md +5 -4
  224. package/doc/implemented/async.md +38 -0
  225. package/doc/implemented/binder.md +13 -0
  226. package/doc/implemented/cli.md +47 -0
  227. package/doc/implemented/codegen.md +33 -0
  228. package/doc/implemented/collections.md +26 -0
  229. package/doc/implemented/driver.md +19 -0
  230. package/doc/implemented/extensions.md +19 -0
  231. package/doc/implemented/fetch.md +12 -0
  232. package/doc/implemented/lexer.md +23 -0
  233. package/doc/implemented/modules.md +28 -0
  234. package/doc/implemented/node/assert.md +17 -0
  235. package/doc/implemented/node/buffer.md +29 -0
  236. package/doc/implemented/node/child-process.md +29 -0
  237. package/doc/implemented/node/crypto.md +9 -0
  238. package/doc/implemented/node/dgram.md +15 -0
  239. package/doc/implemented/node/events.md +37 -0
  240. package/doc/implemented/node/fs-promises.md +38 -0
  241. package/doc/implemented/node/fs.md +112 -0
  242. package/doc/implemented/node/http.md +21 -0
  243. package/doc/implemented/node/net.md +17 -0
  244. package/doc/implemented/node/os.md +22 -0
  245. package/doc/implemented/node/path.md +33 -0
  246. package/doc/implemented/node/process.md +23 -0
  247. package/doc/implemented/node/querystring.md +20 -0
  248. package/doc/implemented/node/stream-promises.md +8 -0
  249. package/doc/implemented/node/stream.md +19 -0
  250. package/doc/implemented/node/test.md +10 -0
  251. package/doc/implemented/node/url.md +8 -0
  252. package/doc/implemented/node/util.md +25 -0
  253. package/doc/implemented/node/worker-threads.md +10 -0
  254. package/doc/implemented/node/zlib.md +8 -0
  255. package/doc/implemented/node.md +48 -0
  256. package/doc/implemented/operators.md +38 -0
  257. package/doc/implemented/parser.md +58 -0
  258. package/doc/implemented/pipeline.md +28 -0
  259. package/doc/implemented/runtime-core.md +32 -0
  260. package/doc/implemented/stdlib.md +78 -0
  261. package/doc/implemented/strings.md +27 -0
  262. package/doc/implemented/tests.md +10 -0
  263. package/doc/implemented/typed-arrays.md +26 -0
  264. package/doc/implemented/value-model.md +18 -0
  265. package/doc/implemented.md +54 -355
  266. package/doc/node-implemented.md +3 -585
  267. package/doc/node-unimplemented.md +3 -164
  268. package/doc/requirements.md +23 -8
  269. package/doc/unimplemented/classes.md +22 -0
  270. package/doc/unimplemented/deviations.md +27 -0
  271. package/doc/unimplemented/expressions.md +26 -0
  272. package/doc/unimplemented/functions.md +21 -0
  273. package/doc/unimplemented/modules.md +22 -0
  274. package/doc/unimplemented/node/async.md +17 -0
  275. package/doc/unimplemented/node/bun.md +9 -0
  276. package/doc/unimplemented/node/fs-promises.md +16 -0
  277. package/doc/unimplemented/node/fs.md +31 -0
  278. package/doc/unimplemented/node/globals.md +23 -0
  279. package/doc/unimplemented/node/modules.md +21 -0
  280. package/doc/unimplemented/node.md +21 -0
  281. package/doc/unimplemented/statements.md +18 -0
  282. package/doc/unimplemented/stdlib.md +54 -0
  283. package/doc/unimplemented/toolchain.md +14 -0
  284. package/doc/unimplemented/types.md +12 -0
  285. package/doc/unimplemented.md +18 -275
  286. package/doc/xbintsc.config.schema.json +12 -0
  287. package/doc/zh-CN/gui/build.md +11 -3
  288. package/doc/zh-CN/gui/known-issues.md +9 -4
  289. package/doc/zh-CN/gui/rendering.md +2 -1
  290. package/doc/zh-CN/gui.md +3 -2
  291. package/doc/zh-CN/icon.md +5 -4
  292. package/doc/zh-CN/implemented/async.md +38 -0
  293. package/doc/zh-CN/implemented/binder.md +13 -0
  294. package/doc/zh-CN/implemented/cli.md +46 -0
  295. package/doc/zh-CN/implemented/codegen.md +33 -0
  296. package/doc/zh-CN/implemented/collections.md +26 -0
  297. package/doc/zh-CN/implemented/driver.md +19 -0
  298. package/doc/zh-CN/implemented/extensions.md +19 -0
  299. package/doc/zh-CN/implemented/fetch.md +12 -0
  300. package/doc/zh-CN/implemented/lexer.md +23 -0
  301. package/doc/zh-CN/implemented/modules.md +28 -0
  302. package/doc/zh-CN/implemented/node/assert.md +17 -0
  303. package/doc/zh-CN/implemented/node/buffer.md +25 -0
  304. package/doc/zh-CN/implemented/node/child-process.md +27 -0
  305. package/doc/zh-CN/implemented/node/crypto.md +9 -0
  306. package/doc/zh-CN/implemented/node/dgram.md +15 -0
  307. package/doc/zh-CN/implemented/node/events.md +36 -0
  308. package/doc/zh-CN/implemented/node/fs-promises.md +27 -0
  309. package/doc/zh-CN/implemented/node/fs.md +105 -0
  310. package/doc/zh-CN/implemented/node/http.md +17 -0
  311. package/doc/zh-CN/implemented/node/net.md +17 -0
  312. package/doc/zh-CN/implemented/node/os.md +21 -0
  313. package/doc/zh-CN/implemented/node/path.md +26 -0
  314. package/doc/zh-CN/implemented/node/process.md +23 -0
  315. package/doc/zh-CN/implemented/node/querystring.md +20 -0
  316. package/doc/zh-CN/implemented/node/stream-promises.md +8 -0
  317. package/doc/zh-CN/implemented/node/stream.md +15 -0
  318. package/doc/zh-CN/implemented/node/test.md +10 -0
  319. package/doc/zh-CN/implemented/node/url.md +8 -0
  320. package/doc/zh-CN/implemented/node/util.md +25 -0
  321. package/doc/zh-CN/implemented/node/worker-threads.md +9 -0
  322. package/doc/zh-CN/implemented/node/zlib.md +8 -0
  323. package/doc/zh-CN/implemented/node.md +45 -0
  324. package/doc/zh-CN/implemented/operators.md +38 -0
  325. package/doc/zh-CN/implemented/parser.md +58 -0
  326. package/doc/zh-CN/implemented/pipeline.md +25 -0
  327. package/doc/zh-CN/implemented/runtime-core.md +31 -0
  328. package/doc/zh-CN/implemented/stdlib.md +76 -0
  329. package/doc/zh-CN/implemented/strings.md +27 -0
  330. package/doc/zh-CN/implemented/tests.md +10 -0
  331. package/doc/zh-CN/implemented/typed-arrays.md +26 -0
  332. package/doc/zh-CN/implemented/value-model.md +18 -0
  333. package/doc/zh-CN/implemented.md +50 -350
  334. package/doc/zh-CN/node-implemented.md +4 -531
  335. package/doc/zh-CN/node-unimplemented.md +4 -139
  336. package/doc/zh-CN/plan-require-node-modules.md +4 -4
  337. package/doc/zh-CN/requirements.md +20 -6
  338. package/doc/zh-CN/unimplemented/classes.md +22 -0
  339. package/doc/zh-CN/unimplemented/deviations.md +24 -0
  340. package/doc/zh-CN/unimplemented/expressions.md +24 -0
  341. package/doc/zh-CN/unimplemented/functions.md +21 -0
  342. package/doc/zh-CN/unimplemented/modules.md +19 -0
  343. package/doc/zh-CN/unimplemented/node/async.md +17 -0
  344. package/doc/zh-CN/unimplemented/node/bun.md +8 -0
  345. package/doc/zh-CN/unimplemented/node/fs-promises.md +12 -0
  346. package/doc/zh-CN/unimplemented/node/fs.md +24 -0
  347. package/doc/zh-CN/unimplemented/node/globals.md +14 -0
  348. package/doc/zh-CN/unimplemented/node/modules.md +15 -0
  349. package/doc/zh-CN/unimplemented/node.md +18 -0
  350. package/doc/zh-CN/unimplemented/statements.md +15 -0
  351. package/doc/zh-CN/unimplemented/stdlib.md +54 -0
  352. package/doc/zh-CN/unimplemented/toolchain.md +14 -0
  353. package/doc/zh-CN/unimplemented/types.md +11 -0
  354. package/doc/zh-CN/unimplemented.md +14 -237
  355. package/llms.txt +32 -4
  356. package/package.json +1 -1
  357. package/runtime/ext_gui/renderer_shaders.h +2 -2
  358. package/runtime/ext_gui/stb_image.h +1 -17
  359. package/runtime/ext_node/child_process/child_process.c +173 -73
  360. package/runtime/rt.h +15 -0
  361. package/runtime/rt_internal.h +106 -0
  362. package/runtime/xt_alloc.c +43 -7
  363. package/runtime/xt_array_buffer.c +284 -0
  364. package/runtime/xt_async.c +46 -21
  365. package/runtime/xt_bigint/helpers.inc +3 -3
  366. package/runtime/xt_builtins.c +21 -17
  367. package/runtime/xt_constructors.c +12 -2
  368. package/runtime/xt_containers/access.inc +148 -3
  369. package/runtime/xt_containers/objects.inc +26 -2
  370. package/runtime/xt_containers/shapes.inc +71 -0
  371. package/runtime/xt_containers.c +1 -0
  372. package/runtime/xt_coroutine.c +17 -0
  373. package/runtime/xt_generator.c +299 -10
  374. package/runtime/xt_io/inspect.inc +112 -0
  375. package/runtime/xt_loop.c +35 -4
  376. package/runtime/xt_performance.c +37 -0
  377. package/runtime/xt_promise.c +63 -1
  378. package/runtime/xt_stdlib/arrays.inc +1 -1
  379. package/runtime/xt_stdlib/dispatch.inc +46 -11
  380. package/runtime/xt_stdlib/strings.inc +1 -1
  381. package/runtime/xt_stdlib2/array-statics.inc +25 -0
  382. package/runtime/xt_stdlib2/arrays.inc +5 -3
  383. package/runtime/xt_stdlib2/container.inc +5 -0
  384. package/runtime/xt_stdlib2/date.inc +111 -3
  385. package/runtime/xt_stdlib2/error.inc +24 -0
  386. package/runtime/xt_stdlib2/json.inc +310 -19
  387. package/runtime/xt_stdlib2/number-string-statics.inc +1 -1
  388. package/runtime/xt_stdlib2/objects.inc +122 -0
  389. package/runtime/xt_stdlib2/set.inc +1 -1
  390. package/runtime/xt_structured_clone.c +159 -0
  391. package/runtime/xt_symbol.c +2 -2
  392. package/runtime/xt_text_codec.c +69 -0
  393. package/runtime/xt_typed_array/construction.inc +35 -5
  394. package/runtime/xt_typed_array/elements.inc +159 -0
  395. package/runtime/xt_typed_array/methods.inc +21 -5
  396. package/runtime/xt_typed_array.c +7 -10
  397. package/runtime/xt_url.c +375 -0
  398. package/runtime/xt_values/arithmetic.inc +2 -2
  399. package/runtime/xt_values/conversions.inc +1 -1
  400. package/runtime/xt_weak.c +281 -0
  401. package/scripts/build-gui.ts +133 -60
  402. package/scripts/check-version.ts +3 -3
  403. package/src/binder/declarations.ts +14 -3
  404. package/src/cli/hints.ts +8 -1
  405. package/src/cli/main.ts +119 -18
  406. package/src/cli/watch.ts +101 -0
  407. package/src/codegen/generator/calls/access.ts +10 -2
  408. package/src/codegen/generator/calls/closures.ts +12 -4
  409. package/src/codegen/generator/context.ts +23 -3
  410. package/src/codegen/generator/expressions/operators.ts +27 -13
  411. package/src/codegen/generator/expressions/primary.ts +4 -0
  412. package/src/codegen/generator/module.ts +0 -7
  413. package/src/codegen/generator/numeric.ts +85 -11
  414. package/src/codegen/generator/state.ts +23 -0
  415. package/src/codegen/generator/statements/control-flow.ts +1 -4
  416. package/src/codegen/generator/statements/loops.ts +50 -16
  417. package/src/codegen/generator/tables.ts +26 -1
  418. package/src/diagnostics/diagnostic.ts +23 -3
  419. package/src/driver/app-artifacts.ts +77 -0
  420. package/src/driver/build-key.ts +55 -0
  421. package/src/driver/bundler/graph.ts +63 -13
  422. package/src/driver/bundler/merge.ts +4 -1
  423. package/src/driver/compiler.ts +93 -327
  424. package/src/driver/config.ts +11 -0
  425. package/src/driver/frontend.ts +120 -0
  426. package/src/driver/index.ts +0 -1
  427. package/src/driver/options.ts +70 -0
  428. package/src/driver/runtime-objects.ts +133 -0
  429. package/src/driver/toolchain-provider.ts +4 -0
  430. package/src/driver/toolchain.ts +154 -10
  431. package/src/driver/version.ts +12 -0
  432. package/src/driver/win-icon.ts +36 -36
  433. package/src/parser/declarations/classes.ts +4 -0
  434. package/src/parser/declarations/functions.ts +12 -1
  435. package/src/parser/modules.ts +8 -4
  436. package/src/parser/parser.ts +28 -0
@@ -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);
@@ -35,9 +35,131 @@ static xt_value xt_object_group_by(xt_value value, xt_value fn) {
35
35
  return result;
36
36
  }
37
37
 
38
+ /* -- property descriptors ------------------------------------------------- */
39
+
40
+ /* `attr` defaults for `defineProperty` are all false; literal properties are
41
+ * all true. Store the bits per key under a symbol so the flag table stays out
42
+ * of Object.keys / JSON. Writable/enumerable are reported truthfully, but the
43
+ * runtime does not enforce them on later writes or enumeration yet. */
44
+ static xt_value xt_object_descriptor_flags_key_value = XT_UNDEFINED;
45
+
46
+ static xt_value xt_object_descriptor_flags_key(void) {
47
+ if (!xt_is_symbol(xt_object_descriptor_flags_key_value)) {
48
+ xt_object_descriptor_flags_key_value =
49
+ xt_symbol_new(xt_string_from_cstr("__propertyDescriptorFlags"));
50
+ xt_gc_add_root(&xt_object_descriptor_flags_key_value);
51
+ }
52
+ return xt_object_descriptor_flags_key_value;
53
+ }
54
+
55
+ static xt_value xt_object_descriptor_flags(xt_value target) {
56
+ if (!XT_IS_OBJECT(target)) return XT_UNDEFINED;
57
+ xt_value flags = xt_object_get(target, xt_object_descriptor_flags_key());
58
+ if (!XT_IS_OBJECT(flags)) {
59
+ flags = xt_object_new();
60
+ xt_object_set(target, xt_object_descriptor_flags_key(), flags);
61
+ }
62
+ return flags;
63
+ }
64
+
65
+ static int xt_object_descriptor_mask(xt_value target, xt_value key) {
66
+ if (!XT_IS_OBJECT(target)) return 7;
67
+ xt_value flags = xt_object_get(target, xt_object_descriptor_flags_key());
68
+ if (!XT_IS_OBJECT(flags)) return 7;
69
+ xt_value mask = xt_object_get(flags, key);
70
+ return mask == XT_UNDEFINED ? 7 : xt_to_int32(mask);
71
+ }
72
+
73
+ static xt_value xt_object_data_descriptor(xt_value value, int enumerable, int configurable,
74
+ int writable) {
75
+ xt_value descriptor = xt_object_new();
76
+ xt_object_set(descriptor, xt_string_from_cstr("value"), value);
77
+ xt_object_set(descriptor, xt_string_from_cstr("writable"), xt_bool(writable));
78
+ xt_object_set(descriptor, xt_string_from_cstr("enumerable"), xt_bool(enumerable));
79
+ xt_object_set(descriptor, xt_string_from_cstr("configurable"), xt_bool(configurable));
80
+ return descriptor;
81
+ }
82
+
83
+ static xt_value xt_object_get_own_property_descriptor(xt_value target, xt_value key) {
84
+ if (XT_IS_ARRAY(target)) {
85
+ if (XT_IS_STRING(key) && xt_as_string(key)->length == 6 &&
86
+ memcmp(xt_string_bytes(xt_as_string(key)), "length", 6) == 0) {
87
+ return xt_object_data_descriptor(xt_array_length(target), 0, 0, 1);
88
+ }
89
+ xt_value item = xt_get(target, key);
90
+ if (item != XT_UNDEFINED) return xt_object_data_descriptor(item, 1, 1, 1);
91
+ return XT_UNDEFINED;
92
+ }
93
+ if (!XT_IS_OBJECT(target)) return XT_UNDEFINED;
94
+ xt_object *object = (xt_object *)XT_GET_PTR(target);
95
+ if (object->header.kind != XT_OBJECT_KIND_OBJECT && object->header.kind != XT_OBJECT_KIND_ERROR) {
96
+ return XT_UNDEFINED;
97
+ }
98
+ xt_property *property = xt_object_find_property(object, xt_to_property_key(key));
99
+ if (!property) return XT_UNDEFINED;
100
+ int mask = xt_object_descriptor_mask(target, key);
101
+ if (property->getter != XT_UNDEFINED || property->setter != XT_UNDEFINED) {
102
+ xt_value descriptor = xt_object_new();
103
+ if (property->getter != XT_UNDEFINED) {
104
+ xt_object_set(descriptor, xt_string_from_cstr("get"), property->getter);
105
+ }
106
+ if (property->setter != XT_UNDEFINED) {
107
+ xt_object_set(descriptor, xt_string_from_cstr("set"), property->setter);
108
+ }
109
+ xt_object_set(descriptor, xt_string_from_cstr("enumerable"), xt_bool((mask & 2) != 0));
110
+ xt_object_set(descriptor, xt_string_from_cstr("configurable"), xt_bool((mask & 4) != 0));
111
+ return descriptor;
112
+ }
113
+ return xt_object_data_descriptor(property->value, (mask & 2) != 0, (mask & 4) != 0,
114
+ (mask & 1) != 0);
115
+ }
116
+
117
+ static xt_value xt_object_define_property(xt_value target, xt_value key, xt_value descriptor) {
118
+ if (!XT_IS_OBJECT(descriptor)) return target;
119
+ int writable = xt_truthy(xt_object_get(descriptor, xt_string_from_cstr("writable")));
120
+ int enumerable = xt_truthy(xt_object_get(descriptor, xt_string_from_cstr("enumerable")));
121
+ int configurable = xt_truthy(xt_object_get(descriptor, xt_string_from_cstr("configurable")));
122
+ int mask = (writable ? 1 : 0) | (enumerable ? 2 : 0) | (configurable ? 4 : 0);
123
+ xt_value flags = xt_object_descriptor_flags(target);
124
+ if (XT_IS_OBJECT(flags)) xt_object_set(flags, key, xt_number((double)mask));
125
+ xt_value getter = xt_object_get(descriptor, xt_string_from_cstr("get"));
126
+ xt_value setter = xt_object_get(descriptor, xt_string_from_cstr("set"));
127
+ if (getter != XT_UNDEFINED || setter != XT_UNDEFINED) {
128
+ if (getter != XT_UNDEFINED) xt_object_define_getter(target, key, getter);
129
+ if (setter != XT_UNDEFINED) xt_object_define_setter(target, key, setter);
130
+ return target;
131
+ }
132
+ if (xt_object_has_own(descriptor, xt_string_from_cstr("value"))) {
133
+ xt_set(target, key, xt_object_get(descriptor, xt_string_from_cstr("value")));
134
+ }
135
+ return target;
136
+ }
137
+
138
+ static xt_value xt_object_get_own_property_descriptors(xt_value target) {
139
+ xt_value result = xt_object_new();
140
+ xt_value names = xt_object_own_property_names(target);
141
+ xt_array *keys = xt_as_array(names);
142
+ if (!keys) return result;
143
+ for (uint32_t i = 0; i < keys->length; i++) {
144
+ xt_value descriptor = xt_object_get_own_property_descriptor(target, keys->items[i]);
145
+ if (descriptor != XT_UNDEFINED) xt_object_set(result, keys->items[i], descriptor);
146
+ }
147
+ return result;
148
+ }
149
+
38
150
  xt_value xt_object_static(xt_value name, int32_t argc, xt_value *argv) {
39
151
  const char *fn = xt_string_data(name);
40
152
  if (!fn) return XT_UNDEFINED;
153
+ if (strcmp(fn, "getOwnPropertyDescriptor") == 0) {
154
+ return xt_object_get_own_property_descriptor(xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1));
155
+ }
156
+ if (strcmp(fn, "getOwnPropertyDescriptors") == 0) {
157
+ return xt_object_get_own_property_descriptors(xt_arg_at(argc, argv, 0));
158
+ }
159
+ if (strcmp(fn, "defineProperty") == 0) {
160
+ return xt_object_define_property(xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1),
161
+ xt_arg_at(argc, argv, 2));
162
+ }
41
163
  if (strcmp(fn, "keys") == 0) return xt_object_keys(xt_arg_at(argc, argv, 0));
42
164
  if (strcmp(fn, "getOwnPropertyNames") == 0) return xt_object_own_property_names(xt_arg_at(argc, argv, 0));
43
165
  if (strcmp(fn, "getOwnPropertySymbols") == 0) return xt_object_own_property_symbols(xt_arg_at(argc, argv, 0));
@@ -55,7 +55,7 @@ xt_value xt_iter_open(xt_value value) {
55
55
  return XT_FROM_PTR(XT_TAG_OBJECT, state);
56
56
  }
57
57
  }
58
- xt_throw(xt_string_from_cstr("TypeError: value is not iterable"));
58
+ xt_throw(xt_error_from_message("TypeError: value is not iterable"));
59
59
  return XT_UNDEFINED;
60
60
  }
61
61