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
@@ -1,5 +1,16 @@
1
1
  /* -- method dispatch ------------------------------------------------------ */
2
2
 
3
+ /* A method that no built-in table recognises must throw, exactly like a
4
+ * missing property called as a function in JavaScript. Returning `undefined`
5
+ * made typos and unimplemented APIs (e.g. `"x".normalize()`) fail silently. */
6
+ static _Noreturn void xt_throw_no_method(const char *type, const char *method) {
7
+ char message[256];
8
+ snprintf(message, sizeof(message), "TypeError: %s has no callable method '%s'", type, method);
9
+ xt_value argument = xt_string_from_cstr(message);
10
+ xt_throw(xt_type_error_ctor(1, &argument));
11
+ abort();
12
+ }
13
+
3
14
  static xt_value xt_array_method(xt_value target, const char *method, int32_t argc, xt_value *argv, int *handled) {
4
15
  *handled = 1;
5
16
  if (strcmp(method, "push") == 0) {
@@ -40,6 +51,7 @@ static xt_value xt_string_method(xt_value target, const char *method, int32_t ar
40
51
  *handled = 1;
41
52
  if (strcmp(method, "charAt") == 0) return xt_string_char_at(target, xt_arg_at(argc, argv, 0));
42
53
  if (strcmp(method, "charCodeAt") == 0) return xt_string_char_code_at(target, xt_arg_at(argc, argv, 0));
54
+ if (strcmp(method, "codePointAt") == 0) return xt_string_code_point_at_value(target, xt_arg_at(argc, argv, 0));
43
55
  if (strcmp(method, "indexOf") == 0) return xt_string_index_of(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1));
44
56
  if (strcmp(method, "includes") == 0) return xt_bool(xt_truthy(xt_ne(xt_string_index_of(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1)), xt_number(-1))));
45
57
  if (strcmp(method, "slice") == 0) return xt_string_slice(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1));
@@ -51,8 +63,8 @@ static xt_value xt_string_method(xt_value target, const char *method, int32_t ar
51
63
  if (strcmp(method, "trim") == 0) return xt_string_trim(target);
52
64
  if (strcmp(method, "replace") == 0) return xt_string_replace(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1));
53
65
  if (strcmp(method, "repeat") == 0) return xt_string_repeat(target, xt_arg_at(argc, argv, 0));
54
- if (strcmp(method, "startsWith") == 0) return xt_string_starts_with(target, xt_arg_at(argc, argv, 0));
55
- if (strcmp(method, "endsWith") == 0) return xt_string_ends_with(target, xt_arg_at(argc, argv, 0));
66
+ if (strcmp(method, "startsWith") == 0) return xt_string_starts_with(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1));
67
+ if (strcmp(method, "endsWith") == 0) return xt_string_ends_with(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1));
56
68
  if (strcmp(method, "concat") == 0) return xt_string_concat_args(target, argc, argv);
57
69
  *handled = 0;
58
70
  return XT_UNDEFINED;
@@ -91,7 +103,7 @@ static xt_value xt_method_value_invoke(xt_value thisValue, xt_value env, int32_t
91
103
  snprintf(message, sizeof(message),
92
104
  "TypeError: Cannot read properties of undefined (reading '%s')",
93
105
  method ? method : "method");
94
- xt_throw(xt_string_from_cstr(message));
106
+ xt_throw(xt_error_from_message(message));
95
107
  }
96
108
  return xt_call_method(thisValue, name, argc, argv);
97
109
  }
@@ -158,6 +170,18 @@ static const xt_method_spec XT_SET_METHODS[] = {
158
170
  {"entries", 0}, {"forEach", 1},
159
171
  };
160
172
 
173
+ static const xt_method_spec XT_WEAKMAP_METHODS[] = {
174
+ {"get", 1}, {"set", 2}, {"has", 1}, {"delete", 1},
175
+ };
176
+
177
+ static const xt_method_spec XT_WEAKSET_METHODS[] = {
178
+ {"add", 1}, {"has", 1}, {"delete", 1},
179
+ };
180
+
181
+ static const xt_method_spec XT_WEAKREF_METHODS[] = {
182
+ {"deref", 0},
183
+ };
184
+
161
185
  static const xt_method_spec XT_REGEXP_METHODS[] = {
162
186
  {"test", 1}, {"exec", 1}, {"toString", 0},
163
187
  };
