xbintsc 0.3.87 → 0.5.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (458) hide show
  1. package/AGENTS.md +23 -11
  2. package/README.md +11 -9
  3. package/README.zh-CN.md +7 -7
  4. package/dist/src/binder/declarations.js +14 -3
  5. package/dist/src/binder/declarations.js.map +1 -1
  6. package/dist/src/cli/hints.js +7 -1
  7. package/dist/src/cli/hints.js.map +1 -1
  8. package/dist/src/cli/main.js +115 -15
  9. package/dist/src/cli/main.js.map +1 -1
  10. package/dist/src/cli/watch.d.ts +25 -0
  11. package/dist/src/cli/watch.js +93 -0
  12. package/dist/src/cli/watch.js.map +1 -0
  13. package/dist/src/codegen/generator/calls/access.js +17 -4
  14. package/dist/src/codegen/generator/calls/access.js.map +1 -1
  15. package/dist/src/codegen/generator/calls/closures.js +13 -1
  16. package/dist/src/codegen/generator/calls/closures.js.map +1 -1
  17. package/dist/src/codegen/generator/calls/invocation.js +4 -3
  18. package/dist/src/codegen/generator/calls/invocation.js.map +1 -1
  19. package/dist/src/codegen/generator/context.d.ts +8 -0
  20. package/dist/src/codegen/generator/context.js +22 -3
  21. package/dist/src/codegen/generator/context.js.map +1 -1
  22. package/dist/src/codegen/generator/expressions/operators.js +17 -15
  23. package/dist/src/codegen/generator/expressions/operators.js.map +1 -1
  24. package/dist/src/codegen/generator/expressions/primary.js +11 -1
  25. package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
  26. package/dist/src/codegen/generator/module.d.ts +0 -1
  27. package/dist/src/codegen/generator/module.js +10 -17
  28. package/dist/src/codegen/generator/module.js.map +1 -1
  29. package/dist/src/codegen/generator/numeric.d.ts +6 -3
  30. package/dist/src/codegen/generator/numeric.js +54 -11
  31. package/dist/src/codegen/generator/numeric.js.map +1 -1
  32. package/dist/src/codegen/generator/state.js +27 -0
  33. package/dist/src/codegen/generator/state.js.map +1 -1
  34. package/dist/src/codegen/generator/statements/control-flow.js +2 -7
  35. package/dist/src/codegen/generator/statements/control-flow.js.map +1 -1
  36. package/dist/src/codegen/generator/statements/loops.js +48 -16
  37. package/dist/src/codegen/generator/statements/loops.js.map +1 -1
  38. package/dist/src/codegen/generator/tables.d.ts +9 -0
  39. package/dist/src/codegen/generator/tables.js +100 -3
  40. package/dist/src/codegen/generator/tables.js.map +1 -1
  41. package/dist/src/diagnostics/diagnostic.d.ts +3 -1
  42. package/dist/src/diagnostics/diagnostic.js +23 -3
  43. package/dist/src/diagnostics/diagnostic.js.map +1 -1
  44. package/dist/src/driver/app-artifacts.d.ts +42 -0
  45. package/dist/src/driver/app-artifacts.js +53 -0
  46. package/dist/src/driver/app-artifacts.js.map +1 -0
  47. package/dist/src/driver/build-key.d.ts +29 -0
  48. package/dist/src/driver/build-key.js +35 -0
  49. package/dist/src/driver/build-key.js.map +1 -0
  50. package/dist/src/driver/bundler/graph.js +61 -12
  51. package/dist/src/driver/bundler/graph.js.map +1 -1
  52. package/dist/src/driver/bundler/merge.js +7 -1
  53. package/dist/src/driver/bundler/merge.js.map +1 -1
  54. package/dist/src/driver/compiler.d.ts +10 -67
  55. package/dist/src/driver/compiler.js +94 -230
  56. package/dist/src/driver/compiler.js.map +1 -1
  57. package/dist/src/driver/config.d.ts +3 -0
  58. package/dist/src/driver/config.js +8 -0
  59. package/dist/src/driver/config.js.map +1 -1
  60. package/dist/src/driver/frontend.d.ts +37 -0
  61. package/dist/src/driver/frontend.js +92 -0
  62. package/dist/src/driver/frontend.js.map +1 -0
  63. package/dist/src/driver/index.d.ts +1 -1
  64. package/dist/src/driver/index.js.map +1 -1
  65. package/dist/src/driver/options.d.ts +64 -0
  66. package/dist/src/driver/options.js +9 -0
  67. package/dist/src/driver/options.js.map +1 -0
  68. package/dist/src/driver/runtime-objects.d.ts +38 -0
  69. package/dist/src/driver/runtime-objects.js +111 -0
  70. package/dist/src/driver/runtime-objects.js.map +1 -0
  71. package/dist/src/driver/toolchain-provider.d.ts +4 -0
  72. package/dist/src/driver/toolchain-provider.js +4 -0
  73. package/dist/src/driver/toolchain-provider.js.map +1 -1
  74. package/dist/src/driver/toolchain.d.ts +32 -1
  75. package/dist/src/driver/toolchain.js +115 -11
  76. package/dist/src/driver/toolchain.js.map +1 -1
  77. package/dist/src/driver/version.d.ts +12 -0
  78. package/dist/src/driver/version.js +13 -0
  79. package/dist/src/driver/version.js.map +1 -0
  80. package/dist/src/driver/win-icon.d.ts +7 -9
  81. package/dist/src/driver/win-icon.js +37 -35
  82. package/dist/src/driver/win-icon.js.map +1 -1
  83. package/dist/src/parser/declarations/classes.js +5 -0
  84. package/dist/src/parser/declarations/classes.js.map +1 -1
  85. package/dist/src/parser/declarations/functions.js +13 -1
  86. package/dist/src/parser/declarations/functions.js.map +1 -1
  87. package/dist/src/parser/modules.js +8 -3
  88. package/dist/src/parser/modules.js.map +1 -1
  89. package/dist/src/parser/parser.d.ts +1 -0
  90. package/dist/src/parser/parser.js +23 -0
  91. package/dist/src/parser/parser.js.map +1 -1
  92. package/dist/tests/cli/check.test.d.ts +6 -0
  93. package/dist/tests/cli/check.test.js +68 -0
  94. package/dist/tests/cli/check.test.js.map +1 -0
  95. package/dist/tests/cli/main.test.js +19 -0
  96. package/dist/tests/cli/main.test.js.map +1 -1
  97. package/dist/tests/cli/watch.test.d.ts +6 -0
  98. package/dist/tests/cli/watch.test.js +72 -0
  99. package/dist/tests/cli/watch.test.js.map +1 -0
  100. package/dist/tests/codegen/closures.test.js +8 -0
  101. package/dist/tests/codegen/closures.test.js.map +1 -1
  102. package/dist/tests/codegen/expressions.test.js +15 -3
  103. package/dist/tests/codegen/expressions.test.js.map +1 -1
  104. package/dist/tests/codegen/llvm.test.js +16 -0
  105. package/dist/tests/codegen/llvm.test.js.map +1 -1
  106. package/dist/tests/diagnostics/diagnostic.test.js +8 -0
  107. package/dist/tests/diagnostics/diagnostic.test.js.map +1 -1
  108. package/dist/tests/docs/structure.test.d.ts +1 -0
  109. package/dist/tests/docs/structure.test.js +92 -0
  110. package/dist/tests/docs/structure.test.js.map +1 -0
  111. package/dist/tests/driver/compiler.test.js +6 -0
  112. package/dist/tests/driver/compiler.test.js.map +1 -1
  113. package/dist/tests/driver/config.test.js +9 -0
  114. package/dist/tests/driver/config.test.js.map +1 -1
  115. package/dist/tests/driver/icon.test.js +19 -32
  116. package/dist/tests/driver/icon.test.js.map +1 -1
  117. package/dist/tests/driver/invalid-input.test.d.ts +10 -0
  118. package/dist/tests/driver/invalid-input.test.js +29 -0
  119. package/dist/tests/driver/invalid-input.test.js.map +1 -0
  120. package/dist/tests/driver/modules.test.js +42 -3
  121. package/dist/tests/driver/modules.test.js.map +1 -1
  122. package/dist/tests/driver/toolchain-provider.test.js +27 -1
  123. package/dist/tests/driver/toolchain-provider.test.js.map +1 -1
  124. package/dist/tests/driver/toolchain.test.js +60 -2
  125. package/dist/tests/driver/toolchain.test.js.map +1 -1
  126. package/dist/tests/e2e/array-buffer.test.d.ts +5 -0
  127. package/dist/tests/e2e/array-buffer.test.js +38 -0
  128. package/dist/tests/e2e/array-buffer.test.js.map +1 -0
  129. package/dist/tests/e2e/array-from-iterables.test.d.ts +7 -0
  130. package/dist/tests/e2e/array-from-iterables.test.js +34 -0
  131. package/dist/tests/e2e/array-from-iterables.test.js.map +1 -0
  132. package/dist/tests/e2e/array-symbol-iterator.test.d.ts +8 -0
  133. package/dist/tests/e2e/array-symbol-iterator.test.js +42 -0
  134. package/dist/tests/e2e/array-symbol-iterator.test.js.map +1 -0
  135. package/dist/tests/e2e/async-await.test.d.ts +10 -0
  136. package/dist/tests/e2e/async-await.test.js +247 -0
  137. package/dist/tests/e2e/async-await.test.js.map +1 -0
  138. package/dist/tests/e2e/async-generators.test.d.ts +1 -0
  139. package/dist/tests/e2e/async-generators.test.js +154 -0
  140. package/dist/tests/e2e/async-generators.test.js.map +1 -0
  141. package/dist/tests/e2e/await-ordering.test.d.ts +5 -0
  142. package/dist/tests/e2e/await-ordering.test.js +37 -0
  143. package/dist/tests/e2e/await-ordering.test.js.map +1 -0
  144. package/dist/tests/e2e/compile-builtins.test.js +1 -1
  145. package/dist/tests/e2e/compile-modules.test.js +7 -0
  146. package/dist/tests/e2e/compile-modules.test.js.map +1 -1
  147. package/dist/tests/e2e/date-parse.test.d.ts +8 -0
  148. package/dist/tests/e2e/date-parse.test.js +38 -0
  149. package/dist/tests/e2e/date-parse.test.js.map +1 -0
  150. package/dist/tests/e2e/default-anonymous-exports.test.d.ts +7 -0
  151. package/dist/tests/e2e/default-anonymous-exports.test.js +23 -0
  152. package/dist/tests/e2e/default-anonymous-exports.test.js.map +1 -0
  153. package/dist/tests/e2e/globals-microtask.test.d.ts +9 -0
  154. package/dist/tests/e2e/globals-microtask.test.js +37 -0
  155. package/dist/tests/e2e/globals-microtask.test.js.map +1 -0
  156. package/dist/tests/e2e/gui-media.test.js +8 -1
  157. package/dist/tests/e2e/gui-media.test.js.map +1 -1
  158. package/dist/tests/e2e/inspect-builtins.test.d.ts +10 -0
  159. package/dist/tests/e2e/inspect-builtins.test.js +43 -0
  160. package/dist/tests/e2e/inspect-builtins.test.js.map +1 -0
  161. package/dist/tests/e2e/json-builtin-objects.test.d.ts +9 -0
  162. package/dist/tests/e2e/json-builtin-objects.test.js +23 -0
  163. package/dist/tests/e2e/json-builtin-objects.test.js.map +1 -0
  164. package/dist/tests/e2e/json-circular.test.d.ts +6 -0
  165. package/dist/tests/e2e/json-circular.test.js +43 -0
  166. package/dist/tests/e2e/json-circular.test.js.map +1 -0
  167. package/dist/tests/e2e/json-parse-reviver.test.d.ts +6 -0
  168. package/dist/tests/e2e/json-parse-reviver.test.js +29 -0
  169. package/dist/tests/e2e/json-parse-reviver.test.js.map +1 -0
  170. package/dist/tests/e2e/json-stringify-replacer.test.d.ts +6 -0
  171. package/dist/tests/e2e/json-stringify-replacer.test.js +27 -0
  172. package/dist/tests/e2e/json-stringify-replacer.test.js.map +1 -0
  173. package/dist/tests/e2e/json-stringify-space.test.d.ts +6 -0
  174. package/dist/tests/e2e/json-stringify-space.test.js +23 -0
  175. package/dist/tests/e2e/json-stringify-space.test.js.map +1 -0
  176. package/dist/tests/e2e/method-dispatch-errors.test.d.ts +9 -0
  177. package/dist/tests/e2e/method-dispatch-errors.test.js +38 -0
  178. package/dist/tests/e2e/method-dispatch-errors.test.js.map +1 -0
  179. package/dist/tests/e2e/native-extensions.test.js +1 -1
  180. package/dist/tests/e2e/native-extensions.test.js.map +1 -1
  181. package/dist/tests/e2e/promise-with-resolvers.test.d.ts +5 -0
  182. package/dist/tests/e2e/promise-with-resolvers.test.js +20 -0
  183. package/dist/tests/e2e/promise-with-resolvers.test.js.map +1 -0
  184. package/dist/tests/e2e/property-descriptors.test.d.ts +5 -0
  185. package/dist/tests/e2e/property-descriptors.test.js +25 -0
  186. package/dist/tests/e2e/property-descriptors.test.js.map +1 -0
  187. package/dist/tests/e2e/property-ic.test.d.ts +1 -0
  188. package/dist/tests/e2e/property-ic.test.js +55 -0
  189. package/dist/tests/e2e/property-ic.test.js.map +1 -0
  190. package/dist/tests/e2e/runtime-coverage-globals.test.js +46 -0
  191. package/dist/tests/e2e/runtime-coverage-globals.test.js.map +1 -1
  192. package/dist/tests/e2e/runtime-errors.test.d.ts +10 -0
  193. package/dist/tests/e2e/runtime-errors.test.js +52 -0
  194. package/dist/tests/e2e/runtime-errors.test.js.map +1 -0
  195. package/dist/tests/e2e/string-utf16.test.d.ts +6 -0
  196. package/dist/tests/e2e/string-utf16.test.js +133 -0
  197. package/dist/tests/e2e/string-utf16.test.js.map +1 -0
  198. package/dist/tests/e2e/structured-clone.test.d.ts +6 -0
  199. package/dist/tests/e2e/structured-clone.test.js +49 -0
  200. package/dist/tests/e2e/structured-clone.test.js.map +1 -0
  201. package/dist/tests/e2e/text-codec.test.d.ts +6 -0
  202. package/dist/tests/e2e/text-codec.test.js +24 -0
  203. package/dist/tests/e2e/text-codec.test.js.map +1 -0
  204. package/dist/tests/e2e/typed-array-views.test.d.ts +6 -0
  205. package/dist/tests/e2e/typed-array-views.test.js +39 -0
  206. package/dist/tests/e2e/typed-array-views.test.js.map +1 -0
  207. package/dist/tests/e2e/url-search-params.test.d.ts +5 -0
  208. package/dist/tests/e2e/url-search-params.test.js +30 -0
  209. package/dist/tests/e2e/url-search-params.test.js.map +1 -0
  210. package/dist/tests/e2e/weak-collections.test.d.ts +1 -0
  211. package/dist/tests/e2e/weak-collections.test.js +88 -0
  212. package/dist/tests/e2e/weak-collections.test.js.map +1 -0
  213. package/dist/tests/parser/declarations.test.js +12 -0
  214. package/dist/tests/parser/declarations.test.js.map +1 -1
  215. package/dist/tests/parser/module-syntax.test.js +9 -0
  216. package/dist/tests/parser/module-syntax.test.js.map +1 -1
  217. package/dist/tests/parser/parser.test.js +7 -0
  218. package/dist/tests/parser/parser.test.js.map +1 -1
  219. package/dist/tests/version.test.js +5 -1
  220. package/dist/tests/version.test.js.map +1 -1
  221. package/doc/ai/README.md +4 -3
  222. package/doc/ai/cli.md +41 -0
  223. package/doc/ai/contributing.md +26 -21
  224. package/doc/ai/extensions.md +12 -9
  225. package/doc/ai/language-support.md +26 -19
  226. package/doc/ai/troubleshooting.md +15 -12
  227. package/doc/ai/zh-CN/README.md +3 -2
  228. package/doc/ai/zh-CN/cli.md +35 -0
  229. package/doc/ai/zh-CN/contributing.md +19 -18
  230. package/doc/ai/zh-CN/extensions.md +10 -7
  231. package/doc/ai/zh-CN/language-support.md +26 -20
  232. package/doc/ai/zh-CN/troubleshooting.md +12 -10
  233. package/doc/gui/build.md +13 -4
  234. package/doc/gui/known-issues.md +9 -5
  235. package/doc/gui/rendering.md +3 -1
  236. package/doc/gui.md +4 -3
  237. package/doc/icon.md +5 -4
  238. package/doc/implemented/async.md +38 -0
  239. package/doc/implemented/binder.md +13 -0
  240. package/doc/implemented/cli.md +47 -0
  241. package/doc/implemented/codegen.md +33 -0
  242. package/doc/implemented/collections.md +26 -0
  243. package/doc/implemented/driver.md +19 -0
  244. package/doc/implemented/extensions.md +19 -0
  245. package/doc/implemented/fetch.md +12 -0
  246. package/doc/implemented/lexer.md +23 -0
  247. package/doc/implemented/modules.md +28 -0
  248. package/doc/implemented/node/assert.md +17 -0
  249. package/doc/implemented/node/buffer.md +29 -0
  250. package/doc/implemented/node/child-process.md +29 -0
  251. package/doc/implemented/node/crypto.md +9 -0
  252. package/doc/implemented/node/dgram.md +15 -0
  253. package/doc/implemented/node/events.md +37 -0
  254. package/doc/implemented/node/fs-promises.md +38 -0
  255. package/doc/implemented/node/fs.md +112 -0
  256. package/doc/implemented/node/http.md +21 -0
  257. package/doc/implemented/node/net.md +17 -0
  258. package/doc/implemented/node/os.md +22 -0
  259. package/doc/implemented/node/path.md +33 -0
  260. package/doc/implemented/node/process.md +23 -0
  261. package/doc/implemented/node/querystring.md +20 -0
  262. package/doc/implemented/node/stream-promises.md +8 -0
  263. package/doc/implemented/node/stream.md +19 -0
  264. package/doc/implemented/node/test.md +10 -0
  265. package/doc/implemented/node/url.md +8 -0
  266. package/doc/implemented/node/util.md +25 -0
  267. package/doc/implemented/node/worker-threads.md +10 -0
  268. package/doc/implemented/node/zlib.md +8 -0
  269. package/doc/implemented/node.md +48 -0
  270. package/doc/implemented/operators.md +38 -0
  271. package/doc/implemented/parser.md +58 -0
  272. package/doc/implemented/pipeline.md +28 -0
  273. package/doc/implemented/runtime-core.md +32 -0
  274. package/doc/implemented/stdlib.md +78 -0
  275. package/doc/implemented/strings.md +27 -0
  276. package/doc/implemented/tests.md +10 -0
  277. package/doc/implemented/typed-arrays.md +26 -0
  278. package/doc/implemented/value-model.md +18 -0
  279. package/doc/implemented.md +54 -352
  280. package/doc/node-implemented.md +3 -585
  281. package/doc/node-unimplemented.md +3 -164
  282. package/doc/requirements.md +23 -8
  283. package/doc/unimplemented/classes.md +22 -0
  284. package/doc/unimplemented/deviations.md +27 -0
  285. package/doc/unimplemented/expressions.md +26 -0
  286. package/doc/unimplemented/functions.md +21 -0
  287. package/doc/unimplemented/modules.md +22 -0
  288. package/doc/unimplemented/node/async.md +17 -0
  289. package/doc/unimplemented/node/bun.md +9 -0
  290. package/doc/unimplemented/node/fs-promises.md +16 -0
  291. package/doc/unimplemented/node/fs.md +31 -0
  292. package/doc/unimplemented/node/globals.md +23 -0
  293. package/doc/unimplemented/node/modules.md +21 -0
  294. package/doc/unimplemented/node.md +21 -0
  295. package/doc/unimplemented/statements.md +18 -0
  296. package/doc/unimplemented/stdlib.md +54 -0
  297. package/doc/unimplemented/toolchain.md +14 -0
  298. package/doc/unimplemented/types.md +12 -0
  299. package/doc/unimplemented.md +18 -274
  300. package/doc/xbintsc.config.schema.json +12 -0
  301. package/doc/zh-CN/gui/build.md +11 -3
  302. package/doc/zh-CN/gui/known-issues.md +9 -4
  303. package/doc/zh-CN/gui/rendering.md +2 -1
  304. package/doc/zh-CN/gui.md +3 -2
  305. package/doc/zh-CN/icon.md +5 -4
  306. package/doc/zh-CN/implemented/async.md +38 -0
  307. package/doc/zh-CN/implemented/binder.md +13 -0
  308. package/doc/zh-CN/implemented/cli.md +46 -0
  309. package/doc/zh-CN/implemented/codegen.md +33 -0
  310. package/doc/zh-CN/implemented/collections.md +26 -0
  311. package/doc/zh-CN/implemented/driver.md +19 -0
  312. package/doc/zh-CN/implemented/extensions.md +19 -0
  313. package/doc/zh-CN/implemented/fetch.md +12 -0
  314. package/doc/zh-CN/implemented/lexer.md +23 -0
  315. package/doc/zh-CN/implemented/modules.md +28 -0
  316. package/doc/zh-CN/implemented/node/assert.md +17 -0
  317. package/doc/zh-CN/implemented/node/buffer.md +25 -0
  318. package/doc/zh-CN/implemented/node/child-process.md +27 -0
  319. package/doc/zh-CN/implemented/node/crypto.md +9 -0
  320. package/doc/zh-CN/implemented/node/dgram.md +15 -0
  321. package/doc/zh-CN/implemented/node/events.md +36 -0
  322. package/doc/zh-CN/implemented/node/fs-promises.md +27 -0
  323. package/doc/zh-CN/implemented/node/fs.md +105 -0
  324. package/doc/zh-CN/implemented/node/http.md +17 -0
  325. package/doc/zh-CN/implemented/node/net.md +17 -0
  326. package/doc/zh-CN/implemented/node/os.md +21 -0
  327. package/doc/zh-CN/implemented/node/path.md +26 -0
  328. package/doc/zh-CN/implemented/node/process.md +23 -0
  329. package/doc/zh-CN/implemented/node/querystring.md +20 -0
  330. package/doc/zh-CN/implemented/node/stream-promises.md +8 -0
  331. package/doc/zh-CN/implemented/node/stream.md +15 -0
  332. package/doc/zh-CN/implemented/node/test.md +10 -0
  333. package/doc/zh-CN/implemented/node/url.md +8 -0
  334. package/doc/zh-CN/implemented/node/util.md +25 -0
  335. package/doc/zh-CN/implemented/node/worker-threads.md +9 -0
  336. package/doc/zh-CN/implemented/node/zlib.md +8 -0
  337. package/doc/zh-CN/implemented/node.md +45 -0
  338. package/doc/zh-CN/implemented/operators.md +38 -0
  339. package/doc/zh-CN/implemented/parser.md +58 -0
  340. package/doc/zh-CN/implemented/pipeline.md +25 -0
  341. package/doc/zh-CN/implemented/runtime-core.md +31 -0
  342. package/doc/zh-CN/implemented/stdlib.md +76 -0
  343. package/doc/zh-CN/implemented/strings.md +27 -0
  344. package/doc/zh-CN/implemented/tests.md +10 -0
  345. package/doc/zh-CN/implemented/typed-arrays.md +26 -0
  346. package/doc/zh-CN/implemented/value-model.md +18 -0
  347. package/doc/zh-CN/implemented.md +50 -347
  348. package/doc/zh-CN/node-implemented.md +4 -531
  349. package/doc/zh-CN/node-unimplemented.md +4 -139
  350. package/doc/zh-CN/plan-require-node-modules.md +4 -4
  351. package/doc/zh-CN/requirements.md +20 -6
  352. package/doc/zh-CN/unimplemented/classes.md +22 -0
  353. package/doc/zh-CN/unimplemented/deviations.md +24 -0
  354. package/doc/zh-CN/unimplemented/expressions.md +24 -0
  355. package/doc/zh-CN/unimplemented/functions.md +21 -0
  356. package/doc/zh-CN/unimplemented/modules.md +19 -0
  357. package/doc/zh-CN/unimplemented/node/async.md +17 -0
  358. package/doc/zh-CN/unimplemented/node/bun.md +8 -0
  359. package/doc/zh-CN/unimplemented/node/fs-promises.md +12 -0
  360. package/doc/zh-CN/unimplemented/node/fs.md +24 -0
  361. package/doc/zh-CN/unimplemented/node/globals.md +14 -0
  362. package/doc/zh-CN/unimplemented/node/modules.md +15 -0
  363. package/doc/zh-CN/unimplemented/node.md +18 -0
  364. package/doc/zh-CN/unimplemented/statements.md +15 -0
  365. package/doc/zh-CN/unimplemented/stdlib.md +54 -0
  366. package/doc/zh-CN/unimplemented/toolchain.md +14 -0
  367. package/doc/zh-CN/unimplemented/types.md +11 -0
  368. package/doc/zh-CN/unimplemented.md +14 -236
  369. package/llms.txt +32 -4
  370. package/package.json +1 -1
  371. package/runtime/ext_gui/renderer_shaders.h +2 -2
  372. package/runtime/ext_gui/stb_image.h +1 -17
  373. package/runtime/ext_node/child_process/child_process.c +173 -73
  374. package/runtime/rt.h +47 -0
  375. package/runtime/rt_internal.h +205 -10
  376. package/runtime/xt_alloc.c +49 -7
  377. package/runtime/xt_array_buffer.c +284 -0
  378. package/runtime/xt_async.c +222 -0
  379. package/runtime/xt_bigint/helpers.inc +3 -3
  380. package/runtime/xt_builtins.c +59 -51
  381. package/runtime/xt_constructors.c +399 -0
  382. package/runtime/xt_containers/access.inc +195 -14
  383. package/runtime/xt_containers/arrays.inc +26 -2
  384. package/runtime/xt_containers/objects.inc +226 -5
  385. package/runtime/xt_containers/shapes.inc +71 -0
  386. package/runtime/xt_containers.c +1 -0
  387. package/runtime/xt_coroutine.c +229 -0
  388. package/runtime/xt_generator.c +325 -167
  389. package/runtime/xt_io/inspect.inc +147 -2
  390. package/runtime/xt_loop.c +35 -4
  391. package/runtime/xt_performance.c +37 -0
  392. package/runtime/xt_promise.c +125 -18
  393. package/runtime/xt_stdlib/arrays.inc +1 -1
  394. package/runtime/xt_stdlib/dispatch.inc +64 -13
  395. package/runtime/xt_stdlib/strings.inc +74 -17
  396. package/runtime/xt_stdlib2/array-statics.inc +28 -3
  397. package/runtime/xt_stdlib2/arrays.inc +5 -3
  398. package/runtime/xt_stdlib2/container.inc +5 -0
  399. package/runtime/xt_stdlib2/date.inc +111 -3
  400. package/runtime/xt_stdlib2/error.inc +35 -0
  401. package/runtime/xt_stdlib2/json.inc +353 -33
  402. package/runtime/xt_stdlib2/number-string-statics.inc +24 -15
  403. package/runtime/xt_stdlib2/objects.inc +123 -1
  404. package/runtime/xt_stdlib2/regexp-match.inc +2 -2
  405. package/runtime/xt_stdlib2/set.inc +7 -1
  406. package/runtime/xt_stdlib2/strings.inc +70 -40
  407. package/runtime/xt_structured_clone.c +159 -0
  408. package/runtime/xt_symbol.c +2 -2
  409. package/runtime/xt_text_codec.c +69 -0
  410. package/runtime/xt_typed_array/construction.inc +78 -7
  411. package/runtime/xt_typed_array/elements.inc +159 -0
  412. package/runtime/xt_typed_array/methods.inc +21 -5
  413. package/runtime/xt_typed_array.c +11 -10
  414. package/runtime/xt_url.c +375 -0
  415. package/runtime/xt_values/arithmetic.inc +2 -2
  416. package/runtime/xt_values/constructors.inc +8 -0
  417. package/runtime/xt_values/conversions.inc +1 -1
  418. package/runtime/xt_values/strings.inc +19 -3
  419. package/runtime/xt_values/utf16.inc +340 -0
  420. package/runtime/xt_values.c +1 -0
  421. package/runtime/xt_weak.c +281 -0
  422. package/scripts/build-gui.ts +133 -60
  423. package/scripts/check-version.ts +3 -3
  424. package/src/binder/declarations.ts +14 -3
  425. package/src/cli/hints.ts +8 -1
  426. package/src/cli/main.ts +119 -18
  427. package/src/cli/watch.ts +101 -0
  428. package/src/codegen/generator/calls/access.ts +17 -4
  429. package/src/codegen/generator/calls/closures.ts +12 -1
  430. package/src/codegen/generator/calls/invocation.ts +4 -3
  431. package/src/codegen/generator/context.ts +23 -3
  432. package/src/codegen/generator/expressions/operators.ts +27 -13
  433. package/src/codegen/generator/expressions/primary.ts +10 -1
  434. package/src/codegen/generator/module.ts +10 -19
  435. package/src/codegen/generator/numeric.ts +85 -11
  436. package/src/codegen/generator/state.ts +27 -0
  437. package/src/codegen/generator/statements/control-flow.ts +2 -6
  438. package/src/codegen/generator/statements/loops.ts +50 -16
  439. package/src/codegen/generator/tables.ts +110 -3
  440. package/src/diagnostics/diagnostic.ts +23 -3
  441. package/src/driver/app-artifacts.ts +77 -0
  442. package/src/driver/build-key.ts +55 -0
  443. package/src/driver/bundler/graph.ts +63 -13
  444. package/src/driver/bundler/merge.ts +4 -1
  445. package/src/driver/compiler.ts +93 -324
  446. package/src/driver/config.ts +11 -0
  447. package/src/driver/frontend.ts +120 -0
  448. package/src/driver/index.ts +0 -1
  449. package/src/driver/options.ts +70 -0
  450. package/src/driver/runtime-objects.ts +133 -0
  451. package/src/driver/toolchain-provider.ts +4 -0
  452. package/src/driver/toolchain.ts +154 -10
  453. package/src/driver/version.ts +12 -0
  454. package/src/driver/win-icon.ts +36 -36
  455. package/src/parser/declarations/classes.ts +4 -0
  456. package/src/parser/declarations/functions.ts +12 -1
  457. package/src/parser/modules.ts +8 -4
  458. package/src/parser/parser.ts +28 -0
