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/cli/main.ts
CHANGED
|
@@ -30,7 +30,6 @@ import {
|
|
|
30
30
|
thrownFailure,
|
|
31
31
|
toolchainPointer,
|
|
32
32
|
UNEXPECTED_FAILURE_HINT,
|
|
33
|
-
type DocumentationPointer,
|
|
34
33
|
} from "./hints.js";
|
|
35
34
|
import { createDefaultRegistry, type ExtensionRegistry } from "../extensions/registry.js";
|
|
36
35
|
import { bundledExtensions } from "../extensions/catalog.js";
|
|
@@ -44,6 +43,10 @@ import {
|
|
|
44
43
|
type AppConfig,
|
|
45
44
|
type ProjectConfig,
|
|
46
45
|
} from "../driver/config.js";
|
|
46
|
+
import { fingerprintTree, startWatching } from "./watch.js";
|
|
47
|
+
|
|
48
|
+
/** Sentinel: watch mode keeps the process alive instead of exiting. */
|
|
49
|
+
const KEEP_RUNNING = -1;
|
|
47
50
|
|
|
48
51
|
export interface CliIo {
|
|
49
52
|
readonly stdout: (text: string) => void;
|
|
@@ -80,6 +83,8 @@ const VALUE_FLAGS = new Set([
|
|
|
80
83
|
"icon",
|
|
81
84
|
"app-id",
|
|
82
85
|
"app-name",
|
|
86
|
+
"pgo-generate",
|
|
87
|
+
"pgo-use",
|
|
83
88
|
]);
|
|
84
89
|
|
|
85
90
|
function parseArgs(argv: readonly string[]): ParsedArgs {
|
|
@@ -200,22 +205,29 @@ function emitHint(io: CliIo, line: string): void {
|
|
|
200
205
|
* the question.
|
|
201
206
|
*/
|
|
202
207
|
function reportThrown(error: unknown, io: CliIo): number {
|
|
203
|
-
|
|
204
|
-
error
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const
|
|
210
|
-
|
|
208
|
+
if (error instanceof ToolchainError) {
|
|
209
|
+
io.stderr(`xbintsc: ${error.message.trimEnd()}\n`);
|
|
210
|
+
const pointer = toolchainPointer(error.message);
|
|
211
|
+
emitHint(io, `hint: ${pointer.text} — see ${pointer.path}`);
|
|
212
|
+
return 1;
|
|
213
|
+
}
|
|
214
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
215
|
+
const failure = thrownFailure(message);
|
|
216
|
+
if (failure === undefined) {
|
|
217
|
+
/* An uncaught exception that is not a known toolchain/setup failure is a
|
|
218
|
+
* compiler bug: say so instead of blaming the user's source or toolchain. */
|
|
219
|
+
io.stderr(`xbintsc: internal error: ${message.trimEnd()}\n`);
|
|
220
|
+
emitHint(
|
|
221
|
+
io,
|
|
222
|
+
`hint: this is a bug in xbintsc, not in your program — please report it with the input that triggered it — see ${UNEXPECTED_FAILURE_HINT.path}`,
|
|
223
|
+
);
|
|
224
|
+
return 1;
|
|
225
|
+
}
|
|
226
|
+
io.stderr(`xbintsc: ${message.trimEnd()}\n`);
|
|
227
|
+
emitHint(io, `hint: ${failure.pointer.text} — see ${failure.pointer.path}`);
|
|
211
228
|
return 1;
|
|
212
229
|
}
|
|
213
230
|
|
|
214
|
-
/** The document that explains a failure the CLI reports as a plain message. */
|
|
215
|
-
function thrownPointer(message: string): DocumentationPointer {
|
|
216
|
-
return thrownFailure(message)?.pointer ?? UNEXPECTED_FAILURE_HINT;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
231
|
/** Report a project-config failure, which never becomes a diagnostic bag. */
|
|
220
232
|
function reportConfigError(error: string, io: CliIo): number {
|
|
221
233
|
io.stderr(`xbintsc: ${error}\n`);
|
|
@@ -231,6 +243,8 @@ const HELP = `xbintsc ${COMPILER_VERSION} - TypeScript binary compiler
|
|
|
231
243
|
Usage:
|
|
232
244
|
xbintsc build <file.ts> [options] Compile to a native binary
|
|
233
245
|
xbintsc run <file.ts> [-- args] Compile and execute
|
|
246
|
+
xbintsc check <file.ts> Parse and bind without linking
|
|
247
|
+
xbintsc watch <file.ts> [options] Rebuild whenever the source tree changes
|
|
234
248
|
xbintsc emit <file.ts> Print LLVM IR
|
|
235
249
|
xbintsc doctor Report the resolved toolchain
|
|
236
250
|
xbintsc version Print the version
|
|
@@ -255,11 +269,15 @@ Options:
|
|
|
255
269
|
--verbose Print progress information
|
|
256
270
|
--time Print per-phase build timings
|
|
257
271
|
--debug Emit debug info (DWARF/CodeView) and keep frame pointers
|
|
272
|
+
--lto Compile program and runtime to LTO bitcode; link with lld
|
|
273
|
+
--pgo-generate [dir] Build an instrumented binary writing profiles to dir
|
|
274
|
+
--pgo-use [dir] Build with the profiles collected from --pgo-generate
|
|
275
|
+
--json Print diagnostics as a JSON array on stdout
|
|
258
276
|
--no-hints Do not append the "hint: … see <doc>" line to failures
|
|
259
277
|
|
|
260
278
|
xbintsc compiles a subset of TypeScript to a native binary. Types are erased
|
|
261
|
-
(never checked), Node
|
|
262
|
-
|
|
279
|
+
(never checked), Node built-ins need --ext node, packages in node_modules are
|
|
280
|
+
bundled at build time, and clang 16+ is required to link.
|
|
263
281
|
|
|
264
282
|
Docs: doc/ai/README.md (task guide) - doc/ai/language-support.md (subset) -
|
|
265
283
|
doc/ai/troubleshooting.md (failures) - llms.txt (index of every document)
|
|
@@ -323,7 +341,7 @@ function doctor(io: CliIo): number {
|
|
|
323
341
|
try {
|
|
324
342
|
if (!toolchain) throw new Error("no toolchain");
|
|
325
343
|
const resource = resolveResourceCompiler(realRunner, toolchain.clang);
|
|
326
|
-
io.stdout(`icon res : ${resource ?
|
|
344
|
+
io.stdout(`icon res : ${resource ? resource.tool : "none (.exe icon disabled)"}\n`);
|
|
327
345
|
} catch {
|
|
328
346
|
io.stdout("icon res : unknown\n");
|
|
329
347
|
}
|
|
@@ -414,6 +432,57 @@ function dispatch(argv: readonly string[], io: CliIo): number {
|
|
|
414
432
|
return 0;
|
|
415
433
|
}
|
|
416
434
|
|
|
435
|
+
if (command === "check") {
|
|
436
|
+
const cliEntry = args.positionals[0];
|
|
437
|
+
const resolved = resolveProjectConfig(args.flags, cliEntry);
|
|
438
|
+
if (!resolved.ok) return reportConfigError(resolved.error, io);
|
|
439
|
+
const entry = cliEntry ?? resolved.config.entry;
|
|
440
|
+
if (!entry) {
|
|
441
|
+
io.stderr(`xbintsc: check requires a source file (or 'entry' in ${CONFIG_FILE_NAME})\n`);
|
|
442
|
+
emitHint(io, `hint: pass the entry file, or set 'entry' in ${CONFIG_FILE_NAME} — see ${DOC_CLI}`);
|
|
443
|
+
return 1;
|
|
444
|
+
}
|
|
445
|
+
const extNames = listFlag(args.flags, "ext") ?? resolved.config.extensions ?? [];
|
|
446
|
+
const nativeManifests = listFlag(args.flags, "ext-native") ?? resolved.config.extNative ?? [];
|
|
447
|
+
const registry = buildRegistry(extNames, nativeManifests);
|
|
448
|
+
/* Front-end only: parse, bundle and lower far enough to report binder /
|
|
449
|
+
* unsupported-feature diagnostics, but never invoke clang or write output. */
|
|
450
|
+
const { diagnostics } = compileEntry(entry, registry);
|
|
451
|
+
const failed = diagnostics.some((diagnostic) => diagnostic.category === "error");
|
|
452
|
+
if (args.flags.has("json")) {
|
|
453
|
+
io.stdout(`${JSON.stringify(diagnostics)}\n`);
|
|
454
|
+
} else if (failed) {
|
|
455
|
+
printDiagnostics(diagnostics, entry, io);
|
|
456
|
+
}
|
|
457
|
+
return failed ? 1 : 0;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
if (command === "watch") {
|
|
461
|
+
const cliEntry = args.positionals[0];
|
|
462
|
+
const resolved = resolveProjectConfig(args.flags, cliEntry);
|
|
463
|
+
if (!resolved.ok) return reportConfigError(resolved.error, io);
|
|
464
|
+
const entry = cliEntry ?? resolved.config.entry;
|
|
465
|
+
if (!entry) {
|
|
466
|
+
io.stderr(`xbintsc: watch requires a source file (or 'entry' in ${CONFIG_FILE_NAME})\n`);
|
|
467
|
+
emitHint(io, `hint: pass the entry file, or set 'entry' in ${CONFIG_FILE_NAME} — see ${DOC_CLI}`);
|
|
468
|
+
return 1;
|
|
469
|
+
}
|
|
470
|
+
/* Re-enter the normal build path with the same flags, exactly as if the
|
|
471
|
+
* user had typed `build`; the config is re-read on every rebuild too. */
|
|
472
|
+
const forwarded = ["build", ...argv.slice(1)];
|
|
473
|
+
run(forwarded, io);
|
|
474
|
+
const root = dirname(resolve(entry));
|
|
475
|
+
startWatching({
|
|
476
|
+
scan: () => fingerprintTree(root),
|
|
477
|
+
onRebuild: () => {
|
|
478
|
+
io.stdout("\n");
|
|
479
|
+
run(forwarded, io);
|
|
480
|
+
},
|
|
481
|
+
});
|
|
482
|
+
io.stdout(`xbintsc: watching ${root} for changes (Ctrl+C to stop)\n`);
|
|
483
|
+
return KEEP_RUNNING;
|
|
484
|
+
}
|
|
485
|
+
|
|
417
486
|
if (command === "emit") {
|
|
418
487
|
const cliEntry = args.positionals[0];
|
|
419
488
|
const resolved = resolveProjectConfig(args.flags, cliEntry);
|
|
@@ -429,6 +498,10 @@ function dispatch(argv: readonly string[], io: CliIo): number {
|
|
|
429
498
|
const registry = buildRegistry(extNames, nativeManifests);
|
|
430
499
|
const { ir, diagnostics } = compileEntry(entry, registry, { debug: Boolean(args.flags.get("debug")) });
|
|
431
500
|
if (diagnostics.some((d) => d.category === "error")) {
|
|
501
|
+
if (args.flags.has("json")) {
|
|
502
|
+
io.stdout(`${JSON.stringify(diagnostics)}\n`);
|
|
503
|
+
return 1;
|
|
504
|
+
}
|
|
432
505
|
printDiagnostics(diagnostics, entry, io);
|
|
433
506
|
return 1;
|
|
434
507
|
}
|
|
@@ -452,6 +525,24 @@ function dispatch(argv: readonly string[], io: CliIo): number {
|
|
|
452
525
|
const extNames = listFlag(args.flags, "ext") ?? config.extensions ?? [];
|
|
453
526
|
const nativeManifests = listFlag(args.flags, "ext-native") ?? config.extNative ?? [];
|
|
454
527
|
const registry = buildRegistry(extNames, nativeManifests);
|
|
528
|
+
const pgoGenerate = args.flags.get("pgo-generate");
|
|
529
|
+
const pgoUse = args.flags.get("pgo-use");
|
|
530
|
+
if (pgoGenerate !== undefined && pgoUse !== undefined) {
|
|
531
|
+
io.stderr("xbintsc: --pgo-generate and --pgo-use are mutually exclusive\n");
|
|
532
|
+
return 1;
|
|
533
|
+
}
|
|
534
|
+
const pgo =
|
|
535
|
+
pgoGenerate !== undefined
|
|
536
|
+
? ("generate" as const)
|
|
537
|
+
: pgoUse !== undefined
|
|
538
|
+
? ("use" as const)
|
|
539
|
+
: config.pgo;
|
|
540
|
+
const pgoDir =
|
|
541
|
+
typeof pgoGenerate === "string"
|
|
542
|
+
? pgoGenerate
|
|
543
|
+
: typeof pgoUse === "string"
|
|
544
|
+
? pgoUse
|
|
545
|
+
: config.pgoDir;
|
|
455
546
|
|
|
456
547
|
const result = build(entry, {
|
|
457
548
|
output: typeof args.flags.get("output") === "string" ? (args.flags.get("output") as string) : config.output,
|
|
@@ -463,9 +554,16 @@ function dispatch(argv: readonly string[], io: CliIo): number {
|
|
|
463
554
|
extensions: registry,
|
|
464
555
|
app: mergeAppConfig(args.flags, config),
|
|
465
556
|
debug: Boolean(args.flags.get("debug")),
|
|
557
|
+
lto: Boolean(args.flags.get("lto")) || config.lto === true,
|
|
558
|
+
...(pgo ? { pgo } : {}),
|
|
559
|
+
...(pgoDir ? { pgoDir } : {}),
|
|
466
560
|
});
|
|
467
561
|
|
|
468
562
|
if (result.diagnostics.some((d) => d.category === "error")) {
|
|
563
|
+
if (args.flags.has("json")) {
|
|
564
|
+
io.stdout(`${JSON.stringify(result.diagnostics)}\n`);
|
|
565
|
+
return 1;
|
|
566
|
+
}
|
|
469
567
|
printDiagnostics(result.diagnostics, entry, io);
|
|
470
568
|
return 1;
|
|
471
569
|
}
|
|
@@ -493,5 +591,8 @@ function dispatch(argv: readonly string[], io: CliIo): number {
|
|
|
493
591
|
const isMain =
|
|
494
592
|
process.argv[1] !== undefined && import.meta.url === pathToFileURL(process.argv[1]).href;
|
|
495
593
|
if (isMain) {
|
|
496
|
-
|
|
594
|
+
const status = run(process.argv.slice(2));
|
|
595
|
+
/* Watch mode returns KEEP_RUNNING; the polling interval keeps the process
|
|
596
|
+
* alive, so calling process.exit here would stop it immediately. */
|
|
597
|
+
if (status !== KEEP_RUNNING) process.exit(status);
|
|
497
598
|
}
|
package/src/cli/watch.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `xbintsc watch` support: fingerprint a source tree and rebuild when it
|
|
3
|
+
* changes.
|
|
4
|
+
*
|
|
5
|
+
* The scan is deliberately polling-based. A self-hosted xbintsc binary has no
|
|
6
|
+
* `fs.watch` backend in the Node extension, and polling works identically on
|
|
7
|
+
* every platform. The tree is the entry file's directory, with build outputs
|
|
8
|
+
* and dependency directories excluded; package sources inside `node_modules`
|
|
9
|
+
* are not watched (run the build once after installing a dependency).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { readFileSync, readdirSync, statSync, type Dirent } from "node:fs";
|
|
13
|
+
import { extname, join, resolve } from "node:path";
|
|
14
|
+
|
|
15
|
+
const WATCHED_EXTENSIONS = new Set([
|
|
16
|
+
".ts",
|
|
17
|
+
".tsx",
|
|
18
|
+
".js",
|
|
19
|
+
".mjs",
|
|
20
|
+
".cjs",
|
|
21
|
+
".json",
|
|
22
|
+
".html",
|
|
23
|
+
".css",
|
|
24
|
+
]);
|
|
25
|
+
|
|
26
|
+
const IGNORED_DIRECTORIES = new Set([
|
|
27
|
+
"node_modules",
|
|
28
|
+
".git",
|
|
29
|
+
".github",
|
|
30
|
+
".xbintsc",
|
|
31
|
+
".xbintsc-cache",
|
|
32
|
+
"build",
|
|
33
|
+
"dist",
|
|
34
|
+
"coverage",
|
|
35
|
+
"scratch",
|
|
36
|
+
"target",
|
|
37
|
+
"vendor",
|
|
38
|
+
]);
|
|
39
|
+
|
|
40
|
+
/** One string that changes whenever a watched file changes. */
|
|
41
|
+
export function fingerprintTree(root: string): string {
|
|
42
|
+
const entries: string[] = [];
|
|
43
|
+
collect(resolve(root), entries);
|
|
44
|
+
entries.sort();
|
|
45
|
+
return entries.join("|");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function collect(directory: string, out: string[]): void {
|
|
49
|
+
let entries: Dirent[];
|
|
50
|
+
try {
|
|
51
|
+
entries = readdirSync(directory, { withFileTypes: true });
|
|
52
|
+
} catch {
|
|
53
|
+
return; // the directory disappeared between scans
|
|
54
|
+
}
|
|
55
|
+
for (const entry of entries) {
|
|
56
|
+
const path = join(directory, entry.name);
|
|
57
|
+
if (entry.isDirectory()) {
|
|
58
|
+
if (!IGNORED_DIRECTORIES.has(entry.name)) collect(path, out);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (!entry.isFile()) continue;
|
|
62
|
+
if (!WATCHED_EXTENSIONS.has(extname(entry.name).toLowerCase())) continue;
|
|
63
|
+
try {
|
|
64
|
+
const stat = statSync(path);
|
|
65
|
+
/* mtime resolution is coarse on some filesystems (and on Windows two
|
|
66
|
+
* same-size writes can share a timestamp), so hash the bytes as well. */
|
|
67
|
+
let hash = 2166136261;
|
|
68
|
+
const contents = readFileSync(path);
|
|
69
|
+
for (let i = 0; i < contents.length; i++) {
|
|
70
|
+
hash = Math.imul(hash ^ (contents[i] ?? 0), 16777619);
|
|
71
|
+
}
|
|
72
|
+
out.push(`${path}:${stat.mtimeMs}:${stat.size}:${hash >>> 0}`);
|
|
73
|
+
} catch {
|
|
74
|
+
// A file removed during the scan is picked up by the next iteration.
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface WatchOptions {
|
|
80
|
+
/** Current fingerprint of everything that should trigger a rebuild. */
|
|
81
|
+
readonly scan: () => string;
|
|
82
|
+
/** Called after the fingerprint changes. Must be synchronous. */
|
|
83
|
+
readonly onRebuild: () => void;
|
|
84
|
+
/** Poll interval; defaults to 300 ms. */
|
|
85
|
+
readonly intervalMs?: number;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Start polling. Returns a stop function. The caller performs the initial
|
|
90
|
+
* build, so this never fires `onRebuild` for the state it starts in.
|
|
91
|
+
*/
|
|
92
|
+
export function startWatching(options: WatchOptions): () => void {
|
|
93
|
+
let previous = options.scan();
|
|
94
|
+
const timer = setInterval(() => {
|
|
95
|
+
const next = options.scan();
|
|
96
|
+
if (next === previous) return;
|
|
97
|
+
previous = next;
|
|
98
|
+
options.onRebuild();
|
|
99
|
+
}, options.intervalMs ?? 300);
|
|
100
|
+
return () => clearInterval(timer);
|
|
101
|
+
}
|
|
@@ -143,7 +143,14 @@ export const accessCallMethods: AccessCallMethods = {
|
|
|
143
143
|
const access = (): string => {
|
|
144
144
|
const key = this.emitExpression(node.argumentExpression);
|
|
145
145
|
const result = this.reg();
|
|
146
|
-
|
|
146
|
+
/* Array-index reads are not object property layouts, so skip the IC for
|
|
147
|
+
* a numeric literal; every other key may benefit from it. */
|
|
148
|
+
if (node.argumentExpression.kind === SyntaxKind.NumericLiteral) {
|
|
149
|
+
this.emit(` ${result} = call i64 @xt_get(i64 ${object}, i64 ${key})`);
|
|
150
|
+
} else {
|
|
151
|
+
const cache = this.icCachePointer();
|
|
152
|
+
this.emit(` ${result} = call i64 @xt_get_ic(i64 ${object}, i64 ${key}, i64* ${cache})`);
|
|
153
|
+
}
|
|
147
154
|
return result;
|
|
148
155
|
};
|
|
149
156
|
return node.optional ? this.emitOptional(object, access) : access();
|
|
@@ -158,8 +165,9 @@ export const accessCallMethods: AccessCallMethods = {
|
|
|
158
165
|
return result;
|
|
159
166
|
}
|
|
160
167
|
const key = this.stringValue(name);
|
|
168
|
+
const cache = this.icCachePointer();
|
|
161
169
|
const result = this.reg();
|
|
162
|
-
this.emit(` ${result} = call i64 @
|
|
170
|
+
this.emit(` ${result} = call i64 @xt_get_ic(i64 ${object}, i64 ${key}, i64* ${cache})`);
|
|
163
171
|
return result;
|
|
164
172
|
},
|
|
165
173
|
|
|
@@ -79,9 +79,17 @@ export const closureCallMethods: ClosureCallMethods = {
|
|
|
79
79
|
if (fn.isConstructor && fn.classInfo) name = fn.classInfo.name;
|
|
80
80
|
const nameValue = this.stringValue(name);
|
|
81
81
|
this.emit(` call i64 @xt_function_set_metadata(i64 ${closure}, i64 ${nameValue}, i32 ${arity})`);
|
|
82
|
-
if (fn.isGenerator)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
if (fn.isAsync && fn.isGenerator) {
|
|
83
|
+
/* `async function*`: a generator whose `.next()` returns promises. The
|
|
84
|
+
* runtime needs both flags, so use the combined marker instead of the
|
|
85
|
+
* two separate setters. */
|
|
86
|
+
this.emit(` call i64 @xt_function_set_async_generator(i64 ${closure})`);
|
|
87
|
+
} else if (fn.isGenerator) {
|
|
88
|
+
this.emit(` call i64 @xt_function_set_generator(i64 ${closure})`);
|
|
89
|
+
} else if (fn.isAsync) {
|
|
90
|
+
/* `async` functions run on a coroutine: the runtime must know at call
|
|
91
|
+
* time so it can return a promise and suspend at `await`. */
|
|
92
|
+
this.emit(` call i64 @xt_function_set_async(i64 ${closure})`);
|
|
93
|
+
}
|
|
86
94
|
},
|
|
87
95
|
};
|
|
@@ -64,6 +64,8 @@ export class GeneratorContext {
|
|
|
64
64
|
readonly lineStartsByFile = new Map<string, number[]>();
|
|
65
65
|
stringCounter = 0;
|
|
66
66
|
staticCounter = 0;
|
|
67
|
+
/** Monotonic id for per-property-access inline-cache globals. */
|
|
68
|
+
icCounter = 0;
|
|
67
69
|
/**
|
|
68
70
|
* How many `UnsupportedFeature` diagnostics the function currently being
|
|
69
71
|
* emitted produced. Unsupported constructs can leave the generator with a
|
|
@@ -187,8 +189,8 @@ export class GeneratorContext {
|
|
|
187
189
|
if (!symbols.some((symbol) => this.usedAsValue(symbol))) return;
|
|
188
190
|
this.diagnostics.error(
|
|
189
191
|
DiagnosticCode.ModuleNotFound,
|
|
190
|
-
`module '${specifier}' is not supported:
|
|
191
|
-
"relative
|
|
192
|
+
`module '${specifier}' is not supported: expected a Node built-in ` +
|
|
193
|
+
"(with --ext node), a relative .ts/.js file, or a package in node_modules",
|
|
192
194
|
declaration.moduleSpecifier,
|
|
193
195
|
this.fileNameOf(declaration.moduleSpecifier),
|
|
194
196
|
);
|
|
@@ -309,6 +311,19 @@ export class GeneratorContext {
|
|
|
309
311
|
return ptr;
|
|
310
312
|
}
|
|
311
313
|
|
|
314
|
+
/**
|
|
315
|
+
* Allocate a two-word inline cache for one property-access site and return
|
|
316
|
+
* the `i64*` the runtime fills with (shape, property index). The global is
|
|
317
|
+
* zero-initialised, which the runtime treats as an empty cache.
|
|
318
|
+
*/
|
|
319
|
+
icCachePointer(): string {
|
|
320
|
+
const name = `@ic.${this.icCounter++}`;
|
|
321
|
+
this.globals.push(`${name} = internal global [2 x i64] zeroinitializer`);
|
|
322
|
+
const ptr = this.reg();
|
|
323
|
+
this.emit(` ${ptr} = getelementptr [2 x i64], [2 x i64]* ${name}, i64 0, i64 0`);
|
|
324
|
+
return ptr;
|
|
325
|
+
}
|
|
326
|
+
|
|
312
327
|
/** Lay already-computed values out as a contiguous `i64*` argument buffer. */
|
|
313
328
|
emitValueArguments(values: readonly string[]): { argc: string; ptr: string } {
|
|
314
329
|
if (values.length === 0) return { argc: "0", ptr: "null" };
|
|
@@ -517,10 +532,15 @@ export class GeneratorContext {
|
|
|
517
532
|
|
|
518
533
|
unsupported(node: Node, what: string): void {
|
|
519
534
|
const label = kindName(node.kind);
|
|
535
|
+
const hasName = label !== String(node.kind);
|
|
536
|
+
/* `unsupported(statement, "statement")` is the generic fallback; when the
|
|
537
|
+
* syntax kind has a human name, use it directly instead of appending a
|
|
538
|
+
* redundant "(statement)". */
|
|
539
|
+
const subject = what === "statement" && hasName ? `this ${label}` : `this ${what} (${label})`;
|
|
520
540
|
this.unsupportedCount++;
|
|
521
541
|
this.diagnostics.error(
|
|
522
542
|
DiagnosticCode.UnsupportedFeature,
|
|
523
|
-
`xbintsc does not yet support
|
|
543
|
+
`xbintsc does not yet support ${subject}`,
|
|
524
544
|
node,
|
|
525
545
|
this.fileNameOf(node),
|
|
526
546
|
);
|
|
@@ -24,6 +24,15 @@ function isStringLike(node: Expression): boolean {
|
|
|
24
24
|
return node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NoSubstitutionTemplateLiteral;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
/** True for a numeric literal (optionally signed), whose tag check can be skipped. */
|
|
28
|
+
function isNumericLiteral(node: Expression): boolean {
|
|
29
|
+
if (node.kind === SyntaxKind.NumericLiteral) return true;
|
|
30
|
+
if (node.kind !== SyntaxKind.PrefixUnaryExpression) return false;
|
|
31
|
+
const prefix = node as PrefixUnaryExpression;
|
|
32
|
+
if (prefix.operator !== PrefixUnaryOperator.Minus && prefix.operator !== PrefixUnaryOperator.Plus) return false;
|
|
33
|
+
return prefix.operand.kind === SyntaxKind.NumericLiteral;
|
|
34
|
+
}
|
|
35
|
+
|
|
27
36
|
/**
|
|
28
37
|
* The built-in constructor a right-hand `instanceof` operand names, if any.
|
|
29
38
|
* A user binding with the same name shadows it.
|
|
@@ -84,7 +93,15 @@ export const operatorExpressionMethods: OperatorExpressionMethods = {
|
|
|
84
93
|
// `+` concatenates when either side is known to be a string; skip the
|
|
85
94
|
// numeric tag checks for that shape and call the runtime directly.
|
|
86
95
|
const knownStringConcat = operator === "+" && (isStringLike(node.left) || isStringLike(node.right));
|
|
87
|
-
return this.emitBinaryOperation(
|
|
96
|
+
return this.emitBinaryOperation(
|
|
97
|
+
left,
|
|
98
|
+
right,
|
|
99
|
+
operator,
|
|
100
|
+
runtime,
|
|
101
|
+
!knownStringConcat,
|
|
102
|
+
isNumericLiteral(node.left),
|
|
103
|
+
isNumericLiteral(node.right),
|
|
104
|
+
);
|
|
88
105
|
},
|
|
89
106
|
|
|
90
107
|
emitShortCircuit(node: BinaryExpression, kind: "and" | "or" | "nullish"): string {
|
|
@@ -95,15 +112,9 @@ export const operatorExpressionMethods: OperatorExpressionMethods = {
|
|
|
95
112
|
const endLabel = this.label("sc.end");
|
|
96
113
|
let condition: string;
|
|
97
114
|
if (kind === "and") {
|
|
98
|
-
|
|
99
|
-
this.emit(` ${truthy} = call i32 @xt_truthy(i64 ${left})`);
|
|
100
|
-
condition = this.reg();
|
|
101
|
-
this.emit(` ${condition} = icmp ne i32 ${truthy}, 0`);
|
|
115
|
+
condition = this.emitTruthiness(left, node.left);
|
|
102
116
|
} else if (kind === "or") {
|
|
103
|
-
const
|
|
104
|
-
this.emit(` ${truthy} = call i32 @xt_truthy(i64 ${left})`);
|
|
105
|
-
const isTruthy = this.reg();
|
|
106
|
-
this.emit(` ${isTruthy} = icmp ne i32 ${truthy}, 0`);
|
|
117
|
+
const isTruthy = this.emitTruthiness(left, node.left);
|
|
107
118
|
condition = this.reg();
|
|
108
119
|
this.emit(` ${condition} = xor i1 ${isTruthy}, true`);
|
|
109
120
|
} else {
|
|
@@ -128,10 +139,7 @@ export const operatorExpressionMethods: OperatorExpressionMethods = {
|
|
|
128
139
|
emitConditional(node: ConditionalExpression): string {
|
|
129
140
|
const result = this.alloca();
|
|
130
141
|
const condition = this.emitExpression(node.condition);
|
|
131
|
-
const
|
|
132
|
-
this.emit(` ${truthy} = call i32 @xt_truthy(i64 ${condition})`);
|
|
133
|
-
const nonzero = this.reg();
|
|
134
|
-
this.emit(` ${nonzero} = icmp ne i32 ${truthy}, 0`);
|
|
142
|
+
const nonzero = this.emitTruthiness(condition, node.condition);
|
|
135
143
|
const trueLabel = this.label("cond.true");
|
|
136
144
|
const falseLabel = this.label("cond.false");
|
|
137
145
|
const endLabel = this.label("cond.end");
|
|
@@ -195,6 +203,9 @@ export const operatorExpressionMethods: OperatorExpressionMethods = {
|
|
|
195
203
|
one,
|
|
196
204
|
node.operator === PrefixUnaryOperator.PlusPlus ? "+" : "-",
|
|
197
205
|
fn,
|
|
206
|
+
true,
|
|
207
|
+
false,
|
|
208
|
+
true,
|
|
198
209
|
);
|
|
199
210
|
this.emitAssignmentTarget(node.operand, next);
|
|
200
211
|
return next;
|
|
@@ -214,6 +225,9 @@ export const operatorExpressionMethods: OperatorExpressionMethods = {
|
|
|
214
225
|
one,
|
|
215
226
|
node.operator === PostfixUnaryOperator.PlusPlus ? "+" : "-",
|
|
216
227
|
fn,
|
|
228
|
+
true,
|
|
229
|
+
false,
|
|
230
|
+
true,
|
|
217
231
|
);
|
|
218
232
|
this.emitAssignmentTarget(node.operand, next);
|
|
219
233
|
return current;
|
|
@@ -245,6 +245,10 @@ export const primaryExpressionMethods: PrimaryExpressionMethods = {
|
|
|
245
245
|
this.reportRequireUse(identifier);
|
|
246
246
|
return i64(XT_UNDEFINED);
|
|
247
247
|
}
|
|
248
|
+
/* The parser's recovery node for a missing expression. The syntax
|
|
249
|
+
* error has already been reported; "Cannot find name '<error>'" is
|
|
250
|
+
* pure noise on top of it. */
|
|
251
|
+
if (identifier.text === "<error>") return i64(XT_UNDEFINED);
|
|
248
252
|
this.diagnostics.error(
|
|
249
253
|
DiagnosticCode.CannotFindName,
|
|
250
254
|
`Cannot find name '${identifier.text}'`,
|
|
@@ -100,13 +100,6 @@ export const moduleMethods: ModuleMethods = {
|
|
|
100
100
|
|
|
101
101
|
emitFunction(fn: FunctionInfo): void {
|
|
102
102
|
this.unsupportedCount = 0;
|
|
103
|
-
// `async function*` would need an async iterator and a promise-returning
|
|
104
|
-
// `.next()`; the generator/async lowering below would silently produce a
|
|
105
|
-
// synchronous generator instead, so reject it rather than miscompile.
|
|
106
|
-
if (fn.isAsync && fn.isGenerator) {
|
|
107
|
-
this.unsupported(fn.node, "async generator function");
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
103
|
const name = this.functionName(fn);
|
|
111
104
|
const debugSubprogram = this.debugSubprogramFor(fn);
|
|
112
105
|
const state: FunctionState = {
|