@@ -214,6 +238,12 @@ xt_value xt_method_value(xt_value target, xt_value name) {
214
238
  known = xt_method_lookup(XT_MAP_METHODS, XT_NAME_COUNT(XT_MAP_METHODS), method, &arity);
215
239
  } else if (kind == XT_OBJECT_KIND_SET) {
216
240
  known = xt_method_lookup(XT_SET_METHODS, XT_NAME_COUNT(XT_SET_METHODS), method, &arity);
241
+ } else if (kind == XT_OBJECT_KIND_WEAK_MAP) {
242
+ known = xt_method_lookup(XT_WEAKMAP_METHODS, XT_NAME_COUNT(XT_WEAKMAP_METHODS), method, &arity);
243
+ } else if (kind == XT_OBJECT_KIND_WEAK_SET) {
244
+ known = xt_method_lookup(XT_WEAKSET_METHODS, XT_NAME_COUNT(XT_WEAKSET_METHODS), method, &arity);
245
+ } else if (kind == XT_OBJECT_KIND_WEAK_REF) {
246
+ known = xt_method_lookup(XT_WEAKREF_METHODS, XT_NAME_COUNT(XT_WEAKREF_METHODS), method, &arity);
217
247
  } else if (kind == XT_OBJECT_KIND_REGEXP) {
218
248
  known = xt_method_lookup(XT_REGEXP_METHODS, XT_NAME_COUNT(XT_REGEXP_METHODS), method, &arity);
219
249
  } else if (kind == XT_OBJECT_KIND_PROMISE) {
@@ -239,7 +269,7 @@ xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *
239
269
  * resolve it as an ordinary property and call it with `target` as `this`. */
240
270
  if (xt_is_symbol(name)) {
241
271
  if (target == XT_UNDEFINED || target == XT_NULL) {
242
- xt_throw(xt_string_from_cstr("TypeError: Cannot read properties of null (reading a Symbol)"));
272
+ xt_throw(xt_error_from_message("TypeError: Cannot read properties of null (reading a Symbol)"));
243
273
  }
244
274
  xt_value fn = xt_get(target, name);
245
275
  if (XT_IS_FUNCTION(fn)) return xt_call_with_this(fn, target, argc, argv);
@@ -252,7 +282,7 @@ xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *
252
282
  * `target` as `this`, instead of silently returning undefined. */
253
283
  xt_value fn = xt_get(target, name);
254
284
  if (XT_IS_FUNCTION(fn)) return xt_call_with_this(fn, target, argc, argv);
255
- xt_throw(xt_string_from_cstr("TypeError: value at computed index is not a function"));
285
+ xt_throw(xt_error_from_message("TypeError: value at computed index is not a function"));
256
286
  return XT_UNDEFINED;
257
287
  }
258
288
  if (target == XT_UNDEFINED || target == XT_NULL) {
@@ -260,13 +290,13 @@ xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *
260
290
  char message[256];
261
291
  snprintf(message, sizeof(message),
262
292
  "TypeError: Cannot read properties of %s (reading '%s')", base, method);
263
- xt_throw(xt_string_from_cstr(message));
293
+ xt_throw(xt_error_from_message(message));
264
294
  }
265
295
  int handled = 0;
266
296
  if (xt_is_symbol(target)) {
267
297
  if (strcmp(method, "toString") == 0) return xt_symbol_to_string(target);
268
298
  if (strcmp(method, "valueOf") == 0) return target;
269
- return XT_UNDEFINED;
299
+ xt_throw_no_method("symbol", method);
270
300
  }
271
301
  if (XT_IS_OBJECT(target)) {
272
302
  xt_object *obj = (xt_object *)XT_GET_PTR(target);
@@ -286,15 +316,23 @@ xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *
286
316
  if (kind != XT_OBJECT_KIND_OBJECT && kind != XT_OBJECT_KIND_FUNCTION) {
287
317
  xt_value result = xt_ext_container_method(target, method, argc, argv, &handled);
288
318
  if (handled) return result;
319
+ /* Containers keep their methods in dedicated C dispatch tables, but
320
+ * still inherit `Object.prototype` (`new Map().toString()`). */
321
+ xt_value inherited = xt_get(target, name);
322
+ if (XT_IS_FUNCTION(inherited)) return xt_call_with_this(inherited, target, argc, argv);
289
323
  }
290
324
  xt_value fn = xt_object_get(target, name);
291
325
  if (XT_IS_FUNCTION(fn)) return xt_call_with_this(fn, target, argc, argv);
292
326
  xt_value result = xt_ext_object_method(target, method, argc, argv, &handled);
293
327
  if (handled) return result;
328
+ /* Inherited Object.prototype methods on containers without a property bag
329
+ * (`new Map().toString()`, ...). */
330
+ xt_value inherited = xt_get(target, name);
331
+ if (XT_IS_FUNCTION(inherited)) return xt_call_with_this(inherited, target, argc, argv);
294
332
  {
295
333
  char message[256];
296
334
  snprintf(message, sizeof(message), "TypeError: object has no callable method '%s'", method);
297
- xt_throw(xt_string_from_cstr(message));
335
+ xt_throw(xt_error_from_message(message));
298
336
  }
299
337
  return XT_UNDEFINED;
300
338
  }
@@ -333,6 +371,13 @@ xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *
333
371
  }
334
372
  xt_value fn = xt_object_get(target, name);
