xbintsc 0.5.6 → 0.5.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (490) hide show
  1. package/AGENTS.md +20 -10
  2. package/README.md +8 -7
  3. package/README.zh-CN.md +6 -6
  4. package/dist/src/binder/declarations.js +14 -3
  5. package/dist/src/binder/declarations.js.map +1 -1
  6. package/dist/src/cli/hints.js +7 -1
  7. package/dist/src/cli/hints.js.map +1 -1
  8. package/dist/src/cli/main.js +115 -15
  9. package/dist/src/cli/main.js.map +1 -1
  10. package/dist/src/cli/watch.d.ts +25 -0
  11. package/dist/src/cli/watch.js +93 -0
  12. package/dist/src/cli/watch.js.map +1 -0
  13. package/dist/src/codegen/generator/calls/access.js +11 -2
  14. package/dist/src/codegen/generator/calls/access.js.map +1 -1
  15. package/dist/src/codegen/generator/calls/closures.js +12 -4
  16. package/dist/src/codegen/generator/calls/closures.js.map +1 -1
  17. package/dist/src/codegen/generator/context.d.ts +8 -0
  18. package/dist/src/codegen/generator/context.js +22 -3
  19. package/dist/src/codegen/generator/context.js.map +1 -1
  20. package/dist/src/codegen/generator/expressions/operators.js +17 -15
  21. package/dist/src/codegen/generator/expressions/operators.js.map +1 -1
  22. package/dist/src/codegen/generator/expressions/primary.js +5 -0
  23. package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
  24. package/dist/src/codegen/generator/module.js +0 -7
  25. package/dist/src/codegen/generator/module.js.map +1 -1
  26. package/dist/src/codegen/generator/numeric.d.ts +6 -3
  27. package/dist/src/codegen/generator/numeric.js +54 -11
  28. package/dist/src/codegen/generator/numeric.js.map +1 -1
  29. package/dist/src/codegen/generator/state.js +23 -0
  30. package/dist/src/codegen/generator/state.js.map +1 -1
  31. package/dist/src/codegen/generator/statements/control-flow.js +1 -4
  32. package/dist/src/codegen/generator/statements/control-flow.js.map +1 -1
  33. package/dist/src/codegen/generator/statements/loops.js +48 -16
  34. package/dist/src/codegen/generator/statements/loops.js.map +1 -1
  35. package/dist/src/codegen/generator/tables.js +26 -1
  36. package/dist/src/codegen/generator/tables.js.map +1 -1
  37. package/dist/src/diagnostics/diagnostic.d.ts +3 -1
  38. package/dist/src/diagnostics/diagnostic.js +23 -3
  39. package/dist/src/diagnostics/diagnostic.js.map +1 -1
  40. package/dist/src/driver/app-artifacts.d.ts +42 -0
  41. package/dist/src/driver/app-artifacts.js +53 -0
  42. package/dist/src/driver/app-artifacts.js.map +1 -0
  43. package/dist/src/driver/build-key.d.ts +29 -0
  44. package/dist/src/driver/build-key.js +35 -0
  45. package/dist/src/driver/build-key.js.map +1 -0
  46. package/dist/src/driver/bundler/graph.js +61 -12
  47. package/dist/src/driver/bundler/graph.js.map +1 -1
  48. package/dist/src/driver/bundler/merge.js +7 -1
  49. package/dist/src/driver/bundler/merge.js.map +1 -1
  50. package/dist/src/driver/compiler.d.ts +10 -67
  51. package/dist/src/driver/compiler.js +95 -234
  52. package/dist/src/driver/compiler.js.map +1 -1
  53. package/dist/src/driver/config.d.ts +3 -0
  54. package/dist/src/driver/config.js +8 -0
  55. package/dist/src/driver/config.js.map +1 -1
  56. package/dist/src/driver/frontend.d.ts +37 -0
  57. package/dist/src/driver/frontend.js +92 -0
  58. package/dist/src/driver/frontend.js.map +1 -0
  59. package/dist/src/driver/index.d.ts +1 -1
  60. package/dist/src/driver/index.js.map +1 -1
  61. package/dist/src/driver/options.d.ts +64 -0
  62. package/dist/src/driver/options.js +9 -0
  63. package/dist/src/driver/options.js.map +1 -0
  64. package/dist/src/driver/runtime-objects.d.ts +38 -0
  65. package/dist/src/driver/runtime-objects.js +112 -0
  66. package/dist/src/driver/runtime-objects.js.map +1 -0
  67. package/dist/src/driver/toolchain-provider.d.ts +4 -0
  68. package/dist/src/driver/toolchain-provider.js +4 -0
  69. package/dist/src/driver/toolchain-provider.js.map +1 -1
  70. package/dist/src/driver/toolchain.d.ts +32 -1
  71. package/dist/src/driver/toolchain.js +115 -11
  72. package/dist/src/driver/toolchain.js.map +1 -1
  73. package/dist/src/driver/version.d.ts +12 -0
  74. package/dist/src/driver/version.js +13 -0
  75. package/dist/src/driver/version.js.map +1 -0
  76. package/dist/src/driver/win-icon.d.ts +7 -9
  77. package/dist/src/driver/win-icon.js +37 -35
  78. package/dist/src/driver/win-icon.js.map +1 -1
  79. package/dist/src/extensions/node/fs/index.d.ts +4 -3
  80. package/dist/src/extensions/node/fs/index.js +12 -3
  81. package/dist/src/extensions/node/fs/index.js.map +1 -1
  82. package/dist/src/extensions/node/fs-promises/index.d.ts +5 -5
  83. package/dist/src/extensions/node/fs-promises/index.js +15 -6
  84. package/dist/src/extensions/node/fs-promises/index.js.map +1 -1
  85. package/dist/src/parser/declarations/classes.js +5 -0
  86. package/dist/src/parser/declarations/classes.js.map +1 -1
  87. package/dist/src/parser/declarations/functions.js +13 -1
  88. package/dist/src/parser/declarations/functions.js.map +1 -1
  89. package/dist/src/parser/modules.js +8 -3
  90. package/dist/src/parser/modules.js.map +1 -1
  91. package/dist/src/parser/parser.d.ts +1 -0
  92. package/dist/src/parser/parser.js +23 -0
  93. package/dist/src/parser/parser.js.map +1 -1
  94. package/dist/tests/cli/check.test.d.ts +6 -0
  95. package/dist/tests/cli/check.test.js +68 -0
  96. package/dist/tests/cli/check.test.js.map +1 -0
  97. package/dist/tests/cli/main.test.js +19 -0
  98. package/dist/tests/cli/main.test.js.map +1 -1
  99. package/dist/tests/cli/watch.test.d.ts +6 -0
  100. package/dist/tests/cli/watch.test.js +72 -0
  101. package/dist/tests/cli/watch.test.js.map +1 -0
  102. package/dist/tests/codegen/expressions.test.js +15 -3
  103. package/dist/tests/codegen/expressions.test.js.map +1 -1
  104. package/dist/tests/codegen/llvm.test.js +16 -0
  105. package/dist/tests/codegen/llvm.test.js.map +1 -1
  106. package/dist/tests/diagnostics/diagnostic.test.js +8 -0
  107. package/dist/tests/diagnostics/diagnostic.test.js.map +1 -1
  108. package/dist/tests/docs/structure.test.d.ts +1 -0
  109. package/dist/tests/docs/structure.test.js +92 -0
  110. package/dist/tests/docs/structure.test.js.map +1 -0
  111. package/dist/tests/driver/compiler.test.js +6 -0
  112. package/dist/tests/driver/compiler.test.js.map +1 -1
  113. package/dist/tests/driver/config.test.js +9 -0
  114. package/dist/tests/driver/config.test.js.map +1 -1
  115. package/dist/tests/driver/icon.test.js +19 -32
  116. package/dist/tests/driver/icon.test.js.map +1 -1
  117. package/dist/tests/driver/invalid-input.test.d.ts +10 -0
  118. package/dist/tests/driver/invalid-input.test.js +29 -0
  119. package/dist/tests/driver/invalid-input.test.js.map +1 -0
  120. package/dist/tests/driver/modules.test.js +42 -3
  121. package/dist/tests/driver/modules.test.js.map +1 -1
  122. package/dist/tests/driver/toolchain-provider.test.js +27 -1
  123. package/dist/tests/driver/toolchain-provider.test.js.map +1 -1
  124. package/dist/tests/driver/toolchain.test.js +60 -2
  125. package/dist/tests/driver/toolchain.test.js.map +1 -1
  126. package/dist/tests/e2e/array-buffer.test.d.ts +5 -0
  127. package/dist/tests/e2e/array-buffer.test.js +38 -0
  128. package/dist/tests/e2e/array-buffer.test.js.map +1 -0
  129. package/dist/tests/e2e/array-from-iterables.test.d.ts +7 -0
  130. package/dist/tests/e2e/array-from-iterables.test.js +34 -0
  131. package/dist/tests/e2e/array-from-iterables.test.js.map +1 -0
  132. package/dist/tests/e2e/array-symbol-iterator.test.d.ts +8 -0
  133. package/dist/tests/e2e/array-symbol-iterator.test.js +42 -0
  134. package/dist/tests/e2e/array-symbol-iterator.test.js.map +1 -0
  135. package/dist/tests/e2e/async-await.test.js +1 -1
  136. package/dist/tests/e2e/async-fs.test.d.ts +9 -0
  137. package/dist/tests/e2e/async-fs.test.js +119 -0
  138. package/dist/tests/e2e/async-fs.test.js.map +1 -0
  139. package/dist/tests/e2e/async-generators.test.d.ts +1 -0
  140. package/dist/tests/e2e/async-generators.test.js +154 -0
  141. package/dist/tests/e2e/async-generators.test.js.map +1 -0
  142. package/dist/tests/e2e/await-ordering.test.d.ts +5 -0
  143. package/dist/tests/e2e/await-ordering.test.js +37 -0
  144. package/dist/tests/e2e/await-ordering.test.js.map +1 -0
  145. package/dist/tests/e2e/compile-builtins.test.js +1 -1
  146. package/dist/tests/e2e/compile-modules.test.js +7 -0
  147. package/dist/tests/e2e/compile-modules.test.js.map +1 -1
  148. package/dist/tests/e2e/date-parse.test.d.ts +8 -0
  149. package/dist/tests/e2e/date-parse.test.js +38 -0
  150. package/dist/tests/e2e/date-parse.test.js.map +1 -0
  151. package/dist/tests/e2e/default-anonymous-exports.test.d.ts +7 -0
  152. package/dist/tests/e2e/default-anonymous-exports.test.js +23 -0
  153. package/dist/tests/e2e/default-anonymous-exports.test.js.map +1 -0
  154. package/dist/tests/e2e/fetch.test.js +24 -0
  155. package/dist/tests/e2e/fetch.test.js.map +1 -1
  156. package/dist/tests/e2e/globals-microtask.test.d.ts +9 -0
  157. package/dist/tests/e2e/globals-microtask.test.js +37 -0
  158. package/dist/tests/e2e/globals-microtask.test.js.map +1 -0
  159. package/dist/tests/e2e/gui-inline-svg.test.d.ts +11 -0
  160. package/dist/tests/e2e/gui-inline-svg.test.js +160 -0
  161. package/dist/tests/e2e/gui-inline-svg.test.js.map +1 -0
  162. package/dist/tests/e2e/gui-media.test.js +8 -1
  163. package/dist/tests/e2e/gui-media.test.js.map +1 -1
  164. package/dist/tests/e2e/inspect-builtins.test.d.ts +10 -0
  165. package/dist/tests/e2e/inspect-builtins.test.js +43 -0
  166. package/dist/tests/e2e/inspect-builtins.test.js.map +1 -0
  167. package/dist/tests/e2e/json-builtin-objects.test.d.ts +9 -0
  168. package/dist/tests/e2e/json-builtin-objects.test.js +23 -0
  169. package/dist/tests/e2e/json-builtin-objects.test.js.map +1 -0
  170. package/dist/tests/e2e/json-circular.test.d.ts +6 -0
  171. package/dist/tests/e2e/json-circular.test.js +43 -0
  172. package/dist/tests/e2e/json-circular.test.js.map +1 -0
  173. package/dist/tests/e2e/json-parse-reviver.test.d.ts +6 -0
  174. package/dist/tests/e2e/json-parse-reviver.test.js +29 -0
  175. package/dist/tests/e2e/json-parse-reviver.test.js.map +1 -0
  176. package/dist/tests/e2e/json-stringify-replacer.test.d.ts +6 -0
  177. package/dist/tests/e2e/json-stringify-replacer.test.js +27 -0
  178. package/dist/tests/e2e/json-stringify-replacer.test.js.map +1 -0
  179. package/dist/tests/e2e/json-stringify-space.test.d.ts +6 -0
  180. package/dist/tests/e2e/json-stringify-space.test.js +23 -0
  181. package/dist/tests/e2e/json-stringify-space.test.js.map +1 -0
  182. package/dist/tests/e2e/method-dispatch-errors.test.d.ts +9 -0
  183. package/dist/tests/e2e/method-dispatch-errors.test.js +38 -0
  184. package/dist/tests/e2e/method-dispatch-errors.test.js.map +1 -0
  185. package/dist/tests/e2e/native-extensions.test.js +1 -1
  186. package/dist/tests/e2e/native-extensions.test.js.map +1 -1
  187. package/dist/tests/e2e/promise-with-resolvers.test.d.ts +5 -0
  188. package/dist/tests/e2e/promise-with-resolvers.test.js +20 -0
  189. package/dist/tests/e2e/promise-with-resolvers.test.js.map +1 -0
  190. package/dist/tests/e2e/property-descriptors.test.d.ts +5 -0
  191. package/dist/tests/e2e/property-descriptors.test.js +25 -0
  192. package/dist/tests/e2e/property-descriptors.test.js.map +1 -0
  193. package/dist/tests/e2e/property-ic.test.d.ts +1 -0
  194. package/dist/tests/e2e/property-ic.test.js +55 -0
  195. package/dist/tests/e2e/property-ic.test.js.map +1 -0
  196. package/dist/tests/e2e/runtime-errors.test.d.ts +10 -0
  197. package/dist/tests/e2e/runtime-errors.test.js +52 -0
  198. package/dist/tests/e2e/runtime-errors.test.js.map +1 -0
  199. package/dist/tests/e2e/structured-clone.test.d.ts +6 -0
  200. package/dist/tests/e2e/structured-clone.test.js +49 -0
  201. package/dist/tests/e2e/structured-clone.test.js.map +1 -0
  202. package/dist/tests/e2e/text-codec.test.d.ts +6 -0
  203. package/dist/tests/e2e/text-codec.test.js +24 -0
  204. package/dist/tests/e2e/text-codec.test.js.map +1 -0
  205. package/dist/tests/e2e/typed-array-views.test.d.ts +6 -0
  206. package/dist/tests/e2e/typed-array-views.test.js +39 -0
  207. package/dist/tests/e2e/typed-array-views.test.js.map +1 -0
  208. package/dist/tests/e2e/url-search-params.test.d.ts +5 -0
  209. package/dist/tests/e2e/url-search-params.test.js +30 -0
  210. package/dist/tests/e2e/url-search-params.test.js.map +1 -0
  211. package/dist/tests/e2e/weak-collections.test.d.ts +1 -0
  212. package/dist/tests/e2e/weak-collections.test.js +88 -0
  213. package/dist/tests/e2e/weak-collections.test.js.map +1 -0
  214. package/dist/tests/parser/declarations.test.js +12 -0
  215. package/dist/tests/parser/declarations.test.js.map +1 -1
  216. package/dist/tests/parser/module-syntax.test.js +9 -0
  217. package/dist/tests/parser/module-syntax.test.js.map +1 -1
  218. package/dist/tests/parser/parser.test.js +7 -0
  219. package/dist/tests/parser/parser.test.js.map +1 -1
  220. package/dist/tests/version.test.js +5 -1
  221. package/dist/tests/version.test.js.map +1 -1
  222. package/doc/ai/README.md +4 -3
  223. package/doc/ai/cli.md +41 -0
  224. package/doc/ai/contributing.md +20 -16
  225. package/doc/ai/extensions.md +13 -10
  226. package/doc/ai/language-support.md +19 -14
  227. package/doc/ai/troubleshooting.md +11 -9
  228. package/doc/ai/zh-CN/README.md +3 -2
  229. package/doc/ai/zh-CN/cli.md +35 -0
  230. package/doc/ai/zh-CN/contributing.md +16 -15
  231. package/doc/ai/zh-CN/extensions.md +12 -9
  232. package/doc/ai/zh-CN/language-support.md +19 -15
  233. package/doc/ai/zh-CN/troubleshooting.md +9 -8
  234. package/doc/gui/api.md +8 -0
  235. package/doc/gui/build.md +13 -4
  236. package/doc/gui/known-issues.md +19 -14
  237. package/doc/gui/media.md +32 -3
  238. package/doc/gui/rendering.md +3 -1
  239. package/doc/gui.md +28 -5
  240. package/doc/icon.md +5 -4
  241. package/doc/implemented/async.md +51 -0
  242. package/doc/implemented/binder.md +13 -0
  243. package/doc/implemented/cli.md +47 -0
  244. package/doc/implemented/codegen.md +33 -0
  245. package/doc/implemented/collections.md +26 -0
  246. package/doc/implemented/driver.md +19 -0
  247. package/doc/implemented/extensions.md +19 -0
  248. package/doc/implemented/fetch.md +44 -0
  249. package/doc/implemented/lexer.md +23 -0
  250. package/doc/implemented/modules.md +28 -0
  251. package/doc/implemented/node/assert.md +17 -0
  252. package/doc/implemented/node/buffer.md +29 -0
  253. package/doc/implemented/node/child-process.md +29 -0
  254. package/doc/implemented/node/crypto.md +9 -0
  255. package/doc/implemented/node/dgram.md +15 -0
  256. package/doc/implemented/node/events.md +37 -0
  257. package/doc/implemented/node/fs-promises.md +49 -0
  258. package/doc/implemented/node/fs.md +112 -0
  259. package/doc/implemented/node/http.md +21 -0
  260. package/doc/implemented/node/net.md +17 -0
  261. package/doc/implemented/node/os.md +22 -0
  262. package/doc/implemented/node/path.md +33 -0
  263. package/doc/implemented/node/process.md +23 -0
  264. package/doc/implemented/node/querystring.md +20 -0
  265. package/doc/implemented/node/stream-promises.md +8 -0
  266. package/doc/implemented/node/stream.md +19 -0
  267. package/doc/implemented/node/test.md +10 -0
  268. package/doc/implemented/node/url.md +8 -0
  269. package/doc/implemented/node/util.md +25 -0
  270. package/doc/implemented/node/worker-threads.md +10 -0
  271. package/doc/implemented/node/zlib.md +8 -0
  272. package/doc/implemented/node.md +48 -0
  273. package/doc/implemented/operators.md +38 -0
  274. package/doc/implemented/parser.md +58 -0
  275. package/doc/implemented/pipeline.md +28 -0
  276. package/doc/implemented/runtime-core.md +32 -0
  277. package/doc/implemented/stdlib.md +78 -0
  278. package/doc/implemented/strings.md +27 -0
  279. package/doc/implemented/tests.md +10 -0
  280. package/doc/implemented/typed-arrays.md +26 -0
  281. package/doc/implemented/value-model.md +18 -0
  282. package/doc/implemented.md +54 -355
  283. package/doc/node-implemented.md +3 -585
  284. package/doc/node-unimplemented.md +3 -164
  285. package/doc/requirements.md +23 -8
  286. package/doc/unimplemented/classes.md +22 -0
  287. package/doc/unimplemented/deviations.md +27 -0
  288. package/doc/unimplemented/expressions.md +26 -0
  289. package/doc/unimplemented/functions.md +21 -0
  290. package/doc/unimplemented/modules.md +22 -0
  291. package/doc/unimplemented/node/async.md +20 -0
  292. package/doc/unimplemented/node/bun.md +9 -0
  293. package/doc/unimplemented/node/fs-promises.md +20 -0
  294. package/doc/unimplemented/node/fs.md +30 -0
  295. package/doc/unimplemented/node/globals.md +23 -0
  296. package/doc/unimplemented/node/modules.md +21 -0
  297. package/doc/unimplemented/node.md +21 -0
  298. package/doc/unimplemented/statements.md +18 -0
  299. package/doc/unimplemented/stdlib.md +54 -0
  300. package/doc/unimplemented/toolchain.md +14 -0
  301. package/doc/unimplemented/types.md +12 -0
  302. package/doc/unimplemented.md +18 -275
  303. package/doc/xbintsc.config.schema.json +12 -0
  304. package/doc/zh-CN/gui/api.md +7 -0
  305. package/doc/zh-CN/gui/build.md +11 -3
  306. package/doc/zh-CN/gui/known-issues.md +17 -11
  307. package/doc/zh-CN/gui/media.md +26 -2
  308. package/doc/zh-CN/gui/rendering.md +2 -1
  309. package/doc/zh-CN/gui.md +21 -3
  310. package/doc/zh-CN/icon.md +5 -4
  311. package/doc/zh-CN/implemented/async.md +49 -0
  312. package/doc/zh-CN/implemented/binder.md +13 -0
  313. package/doc/zh-CN/implemented/cli.md +46 -0
  314. package/doc/zh-CN/implemented/codegen.md +33 -0
  315. package/doc/zh-CN/implemented/collections.md +26 -0
  316. package/doc/zh-CN/implemented/driver.md +19 -0
  317. package/doc/zh-CN/implemented/extensions.md +19 -0
  318. package/doc/zh-CN/implemented/fetch.md +31 -0
  319. package/doc/zh-CN/implemented/lexer.md +23 -0
  320. package/doc/zh-CN/implemented/modules.md +28 -0
  321. package/doc/zh-CN/implemented/node/assert.md +17 -0
  322. package/doc/zh-CN/implemented/node/buffer.md +25 -0
  323. package/doc/zh-CN/implemented/node/child-process.md +27 -0
  324. package/doc/zh-CN/implemented/node/crypto.md +9 -0
  325. package/doc/zh-CN/implemented/node/dgram.md +15 -0
  326. package/doc/zh-CN/implemented/node/events.md +36 -0
  327. package/doc/zh-CN/implemented/node/fs-promises.md +30 -0
  328. package/doc/zh-CN/implemented/node/fs.md +105 -0
  329. package/doc/zh-CN/implemented/node/http.md +17 -0
  330. package/doc/zh-CN/implemented/node/net.md +17 -0
  331. package/doc/zh-CN/implemented/node/os.md +21 -0
  332. package/doc/zh-CN/implemented/node/path.md +26 -0
  333. package/doc/zh-CN/implemented/node/process.md +23 -0
  334. package/doc/zh-CN/implemented/node/querystring.md +20 -0
  335. package/doc/zh-CN/implemented/node/stream-promises.md +8 -0
  336. package/doc/zh-CN/implemented/node/stream.md +15 -0
  337. package/doc/zh-CN/implemented/node/test.md +10 -0
  338. package/doc/zh-CN/implemented/node/url.md +8 -0
  339. package/doc/zh-CN/implemented/node/util.md +25 -0
  340. package/doc/zh-CN/implemented/node/worker-threads.md +9 -0
  341. package/doc/zh-CN/implemented/node/zlib.md +8 -0
  342. package/doc/zh-CN/implemented/node.md +45 -0
  343. package/doc/zh-CN/implemented/operators.md +38 -0
  344. package/doc/zh-CN/implemented/parser.md +58 -0
  345. package/doc/zh-CN/implemented/pipeline.md +25 -0
  346. package/doc/zh-CN/implemented/runtime-core.md +31 -0
  347. package/doc/zh-CN/implemented/stdlib.md +76 -0
  348. package/doc/zh-CN/implemented/strings.md +27 -0
  349. package/doc/zh-CN/implemented/tests.md +10 -0
  350. package/doc/zh-CN/implemented/typed-arrays.md +26 -0
  351. package/doc/zh-CN/implemented/value-model.md +18 -0
  352. package/doc/zh-CN/implemented.md +50 -350
  353. package/doc/zh-CN/node-implemented.md +4 -531
  354. package/doc/zh-CN/node-unimplemented.md +4 -139
  355. package/doc/zh-CN/plan-require-node-modules.md +4 -4
  356. package/doc/zh-CN/requirements.md +20 -6
  357. package/doc/zh-CN/unimplemented/classes.md +22 -0
  358. package/doc/zh-CN/unimplemented/deviations.md +24 -0
  359. package/doc/zh-CN/unimplemented/expressions.md +24 -0
  360. package/doc/zh-CN/unimplemented/functions.md +21 -0
  361. package/doc/zh-CN/unimplemented/modules.md +19 -0
  362. package/doc/zh-CN/unimplemented/node/async.md +20 -0
  363. package/doc/zh-CN/unimplemented/node/bun.md +8 -0
  364. package/doc/zh-CN/unimplemented/node/fs-promises.md +12 -0
  365. package/doc/zh-CN/unimplemented/node/fs.md +24 -0
  366. package/doc/zh-CN/unimplemented/node/globals.md +14 -0
  367. package/doc/zh-CN/unimplemented/node/modules.md +15 -0
  368. package/doc/zh-CN/unimplemented/node.md +18 -0
  369. package/doc/zh-CN/unimplemented/statements.md +15 -0
  370. package/doc/zh-CN/unimplemented/stdlib.md +54 -0
  371. package/doc/zh-CN/unimplemented/toolchain.md +14 -0
  372. package/doc/zh-CN/unimplemented/types.md +11 -0
  373. package/doc/zh-CN/unimplemented.md +14 -237
  374. package/llms.txt +32 -4
  375. package/package.json +1 -1
  376. package/runtime/ext_gui/inline_svg.cpp +219 -0
  377. package/runtime/ext_gui/inline_svg.h +41 -0
  378. package/runtime/ext_gui/layout.cpp +18 -0
  379. package/runtime/ext_gui/layout.h +7 -0
  380. package/runtime/ext_gui/layout_flow.cpp +4 -3
  381. package/runtime/ext_gui/paint.cpp +14 -0
  382. package/runtime/ext_gui/paint.h +5 -1
  383. package/runtime/ext_gui/renderer_image.cpp +53 -25
  384. package/runtime/ext_gui/renderer_shaders.h +2 -2
  385. package/runtime/ext_gui/stb_image.h +1 -17
  386. package/runtime/ext_gui/style_ua.cpp +3 -0
  387. package/runtime/ext_gui/svg.cpp +122 -39
  388. package/runtime/ext_gui/svg.h +14 -3
  389. package/runtime/ext_gui/window.cpp +28 -0
  390. package/runtime/ext_node/child_process/child_process.c +173 -73
  391. package/runtime/ext_node/fs/async_api.c +314 -0
  392. package/runtime/ext_node/fs/async_complete.c +99 -0
  393. package/runtime/ext_node/fs/async_fh.c +206 -0
  394. package/runtime/ext_node/fs/async_job.c +81 -0
  395. package/runtime/ext_node/fs/async_job.h +132 -0
  396. package/runtime/ext_node/fs/async_worker.c +534 -0
  397. package/runtime/ext_node/fs/async_worker_dir.c +439 -0
  398. package/runtime/ext_node/fs/async_worker_dir.h +33 -0
  399. package/runtime/ext_node/fs/async_worker_fd.c +74 -0
  400. package/runtime/ext_node/fs/dir.c +60 -15
  401. package/runtime/ext_node/fs/fs_common.h +9 -0
  402. package/runtime/ext_node/fs/fs_ops.c +18 -29
  403. package/runtime/ext_node/fs/parts/builtins.inc +34 -0
  404. package/runtime/ext_node/fs/parts/platform.inc +66 -0
  405. package/runtime/ext_node/fs/promises.c +44 -234
  406. package/runtime/rt.h +15 -0
  407. package/runtime/rt_internal.h +108 -0
  408. package/runtime/xt_alloc.c +43 -7
  409. package/runtime/xt_array_buffer.c +284 -0
  410. package/runtime/xt_async.c +46 -21
  411. package/runtime/xt_async_io.c +333 -0
  412. package/runtime/xt_async_io.h +47 -0
  413. package/runtime/xt_bigint/helpers.inc +3 -3
  414. package/runtime/xt_builtins.c +21 -17
  415. package/runtime/xt_constructors.c +12 -2
  416. package/runtime/xt_containers/access.inc +148 -3
  417. package/runtime/xt_containers/objects.inc +26 -2
  418. package/runtime/xt_containers/shapes.inc +71 -0
  419. package/runtime/xt_containers.c +1 -0
  420. package/runtime/xt_coroutine.c +17 -0
  421. package/runtime/xt_fetch/async.inc +295 -0
  422. package/runtime/xt_fetch/request.inc +6 -183
  423. package/runtime/xt_fetch/socket.inc +5 -4
  424. package/runtime/xt_fetch.c +6 -4
  425. package/runtime/xt_generator.c +299 -10
  426. package/runtime/xt_io/inspect.inc +112 -0
  427. package/runtime/xt_loop.c +79 -7
  428. package/runtime/xt_performance.c +37 -0
  429. package/runtime/xt_promise.c +63 -1
  430. package/runtime/xt_stdlib/arrays.inc +1 -1
  431. package/runtime/xt_stdlib/dispatch.inc +46 -11
  432. package/runtime/xt_stdlib/strings.inc +1 -1
  433. package/runtime/xt_stdlib2/array-statics.inc +25 -0
  434. package/runtime/xt_stdlib2/arrays.inc +5 -3
  435. package/runtime/xt_stdlib2/container.inc +5 -0
  436. package/runtime/xt_stdlib2/date.inc +111 -3
  437. package/runtime/xt_stdlib2/error.inc +24 -0
  438. package/runtime/xt_stdlib2/json.inc +310 -19
  439. package/runtime/xt_stdlib2/number-string-statics.inc +1 -1
  440. package/runtime/xt_stdlib2/objects.inc +122 -0
  441. package/runtime/xt_stdlib2/set.inc +1 -1
  442. package/runtime/xt_structured_clone.c +159 -0
  443. package/runtime/xt_symbol.c +2 -2
  444. package/runtime/xt_text_codec.c +69 -0
  445. package/runtime/xt_typed_array/construction.inc +35 -5
  446. package/runtime/xt_typed_array/elements.inc +159 -0
  447. package/runtime/xt_typed_array/methods.inc +21 -5
  448. package/runtime/xt_typed_array.c +7 -10
  449. package/runtime/xt_url.c +375 -0
  450. package/runtime/xt_values/arithmetic.inc +2 -2
  451. package/runtime/xt_values/conversions.inc +1 -1
  452. package/runtime/xt_weak.c +281 -0
  453. package/scripts/build-gui.ts +133 -60
  454. package/scripts/check-version.ts +3 -3
  455. package/src/binder/declarations.ts +14 -3
  456. package/src/cli/hints.ts +8 -1
  457. package/src/cli/main.ts +119 -18
  458. package/src/cli/watch.ts +101 -0
  459. package/src/codegen/generator/calls/access.ts +10 -2
  460. package/src/codegen/generator/calls/closures.ts +12 -4
  461. package/src/codegen/generator/context.ts +23 -3
  462. package/src/codegen/generator/expressions/operators.ts +27 -13
  463. package/src/codegen/generator/expressions/primary.ts +4 -0
  464. package/src/codegen/generator/module.ts +0 -7
  465. package/src/codegen/generator/numeric.ts +85 -11
  466. package/src/codegen/generator/state.ts +23 -0
  467. package/src/codegen/generator/statements/control-flow.ts +1 -4
  468. package/src/codegen/generator/statements/loops.ts +50 -16
  469. package/src/codegen/generator/tables.ts +26 -1
  470. package/src/diagnostics/diagnostic.ts +23 -3
  471. package/src/driver/app-artifacts.ts +77 -0
  472. package/src/driver/build-key.ts +55 -0
  473. package/src/driver/bundler/graph.ts +63 -13
  474. package/src/driver/bundler/merge.ts +4 -1
  475. package/src/driver/compiler.ts +94 -328
  476. package/src/driver/config.ts +11 -0
  477. package/src/driver/frontend.ts +120 -0
  478. package/src/driver/index.ts +0 -1
  479. package/src/driver/options.ts +70 -0
  480. package/src/driver/runtime-objects.ts +134 -0
  481. package/src/driver/toolchain-provider.ts +4 -0
  482. package/src/driver/toolchain.ts +154 -10
  483. package/src/driver/version.ts +12 -0
  484. package/src/driver/win-icon.ts +36 -36
  485. package/src/extensions/node/fs/index.ts +12 -3
  486. package/src/extensions/node/fs-promises/index.ts +15 -6
  487. package/src/parser/declarations/classes.ts +4 -0
  488. package/src/parser/declarations/functions.ts +12 -1
  489. package/src/parser/modules.ts +8 -4
  490. package/src/parser/parser.ts +28 -0