@@ -2,6 +2,20 @@
2
2
  /* Generic member access */
3
3
  /* ------------------------------------------------------------------------- */
4
4
 
5
+ /* Inherited lookup for values whose representation is not an `xt_object`
6
+ * property table (Map/Set/Date/RegExp/Promise/Symbol). `__proto__` returns the
7
+ * prototype itself instead of invoking Object.prototype's getter with the
8
+ * wrong receiver. */
9
+ static xt_value xt_get_inherited(xt_value target, xt_value key) {
10
+ xt_value proto = xt_object_get_prototype(target);
11
+ if (proto == XT_UNDEFINED || proto == XT_NULL || proto == target) return XT_UNDEFINED;
12
+ if (XT_IS_STRING(key)) {
13
+ xt_string *k = xt_as_string(key);
14
+ if (k->length == 9 && memcmp(xt_string_bytes(k), "__proto__", 9) == 0) return proto;
15
+ }
16
+ return xt_get(proto, key);
17
+ }
18
+
5
19
  /*
6
20
  * Reading a property of `null` / `undefined` is a TypeError in JavaScript.
7
21
  * Short-circuiting `?.` guards forbid reaching this point for a nullish
@@ -18,7 +32,77 @@ static void xt_throw_read_of_nullish(xt_value target, xt_value key) {
18
32
  char message[256];
19
33
  snprintf(message, sizeof(message),
20
34
  "TypeError: Cannot read properties of %s (reading '%s')", base, keybuf);
21
- xt_throw(xt_string_from_cstr(message));
35
+ xt_throw(xt_error_from_message(message));
36
+ }
37
+
38
+ /* -- Array.prototype[Symbol.iterator] -------------------------------------- */
39
+ /*
40
+ * `for...of` and spread use the internal index protocol, but libraries also
41
+ * call the iterator method explicitly (`arr[Symbol.iterator]()`, `Array.from`,
42
+ * manual `.next()`). Build a small iterator object per call: `next` closes over
43
+ * the array and a one-element box holding the current index, and the iterator
44
+ * is itself iterable so it can be passed back to `for...of` / spread.
45
+ */
46
+ static xt_value xt_array_iterator_next(xt_value thisValue, xt_value env, int32_t argc,
47
+ xt_value *argv) {
48
+ (void)thisValue;
49
+ (void)argc;
50
+ (void)argv;
51
+ xt_value array = xt_closure_env(env, 0);
52
+ xt_value indexBox = xt_closure_env(env, 1);
53
+ int32_t index = xt_to_int32(xt_get(indexBox, xt_number(0)));
54
+ xt_array *items = xt_as_array(array);
55
+ xt_value result = xt_object_new();
56
+ if (!items || index < 0 || (uint32_t)index >= items->length) {
57
+ xt_object_set(result, xt_string_from_cstr("value"), XT_UNDEFINED);
58
+ xt_object_set(result, xt_string_from_cstr("done"), XT_TRUE);
59
+ return result;
60
+ }
61
+ xt_object_set(result, xt_string_from_cstr("value"), items->items[index]);
62
+ xt_object_set(result, xt_string_from_cstr("done"), XT_FALSE);
63
+ xt_set(indexBox, xt_number(0), xt_number(index + 1));
64
+ return result;
65
+ }
66
+
67
+ static xt_value xt_iterator_return_this(xt_value thisValue, xt_value env, int32_t argc,
68
+ xt_value *argv) {
69
+ (void)env;
70
+ (void)argc;
71
+ (void)argv;
72
+ return thisValue;
73
+ }
74
+
75
+ static xt_value xt_array_iterator(xt_value thisValue, xt_value env, int32_t argc,
76
+ xt_value *argv) {
77
+ (void)env;
78
+ (void)argc;
79
+ (void)argv;
80
+ if (!XT_IS_ARRAY(thisValue)) {
81
+ xt_value message =
82
+ xt_string_from_cstr("Array.prototype[Symbol.iterator] called on a non-array");
83
+ xt_throw(xt_type_error_ctor(1, &message));
84
+ }
85
+ xt_value indexBox = xt_array_new(0, NULL);
86
+ xt_array_push(indexBox, xt_number(0));
87
+ xt_value captured[2] = {thisValue, indexBox};
88
+ xt_value iterator = xt_object_new();
89
+ xt_object_set(iterator, xt_string_from_cstr("next"),
90
+ xt_closure_new((void *)xt_array_iterator_next, 2, captured));
91
+ xt_object_set(iterator, xt_symbol_well_known("iterator"),
92
+ xt_closure_new((void *)xt_iterator_return_this, 0, NULL));
93
+ return iterator;
94
+ }
95
+
96
+ /* The method value is stable (`arr[Symbol.iterator] === arr[Symbol.iterator]`),
97
+ * so cache it and root the cache for the collector. */
98
+ static xt_value xt_array_iterator_method_value = XT_UNDEFINED;
99
+
100
+ static xt_value xt_array_iterator_method(void) {
101
+ if (!XT_IS_FUNCTION(xt_array_iterator_method_value)) {
102
+ xt_array_iterator_method_value = xt_closure_new((void *)xt_array_iterator, 0, NULL);
103
+ xt_gc_add_root(&xt_array_iterator_method_value);
104
+ }
105
+ return xt_array_iterator_method_value;
22
106
  }
