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
@@ -36,6 +36,5 @@ export {
36
36
  ensureWindowsIconResource,
37
37
  resolveResourceCompiler,
38
38
  type ResourceCompiler,
39
- type ResourceCompilerKind,
40
39
  } from "./win-icon.js";
41
40
  export { bundlePathFor, infoPlist, packageMacApp, type MacBundleOptions } from "./mac-bundle.js";
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Public option and result types for the build driver.
3
+ *
4
+ * They live apart from the orchestration in `compiler.ts` so a feature that
5
+ * adds one option touches this file (and the phase that consumes it) without
6
+ * colliding with unrelated driver work.
7
+ */
8
+
9
+ import type { Diagnostic } from "../diagnostics/diagnostic.js";
10
+ import type { ExtensionRegistry } from "../extensions/registry.js";
11
+ import type { AppConfig } from "./config.js";
12
+ import type { PgoMode, Runner } from "./toolchain.js";
13
+
14
+ /** What `build` produces: an executable, an object file or LLVM IR only. */
15
+ export type EmitKind = "exe" | "obj" | "ir";
16
+
17
+ export interface BuildOptions {
18
+ /** Explicit output path (defaults to the source base name in `outDir`). */
19
+ readonly output?: string;
20
+ readonly outDir?: string;
21
+ readonly optimize?: "0" | "1" | "2" | "3";
22
+ readonly emit?: EmitKind;
23
+ readonly force?: boolean;
24
+ readonly verbose?: boolean;
25
+ readonly cacheDir?: string;
26
+ readonly extensions?: ExtensionRegistry;
27
+ readonly runner?: Runner;
28
+ readonly clang?: string;
29
+ /** Prefer a prebuilt `runtime/lib/<os>-<arch>/*.a` archive when present (default true). */
30
+ readonly preferPrebuilt?: boolean;
31
+ readonly write?: boolean;
32
+ /** Application icon embedded into the binary (shorthand for `app.icon`). */
33
+ readonly icon?: string;
34
+ /** Application metadata: name, icon and macOS bundle settings. */
35
+ readonly app?: AppConfig;
36
+ /** Emit LLVM debug metadata so `-g` produces DWARF/CodeView (default false). */
37
+ readonly debug?: boolean;
38
+ /** Compile the program and runtime to LTO bitcode and link with lld. */
39
+ readonly lto?: boolean;
40
+ /**
41
+ * Profile-guided optimization. `generate` builds an instrumented binary that
42
+ * writes `.profraw` files into `pgoDir`; `use` consumes them.
43
+ */
44
+ readonly pgo?: PgoMode;
45
+ /** Profile directory (default: `<outDir>/pgo`). */
46
+ readonly pgoDir?: string;
47
+ }
48
+
49
+ /** One phase of a build, in milliseconds (reported by `--time`). */
50
+ export interface PhaseTiming {
51
+ readonly phase: "frontend" | "codegen" | "runtime" | "clang" | "link";
52
+ readonly ms: number;
53
+ }
54
+
55
+ export interface BuildResult {
56
+ readonly outputPath: string;
57
+ readonly irPath?: string;
58
+ readonly cached: boolean;
59
+ readonly diagnostics: readonly Diagnostic[];
60
+ readonly ir?: string;
61
+ /** macOS `.app` bundle produced by `app.bundle` (darwin only). */
62
+ readonly bundlePath?: string;
63
+ /** Per-phase timings, collected for `xbintsc build --time`. */
64
+ readonly timings?: readonly PhaseTiming[];
65
+ }
66
+
67
+ export interface CompileStringResult {
68
+ readonly ir: string;
69
+ readonly diagnostics: readonly Diagnostic[];
70
+ }
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Compiling the C runtime (and every extension's C sources) into linkable
3
+ * objects, reusing cached objects keyed by the source/header content hash.
4
+ *
5
+ * `RUNTIME_SOURCES` is the list of core translation units. A feature that adds
6
+ * a runtime file adds one line here and nowhere else.
7
+ */
8
+
9
+ import { existsSync, readFileSync, readdirSync } from "node:fs";
10
+ import { basename, join, resolve } from "node:path";
11
+ import type { ExtensionRegistry } from "../extensions/registry.js";
12
+ import { hashParts } from "./cache.js";
13
+ import { findRuntimeLibrary } from "./runtime-lib.js";
14
+ import { compileC, optimizationFlags, RUNTIME_CFLAGS, type PgoMode, type Runner } from "./toolchain.js";
15
+ import { COMPILER_VERSION } from "./version.js";
16
+
17
+ /** Core runtime translation units (each compiled and cached independently). */
18
+ export const RUNTIME_SOURCES = [
19
+ "xt_alloc.c",
20
+ "xt_values.c",
21
+ "xt_bigint.c",
22
+ "xt_containers.c",
23
+ "xt_weak.c",
24
+ "xt_typed_array.c",
25
+ "xt_stdlib.c",
26
+ "xt_stdlib2.c",
27
+ "xt_promise.c",
28
+ "xt_async.c",
29
+ "xt_loop.c",
30
+ "xt_async_io.c",
31
+ "xt_generator.c",
32
+ "xt_coroutine.c",
33
+ "xt_fetch.c",
34
+ "xt_symbol.c",
35
+ "xt_builtins.c",
36
+ "xt_constructors.c",
37
+ "xt_structured_clone.c",
38
+ "xt_performance.c",
39
+ "xt_text_codec.c",
40
+ "xt_url.c",
41
+ "xt_array_buffer.c",
42
+ "xt_io.c",
43
+ ] as const;
44
+
45
+ export interface RuntimeObjects {
46
+ readonly runtimeObjects: readonly string[];
47
+ readonly extensionObjects: readonly string[];
48
+ /** Pre-built C++/Rust objects and archives contributed by native extensions. */
49
+ readonly nativeObjects: readonly string[];
50
+ }
51
+
52
+ export interface RuntimeObjectsOptions {
53
+ readonly runner: Runner;
54
+ readonly clang: string;
55
+ readonly runtimeDir: string;
56
+ readonly cacheDir: string;
57
+ readonly registry: ExtensionRegistry;
58
+ readonly preferPrebuilt: boolean;
59
+ readonly env: Record<string, string>;
60
+ readonly lto: boolean;
61
+ readonly pgo: PgoMode | undefined;
62
+ readonly pgoDir: string;
63
+ }
64
+
65
+ /**
66
+ * Compile the core runtime and every extension source, reusing cached object
67
+ * files keyed on the C source hash. Returns the object paths to link.
68
+ *
69
+ * When `preferPrebuilt` is set, a shipped static archive
70
+ * (`runtime/lib/<os>-<arch>/{core,ext_<name>}.a`) is used instead of compiling
71
+ * that group's C sources. Missing archives fall back to compiling the sources.
72
+ */
73
+ export function ensureRuntimeObjects(options: RuntimeObjectsOptions): RuntimeObjects {
74
+ const { runner, clang, runtimeDir, cacheDir, registry, preferPrebuilt, env, lto, pgo, pgoDir } = options;
75
+ const optimization = optimizationFlags(lto, pgo, pgoDir);
76
+ /* Runtime objects depend on the shared headers (rt.h/rt_internal.h/...) and
77
+ the `#include`d implementation fragments (`.inc`), so any change to them
78
+ must invalidate every cached object. Hash them all. */
79
+ const headerParts: string[] = [];
80
+ const collectHeaders = (dir: string): void => {
81
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
82
+ const full = join(dir, entry.name);
83
+ if (entry.isDirectory()) collectHeaders(full);
84
+ else if (entry.name.endsWith(".h") || entry.name.endsWith(".inc")) headerParts.push(readFileSync(full, "utf8"));
85
+ }
86
+ };
87
+ collectHeaders(runtimeDir);
88
+ const headerStamp = hashParts(headerParts);
89
+
90
+ const compileOne = (sourcePath: string, tag: string): string => {
91
+ const body = readFileSync(sourcePath, "utf8");
92
+ const key = hashParts([
93
+ "runtime",
94
+ COMPILER_VERSION,
95
+ RUNTIME_CFLAGS.join(" "),
96
+ optimization.join(" "),
97
+ tag,
98
+ headerStamp,
99
+ body,
100
+ clang,
101
+ process.platform,
102
+ ]);
103
+ const objectPath = join(cacheDir, `${tag}-${key}.o`);
104
+ if (!existsSync(objectPath)) {
105
+ compileC(runner, clang, sourcePath, objectPath, runtimeDir, env, optimization);
106
+ }
107
+ return objectPath;
108
+ };
109
+
110
+ const coreArchive = preferPrebuilt ? findRuntimeLibrary("core") : undefined;
111
+ const runtimeObjects = coreArchive
112
+ ? [coreArchive]
113
+ : RUNTIME_SOURCES.map((source) => compileOne(join(runtimeDir, source), basename(source, ".c")));
114
+
115
+ const extensionObjects: string[] = [];
116
+ const seen = new Set<string>();
117
+ for (const extension of registry.all()) {
118
+ const sources = extension.runtimeSources ? extension.runtimeSources() : [];
119
+ if (sources.length === 0) continue;
120
+ const archive = preferPrebuilt ? findRuntimeLibrary(`ext_${extension.name}`) : undefined;
121
+ if (archive) {
122
+ extensionObjects.push(archive);
123
+ continue;
124
+ }
125
+ for (const sourcePath of sources) {
126
+ const dedupeKey = resolve(sourcePath);
127
+ if (seen.has(dedupeKey)) continue;
128
+ seen.add(dedupeKey);
129
+ extensionObjects.push(compileOne(sourcePath, `ext_${extensionObjects.length}_${basename(sourcePath, ".c")}`));
130
+ }
131
+ }
132
+ // A native archive may be shared by several manifests; link each once.
133
+ return { runtimeObjects, extensionObjects, nativeObjects: [...new Set(registry.nativeObjects())] };
134
+ }
@@ -17,6 +17,10 @@
17
17
  * The version is checked here, not left to the first failed C compile: the
