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
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Directory-walking worker jobs: `readdir`, `opendir`, recursive `rm`/`cp` and
|
|
3
|
+
* `glob`. All of it runs off the main thread; only the entry table built here
|
|
4
|
+
* crosses back (via async_complete.c).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
#include "async_worker_dir.h"
|
|
8
|
+
|
|
9
|
+
#include <errno.h>
|
|
10
|
+
|
|
11
|
+
#if !defined(_WIN32)
|
|
12
|
+
#include <sys/time.h>
|
|
13
|
+
#include <unistd.h>
|
|
14
|
+
#endif
|
|
15
|
+
|
|
16
|
+
/* -- readdir / opendir ----------------------------------------------------- */
|
|
17
|
+
|
|
18
|
+
static int xt_fs_worker_scan(xt_fs_job *job, const char *base, const char *prefix, int recursive, int with_types) {
|
|
19
|
+
size_t baseLength = strlen(base);
|
|
20
|
+
size_t prefixLength = strlen(prefix);
|
|
21
|
+
char *dirPath = (char *)malloc(baseLength + prefixLength + 2);
|
|
22
|
+
if (!dirPath) return -1;
|
|
23
|
+
if (prefixLength == 0) snprintf(dirPath, baseLength + prefixLength + 2, "%s", base);
|
|
24
|
+
else snprintf(dirPath, baseLength + prefixLength + 2, "%s/%s", base, prefix);
|
|
25
|
+
size_t dirLength = strlen(dirPath);
|
|
26
|
+
while (dirLength > 1 && (dirPath[dirLength - 1] == '/' || dirPath[dirLength - 1] == '\\')) {
|
|
27
|
+
dirPath[--dirLength] = '\0';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
xt_fs_dir dir;
|
|
31
|
+
if (!xt_fs_dir_open(&dir, dirPath)) {
|
|
32
|
+
int saved = errno;
|
|
33
|
+
free(dirPath);
|
|
34
|
+
errno = saved;
|
|
35
|
+
return -1;
|
|
36
|
+
}
|
|
37
|
+
while (xt_fs_dir_next(&dir)) {
|
|
38
|
+
const char *name = xt_fs_dir_name(&dir);
|
|
39
|
+
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) continue;
|
|
40
|
+
size_t nameLength = strlen(name);
|
|
41
|
+
char *relative = (char *)malloc(prefixLength + nameLength + 1);
|
|
42
|
+
if (!relative) continue;
|
|
43
|
+
snprintf(relative, prefixLength + nameLength + 1, "%s%s", prefix, name);
|
|
44
|
+
unsigned int mode = 0;
|
|
45
|
+
if (recursive || with_types) {
|
|
46
|
+
char *full = xt_fs_worker_join(dirPath, name);
|
|
47
|
+
if (full) {
|
|
48
|
+
xt_fs_stat_t info;
|
|
49
|
+
if (xt_fs_lstat_fn(full, &info) == 0) mode = (unsigned int)info.st_mode;
|
|
50
|
+
free(full);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (xt_fs_entry_push(job, relative, name, mode) != 0) {
|
|
54
|
+
free(relative);
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
if (recursive && mode && S_ISDIR(mode)) {
|
|
58
|
+
char *child = (char *)malloc(prefixLength + nameLength + 2);
|
|
59
|
+
if (child) {
|
|
60
|
+
snprintf(child, prefixLength + nameLength + 2, "%s%s/", prefix, name);
|
|
61
|
+
xt_fs_worker_scan(job, base, child, recursive, with_types);
|
|
62
|
+
free(child);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
free(relative);
|
|
66
|
+
}
|
|
67
|
+
xt_fs_dir_close(&dir);
|
|
68
|
+
free(dirPath);
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
void xt_fs_worker_readdir(xt_fs_job *job) {
|
|
73
|
+
if (!job->path) {
|
|
74
|
+
xt_fs_job_fail(job, EINVAL, "readdir", NULL);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (xt_fs_worker_scan(job, job->path, "", job->recursive, job->with_types) != 0) {
|
|
78
|
+
xt_fs_job_fail(job, errno, "open directory", job->path);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
void xt_fs_worker_opendir(xt_fs_job *job) {
|
|
83
|
+
if (!job->path) {
|
|
84
|
+
xt_fs_job_fail(job, EINVAL, "opendir", NULL);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (xt_fs_worker_scan(job, job->path, "", 0, 1) != 0) {
|
|
88
|
+
xt_fs_job_fail(job, errno, "open directory", job->path);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* -- recursive rm ---------------------------------------------------------- */
|
|
93
|
+
|
|
94
|
+
static int xt_fs_worker_remove(const char *path) {
|
|
95
|
+
xt_fs_stat_t info;
|
|
96
|
+
if (xt_fs_lstat_fn(path, &info) != 0) return -1;
|
|
97
|
+
if (!S_ISDIR(info.st_mode)) {
|
|
98
|
+
#if defined(_WIN32)
|
|
99
|
+
return _unlink(path);
|
|
100
|
+
#else
|
|
101
|
+
return unlink(path);
|
|
102
|
+
#endif
|
|
103
|
+
}
|
|
104
|
+
xt_fs_dir dir;
|
|
105
|
+
if (!xt_fs_dir_open(&dir, path)) return -1;
|
|
106
|
+
while (xt_fs_dir_next(&dir)) {
|
|
107
|
+
const char *name = xt_fs_dir_name(&dir);
|
|
108
|
+
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) continue;
|
|
109
|
+
char *child = xt_fs_worker_join(path, name);
|
|
110
|
+
if (!child) continue;
|
|
111
|
+
xt_fs_worker_remove(child);
|
|
112
|
+
free(child);
|
|
113
|
+
}
|
|
114
|
+
xt_fs_dir_close(&dir);
|
|
115
|
+
return xt_fs_rmdir_one(path);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
void xt_fs_worker_remove_tree(xt_fs_job *job) {
|
|
119
|
+
if (!job->path) {
|
|
120
|
+
xt_fs_job_fail(job, EINVAL, "remove", NULL);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
int status = job->recursive ? xt_fs_worker_remove(job->path) : remove(job->path);
|
|
124
|
+
if (status != 0) {
|
|
125
|
+
if (job->force && errno == ENOENT) return;
|
|
126
|
+
xt_fs_job_fail(job, errno, "remove", job->path);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* Stream `from` into `to` without materialising the whole file. */
|
|
131
|
+
int xt_fs_worker_copy_bytes(const char *from, const char *to) {
|
|
132
|
+
int source = XT_FS_OPEN(from, XT_FS_RDONLY | XT_FS_BINARY_FLAG, 0);
|
|
133
|
+
if (source < 0) return -1;
|
|
134
|
+
int destination = XT_FS_OPEN(to, XT_FS_WRONLY | XT_FS_CREAT | XT_FS_TRUNC | XT_FS_BINARY_FLAG, 0666);
|
|
135
|
+
if (destination < 0) {
|
|
136
|
+
int saved = errno;
|
|
137
|
+
XT_FS_CLOSE(source);
|
|
138
|
+
errno = saved;
|
|
139
|
+
return -1;
|
|
140
|
+
}
|
|
141
|
+
char buffer[65536];
|
|
142
|
+
int status = 0;
|
|
143
|
+
for (;;) {
|
|
144
|
+
ssize_t count = XT_FS_READ(source, buffer, sizeof(buffer));
|
|
145
|
+
if (count < 0) {
|
|
146
|
+
status = -1;
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
if (count == 0) break;
|
|
150
|
+
size_t written = 0;
|
|
151
|
+
while (written < (size_t)count) {
|
|
152
|
+
ssize_t chunk = XT_FS_WRITE(destination, buffer + written, (size_t)count - written);
|
|
153
|
+
if (chunk <= 0) {
|
|
154
|
+
status = -1;
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
written += (size_t)chunk;
|
|
158
|
+
}
|
|
159
|
+
if (status != 0) break;
|
|
160
|
+
}
|
|
161
|
+
int saved = errno;
|
|
162
|
+
if (XT_FS_CLOSE(source) != 0 && status == 0) {
|
|
163
|
+
status = -1;
|
|
164
|
+
saved = errno;
|
|
165
|
+
}
|
|
166
|
+
if (XT_FS_CLOSE(destination) != 0 && status == 0) {
|
|
167
|
+
status = -1;
|
|
168
|
+
saved = errno;
|
|
169
|
+
}
|
|
170
|
+
errno = saved;
|
|
171
|
+
return status;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
void xt_fs_worker_copy_file(xt_fs_job *job) {
|
|
175
|
+
if (!job->path || !job->path2) {
|
|
176
|
+
xt_fs_job_fail(job, EINVAL, "copyfile", NULL);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if ((job->flags & 1) && xt_fs_access(job->path2, F_OK) == 0) {
|
|
180
|
+
xt_fs_job_fail(job, EEXIST, "copyfile", job->path2);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
if (xt_fs_worker_copy_bytes(job->path, job->path2) != 0) {
|
|
184
|
+
xt_fs_job_fail(job, errno, "open", job->path);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/* -- recursive cp ---------------------------------------------------------- */
|
|
189
|
+
|
|
190
|
+
static int xt_fs_worker_copy_any(const char *src, const char *dest, xt_fs_job *job) {
|
|
191
|
+
xt_fs_stat_t info;
|
|
192
|
+
if (xt_fs_lstat_fn(src, &info) != 0) return -1;
|
|
193
|
+
if (S_ISDIR(info.st_mode)) {
|
|
194
|
+
if (!job->recursive) {
|
|
195
|
+
errno = EISDIR;
|
|
196
|
+
return -1;
|
|
197
|
+
}
|
|
198
|
+
if (xt_fs_mkdir_mode(dest, (int)(info.st_mode & 0777)) != 0 && errno != EEXIST) return -1;
|
|
199
|
+
xt_fs_dir dir;
|
|
200
|
+
if (!xt_fs_dir_open(&dir, src)) return -1;
|
|
201
|
+
int status = 0;
|
|
202
|
+
while (xt_fs_dir_next(&dir)) {
|
|
203
|
+
const char *name = xt_fs_dir_name(&dir);
|
|
204
|
+
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) continue;
|
|
205
|
+
char *childSrc = xt_fs_worker_join(src, name);
|
|
206
|
+
char *childDest = xt_fs_worker_join(dest, name);
|
|
207
|
+
if (childSrc && childDest && xt_fs_worker_copy_any(childSrc, childDest, job) != 0) status = -1;
|
|
208
|
+
free(childSrc);
|
|
209
|
+
free(childDest);
|
|
210
|
+
}
|
|
211
|
+
xt_fs_dir_close(&dir);
|
|
212
|
+
return status;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (xt_fs_access(dest, F_OK) == 0) {
|
|
216
|
+
if (!job->force) {
|
|
217
|
+
if (job->error_on_exist) {
|
|
218
|
+
errno = EEXIST;
|
|
219
|
+
return -1;
|
|
220
|
+
}
|
|
221
|
+
return 0;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
#if !defined(_WIN32)
|
|
226
|
+
if (S_ISLNK(info.st_mode) && !job->dereference) {
|
|
227
|
+
size_t capacity = 256;
|
|
228
|
+
for (;;) {
|
|
229
|
+
char *target = (char *)malloc(capacity);
|
|
230
|
+
if (!target) return -1;
|
|
231
|
+
ssize_t length = readlink(src, target, capacity);
|
|
232
|
+
if (length < 0) {
|
|
233
|
+
free(target);
|
|
234
|
+
return -1;
|
|
235
|
+
}
|
|
236
|
+
if ((size_t)length < capacity) {
|
|
237
|
+
target[length] = '\0';
|
|
238
|
+
int status = symlink(target, dest);
|
|
239
|
+
free(target);
|
|
240
|
+
return status;
|
|
241
|
+
}
|
|
242
|
+
free(target);
|
|
243
|
+
capacity *= 2;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
#endif
|
|
247
|
+
|
|
248
|
+
int status = xt_fs_worker_copy_bytes(src, dest);
|
|
249
|
+
if (status != 0) return -1;
|
|
250
|
+
|
|
251
|
+
if (job->preserve) {
|
|
252
|
+
#if !defined(_WIN32)
|
|
253
|
+
struct timeval times[2];
|
|
254
|
+
times[0].tv_sec = info.st_atime;
|
|
255
|
+
times[0].tv_usec = 0;
|
|
256
|
+
times[1].tv_sec = info.st_mtime;
|
|
257
|
+
times[1].tv_usec = 0;
|
|
258
|
+
utimes(dest, times);
|
|
259
|
+
#endif
|
|
260
|
+
}
|
|
261
|
+
return 0;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
void xt_fs_worker_copy_tree(xt_fs_job *job) {
|
|
265
|
+
if (!job->path || !job->path2) {
|
|
266
|
+
xt_fs_job_fail(job, EINVAL, "cp", NULL);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
if (xt_fs_worker_copy_any(job->path, job->path2, job) != 0) {
|
|
270
|
+
xt_fs_job_fail(job, errno, "cp", job->path);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/* -- glob ------------------------------------------------------------------ */
|
|
275
|
+
|
|
276
|
+
/* Single path-segment match (`*`, `?`, `[...]`; no separator). */
|
|
277
|
+
static int xt_fs_worker_glob_match(const char *pattern, const char *text) {
|
|
278
|
+
while (*pattern) {
|
|
279
|
+
if (*pattern == '*') {
|
|
280
|
+
pattern++;
|
|
281
|
+
if (!*pattern) return 1;
|
|
282
|
+
while (*text) {
|
|
283
|
+
if (xt_fs_worker_glob_match(pattern, text)) return 1;
|
|
284
|
+
text++;
|
|
285
|
+
}
|
|
286
|
+
return 0;
|
|
287
|
+
}
|
|
288
|
+
if (*pattern == '?') {
|
|
289
|
+
if (!*text) return 0;
|
|
290
|
+
pattern++;
|
|
291
|
+
text++;
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
if (*pattern == '[') {
|
|
295
|
+
const char *cursor = pattern + 1;
|
|
296
|
+
int negate = 0;
|
|
297
|
+
int matched = 0;
|
|
298
|
+
char value = *text;
|
|
299
|
+
if (*cursor == '!' || *cursor == '^') {
|
|
300
|
+
negate = 1;
|
|
301
|
+
cursor++;
|
|
302
|
+
}
|
|
303
|
+
while (*cursor && *cursor != ']') {
|
|
304
|
+
char low = *cursor++;
|
|
305
|
+
char high = low;
|
|
306
|
+
if (*cursor == '-' && cursor[1] && cursor[1] != ']') {
|
|
307
|
+
cursor++;
|
|
308
|
+
high = *cursor++;
|
|
309
|
+
}
|
|
310
|
+
if (value >= low && value <= high) matched = 1;
|
|
311
|
+
}
|
|
312
|
+
if (*cursor == ']') cursor++;
|
|
313
|
+
if (!*text || matched == negate) return 0;
|
|
314
|
+
pattern = cursor;
|
|
315
|
+
text++;
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
if (*pattern != *text) return 0;
|
|
319
|
+
pattern++;
|
|
320
|
+
text++;
|
|
321
|
+
}
|
|
322
|
+
return *text == '\0';
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
static int xt_fs_worker_glob_is_dir(const char *path, int follow) {
|
|
326
|
+
xt_fs_stat_t info;
|
|
327
|
+
int failed = follow ? xt_fs_stat_fn(path, &info) : xt_fs_lstat_fn(path, &info);
|
|
328
|
+
if (failed != 0) return 0;
|
|
329
|
+
return S_ISDIR(info.st_mode);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
static void xt_fs_worker_glob_walk(xt_fs_job *job, const char *dirPath, const char *pattern,
|
|
333
|
+
const char *resultPrefix);
|
|
334
|
+
|
|
335
|
+
static void xt_fs_worker_glob_descend(xt_fs_job *job, const char *dirPath, const char *pattern,
|
|
336
|
+
const char *resultPrefix) {
|
|
337
|
+
xt_fs_dir dir;
|
|
338
|
+
if (!xt_fs_dir_open(&dir, dirPath)) return;
|
|
339
|
+
while (xt_fs_dir_next(&dir)) {
|
|
340
|
+
const char *name = xt_fs_dir_name(&dir);
|
|
341
|
+
if (name[0] == '.') continue;
|
|
342
|
+
char *child = xt_fs_worker_join(dirPath, name);
|
|
343
|
+
if (!child) continue;
|
|
344
|
+
if (xt_fs_worker_glob_is_dir(child, 0)) {
|
|
345
|
+
size_t size = strlen(resultPrefix) + strlen(name) + 2;
|
|
346
|
+
char *childPrefix = (char *)malloc(size);
|
|
347
|
+
if (childPrefix) {
|
|
348
|
+
snprintf(childPrefix, size, "%s%s/", resultPrefix, name);
|
|
349
|
+
xt_fs_worker_glob_walk(job, child, pattern, childPrefix);
|
|
350
|
+
free(childPrefix);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
free(child);
|
|
354
|
+
}
|
|
355
|
+
xt_fs_dir_close(&dir);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
static void xt_fs_worker_glob_walk(xt_fs_job *job, const char *dirPath, const char *pattern,
|
|
359
|
+
const char *resultPrefix) {
|
|
360
|
+
if (pattern[0] == '\0') {
|
|
361
|
+
if (resultPrefix[0] != '\0') {
|
|
362
|
+
size_t length = strlen(resultPrefix);
|
|
363
|
+
char *trimmed = (char *)malloc(length + 1);
|
|
364
|
+
if (!trimmed) return;
|
|
365
|
+
memcpy(trimmed, resultPrefix, length + 1);
|
|
366
|
+
while (length > 1 && trimmed[length - 1] == '/') trimmed[--length] = '\0';
|
|
367
|
+
xt_fs_entry_push(job, trimmed, trimmed, 0);
|
|
368
|
+
free(trimmed);
|
|
369
|
+
}
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const char *slash = strchr(pattern, '/');
|
|
374
|
+
size_t segmentLength = slash ? (size_t)(slash - pattern) : strlen(pattern);
|
|
375
|
+
const char *rest = slash ? slash + 1 : "";
|
|
376
|
+
|
|
377
|
+
if (segmentLength == 2 && pattern[0] == '*' && pattern[1] == '*') {
|
|
378
|
+
xt_fs_worker_glob_walk(job, dirPath, rest, resultPrefix);
|
|
379
|
+
xt_fs_worker_glob_descend(job, dirPath, pattern, resultPrefix);
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
char segment[256];
|
|
384
|
+
if (segmentLength >= sizeof(segment)) return;
|
|
385
|
+
memcpy(segment, pattern, segmentLength);
|
|
386
|
+
segment[segmentLength] = '\0';
|
|
387
|
+
|
|
388
|
+
xt_fs_dir dir;
|
|
389
|
+
if (!xt_fs_dir_open(&dir, dirPath)) return;
|
|
390
|
+
while (xt_fs_dir_next(&dir)) {
|
|
391
|
+
const char *name = xt_fs_dir_name(&dir);
|
|
392
|
+
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) continue;
|
|
393
|
+
if (name[0] == '.' && segment[0] != '.') continue;
|
|
394
|
+
if (!xt_fs_worker_glob_match(segment, name)) continue;
|
|
395
|
+
char *child = xt_fs_worker_join(dirPath, name);
|
|
396
|
+
if (!child) continue;
|
|
397
|
+
if (rest[0] == '\0') {
|
|
398
|
+
size_t size = strlen(resultPrefix) + strlen(name) + 1;
|
|
399
|
+
char *result = (char *)malloc(size);
|
|
400
|
+
if (result) {
|
|
401
|
+
snprintf(result, size, "%s%s", resultPrefix, name);
|
|
402
|
+
xt_fs_entry_push(job, result, result, 0);
|
|
403
|
+
free(result);
|
|
404
|
+
}
|
|
405
|
+
} else if (xt_fs_worker_glob_is_dir(child, 1)) {
|
|
406
|
+
size_t size = strlen(resultPrefix) + strlen(name) + 2;
|
|
407
|
+
char *childPrefix = (char *)malloc(size);
|
|
408
|
+
if (childPrefix) {
|
|
409
|
+
snprintf(childPrefix, size, "%s%s/", resultPrefix, name);
|
|
410
|
+
xt_fs_worker_glob_walk(job, child, rest, childPrefix);
|
|
411
|
+
free(childPrefix);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
free(child);
|
|
415
|
+
}
|
|
416
|
+
xt_fs_dir_close(&dir);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
static void xt_fs_worker_glob_pattern(xt_fs_job *job, const char *pattern, const char *cwd) {
|
|
420
|
+
if (!pattern) return;
|
|
421
|
+
const char *base = cwd && cwd[0] ? cwd : ".";
|
|
422
|
+
const char *prefix = "";
|
|
423
|
+
if (pattern[0] == '/') {
|
|
424
|
+
base = "/";
|
|
425
|
+
prefix = "/";
|
|
426
|
+
pattern++;
|
|
427
|
+
}
|
|
428
|
+
xt_fs_worker_glob_walk(job, base, pattern, prefix);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
void xt_fs_worker_glob(xt_fs_job *job) {
|
|
432
|
+
if (job->patterns) {
|
|
433
|
+
for (size_t i = 0; i < job->pattern_count; i++) {
|
|
434
|
+
xt_fs_worker_glob_pattern(job, job->patterns[i], job->path2);
|
|
435
|
+
}
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
xt_fs_worker_glob_pattern(job, job->text, job->path2);
|
|
439
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Directory-walking jobs shared by the worker translation units.
|
|
3
|
+
*
|
|
4
|
+
* These run on an async worker thread and only touch plain C memory. Their
|
|
5
|
+
* results are `xt_fs_entry` arrays on the job, turned into strings, `Dirent`s or
|
|
6
|
+
* `Dir` objects by async_complete.c.
|
|
7
|
+
*/
|
|
8
|
+
#ifndef XT_NODE_FS_ASYNC_WORKER_DIR_H
|
|
9
|
+
#define XT_NODE_FS_ASYNC_WORKER_DIR_H
|
|
10
|
+
|
|
11
|
+
#include "async_job.h"
|
|
12
|
+
|
|
13
|
+
void xt_fs_worker_readdir(xt_fs_job *job);
|
|
14
|
+
void xt_fs_worker_opendir(xt_fs_job *job);
|
|
15
|
+
void xt_fs_worker_remove_tree(xt_fs_job *job);
|
|
16
|
+
void xt_fs_worker_copy_tree(xt_fs_job *job);
|
|
17
|
+
void xt_fs_worker_glob(xt_fs_job *job);
|
|
18
|
+
|
|
19
|
+
/* Shared byte helpers (async_worker.c). */
|
|
20
|
+
int xt_fs_worker_read_fd(int fd, unsigned char **out, size_t *out_length);
|
|
21
|
+
int xt_fs_worker_read_file(const char *path, unsigned char **out, size_t *out_length);
|
|
22
|
+
int xt_fs_worker_write_fd(int fd, const unsigned char *data, size_t length);
|
|
23
|
+
int xt_fs_worker_write_file(const char *path, const unsigned char *data, size_t length, int append);
|
|
24
|
+
int xt_fs_entry_push(xt_fs_job *job, const char *name, const char *bare, unsigned int mode);
|
|
25
|
+
char *xt_fs_worker_join(const char *dir, const char *name);
|
|
26
|
+
int xt_fs_worker_copy_bytes(const char *from, const char *to);
|
|
27
|
+
void xt_fs_worker_copy_file(xt_fs_job *job);
|
|
28
|
+
|
|
29
|
+
/* Descriptor read/write jobs (async_worker_fd.c). */
|
|
30
|
+
void xt_fs_worker_fd_read(xt_fs_job *job);
|
|
31
|
+
void xt_fs_worker_fd_write(xt_fs_job *job);
|
|
32
|
+
|
|
33
|
+
#endif /* XT_NODE_FS_ASYNC_WORKER_DIR_H */
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Descriptor read/write worker jobs.
|
|
3
|
+
*
|
|
4
|
+
* Split out of async_worker.c to keep each translation unit small. These only
|
|
5
|
+
* touch the descriptor and a plain byte buffer; the completion handler copies
|
|
6
|
+
* the bytes into the caller's `Buffer` on the main thread.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#include "async_worker_dir.h"
|
|
10
|
+
|
|
11
|
+
#include <errno.h>
|
|
12
|
+
|
|
13
|
+
#if defined(_WIN32)
|
|
14
|
+
#include <io.h>
|
|
15
|
+
#else
|
|
16
|
+
#include <unistd.h>
|
|
17
|
+
#endif
|
|
18
|
+
|
|
19
|
+
void xt_fs_worker_fd_read(xt_fs_job *job) {
|
|
20
|
+
size_t length = (size_t)job->length;
|
|
21
|
+
if (length == 0) {
|
|
22
|
+
job->bytes = NULL;
|
|
23
|
+
job->bytes_length = 0;
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
unsigned char *bytes = (unsigned char *)malloc(length);
|
|
27
|
+
if (!bytes) {
|
|
28
|
+
xt_fs_job_fail(job, ENOMEM, "read", NULL);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
ssize_t count;
|
|
32
|
+
if (job->position >= 0) {
|
|
33
|
+
#if defined(_WIN32)
|
|
34
|
+
_lseeki64(job->fd, job->position, SEEK_SET);
|
|
35
|
+
count = _read(job->fd, bytes, (unsigned int)length);
|
|
36
|
+
#else
|
|
37
|
+
count = pread(job->fd, bytes, length, (off_t)job->position);
|
|
38
|
+
#endif
|
|
39
|
+
} else {
|
|
40
|
+
count = XT_FS_READ(job->fd, bytes, length);
|
|
41
|
+
}
|
|
42
|
+
if (count < 0) {
|
|
43
|
+
int saved = errno;
|
|
44
|
+
free(bytes);
|
|
45
|
+
xt_fs_job_fail(job, saved, "read", NULL);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
job->bytes = bytes;
|
|
49
|
+
job->bytes_length = (size_t)count;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
void xt_fs_worker_fd_write(xt_fs_job *job) {
|
|
53
|
+
if (job->data_length == 0) {
|
|
54
|
+
job->written = 0;
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
ssize_t count;
|
|
58
|
+
if (job->position >= 0) {
|
|
59
|
+
#if defined(_WIN32)
|
|
60
|
+
_lseeki64(job->fd, job->position, SEEK_SET);
|
|
61
|
+
count = _write(job->fd, job->data, (unsigned int)job->data_length);
|
|
62
|
+
#else
|
|
63
|
+
count = pwrite(job->fd, job->data, job->data_length, (off_t)job->position);
|
|
64
|
+
#endif
|
|
65
|
+
} else {
|
|
66
|
+
count = XT_FS_WRITE(job->fd, job->data, job->data_length);
|
|
67
|
+
}
|
|
68
|
+
if (count < 0) {
|
|
69
|
+
xt_fs_job_fail(job, errno, "write", NULL);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
job->written = (long long)count;
|
|
73
|
+
}
|
|
74
|
+
|
|
@@ -1,21 +1,40 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* `fs.opendirSync` / the `Dir` object for xbintsc.
|
|
2
|
+
* `fs.opendirSync` / `fs.promises.opendir` and the `Dir` object for xbintsc.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* `Dir`
|
|
4
|
+
* A `Dir` either owns a live directory handle (the synchronous `opendirSync`
|
|
5
|
+
* path) or an entry table collected by an async worker (`opendir` from
|
|
6
|
+
* `fs/promises`). `readSync`/`closeSync` serve both; `read`/`close` invoke their
|
|
7
|
+
* callbacks immediately. `Dir` is a plain object, so `dir instanceof Dir` is not
|
|
8
|
+
* supported yet.
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
#include "../node_common.h"
|
|
11
12
|
#include "fs_common.h"
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
/* A pointer is stored as a number; `undefined`/`NaN` must read as "none" (a
|
|
15
|
+
* bare cast would turn NaN into a bogus non-zero handle on some targets). */
|
|
16
|
+
static void *xt_fs_dir_pointer(xt_value thisValue, const char *key) {
|
|
17
|
+
double value = xt_to_number(xt_object_get_cstr(thisValue, key));
|
|
18
|
+
if (!(value > 0)) return NULL;
|
|
19
|
+
return (void *)(uintptr_t)value;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static xt_fs_dir *xt_fs_dir_handle(xt_value thisValue) { return (xt_fs_dir *)xt_fs_dir_pointer(thisValue, "__xt_dir"); }
|
|
23
|
+
|
|
24
|
+
static xt_fs_entry *xt_fs_dir_entries(xt_value thisValue) {
|
|
25
|
+
return (xt_fs_entry *)xt_fs_dir_pointer(thisValue, "__xt_entries");
|
|
16
26
|
}
|
|
17
27
|
|
|
18
28
|
static xt_value xt_fs_dir_read_entry(xt_value thisValue) {
|
|
29
|
+
xt_fs_entry *entries = xt_fs_dir_entries(thisValue);
|
|
30
|
+
if (entries) {
|
|
31
|
+
size_t index = (size_t)xt_to_number(xt_object_get_cstr(thisValue, "__xt_index"));
|
|
32
|
+
size_t count = (size_t)xt_to_number(xt_object_get_cstr(thisValue, "__xt_count"));
|
|
33
|
+
if (index >= count) return xt_null();
|
|
34
|
+
xt_fs_entry *entry = &entries[index];
|
|
35
|
+
xt_object_set(thisValue, xt_string_from_cstr("__xt_index"), xt_number((double)(index + 1)));
|
|
36
|
+
return xt_node_dirent_named(entry->bare ? entry->bare : entry->name, entry->mode);
|
|
37
|
+
}
|
|
19
38
|
xt_fs_dir *dir = xt_fs_dir_handle(thisValue);
|
|
20
39
|
if (!dir) return xt_null();
|
|
21
40
|
const char *path = xt_node_cstr(xt_object_get_cstr(thisValue, "path"));
|
|
@@ -38,6 +57,16 @@ static xt_value xt_fs_dir_close_sync(xt_value thisValue, xt_value env, int32_t a
|
|
|
38
57
|
(void)env;
|
|
39
58
|
(void)argc;
|
|
40
59
|
(void)argv;
|
|
60
|
+
xt_fs_entry *entries = xt_fs_dir_entries(thisValue);
|
|
61
|
+
if (entries) {
|
|
62
|
+
size_t count = (size_t)xt_to_number(xt_object_get_cstr(thisValue, "__xt_count"));
|
|
63
|
+
for (size_t i = 0; i < count; i++) {
|
|
64
|
+
free(entries[i].name);
|
|
65
|
+
if (entries[i].bare != entries[i].name) free(entries[i].bare);
|
|
66
|
+
}
|
|
67
|
+
free(entries);
|
|
68
|
+
xt_object_set(thisValue, xt_string_from_cstr("__xt_entries"), xt_number(0));
|
|
69
|
+
}
|
|
41
70
|
xt_fs_dir *dir = xt_fs_dir_handle(thisValue);
|
|
42
71
|
if (dir) {
|
|
43
72
|
xt_fs_dir_close(dir);
|
|
@@ -72,6 +101,28 @@ static xt_value xt_fs_dir_close_async(xt_value thisValue, xt_value env, int32_t
|
|
|
72
101
|
return xt_undefined();
|
|
73
102
|
}
|
|
74
103
|
|
|
104
|
+
static xt_value xt_node_dir_object(const char *path) {
|
|
105
|
+
xt_value object = xt_object_new();
|
|
106
|
+
xt_node_set(object, "path", xt_string_from_cstr(path ? path : ""));
|
|
107
|
+
xt_node_set(object, "__xt_dir", xt_number(0));
|
|
108
|
+
xt_node_set(object, "__xt_entries", xt_number(0));
|
|
109
|
+
xt_node_define_method(object, "readSync", (void *)xt_fs_dir_read_sync);
|
|
110
|
+
xt_node_define_method(object, "closeSync", (void *)xt_fs_dir_close_sync);
|
|
111
|
+
xt_node_define_method(object, "read", (void *)xt_fs_dir_read_async);
|
|
112
|
+
xt_node_define_method(object, "close", (void *)xt_fs_dir_close_async);
|
|
113
|
+
return object;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* Adopt an entry table collected on a worker. The `Dir` owns the table and
|
|
117
|
+
* frees it on close; the caller must not free it afterwards. */
|
|
118
|
+
xt_value xt_node_dir_from_entries(const char *path, xt_fs_entry *entries, size_t count) {
|
|
119
|
+
xt_value object = xt_node_dir_object(path);
|
|
120
|
+
xt_node_set(object, "__xt_entries", xt_number((double)(uintptr_t)entries));
|
|
121
|
+
xt_node_set(object, "__xt_count", xt_number((double)count));
|
|
122
|
+
xt_node_set(object, "__xt_index", xt_number(0));
|
|
123
|
+
return object;
|
|
124
|
+
}
|
|
125
|
+
|
|
75
126
|
xt_value xt_node_opendir(int32_t argc, xt_value *argv) {
|
|
76
127
|
if (argc < 1) return xt_undefined();
|
|
77
128
|
const char *path = xt_node_cstr(argv[0]);
|
|
@@ -89,13 +140,7 @@ xt_value xt_node_opendir(int32_t argc, xt_value *argv) {
|
|
|
89
140
|
xt_fs_error("open directory", path);
|
|
90
141
|
return xt_undefined();
|
|
91
142
|
}
|
|
92
|
-
|
|
93
|
-
xt_value object = xt_object_new();
|
|
94
|
-
xt_node_set(object, "path", xt_string_from_cstr(path));
|
|
143
|
+
xt_value object = xt_node_dir_object(path);
|
|
95
144
|
xt_node_set(object, "__xt_dir", xt_number((double)(uintptr_t)dir));
|
|
96
|
-
xt_node_define_method(object, "readSync", (void *)xt_fs_dir_read_sync);
|
|
97
|
-
xt_node_define_method(object, "closeSync", (void *)xt_fs_dir_close_sync);
|
|
98
|
-
xt_node_define_method(object, "read", (void *)xt_fs_dir_read_async);
|
|
99
|
-
xt_node_define_method(object, "close", (void *)xt_fs_dir_close_async);
|
|
100
145
|
return object;
|
|
101
146
|
}
|
|
@@ -32,4 +32,13 @@
|
|
|
32
32
|
#include "parts/buffer-bridge.inc"
|
|
33
33
|
#include "parts/encoding.inc"
|
|
34
34
|
|
|
35
|
+
/* One directory entry collected by the asynchronous worker (see async_job.h).
|
|
36
|
+
* `name` is relative to the scanned directory, `bare` is the entry name alone.
|
|
37
|
+
* Defined here because both the sync `Dir` and the async promise layer use it. */
|
|
38
|
+
typedef struct {
|
|
39
|
+
char *name;
|
|
40
|
+
char *bare;
|
|
41
|
+
unsigned int mode;
|
|
42
|
+
} xt_fs_entry;
|
|
43
|
+
|
|
35
44
|
#endif /* XT_NODE_FS_COMMON_H */
|