335
373
  if (XT_IS_FUNCTION(fn)) return xt_call_with_this(fn, target, argc, argv);
374
+ /* Statics of a first-class built-in constructor (`const A = Array;
375
+ * A.isArray(x)`). */
376
+ xt_value builtinStatic = xt_builtin_static_value(target, name);
377
+ if (builtinStatic != XT_UNDEFINED) {
378
+ if (XT_IS_FUNCTION(builtinStatic)) return xt_call_with_this(builtinStatic, target, argc, argv);
379
+ return builtinStatic;
380
+ }
336
381
  if (strcmp(method, "toString") == 0) {
337
382
  /* Source text is not retained; report a native-style representation. */
338
383
  xt_function *self = (xt_function *)XT_GET_PTR(target);
@@ -344,32 +389,38 @@ xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *
344
389
  {
345
390
  char message[256];
346
391
  snprintf(message, sizeof(message), "TypeError: function has no callable method '%s'", method);
347
- xt_throw(xt_string_from_cstr(message));
392
+ xt_throw(xt_error_from_message(message));
348
393
  }
349
394
  return XT_UNDEFINED;
350
395
  }
351
396
  if (XT_IS_ARRAY(target)) {
352
397
  xt_value result = xt_ext_array_method(target, method, argc, argv, &handled);
353
398
  if (handled) return result;
354
- return xt_array_method(target, method, argc, argv, &handled);
399
+ result = xt_array_method(target, method, argc, argv, &handled);
400
+ if (handled) return result;
401
+ xt_throw_no_method("array", method);
355
402
  }
356
403
  if (XT_IS_STRING(target)) {
357
404
  xt_value result = xt_ext_string_method(target, method, argc, argv, &handled);
358
405
  if (handled) return result;
359
- return xt_string_method(target, method, argc, argv, &handled);
406
+ result = xt_string_method(target, method, argc, argv, &handled);
407
+ if (handled) return result;
408
+ xt_throw_no_method("string", method);
360
409
  }
361
410
  if (XT_IS_BIGINT(target)) {
362
411
  xt_value result = xt_bigint_method(target, method, argc, argv, &handled);
363
412
  if (handled) return result;
413
+ xt_throw_no_method("bigint", method);
364
414
  }
365
415
  if (XT_IS_NUMBER(target)) {
366
416
  xt_value result = xt_ext_number_method(target, method, argc, argv, &handled);
367
417
  if (handled) return result;
418
+ xt_throw_no_method("number", method);
368
419
  }
369
420
  if (target == XT_TRUE || target == XT_FALSE) {
370
421
  if (strcmp(method, "toString") == 0) return target == XT_TRUE ? xt_string_from_cstr("true") : xt_string_from_cstr("false");
371
422
  if (strcmp(method, "valueOf") == 0) return target;
372
- return XT_UNDEFINED;
423
+ xt_throw_no_method("boolean", method);
373
424
  }
374
- return XT_UNDEFINED;
425
+ xt_throw_no_method("value", method);
375
426
  }
@@ -1,5 +1,6 @@
1
1
  /* -- string methods ------------------------------------------------------- */
2
2
 