18
18
  * emitted IR needs LLVM 16+ (opaque pointers), and a "clang 15 is too old"
19
19
  * error up front is far more actionable than a wall of IR type errors later.
20
+ * On Windows the target is checked as well: only an MSVC-targeting clang can
21
+ * link against the runtime, so a compiler built for another Windows ABI is
22
+ * skipped (or rejected, when named explicitly) instead of producing objects
23
+ * the linker cannot mix.
20
24
  *
21
25
  * Extra linker arguments (for example `-fuse-ld=lld`) can be supplied through
22
26
  * `xbintsc_LINKER_ARGS`.
@@ -6,8 +6,8 @@
6
6
  */
7
7
 
8
8
  import { spawnSync, type SpawnSyncOptions } from "node:child_process";
9
- import { existsSync } from "node:fs";
10
- import { join } from "node:path";
9
+ import { existsSync, readdirSync } from "node:fs";
10
+ import { dirname, join } from "node:path";
11
11
 
12
12
  export interface CommandResult {
13
13
  readonly status: number;
@@ -75,6 +75,8 @@ export interface ClangProbe {
75
75
  /** True when the command ran and exited 0. */
76
76
  readonly responds: boolean;
77
77
  readonly version?: ClangVersion;
78
+ /** The `Target:` triple clang was built for, when it prints one. */
79
+ readonly target?: string;
78
80
  /** First line of the version output, for diagnostics. */
79
81
  readonly summary: string;
80
82
  }
@@ -98,6 +100,22 @@ export function parseClangVersion(output: string): ClangVersion | undefined {
98
100
  return { major: Number(match[1]), minor: Number(match[2]), patch: Number(match[3]) };
99
101
  }
100
102
 
103
+ /**
104
+ * Extract the `Target:` triple from `clang --version` output. Windows builds
105
+ * must target the MSVC ABI; clang built for a GNU/Windows or other triple emits
106
+ * objects that cannot be linked into an xbintsc executable (see
107
+ * {@link isMsvcTarget}).
108
+ */
109
+ export function parseClangTarget(output: string): string | undefined {
110
+ const match = /^\s*Target:\s*(\S+)/m.exec(output);
111
+ return match?.[1];
112
+ }
113
+
114
+ /** True when a clang target triple uses the MSVC ABI on Windows. */
115
+ export function isMsvcTarget(target: string): boolean {
116
+ return /-windows-msvc/i.test(target);
117
+ }
118
+
101
119
  function firstLineOf(text: string): string {
102
120
  const end = text.indexOf("\n");
103
121
  return (end === -1 ? text : text.slice(0, end)).trim();
@@ -113,10 +131,12 @@ export function probeClang(
113
131
  const result = runner.run(command, ["--version"], env ? { env } : undefined);
114
132
  const output = `${result.stdout}\n${result.stderr}`;
115
133
  const version = parseClangVersion(output);
134
+ const target = parseClangTarget(output);
116
135
  return {
117
136
  command,
118
137
  responds: result.status === 0,
119
138
  ...(version ? { version } : {}),
139
+ ...(target ? { target } : {}),
120
140
  summary: firstLineOf(result.stdout) || firstLineOf(result.stderr),
121
141
  };
122
142
  } catch {
@@ -171,23 +191,57 @@ function tooOldError(probe: ClangProbe): ToolchainError {
171
191
  );
172
192
  }
173
193
 
194
+ /**
195
+ * Windows links against the MSVC ABI, so a clang built for another Windows ABI
196
+ * (or for a different OS) cannot be used: its objects would not link with the
197
+ * MSVC runtime. This turns that mismatch into an actionable error instead of a
198
+ * wall of unresolved symbols.
199
+ */
200
+ function wrongTargetError(probe: ClangProbe): ToolchainError {
201
+ return new ToolchainError(
202
+ "clang --version",
203
+ 1,
204
+ `${probe.command} targets ${probe.target}, but xbintsc on Windows requires a clang whose default ` +
205
+ "target is the MSVC ABI (for example x86_64-pc-windows-msvc).\n" +
206
+ "Install the Visual Studio C++ build tools and use the LLVM bundled with Visual Studio " +
207
+ "(VC\\Tools\\Llvm\\<arch>\\bin\\clang.exe), or set xbintsc_CLANG to an MSVC-targeting clang.",
208
+ );
209
+ }
210
+
211
+ function hasWrongWindowsTarget(probe: ClangProbe): boolean {
212
+ return process.platform === "win32" && probe.target !== undefined && !isMsvcTarget(probe.target);
213
+ }
214
+
174
215
  function noCompilerError(tried: readonly ClangProbe[]): ToolchainError {
175
216
  const responded = tried.filter((probe) => probe.responds);
176
217
  const details = responded.map((probe) => {
177
218
  const version = probe.version
178
219
  ? `clang ${probe.version.major}.${probe.version.minor}.${probe.version.patch}`
179
220
  : probe.summary || "unknown version";
180
- return ` ${probe.command}: ${version}`;
221
+ const target = probe.target ? ` (target ${probe.target})` : "";
222
+ return ` ${probe.command}: ${version}${target}`;
181
223
  });
224
+ const wrongTarget = responded.some(hasWrongWindowsTarget);
182
225
  const tooOld = responded.some((probe) => probe.version !== undefined && probe.version.major < MINIMUM_CLANG_MAJOR);
183
- const reason = tooOld
184
- ? `Only clang older than ${MINIMUM_CLANG_MAJOR} was found; xbintsc requires clang ${MINIMUM_CLANG_MAJOR}+ ` +
185
- "(the emitted LLVM IR uses opaque pointers)."
186
- : `No clang ${MINIMUM_CLANG_MAJOR}+ was found.`;
226
+ const reasons: string[] = [];
227
+ if (tooOld) {
228
+ reasons.push(
229
+ `Only clang older than ${MINIMUM_CLANG_MAJOR} was found; xbintsc requires clang ${MINIMUM_CLANG_MAJOR}+ ` +
230
+ "(the emitted LLVM IR uses opaque pointers).",
231
+ );
232
+ }
233
+ if (wrongTarget) {
234
+ reasons.push(
235
+ "Only clang targeting a non-MSVC Windows ABI was found; the Windows build links against the MSVC ABI.",
236
+ );
237
+ }
238
+ if (reasons.length === 0) reasons.push(`No clang ${MINIMUM_CLANG_MAJOR}+ was found.`);
187
239
  return new ToolchainError(
188
240
  "clang --version",
189
241
  1,
190
- [reason, ...(details.length > 0 ? ["Tested:", ...details] : []), "Set xbintsc_CLANG to a clang binary."].join("\n"),
242
+ [...reasons, ...(details.length > 0 ? ["Tested:", ...details] : []), "Set xbintsc_CLANG to a clang binary."].join(
243
+ "\n",
244
+ ),
191
245
  );
192
246
  }
193
247
 
@@ -207,6 +261,7 @@ export function locateClang(runner: Runner = realRunner): ClangLocation {
207
261
  if (explicit) {
208
262
  const probe = probeClang(runner, explicit);
209
263
  if (probe.responds) {
264
+ if (hasWrongWindowsTarget(probe)) throw wrongTargetError(probe);
210
265
  if (probe.version && probe.version.major < MINIMUM_CLANG_MAJOR) throw tooOldError(probe);
211
266
  return { command: explicit, source: "env", ...(probe.version ? { version: probe.version } : {}) };
212
267
  }
@@ -216,6 +271,7 @@ export function locateClang(runner: Runner = realRunner): ClangLocation {
216
271
  const probe = probeClang(runner, command);
217
272
  tried.push(probe);
218
273
  if (!probe.responds || !probe.version) continue;
274
+ if (hasWrongWindowsTarget(probe)) continue;
219
275
  if (probe.version.major < MINIMUM_CLANG_MAJOR) continue;
220
276
  return { command, source: "system", version: probe.version };
221
277
  }
@@ -227,6 +283,22 @@ export function findClang(runner: Runner = realRunner): string {
227
283
  return locateClang(runner).command;
228
284
  }
229
285
 
286
+ /** Profile-guided optimization stage (`--pgo-generate` / `--pgo-use`). */
287
+ export type PgoMode = "generate" | "use";
288
+
289
+ /** clang flags for LTO and the selected PGO stage. */
290
+ export function optimizationFlags(
291
+ lto: boolean | undefined,
292
+ pgo: PgoMode | undefined,
293
+ pgoDir: string | undefined,
294
+ ): string[] {
295
+ const flags: string[] = [];
296
+ if (lto) flags.push("-flto");
297
+ if (pgo === "generate") flags.push(`-fprofile-generate=${pgoDir ?? "pgo"}`);
298
+ else if (pgo === "use") flags.push(`-fprofile-use=${pgoDir ?? "pgo"}`);
299
+ return flags;
300
+ }
301
+
230
302
  export interface CompileIrOptions {
231
303
  readonly clang: string;
232
304
  readonly irPath: string;
@@ -235,6 +307,11 @@ export interface CompileIrOptions {
235
307
  readonly env?: Record<string, string>;
236
308
  /** Emit debug info (`-g`) and keep frame pointers for crash backtraces. */
237
309
  readonly debug?: boolean;
310
+ /** Compile to LTO bitcode and let the linker optimize across units. */
311
+ readonly lto?: boolean;
312
+ /** Instrument (`generate`) or consume (`use`) an LLVM profile. */
313
+ readonly pgo?: PgoMode;
314
+ readonly pgoDir?: string;
238
315
  }
239
316
 
240
317
  /**
@@ -247,9 +324,19 @@ const SECTION_FLAGS = ["-ffunction-sections", "-fdata-sections"];
247
324
  /** Compile an LLVM IR file to a native object file. */
248
325
  export function compileIr(runner: Runner, options: CompileIrOptions): void {
249
326
  const debugFlags = options.debug ? ["-g", "-fno-omit-frame-pointer"] : [];
327
+ const profileFlags = optimizationFlags(options.lto, options.pgo, options.pgoDir);
250
328
  const result = runner.run(
251
329
  options.clang,
252
- [`-O${options.optimize}`, ...SECTION_FLAGS, ...debugFlags, "-c", options.irPath, "-o", options.objectPath],
330
+ [
331
+ `-O${options.optimize}`,
332
+ ...SECTION_FLAGS,
333
+ ...debugFlags,
334
+ ...profileFlags,
335
+ "-c",
336
+ options.irPath,
337
+ "-o",
338
+ options.objectPath,
339
+ ],
253
340
  { env: options.env },
254
341
  );
255
342
  if (result.status !== 0) throw new ToolchainError(`${options.clang} ${options.irPath}`, result.status, result.stderr);
@@ -262,6 +349,9 @@ export interface LinkOptions {
262
349
  readonly linkerFlags: readonly string[];
263
350
  readonly optimize: string;
264
351
  readonly env?: Record<string, string>;
352
+ readonly lto?: boolean;
353
+ readonly pgo?: PgoMode;
354
+ readonly pgoDir?: string;
265
355
  }
266
356
 
267
357
  /** Platform flag that drops unreferenced sections (paired with {@link SECTION_FLAGS}). */
@@ -272,8 +362,14 @@ function deadStripFlag(): string[] {
272
362
  }
273
363
 
274
364
  export function link(runner: Runner, options: LinkOptions): void {
365
+ const profileFlags = optimizationFlags(options.lto, options.pgo, options.pgoDir);
275
366
  const args = [
276
367
  `-O${options.optimize}`,
368
+ ...profileFlags,
369
+ /* LTO bitcode needs a linker with an LTO plugin. lld ships with LLVM and
370
+ * understands both ELF/Mach-O and COFF; without it MSVC link.exe rejects
371
+ * the bitcode object on Windows. */
372
+ ...(options.lto ? ["-fuse-ld=lld"] : []),
277
373
  ...options.objectPaths,
278
374
  "-o",
279
375
  options.outputPath,
@@ -305,11 +401,59 @@ export function compileC(
305
401
  objectPath: string,
306
402
  includeDir: string,
307
403
  env?: Record<string, string>,
404
+ extraFlags: readonly string[] = [],
308
405
  ): void {
309
406
  const result = runner.run(
310
407
  clang,
311
- [...RUNTIME_CFLAGS, "-c", sourcePath, "-o", objectPath, `-I${includeDir}`],
408
+ [...RUNTIME_CFLAGS, ...extraFlags, "-c", sourcePath, "-o", objectPath, `-I${includeDir}`],
312
409
  { env },
313
410
  );
314
411
  if (result.status !== 0) throw new ToolchainError(`${clang} ${sourcePath}`, result.status, result.stderr);
315
412
  }
413
+
414
+ /**
415
+ * Merge the `.profraw` files written by an instrumented binary into the
416
+ * `default.profdata` that `-fprofile-use=<dir>` expects. Clang's `-fprofile-use`
417
+ * does not read raw profiles directly; this runs `llvm-profdata merge`.
418
+ *
419
+ * `xbintsc_LLVM_PROFDATA` selects the tool when it is not on `PATH`.
420
+ */
421
+ export function mergeProfileData(
422
+ runner: Runner,
423
+ directory: string,
424
+ clang: string,
425
+ env?: Record<string, string>,
426
+ ): void {
427
+ const profdata = join(directory, "default.profdata");
428
+ if (existsSync(profdata)) return;
429
+ let raw: string[];
430
+ try {
431
+ raw = readdirSync(directory)
432
+ .filter((name) => name.endsWith(".profraw"))
433
+ .map((name) => join(directory, name));
434
+ } catch {
435
+ raw = [];
436
+ }
437
+ if (raw.length === 0) {
438
+ throw new ToolchainError(
439
+ "llvm-profdata merge",
440
+ 1,
441
+ `no .profraw files found in ${directory}; run the --pgo-generate binary before --pgo-use.`,
442
+ );
443
+ }
444
+ /* Prefer the llvm-profdata shipped next to clang: a system-wide copy from a
445
+ * different LLVM version rejects newer raw profile formats. */
446
+ const suffix = process.platform === "win32" ? ".exe" : "";
447
+ const adjacent = join(dirname(clang), `llvm-profdata${suffix}`);
448
+ const tool =
449
+ process.env.xbintsc_LLVM_PROFDATA ??
450
+ (existsSync(adjacent) ? adjacent : "llvm-profdata");
451
+ const result = runner.run(tool, ["merge", "-o", profdata, ...raw], env ? { env } : undefined);
452
+ if (result.status !== 0) {
453
+ throw new ToolchainError(
454
+ `${tool} merge`,
455
+ result.status,
456
+ `${result.stderr}\nInstall LLVM's llvm-profdata or set xbintsc_LLVM_PROFDATA to it.`,
457
+ );
458
+ }
459
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The compiler's own version.
3
+ *
4
+ * It is part of the incremental cache key, so it must be bumped for every
5
+ * release (a test enforces that it matches `package.json`); a stale version
6
+ * would let an upgraded compiler reuse binaries produced by the previous one.
7
+ *
8
+ * Keep this constant in its own module: the pre-commit hook bumps it on
9
+ * `main`/`master` only (see `.githooks/pre-commit`), so feature branches never
10
+ * change this line and merging two of them cannot conflict here.
11
+ */
12
+ export const COMPILER_VERSION = "0.5.21";
@@ -4,9 +4,8 @@
4
4
  * Windows reads the application icon from a resource section in the `.exe`, so
5
5
  * an embedded blob is not enough: the icon is wrapped in a `.rc` script and
6
6
  * compiled to a resource object that is linked into the executable. `llvm-rc`
7
- * (shipping with clang) is preferred; MinGW `windres` is the fallback. Both are
8
- * optional — a missing resource compiler degrades to the runtime window icon
9
- * instead of failing the build.
7
+ * (shipping with LLVM/clang, and next to the clang xbintsc resolves) produces
8
+ * the MSVC-compatible `.res` object the linker expects.
10
9
  */
11
10
 
12
11
  import { existsSync, mkdirSync, writeFileSync } from "node:fs";
@@ -15,51 +14,56 @@ import { hashParts } from "./cache.js";
15
14
  import { IconError, toIcoBytes, type IconInfo } from "./icon.js";
16
15
  import type { Runner } from "./toolchain.js";
17
16
 
18
- export type ResourceCompilerKind = "llvm-rc" | "windres";
19
-
20
17
  export interface ResourceCompiler {
21
18
  readonly tool: string;
22
- readonly kind: ResourceCompilerKind;
23
19
  }
24
20
 
25
21
  /**
26
- * Locate a resource compiler. `xbintsc_RC` wins, then `llvm-rc` next to the
27
- * resolved clang, then `llvm-rc` and `windres` on `PATH`.
22
+ * Probe `llvm-rc`.
23
+ *
24
+ * It has no `--version` flag: any invocation that is not a valid conversion
25
+ * exits non-zero, but a usage-only run (`/?`) prints the tool name, which is
26
+ * what identifies it. Treat a usage banner as success so a real `llvm-rc`
27
+ * installed next to clang is not skipped.
28
+ */
29
+ function isLlvmRc(runner: Runner, tool: string): boolean {
30
+ try {
31
+ const result = runner.run(tool, ["/?"]);
32
+ if (result.status === 0) return true;
33
+ return /LLVM Resource Converter/i.test(result.stdout + result.stderr);
34
+ } catch {
35
+ return false;
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Locate `llvm-rc`. `xbintsc_RC` wins, then `llvm-rc` next to the resolved
41
+ * clang, then `llvm-rc` on `PATH`. Returns `undefined` when none exists; the
42
+ * caller then builds without the embedded icon.
28
43
  */
29
44
  export function resolveResourceCompiler(runner: Runner, clang: string): ResourceCompiler | undefined {
30
45
  const exe = process.platform === "win32" ? ".exe" : "";
31
46
  // An explicit override is trusted: probe it and fall back rather than
32
47
  // rejecting it on a path prefix check (it may be a bare command on PATH).
33
48
  const override = process.env.xbintsc_RC;
34
- if (override) {
35
- const kind: ResourceCompilerKind = /windres/i.test(override) ? "windres" : "llvm-rc";
36
- try {
37
- if (runner.run(override, ["--version"]).status === 0) return { tool: override, kind };
38
- } catch {
39
- // Fall through to the discovered compilers.
40
- }
41
- }
42
- const candidates: ResourceCompiler[] = [];
49
+ if (override && isLlvmRc(runner, override)) return { tool: override };
50
+
51
+ const candidates: string[] = [];
43
52
  if (clang && (clang.includes("/") || clang.includes("\\"))) {
44
- candidates.push({ tool: join(dirname(clang), `llvm-rc${exe}`), kind: "llvm-rc" });
53
+ candidates.push(join(dirname(clang), `llvm-rc${exe}`));
45
54
  }
46
- candidates.push({ tool: `llvm-rc${exe}`, kind: "llvm-rc" });
47
- candidates.push({ tool: `windres${exe}`, kind: "windres" });
55
+ candidates.push(`llvm-rc${exe}`);
48
56
 
49
- for (const candidate of candidates) {
50
- if ((candidate.tool.includes("/") || candidate.tool.includes("\\")) && !existsSync(candidate.tool)) continue;
51
- try {
52
- if (runner.run(candidate.tool, ["--version"]).status === 0) return candidate;
53
- } catch {
54
- // Not runnable; try the next candidate.
55
- }
57
+ for (const tool of candidates) {
58
+ if ((tool.includes("/") || tool.includes("\\")) && !existsSync(tool)) continue;
59
+ if (isLlvmRc(runner, tool)) return { tool };
56
60
  }
57
61
  return undefined;
58
62
  }
59
63
 
60
64
  /**
61
- * Compile the icon into a linkable PE resource object (`.res` for llvm-rc, a
62
- * COFF `.o` for windres). Cached by contents and compiler kind.
65
+ * Compile the icon into a linkable PE resource object (`.res`, cached by
66
+ * contents).
63
67
  */
64
68
  export function ensureWindowsIconResource(
65
69
  runner: Runner,
@@ -69,11 +73,11 @@ export function ensureWindowsIconResource(
69
73
  env?: Record<string, string>,
70
74
  ): string {
71
75
  const icoBytes = toIcoBytes(icon);
72
- const key = hashParts(["icon-res", compiler.kind, Buffer.from(icoBytes).toString("base64")]);
76
+ const key = hashParts(["icon-res", Buffer.from(icoBytes).toString("base64")]);
73
77
  const icoName = `icon-${key}.ico`;
74
78
  const icoPath = join(cacheDir, icoName);
75
79
  const rcPath = join(cacheDir, `icon-${key}.rc`);
76
- const objectPath = join(cacheDir, `icon-${key}.${compiler.kind === "windres" ? "o" : "res"}`);
80
+ const objectPath = join(cacheDir, `icon-${key}.res`);
77
81
  if (existsSync(objectPath)) return objectPath;
78
82
 
79
83
  mkdirSync(cacheDir, { recursive: true });
@@ -82,11 +86,7 @@ export function ensureWindowsIconResource(
82
86
  // its working directory so the relative path resolves.
83
87
  writeFileSync(rcPath, `1 ICON "${icoName}"\n`);
84
88
 
85
- const args =
86
- compiler.kind === "windres"
87
- ? [rcPath, "-O", "coff", "-o", objectPath]
88
- : ["/fo", objectPath, rcPath];
89
- const result = runner.run(compiler.tool, args, { cwd: cacheDir, env });
89
+ const result = runner.run(compiler.tool, ["/fo", objectPath, rcPath], { cwd: cacheDir, env });
90
90
  if (result.status !== 0 || !existsSync(objectPath)) {
91
91
  throw new IconError(
92
92
  `Failed to compile the Windows icon resource with ${compiler.tool}:\n${result.stderr || result.stdout}`,
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * Node's `fs` module: synchronous file and directory operations backed by
3
- * `runtime/ext_node/fs`. Asynchronous callbacks are not supported (xbintsc has
4
- * no event loop), so the API is the `*Sync` surface plus `watch`/`watchFile`
5
- * (which return API-shaped watchers that never emit).
3
+ * `runtime/ext_node/fs`, plus the `fs.promises` namespace (implemented in
4
+ * `async_*.c` on top of the asynchronous I/O pool). The callback-style
5
+ * `readFile`/`writeFile` forms are not supported; `*Sync` and `fs.promises` are.
6
+ * `watch`/`watchFile` return API-shaped watchers that never emit.
6
7
  *
7
8
  * `fs.constants` and `fs.promises` are exposed as value getters, so both
8
9
  * `import { constants } from "fs"` and the `fs.constants.F_OK` property form
@@ -40,6 +41,14 @@ export const fsModule: NodeModule = {
40
41
  resolveFrom(import.meta.url, "../../../../runtime/ext_node/fs/watch.c"),
41
42
  resolveFrom(import.meta.url, "../../../../runtime/ext_node/fs/constants.c"),
42
43
  resolveFrom(import.meta.url, "../../../../runtime/ext_node/fs/streams.c"),
44
+ resolveFrom(import.meta.url, "../../../../runtime/ext_node/fs/async_job.c"),
45
+ resolveFrom(import.meta.url, "../../../../runtime/ext_node/fs/async_worker.c"),
46
+ resolveFrom(import.meta.url, "../../../../runtime/ext_node/fs/async_worker_dir.c"),
47
+ resolveFrom(import.meta.url, "../../../../runtime/ext_node/fs/async_worker_fd.c"),
48
+ resolveFrom(import.meta.url, "../../../../runtime/ext_node/fs/async_complete.c"),
49
+ resolveFrom(import.meta.url, "../../../../runtime/ext_node/fs/async_api.c"),
50
+ resolveFrom(import.meta.url, "../../../../runtime/ext_node/fs/async_fh.c"),
51
+ resolveFrom(import.meta.url, "../../../../runtime/ext_node/fs/promises.c"),
43
52
  ],
44
53
  builtins: () => builtins,
45
54
  exports: () => exports,