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
@@ -5,161 +5,35 @@
5
5
  * The runtime (and any registered extension sources) are compiled once and
6
6
  * cached, and the whole build is skipped when the incremental cache says
7
7
  * nothing relevant changed.
8
+ *
9
+ * This module only orchestrates the phases. The front end lives in
10
+ * `frontend.ts`, cache-key inputs in `build-key.ts`, runtime compilation in
11
+ * `runtime-objects.ts`, platform artifacts in `app-artifacts.ts`, and the
12
+ * version constant in `version.ts`.
8
13
  */
9
14
 
10
- import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
15
+ import { mkdirSync, writeFileSync } from "node:fs";
11
16
  import { basename, dirname, extname, join, resolve } from "node:path";
12
- import { DiagnosticBag, DiagnosticCode, type Diagnostic } from "../diagnostics/diagnostic.js";
13
- import { SourceFile } from "../diagnostics/source.js";
14
- import { sourceTextBytes } from "../diagnostics/source-text.js";
15
- import { Parser } from "../parser/parser.js";
17
+ import { DiagnosticBag, DiagnosticCode } from "../diagnostics/diagnostic.js";
16
18
  import { generate } from "../codegen/llvm.js";
17
- import { SyntaxKind } from "../ast/nodes.js";
18
- import { bundleModules } from "./modules.js";
19
- import { createDefaultRegistry, type ExtensionRegistry } from "../extensions/registry.js";
20
- import { BuildCache, hashParts } from "./cache.js";
21
- import { compilerFingerprint, registryFingerprint, runtimeFingerprint } from "./fingerprint.js";
19
+ import { createDefaultRegistry } from "../extensions/registry.js";
20
+ import { BuildCache } from "./cache.js";
22
21
  import { findRuntimeDir } from "./paths.js";
23
- import { findRuntimeLibrary } from "./runtime-lib.js";
24
22
  import { resolveToolchain } from "./toolchain-provider.js";
25
- import { ensureIconObject, readIcon, EMPTY_ICON, IconError, type IconInfo } from "./icon.js";
26
- import { ensureWindowsIconResource, resolveResourceCompiler } from "./win-icon.js";
27
- import { ensureWindowsEntryObject } from "./win-entry.js";
23
+ import { readIcon, IconError, type IconInfo } from "./icon.js";
28
24
  import { bundlePathFor, packageMacApp } from "./mac-bundle.js";
29
25
  import type { AppConfig } from "./config.js";
