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/runtime/xt_generator.c
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* xbintsc runtime — stackful generators.
|
|
2
|
+
* xbintsc runtime — stackful generators and async generators.
|
|
3
3
|
*
|
|
4
4
|
* A generator function object carries `is_generator`. Calling it does not run
|
|
5
5
|
* the body; it creates an `xt_generator` that owns a private stack. `.next()`
|
|
@@ -8,6 +8,12 @@
|
|
|
8
8
|
* `finally` and nested loops work across suspension points without a state
|
|
9
9
|
* machine transform.
|
|
10
10
|
*
|
|
11
|
+
* An `async function*` uses the same coroutine, but every `.next()` /
|
|
12
|
+
* `.throw()` / `.return()` returns a promise. The body may also suspend at an
|
|
13
|
+
* `await`: `xt_generator_await` parks the coroutine on the awaited promise and
|
|
14
|
+
* leaves the current `.next()` promise pending until the body yields or
|
|
15
|
+
* completes. This is what makes `for await...of` work without a state machine.
|
|
16
|
+
*
|
|
11
17
|
* The private stack and the context switch come from `xt_coroutine.c`, which
|
|
12
18
|
* `async` functions use as well. The generator's exception stack is swapped
|
|
13
19
|
* alongside it so a `throw` inside the body still targets the body's own
|
|
@@ -19,6 +25,14 @@
|
|
|
19
25
|
#include <stdlib.h>
|
|
20
26
|
#include <string.h>
|
|
21
27
|
|
|
28
|
+
/* One queued async-generator request. Requests are processed in call order, so
|
|
29
|
+
* two `.next()` calls before the body yields do not overwrite each other. */
|
|
30
|
+
typedef struct {
|
|
31
|
+
xt_value promise;
|
|
32
|
+
xt_value sent;
|
|
33
|
+
int kind; /* 0 = next, 1 = throw, 2 = return */
|
|
34
|
+
} xt_async_request;
|
|
35
|
+
|
|
22
36
|
typedef struct xt_generator {
|
|
23
37
|
xt_header header;
|
|
24
38
|
xt_value function;
|
|
@@ -33,11 +47,30 @@ typedef struct xt_generator {
|
|
|
33
47
|
int started;
|
|
34
48
|
int done;
|
|
35
49
|
int threw;
|
|
50
|
+
/* Async-generator state. `pending_promise` belongs to the request currently
|
|
51
|
+
* executing; `requests` holds calls made while it is pending. */
|
|
52
|
+
int is_async;
|
|
53
|
+
xt_value pending_promise;
|
|
54
|
+
xt_value resume_value;
|
|
55
|
+
int await_threw;
|
|
56
|
+
xt_async_request *requests;
|
|
57
|
+
uint32_t request_count;
|
|
58
|
+
uint32_t request_capacity;
|
|
36
59
|
/* Private stack, context switch and GC region bookkeeping live in
|
|
37
60
|
* xt_coroutine.c; `NULL` once the body has finished. */
|
|
38
61
|
xt_coroutine *coroutine;
|
|
39
62
|
} xt_generator;
|
|
40
63
|
|
|
64
|
+
/* Resolved async iterator for a *synchronous* iterable (`for await` over an
|
|
65
|
+
* array). The source uses the ordinary index protocol; each step is wrapped in
|
|
66
|
+
* an already-settled promise. */
|
|
67
|
+
typedef struct {
|
|
68
|
+
xt_header header;
|
|
69
|
+
xt_value iterator;
|
|
70
|
+
xt_value index;
|
|
71
|
+
int done;
|
|
72
|
+
} xt_async_iterator_state;
|
|
73
|
+
|
|
41
74
|
/* The generator whose coroutine is running, if any. */
|
|
42
75
|
static xt_generator *g_active_generator = NULL;
|
|
43
76
|
|
|
@@ -46,6 +79,11 @@ int xt_is_generator(xt_value value) {
|
|
|
46
79
|
return ((xt_header *)XT_GET_PTR(value))->kind == XT_OBJECT_KIND_GENERATOR;
|
|
47
80
|
}
|
|
48
81
|
|
|
82
|
+
int xt_is_async_generator(xt_value value) {
|
|
83
|
+
if (!xt_is_generator(value)) return 0;
|
|
84
|
+
return ((xt_generator *)XT_GET_PTR(value))->is_async;
|
|
85
|
+
}
|
|
86
|
+
|
|
49
87
|
static xt_generator *xt_as_generator(xt_value value) {
|
|
50
88
|
if (!xt_is_generator(value)) return NULL;
|
|
51
89
|
return (xt_generator *)XT_GET_PTR(value);
|
|
@@ -58,6 +96,10 @@ static xt_value xt_generator_result_object(xt_value value, int done) {
|
|
|
58
96
|
return result;
|
|
59
97
|
}
|
|
60
98
|
|
|
99
|
+
static xt_value xt_generator_done_promise(xt_value value) {
|
|
100
|
+
return xt_promise_resolve(xt_generator_result_object(value, 1));
|
|
101
|
+
}
|
|
102
|
+
|
|
61
103
|
/* Runs on the generator's private stack. */
|
|
62
104
|
static void xt_generator_run(void *arg) {
|
|
63
105
|
xt_generator *gen = (xt_generator *)arg;
|
|
@@ -83,7 +125,9 @@ static void xt_generator_dispose(xt_generator *gen) {
|
|
|
83
125
|
|
|
84
126
|
static void xt_generator_boot(xt_generator *gen);
|
|
85
127
|
|
|
86
|
-
|
|
128
|
+
/* Enter the coroutine. Returns with the coroutine suspended (yield/await) or
|
|
129
|
+
* finished. */
|
|
130
|
+
static void xt_generator_enter(xt_generator *gen) {
|
|
87
131
|
if (!gen->coroutine) xt_generator_boot(gen);
|
|
88
132
|
xt_generator *previous = g_active_generator;
|
|
89
133
|
g_active_generator = gen;
|
|
@@ -92,6 +136,84 @@ static void xt_generator_resume(xt_generator *gen) {
|
|
|
92
136
|
g_active_generator = previous;
|
|
93
137
|
}
|
|
94
138
|
|
|
139
|
+
/* Settle the promise of the request that just finished. */
|
|
140
|
+
static void xt_generator_settle_pending(xt_generator *gen) {
|
|
141
|
+
if (!gen->is_async || gen->pending_promise == XT_UNDEFINED) return;
|
|
142
|
+
xt_value promise = gen->pending_promise;
|
|
143
|
+
gen->pending_promise = XT_UNDEFINED;
|
|
144
|
+
if (gen->threw) xt_promise_reject_value(promise, gen->result);
|
|
145
|
+
else xt_promise_fulfill(promise, xt_generator_result_object(gen->result, 1));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
static xt_value xt_async_enqueue(xt_generator *gen, xt_value sent, int kind);
|
|
149
|
+
|
|
150
|
+
static void xt_generator_start_next(xt_generator *gen) {
|
|
151
|
+
if (gen->request_count == 0) return;
|
|
152
|
+
xt_async_request request = gen->requests[0];
|
|
153
|
+
for (uint32_t i = 1; i < gen->request_count; i++) gen->requests[i - 1] = gen->requests[i];
|
|
154
|
+
gen->request_count--;
|
|
155
|
+
gen->pending_promise = request.promise;
|
|
156
|
+
gen->sent = request.sent;
|
|
157
|
+
gen->resume_kind = request.kind;
|
|
158
|
+
|
|
159
|
+
if (gen->done) {
|
|
160
|
+
if (request.kind == 1) xt_promise_reject_value(request.promise, request.sent);
|
|
161
|
+
else xt_promise_fulfill(request.promise, xt_generator_result_object(request.sent, 1));
|
|
162
|
+
gen->pending_promise = XT_UNDEFINED;
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
/* A `.throw()` before the body starts rejects the request; a `.return()`
|
|
166
|
+
* before it starts completes the generator without running the body. */
|
|
167
|
+
if (!gen->started) {
|
|
168
|
+
if (request.kind == 1) {
|
|
169
|
+
gen->done = 1;
|
|
170
|
+
gen->threw = 1;
|
|
171
|
+
gen->result = request.sent;
|
|
172
|
+
xt_promise_reject_value(request.promise, request.sent);
|
|
173
|
+
gen->pending_promise = XT_UNDEFINED;
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (request.kind == 2) {
|
|
177
|
+
gen->done = 1;
|
|
178
|
+
gen->threw = 0;
|
|
179
|
+
gen->result = request.sent;
|
|
180
|
+
xt_promise_fulfill(request.promise, xt_generator_result_object(request.sent, 1));
|
|
181
|
+
gen->pending_promise = XT_UNDEFINED;
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
gen->started = 1;
|
|
186
|
+
xt_generator_enter(gen);
|
|
187
|
+
if (gen->done) xt_generator_settle_pending(gen);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/* Drain queued requests whose predecessor has already finished. */
|
|
191
|
+
static void xt_generator_drain_requests(xt_generator *gen) {
|
|
192
|
+
while (gen->pending_promise == XT_UNDEFINED && gen->request_count > 0) {
|
|
193
|
+
xt_generator_start_next(gen);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
static xt_value xt_async_enqueue(xt_generator *gen, xt_value sent, int kind) {
|
|
198
|
+
if (gen->done) {
|
|
199
|
+
if (kind == 1) return xt_promise_reject(sent);
|
|
200
|
+
return xt_generator_done_promise(kind == 2 ? sent : XT_UNDEFINED);
|
|
201
|
+
}
|
|
202
|
+
xt_value promise = xt_promise_create();
|
|
203
|
+
if (gen->request_count >= gen->request_capacity) {
|
|
204
|
+
uint32_t capacity = gen->request_capacity == 0 ? 4 : gen->request_capacity * 2;
|
|
205
|
+
gen->requests = (xt_async_request *)realloc(gen->requests, sizeof(xt_async_request) * capacity);
|
|
206
|
+
if (!gen->requests) abort();
|
|
207
|
+
gen->request_capacity = capacity;
|
|
208
|
+
}
|
|
209
|
+
gen->requests[gen->request_count].promise = promise;
|
|
210
|
+
gen->requests[gen->request_count].sent = sent;
|
|
211
|
+
gen->requests[gen->request_count].kind = kind;
|
|
212
|
+
gen->request_count++;
|
|
213
|
+
if (gen->pending_promise == XT_UNDEFINED) xt_generator_drain_requests(gen);
|
|
214
|
+
return promise;
|
|
215
|
+
}
|
|
216
|
+
|
|
95
217
|
/* The active generator is only reachable through this static pointer, and its
|
|
96
218
|
* private stack holds values that are invisible to a scan of the main stack. */
|
|
97
219
|
static void xt_generator_gc_scan_roots(void) {
|
|
@@ -108,17 +230,27 @@ static void xt_generator_gc_register(void) {
|
|
|
108
230
|
|
|
109
231
|
void xt_generator_gc_trace(xt_header *header) {
|
|
110
232
|
xt_generator *gen = (xt_generator *)header;
|
|
111
|
-
|
|
112
|
-
|
|
233
|
+
xt_gc_mark_value(gen->function);
|
|
234
|
+
xt_gc_mark_value(gen->this_value);
|
|
235
|
+
xt_gc_mark_value(gen->sent);
|
|
236
|
+
xt_gc_mark_value(gen->result);
|
|
237
|
+
xt_gc_mark_value(gen->iter_value);
|
|
238
|
+
xt_gc_mark_value(gen->pending_promise);
|
|
239
|
+
xt_gc_mark_value(gen->resume_value);
|
|
113
240
|
if (gen->args && gen->argc > 0) {
|
|
114
241
|
xt_gc_scan_region(gen->args, sizeof(xt_value) * (size_t)gen->argc);
|
|
115
242
|
}
|
|
243
|
+
for (uint32_t i = 0; i < gen->request_count; i++) {
|
|
244
|
+
xt_gc_mark_value(gen->requests[i].promise);
|
|
245
|
+
xt_gc_mark_value(gen->requests[i].sent);
|
|
246
|
+
}
|
|
116
247
|
xt_coroutine_gc_trace(gen->coroutine);
|
|
117
248
|
}
|
|
118
249
|
|
|
119
250
|
void xt_generator_gc_release(xt_header *header) {
|
|
120
251
|
xt_generator *gen = (xt_generator *)header;
|
|
121
252
|
free(gen->args);
|
|
253
|
+
free(gen->requests);
|
|
122
254
|
xt_coroutine_release(gen->coroutine);
|
|
123
255
|
gen->coroutine = NULL;
|
|
124
256
|
}
|
|
@@ -129,6 +261,7 @@ static void xt_generator_boot(xt_generator *gen) {
|
|
|
129
261
|
|
|
130
262
|
xt_value xt_generator_new(xt_value function, xt_value thisValue, int32_t argc, xt_value *argv) {
|
|
131
263
|
xt_generator *gen = (xt_generator *)xt_alloc(sizeof(xt_generator), XT_OBJECT_KIND_GENERATOR);
|
|
264
|
+
xt_function *fn = (xt_function *)XT_GET_PTR(function);
|
|
132
265
|
gen->function = function;
|
|
133
266
|
gen->this_value = thisValue;
|
|
134
267
|
gen->argc = argc;
|
|
@@ -137,6 +270,17 @@ xt_value xt_generator_new(xt_value function, xt_value thisValue, int32_t argc, x
|
|
|
137
270
|
gen->result = XT_UNDEFINED;
|
|
138
271
|
gen->sent = XT_UNDEFINED;
|
|
139
272
|
gen->iter_value = XT_UNDEFINED;
|
|
273
|
+
gen->resume_kind = 0;
|
|
274
|
+
gen->started = 0;
|
|
275
|
+
gen->done = 0;
|
|
276
|
+
gen->threw = 0;
|
|
277
|
+
gen->is_async = fn->is_async_generator;
|
|
278
|
+
gen->pending_promise = XT_UNDEFINED;
|
|
279
|
+
gen->resume_value = XT_UNDEFINED;
|
|
280
|
+
gen->await_threw = 0;
|
|
281
|
+
gen->requests = NULL;
|
|
282
|
+
gen->request_count = 0;
|
|
283
|
+
gen->request_capacity = 0;
|
|
140
284
|
if (argc > 0 && argv) {
|
|
141
285
|
gen->args = (xt_value *)malloc(sizeof(xt_value) * (size_t)argc);
|
|
142
286
|
if (!gen->args) abort();
|
|
@@ -149,13 +293,15 @@ xt_value xt_generator_new(xt_value function, xt_value thisValue, int32_t argc, x
|
|
|
149
293
|
xt_value xt_generator_next(xt_value generator, xt_value sent) {
|
|
150
294
|
xt_generator *gen = xt_as_generator(generator);
|
|
151
295
|
if (!gen) {
|
|
152
|
-
xt_throw(
|
|
296
|
+
xt_throw(xt_error_from_message("TypeError: not a generator"));
|
|
153
297
|
return XT_UNDEFINED;
|
|
154
298
|
}
|
|
299
|
+
if (gen->is_async) return xt_async_enqueue(gen, sent, 0);
|
|
155
300
|
if (gen->done) return xt_generator_result_object(XT_UNDEFINED, 1);
|
|
156
301
|
gen->sent = sent;
|
|
157
302
|
gen->resume_kind = 0;
|
|
158
|
-
|
|
303
|
+
gen->started = 1;
|
|
304
|
+
xt_generator_enter(gen);
|
|
159
305
|
if (gen->done) {
|
|
160
306
|
if (gen->threw) xt_throw(gen->result);
|
|
161
307
|
return xt_generator_result_object(gen->result, 1);
|
|
@@ -166,16 +312,18 @@ xt_value xt_generator_next(xt_value generator, xt_value sent) {
|
|
|
166
312
|
xt_value xt_generator_throw(xt_value generator, xt_value error) {
|
|
167
313
|
xt_generator *gen = xt_as_generator(generator);
|
|
168
314
|
if (!gen) {
|
|
169
|
-
xt_throw(
|
|
315
|
+
xt_throw(xt_error_from_message("TypeError: not a generator"));
|
|
170
316
|
return XT_UNDEFINED;
|
|
171
317
|
}
|
|
318
|
+
if (gen->is_async) return xt_async_enqueue(gen, error, 1);
|
|
172
319
|
if (gen->done) {
|
|
173
320
|
xt_throw(error);
|
|
174
321
|
return XT_UNDEFINED;
|
|
175
322
|
}
|
|
176
323
|
gen->sent = error;
|
|
177
324
|
gen->resume_kind = 1;
|
|
178
|
-
|
|
325
|
+
gen->started = 1;
|
|
326
|
+
xt_generator_enter(gen);
|
|
179
327
|
if (gen->done) {
|
|
180
328
|
if (gen->threw) xt_throw(gen->result);
|
|
181
329
|
return xt_generator_result_object(gen->result, 1);
|
|
@@ -186,9 +334,10 @@ xt_value xt_generator_throw(xt_value generator, xt_value error) {
|
|
|
186
334
|
xt_value xt_generator_return(xt_value generator, xt_value value) {
|
|
187
335
|
xt_generator *gen = xt_as_generator(generator);
|
|
188
336
|
if (!gen) {
|
|
189
|
-
xt_throw(
|
|
337
|
+
xt_throw(xt_error_from_message("TypeError: not a generator"));
|
|
190
338
|
return XT_UNDEFINED;
|
|
191
339
|
}
|
|
340
|
+
if (gen->is_async) return xt_async_enqueue(gen, value, 2);
|
|
192
341
|
/* Abandon the coroutine without resuming: finally blocks are not run. */
|
|
193
342
|
gen->done = 1;
|
|
194
343
|
gen->threw = 0;
|
|
@@ -203,21 +352,84 @@ xt_value xt_yield(xt_value value) {
|
|
|
203
352
|
xt_generator *gen = g_active_generator;
|
|
204
353
|
if (!gen || gen->done) return XT_UNDEFINED;
|
|
205
354
|
gen->result = value;
|
|
355
|
+
/* Settle the async `.next()` request that produced this yield. A pending
|
|
356
|
+
* `.throw(e)` must *not* settle it: if the body catches the error it may
|
|
357
|
+
* yield again, and only that next yield (or the escaped exception) settles
|
|
358
|
+
* the request. */
|
|
359
|
+
if (gen->is_async && gen->resume_kind != 1 && gen->pending_promise != XT_UNDEFINED) {
|
|
360
|
+
xt_value promise = gen->pending_promise;
|
|
361
|
+
gen->pending_promise = XT_UNDEFINED;
|
|
362
|
+
xt_promise_fulfill(promise, xt_generator_result_object(value, gen->resume_kind == 2));
|
|
363
|
+
}
|
|
364
|
+
/* The resume kind may change while suspended: control returns here only
|
|
365
|
+
* when the next `.next()` / `.throw()` / `.return()` resumes the coroutine,
|
|
366
|
+
* so the checks below must sit after the context switch. */
|
|
206
367
|
xt_coroutine_leave(gen->coroutine);
|
|
207
368
|
if (gen->resume_kind == 1) {
|
|
369
|
+
gen->resume_kind = 0;
|
|
208
370
|
xt_throw(gen->sent);
|
|
209
371
|
return XT_UNDEFINED;
|
|
210
372
|
}
|
|
211
373
|
if (gen->resume_kind == 2) {
|
|
374
|
+
gen->resume_kind = 0;
|
|
212
375
|
gen->done = 1;
|
|
213
376
|
gen->threw = 0;
|
|
214
377
|
gen->result = gen->sent;
|
|
378
|
+
if (gen->is_async && gen->pending_promise != XT_UNDEFINED) {
|
|
379
|
+
xt_value promise = gen->pending_promise;
|
|
380
|
+
gen->pending_promise = XT_UNDEFINED;
|
|
381
|
+
xt_promise_fulfill(promise, xt_generator_result_object(gen->sent, 1));
|
|
382
|
+
}
|
|
215
383
|
xt_coroutine_leave(gen->coroutine);
|
|
216
384
|
return XT_UNDEFINED;
|
|
217
385
|
}
|
|
218
386
|
return gen->sent;
|
|
219
387
|
}
|
|
220
388
|
|
|
389
|
+
/* `await value` inside an async generator. The generator's current `.next()`
|
|
390
|
+
* promise stays pending; when the awaited promise settles the coroutine is
|
|
391
|
+
* resumed and this function returns the settlement (or throws a rejection). */
|
|
392
|
+
int xt_generator_await(xt_value value, xt_value *result) {
|
|
393
|
+
xt_generator *gen = g_active_generator;
|
|
394
|
+
if (!gen || !gen->is_async || gen->done || !gen->coroutine) return 0;
|
|
395
|
+
/* A nested async function inside the generator runs on its own coroutine;
|
|
396
|
+
* its awaits must not suspend the generator. */
|
|
397
|
+
if (!xt_coroutine_is_current(gen->coroutine)) return 0;
|
|
398
|
+
int state = xt_promise_state_of(value);
|
|
399
|
+
if (state == XT_PROMISE_PENDING) {
|
|
400
|
+
gen->await_threw = 0;
|
|
401
|
+
gen->resume_value = XT_UNDEFINED;
|
|
402
|
+
xt_promise_add_async_waiter(value, gen);
|
|
403
|
+
xt_coroutine_leave(gen->coroutine);
|
|
404
|
+
} else {
|
|
405
|
+
int rejected = state == XT_PROMISE_REJECTED;
|
|
406
|
+
xt_value settled = (state == XT_PROMISE_FULFILLED || rejected)
|
|
407
|
+
? xt_promise_value_of(value)
|
|
408
|
+
: value;
|
|
409
|
+
gen->await_threw = rejected;
|
|
410
|
+
gen->resume_value = settled;
|
|
411
|
+
xt_promise_queue_async_wake(gen, settled, rejected);
|
|
412
|
+
xt_coroutine_leave(gen->coroutine);
|
|
413
|
+
}
|
|
414
|
+
if (gen->await_threw) {
|
|
415
|
+
gen->await_threw = 0;
|
|
416
|
+
xt_throw(gen->resume_value);
|
|
417
|
+
return 1;
|
|
418
|
+
}
|
|
419
|
+
*result = gen->resume_value;
|
|
420
|
+
return 1;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
void xt_generator_wake(void *pointer, xt_value value, int rejected) {
|
|
424
|
+
xt_generator *gen = (xt_generator *)pointer;
|
|
425
|
+
if (!gen || gen->done || !gen->coroutine) return;
|
|
426
|
+
gen->resume_value = value;
|
|
427
|
+
gen->await_threw = rejected;
|
|
428
|
+
xt_generator_enter(gen);
|
|
429
|
+
if (gen->done) xt_generator_settle_pending(gen);
|
|
430
|
+
else xt_generator_drain_requests(gen);
|
|
431
|
+
}
|
|
432
|
+
|
|
221
433
|
/* `yield* delegate`: relay every value the delegate produces. */
|
|
222
434
|
xt_value xt_yield_star(xt_value delegate) {
|
|
223
435
|
xt_value nextName = xt_string_from_cstr("next");
|
|
@@ -249,7 +461,7 @@ xt_value xt_yield_star(xt_value delegate) {
|
|
|
249
461
|
/* `for...of` step for generators: pull and cache the next value. */
|
|
250
462
|
int xt_generator_has_next(xt_value generator) {
|
|
251
463
|
xt_generator *gen = xt_as_generator(generator);
|
|
252
|
-
if (!gen || gen->done) return 0;
|
|
464
|
+
if (!gen || gen->done || gen->is_async) return 0;
|
|
253
465
|
xt_value step = xt_generator_next(generator, XT_UNDEFINED);
|
|
254
466
|
if (xt_truthy(xt_get(step, xt_string_from_cstr("done")))) return 0;
|
|
255
467
|
gen->iter_value = xt_get(step, xt_string_from_cstr("value"));
|
|
@@ -265,3 +477,80 @@ xt_value xt_function_set_generator(xt_value value) {
|
|
|
265
477
|
if (XT_IS_FUNCTION(value)) ((xt_function *)XT_GET_PTR(value))->is_generator = 1;
|
|
266
478
|
return value;
|
|
267
479
|
}
|
|
480
|
+
|
|
481
|
+
xt_value xt_function_set_async_generator(xt_value value) {
|
|
482
|
+
if (XT_IS_FUNCTION(value)) {
|
|
483
|
+
xt_function *function = (xt_function *)XT_GET_PTR(value);
|
|
484
|
+
function->is_generator = 1;
|
|
485
|
+
function->is_async_generator = 1;
|
|
486
|
+
}
|
|
487
|
+
return value;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/* -- async iteration ------------------------------------------------------ */
|
|
491
|
+
|
|
492
|
+
static xt_value xt_async_iterator_self(xt_value thisValue, xt_value env, int32_t argc,
|
|
493
|
+
xt_value *argv) {
|
|
494
|
+
(void)env;
|
|
495
|
+
(void)argc;
|
|
496
|
+
(void)argv;
|
|
497
|
+
return thisValue;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
xt_value xt_async_iterator_method(void) {
|
|
501
|
+
static xt_value method = XT_UNDEFINED;
|
|
502
|
+
if (!XT_IS_FUNCTION(method)) {
|
|
503
|
+
method = xt_closure_new((void *)xt_async_iterator_self, 0, NULL);
|
|
504
|
+
xt_gc_add_root(&method);
|
|
505
|
+
}
|
|
506
|
+
return method;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
xt_value xt_async_iter_open(xt_value value) {
|
|
510
|
+
if (xt_is_async_generator(value)) return value;
|
|
511
|
+
/* A user object may implement `[Symbol.asyncIterator]()`. */
|
|
512
|
+
if (XT_IS_OBJECT(value) || XT_IS_ARRAY(value) || XT_IS_FUNCTION(value)) {
|
|
513
|
+
xt_value method = xt_get(value, xt_symbol_well_known("asyncIterator"));
|
|
514
|
+
if (XT_IS_FUNCTION(method)) {
|
|
515
|
+
xt_value iterator = xt_call_with_this(method, value, 0, NULL);
|
|
516
|
+
if (XT_IS_OBJECT(iterator) || XT_IS_FUNCTION(iterator)) return iterator;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
/* Fall back to the synchronous protocol and adapt each step. */
|
|
520
|
+
xt_async_iterator_state *state =
|
|
521
|
+
(xt_async_iterator_state *)xt_alloc(sizeof(xt_async_iterator_state),
|
|
522
|
+
XT_OBJECT_KIND_ASYNC_ITERATOR);
|
|
523
|
+
state->iterator = xt_iter_open(value);
|
|
524
|
+
state->index = xt_number(0);
|
|
525
|
+
state->done = 0;
|
|
526
|
+
return XT_FROM_PTR(XT_TAG_OBJECT, state);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
static int xt_is_async_iterator_state(xt_value value) {
|
|
530
|
+
return XT_IS_OBJECT(value) &&
|
|
531
|
+
((xt_header *)XT_GET_PTR(value))->kind == XT_OBJECT_KIND_ASYNC_ITERATOR;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
xt_value xt_async_iter_next(xt_value iterator) {
|
|
535
|
+
if (xt_is_async_generator(iterator)) return xt_generator_next(iterator, XT_UNDEFINED);
|
|
536
|
+
if (xt_is_async_iterator_state(iterator)) {
|
|
537
|
+
xt_async_iterator_state *state = (xt_async_iterator_state *)XT_GET_PTR(iterator);
|
|
538
|
+
if (state->done) return xt_promise_resolve(xt_generator_result_object(XT_UNDEFINED, 1));
|
|
539
|
+
if (!xt_truthy(xt_iter_has(state->iterator, state->index))) {
|
|
540
|
+
state->done = 1;
|
|
541
|
+
return xt_promise_resolve(xt_generator_result_object(XT_UNDEFINED, 1));
|
|
542
|
+
}
|
|
543
|
+
xt_value value = xt_iter_value(state->iterator, state->index);
|
|
544
|
+
state->index = xt_add(state->index, xt_number(1));
|
|
545
|
+
return xt_promise_resolve(xt_generator_result_object(value, 0));
|
|
546
|
+
}
|
|
547
|
+
xt_value step = xt_call_method(iterator, xt_string_from_cstr("next"), 0, NULL);
|
|
548
|
+
if (xt_promise_state_of(step) >= 0) return step;
|
|
549
|
+
return xt_promise_resolve(step);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
void xt_async_iterator_gc_trace(xt_header *header) {
|
|
553
|
+
xt_async_iterator_state *state = (xt_async_iterator_state *)header;
|
|
554
|
+
xt_gc_mark_value(state->iterator);
|
|
555
|
+
xt_gc_mark_value(state->index);
|
|
556
|
+
}
|
|
@@ -179,8 +179,120 @@ static void xt_inspect(xt_value v, FILE *out, int nested) {
|
|
|
179
179
|
xt_inspect_pop();
|
|
180
180
|
return;
|
|
181
181
|
}
|
|
182
|
+
int typedKind = xt_typed_array_kind_of(v);
|
|
183
|
+
if (typedKind >= 0) {
|
|
184
|
+
const char *name = xt_typed_array_name_of(typedKind);
|
|
185
|
+
uint32_t length = (uint32_t)xt_to_number(xt_get(v, xt_string_from_cstr("length")));
|
|
186
|
+
fprintf(out, "%s(%u) [", name ? name : "TypedArray", length);
|
|
187
|
+
for (uint32_t i = 0; i < length; i++) {
|
|
188
|
+
fputs(i == 0 ? " " : ", ", out);
|
|
189
|
+
xt_inspect(xt_typed_array_read(v, i), out, 1);
|
|
190
|
+
}
|
|
191
|
+
if (length > 0) fputc(' ', out);
|
|
192
|
+
fputc(']', out);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
182
195
|
if (XT_IS_OBJECT(v)) {
|
|
183
196
|
xt_object *obj = (xt_object *)XT_GET_PTR(v);
|
|
197
|
+
/* Map, Set, Date, RegExp, Promise, generators and iterators are heap
|
|
198
|
+
* objects with their own struct layouts, so treating them as `xt_object`
|
|
199
|
+
* and reading `count`/`properties` reads unrelated memory (it used to
|
|
200
|
+
* crash on a non-empty Map). Format each kind from its real fields. */
|
|
201
|
+
switch (obj->header.kind) {
|
|
202
|
+
case XT_OBJECT_KIND_MAP: {
|
|
203
|
+
xt_map *map = (xt_map *)obj;
|
|
204
|
+
int seenMap = xt_inspect_seen(map);
|
|
205
|
+
if (seenMap > 0) {
|
|
206
|
+
fprintf(out, "[Circular *%d]", seenMap);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
if (xt_inspect_depth >= XT_INSPECT_MAX_DEPTH) {
|
|
210
|
+
fputs("[Map]", out);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
xt_inspect_push(map);
|
|
214
|
+
fprintf(out, "Map(%u) {", map->count);
|
|
215
|
+
for (uint32_t i = 0; i < map->count; i++) {
|
|
216
|
+
fputs(i == 0 ? " " : ", ", out);
|
|
217
|
+
xt_inspect(map->keys[i], out, 1);
|
|
218
|
+
fputs(" => ", out);
|
|
219
|
+
xt_inspect(map->values[i], out, 1);
|
|
220
|
+
}
|
|
221
|
+
if (map->count > 0) fputc(' ', out);
|
|
222
|
+
fputc('}', out);
|
|
223
|
+
xt_inspect_pop();
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
case XT_OBJECT_KIND_SET: {
|
|
227
|
+
xt_set_object *set = (xt_set_object *)obj;
|
|
228
|
+
int seenSet = xt_inspect_seen(set);
|
|
229
|
+
if (seenSet > 0) {
|
|
230
|
+
fprintf(out, "[Circular *%d]", seenSet);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
if (xt_inspect_depth >= XT_INSPECT_MAX_DEPTH) {
|
|
234
|
+
fputs("[Set]", out);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
xt_inspect_push(set);
|
|
238
|
+
fprintf(out, "Set(%u) {", set->count);
|
|
239
|
+
for (uint32_t i = 0; i < set->count; i++) {
|
|
240
|
+
fputs(i == 0 ? " " : ", ", out);
|
|
241
|
+
xt_inspect(set->values[i], out, 1);
|
|
242
|
+
}
|
|
243
|
+
if (set->count > 0) fputc(' ', out);
|
|
244
|
+
fputc('}', out);
|
|
245
|
+
xt_inspect_pop();
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
case XT_OBJECT_KIND_DATE: {
|
|
249
|
+
/* `Date.prototype.toISOString` is the representation Node prints. */
|
|
250
|
+
xt_value text = xt_call_method(v, xt_string_from_cstr("toISOString"), 0, NULL);
|
|
251
|
+
xt_inspect(text, out, 0);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
case XT_OBJECT_KIND_REGEXP: {
|
|
255
|
+
xt_regexp *regexp = (xt_regexp *)obj;
|
|
256
|
+
fputc('/', out);
|
|
257
|
+
xt_inspect(regexp->source, out, 0);
|
|
258
|
+
fputc('/', out);
|
|
259
|
+
xt_inspect(regexp->flags, out, 0);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
case XT_OBJECT_KIND_PROMISE: {
|
|
263
|
+
int state = xt_promise_state_of(v);
|
|
264
|
+
fputs("Promise { ", out);
|
|
265
|
+
if (state == XT_PROMISE_PENDING) {
|
|
266
|
+
fputs("<pending>", out);
|
|
267
|
+
} else {
|
|
268
|
+
if (state == XT_PROMISE_REJECTED) fputs("<rejected> ", out);
|
|
269
|
+
xt_inspect(xt_promise_value_of(v), out, 1);
|
|
270
|
+
}
|
|
271
|
+
fputs(" }", out);
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
case XT_OBJECT_KIND_WEAK_MAP:
|
|
275
|
+
fputs("WeakMap { <items unknown> }", out);
|
|
276
|
+
return;
|
|
277
|
+
case XT_OBJECT_KIND_WEAK_SET:
|
|
278
|
+
fputs("WeakSet { <items unknown> }", out);
|
|
279
|
+
return;
|
|
280
|
+
case XT_OBJECT_KIND_WEAK_REF:
|
|
281
|
+
fputs("WeakRef {}", out);
|
|
282
|
+
return;
|
|
283
|
+
case XT_OBJECT_KIND_GENERATOR:
|
|
284
|
+
fputs("Object [Generator] {}", out);
|
|
285
|
+
return;
|
|
286
|
+
case XT_OBJECT_KIND_ITERATOR:
|
|
287
|
+
case XT_OBJECT_KIND_ASYNC:
|
|
288
|
+
/* Internal helper objects have no useful user-visible shape. */
|
|
289
|
+
fputs("[object Object]", out);
|
|
290
|
+
return;
|
|
291
|
+
default:
|
|
292
|
+
/* XT_OBJECT_KIND_OBJECT and XT_OBJECT_KIND_ERROR share the property
|
|
293
|
+
* bag layout and fall through to the generic formatter below. */
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
184
296
|
int seen = xt_inspect_seen(obj);
|
|
185
297
|
if (seen > 0) {
|
|
186
298
|
fprintf(out, "[Circular *%d]", seen);
|