23
107
 
24
108
  xt_value xt_get(xt_value target, xt_value key) {
@@ -37,8 +121,16 @@ xt_value xt_get(xt_value target, xt_value key) {
37
121
  xt_value value = xt_object_get(extra, key);
38
122
  if (value != XT_UNDEFINED) return value;
39
123
  }
40
- /* Fall back to first-class built-in methods (`arr.map`). */
41
- return xt_method_value(target, key);
124
+ /* Fall back to first-class built-in methods (`arr.map`) and then to
125
+ * the array's [[Prototype]] (`arr.hasOwnProperty`). */
126
+ xt_value method = xt_method_value(target, key);
127
+ if (method != XT_UNDEFINED) return method;
128
+ xt_value proto = ((xt_array *)XT_GET_PTR(target))->prototype;
129
+ if (proto != XT_UNDEFINED && proto != XT_NULL) {
130
+ if (k->length == 9 && memcmp(xt_string_bytes(k), "__proto__", 9) == 0) return proto;
131
+ return xt_get(proto, key);
132
+ }
133
+ return XT_UNDEFINED;
42
134
  }
43
135
  return xt_array_get(target, key);
44
136
  }
@@ -49,7 +141,14 @@ xt_value xt_get(xt_value target, xt_value key) {
49
141
  xt_value value = xt_object_get(extra, key);
50
142
  if (value != XT_UNDEFINED) return value;
51
143
  }
