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.
- package/AGENTS.md +20 -10
- package/README.md +8 -7
- package/README.zh-CN.md +6 -6
- package/dist/src/binder/declarations.js +14 -3
- package/dist/src/binder/declarations.js.map +1 -1
- package/dist/src/cli/hints.js +7 -1
- package/dist/src/cli/hints.js.map +1 -1
- package/dist/src/cli/main.js +115 -15
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/cli/watch.d.ts +25 -0
- package/dist/src/cli/watch.js +93 -0
- package/dist/src/cli/watch.js.map +1 -0
- package/dist/src/codegen/generator/calls/access.js +11 -2
- package/dist/src/codegen/generator/calls/access.js.map +1 -1
- package/dist/src/codegen/generator/calls/closures.js +12 -4
- package/dist/src/codegen/generator/calls/closures.js.map +1 -1
- package/dist/src/codegen/generator/context.d.ts +8 -0
- package/dist/src/codegen/generator/context.js +22 -3
- package/dist/src/codegen/generator/context.js.map +1 -1
- package/dist/src/codegen/generator/expressions/operators.js +17 -15
- package/dist/src/codegen/generator/expressions/operators.js.map +1 -1
- package/dist/src/codegen/generator/expressions/primary.js +5 -0
- package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
- package/dist/src/codegen/generator/module.js +0 -7
- package/dist/src/codegen/generator/module.js.map +1 -1
- package/dist/src/codegen/generator/numeric.d.ts +6 -3
- package/dist/src/codegen/generator/numeric.js +54 -11
- package/dist/src/codegen/generator/numeric.js.map +1 -1
- package/dist/src/codegen/generator/state.js +23 -0
- package/dist/src/codegen/generator/state.js.map +1 -1
- package/dist/src/codegen/generator/statements/control-flow.js +1 -4
- package/dist/src/codegen/generator/statements/control-flow.js.map +1 -1
- package/dist/src/codegen/generator/statements/loops.js +48 -16
- package/dist/src/codegen/generator/statements/loops.js.map +1 -1
- package/dist/src/codegen/generator/tables.js +26 -1
- package/dist/src/codegen/generator/tables.js.map +1 -1
- package/dist/src/diagnostics/diagnostic.d.ts +3 -1
- package/dist/src/diagnostics/diagnostic.js +23 -3
- package/dist/src/diagnostics/diagnostic.js.map +1 -1
- package/dist/src/driver/app-artifacts.d.ts +42 -0
- package/dist/src/driver/app-artifacts.js +53 -0
- package/dist/src/driver/app-artifacts.js.map +1 -0
- package/dist/src/driver/build-key.d.ts +29 -0
- package/dist/src/driver/build-key.js +35 -0
- package/dist/src/driver/build-key.js.map +1 -0
- package/dist/src/driver/bundler/graph.js +61 -12
- package/dist/src/driver/bundler/graph.js.map +1 -1
- package/dist/src/driver/bundler/merge.js +7 -1
- package/dist/src/driver/bundler/merge.js.map +1 -1
- package/dist/src/driver/compiler.d.ts +10 -67
- package/dist/src/driver/compiler.js +95 -234
- package/dist/src/driver/compiler.js.map +1 -1
- package/dist/src/driver/config.d.ts +3 -0
- package/dist/src/driver/config.js +8 -0
- package/dist/src/driver/config.js.map +1 -1
- package/dist/src/driver/frontend.d.ts +37 -0
- package/dist/src/driver/frontend.js +92 -0
- package/dist/src/driver/frontend.js.map +1 -0
- package/dist/src/driver/index.d.ts +1 -1
- package/dist/src/driver/index.js.map +1 -1
- package/dist/src/driver/options.d.ts +64 -0
- package/dist/src/driver/options.js +9 -0
- package/dist/src/driver/options.js.map +1 -0
- package/dist/src/driver/runtime-objects.d.ts +38 -0
- package/dist/src/driver/runtime-objects.js +112 -0
- package/dist/src/driver/runtime-objects.js.map +1 -0
- package/dist/src/driver/toolchain-provider.d.ts +4 -0
- package/dist/src/driver/toolchain-provider.js +4 -0
- package/dist/src/driver/toolchain-provider.js.map +1 -1
- package/dist/src/driver/toolchain.d.ts +32 -1
- package/dist/src/driver/toolchain.js +115 -11
- package/dist/src/driver/toolchain.js.map +1 -1
- package/dist/src/driver/version.d.ts +12 -0
- package/dist/src/driver/version.js +13 -0
- package/dist/src/driver/version.js.map +1 -0
- package/dist/src/driver/win-icon.d.ts +7 -9
- package/dist/src/driver/win-icon.js +37 -35
- package/dist/src/driver/win-icon.js.map +1 -1
- package/dist/src/extensions/node/fs/index.d.ts +4 -3
- package/dist/src/extensions/node/fs/index.js +12 -3
- package/dist/src/extensions/node/fs/index.js.map +1 -1
- package/dist/src/extensions/node/fs-promises/index.d.ts +5 -5
- package/dist/src/extensions/node/fs-promises/index.js +15 -6
- package/dist/src/extensions/node/fs-promises/index.js.map +1 -1
- package/dist/src/parser/declarations/classes.js +5 -0
- package/dist/src/parser/declarations/classes.js.map +1 -1
- package/dist/src/parser/declarations/functions.js +13 -1
- package/dist/src/parser/declarations/functions.js.map +1 -1
- package/dist/src/parser/modules.js +8 -3
- package/dist/src/parser/modules.js.map +1 -1
- package/dist/src/parser/parser.d.ts +1 -0
- package/dist/src/parser/parser.js +23 -0
- package/dist/src/parser/parser.js.map +1 -1
- package/dist/tests/cli/check.test.d.ts +6 -0
- package/dist/tests/cli/check.test.js +68 -0
- package/dist/tests/cli/check.test.js.map +1 -0
- package/dist/tests/cli/main.test.js +19 -0
- package/dist/tests/cli/main.test.js.map +1 -1
- package/dist/tests/cli/watch.test.d.ts +6 -0
- package/dist/tests/cli/watch.test.js +72 -0
- package/dist/tests/cli/watch.test.js.map +1 -0
- package/dist/tests/codegen/expressions.test.js +15 -3
- package/dist/tests/codegen/expressions.test.js.map +1 -1
- package/dist/tests/codegen/llvm.test.js +16 -0
- package/dist/tests/codegen/llvm.test.js.map +1 -1
- package/dist/tests/diagnostics/diagnostic.test.js +8 -0
- package/dist/tests/diagnostics/diagnostic.test.js.map +1 -1
- package/dist/tests/docs/structure.test.d.ts +1 -0
- package/dist/tests/docs/structure.test.js +92 -0
- package/dist/tests/docs/structure.test.js.map +1 -0
- package/dist/tests/driver/compiler.test.js +6 -0
- package/dist/tests/driver/compiler.test.js.map +1 -1
- package/dist/tests/driver/config.test.js +9 -0
- package/dist/tests/driver/config.test.js.map +1 -1
- package/dist/tests/driver/icon.test.js +19 -32
- package/dist/tests/driver/icon.test.js.map +1 -1
- package/dist/tests/driver/invalid-input.test.d.ts +10 -0
- package/dist/tests/driver/invalid-input.test.js +29 -0
- package/dist/tests/driver/invalid-input.test.js.map +1 -0
- package/dist/tests/driver/modules.test.js +42 -3
- package/dist/tests/driver/modules.test.js.map +1 -1
- package/dist/tests/driver/toolchain-provider.test.js +27 -1
- package/dist/tests/driver/toolchain-provider.test.js.map +1 -1
- package/dist/tests/driver/toolchain.test.js +60 -2
- package/dist/tests/driver/toolchain.test.js.map +1 -1
- package/dist/tests/e2e/array-buffer.test.d.ts +5 -0
- package/dist/tests/e2e/array-buffer.test.js +38 -0
- package/dist/tests/e2e/array-buffer.test.js.map +1 -0
- package/dist/tests/e2e/array-from-iterables.test.d.ts +7 -0
- package/dist/tests/e2e/array-from-iterables.test.js +34 -0
- package/dist/tests/e2e/array-from-iterables.test.js.map +1 -0
- package/dist/tests/e2e/array-symbol-iterator.test.d.ts +8 -0
- package/dist/tests/e2e/array-symbol-iterator.test.js +42 -0
- package/dist/tests/e2e/array-symbol-iterator.test.js.map +1 -0
- package/dist/tests/e2e/async-await.test.js +1 -1
- package/dist/tests/e2e/async-fs.test.d.ts +9 -0
- package/dist/tests/e2e/async-fs.test.js +119 -0
- package/dist/tests/e2e/async-fs.test.js.map +1 -0
- package/dist/tests/e2e/async-generators.test.d.ts +1 -0
- package/dist/tests/e2e/async-generators.test.js +154 -0
- package/dist/tests/e2e/async-generators.test.js.map +1 -0
- package/dist/tests/e2e/await-ordering.test.d.ts +5 -0
- package/dist/tests/e2e/await-ordering.test.js +37 -0
- package/dist/tests/e2e/await-ordering.test.js.map +1 -0
- package/dist/tests/e2e/compile-builtins.test.js +1 -1
- package/dist/tests/e2e/compile-modules.test.js +7 -0
- package/dist/tests/e2e/compile-modules.test.js.map +1 -1
- package/dist/tests/e2e/date-parse.test.d.ts +8 -0
- package/dist/tests/e2e/date-parse.test.js +38 -0
- package/dist/tests/e2e/date-parse.test.js.map +1 -0
- package/dist/tests/e2e/default-anonymous-exports.test.d.ts +7 -0
- package/dist/tests/e2e/default-anonymous-exports.test.js +23 -0
- package/dist/tests/e2e/default-anonymous-exports.test.js.map +1 -0
- package/dist/tests/e2e/fetch.test.js +24 -0
- package/dist/tests/e2e/fetch.test.js.map +1 -1
- package/dist/tests/e2e/globals-microtask.test.d.ts +9 -0
- package/dist/tests/e2e/globals-microtask.test.js +37 -0
- package/dist/tests/e2e/globals-microtask.test.js.map +1 -0
- package/dist/tests/e2e/gui-inline-svg.test.d.ts +11 -0
- package/dist/tests/e2e/gui-inline-svg.test.js +160 -0
- package/dist/tests/e2e/gui-inline-svg.test.js.map +1 -0
- package/dist/tests/e2e/gui-media.test.js +8 -1
- package/dist/tests/e2e/gui-media.test.js.map +1 -1
- package/dist/tests/e2e/inspect-builtins.test.d.ts +10 -0
- package/dist/tests/e2e/inspect-builtins.test.js +43 -0
- package/dist/tests/e2e/inspect-builtins.test.js.map +1 -0
- package/dist/tests/e2e/json-builtin-objects.test.d.ts +9 -0
- package/dist/tests/e2e/json-builtin-objects.test.js +23 -0
- package/dist/tests/e2e/json-builtin-objects.test.js.map +1 -0
- package/dist/tests/e2e/json-circular.test.d.ts +6 -0
- package/dist/tests/e2e/json-circular.test.js +43 -0
- package/dist/tests/e2e/json-circular.test.js.map +1 -0
- package/dist/tests/e2e/json-parse-reviver.test.d.ts +6 -0
- package/dist/tests/e2e/json-parse-reviver.test.js +29 -0
- package/dist/tests/e2e/json-parse-reviver.test.js.map +1 -0
- package/dist/tests/e2e/json-stringify-replacer.test.d.ts +6 -0
- package/dist/tests/e2e/json-stringify-replacer.test.js +27 -0
- package/dist/tests/e2e/json-stringify-replacer.test.js.map +1 -0
- package/dist/tests/e2e/json-stringify-space.test.d.ts +6 -0
- package/dist/tests/e2e/json-stringify-space.test.js +23 -0
- package/dist/tests/e2e/json-stringify-space.test.js.map +1 -0
- package/dist/tests/e2e/method-dispatch-errors.test.d.ts +9 -0
- package/dist/tests/e2e/method-dispatch-errors.test.js +38 -0
- package/dist/tests/e2e/method-dispatch-errors.test.js.map +1 -0
- package/dist/tests/e2e/native-extensions.test.js +1 -1
- package/dist/tests/e2e/native-extensions.test.js.map +1 -1
- package/dist/tests/e2e/promise-with-resolvers.test.d.ts +5 -0
- package/dist/tests/e2e/promise-with-resolvers.test.js +20 -0
- package/dist/tests/e2e/promise-with-resolvers.test.js.map +1 -0
- package/dist/tests/e2e/property-descriptors.test.d.ts +5 -0
- package/dist/tests/e2e/property-descriptors.test.js +25 -0
- package/dist/tests/e2e/property-descriptors.test.js.map +1 -0
- package/dist/tests/e2e/property-ic.test.d.ts +1 -0
- package/dist/tests/e2e/property-ic.test.js +55 -0
- package/dist/tests/e2e/property-ic.test.js.map +1 -0
- package/dist/tests/e2e/runtime-errors.test.d.ts +10 -0
- package/dist/tests/e2e/runtime-errors.test.js +52 -0
- package/dist/tests/e2e/runtime-errors.test.js.map +1 -0
- package/dist/tests/e2e/structured-clone.test.d.ts +6 -0
- package/dist/tests/e2e/structured-clone.test.js +49 -0
- package/dist/tests/e2e/structured-clone.test.js.map +1 -0
- package/dist/tests/e2e/text-codec.test.d.ts +6 -0
- package/dist/tests/e2e/text-codec.test.js +24 -0
- package/dist/tests/e2e/text-codec.test.js.map +1 -0
- package/dist/tests/e2e/typed-array-views.test.d.ts +6 -0
- package/dist/tests/e2e/typed-array-views.test.js +39 -0
- package/dist/tests/e2e/typed-array-views.test.js.map +1 -0
- package/dist/tests/e2e/url-search-params.test.d.ts +5 -0
- package/dist/tests/e2e/url-search-params.test.js +30 -0
- package/dist/tests/e2e/url-search-params.test.js.map +1 -0
- package/dist/tests/e2e/weak-collections.test.d.ts +1 -0
- package/dist/tests/e2e/weak-collections.test.js +88 -0
- package/dist/tests/e2e/weak-collections.test.js.map +1 -0
- package/dist/tests/parser/declarations.test.js +12 -0
- package/dist/tests/parser/declarations.test.js.map +1 -1
- package/dist/tests/parser/module-syntax.test.js +9 -0
- package/dist/tests/parser/module-syntax.test.js.map +1 -1
- package/dist/tests/parser/parser.test.js +7 -0
- package/dist/tests/parser/parser.test.js.map +1 -1
- package/dist/tests/version.test.js +5 -1
- package/dist/tests/version.test.js.map +1 -1
- package/doc/ai/README.md +4 -3
- package/doc/ai/cli.md +41 -0
- package/doc/ai/contributing.md +20 -16
- package/doc/ai/extensions.md +13 -10
- package/doc/ai/language-support.md +19 -14
- package/doc/ai/troubleshooting.md +11 -9
- package/doc/ai/zh-CN/README.md +3 -2
- package/doc/ai/zh-CN/cli.md +35 -0
- package/doc/ai/zh-CN/contributing.md +16 -15
- package/doc/ai/zh-CN/extensions.md +12 -9
- package/doc/ai/zh-CN/language-support.md +19 -15
- package/doc/ai/zh-CN/troubleshooting.md +9 -8
- package/doc/gui/api.md +8 -0
- package/doc/gui/build.md +13 -4
- package/doc/gui/known-issues.md +19 -14
- package/doc/gui/media.md +32 -3
- package/doc/gui/rendering.md +3 -1
- package/doc/gui.md +28 -5
- package/doc/icon.md +5 -4
- package/doc/implemented/async.md +51 -0
- package/doc/implemented/binder.md +13 -0
- package/doc/implemented/cli.md +47 -0
- package/doc/implemented/codegen.md +33 -0
- package/doc/implemented/collections.md +26 -0
- package/doc/implemented/driver.md +19 -0
- package/doc/implemented/extensions.md +19 -0
- package/doc/implemented/fetch.md +44 -0
- package/doc/implemented/lexer.md +23 -0
- package/doc/implemented/modules.md +28 -0
- package/doc/implemented/node/assert.md +17 -0
- package/doc/implemented/node/buffer.md +29 -0
- package/doc/implemented/node/child-process.md +29 -0
- package/doc/implemented/node/crypto.md +9 -0
- package/doc/implemented/node/dgram.md +15 -0
- package/doc/implemented/node/events.md +37 -0
- package/doc/implemented/node/fs-promises.md +49 -0
- package/doc/implemented/node/fs.md +112 -0
- package/doc/implemented/node/http.md +21 -0
- package/doc/implemented/node/net.md +17 -0
- package/doc/implemented/node/os.md +22 -0
- package/doc/implemented/node/path.md +33 -0
- package/doc/implemented/node/process.md +23 -0
- package/doc/implemented/node/querystring.md +20 -0
- package/doc/implemented/node/stream-promises.md +8 -0
- package/doc/implemented/node/stream.md +19 -0
- package/doc/implemented/node/test.md +10 -0
- package/doc/implemented/node/url.md +8 -0
- package/doc/implemented/node/util.md +25 -0
- package/doc/implemented/node/worker-threads.md +10 -0
- package/doc/implemented/node/zlib.md +8 -0
- package/doc/implemented/node.md +48 -0
- package/doc/implemented/operators.md +38 -0
- package/doc/implemented/parser.md +58 -0
- package/doc/implemented/pipeline.md +28 -0
- package/doc/implemented/runtime-core.md +32 -0
- package/doc/implemented/stdlib.md +78 -0
- package/doc/implemented/strings.md +27 -0
- package/doc/implemented/tests.md +10 -0
- package/doc/implemented/typed-arrays.md +26 -0
- package/doc/implemented/value-model.md +18 -0
- package/doc/implemented.md +54 -355
- package/doc/node-implemented.md +3 -585
- package/doc/node-unimplemented.md +3 -164
- package/doc/requirements.md +23 -8
- package/doc/unimplemented/classes.md +22 -0
- package/doc/unimplemented/deviations.md +27 -0
- package/doc/unimplemented/expressions.md +26 -0
- package/doc/unimplemented/functions.md +21 -0
- package/doc/unimplemented/modules.md +22 -0
- package/doc/unimplemented/node/async.md +20 -0
- package/doc/unimplemented/node/bun.md +9 -0
- package/doc/unimplemented/node/fs-promises.md +20 -0
- package/doc/unimplemented/node/fs.md +30 -0
- package/doc/unimplemented/node/globals.md +23 -0
- package/doc/unimplemented/node/modules.md +21 -0
- package/doc/unimplemented/node.md +21 -0
- package/doc/unimplemented/statements.md +18 -0
- package/doc/unimplemented/stdlib.md +54 -0
- package/doc/unimplemented/toolchain.md +14 -0
- package/doc/unimplemented/types.md +12 -0
- package/doc/unimplemented.md +18 -275
- package/doc/xbintsc.config.schema.json +12 -0
- package/doc/zh-CN/gui/api.md +7 -0
- package/doc/zh-CN/gui/build.md +11 -3
- package/doc/zh-CN/gui/known-issues.md +17 -11
- package/doc/zh-CN/gui/media.md +26 -2
- package/doc/zh-CN/gui/rendering.md +2 -1
- package/doc/zh-CN/gui.md +21 -3
- package/doc/zh-CN/icon.md +5 -4
- package/doc/zh-CN/implemented/async.md +49 -0
- package/doc/zh-CN/implemented/binder.md +13 -0
- package/doc/zh-CN/implemented/cli.md +46 -0
- package/doc/zh-CN/implemented/codegen.md +33 -0
- package/doc/zh-CN/implemented/collections.md +26 -0
- package/doc/zh-CN/implemented/driver.md +19 -0
- package/doc/zh-CN/implemented/extensions.md +19 -0
- package/doc/zh-CN/implemented/fetch.md +31 -0
- package/doc/zh-CN/implemented/lexer.md +23 -0
- package/doc/zh-CN/implemented/modules.md +28 -0
- package/doc/zh-CN/implemented/node/assert.md +17 -0
- package/doc/zh-CN/implemented/node/buffer.md +25 -0
- package/doc/zh-CN/implemented/node/child-process.md +27 -0
- package/doc/zh-CN/implemented/node/crypto.md +9 -0
- package/doc/zh-CN/implemented/node/dgram.md +15 -0
- package/doc/zh-CN/implemented/node/events.md +36 -0
- package/doc/zh-CN/implemented/node/fs-promises.md +30 -0
- package/doc/zh-CN/implemented/node/fs.md +105 -0
- package/doc/zh-CN/implemented/node/http.md +17 -0
- package/doc/zh-CN/implemented/node/net.md +17 -0
- package/doc/zh-CN/implemented/node/os.md +21 -0
- package/doc/zh-CN/implemented/node/path.md +26 -0
- package/doc/zh-CN/implemented/node/process.md +23 -0
- package/doc/zh-CN/implemented/node/querystring.md +20 -0
- package/doc/zh-CN/implemented/node/stream-promises.md +8 -0
- package/doc/zh-CN/implemented/node/stream.md +15 -0
- package/doc/zh-CN/implemented/node/test.md +10 -0
- package/doc/zh-CN/implemented/node/url.md +8 -0
- package/doc/zh-CN/implemented/node/util.md +25 -0
- package/doc/zh-CN/implemented/node/worker-threads.md +9 -0
- package/doc/zh-CN/implemented/node/zlib.md +8 -0
- package/doc/zh-CN/implemented/node.md +45 -0
- package/doc/zh-CN/implemented/operators.md +38 -0
- package/doc/zh-CN/implemented/parser.md +58 -0
- package/doc/zh-CN/implemented/pipeline.md +25 -0
- package/doc/zh-CN/implemented/runtime-core.md +31 -0
- package/doc/zh-CN/implemented/stdlib.md +76 -0
- package/doc/zh-CN/implemented/strings.md +27 -0
- package/doc/zh-CN/implemented/tests.md +10 -0
- package/doc/zh-CN/implemented/typed-arrays.md +26 -0
- package/doc/zh-CN/implemented/value-model.md +18 -0
- package/doc/zh-CN/implemented.md +50 -350
- package/doc/zh-CN/node-implemented.md +4 -531
- package/doc/zh-CN/node-unimplemented.md +4 -139
- package/doc/zh-CN/plan-require-node-modules.md +4 -4
- package/doc/zh-CN/requirements.md +20 -6
- package/doc/zh-CN/unimplemented/classes.md +22 -0
- package/doc/zh-CN/unimplemented/deviations.md +24 -0
- package/doc/zh-CN/unimplemented/expressions.md +24 -0
- package/doc/zh-CN/unimplemented/functions.md +21 -0
- package/doc/zh-CN/unimplemented/modules.md +19 -0
- package/doc/zh-CN/unimplemented/node/async.md +20 -0
- package/doc/zh-CN/unimplemented/node/bun.md +8 -0
- package/doc/zh-CN/unimplemented/node/fs-promises.md +12 -0
- package/doc/zh-CN/unimplemented/node/fs.md +24 -0
- package/doc/zh-CN/unimplemented/node/globals.md +14 -0
- package/doc/zh-CN/unimplemented/node/modules.md +15 -0
- package/doc/zh-CN/unimplemented/node.md +18 -0
- package/doc/zh-CN/unimplemented/statements.md +15 -0
- package/doc/zh-CN/unimplemented/stdlib.md +54 -0
- package/doc/zh-CN/unimplemented/toolchain.md +14 -0
- package/doc/zh-CN/unimplemented/types.md +11 -0
- package/doc/zh-CN/unimplemented.md +14 -237
- package/llms.txt +32 -4
- package/package.json +1 -1
- package/runtime/ext_gui/inline_svg.cpp +219 -0
- package/runtime/ext_gui/inline_svg.h +41 -0
- package/runtime/ext_gui/layout.cpp +18 -0
- package/runtime/ext_gui/layout.h +7 -0
- package/runtime/ext_gui/layout_flow.cpp +4 -3
- package/runtime/ext_gui/paint.cpp +14 -0
- package/runtime/ext_gui/paint.h +5 -1
- package/runtime/ext_gui/renderer_image.cpp +53 -25
- package/runtime/ext_gui/renderer_shaders.h +2 -2
- package/runtime/ext_gui/stb_image.h +1 -17
- package/runtime/ext_gui/style_ua.cpp +3 -0
- package/runtime/ext_gui/svg.cpp +122 -39
- package/runtime/ext_gui/svg.h +14 -3
- package/runtime/ext_gui/window.cpp +28 -0
- package/runtime/ext_node/child_process/child_process.c +173 -73
- package/runtime/ext_node/fs/async_api.c +314 -0
- package/runtime/ext_node/fs/async_complete.c +99 -0
- package/runtime/ext_node/fs/async_fh.c +206 -0
- package/runtime/ext_node/fs/async_job.c +81 -0
- package/runtime/ext_node/fs/async_job.h +132 -0
- package/runtime/ext_node/fs/async_worker.c +534 -0
- package/runtime/ext_node/fs/async_worker_dir.c +439 -0
- package/runtime/ext_node/fs/async_worker_dir.h +33 -0
- package/runtime/ext_node/fs/async_worker_fd.c +74 -0
- package/runtime/ext_node/fs/dir.c +60 -15
- package/runtime/ext_node/fs/fs_common.h +9 -0
- package/runtime/ext_node/fs/fs_ops.c +18 -29
- package/runtime/ext_node/fs/parts/builtins.inc +34 -0
- package/runtime/ext_node/fs/parts/platform.inc +66 -0
- package/runtime/ext_node/fs/promises.c +44 -234
- package/runtime/rt.h +15 -0
- package/runtime/rt_internal.h +108 -0
- package/runtime/xt_alloc.c +43 -7
- package/runtime/xt_array_buffer.c +284 -0
- package/runtime/xt_async.c +46 -21
- package/runtime/xt_async_io.c +333 -0
- package/runtime/xt_async_io.h +47 -0
- package/runtime/xt_bigint/helpers.inc +3 -3
- package/runtime/xt_builtins.c +21 -17
- package/runtime/xt_constructors.c +12 -2
- package/runtime/xt_containers/access.inc +148 -3
- package/runtime/xt_containers/objects.inc +26 -2
- package/runtime/xt_containers/shapes.inc +71 -0
- package/runtime/xt_containers.c +1 -0
- package/runtime/xt_coroutine.c +17 -0
- package/runtime/xt_fetch/async.inc +295 -0
- package/runtime/xt_fetch/request.inc +6 -183
- package/runtime/xt_fetch/socket.inc +5 -4
- package/runtime/xt_fetch.c +6 -4
- package/runtime/xt_generator.c +299 -10
- package/runtime/xt_io/inspect.inc +112 -0
- package/runtime/xt_loop.c +79 -7
- package/runtime/xt_performance.c +37 -0
- package/runtime/xt_promise.c +63 -1
- package/runtime/xt_stdlib/arrays.inc +1 -1
- package/runtime/xt_stdlib/dispatch.inc +46 -11
- package/runtime/xt_stdlib/strings.inc +1 -1
- package/runtime/xt_stdlib2/array-statics.inc +25 -0
- package/runtime/xt_stdlib2/arrays.inc +5 -3
- package/runtime/xt_stdlib2/container.inc +5 -0
- package/runtime/xt_stdlib2/date.inc +111 -3
- package/runtime/xt_stdlib2/error.inc +24 -0
- package/runtime/xt_stdlib2/json.inc +310 -19
- package/runtime/xt_stdlib2/number-string-statics.inc +1 -1
- package/runtime/xt_stdlib2/objects.inc +122 -0
- package/runtime/xt_stdlib2/set.inc +1 -1
- package/runtime/xt_structured_clone.c +159 -0
- package/runtime/xt_symbol.c +2 -2
- package/runtime/xt_text_codec.c +69 -0
- package/runtime/xt_typed_array/construction.inc +35 -5
- package/runtime/xt_typed_array/elements.inc +159 -0
- package/runtime/xt_typed_array/methods.inc +21 -5
- package/runtime/xt_typed_array.c +7 -10
- package/runtime/xt_url.c +375 -0
- package/runtime/xt_values/arithmetic.inc +2 -2
- package/runtime/xt_values/conversions.inc +1 -1
- package/runtime/xt_weak.c +281 -0
- package/scripts/build-gui.ts +133 -60
- package/scripts/check-version.ts +3 -3
- package/src/binder/declarations.ts +14 -3
- package/src/cli/hints.ts +8 -1
- package/src/cli/main.ts +119 -18
- package/src/cli/watch.ts +101 -0
- package/src/codegen/generator/calls/access.ts +10 -2
- package/src/codegen/generator/calls/closures.ts +12 -4
- package/src/codegen/generator/context.ts +23 -3
- package/src/codegen/generator/expressions/operators.ts +27 -13
- package/src/codegen/generator/expressions/primary.ts +4 -0
- package/src/codegen/generator/module.ts +0 -7
- package/src/codegen/generator/numeric.ts +85 -11
- package/src/codegen/generator/state.ts +23 -0
- package/src/codegen/generator/statements/control-flow.ts +1 -4
- package/src/codegen/generator/statements/loops.ts +50 -16
- package/src/codegen/generator/tables.ts +26 -1
- package/src/diagnostics/diagnostic.ts +23 -3
- package/src/driver/app-artifacts.ts +77 -0
- package/src/driver/build-key.ts +55 -0
- package/src/driver/bundler/graph.ts +63 -13
- package/src/driver/bundler/merge.ts +4 -1
- package/src/driver/compiler.ts +94 -328
- package/src/driver/config.ts +11 -0
- package/src/driver/frontend.ts +120 -0
- package/src/driver/index.ts +0 -1
- package/src/driver/options.ts +70 -0
- package/src/driver/runtime-objects.ts +134 -0
- package/src/driver/toolchain-provider.ts +4 -0
- package/src/driver/toolchain.ts +154 -10
- package/src/driver/version.ts +12 -0
- package/src/driver/win-icon.ts +36 -36
- package/src/extensions/node/fs/index.ts +12 -3
- package/src/extensions/node/fs-promises/index.ts +15 -6
- package/src/parser/declarations/classes.ts +4 -0
- package/src/parser/declarations/functions.ts +12 -1
- package/src/parser/modules.ts +8 -4
- package/src/parser/parser.ts +28 -0
package/src/driver/compiler.ts
CHANGED
|
@@ -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 {
|
|
15
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
11
16
|
import { basename, dirname, extname, join, resolve } from "node:path";
|
|
12
|
-
import { DiagnosticBag, DiagnosticCode
|
|
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 {
|
|
18
|
-
import {
|
|
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 {
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
} from "./
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
|
220
|
-
|
|
95
|
+
const parsed = parseEntry(absoluteEntry, registry, diagnostics);
|
|
96
|
+
timings.push({ phase: "frontend", ms: Date.now() - buildStarted });
|
|
221
97
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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 =
|
|
256
|
-
|
|
257
|
-
compilerFingerprint(),
|
|
258
|
-
cacheText,
|
|
120
|
+
const cacheKey = buildCacheKey({
|
|
121
|
+
sourceText: parsed.cacheText,
|
|
259
122
|
emit,
|
|
260
123
|
optimize,
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
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
|
-
|
|
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, {
|
|
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
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
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
|
-
...
|
|
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
|
-
}
|
package/src/driver/config.ts
CHANGED
|
@@ -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
|
+
}
|