3
+ /* Byte-level search. `from` is a byte offset; returns a byte offset or -1. */
3
4
  static int32_t xt_string_find(xt_string *haystack, xt_string *needle, int32_t from) {
4
5
  if (from < 0) from = 0;
5
6
  if ((uint32_t)from > haystack->length) return -1;
@@ -12,44 +13,67 @@ static int32_t xt_string_find(xt_string *haystack, xt_string *needle, int32_t fr
12
13
  return -1;
13
14
  }
14
15
 
16
+ /* JavaScript indexes strings in UTF-16 code units; the byte search above is
17
+ * still correct because every JS index maps to a code-point boundary. */
15
18
  static xt_value xt_string_char_at(xt_value value, xt_value indexValue) {
16
19
  xt_string *s = xt_as_string(value);
17
20
  if (!s) return xt_string_from_cstr("");
18
21
  int32_t index = xt_to_int32(indexValue);
19
- if (index < 0 || (uint32_t)index >= s->length) return xt_string_from_cstr("");
20
- return xt_string_new(xt_string_bytes(s) + index, 1);
22
+ if (index < 0 || (uint32_t)index >= xt_string_utf16_length(s)) return xt_string_from_cstr("");
23
+ return xt_string_unit_value(s, index);
21
24
  }
22
25
 
23
26
  static xt_value xt_string_char_code_at(xt_value value, xt_value indexValue) {
24
27
  xt_string *s = xt_as_string(value);
25
28
  if (!s) return xt_number(NAN);
26
29
  int32_t index = xt_to_int32(indexValue);
27
- if (index < 0 || (uint32_t)index >= s->length) return xt_number(NAN);
28
- return xt_number((double)(unsigned char)xt_string_bytes(s)[index]);
30
+ int32_t unit = xt_string_code_unit(s, index);
31
+ if (unit < 0) return xt_number(NAN);
32
+ return xt_number((double)unit);
33
+ }
34
+
35
+ static xt_value xt_string_code_point_at_value(xt_value value, xt_value indexValue) {
36
+ xt_string *s = xt_as_string(value);
37
+ if (!s) return XT_UNDEFINED;
38
+ int32_t index = xt_to_int32(indexValue);
39
+ int32_t code = xt_string_code_point_at(s, index);
40
+ if (code < 0) return XT_UNDEFINED;
41
+ return xt_number((double)code);
29
42
  }
30
43
 
31
44
  static xt_value xt_string_index_of(xt_value value, xt_value needleValue, xt_value fromValue) {
32
45
  xt_string *s = xt_as_string(value);
33
46
  if (!s) return xt_number(-1);
34
47
  xt_string *needle = xt_as_string(xt_to_string(needleValue));
48
+ int32_t units = (int32_t)xt_string_utf16_length(s);
35
49
  int32_t from = fromValue == XT_UNDEFINED ? 0 : xt_to_int32(fromValue);
36
- return xt_number((double)xt_string_find(s, needle, from));
50
+ if (from < 0) from = 0;
51
+ if (from > units) from = units;
52
+ /* A start position inside a surrogate pair leaves a lone low half; slice the
53
+ * tail so a search for the whole pair correctly fails. */
54
+ if (!xt_string_is_boundary(s, from)) {
55
+ xt_string *tail = xt_as_string(xt_string_slice_units(s, from, units));
56
+ int32_t at = xt_string_find(tail, needle, 0);
57
+ return xt_number(at < 0 ? -1.0 : (double)(from + xt_string_unit_offset(tail, at)));
58
+ }
59
+ int32_t at = xt_string_find(s, needle, xt_string_byte_offset(s, from));
60
+ return xt_number(at < 0 ? -1.0 : (double)xt_string_unit_offset(s, at));
37
61
  }
38
62
 
39
63
  static xt_value xt_string_slice(xt_value value, xt_value startValue, xt_value endValue) {
40
64
  xt_string *s = xt_as_string(value);
41
65
  if (!s) return xt_string_from_cstr("");
42
- int32_t len = (int32_t)s->length;
66
+ int32_t len = (int32_t)xt_string_utf16_length(s);
43
67
  int32_t start = startValue == XT_UNDEFINED ? 0 : xt_to_int32(startValue);
44
68
  int32_t end = endValue == XT_UNDEFINED ? len : xt_to_int32(endValue);
45
69
  xt_normalize_slice(len, &start, &end);
46
- return xt_string_new(xt_string_bytes(s) + start, (size_t)(end - start));
70
+ return xt_string_slice_units(s, start, end);
47
71
  }
48
72
 
49
73
  static xt_value xt_string_substring(xt_value value, xt_value startValue, xt_value endValue) {
50
74
  xt_string *s = xt_as_string(value);
51
75
  if (!s) return xt_string_from_cstr("");
52
- int32_t len = (int32_t)s->length;
76
+ int32_t len = (int32_t)xt_string_utf16_length(s);
53
77
  int32_t start = startValue == XT_UNDEFINED ? 0 : xt_to_int32(startValue);
54
78
  int32_t end = endValue == XT_UNDEFINED ? len : xt_to_int32(endValue);
55
79
  if (start < 0) start = 0;
@@ -61,13 +85,13 @@ static xt_value xt_string_substring(xt_value value, xt_value startValue, xt_valu
61
85
  start = end;
62
86
  end = swap;
63
87
  }
64
- return xt_string_new(xt_string_bytes(s) + start, (size_t)(end - start));
88
+ return xt_string_slice_units(s, start, end);
65
89
  }
66
90
 
67
91
  static xt_value xt_string_substr(xt_value value, xt_value startValue, xt_value lengthValue) {
68
92
  xt_string *s = xt_as_string(value);
69
93
  if (!s) return xt_string_from_cstr("");
70
- int32_t len = (int32_t)s->length;
94
+ int32_t len = (int32_t)xt_string_utf16_length(s);
71
95
  int32_t start = startValue == XT_UNDEFINED ? 0 : xt_to_int32(startValue);
72
96
  if (start < 0) start += len;
73
97
  if (start < 0) start = 0;
@@ -75,7 +99,7 @@ static xt_value xt_string_substr(xt_value value, xt_value startValue, xt_value l
75
99
  int32_t length = lengthValue == XT_UNDEFINED ? len - start : xt_to_int32(lengthValue);
76
100
  if (length < 0) length = 0;
77
101
  if (start + length > len) length = len - start;
78
- return xt_string_new(xt_string_bytes(s) + start, (size_t)length);
102
+ return xt_string_slice_units(s, start, start + length);
79
103
  }
80
104
 
81
105
  static xt_value xt_string_split(xt_value value, xt_value separatorValue, xt_value limitValue) {
@@ -92,7 +116,10 @@ static xt_value xt_string_split(xt_value value, xt_value separatorValue, xt_valu
92
116
  const char *bytes = xt_string_bytes(s);
93
117
  const char *sepBytes = xt_string_bytes(sep);
94
118
  if (sep->length == 0) {
95
- for (uint32_t i = 0; i < s->length; i++) xt_array_push(result, xt_string_new(bytes + i, 1));
119
+ /* Splitting on the empty string yields one string per UTF-16 code unit,
120
+ * so an emoji becomes its two surrogate halves. */
121
+ int32_t units = (int32_t)xt_string_utf16_length(s);
122
+ for (int32_t i = 0; i < units; i++) xt_array_push(result, xt_string_unit_value(s, i));
96
123
  } else {
97
124
  uint32_t start = 0;
98
125
  uint32_t i = 0;
@@ -122,6 +149,7 @@ static xt_value xt_string_case(xt_value value, int upper) {
122
149
  unsigned char c = (unsigned char)bytes[i];
123
150
  mutable[i] = (char)(upper ? toupper((int)c) : tolower((int)c));
124
151
  }
152
+ xt_string_finish(out);
125
153
  return XT_FROM_PTR(XT_TAG_STRING, out);
126
154
  }
127
155
 
@@ -153,6 +181,7 @@ static xt_value xt_string_replace(xt_value value, xt_value searchValue, xt_value
153
181
  memcpy(mutable + at, repl, replacement->length);
154
182
  memcpy(mutable + at + replacement->length, text + at + search->length,
155
183
  s->length - (size_t)at - search->length);
184
+ xt_string_finish(out);
156
185
  return XT_FROM_PTR(XT_TAG_STRING, out);
157
186
  }
158
187
 
@@ -161,30 +190,58 @@ static xt_value xt_string_repeat(xt_value value, xt_value countValue) {
161
190
  if (!s) return value;
162
191
  int32_t count = xt_to_int32(countValue);
163
192
  if (count < 0) {
164
- xt_throw(xt_string_from_cstr("RangeError: Invalid count value"));
193
+ xt_throw(xt_error_from_message("RangeError: Invalid count value"));
165
194
  return XT_UNDEFINED;
166
195
  }
167
196
  xt_string *out = xt_string_alloc((size_t)s->length * (size_t)count);
168
197
  const char *bytes = xt_string_bytes(s);
169
198
  char *mutable = xt_string_mutable(out);
170
199
  for (int32_t i = 0; i < count; i++) memcpy(mutable + (size_t)i * s->length, bytes, s->length);
200
+ xt_string_finish(out);
171
201
  return XT_FROM_PTR(XT_TAG_STRING, out);
172
202
  }
173
203
 
174
- static xt_value xt_string_starts_with(xt_value value, xt_value searchValue) {
204
+ static xt_value xt_string_starts_with(xt_value value, xt_value searchValue, xt_value positionValue) {
175
205
  xt_string *s = xt_as_string(value);
176
206
  if (!s) return XT_FALSE;
177
207
  xt_string *search = xt_as_string(xt_to_string(searchValue));
208
+ const char *sBytes = xt_string_bytes(s);
209
+ const char *searchBytes = xt_string_bytes(search);
210
+ int32_t units = (int32_t)xt_string_utf16_length(s);
211
+ int32_t position = positionValue == XT_UNDEFINED ? 0 : xt_to_int32(positionValue);
212
+ if (position < 0) position = 0;
213
+ if (position > units) position = units;
178
214
  if (search->length > s->length) return XT_FALSE;
179
- return xt_bool(memcmp(xt_string_bytes(s), xt_string_bytes(search), search->length) == 0);
215
+ if (!xt_string_is_boundary(s, position)) {
216
+ xt_string *tail = xt_as_string(xt_string_slice_units(s, position, units));
217
+ if (search->length > tail->length) return XT_FALSE;
218
+ return xt_bool(memcmp(xt_string_bytes(tail), searchBytes, search->length) == 0);
219
+ }
220
+ int32_t at = xt_string_byte_offset(s, position);
221
+ if ((uint32_t)at + search->length > s->length) return XT_FALSE;
222
+ return xt_bool(memcmp(sBytes + at, searchBytes, search->length) == 0);
180
223
  }
181
224
 
182
- static xt_value xt_string_ends_with(xt_value value, xt_value searchValue) {
225
+ static xt_value xt_string_ends_with(xt_value value, xt_value searchValue, xt_value endValue) {
183
226
  xt_string *s = xt_as_string(value);
184
227
  if (!s) return XT_FALSE;
185
228
  xt_string *search = xt_as_string(xt_to_string(searchValue));
229
+ const char *sBytes = xt_string_bytes(s);
230
+ const char *searchBytes = xt_string_bytes(search);
231
+ int32_t units = (int32_t)xt_string_utf16_length(s);
232
+ int32_t end = endValue == XT_UNDEFINED ? units : xt_to_int32(endValue);
233
+ if (end < 0) end = 0;
234
+ if (end > units) end = units;
186
235
  if (search->length > s->length) return XT_FALSE;
187
- return xt_bool(memcmp(xt_string_bytes(s) + s->length - search->length, xt_string_bytes(search), search->length) == 0);
236
+ if (!xt_string_is_boundary(s, end)) {
237
+ xt_string *prefix = xt_as_string(xt_string_slice_units(s, 0, end));
238
+ if (search->length > prefix->length) return XT_FALSE;
239
+ return xt_bool(memcmp(xt_string_bytes(prefix) + prefix->length - search->length,
240
+ searchBytes, search->length) == 0);
241
+ }
242
+ int32_t at = xt_string_byte_offset(s, end);
243
+ if ((uint32_t)at < search->length) return XT_FALSE;
244
+ return xt_bool(memcmp(sBytes + at - search->length, searchBytes, search->length) == 0);
188
245
  }
189
246
 
190
247
  static xt_value xt_string_concat_args(xt_value value, int32_t argc, xt_value *argv) {
@@ -1,5 +1,16 @@
1
1
  /* -- Array statics -------------------------------------------------------- */
2
2
 
3
+ /* True when `Array.from` should consume the value through the iteration
4
+ * protocol instead of the array-like `length` path. Typed arrays stay on the
5
+ * length path because their indexed properties already work that way. */
6
+ static int xt_array_from_is_iterable(xt_value value) {
7
+ if (xt_is_map(value) || xt_is_set(value) || xt_is_generator(value)) return 1;
8
+ if (XT_IS_OBJECT(value) && xt_typed_array_kind_of(value) < 0) {
9
+ return XT_IS_FUNCTION(xt_object_get(value, xt_symbol_well_known("iterator")));
10
+ }
11
+ return 0;
12
+ }
13
+
3
14
  xt_value xt_array_static(xt_value name, int32_t argc, xt_value *argv) {
4
15
  const char *fn = xt_string_data(name);
5
16
  if (!fn) return XT_UNDEFINED;
@@ -18,12 +29,26 @@ xt_value xt_array_static(xt_value name, int32_t argc, xt_value *argv) {
18
29
  }
19
30
  } else if (XT_IS_STRING(source)) {
20
31
  xt_string *s = xt_as_string(source);
21
- const char *bytes = xt_string_bytes(s);
22
- for (uint32_t i = 0; i < s->length; i++) {
23
- xt_value item = xt_string_new(bytes + i, 1);
32
+ uint32_t points = xt_string_code_point_count(s);
33
+ for (uint32_t i = 0; i < points; i++) {
34
+ xt_value item = xt_string_code_point_value(s, (int32_t)i);
24
35
  if (XT_IS_FUNCTION(mapper)) { xt_value args[2] = {item, xt_number((double)i)}; item = xt_closure_call(mapper, 2, args); }
25
36
  xt_array_push(out, item);
26
37
  }
38
+ } else if (xt_array_from_is_iterable(source)) {
39
+ /* Map, Set, generators, iterator objects and custom `[Symbol.iterator]`
40
+ * values do not expose a `length`; walk their `next()` protocol instead
41
+ * of silently producing an empty array. */
42
+ xt_value iterator = xt_iter_open(source);
43
+ for (uint32_t i = 0;; i++) {
44
+ if (!xt_truthy(xt_iter_has(iterator, xt_number((double)i)))) break;
45
+ xt_value item = xt_iter_value(iterator, xt_number((double)i));
46
+ if (XT_IS_FUNCTION(mapper)) {
47
+ xt_value args[2] = {item, xt_number((double)i)};
48
+ item = xt_closure_call(mapper, 2, args);
49
+ }
50
+ xt_array_push(out, item);
51
+ }
27
52
  } else {
28
53
  double length = xt_to_number(xt_get(source, xt_string_from_cstr("length")));
29
54
  for (int32_t i = 0; i < (int32_t)length; i++) {
@@ -85,7 +85,7 @@ static xt_value xt_array_sort(xt_value value, xt_value fn) {
85
85
  int hasFn = XT_IS_FUNCTION(fn);
86
86
  xt_value *scratch = (xt_value *)malloc(sizeof(xt_value) * array->length);
87
87
  if (!scratch) {
88
- xt_throw(xt_string_from_cstr("RangeError: out of memory in Array.prototype.sort"));
88
+ xt_throw(xt_error_from_message("RangeError: out of memory in Array.prototype.sort"));
89
89
  return value;
90
90
  }
91
91
  xt_array_merge_sort(array->items, scratch, array->length, fn, hasFn);
@@ -225,7 +225,9 @@ static xt_value xt_array_with(xt_value value, xt_value indexValue, xt_value newV
225
225
  int32_t index = xt_to_int32(indexValue);
226
226
  if (index < 0) index += (int32_t)array->length;
227
227
  if (index < 0 || index >= (int32_t)array->length) {
228
- xt_throw(xt_add(xt_string_from_cstr("RangeError: Invalid index : "), xt_to_string(indexValue)));
228
+ xt_value message =
229
+ xt_add(xt_string_from_cstr("RangeError: Invalid index : "), xt_to_string(indexValue));
230
+ xt_throw(xt_error_from_message(xt_string_data(message)));
229
231
  return copy;
230
232
  }
231
233
  array->items[index] = newValue;
@@ -266,7 +268,7 @@ xt_value xt_ext_array_method(xt_value target, const char *method, int32_t argc,
266
268
  xt_value acc;
267
269
  if (argc >= 2) acc = argv[1];
268
270
  else if (array->length > 0) acc = array->items[i--];
269
- else { xt_throw(xt_string_from_cstr("TypeError: Reduce of empty array with no initial value")); return XT_UNDEFINED; }
271
+ else { xt_throw(xt_error_from_message("TypeError: Reduce of empty array with no initial value")); return XT_UNDEFINED; }
270
272
  for (; i >= 0; i--) {
271
273
  xt_value args[4] = {acc, array->items[i], xt_number((double)i), target};
272
274
  acc = xt_closure_call(fn, 4, args);
@@ -2,6 +2,11 @@ xt_value xt_ext_container_method(xt_value target, const char *method, int32_t ar
2
2
  xt_object *obj = (xt_object *)XT_GET_PTR(target);
3
3
  if (obj->header.kind == XT_OBJECT_KIND_MAP) return xt_map_method(target, method, argc, argv, handled);
4
4
  if (obj->header.kind == XT_OBJECT_KIND_SET) return xt_set_method(target, method, argc, argv, handled);
5
+ if (obj->header.kind == XT_OBJECT_KIND_WEAK_MAP ||
6
+ obj->header.kind == XT_OBJECT_KIND_WEAK_SET ||
7
+ obj->header.kind == XT_OBJECT_KIND_WEAK_REF) {
8
+ return xt_weak_method(target, method, argc, argv, handled);
9
+ }
5
10
  if (obj->header.kind == XT_OBJECT_KIND_DATE) return xt_date_method(target, method, argc, argv, handled);
6
11
  if (obj->header.kind == XT_OBJECT_KIND_REGEXP) {
7
12
  xt_regexp *regexp = (xt_regexp *)obj;
@@ -4,11 +4,111 @@ int xt_is_date(xt_value value) {
4
4
  return XT_IS_OBJECT(value) && ((xt_object *)XT_GET_PTR(value))->header.kind == XT_OBJECT_KIND_DATE;
5
5
  }
6
6
 
7
+ /* Parse `YYYY-MM-DD`, optionally followed by `T`/space and
8
+ * `HH:MM[:SS[.mmm]]`, then `Z`, `+HH:MM`/`-HH:MM` (or the HHMM spelling).
9
+ * A date-only value is UTC; a date-time without an offset is local time, which
10
+ * is what ECMAScript specifies. Returns milliseconds since the epoch, or NaN
11
+ * for anything outside this subset. */
12
+ static int xt_date_digits(const char *text, int count, int *out) {
13
+ int value = 0;
14
+ for (int i = 0; i < count; i++) {
15
+ if (text[i] < '0' || text[i] > '9') return 0;
16
+ value = value * 10 + (text[i] - '0');
17
+ }
18
+ *out = value;
19
+ return 1;
20
+ }
21
+
22
+ static double xt_date_parse_text(const char *text) {
23
+ size_t length = strlen(text);
24
+ size_t i = 0;
25
+ int year = 0, month = 0, day = 0;
26
+ if (length < 10 || !xt_date_digits(text, 4, &year) || text[4] != '-' ||
27
+ !xt_date_digits(text + 5, 2, &month) || text[7] != '-' ||
28
+ !xt_date_digits(text + 8, 2, &day)) {
29
+ return NAN;
30
+ }
31
+ i = 10;
32
+ int hour = 0, minute = 0, second = 0, millis = 0;
33
+ int hasTime = 0;
34
+ if (i < length && (text[i] == 'T' || text[i] == ' ')) {
35
+ hasTime = 1;
36
+ i++;
37
+ if (i + 5 > length || !xt_date_digits(text + i, 2, &hour) || text[i + 2] != ':' ||
38
+ !xt_date_digits(text + i + 3, 2, &minute)) {
39
+ return NAN;
40
+ }
41
+ i += 5;
42
+ if (i + 3 <= length && text[i] == ':') {
43
+ if (!xt_date_digits(text + i + 1, 2, &second)) return NAN;
44
+ i += 3;
45
+ }
46
+ if (i + 4 <= length && text[i] == '.') {
47
+ if (!xt_date_digits(text + i + 1, 3, &millis)) return NAN;
48
+ i += 4;
49
+ }
50
+ }
51
+ int utc = !hasTime;
52
+ int offsetSeconds = 0;
53
+ if (i < length) {
54
+ if (text[i] == 'Z') {
55
+ utc = 1;
56
+ i++;
57
+ } else if (text[i] == '+' || text[i] == '-') {
58
+ int sign = text[i] == '-' ? -1 : 1;
59
+ i++;
60
+ int offsetHour = 0, offsetMinute = 0;
61
+ if (i + 5 <= length && xt_date_digits(text + i, 2, &offsetHour) && text[i + 2] == ':' &&
62
+ xt_date_digits(text + i + 3, 2, &offsetMinute)) {
63
+ i += 5;
64
+ } else if (i + 4 <= length && xt_date_digits(text + i, 2, &offsetHour) &&
65
+ xt_date_digits(text + i + 2, 2, &offsetMinute)) {
66
+ i += 4;
67
+ } else {
68
+ return NAN;
69
+ }
70
+ if (offsetHour > 23 || offsetMinute > 59) return NAN;
71
+ offsetSeconds = sign * (offsetHour * 3600 + offsetMinute * 60);
72
+ utc = 1;
73
+ } else {
74
+ return NAN;
75
+ }
76
+ }
77
+ if (i != length) return NAN;
78
+ if (month < 1 || month > 12 || day < 1 || day > 31 ||
79
+ hour > 23 || minute > 59 || second > 59) {
80
+ return NAN;
81
+ }
82
+ struct tm tm;
83
+ memset(&tm, 0, sizeof(tm));
84
+ tm.tm_year = year - 1900;
85
+ tm.tm_mon = month - 1;
86
+ tm.tm_mday = day;
87
+ tm.tm_hour = hour;
88
+ tm.tm_min = minute;
89
+ tm.tm_sec = second;
90
+ time_t seconds;
91
+ if (utc) {
92
+ seconds = xt_timegm(&tm);
93
+ } else {
94
+ tm.tm_isdst = -1;
95
+ seconds = mktime(&tm);
96
+ if (seconds == (time_t)-1) return NAN;
97
+ }
98
+ if (utc && offsetSeconds != 0) seconds -= offsetSeconds;
99
+ return (double)seconds * 1000.0 + (double)millis;
100
+ }
101
+
7
102
  xt_value xt_date_ctor(int32_t argc, xt_value *argv) {
8
103
  xt_date *date = (xt_date *)xt_alloc(sizeof(xt_date), XT_OBJECT_KIND_DATE);
9
104
  if (argc == 0) date->time = (double)time(NULL) * 1000.0;
10
- else if (argc == 1) date->time = XT_IS_STRING(argv[0]) ? 0.0 : xt_to_number(argv[0]);
11
- else {
105
+ else if (argc == 1) {
106
+ if (XT_IS_STRING(argv[0])) {
107
+ date->time = xt_date_parse_text(xt_string_data(argv[0]));
108
+ } else {
109
+ date->time = xt_to_number(argv[0]);
110
+ }
111
+ } else {
12
112
  struct tm tm;
13
113
  memset(&tm, 0, sizeof(tm));
14
114
  tm.tm_year = xt_to_int32(argv[0]) - 1900;
@@ -27,7 +127,11 @@ xt_value xt_date_static(xt_value name, int32_t argc, xt_value *argv) {
27
127
  const char *fn = xt_string_data(name);
28
128
  if (!fn) return XT_UNDEFINED;
29
129
  if (strcmp(fn, "now") == 0) return xt_number((double)time(NULL) * 1000.0);
30
- if (strcmp(fn, "parse") == 0) return xt_number(0);
130
+ if (strcmp(fn, "parse") == 0) {
131
+ xt_value input = xt_arg_at(argc, argv, 0);
132
+ if (!XT_IS_STRING(input)) return xt_number(NAN);
133
+ return xt_number(xt_date_parse_text(xt_string_data(input)));
134
+ }
31
135
  if (strcmp(fn, "UTC") == 0) {
32
136
  struct tm tm;
33
137
  memset(&tm, 0, sizeof(tm));
@@ -68,6 +172,10 @@ static xt_value xt_date_method(xt_value target, const char *method, int32_t argc
68
172
  if (strcmp(name, "getSeconds") == 0) return xt_number(tm.tm_sec);
69
173
  if (strcmp(name, "getMilliseconds") == 0) return xt_number(fmod(date->time, 1000.0));
70
174
  if (strcmp(method, "toISOString") == 0) {
175
+ if (isnan(date->time)) {
176
+ xt_value message = xt_string_from_cstr("Invalid time value");
177
+ xt_throw(xt_range_error_ctor(1, &message));
178
+ }
71
179
  char buffer[64];
72
180
  snprintf(buffer, sizeof(buffer), "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", tm.tm_year + 1900, tm.tm_mon + 1,
73
181
  tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, (int)fmod(date->time, 1000.0));