30
- import {
31
- compileC,
32
- compileIr,
33
- link,
34
- realRunner,
35
- RUNTIME_CFLAGS,
36
- type Runner,
37
- } from "./toolchain.js";
38
-
39
- /**
40
- * The compiler's own version. It is part of the incremental cache key, so it
41
- * must be bumped for every release (a test enforces that it matches
42
- * `package.json`); a stale version would let an upgraded compiler reuse binaries
43
- * produced by the previous one.
44
- */
45
- export const COMPILER_VERSION = "0.5.6";
46
-
47
- export type EmitKind = "exe" | "obj" | "ir";
48
-
49
- export interface BuildOptions {
50
- /** Explicit output path (defaults to the source base name in `outDir`). */
51
- readonly output?: string;
52
- readonly outDir?: string;
53
- readonly optimize?: "0" | "1" | "2" | "3";
54
- readonly emit?: EmitKind;
55
- readonly force?: boolean;
56
- readonly verbose?: boolean;
57
- readonly cacheDir?: string;
58
- readonly extensions?: ExtensionRegistry;
59
- readonly runner?: Runner;
60
- readonly clang?: string;
61
- /** Prefer a prebuilt `runtime/lib/<os>-<arch>/*.a` archive when present (default true). */
62
- readonly preferPrebuilt?: boolean;
63
- readonly write?: boolean;
64
- /** Application icon embedded into the binary (shorthand for `app.icon`). */
65
- readonly icon?: string;
66
- /** Application metadata: name, icon and macOS bundle settings. */
67
- readonly app?: AppConfig;
68
- /** Emit LLVM debug metadata so `-g` produces DWARF/CodeView (default false). */
69
- readonly debug?: boolean;
70
- }
71
-
72
- /** One phase of a build, in milliseconds (reported by `--time`). */
73
- export interface PhaseTiming {
74
- readonly phase: "frontend" | "codegen" | "runtime" | "clang" | "link";
75
- readonly ms: number;
76
- }
77
-
78
- export interface BuildResult {
79
- readonly outputPath: string;
80
- readonly irPath?: string;
81
- readonly cached: boolean;
82
- readonly diagnostics: readonly Diagnostic[];
83
- readonly ir?: string;
84
- /** macOS `.app` bundle produced by `app.bundle` (darwin only). */
85
- readonly bundlePath?: string;
86
- /** Per-phase timings, collected for `xbintsc build --time`. */
87
- readonly timings?: readonly PhaseTiming[];
88
- }
89
-
90
- export interface CompileStringResult {
91
- readonly ir: string;
92
- readonly diagnostics: readonly Diagnostic[];
93
- }
94
-
95
- /** Compile TypeScript source text to LLVM IR without touching the toolchain. */
96
- export function compileString(
97
- source: string,
98
- fileName = "input.ts",
99
- extensions?: ExtensionRegistry,
100
- options: { readonly debug?: boolean } = {},
101
- ): CompileStringResult {
102
- const file = new SourceFile(fileName, source);
103
- const diagnostics = new DiagnosticBag();
104
- const parser = new Parser(file, diagnostics);
105
- const sourceFile = parser.parseSourceFile();
106
- const registry = extensions ?? createDefaultRegistry();
107
- const { ir } = generate(sourceFile, diagnostics, {
108
- builtins: registry.builtins(),
109
- modules: registry.modules(),
110
- moduleHints: registry.moduleHints(),
111
- debug: options.debug === true,
112
- });
113
- return { ir, diagnostics: diagnostics.diagnostics };
114
- }
115
-
116
- /**
117
- * Every module specifier the registry can resolve at code generation time (the
118
- * registered platform modules plus the hints for known-but-disabled
119
- * extensions). Bare imports outside this set are looked up in `node_modules`
120
- * and bundled as source.
121
- */
122
- function externalModuleSpecifiers(registry: ExtensionRegistry): Set<string> {
123
- return new Set([
124
- ...Object.keys(registry.modules()),
125
- ...Object.keys(registry.moduleHints()),
126
- ]);
127
- }
128
-
129
- /**
130
- * Compile a file to LLVM IR, bundling every reachable relative module first so
131
- * that imports from other TypeScript sources resolve exactly like `build`.
132
- */
133
- export function compileEntry(
134
- entryPath: string,
135
- extensions?: ExtensionRegistry,
136
- options: { readonly debug?: boolean } = {},
137
- ): CompileStringResult {
138
- const absoluteEntry = resolve(entryPath);
139
- const sourceText = sourceTextBytes(readFileSync(absoluteEntry, "utf8"));
140
- const file = new SourceFile(absoluteEntry, sourceText);
141
- const diagnostics = new DiagnosticBag();
142
- const parser = new Parser(file, diagnostics);
143
- let sourceFile = parser.parseSourceFile();
144
- const registry = extensions ?? createDefaultRegistry();
145
- const isModule = sourceFile.statements.some(
146
- (statement) =>
147
- statement.kind === SyntaxKind.ImportDeclaration ||
148
- statement.kind === SyntaxKind.ExportDeclaration ||
149
- statement.kind === SyntaxKind.ExportAssignment,
150
- );
151
- if (isModule) {
152
- const bundled = bundleModules(absoluteEntry, diagnostics, externalModuleSpecifiers(registry), registry.assetLoaders());
153
- if (bundled) sourceFile = bundled.sourceFile;
154
- }
155
- const { ir } = generate(sourceFile, diagnostics, {
156
- builtins: registry.builtins(),
157
- modules: registry.modules(),
158
- moduleHints: registry.moduleHints(),
159
- debug: options.debug === true,
160
- });
161
- return { ir, diagnostics: diagnostics.diagnostics };
162
- }
26
+ import { compileIr, link, mergeProfileData, realRunner, ToolchainError } from "./toolchain.js";
27
+ import { parseEntry } from "./frontend.js";
28
+ import { ensureRuntimeObjects } from "./runtime-objects.js";
29
+ import { ensureAppArtifacts } from "./app-artifacts.js";
30
+ import { buildCacheKey } from "./build-key.js";
31
+ import type { BuildOptions, BuildResult, EmitKind, PhaseTiming } from "./options.js";
32
+
33
+ export { COMPILER_VERSION } from "./version.js";
34
+ export { compileString, compileEntry, parseEntry, type ParsedEntry } from "./frontend.js";
35
+ export { RUNTIME_SOURCES, type RuntimeObjects } from "./runtime-objects.js";
36
+ export type { BuildOptions, BuildResult, CompileStringResult, EmitKind, PhaseTiming } from "./options.js";
163
37
 