52
- return xt_method_value(target, key);
144
+ /* Array.prototype[Symbol.iterator] is the fallback, after any own
145
+ * symbol property the program assigned. */
146
+ if (key == xt_symbol_well_known("iterator")) return xt_array_iterator_method();
147
+ xt_value method = xt_method_value(target, key);
148
+ if (method != XT_UNDEFINED) return method;
149
+ xt_value proto = ((xt_array *)XT_GET_PTR(target))->prototype;
150
+ if (proto != XT_UNDEFINED && proto != XT_NULL) return xt_get(proto, key);
151
+ return XT_UNDEFINED;
53
152
  }
54
153
  return xt_array_get(target, key);
55
154
  }
@@ -69,6 +168,9 @@ xt_value xt_get(xt_value target, xt_value key) {
69
168
  {
70
169
  xt_value value = xt_object_get(target, key);
71
170
  if (value != XT_UNDEFINED) return value;
171
+ /* `const A = Array; A.isArray`, `const S = Symbol; S.iterator`, ... */
172
+ value = xt_builtin_static_value(target, key);
173
+ if (value != XT_UNDEFINED) return value;
72
174
  return xt_method_value(target, key);
73
175
  }
74
176
  }
@@ -76,6 +178,17 @@ xt_value xt_get(xt_value target, xt_value key) {
76
178
  /* Map/Set expose `.size`; promises, dates and regexps have their own
77
179
  * getters implemented in the standard library. */
78
180
  xt_object *obj = (xt_object *)XT_GET_PTR(target);
181
+ if (obj->header.kind == XT_OBJECT_KIND_GENERATOR && xt_is_symbol(key)) {
182
+ /* Generators are iterable objects: `Symbol.iterator` returns the
183
+ * generator itself, and an async generator also exposes
184
+ * `Symbol.asyncIterator`. */
185
+ if (key == xt_symbol_well_known("asyncIterator") && xt_is_async_generator(target)) {
186
+ return xt_async_iterator_method();
187
+ }
188
+ if (key == xt_symbol_well_known("iterator") && !xt_is_async_generator(target)) {
189
+ return xt_async_iterator_method();
190
+ }
191
+ }
79
192
  if (obj->header.kind == XT_OBJECT_KIND_SYMBOL) {
80
193
  if (XT_IS_STRING(key)) {
81
194
  xt_string *k = xt_as_string(key);
@@ -83,7 +196,9 @@ xt_value xt_get(xt_value target, xt_value key) {
83
196
  return xt_symbol_description(target);
84
197
  }
85
198
  }
86
- return xt_method_value(target, key);
199
+ xt_value method = xt_method_value(target, key);
200
+ if (method != XT_UNDEFINED) return method;
201
+ return xt_get_inherited(target, key);
87
202
  }
88
203
  if (obj->header.kind == XT_OBJECT_KIND_MAP || obj->header.kind == XT_OBJECT_KIND_SET) {
89
204
  if (XT_IS_STRING(key)) {
@@ -107,27 +222,51 @@ xt_value xt_get(xt_value target, xt_value key) {
107
222
  }
108
223
  }
109
224
  {
225
+ /* Typed arrays keep their elements in a shared ArrayBuffer: serve
226
+ * `.buffer` / element reads from it instead of the property bag. */
227
+ int typed = xt_typed_array_kind_of(target);
228
+ if (typed >= 0) {
229
+ if (XT_IS_STRING(key)) {
230
+ xt_string *k = xt_as_string(key);
231
+ if (k->length == 6 && memcmp(xt_string_bytes(k), "buffer", 6) == 0) {
232
+ return xt_typed_array_buffer_of(target);
233
+ }
234
+ if (k->length == 10 && memcmp(xt_string_bytes(k), "byteOffset", 10) == 0) {
235
+ return xt_number((double)xt_typed_array_byte_offset_of(target));
236
+ }
237
+ uint32_t index = 0;
238
+ if (xt_key_is_array_index(k, &index)) return xt_typed_array_read(target, index);
239
+ } else if (XT_IS_NUMBER(key)) {
240
+ int32_t index = xt_to_int32(key);
241
+ if (index >= 0) return xt_typed_array_read(target, (uint32_t)index);
242
+ }
243
+ }
110
244
  xt_value value = xt_object_get(target, key);
111
245
  if (value != XT_UNDEFINED) return value;
112
- return xt_method_value(target, key);
246
+ xt_value method = xt_method_value(target, key);
247
+ if (method != XT_UNDEFINED) return method;
248
+ if (obj->header.kind != XT_OBJECT_KIND_OBJECT && obj->header.kind != XT_OBJECT_KIND_ERROR) {
249
+ return xt_get_inherited(target, key);
250
+ }
251
+ return XT_UNDEFINED;
113
252
  }
114
253
  }
115
254
  if (XT_IS_STRING(target)) {
116
255
  /* Property access on a string: `.length`, numeric indexing and built-in
117
- * methods. */
256
+ * methods. Indices are UTF-16 code units, so `s[0]` of a Chinese string is
257
+ * the whole character and an emoji index into its surrogate pair. */
118
258
  xt_string *s = xt_as_string(target);
259
+ uint32_t units = xt_string_utf16_length(s);
119
260
  if (XT_IS_STRING(key)) {
120
261
  xt_string *k = xt_as_string(key);
121
- if (k->length == 6 && memcmp(xt_string_bytes(k), "length", 6) == 0) return xt_number((double)s->length);
262
+ if (k->length == 6 && memcmp(xt_string_bytes(k), "length", 6) == 0) return xt_number((double)units);
122
263
  uint32_t index = 0;
123
- if (xt_key_is_array_index(k, &index) && index < s->length) {
124
- return xt_string_new(xt_string_bytes(s) + index, 1);
125
- }
264
+ if (xt_key_is_array_index(k, &index) && index < units) return xt_string_unit_value(s, (int32_t)index);
126
265
  return xt_method_value(target, key);
127
266
  }
128
267
  if (XT_IS_NUMBER(key)) {
129
268
  int32_t index = xt_to_int32(key);
130
- if (index >= 0 && (uint32_t)index < s->length) return xt_string_new(xt_string_bytes(s) + index, 1);
269
+ if (index >= 0 && (uint32_t)index < units) return xt_string_unit_value(s, index);
131
270
  }
132
271
  return XT_UNDEFINED;
133
272
  }
@@ -138,6 +277,47 @@ xt_value xt_get(xt_value target, xt_value key) {
138
277
  return XT_UNDEFINED;
139
278
  }
140
279
 
280
+ /* Inline-cached property read. The generated code gives every source-level
281
+ * property access two zeroed i64 words; the first stores the receiver's shape
282
+ * and the second the property index. A shape hit is a pointer compare plus one
283
+ * key check, which avoids the linear property scan. Only ordinary objects and
284
+ * errors use the cache; arrays, functions, strings and containers fall back to
285
+ * the generic path. */
286
+ xt_value xt_get_ic(xt_value target, xt_value key, int64_t *cache) {
287
+ if (!cache || !XT_IS_OBJECT(target)) return xt_get(target, key);
288
+ xt_object *obj = (xt_object *)XT_GET_PTR(target);
289
+ if (obj->header.kind != XT_OBJECT_KIND_OBJECT && obj->header.kind != XT_OBJECT_KIND_ERROR) {
290
+ return xt_get(target, key);
291
+ }
292
+ if (!XT_IS_STRING(key) && !xt_is_symbol(key)) return xt_get(target, key);
293
+ xt_shape *shape = obj->shape;
294
+ uintptr_t cachedShape = (uintptr_t)cache[0];
295
+ int64_t cachedIndex = cache[1];
296
+ if (shape && cachedShape == (uintptr_t)shape && cachedIndex >= 0 &&
297
+ cachedIndex < (int64_t)obj->count) {
298
+ xt_property *prop = &obj->properties[cachedIndex];
299
+ if (prop->key == key || xt_property_key_equals(prop->key, key)) {
300
+ if (prop->getter != XT_UNDEFINED && XT_IS_FUNCTION(prop->getter)) {
301
+ return xt_call_with_this(prop->getter, target, 0, NULL);
302
+ }
303
+ if (prop->getter != XT_UNDEFINED) return XT_UNDEFINED;
304
+ return prop->value;
305
+ }
306
+ }
307
+ xt_value propertyKey = xt_to_property_key(key);
308
+ xt_property *prop = xt_object_find_property(obj, propertyKey);
309
+ if (prop) {
310
+ cache[0] = (int64_t)(uintptr_t)shape;
311
+ cache[1] = (int64_t)(prop - obj->properties);
312
+ if (prop->getter != XT_UNDEFINED && XT_IS_FUNCTION(prop->getter)) {
313
+ return xt_call_with_this(prop->getter, target, 0, NULL);
314
+ }
315
+ if (prop->getter != XT_UNDEFINED) return XT_UNDEFINED;
316
+ return prop->value;
317
+ }
318
+ return xt_get(target, key);
319
+ }
320
+
141
321
  xt_value xt_set(xt_value target, xt_value key, xt_value value) {
142
322
  if (XT_IS_ARRAY(target)) {
143
323
  /* Assigning `arr.length` truncates or extends the array. */
@@ -173,7 +353,7 @@ xt_value xt_set(xt_value target, xt_value key, xt_value value) {
173
353
  if ((k->length == 6 && memcmp(xt_string_bytes(k), "length", 6) == 0) ||
174
354
  (k->length == 10 && memcmp(xt_string_bytes(k), "byteLength", 10) == 0) ||
175
355
  (k->length == 10 && memcmp(xt_string_bytes(k), "byteOffset", 10) == 0)) {
176
- xt_throw(xt_string_from_cstr("TypeError: Cannot assign to read only property"));
356
+ xt_throw(xt_error_from_message("TypeError: Cannot assign to read only property"));
177
357
  return value;
178
358
  }
179
359
  }
@@ -191,7 +371,8 @@ xt_value xt_set(xt_value target, xt_value key, xt_value value) {
191
371
  if (isIndex) {
192
372
  double length = xt_to_number(xt_object_get_cstr(target, "length"));
193
373
  if (index >= (uint32_t)length) return value; /* out-of-bounds writes are ignored */
194
- return xt_object_set(target, key, xt_number(xt_typed_array_coerce(typed, xt_to_number(value))));
374
+ xt_typed_array_write(target, index, value);
375
+ return value;
195
376
  }
196
377
  }
197
378
  return xt_object_set(target, key, value);
@@ -15,12 +15,20 @@ void xt_array_reserve(xt_array *array, uint32_t needed) {
15
15
  array->capacity = capacity;
16
16
  }
17
17
 
18
- xt_value xt_array_new(int32_t count, xt_value *items) {
18
+ /* Array.prototype: every ordinary array inherits from it. The prototype itself
19
+ * is an array, like ECMAScript, so `Array.isArray(Array.prototype)` holds. It
20
+ * is created with the ordinary object prototype as its own [[Prototype]], which
21
+ * terminates the array-specific link. */
22
+ static xt_value xt_array_proto_root = XT_UNDEFINED;
23
+ static int xt_array_proto_ready = 0;
24
+
25
+ static xt_value xt_array_new_with_proto(int32_t count, xt_value *items, xt_value proto) {
19
26
  xt_array *array = (xt_array *)xt_alloc(sizeof(xt_array), XT_OBJECT_KIND_ARRAY);
20
27
  array->length = 0;
21
28
  array->capacity = 0;
22
29
  array->items = NULL;
23
30
  array->extra = XT_UNDEFINED;
31
+ array->prototype = proto;
24
32
  if (count > 0) {
25
33
  xt_array_reserve(array, (uint32_t)count);
26
34
  for (int32_t i = 0; i < count; i++) array->items[i] = items[i];
@@ -29,6 +37,22 @@ xt_value xt_array_new(int32_t count, xt_value *items) {
29
37
  return XT_FROM_PTR(XT_TAG_ARRAY, array);
30
38
  }
31
39
 
40
+ xt_value xt_array_prototype(void) {
41
+ if (xt_array_proto_ready) return xt_array_proto_root;
42
+ xt_array_proto_ready = 1;
43
+ xt_array_proto_root = xt_array_new_with_proto(0, NULL, xt_object_prototype());
44
+ xt_gc_add_root(&xt_array_proto_root);
45
+ xt_value constructor = xt_builtin_constructor(xt_string_from_cstr("Array"));
46
+ if (constructor != XT_UNDEFINED) {
47
+ xt_set(xt_array_proto_root, xt_string_from_cstr("constructor"), constructor);
48
+ }
49
+ return xt_array_proto_root;
50
+ }
51
+
52
+ xt_value xt_array_new(int32_t count, xt_value *items) {
53
+ return xt_array_new_with_proto(count, items, xt_array_prototype());
54
+ }
55
+
32
56
  /* Named properties of an array live in a lazily-created side object. Returns
33
57
  * XT_UNDEFINED when `create` is false and no such object exists yet. */
34
58
  static xt_value xt_array_extra(xt_array *array, int create) {
@@ -69,7 +93,7 @@ xt_value xt_array_push(xt_value value, xt_value newValue) {
69
93
 
70
94
  xt_value xt_array_length(xt_value value) {
71
95
  if (XT_IS_ARRAY(value)) return xt_number((double)((xt_array *)XT_GET_PTR(value))->length);
72
- if (XT_IS_STRING(value)) return xt_number((double)xt_string_length(xt_as_string(value)));
96
+ if (XT_IS_STRING(value)) return xt_number((double)xt_string_utf16_length(xt_as_string(value)));
73
97
  /* Functions expose their arity as `.length`. */
74
98
  if (XT_IS_FUNCTION(value)) {
75
99
  int32_t arity = ((xt_function *)XT_GET_PTR(value))->arity;
@@ -14,13 +14,159 @@ static void xt_object_reserve(xt_object *obj, uint32_t needed) {
14
14
  obj->capacity = capacity;
15
15
  }
16
16
 
17
- xt_value xt_object_new(void) { return xt_object_new_with_proto(XT_UNDEFINED); }
17
+ xt_value xt_object_new(void) { return xt_object_new_with_proto(xt_object_prototype()); }
18
+
19
+ /* ------------------------------------------------------------------------- */
20
+ /* Object.prototype */
21
+ /* ------------------------------------------------------------------------- */
22
+
23
+ /* `Object.prototype` is the root of the ordinary object prototype chain. Every
24
+ * plain object created by `xt_object_new` inherits from it, which is what makes
25
+ *
26
+ * Object.getPrototypeOf({}) === Object.prototype
27
+ * Object.prototype.hasOwnProperty.call(obj, key)
28
+ *
29
+ * hold. It is created lazily (and exactly once) with a null prototype, so the
30
+ * root itself terminates the chain. */
31
+ static xt_value xt_object_proto_root = XT_UNDEFINED;
32
+ static int xt_object_proto_ready = 0;
33
+ static xt_value xt_function_proto_root = XT_UNDEFINED;
34
+ static int xt_function_proto_ready = 0;
35
+
36
+ static const char *xt_object_tag_of(xt_value value) {
37
+ if (value == XT_UNDEFINED) return "Undefined";
38
+ if (value == XT_NULL) return "Null";
39
+ if (XT_IS_ARRAY(value)) return "Array";
40
+ if (XT_IS_FUNCTION(value)) return "Function";
41
+ if (XT_IS_STRING(value)) return "String";
42
+ if (XT_IS_BIGINT(value)) return "BigInt";
43
+ if (XT_IS_NUMBER(value)) return "Number";
44
+ if (value == XT_TRUE || value == XT_FALSE) return "Boolean";
45
+ if (XT_IS_OBJECT(value)) {
46
+ switch (((xt_object *)XT_GET_PTR(value))->header.kind) {
47
+ case XT_OBJECT_KIND_ERROR: return "Error";
48
+ case XT_OBJECT_KIND_MAP: return "Map";
49
+ case XT_OBJECT_KIND_SET: return "Set";
50
+ case XT_OBJECT_KIND_WEAK_MAP: return "WeakMap";
51
+ case XT_OBJECT_KIND_WEAK_SET: return "WeakSet";
52
+ case XT_OBJECT_KIND_WEAK_REF: return "WeakRef";
53
+ case XT_OBJECT_KIND_DATE: return "Date";
54
+ case XT_OBJECT_KIND_REGEXP: return "RegExp";
55
+ case XT_OBJECT_KIND_PROMISE: return "Promise";
56
+ case XT_OBJECT_KIND_SYMBOL: return "Symbol";
57
+ case XT_OBJECT_KIND_GENERATOR: return "Generator";
58
+ default: return "Object";
59
+ }
60
+ }
61
+ return "Object";
62
+ }
63
+
64
+ /* Backing trampoline for the methods on `Object.prototype`. The method name
65
+ * travels in environment slot 0; `this` is the receiver, exactly like a
66
+ * JavaScript method. */
67
+ static xt_value xt_object_proto_method(xt_value thisValue, xt_value env, int32_t argc,
68
+ xt_value *argv) {
69
+ xt_value nameValue = xt_closure_env(env, 0);
70
+ const char *name = xt_string_data(nameValue);
71
+ if (!name) return XT_UNDEFINED;
72
+ if (strcmp(name, "hasOwnProperty") == 0) {
73
+ if (thisValue == XT_UNDEFINED || thisValue == XT_NULL) {
74
+ xt_throw(xt_error_from_message("TypeError: Cannot convert undefined or null to object"));
75
+ }
76
+ return xt_object_has_own(thisValue, xt_arg_at(argc, argv, 0));
77
+ }
78
+ if (strcmp(name, "propertyIsEnumerable") == 0) {
79
+ if (thisValue == XT_UNDEFINED || thisValue == XT_NULL) {
80
+ xt_throw(xt_error_from_message("TypeError: Cannot convert undefined or null to object"));
81
+ }
82
+ /* Enumerability is not tracked; every own property is enumerable. */
83
+ return xt_object_has_own(thisValue, xt_arg_at(argc, argv, 0));
84
+ }
85
+ if (strcmp(name, "toString") == 0) {
86
+ char buffer[64];
87
+ snprintf(buffer, sizeof(buffer), "[object %s]", xt_object_tag_of(thisValue));
88
+ return xt_string_from_cstr(buffer);
89
+ }
90
+ if (strcmp(name, "valueOf") == 0) return thisValue;
91
+ if (strcmp(name, "isPrototypeOf") == 0) {
92
+ xt_value cursor = xt_object_get_prototype(xt_arg_at(argc, argv, 0));
93
+ while (cursor != XT_UNDEFINED && cursor != XT_NULL) {
94
+ if (cursor == thisValue) return XT_TRUE;
95
+ cursor = xt_object_get_prototype(cursor);
96
+ }
97
+ return XT_FALSE;
98
+ }
99
+ if (strcmp(name, "__proto__") == 0) return xt_object_get_prototype(thisValue);
100
+ return XT_UNDEFINED;
101
+ }
102
+
103
+ /* `__proto__ = value`: ordinary assignment through the inherited setter. */
104
+ static xt_value xt_object_proto_setter(xt_value thisValue, xt_value env, int32_t argc,
105
+ xt_value *argv) {
106
+ (void)env;
107
+ (void)argc;
108
+ xt_value proto = xt_arg_at(argc, argv, 0);
109
+ if (proto == XT_NULL || XT_IS_OBJECT(proto) || XT_IS_ARRAY(proto) || XT_IS_FUNCTION(proto)) {
110
+ xt_object_set_prototype(thisValue, proto);
111
+ }
112
+ return XT_UNDEFINED;
113
+ }
114
+
115
+ static xt_value xt_object_proto_define(xt_value proto, const char *name, int32_t arity) {
116
+ xt_value env[1] = {xt_string_from_cstr(name)};
117
+ xt_value closure = xt_closure_new((void *)xt_object_proto_method, 1, env);
118
+ xt_function_set_metadata(closure, env[0], arity);
119
+ xt_object_set(proto, env[0], closure);
120
+ return closure;
121
+ }
122
+
123
+ xt_value xt_function_prototype(void) {
124
+ if (xt_function_proto_ready) return xt_function_proto_root;
125
+ xt_function_proto_ready = 1;
126
+ xt_function_proto_root = xt_object_new_with_proto(xt_object_prototype());
127
+ xt_gc_add_root(&xt_function_proto_root);
128
+ /* `Array.constructor === Function` (every function inherits from here). The
129
+ * factory sees the ready flag, so this does not recurse. */
130
+ xt_value constructor = xt_builtin_constructor(xt_string_from_cstr("Function"));
131
+ if (constructor != XT_UNDEFINED) {
132
+ xt_object_set(xt_function_proto_root, xt_string_from_cstr("constructor"), constructor);
133
+ }
134
+ return xt_function_proto_root;
135
+ }
136
+
137
+ xt_value xt_object_prototype(void) {
138
+ if (xt_object_proto_ready) return xt_object_proto_root;
139
+ xt_object_proto_ready = 1;
140
+ xt_object_proto_root = xt_object_new_with_proto(XT_NULL);
141
+ xt_gc_add_root(&xt_object_proto_root);
142
+ xt_object_proto_define(xt_object_proto_root, "hasOwnProperty", 1);
143
+ xt_object_proto_define(xt_object_proto_root, "propertyIsEnumerable", 1);
144
+ xt_object_proto_define(xt_object_proto_root, "isPrototypeOf", 1);
145
+ xt_object_proto_define(xt_object_proto_root, "toString", 0);
146
+ xt_object_proto_define(xt_object_proto_root, "valueOf", 0);
147
+ xt_value protoEnv[1] = {xt_string_from_cstr("__proto__")};
148
+ xt_value getter = xt_closure_new((void *)xt_object_proto_method, 1, protoEnv);
149
+ xt_value setter = xt_closure_new((void *)xt_object_proto_setter, 0, NULL);
150
+ xt_function_set_metadata(getter, protoEnv[0], 0);
151
+ xt_function_set_metadata(setter, protoEnv[0], 1);
152
+ xt_object_define_getter(xt_object_proto_root, protoEnv[0], getter);
153
+ xt_object_define_setter(xt_object_proto_root, protoEnv[0], setter);
154
+ /* `({}).constructor === Object`. The constructor factory calls back into
155
+ * `xt_object_prototype` while building the Object function, but the ready
156
+ * flag is already set and the root exists. */
157
+ xt_value constructor = xt_builtin_constructor(xt_string_from_cstr("Object"));
158
+ if (constructor != XT_UNDEFINED) {
159
+ xt_object_set(xt_object_proto_root, xt_string_from_cstr("constructor"), constructor);
160
+ }
161
+ return xt_object_proto_root;
162
+ }
18
163
 
19
164
  xt_value xt_object_new_with_proto(xt_value proto) {
20
165
  xt_object *obj = (xt_object *)xt_alloc(sizeof(xt_object), XT_OBJECT_KIND_OBJECT);
21
166
  obj->count = 0;
22
167
  obj->capacity = 0;
23
168
  obj->properties = NULL;
169
+ obj->shape = xt_shape_empty();
24
170
  obj->prototype = proto;
25
171
  obj->frozen = 0;
26
172
  obj->is_array_base = 0;
@@ -32,7 +178,7 @@ xt_object *xt_as_object(xt_value value) {
32
178
  if (XT_IS_FUNCTION(value)) {
33
179
  /* Functions carry their own property bag (used for static members). */
34
180
  xt_function *fn = (xt_function *)XT_GET_PTR(value);
35
- if (!fn->properties) fn->properties = (xt_object *)XT_GET_PTR(xt_object_new_with_proto(XT_UNDEFINED));
181
+ if (!fn->properties) fn->properties = (xt_object *)XT_GET_PTR(xt_object_new_with_proto(xt_function_prototype()));
36
182
  return fn->properties;
37
183
  }
38
184
  return NULL;
@@ -87,6 +233,7 @@ static xt_property *xt_object_insert_property(xt_object *obj, xt_value key) {
87
233
  }
88
234
  }
89
235
  }
236
+ uint32_t oldCount = obj->count;
90
237
  xt_object_reserve(obj, obj->count + 1);
91
238
  for (uint32_t i = obj->count; i > position; i--) obj->properties[i] = obj->properties[i - 1];
92
239
  xt_property *prop = &obj->properties[position];
@@ -95,6 +242,10 @@ static xt_property *xt_object_insert_property(xt_object *obj, xt_value key) {
95
242
  prop->getter = XT_UNDEFINED;
96
243
  prop->setter = XT_UNDEFINED;
97
244
  obj->count++;
245
+ /* Appending follows a transition; inserting an integer key into the middle
246
+ * reorders the list, so rebuild the canonical shape from the new layout. */
247
+ if (position == oldCount && obj->shape) obj->shape = xt_shape_transition(obj->shape, key);
248
+ else xt_object_shape_changed(obj);
98
249
  return prop;
99
250
  }
100
251
 
@@ -224,12 +375,41 @@ xt_value xt_object_define_setter(xt_value value, xt_value key, xt_value setter)
224
375
  }
225
376
 
226
377
  xt_value xt_object_get_prototype(xt_value value) {
227
- xt_object *obj = xt_as_object(value);
228
- if (obj) return obj->prototype;
378
+ if (XT_IS_ARRAY(value)) return ((xt_array *)XT_GET_PTR(value))->prototype;
379
+ if (XT_IS_FUNCTION(value)) {
380
+ /* A function's [[Prototype]] is the prototype of its property bag
381
+ * (`Function.prototype` unless `Object.setPrototypeOf` changed it). */
382
+ xt_object *bag = xt_as_object(value);
383
+ return bag ? bag->prototype : XT_UNDEFINED;
384
+ }
385
+ if (XT_IS_OBJECT(value)) {
386
+ xt_object *obj = (xt_object *)XT_GET_PTR(value);
387
+ switch (obj->header.kind) {
388
+ case XT_OBJECT_KIND_OBJECT:
389
+ case XT_OBJECT_KIND_ERROR:
390
+ return obj->prototype;
391
+ case XT_OBJECT_KIND_SYMBOL:
392
+ case XT_OBJECT_KIND_MAP:
393
+ case XT_OBJECT_KIND_SET:
394
+ case XT_OBJECT_KIND_WEAK_MAP:
395
+ case XT_OBJECT_KIND_WEAK_SET:
396
+ case XT_OBJECT_KIND_WEAK_REF:
397
+ case XT_OBJECT_KIND_DATE:
398
+ case XT_OBJECT_KIND_REGEXP:
399
+ case XT_OBJECT_KIND_PROMISE:
400
+ return xt_builtin_prototype_for_kind(obj->header.kind);
401
+ default:
402
+ return XT_UNDEFINED;
403
+ }
404
+ }
229
405
  return XT_UNDEFINED;
230
406
  }
231
407
 
232
408
  xt_value xt_object_set_prototype(xt_value value, xt_value proto) {
409
+ if (XT_IS_ARRAY(value)) {
410
+ ((xt_array *)XT_GET_PTR(value))->prototype = proto;
411
+ return value;
412
+ }
233
413
  xt_object *obj = xt_as_object(value);
234
414
  if (obj && !obj->frozen) obj->prototype = proto;
235
415
  return value;
@@ -247,8 +427,33 @@ int xt_object_is_frozen(xt_value value) {
247
427
  }
248
428
 
249
429
  xt_value xt_object_has_own(xt_value value, xt_value key) {
430
+ if (XT_IS_ARRAY(value)) {
431
+ xt_array *array = (xt_array *)XT_GET_PTR(value);
432
+ xt_value propertyKey = xt_to_property_key(key);
433
+ if (XT_IS_STRING(propertyKey)) {
434
+ xt_string *k = xt_as_string(propertyKey);
435
+ if (k->length == 6 && memcmp(xt_string_bytes(k), "length", 6) == 0) return XT_TRUE;
436
+ uint32_t index = 0;
437
+ if (xt_key_is_array_index(k, &index)) return xt_bool(index < array->length);
438
+ }
439
+ return xt_bool(XT_IS_OBJECT(array->extra) &&
440
+ xt_object_find((xt_object *)XT_GET_PTR(array->extra), propertyKey));
441
+ }
442
+ if (XT_IS_STRING(value)) {
443
+ xt_string *string = xt_as_string(value);
444
+ if (xt_is_symbol(key)) return XT_FALSE;
445
+ xt_string *k = xt_as_string(xt_to_string(key));
446
+ if (k->length == 6 && memcmp(xt_string_bytes(k), "length", 6) == 0) return XT_TRUE;
447
+ uint32_t index = 0;
448
+ return xt_bool(xt_key_is_array_index(k, &index) && index < xt_string_utf16_length(string));
449
+ }
250
450
  xt_object *obj = xt_as_object(value);
251
451
  if (!obj) return XT_FALSE;
452
+ /* Map/Set/Date/RegExp/Promise/Symbol use their own struct layout and have no
453
+ * property bag; interpreting them as `xt_object` would read past the end. */
454
+ if (obj->header.kind != XT_OBJECT_KIND_OBJECT && obj->header.kind != XT_OBJECT_KIND_ERROR) {
455
+ return XT_FALSE;
456
+ }
252
457
  return xt_bool(xt_object_find(obj, xt_to_property_key(key)) != NULL);
253
458
  }
254
459
 
@@ -267,6 +472,9 @@ xt_value xt_object_from_entries(xt_value entries) {
267
472
  xt_value xt_object_has(xt_value value, xt_value key) {
268
473
  if (!XT_IS_OBJECT(value)) return XT_FALSE;
269
474
  xt_object *obj = (xt_object *)XT_GET_PTR(value);
475
+ if (obj->header.kind != XT_OBJECT_KIND_OBJECT && obj->header.kind != XT_OBJECT_KIND_ERROR) {
476
+ return XT_FALSE;
477
+ }
270
478
  return xt_bool(xt_object_find(obj, xt_to_property_key(key)) != NULL);
271
479
  }
272
480
 
@@ -286,6 +494,18 @@ xt_value xt_object_own_property_symbols(xt_value value) {
286
494
 
287
495
  xt_value xt_object_keys(xt_value value) {
288
496
  xt_value result = xt_array_new(0, NULL);
497
+ /* A typed array's enumerable own keys are its indices; `length` and the
498
+ * buffer metadata are observable but not enumerable. */
499
+ int typed = xt_typed_array_kind_of(value);
500
+ if (typed >= 0) {
501
+ uint32_t length = (uint32_t)xt_to_number(xt_object_get_cstr(value, "length"));
502
+ for (uint32_t i = 0; i < length; i++) {
503
+ char buffer[32];
504
+ snprintf(buffer, sizeof(buffer), "%u", i);
505
+ xt_array_push(result, xt_string_from_cstr(buffer));
506
+ }
507
+ return result;
508
+ }
289
509
  if (XT_IS_OBJECT(value)) {
290
510
  xt_object *obj = (xt_object *)XT_GET_PTR(value);
291
511
  for (uint32_t i = 0; i < obj->count; i++) {
@@ -310,7 +530,8 @@ xt_value xt_object_keys(xt_value value) {
310
530
  }
311
531
  if (XT_IS_STRING(value)) {
312
532
  xt_string *s = xt_as_string(value);
313
- for (uint32_t i = 0; i < s->length; i++) {
533
+ uint32_t units = xt_string_utf16_length(s);
534
+ for (uint32_t i = 0; i < units; i++) {
314
535
  char buffer[32];
315
536
  snprintf(buffer, sizeof(buffer), "%u", i);
316
537
  xt_array_push(result, xt_string_from_cstr(buffer));