@@ -23,6 +23,7 @@
23
23
  #include <fcntl.h>
24
24
  #include <io.h>
25
25
  #include <process.h>
26
+ #include <windows.h>
26
27
  #else
27
28
  #include <poll.h>
28
29
  #include <sys/wait.h>
@@ -69,38 +70,115 @@ static xt_value make_result(double status, const char *out, const char *err) {
69
70
 
70
71
  #if defined(_WIN32)
71
72
 
72
- static char *read_temp(FILE *file) {
73
- fflush(file);
74
- if (_fseeki64(file, 0, SEEK_END) != 0) return NULL;
75
- long long size = _ftelli64(file);
76
- if (size < 0) return NULL;
77
- _fseeki64(file, 0, SEEK_SET);
78
- char *buffer = (char *)malloc((size_t)size + 1);
79
- if (!buffer) return NULL;
80
- size_t read = fread(buffer, 1, (size_t)size, file);
81
- buffer[read] = 0;
82
- return buffer;
83
- }
84
-
85
73
  /*
86
- * MSVC's `_spawnvp` builds the child command line from argv without quoting
87
- * argv[0]. When the executable path contains a space — the default install
88
- * location is "C:\Program Files\…" — the child sees the path split into several
89
- * arguments ("Files\Microsoft", "Visual", …). Quote argv[0] ourselves. Returns
90
- * NULL when no quoting is needed (the caller keeps the original pointer).
74
+ * `spawnSync` captures stdout/stderr through anonymous pipes. Temporary files
75
+ * are deliberately not used: `tmpfile()` creates its file in the root of the
76
+ * current drive on the UCRT, which fails with "Permission denied" on machines
77
+ * where that directory is not writable, and a restricted temp directory makes
78
+ * every `spawnSync` fail as well. Pipes also avoid the pipe-buffer deadlock the
79
+ * old temp-file design was working around, because one reader thread drains
80
+ * each stream while the child runs.
91
81
  */
92
- static char *quote_argv0(char **child_argv) {
93
- const char *arg = child_argv[0];
94
- if (arg == NULL || strchr(arg, ' ') == NULL) return NULL;
95
- size_t length = strlen(arg);
96
- char *quoted = (char *)malloc(length + 3);
97
- if (!quoted) return NULL;
98
- quoted[0] = '"';
99
- memcpy(quoted + 1, arg, length);
100
- quoted[length + 1] = '"';
101
- quoted[length + 2] = 0;
102
- child_argv[0] = quoted;
103
- return quoted;
82
+ typedef struct {
83
+ HANDLE read;
84
+ char *data;
85
+ size_t length;
86
+ size_t capacity;
87
+ } CapturePipe;
88
+
89
+ static void capture_append(CapturePipe *pipe, const char *chunk, size_t count) {
90
+ if (pipe->length + count + 1 > pipe->capacity) {
91
+ size_t next = pipe->capacity ? pipe->capacity * 2 : 4096;
92
+ while (next < pipe->length + count + 1) next *= 2;
93
+ char *grown = (char *)realloc(pipe->data, next);
94
+ if (!grown) return;
95
+ pipe->data = grown;
96
+ pipe->capacity = next;
97
+ }
98
+ memcpy(pipe->data + pipe->length, chunk, count);
99
+ pipe->length += count;
100
+ pipe->data[pipe->length] = 0;
101
+ }
102
+
103
+ static DWORD WINAPI capture_thread(LPVOID parameter) {
104
+ CapturePipe *pipe = (CapturePipe *)parameter;
105
+ char chunk[4096];
106
+ DWORD got = 0;
107
+ while (ReadFile(pipe->read, chunk, sizeof(chunk), &got, NULL) && got > 0) {
108
+ capture_append(pipe, chunk, (size_t)got);
109
+ }
110
+ return 0;
111
+ }
112
+
113
+ static int create_capture_pipe(CapturePipe *pipe, HANDLE *write_end) {
114
+ SECURITY_ATTRIBUTES attributes;
115
+ HANDLE read_handle = NULL;
116
+ HANDLE write_handle = NULL;
117
+ attributes.nLength = sizeof(attributes);
118
+ attributes.lpSecurityDescriptor = NULL;
119
+ attributes.bInheritHandle = TRUE;
120
+ if (!CreatePipe(&read_handle, &write_handle, &attributes, 0)) return 0;
121
+ /* The child inherits the write end only. */
122
+ SetHandleInformation(read_handle, HANDLE_FLAG_INHERIT, 0);
123
+ pipe->read = read_handle;
124
+ pipe->data = NULL;
125
+ pipe->length = 0;
126
+ pipe->capacity = 0;
127
+ *write_end = write_handle;
128
+ return 1;
129
+ }
130
+
131
+ static void close_capture_pipe(CapturePipe *pipe) {
132
+ if (pipe->read != NULL) CloseHandle(pipe->read);
133
+ free(pipe->data);
134
+ pipe->read = NULL;
135
+ pipe->data = NULL;
136
+ pipe->length = 0;
137
+ pipe->capacity = 0;
138
+ }
139
+
140
+ /* Quote one argument following the CommandLineToArgvW/MSVC rules. */
141
+ static char *append_quoted_argument(char *out, const char *argument) {
142
+ if (*argument != 0 && strpbrk(argument, " \t\n\v\"") == NULL) {
143
+ size_t length = strlen(argument);
144
+ memcpy(out, argument, length);
145
+ return out + length;
146
+ }
147
+ *out++ = '"';
148
+ const char *cursor = argument;
149
+ for (;;) {
150
+ size_t backslashes = 0;
151
+ while (*cursor == '\\') {
152
+ cursor++;
153
+ backslashes++;
154
+ }
155
+ if (*cursor == 0) {
156
+ for (size_t i = 0; i < backslashes * 2; i++) *out++ = '\\';
157
+ *out++ = '"';
158
+ return out;
159
+ }
160
+ if (*cursor == '"') {
161
+ for (size_t i = 0; i < backslashes * 2 + 1; i++) *out++ = '\\';
162
+ } else {
163
+ for (size_t i = 0; i < backslashes; i++) *out++ = '\\';
164
+ }
165
+ *out++ = *cursor++;
166
+ }
167
+ }
168
+
169
+ /* Build the child command line; every argv element is quoted as needed. */
170
+ static char *build_command_line(char **child_argv, int count) {
171
+ size_t capacity = 1;
172
+ for (int i = 0; i < count; i++) capacity += strlen(child_argv[i]) * 2 + 4;
173
+ char *line = (char *)malloc(capacity);
174
+ if (!line) return NULL;
175
+ char *cursor = line;
176
+ for (int i = 0; i < count; i++) {
177
+ if (i > 0) *cursor++ = ' ';
178
+ cursor = append_quoted_argument(cursor, child_argv[i]);
179
+ }
180
+ *cursor = 0;
181
+ return line;
104
182
  }
105
183
 
106
184
  xt_value xt_child_process_spawn_sync(int32_t argc, xt_value *argv) {
@@ -112,60 +190,82 @@ xt_value xt_child_process_spawn_sync(int32_t argc, xt_value *argv) {
112
190
  int count = 0;
113
191
  char **child_argv = (char **)build_argv(command, args, &count);
114
192
  if (!child_argv) return make_result(-1, "", "out of memory");
115
- char *quoted_command = quote_argv0(child_argv);
193
+ char *command_line = build_command_line(child_argv, count);
194
+ if (!command_line) {
195
+ free(child_argv);
196
+ return make_result(-1, "", "out of memory");
197
+ }
116
198
 
117
- char previous[4096];
118
- int had_cwd = cwd && _getcwd(previous, sizeof(previous)) != NULL;
199
+ STARTUPINFOA startup;
200
+ PROCESS_INFORMATION process;
201
+ ZeroMemory(&startup, sizeof(startup));
202
+ ZeroMemory(&process, sizeof(process));
203
+ startup.cb = sizeof(startup);
119
204
 
120
205
  if (option_stdio_inherit(argc > 2 ? argv[2] : XT_UNDEFINED)) {
121
- if (cwd) _chdir(cwd);
122
- intptr_t inherit_rc = _spawnvp(_P_WAIT, command, (const char *const *)child_argv);
123
- if (had_cwd) _chdir(previous);
124
- free(quoted_command);
206
+ BOOL created = CreateProcessA(
207
+ NULL, command_line, NULL, NULL, TRUE, 0, NULL, cwd, &startup, &process);
208
+ free(command_line);
125
209
  free(child_argv);
126
- return make_result(inherit_rc < 0 ? -1 : (double)inherit_rc, "", "");
210
+ if (!created) return make_result(-1, "", "failed to start process");
211
+ WaitForSingleObject(process.hProcess, INFINITE);
212
+ DWORD exit_code = 0;
213
+ GetExitCodeProcess(process.hProcess, &exit_code);
214
+ CloseHandle(process.hThread);
215
+ CloseHandle(process.hProcess);
216
+ return make_result((double)exit_code, "", "");
127
217
  }
128
218
 
129
- FILE *out_file = tmpfile();
130
- FILE *err_file = tmpfile();
131
- if (!out_file || !err_file) {
132
- free(quoted_command);
219
+ CapturePipe out_pipe;
220
+ CapturePipe err_pipe;
221
+ ZeroMemory(&out_pipe, sizeof(out_pipe));
222
+ ZeroMemory(&err_pipe, sizeof(err_pipe));
223
+ HANDLE out_write = NULL;
224
+ HANDLE err_write = NULL;
225
+ if (!create_capture_pipe(&out_pipe, &out_write) || !create_capture_pipe(&err_pipe, &err_write)) {
226
+ if (out_write != NULL) CloseHandle(out_write);
227
+ if (err_write != NULL) CloseHandle(err_write);
228
+ close_capture_pipe(&out_pipe);
229
+ close_capture_pipe(&err_pipe);
230
+ free(command_line);
133
231
  free(child_argv);
134
- if (out_file) fclose(out_file);
135
- if (err_file) fclose(err_file);
136
- return make_result(-1, "", "could not create temporary files");
232
+ return make_result(-1, "", "could not create pipes");
137
233
  }
234
+ startup.dwFlags = STARTF_USESTDHANDLES;
235
+ startup.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
236
+ startup.hStdOutput = out_write;
237
+ startup.hStdError = err_write;
138
238
 
139
- /* Flush anything the parent has already buffered on stdout/stderr before
140
- * redirecting the descriptors; otherwise that pending output would be
141
- * flushed into the child's capture file (and lost from the real stdout). */
142
- fflush(stdout);
143
- fflush(stderr);
144
- int saved_out = _dup(_fileno(stdout));
145
- int saved_err = _dup(_fileno(stderr));
146
- _dup2(_fileno(out_file), _fileno(stdout));
147
- _dup2(_fileno(err_file), _fileno(stderr));
148
-
149
- if (cwd) _chdir(cwd);
150
- intptr_t rc = _spawnvp(_P_WAIT, command, (const char *const *)child_argv);
151
- if (had_cwd) _chdir(previous);
152
- fflush(stdout);
153
- fflush(stderr);
154
- _dup2(saved_out, _fileno(stdout));
155
- _dup2(saved_err, _fileno(stderr));
156
- _close(saved_out);
157
- _close(saved_err);
158
-
159
- char *out = read_temp(out_file);
160
- char *err = read_temp(err_file);
161
- fclose(out_file);
162
- fclose(err_file);
163
- free(quoted_command);
239
+ BOOL created = CreateProcessA(
240
+ NULL, command_line, NULL, NULL, TRUE, 0, NULL, cwd, &startup, &process);
241
+ free(command_line);
164
242
  free(child_argv);
243
+ CloseHandle(out_write);
244
+ CloseHandle(err_write);
245
+ if (!created) {
246
+ close_capture_pipe(&out_pipe);
247
+ close_capture_pipe(&err_pipe);
248
+ return make_result(-1, "", "failed to start process");
249
+ }
250
+
251
+ CloseHandle(process.hThread);
252
+ HANDLE threads[2];
253
+ threads[0] = CreateThread(NULL, 0, capture_thread, &out_pipe, 0, NULL);
254
+ threads[1] = CreateThread(NULL, 0, capture_thread, &err_pipe, 0, NULL);
255
+ for (int i = 0; i < 2; i++) {
256
+ if (threads[i] != NULL) WaitForSingleObject(threads[i], INFINITE);
257
+ }
258
+ WaitForSingleObject(process.hProcess, INFINITE);
259
+ DWORD exit_code = 0;
260
+ GetExitCodeProcess(process.hProcess, &exit_code);
261
+ CloseHandle(process.hProcess);
262
+ for (int i = 0; i < 2; i++) {
263
+ if (threads[i] != NULL) CloseHandle(threads[i]);
264
+ }
165
265
 
166
- xt_value result = make_result(rc < 0 ? -1 : (double)rc, out, err);
167
- free(out);
168
- free(err);
266
+ xt_value result = make_result((double)exit_code, out_pipe.data, err_pipe.data);
267
+ close_capture_pipe(&out_pipe);
268
+ close_capture_pipe(&err_pipe);
169
269
  return result;
170
270
  }
171
271
 
@@ -0,0 +1,314 @@
1
+ /*
2
+ * Main-thread argument marshalling for asynchronous `fs/promises`.
3
+ *
4
+ * Each export copies whatever it needs from the JavaScript values (paths,
5
+ * encodings, buffers, options) into a job, then submits it. The blocking half
6
+ * runs on a worker; the promise is settled later on the reactor thread. This is
7
+ * also where the non-I/O argument parsing matches the synchronous `fs` module.
8
+ */
9
+
10
+ #include "async_job.h"
11
+
12
+ #include <errno.h>
13
+
14
+ static int xt_fs_option_bool(xt_value options, const char *key, int fallback) {
15
+ if (!XT_IS_OBJECT(options)) return fallback;
16
+ xt_value value = xt_object_get_cstr(options, key);
17
+ if (XT_IS_UNDEFINED(value) || XT_IS_NULL(value)) return fallback;
18
+ return xt_truthy(value);
19
+ }
20
+
21
+ static int xt_fs_option_recursive(xt_value options) {
22
+ if (!xt_truthy(options)) return 0;
23
+ if (XT_IS_OBJECT(options)) return xt_truthy(xt_object_get_cstr(options, "recursive"));
24
+ return 1;
25
+ }
26
+
27
+ /* -- file contents --------------------------------------------------------- */
28
+
29
+ xt_value xt_node_p_read_file(int32_t argc, xt_value *argv) {
30
+ if (argc < 1) return xt_promise_resolve(XT_UNDEFINED);
31
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_READ_FILE);
32
+ job->path = xt_fs_take_string(argv[0]);
33
+ job->text = xt_fs_copy_cstr(argc > 1 ? xt_fs_encoding(argv[1]) : NULL);
34
+ return xt_fs_job_submit(job);
35
+ }
36
+
37
+ static xt_value xt_fs_write(int32_t argc, xt_value *argv, int append) {
38
+ if (argc < 2) return xt_promise_resolve(XT_UNDEFINED);
39
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_WRITE_FILE);
40
+ job->path = xt_fs_take_string(argv[0]);
41
+ job->flags = append;
42
+ if (xt_node_is_buffer(argv[1])) {
43
+ job->data = xt_node_buffer_bytes(argv[1], &job->data_length);
44
+ } else {
45
+ xt_value text = xt_to_string(argv[1]);
46
+ const char *data = xt_string_data(text);
47
+ int32_t length = xt_string_length_value(text);
48
+ if (data && length >= 0) {
49
+ const char *encoding = argc > 2 ? xt_fs_encoding(argv[2]) : NULL;
50
+ job->data = xt_fs_decode_text(data, (size_t)length, encoding, &job->data_length);
51
+ }
52
+ }
53
+ return xt_fs_job_submit(job);
54
+ }
55
+
56
+ xt_value xt_node_p_write_file(int32_t argc, xt_value *argv) { return xt_fs_write(argc, argv, 0); }
57
+
58
+ xt_value xt_node_p_append_file(int32_t argc, xt_value *argv) { return xt_fs_write(argc, argv, 1); }
59
+
60
+ /* -- directories ----------------------------------------------------------- */
61
+
62
+ xt_value xt_node_p_mkdir(int32_t argc, xt_value *argv) {
63
+ if (argc < 1) return xt_promise_resolve(XT_UNDEFINED);
64
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_MKDIR);
65
+ job->path = xt_fs_take_string(argv[0]);
66
+ job->mode = 0777;
67
+ xt_value options = argc > 1 ? argv[1] : XT_UNDEFINED;
68
+ if (XT_IS_OBJECT(options) && !XT_IS_UNDEFINED(xt_object_get_cstr(options, "mode"))) {
69
+ job->mode = (int)xt_to_number(xt_object_get_cstr(options, "mode"));
70
+ }
71
+ job->recursive = argc > 1 && xt_fs_option_recursive(options);
72
+ return xt_fs_job_submit(job);
73
+ }
74
+
75
+ xt_value xt_node_p_readdir(int32_t argc, xt_value *argv) {
76
+ if (argc < 1) return xt_promise_resolve(XT_UNDEFINED);
77
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_READDIR);
78
+ job->path = xt_fs_take_string(argv[0]);
79
+ xt_value options = argc > 1 ? argv[1] : XT_UNDEFINED;
80
+ job->with_types = xt_fs_option_bool(options, "withFileTypes", 0);
81
+ job->recursive = xt_fs_option_bool(options, "recursive", 0);
82
+ return xt_fs_job_submit(job);
83
+ }
84
+
85
+ xt_value xt_node_p_rm(int32_t argc, xt_value *argv) {
86
+ if (argc < 1) return xt_promise_resolve(XT_UNDEFINED);
87
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_RM);
88
+ job->path = xt_fs_take_string(argv[0]);
89
+ job->recursive = argc > 1 && xt_fs_option_recursive(argv[1]);
90
+ job->force = xt_fs_option_bool(argc > 1 ? argv[1] : XT_UNDEFINED, "force", 0);
91
+ return xt_fs_job_submit(job);
92
+ }
93
+
94
+ xt_value xt_node_p_unlink(int32_t argc, xt_value *argv) {
95
+ if (argc < 1) return xt_promise_resolve(XT_UNDEFINED);
96
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_UNLINK);
97
+ job->path = xt_fs_take_string(argv[0]);
98
+ return xt_fs_job_submit(job);
99
+ }
100
+
101
+ xt_value xt_node_p_rmdir(int32_t argc, xt_value *argv) {
102
+ if (argc < 1) return xt_promise_resolve(XT_UNDEFINED);
103
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_RMDIR);
104
+ job->path = xt_fs_take_string(argv[0]);
105
+ return xt_fs_job_submit(job);
106
+ }
107
+
108
+ xt_value xt_node_p_rename(int32_t argc, xt_value *argv) {
109
+ if (argc < 2) return xt_promise_resolve(XT_UNDEFINED);
110
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_RENAME);
111
+ job->path = xt_fs_take_string(argv[0]);
112
+ job->path2 = xt_fs_take_string(argv[1]);
113
+ return xt_fs_job_submit(job);
114
+ }
115
+
116
+ xt_value xt_node_p_copy_file(int32_t argc, xt_value *argv) {
117
+ if (argc < 2) return xt_promise_resolve(XT_UNDEFINED);
118
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_COPY_FILE);
119
+ job->path = xt_fs_take_string(argv[0]);
120
+ job->path2 = xt_fs_take_string(argv[1]);
121
+ job->flags = argc > 2 ? (int)xt_to_number(argv[2]) : 0;
122
+ return xt_fs_job_submit(job);
123
+ }
124
+
125
+ xt_value xt_node_p_cp(int32_t argc, xt_value *argv) {
126
+ if (argc < 2) return xt_promise_resolve(XT_UNDEFINED);
127
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_CP);
128
+ job->path = xt_fs_take_string(argv[0]);
129
+ job->path2 = xt_fs_take_string(argv[1]);
130
+ xt_value options = argc > 2 ? argv[2] : XT_UNDEFINED;
131
+ job->recursive = xt_fs_option_bool(options, "recursive", 0);
132
+ job->force = xt_fs_option_bool(options, "force", 1);
133
+ job->error_on_exist = xt_fs_option_bool(options, "errorOnExist", 0);
134
+ job->dereference = xt_fs_option_bool(options, "dereference", 0);
135
+ job->preserve = xt_fs_option_bool(options, "preserveTimestamps", 0);
136
+ return xt_fs_job_submit(job);
137
+ }
138
+
139
+ xt_value xt_node_p_realpath(int32_t argc, xt_value *argv) {
140
+ if (argc < 1) return xt_promise_resolve(XT_UNDEFINED);
141
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_REALPATH);
142
+ job->path = xt_fs_take_string(argv[0]);
143
+ return xt_fs_job_submit(job);
144
+ }
145
+
146
+ /* -- metadata -------------------------------------------------------------- */
147
+
148
+ static xt_value xt_fs_stat_job(xt_fs_job_kind kind, int32_t argc, xt_value *argv) {
149
+ if (argc < 1) return xt_promise_resolve(XT_UNDEFINED);
150
+ xt_fs_job *job = xt_fs_job_new(kind);
151
+ job->path = xt_fs_take_string(argv[0]);
152
+ return xt_fs_job_submit(job);
153
+ }
154
+
155
+ xt_value xt_node_p_stat(int32_t argc, xt_value *argv) {
156
+ return xt_fs_stat_job(XT_FS_JOB_STAT, argc, argv);
157
+ }
158
+
159
+ xt_value xt_node_p_lstat(int32_t argc, xt_value *argv) {
160
+ return xt_fs_stat_job(XT_FS_JOB_LSTAT, argc, argv);
161
+ }
162
+
163
+ xt_value xt_node_p_statfs(int32_t argc, xt_value *argv) {
164
+ return xt_fs_stat_job(XT_FS_JOB_STATFS, argc, argv);
165
+ }
166
+
167
+ xt_value xt_node_p_access(int32_t argc, xt_value *argv) {
168
+ if (argc < 1) return xt_promise_resolve(XT_UNDEFINED);
169
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_ACCESS);
170
+ job->path = xt_fs_take_string(argv[0]);
171
+ job->mode = argc > 1 ? (int)xt_to_number(argv[1]) : F_OK;
172
+ return xt_fs_job_submit(job);
173
+ }
174
+
175
+ xt_value xt_node_p_open(int32_t argc, xt_value *argv) {
176
+ if (argc < 1) return xt_promise_resolve(XT_UNDEFINED);
177
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_OPEN);
178
+ job->path = xt_fs_take_string(argv[0]);
179
+ job->flags = argc > 1 ? xt_fs_parse_flags(argv[1]) : (XT_FS_RDONLY | XT_FS_BINARY_FLAG);
180
+ job->mode = argc > 2 ? (int)xt_to_number(argv[2]) : 0666;
181
+ return xt_fs_job_submit(job);
182
+ }
183
+
184
+ xt_value xt_node_p_chmod(int32_t argc, xt_value *argv) {
185
+ if (argc < 2) return xt_promise_resolve(XT_UNDEFINED);
186
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_CHMOD);
187
+ job->path = xt_fs_take_string(argv[0]);
188
+ job->mode = (int)xt_to_number(argv[1]);
189
+ return xt_fs_job_submit(job);
190
+ }
191
+
192
+ xt_value xt_node_p_lchmod(int32_t argc, xt_value *argv) {
193
+ if (argc < 2) return xt_promise_resolve(XT_UNDEFINED);
194
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_LCHMOD);
195
+ job->path = xt_fs_take_string(argv[0]);
196
+ job->mode = (int)xt_to_number(argv[1]);
197
+ return xt_fs_job_submit(job);
198
+ }
199
+
200
+ static xt_value xt_fs_chown_job(xt_fs_job_kind kind, int32_t argc, xt_value *argv) {
201
+ if (argc < 3) return xt_promise_resolve(XT_UNDEFINED);
202
+ xt_fs_job *job = xt_fs_job_new(kind);
203
+ job->path = xt_fs_take_string(argv[0]);
204
+ job->uid = (int)xt_to_number(argv[1]);
205
+ job->gid = (int)xt_to_number(argv[2]);
206
+ return xt_fs_job_submit(job);
207
+ }
208
+
209
+ xt_value xt_node_p_chown(int32_t argc, xt_value *argv) {
210
+ return xt_fs_chown_job(XT_FS_JOB_CHOWN, argc, argv);
211
+ }
212
+
213
+ xt_value xt_node_p_lchown(int32_t argc, xt_value *argv) {
214
+ return xt_fs_chown_job(XT_FS_JOB_LCHOWN, argc, argv);
215
+ }
216
+
217
+ xt_value xt_node_p_truncate(int32_t argc, xt_value *argv) {
218
+ if (argc < 1) return xt_promise_resolve(XT_UNDEFINED);
219
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_TRUNCATE);
220
+ job->path = xt_fs_take_string(argv[0]);
221
+ job->length = argc > 1 ? (long long)xt_to_number(argv[1]) : 0;
222
+ return xt_fs_job_submit(job);
223
+ }
224
+
225
+ static xt_value xt_fs_utimes_job(xt_fs_job_kind kind, int32_t argc, xt_value *argv) {
226
+ if (argc < 3) return xt_promise_resolve(XT_UNDEFINED);
227
+ xt_fs_job *job = xt_fs_job_new(kind);
228
+ job->path = xt_fs_take_string(argv[0]);
229
+ job->atime = xt_fs_time_seconds(argv[1]);
230
+ job->mtime = xt_fs_time_seconds(argv[2]);
231
+ return xt_fs_job_submit(job);
232
+ }
233
+
234
+ xt_value xt_node_p_utimes(int32_t argc, xt_value *argv) {
235
+ return xt_fs_utimes_job(XT_FS_JOB_UTIMES, argc, argv);
236
+ }
237
+
238
+ xt_value xt_node_p_lutimes(int32_t argc, xt_value *argv) {
239
+ return xt_fs_utimes_job(XT_FS_JOB_LUTIMES, argc, argv);
240
+ }
241
+
242
+ /* -- links and temporary directories --------------------------------------- */
243
+
244
+ xt_value xt_node_p_link(int32_t argc, xt_value *argv) {
245
+ if (argc < 2) return xt_promise_resolve(XT_UNDEFINED);
246
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_LINK);
247
+ job->path = xt_fs_take_string(argv[0]);
248
+ job->path2 = xt_fs_take_string(argv[1]);
249
+ return xt_fs_job_submit(job);
250
+ }
251
+
252
+ xt_value xt_node_p_symlink(int32_t argc, xt_value *argv) {
253
+ if (argc < 2) return xt_promise_resolve(XT_UNDEFINED);
254
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_SYMLINK);
255
+ job->path = xt_fs_take_string(argv[0]);
256
+ job->path2 = xt_fs_take_string(argv[1]);
257
+ job->text = argc > 2 ? xt_fs_take_string(argv[2]) : NULL;
258
+ return xt_fs_job_submit(job);
259
+ }
260
+
261
+ xt_value xt_node_p_readlink(int32_t argc, xt_value *argv) {
262
+ if (argc < 1) return xt_promise_resolve(XT_UNDEFINED);
263
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_READLINK);
264
+ job->path = xt_fs_take_string(argv[0]);
265
+ return xt_fs_job_submit(job);
266
+ }
267
+
268
+ xt_value xt_node_p_mkdtemp(int32_t argc, xt_value *argv) {
269
+ if (argc < 1) return xt_promise_resolve(XT_UNDEFINED);
270
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_MKDTEMP);
271
+ job->path = xt_fs_take_string(argv[0]);
272
+ return xt_fs_job_submit(job);
273
+ }
274
+
275
+ /* -- opendir / glob / watch ------------------------------------------------ */
276
+
277
+ xt_value xt_node_p_opendir(int32_t argc, xt_value *argv) {
278
+ if (argc < 1) return xt_promise_resolve(XT_UNDEFINED);
279
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_OPENDIR);
280
+ job->path = xt_fs_take_string(argv[0]);
281
+ return xt_fs_job_submit(job);
282
+ }
283
+
284
+ xt_value xt_node_p_glob(int32_t argc, xt_value *argv) {
285
+ if (argc < 1) return xt_promise_resolve(XT_UNDEFINED);
286
+ xt_fs_job *job = xt_fs_job_new(XT_FS_JOB_GLOB);
287
+ xt_value pattern = argv[0];
288
+ if (XT_IS_ARRAY(pattern)) {
289
+ int32_t count = (int32_t)xt_to_number(xt_array_length(pattern));
290
+ if (count > 0) {
291
+ job->patterns = (char **)calloc((size_t)count, sizeof(char *));
292
+ if (!job->patterns) abort();
293
+ for (int32_t i = 0; i < count; i++) {
294
+ xt_value item = xt_array_get(pattern, xt_number((double)i));
295
+ if (XT_IS_STRING(item)) {
296
+ job->patterns[job->pattern_count++] = xt_fs_take_string(item);
297
+ }
298
+ }
299
+ }
300
+ } else {
301
+ job->text = xt_fs_take_string(pattern);
302
+ }
303
+ xt_value options = argc > 1 ? argv[1] : XT_UNDEFINED;
304
+ job->with_types = xt_fs_option_bool(options, "withFileTypes", 0);
305
+ xt_value cwd = XT_IS_OBJECT(options) ? xt_object_get_cstr(options, "cwd") : XT_UNDEFINED;
306
+ if (XT_IS_STRING(cwd)) job->path2 = xt_fs_take_string(cwd);
307
+ return xt_fs_job_submit(job);
308
+ }
309
+
310
+ /* There is no real file-watching backend yet; keep the synchronous inert
311
+ * watcher behind an already-settled promise. */
312
+ xt_value xt_node_p_watch(int32_t argc, xt_value *argv) {
313
+ return xt_fs_promisify(xt_node_watch, argc, argv);
314
+ }
@@ -0,0 +1,99 @@
1
+ /*
2
+ * Main-thread half of `fs/promises`: turn worker results into values.
3
+ *
4
+ * Runs on the reactor thread, so `xt_value` construction, promise settlement
5
+ * and the collector are all safe here. Everything the job owns is freed by
6
+ * `xt_fs_job_release` after this returns (except the entry table handed over to
7
+ * a `Dir` object).
8
+ */
9
+
10
+ #include "async_job.h"
11
+
12
+ static void xt_fs_job_resolve(xt_fs_job *job, xt_value value) {
13
+ xt_promise_fulfill(job->base.roots[0], value);
14
+ }
15
+
16
+ static void xt_fs_job_reject(xt_fs_job *job) {
17
+ xt_value error = xt_fs_error_object(job->err, job->syscall, job->error_path);
18
+ xt_promise_reject_value(job->base.roots[0], error);
19
+ }
20
+
21
+ static xt_value xt_fs_statfs_value(const long long *numbers) {
22
+ xt_value object = xt_object_new();
23
+ xt_object_set(object, xt_string_from_cstr("type"), xt_number((double)numbers[0]));
24
+ xt_object_set(object, xt_string_from_cstr("bsize"), xt_number((double)numbers[1]));
25
+ xt_object_set(object, xt_string_from_cstr("blocks"), xt_number((double)numbers[2]));
26
+ xt_object_set(object, xt_string_from_cstr("bfree"), xt_number((double)numbers[3]));
27
+ xt_object_set(object, xt_string_from_cstr("bavail"), xt_number((double)numbers[4]));
28
+ xt_object_set(object, xt_string_from_cstr("files"), xt_number((double)numbers[5]));
29
+ xt_object_set(object, xt_string_from_cstr("ffree"), xt_number((double)numbers[6]));
30
+ return object;
31
+ }
32
+
33
+ static xt_value xt_fs_readdir_value(xt_fs_job *job) {
34
+ xt_value list = xt_array_new(0, NULL);
35
+ for (size_t i = 0; i < job->entry_count; i++) {
36
+ xt_fs_entry *entry = &job->entries[i];
37
+ if (job->with_types) {
38
+ xt_array_push(list, xt_node_dirent_named(entry->bare ? entry->bare : entry->name, entry->mode));
39
+ } else {
40
+ xt_array_push(list, xt_string_from_cstr(entry->name));
41
+ }
42
+ }
43
+ return list;
44
+ }
45
+
46
+ static xt_value xt_fs_glob_value(xt_fs_job *job) {
47
+ xt_value list = xt_array_new(0, NULL);
48
+ for (size_t i = 0; i < job->entry_count; i++) {
49
+ xt_array_push(list, xt_string_from_cstr(job->entries[i].name));
50
+ }
51
+ return list;
52
+ }
53
+
54
+ static xt_value xt_fs_read_bytes_value(xt_fs_job *job) {
55
+ return xt_fs_encode_bytes(job->bytes, job->bytes_length, job->text);
56
+ }
57
+
58
+ static void xt_fs_fd_read_complete(xt_fs_job *job) {
59
+ xt_value buffer = job->base.roots[1];
60
+ uint32_t offset = (uint32_t)job->offset;
61
+ for (size_t i = 0; i < job->bytes_length; i++) {
62
+ xt_node_buffer_set(buffer, offset + (uint32_t)i, job->bytes[i]);
63
+ }
64
+ xt_fs_job_resolve(job, xt_number((double)job->bytes_length));
65
+ }
66
+
67
+ void xt_fs_job_complete(xt_async_job *base) {
68
+ xt_fs_job *job = (xt_fs_job *)base;
69
+ if (job->err) {
70
+ xt_fs_job_reject(job);
71
+ return;
72
+ }
73
+ switch (job->kind) {
74
+ case XT_FS_JOB_READ_FILE:
75
+ case XT_FS_JOB_FD_READ_FILE: xt_fs_job_resolve(job, xt_fs_read_bytes_value(job)); break;
76
+ case XT_FS_JOB_READDIR: xt_fs_job_resolve(job, xt_fs_readdir_value(job)); break;
77
+ case XT_FS_JOB_GLOB: xt_fs_job_resolve(job, xt_fs_glob_value(job)); break;
78
+ case XT_FS_JOB_OPENDIR: {
79
+ xt_value dir = xt_node_dir_from_entries(job->path, job->entries, job->entry_count);
80
+ job->entries = NULL;
81
+ job->entry_count = 0;
82
+ xt_fs_job_resolve(job, dir);
83
+ break;
84
+ }
85
+ case XT_FS_JOB_REALPATH:
86
+ case XT_FS_JOB_READLINK:
87
+ case XT_FS_JOB_MKDTEMP:
88
+ xt_fs_job_resolve(job, job->string ? xt_string_from_cstr(job->string) : XT_UNDEFINED);
89
+ break;
90
+ case XT_FS_JOB_STAT:
91
+ case XT_FS_JOB_LSTAT:
92
+ case XT_FS_JOB_FD_STAT: xt_fs_job_resolve(job, xt_node_stat_result(&job->stat)); break;
93
+ case XT_FS_JOB_STATFS: xt_fs_job_resolve(job, xt_fs_statfs_value(job->numbers)); break;
94
+ case XT_FS_JOB_OPEN: xt_fs_job_resolve(job, xt_fh_new(xt_number((double)job->result_fd))); break;
95
+ case XT_FS_JOB_FD_READ: xt_fs_fd_read_complete(job); break;
96
+ case XT_FS_JOB_FD_WRITE: xt_fs_job_resolve(job, xt_number((double)job->written)); break;
97
+ default: xt_fs_job_resolve(job, XT_UNDEFINED); break;
98
+ }
99
+ }