164
38
  /**
165
39
  * Where the incremental cache lives when the caller does not name a directory:
@@ -199,9 +73,12 @@ export function build(entryPath: string, options: BuildOptions = {}): BuildResul
199
73
  const cacheDir = resolve(options.cacheDir ?? defaultCacheDir());
200
74
  const emit: EmitKind = options.emit ?? "exe";
201
75
  const optimize = options.optimize ?? "2";
76
+ const lto = options.lto === true;
77
+ const pgo = options.pgo;
78
+ const pgoDir = resolve(options.pgoDir ?? join(outDir, "pgo"));
79
+ if (pgo) mkdirSync(pgoDir, { recursive: true });
202
80
 
203
81
  const absoluteEntry = resolve(entryPath);
204
- const sourceText = sourceTextBytes(readFileSync(absoluteEntry, "utf8"));
205
82
  const buildStarted = Date.now();
206
83
  const timings: PhaseTiming[] = [];
207
84
 
@@ -214,29 +91,17 @@ export function build(entryPath: string, options: BuildOptions = {}): BuildResul
214
91
  : executableName(absoluteEntry, outDir, options.output);
215
92
 
216
93
  // -- front end -----------------------------------------------------------
217
- const file = new SourceFile(absoluteEntry, sourceText);
218
94
  const diagnostics = new DiagnosticBag();
219
- const parser = new Parser(file, diagnostics);
220
- let sourceFile = parser.parseSourceFile();
95
+ const parsed = parseEntry(absoluteEntry, registry, diagnostics);
96
+ timings.push({ phase: "frontend", ms: Date.now() - buildStarted });
221
97
 
222
- // Lower `import`/`export` by merging every reachable module into one file.
223
- const isModule = sourceFile.statements.some(
224
- (statement) =>
225
- statement.kind === SyntaxKind.ImportDeclaration ||
226
- statement.kind === SyntaxKind.ExportDeclaration ||
227
- statement.kind === SyntaxKind.ExportAssignment,
228
- );
229
- let cacheText = sourceText;
230
- if (isModule) {
231
- const bundled = bundleModules(absoluteEntry, diagnostics, externalModuleSpecifiers(registry), registry.assetLoaders());
232
- if (bundled) {
233
- sourceFile = bundled.sourceFile;
234
- cacheText = bundled.text;
235
- }
98
+ /* Parse (or module-graph) errors leave missing nodes in the tree. Stop before
99
+ * code generation instead of letting the binder crash on them. */
100
+ if (diagnostics.hasErrors) {
101
+ return { outputPath, cached: false, diagnostics: diagnostics.diagnostics, timings };
236
102
  }
237
- timings.push({ phase: "frontend", ms: Date.now() - buildStarted });
238
103
 
239
- const app = options.app ?? {};
104
+ const app: AppConfig = options.app ?? {};
240
105
  const iconPath = options.icon ?? app.icon;
241
106
  let icon: IconInfo | undefined;
242
107
  if (iconPath) {
@@ -252,21 +117,19 @@ export function build(entryPath: string, options: BuildOptions = {}): BuildResul
252
117
  }
253
118
 
254
119
  const runtimeDir = findRuntimeDir();
255
- const cacheKey = hashParts([
256
- COMPILER_VERSION,
257
- compilerFingerprint(),
258
- cacheText,
120
+ const cacheKey = buildCacheKey({
121
+ sourceText: parsed.cacheText,
259
122
  emit,
260
123
  optimize,
261
- process.platform,
262
- registryFingerprint(registry),
263
- runtimeFingerprint(runtimeDir),
264
- icon ? hashParts(["icon", icon.format, Buffer.from(icon.bytes).toString("base64")]) : "",
265
- app.name ?? "",
266
- String(app.bundle ?? false),
267
- app.bundleId ?? "",
268
- String(options.debug === true),
269
- ]);
124
+ registry,
125
+ runtimeDir,
126
+ icon,
127
+ app,
128
+ debug: options.debug === true,
129
+ lto,
130
+ pgo,
131
+ pgoDir,
132
+ });
270
133
 
271
134
  // A `.app` bundle is deterministic from the output path and name, so it can be
272
135
  // part of the cache key before the bundle actually exists.
@@ -276,12 +139,14 @@ export function build(entryPath: string, options: BuildOptions = {}): BuildResul
276
139
  : undefined;
277
140
  const cache = new BuildCache(cacheDir);
278
141
  const outputs = bundle ? [outputPath, bundle] : [outputPath];
279
- if (!options.force && !diagnostics.hasErrors && cache.isFresh(cacheKey, outputs)) {
142
+ /* PGO profile data can change without the cache key changing, so always
143
+ * rebuild a `--pgo-use` binary; it is an explicit optimization step. */
144
+ if (!options.force && pgo !== "use" && !diagnostics.hasErrors && cache.isFresh(cacheKey, outputs)) {
280
145
  return { outputPath, cached: true, diagnostics: [], timings, ...(bundle ? { bundlePath: bundle } : {}) };
281
146
  }
282
147
 
283
148
  const codegenStarted = Date.now();
284
- const { ir } = generate(sourceFile, diagnostics, {
149
+ const { ir } = generate(parsed.sourceFile, diagnostics, {
285
150
  builtins: registry.builtins(),
286
151
  modules: registry.modules(),
287
152
  moduleHints: registry.moduleHints(),
@@ -318,10 +183,30 @@ export function build(entryPath: string, options: BuildOptions = {}): BuildResul
318
183
  ? { clang: options.clang, linkerArgs: [] as string[], env: {} as Record<string, string> }
319
184
  : resolveToolchain(runner);
320
185
  const clang = toolchain.clang;
186
+ if (pgo === "use") {
187
+ try {
188
+ mergeProfileData(runner, pgoDir, clang, toolchain.env);
189
+ } catch (error) {
190
+ if (error instanceof ToolchainError) {
191
+ diagnostics.error(DiagnosticCode.ToolchainError, error.message);
192
+ return { outputPath, irPath, cached: false, diagnostics: diagnostics.diagnostics, ir };
193
+ }
194
+ throw error;
195
+ }
196
+ }
321
197
  mkdirSync(cacheDir, { recursive: true });
322
198
 
323
199
  const objectPath = emit === "obj" ? outputPath : resolve(outDir, baseName + ".o");
324
- compileIr(runner, { clang, irPath, objectPath, optimize, env: toolchain.env, debug: options.debug === true });
200
+ compileIr(runner, {
201
+ clang,
202
+ irPath,
203
+ objectPath,
204
+ optimize,
205
+ env: toolchain.env,
206
+ debug: options.debug === true,
207
+ lto,
208
+ ...(pgo ? { pgo, pgoDir } : {}),
209
+ });
325
210
  timings.push({ phase: "clang", ms: Date.now() - clangStarted });
326
211
 
327
212
  if (emit === "obj") {
@@ -331,50 +216,33 @@ export function build(entryPath: string, options: BuildOptions = {}): BuildResul
331
216
  }
332
217
 
333
218
  const runtimeStarted = Date.now();
334
- const { runtimeObjects, extensionObjects, nativeObjects } = ensureRuntimeObjects(
219
+ const { runtimeObjects, extensionObjects, nativeObjects } = ensureRuntimeObjects({
335
220
  runner,
336
221
  clang,
337
222
  runtimeDir,
338
223
  cacheDir,
339
224
  registry,
340
- resolvePreferPrebuilt(options.preferPrebuilt),
341
- toolchain.env,
342
- );
225
+ preferPrebuilt: resolvePreferPrebuilt(options.preferPrebuilt) && !lto && pgo === undefined,
226
+ env: toolchain.env,
227
+ lto,
228
+ pgo,
229
+ pgoDir,
230
+ });
343
231
  timings.push({ phase: "runtime", ms: Date.now() - runtimeStarted });
344
232
 
345
- /* On Windows a GUI program links as a **Windows-subsystem** executable, so
346
- * launching it does not flash a console window. That subsystem's C runtime
347
- * wants `WinMain`, so a tiny shim object bridges it to the runtime's `main`.
348
- * `app.console: true` keeps the console subsystem instead (useful while
349
- * debugging, because stdout and stderr only exist there). Other platforms
350
- * have no equivalent. */
351
- const windowsSubsystem = process.platform === "win32" && registry.has("gui") && app.console !== true;
352
- const consoleSubsystem = windowsSubsystem ? ["-Wl,/SUBSYSTEM:WINDOWS"] : [];
353
- const entryObject = windowsSubsystem
354
- ? ensureWindowsEntryObject(runner, clang, cacheDir, toolchain.env)
355
- : undefined;
356
-
357
- const iconObjects: string[] = [];
358
- // The GUI extension references the icon symbols unconditionally, so a GUI
359
- // program gets an (empty) icon object even with no icon configured.
360
- if (icon !== undefined || registry.has("gui")) {
361
- try {
362
- iconObjects.push(ensureIconObject(runner, clang, cacheDir, icon ?? EMPTY_ICON, toolchain.env));
363
- if (icon && process.platform === "win32") {
364
- const resourceCompiler = resolveResourceCompiler(runner, clang);
365
- if (resourceCompiler) {
366
- iconObjects.push(ensureWindowsIconResource(runner, cacheDir, icon, resourceCompiler, toolchain.env));
367
- } else if (options.verbose) {
368
- process.stderr.write("xbintsc: no llvm-rc/windres found; skipping the embedded .exe icon\n");
369
- }
370
- }
371
- } catch (error) {
372
- if (error instanceof IconError) {
373
- diagnostics.error(DiagnosticCode.ToolchainError, error.message);
374
- return { outputPath, irPath, cached: false, diagnostics: diagnostics.diagnostics, ir };
375
- }
376
- throw error;
377
- }
233
+ const artifacts = ensureAppArtifacts({
234
+ runner,
235
+ clang,
236
+ cacheDir,
237
+ registry,
238
+ app,
239
+ icon,
240
+ env: toolchain.env,
241
+ verbose: options.verbose,
242
+ });
243
+ if (artifacts.iconError !== undefined) {
244
+ diagnostics.error(DiagnosticCode.ToolchainError, artifacts.iconError);
245
+ return { outputPath, irPath, cached: false, diagnostics: diagnostics.diagnostics, ir };
378
246
  }
379
247
 
380
248
  const linkStarted = Date.now();
@@ -385,22 +253,24 @@ export function build(entryPath: string, options: BuildOptions = {}): BuildResul
385
253
  ...runtimeObjects,
386
254
  ...extensionObjects,
387
255
  ...nativeObjects,
388
- ...(entryObject !== undefined ? [entryObject] : []),
389
- ...iconObjects,
256
+ ...(artifacts.entryObject !== undefined ? [artifacts.entryObject] : []),
257
+ ...artifacts.iconObjects,
390
258
  ],
391
259
  outputPath,
392
260
  linkerFlags: [
393
261
  ...toolchain.linkerArgs,
394
- ...(process.platform === "win32" ? ["-lws2_32"] : ["-lm"]),
262
+ ...(process.platform === "win32" ? ["-lws2_32"] : ["-lm", "-pthread"]),
395
263
  ...registry.linkerFlags(),
396
264
  /* A GUI program is a Windows-subsystem executable: no console window is
397
265
  * created when it is launched. Console output (stdout/stderr) is lost in
398
266
  * that subsystem, so a program that wants to report things opts back in
399
267
  * with `app.console: true`. */
400
- ...consoleSubsystem,
268
+ ...artifacts.linkerFlags,
401
269
  ],
402
270
  optimize,
403
271
  env: toolchain.env,
272
+ lto,
273
+ ...(pgo ? { pgo, pgoDir } : {}),
404
274
  });
405
275
  timings.push({ phase: "link", ms: Date.now() - linkStarted });
406
276
 
@@ -426,107 +296,3 @@ function defaultBundleId(name: string): string {
426
296
  const sanitized = name.replace(/[^A-Za-z0-9.-]/g, "");
427
297
  return `com.xbintsc.${sanitized || "app"}`;
428
298
  }
429
-
430
- interface RuntimeObjects {
431
- readonly runtimeObjects: readonly string[];
432
- readonly extensionObjects: readonly string[];
433
- /** Pre-built C++/Rust objects and archives contributed by native extensions. */
434
- readonly nativeObjects: readonly string[];
435
- }
436
-
437
- /** Core runtime translation units (each compiled and cached independently). */
438
- export const RUNTIME_SOURCES = [
439
- "xt_alloc.c",
440
- "xt_values.c",
441
- "xt_bigint.c",
442
- "xt_containers.c",
443
- "xt_typed_array.c",
444
- "xt_stdlib.c",
445
- "xt_stdlib2.c",
446
- "xt_promise.c",
447
- "xt_async.c",
448
- "xt_loop.c",
449
- "xt_generator.c",
450
- "xt_coroutine.c",
451
- "xt_fetch.c",
452
- "xt_symbol.c",
453
- "xt_builtins.c",
454
- "xt_constructors.c",
455
- "xt_io.c",
456
- ] as const;
457
-
458
- /**
459
- * Compile the core runtime and every extension source, reusing cached object
460
- * files keyed on the C source hash. Returns the object paths to link.
461
- *
462
- * When `preferPrebuilt` is set, a shipped static archive
463
- * (`runtime/lib/<os>-<arch>/{core,ext_<name>}.a`) is used instead of compiling
464
- * that group's C sources. Missing archives fall back to compiling the sources.
465
- */
466
- function ensureRuntimeObjects(
467
- runner: Runner,
468
- clang: string,
469
- runtimeDir: string,
470
- cacheDir: string,
471
- registry: ExtensionRegistry,
472
- preferPrebuilt: boolean,
473
- env: Record<string, string>,
474
- ): RuntimeObjects {
475
- /* Runtime objects depend on the shared headers (rt.h/rt_internal.h/...) and
476
- the `#include`d implementation fragments (`.inc`), so any change to them
477
- must invalidate every cached object. Hash them all. */
478
- const headerParts: string[] = [];
479
- const collectHeaders = (dir: string): void => {
480
- for (const entry of readdirSync(dir, { withFileTypes: true })) {
481
- const full = join(dir, entry.name);
482
- if (entry.isDirectory()) collectHeaders(full);
483
- else if (entry.name.endsWith(".h") || entry.name.endsWith(".inc")) headerParts.push(readFileSync(full, "utf8"));
484
- }
485
- };
486
- collectHeaders(runtimeDir);
487
- const headerStamp = hashParts(headerParts);
488
-
489
- const compileOne = (sourcePath: string, tag: string): string => {
490
- const body = readFileSync(sourcePath, "utf8");
491
- const key = hashParts([
492
- "runtime",
493
- COMPILER_VERSION,
494
- RUNTIME_CFLAGS.join(" "),
495
- tag,
496
- headerStamp,
497
- body,
498
- clang,
499
- process.platform,
500
- ]);
501
- const objectPath = join(cacheDir, `${tag}-${key}.o`);
502
- if (!existsSync(objectPath)) {
503
- compileC(runner, clang, sourcePath, objectPath, runtimeDir, env);
504
- }
505
- return objectPath;
506
- };
507
-
508
- const coreArchive = preferPrebuilt ? findRuntimeLibrary("core") : undefined;
509
- const runtimeObjects = coreArchive
510
- ? [coreArchive]
511
- : RUNTIME_SOURCES.map((source) => compileOne(join(runtimeDir, source), basename(source, ".c")));
512
-
513
- const extensionObjects: string[] = [];
514
- const seen = new Set<string>();
515
- for (const extension of registry.all()) {
516
- const sources = extension.runtimeSources ? extension.runtimeSources() : [];
517
- if (sources.length === 0) continue;
518
- const archive = preferPrebuilt ? findRuntimeLibrary(`ext_${extension.name}`) : undefined;
519
- if (archive) {
520
- extensionObjects.push(archive);
521
- continue;
522
- }
523
- for (const sourcePath of sources) {
524
- const dedupeKey = resolve(sourcePath);
525
- if (seen.has(dedupeKey)) continue;
526
- seen.add(dedupeKey);
527
- extensionObjects.push(compileOne(sourcePath, `ext_${extensionObjects.length}_${basename(sourcePath, ".c")}`));
528
- }
529
- }
530
- // A native archive may be shared by several manifests; link each once.
531
- return { runtimeObjects, extensionObjects, nativeObjects: [...new Set(registry.nativeObjects())] };
532
- }
@@ -39,6 +39,9 @@ export interface ProjectConfig {
39
39
  readonly outDir?: string;
40
40
  readonly output?: string;
41
41
  readonly optimize?: "0" | "1" | "2" | "3";
42
+ readonly lto?: boolean;
43
+ readonly pgo?: "generate" | "use";
44
+ readonly pgoDir?: string;
42
45
  readonly extensions?: readonly string[];
43
46
  readonly extNative?: readonly string[];
44
47
  readonly force?: boolean;
@@ -103,6 +106,10 @@ export function parseProjectConfig(text: string, where: string = CONFIG_FILE_NAM
103
106
  if (optimize !== undefined && !["0", "1", "2", "3"].includes(optimize)) {
104
107
  throw new ProjectConfigError(`${where}: 'optimize' must be one of "0", "1", "2", "3"`);
105
108
  }
109
+ const pgo = readString(root, "pgo", where);
110
+ if (pgo !== undefined && pgo !== "generate" && pgo !== "use") {
111
+ throw new ProjectConfigError(`${where}: 'pgo' must be "generate" or "use"`);
112
+ }
106
113
 
107
114
  let app: AppConfig | undefined;
108
115
  if (root.app !== undefined) {
@@ -123,6 +130,9 @@ export function parseProjectConfig(text: string, where: string = CONFIG_FILE_NAM
123
130
  outDir: readString(root, "outDir", where),
124
131
  output: readString(root, "output", where),
125
132
  optimize: optimize as ProjectConfig["optimize"],
133
+ lto: readBoolean(root, "lto", where),
134
+ pgo: pgo as ProjectConfig["pgo"],
135
+ pgoDir: readString(root, "pgoDir", where),
126
136
  extensions: readStringArray(root, "extensions", where),
127
137
  extNative: readStringArray(root, "extNative", where),
128
138
  force: readBoolean(root, "force", where),
@@ -174,6 +184,7 @@ export function resolveConfigPaths(loaded: LoadedProjectConfig): ProjectConfig {
174
184
  ...(config.entry ? { entry: resolvePath(directory, config.entry) } : {}),
175
185
  ...(config.outDir ? { outDir: resolvePath(directory, config.outDir) } : {}),
176
186
  ...(config.output ? { output: resolvePath(directory, config.output) } : {}),
187
+ ...(config.pgoDir ? { pgoDir: resolvePath(directory, config.pgoDir) } : {}),
177
188
  ...(config.extNative ? { extNative: config.extNative.map((path) => resolvePath(directory, path)) } : {}),
178
189
  ...(app ? { app } : {}),
179
190
  };
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Front end: source text in, LLVM IR out (no toolchain involved).
3
+ *
4
+ * `compileString` compiles one in-memory source text; `compileEntry` reads a
5
+ * file and first bundles every reachable module. `build` reuses the same
6
+ * `parseEntry` step so the module graph is resolved identically for `emit`,
7
+ * `run` and `build`.
8
+ */
9
+
10
+ import { readFileSync } from "node:fs";
11
+ import { resolve } from "node:path";
12
+ import { DiagnosticBag } from "../diagnostics/diagnostic.js";
13
+ import { SourceFile } from "../diagnostics/source.js";
14
+ import { sourceTextBytes } from "../diagnostics/source-text.js";
15
+ import { Parser } from "../parser/parser.js";
16
+ import { generate } from "../codegen/llvm.js";
17
+ import { SyntaxKind, type SourceFileNode } from "../ast/nodes.js";
18
+ import { bundleModules } from "./modules.js";
19
+ import { createDefaultRegistry, type ExtensionRegistry } from "../extensions/registry.js";
20
+ import type { CompileStringResult } from "./options.js";
21
+
22
+ /**
23
+ * Every module specifier the registry can resolve at code generation time (the
24
+ * registered platform modules plus the hints for known-but-disabled
25
+ * extensions). Bare imports outside this set are looked up in `node_modules`
26
+ * and bundled as source.
27
+ */
28
+ function externalModuleSpecifiers(registry: ExtensionRegistry): Set<string> {
29
+ return new Set([
30
+ ...Object.keys(registry.modules()),
31
+ ...Object.keys(registry.moduleHints()),
32
+ ]);
33
+ }
34
+
35
+ /** A parsed (and, for module entries, already bundled) entry file. */
36
+ export interface ParsedEntry {
37
+ readonly absoluteEntry: string;
38
+ readonly sourceText: string;
39
+ readonly sourceFile: SourceFileNode;
40
+ /** The text the incremental cache hashes (the bundled text for modules). */
41
+ readonly cacheText: string;
42
+ }
43
+
44
+ /**
45
+ * Parse an entry file, bundling its module graph first when it uses
46
+ * `import`/`export`. The caller owns `diagnostics` and must not run code
47
+ * generation when it has errors (the tree would be missing nodes).
48
+ */
49
+ export function parseEntry(
50
+ entryPath: string,
51
+ registry: ExtensionRegistry,
52
+ diagnostics: DiagnosticBag,
53
+ ): ParsedEntry {
54
+ const absoluteEntry = resolve(entryPath);
55
+ const sourceText = sourceTextBytes(readFileSync(absoluteEntry, "utf8"));
56
+ const file = new SourceFile(absoluteEntry, sourceText);
57
+ const parser = new Parser(file, diagnostics);
58
+ let sourceFile = parser.parseSourceFile();
59
+ const isModule = sourceFile.statements.some(
60
+ (statement) =>
61
+ statement.kind === SyntaxKind.ImportDeclaration ||
62
+ statement.kind === SyntaxKind.ExportDeclaration ||
63
+ statement.kind === SyntaxKind.ExportAssignment,
64
+ );
65
+ let cacheText = sourceText;
66
+ if (isModule) {
67
+ const bundled = bundleModules(absoluteEntry, diagnostics, externalModuleSpecifiers(registry), registry.assetLoaders());
68
+ if (bundled) {
69
+ sourceFile = bundled.sourceFile;
70
+ cacheText = bundled.text;
71
+ }
72
+ }
73
+ return { absoluteEntry, sourceText, sourceFile, cacheText };
74
+ }
75
+
76
+ /** Compile TypeScript source text to LLVM IR without touching the toolchain. */
77
+ export function compileString(
78
+ source: string,
79
+ fileName = "input.ts",
80
+ extensions?: ExtensionRegistry,
81
+ options: { readonly debug?: boolean } = {},
82
+ ): CompileStringResult {
83
+ const file = new SourceFile(fileName, source);
84
+ const diagnostics = new DiagnosticBag();
85
+ const parser = new Parser(file, diagnostics);
86
+ const sourceFile = parser.parseSourceFile();
87
+ const registry = extensions ?? createDefaultRegistry();
88
+ /* Code generation assumes a well-formed tree (binder and codegen both read
89
+ * required children), so never lower a file that already failed to parse. */
90
+ if (diagnostics.hasErrors) return { ir: "", diagnostics: diagnostics.diagnostics };
91
+ const { ir } = generate(sourceFile, diagnostics, {
92
+ builtins: registry.builtins(),
93
+ modules: registry.modules(),
94
+ moduleHints: registry.moduleHints(),
95
+ debug: options.debug === true,
96
+ });
97
+ return { ir, diagnostics: diagnostics.diagnostics };
98
+ }
99
+
100
+ /**
101
+ * Compile a file to LLVM IR, bundling every reachable relative module first so
102
+ * that imports from other TypeScript sources resolve exactly like `build`.
103
+ */
104
+ export function compileEntry(
105
+ entryPath: string,
106
+ extensions?: ExtensionRegistry,
107
+ options: { readonly debug?: boolean } = {},
108
+ ): CompileStringResult {
109
+ const registry = extensions ?? createDefaultRegistry();
110
+ const diagnostics = new DiagnosticBag();
111
+ const parsed = parseEntry(entryPath, registry, diagnostics);
112
+ if (diagnostics.hasErrors) return { ir: "", diagnostics: diagnostics.diagnostics };
113
+ const { ir } = generate(parsed.sourceFile, diagnostics, {
114
+ builtins: registry.builtins(),
115
+ modules: registry.modules(),
116
+ moduleHints: registry.moduleHints(),
117
+ debug: options.debug === true,
118
+ });
119
+ return { ir, diagnostics: diagnostics.diagnostics };
120
+ }