xbintsc 0.3.87 → 0.5.20
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 +23 -11
- package/README.md +11 -9
- package/README.zh-CN.md +7 -7
- 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 +17 -4
- package/dist/src/codegen/generator/calls/access.js.map +1 -1
- package/dist/src/codegen/generator/calls/closures.js +13 -1
- package/dist/src/codegen/generator/calls/closures.js.map +1 -1
- package/dist/src/codegen/generator/calls/invocation.js +4 -3
- package/dist/src/codegen/generator/calls/invocation.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 +11 -1
- package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
- package/dist/src/codegen/generator/module.d.ts +0 -1
- package/dist/src/codegen/generator/module.js +10 -17
- 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 +27 -0
- package/dist/src/codegen/generator/state.js.map +1 -1
- package/dist/src/codegen/generator/statements/control-flow.js +2 -7
- 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.d.ts +9 -0
- package/dist/src/codegen/generator/tables.js +100 -3
- 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 +94 -230
- 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 +111 -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/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/closures.test.js +8 -0
- package/dist/tests/codegen/closures.test.js.map +1 -1
- 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.d.ts +10 -0
- package/dist/tests/e2e/async-await.test.js +247 -0
- package/dist/tests/e2e/async-await.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/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-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-coverage-globals.test.js +46 -0
- package/dist/tests/e2e/runtime-coverage-globals.test.js.map +1 -1
- 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/string-utf16.test.d.ts +6 -0
- package/dist/tests/e2e/string-utf16.test.js +133 -0
- package/dist/tests/e2e/string-utf16.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 +26 -21
- package/doc/ai/extensions.md +12 -9
- package/doc/ai/language-support.md +26 -19
- package/doc/ai/troubleshooting.md +15 -12
- 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 +19 -18
- package/doc/ai/zh-CN/extensions.md +10 -7
- package/doc/ai/zh-CN/language-support.md +26 -20
- package/doc/ai/zh-CN/troubleshooting.md +12 -10
- package/doc/gui/build.md +13 -4
- package/doc/gui/known-issues.md +9 -5
- package/doc/gui/rendering.md +3 -1
- package/doc/gui.md +4 -3
- package/doc/icon.md +5 -4
- package/doc/implemented/async.md +38 -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 +12 -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 +38 -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 -352
- 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 +17 -0
- package/doc/unimplemented/node/bun.md +9 -0
- package/doc/unimplemented/node/fs-promises.md +16 -0
- package/doc/unimplemented/node/fs.md +31 -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 -274
- package/doc/xbintsc.config.schema.json +12 -0
- package/doc/zh-CN/gui/build.md +11 -3
- package/doc/zh-CN/gui/known-issues.md +9 -4
- package/doc/zh-CN/gui/rendering.md +2 -1
- package/doc/zh-CN/gui.md +3 -2
- package/doc/zh-CN/icon.md +5 -4
- package/doc/zh-CN/implemented/async.md +38 -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 +12 -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 +27 -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 -347
- 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 +17 -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 -236
- package/llms.txt +32 -4
- package/package.json +1 -1
- package/runtime/ext_gui/renderer_shaders.h +2 -2
- package/runtime/ext_gui/stb_image.h +1 -17
- package/runtime/ext_node/child_process/child_process.c +173 -73
- package/runtime/rt.h +47 -0
- package/runtime/rt_internal.h +205 -10
- package/runtime/xt_alloc.c +49 -7
- package/runtime/xt_array_buffer.c +284 -0
- package/runtime/xt_async.c +222 -0
- package/runtime/xt_bigint/helpers.inc +3 -3
- package/runtime/xt_builtins.c +59 -51
- package/runtime/xt_constructors.c +399 -0
- package/runtime/xt_containers/access.inc +195 -14
- package/runtime/xt_containers/arrays.inc +26 -2
- package/runtime/xt_containers/objects.inc +226 -5
- package/runtime/xt_containers/shapes.inc +71 -0
- package/runtime/xt_containers.c +1 -0
- package/runtime/xt_coroutine.c +229 -0
- package/runtime/xt_generator.c +325 -167
- package/runtime/xt_io/inspect.inc +147 -2
- package/runtime/xt_loop.c +35 -4
- package/runtime/xt_performance.c +37 -0
- package/runtime/xt_promise.c +125 -18
- package/runtime/xt_stdlib/arrays.inc +1 -1
- package/runtime/xt_stdlib/dispatch.inc +64 -13
- package/runtime/xt_stdlib/strings.inc +74 -17
- package/runtime/xt_stdlib2/array-statics.inc +28 -3
- 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 +35 -0
- package/runtime/xt_stdlib2/json.inc +353 -33
- package/runtime/xt_stdlib2/number-string-statics.inc +24 -15
- package/runtime/xt_stdlib2/objects.inc +123 -1
- package/runtime/xt_stdlib2/regexp-match.inc +2 -2
- package/runtime/xt_stdlib2/set.inc +7 -1
- package/runtime/xt_stdlib2/strings.inc +70 -40
- 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 +78 -7
- package/runtime/xt_typed_array/elements.inc +159 -0
- package/runtime/xt_typed_array/methods.inc +21 -5
- package/runtime/xt_typed_array.c +11 -10
- package/runtime/xt_url.c +375 -0
- package/runtime/xt_values/arithmetic.inc +2 -2
- package/runtime/xt_values/constructors.inc +8 -0
- package/runtime/xt_values/conversions.inc +1 -1
- package/runtime/xt_values/strings.inc +19 -3
- package/runtime/xt_values/utf16.inc +340 -0
- package/runtime/xt_values.c +1 -0
- 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 +17 -4
- package/src/codegen/generator/calls/closures.ts +12 -1
- package/src/codegen/generator/calls/invocation.ts +4 -3
- package/src/codegen/generator/context.ts +23 -3
- package/src/codegen/generator/expressions/operators.ts +27 -13
- package/src/codegen/generator/expressions/primary.ts +10 -1
- package/src/codegen/generator/module.ts +10 -19
- package/src/codegen/generator/numeric.ts +85 -11
- package/src/codegen/generator/state.ts +27 -0
- package/src/codegen/generator/statements/control-flow.ts +2 -6
- package/src/codegen/generator/statements/loops.ts +50 -16
- package/src/codegen/generator/tables.ts +110 -3
- 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 +93 -324
- 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 +133 -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/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,284 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* xbintsc runtime — ArrayBuffer and DataView.
|
|
3
|
+
*
|
|
4
|
+
* An ArrayBuffer is a plain object holding its bytes as an array of numbers
|
|
5
|
+
* under a private symbol, plus a public `byteLength`. A DataView is another
|
|
6
|
+
* plain object that points at the buffer and exposes the get/set accessors;
|
|
7
|
+
* every accessor assembles the bytes explicitly, so the default big-endian
|
|
8
|
+
* order and the optional `littleEndian` argument follow ECMAScript.
|
|
9
|
+
*
|
|
10
|
+
* Keeping both as ordinary objects means the garbage collector, property
|
|
11
|
+
* lookup and the rest of the runtime need no new object kind. Typed arrays
|
|
12
|
+
* are buffer-backed views over this object and share its bytes; `new
|
|
13
|
+
* Uint8Array(buffer, offset, length)`, `.buffer` and `subarray` are handled by
|
|
14
|
+
* xt_typed_array.c.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#include "rt_internal.h"
|
|
18
|
+
|
|
19
|
+
#include <math.h>
|
|
20
|
+
#include <stdlib.h>
|
|
21
|
+
#include <string.h>
|
|
22
|
+
|
|
23
|
+
static xt_value xt_ab_data_key_value = XT_UNDEFINED;
|
|
24
|
+
|
|
25
|
+
static xt_value xt_ab_data_key(void) {
|
|
26
|
+
/* A symbol key keeps the backing bytes out of Object.keys / JSON.stringify,
|
|
27
|
+
* like the platform's internal [[ArrayBufferData]] slot. */
|
|
28
|
+
if (!xt_is_symbol(xt_ab_data_key_value)) {
|
|
29
|
+
xt_ab_data_key_value = xt_symbol_new(xt_string_from_cstr("__arrayBufferData"));
|
|
30
|
+
xt_gc_add_root(&xt_ab_data_key_value);
|
|
31
|
+
}
|
|
32
|
+
return xt_ab_data_key_value;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static xt_value xt_ab_data(xt_value buffer) { if (!XT_IS_OBJECT(buffer)) return XT_UNDEFINED;
|
|
36
|
+
return xt_object_get(buffer, xt_ab_data_key());
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static int xt_ab_is_buffer(xt_value value) {
|
|
40
|
+
return XT_IS_ARRAY(xt_ab_data(value));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static xt_value xt_ab_new(uint32_t length) {
|
|
44
|
+
xt_value buffer = xt_object_new();
|
|
45
|
+
xt_object_set(buffer, xt_string_from_cstr("byteLength"), xt_number((double)length));
|
|
46
|
+
xt_value data = xt_array_new(0, NULL);
|
|
47
|
+
for (uint32_t i = 0; i < length; i++) xt_array_push(data, xt_number(0));
|
|
48
|
+
xt_object_set(buffer, xt_ab_data_key(), data);
|
|
49
|
+
return buffer;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static xt_value xt_ab_slice(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv);
|
|
53
|
+
static void xt_ab_install(xt_value object, const char *name, void *fn);
|
|
54
|
+
|
|
55
|
+
xt_value xt_array_buffer_ctor(int32_t argc, xt_value *argv) {
|
|
56
|
+
double length = xt_to_number(xt_arg_at(argc, argv, 0));
|
|
57
|
+
if (!(length >= 0) || length > 4294967295.0) length = 0;
|
|
58
|
+
xt_value buffer = xt_ab_new((uint32_t)length);
|
|
59
|
+
xt_ab_install(buffer, "slice", (void *)xt_ab_slice);
|
|
60
|
+
return buffer;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
int xt_is_array_buffer(xt_value value) { return xt_ab_is_buffer(value); }
|
|
64
|
+
|
|
65
|
+
uint32_t xt_array_buffer_byte_length(xt_value value) {
|
|
66
|
+
if (!xt_ab_is_buffer(value)) return 0;
|
|
67
|
+
return (uint32_t)xt_to_number(xt_get(value, xt_string_from_cstr("byteLength")));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
uint8_t xt_array_buffer_get_byte(xt_value buffer, uint32_t index) {
|
|
71
|
+
xt_value data = xt_ab_data(buffer);
|
|
72
|
+
if (!XT_IS_ARRAY(data)) return 0;
|
|
73
|
+
return (uint8_t)xt_to_int32(xt_get(data, xt_number((double)index)));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
void xt_array_buffer_set_byte(xt_value buffer, uint32_t index, uint8_t value) {
|
|
77
|
+
xt_value data = xt_ab_data(buffer);
|
|
78
|
+
if (!XT_IS_ARRAY(data)) return;
|
|
79
|
+
xt_set(data, xt_number((double)index), xt_number((double)value));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
static xt_value xt_ab_slice(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
83
|
+
(void)env;
|
|
84
|
+
xt_value data = xt_ab_data(thisValue);
|
|
85
|
+
if (!XT_IS_ARRAY(data)) return xt_ab_new(0);
|
|
86
|
+
int32_t length = xt_to_int32(xt_array_length(data));
|
|
87
|
+
int32_t start = argc > 0 && argv[0] != XT_UNDEFINED ? xt_to_int32(argv[0]) : 0;
|
|
88
|
+
int32_t end = argc > 1 && argv[1] != XT_UNDEFINED ? xt_to_int32(argv[1]) : length;
|
|
89
|
+
if (start < 0) start += length;
|
|
90
|
+
if (end < 0) end += length;
|
|
91
|
+
if (start < 0) start = 0;
|
|
92
|
+
if (end > length) end = length;
|
|
93
|
+
if (end < start) end = start;
|
|
94
|
+
xt_value result = xt_ab_new(0);
|
|
95
|
+
xt_ab_install(result, "slice", (void *)xt_ab_slice);
|
|
96
|
+
xt_value source = xt_ab_data(result);
|
|
97
|
+
for (int32_t i = start; i < end; i++) xt_array_push(source, xt_get(data, xt_number((double)i)));
|
|
98
|
+
xt_object_set(result, xt_string_from_cstr("byteLength"), xt_number((double)(end - start)));
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
static void xt_ab_install(xt_value object, const char *name, void *fn) {
|
|
103
|
+
xt_object_set(object, xt_string_from_cstr(name), xt_closure_new(fn, 0, NULL));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
xt_value xt_array_buffer_static(xt_value name, int32_t argc, xt_value *argv) {
|
|
107
|
+
const char *method = xt_string_data(name);
|
|
108
|
+
if (!method) return XT_UNDEFINED;
|
|
109
|
+
if (strcmp(method, "isView") == 0) {
|
|
110
|
+
xt_value value = xt_arg_at(argc, argv, 0);
|
|
111
|
+
if (xt_typed_array_kind_of(value) >= 0) return XT_TRUE;
|
|
112
|
+
if (!XT_IS_OBJECT(value)) return XT_FALSE;
|
|
113
|
+
if (((xt_object *)XT_GET_PTR(value))->header.kind != XT_OBJECT_KIND_OBJECT) return XT_FALSE;
|
|
114
|
+
xt_value buffer = xt_object_get(value, xt_string_from_cstr("buffer"));
|
|
115
|
+
return xt_bool(xt_ab_is_buffer(buffer) &&
|
|
116
|
+
xt_object_get(value, xt_string_from_cstr("byteLength")) != XT_UNDEFINED);
|
|
117
|
+
}
|
|
118
|
+
return XT_UNDEFINED;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/* -- DataView ------------------------------------------------------------- */
|
|
122
|
+
|
|
123
|
+
enum {
|
|
124
|
+
XT_DV_U8,
|
|
125
|
+
XT_DV_I8,
|
|
126
|
+
XT_DV_U16,
|
|
127
|
+
XT_DV_I16,
|
|
128
|
+
XT_DV_U32,
|
|
129
|
+
XT_DV_I32,
|
|
130
|
+
XT_DV_F32,
|
|
131
|
+
XT_DV_F64,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
static uint32_t xt_dv_width(int kind) {
|
|
135
|
+
switch (kind) {
|
|
136
|
+
case XT_DV_U8:
|
|
137
|
+
case XT_DV_I8:
|
|
138
|
+
return 1;
|
|
139
|
+
case XT_DV_U16:
|
|
140
|
+
case XT_DV_I16:
|
|
141
|
+
return 2;
|
|
142
|
+
case XT_DV_U32:
|
|
143
|
+
case XT_DV_I32:
|
|
144
|
+
case XT_DV_F32:
|
|
145
|
+
return 4;
|
|
146
|
+
default:
|
|
147
|
+
return 8;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
static int xt_dv_signed(int kind) {
|
|
152
|
+
return kind == XT_DV_I8 || kind == XT_DV_I16 || kind == XT_DV_I32;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
static xt_value xt_dv_data(xt_value view) {
|
|
156
|
+
return xt_ab_data(xt_get(view, xt_string_from_cstr("buffer")));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
static uint32_t xt_dv_offset(xt_value view) {
|
|
160
|
+
return (uint32_t)xt_to_number(xt_get(view, xt_string_from_cstr("byteOffset")));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
static uint32_t xt_dv_length(xt_value view) {
|
|
164
|
+
return (uint32_t)xt_to_number(xt_get(view, xt_string_from_cstr("byteLength")));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
static int xt_dv_check(xt_value view, xt_value indexValue, uint32_t width, uint32_t *out) {
|
|
168
|
+
double raw = xt_to_number(indexValue);
|
|
169
|
+
if (!(raw >= 0)) raw = -1;
|
|
170
|
+
int64_t index = (int64_t)raw;
|
|
171
|
+
if (index < 0 || (uint64_t)index + width > xt_dv_length(view)) {
|
|
172
|
+
xt_value message = xt_string_from_cstr("Offset is outside the bounds of the DataView");
|
|
173
|
+
xt_throw(xt_range_error_ctor(1, &message));
|
|
174
|
+
}
|
|
175
|
+
*out = xt_dv_offset(view) + (uint32_t)index;
|
|
176
|
+
return 1;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
static uint64_t xt_dv_read_bits(xt_value view, uint32_t offset, uint32_t width, int little) {
|
|
180
|
+
xt_value data = xt_dv_data(view);
|
|
181
|
+
uint64_t value = 0;
|
|
182
|
+
for (uint32_t i = 0; i < width; i++) {
|
|
183
|
+
uint32_t index = little ? offset + width - 1 - i : offset + i;
|
|
184
|
+
uint64_t byte = (uint64_t)xt_to_number(xt_get(data, xt_number((double)index)));
|
|
185
|
+
value = (value << 8) | (byte & 0xff);
|
|
186
|
+
}
|
|
187
|
+
return value;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
static void xt_dv_write_bits(xt_value view, uint32_t offset, uint32_t width, uint64_t value,
|
|
191
|
+
int little) {
|
|
192
|
+
xt_value data = xt_dv_data(view);
|
|
193
|
+
for (uint32_t i = 0; i < width; i++) {
|
|
194
|
+
uint32_t shift = little ? i * 8 : (width - 1 - i) * 8;
|
|
195
|
+
uint32_t index = offset + i;
|
|
196
|
+
xt_set(data, xt_number((double)index), xt_number((double)((value >> shift) & 0xff)));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
static xt_value xt_dv_method(xt_value thisValue, xt_value env, int32_t argc, xt_value *argv) {
|
|
201
|
+
int kind = (int)xt_to_number(xt_closure_env(env, 0));
|
|
202
|
+
int setter = (int)xt_to_number(xt_closure_env(env, 1));
|
|
203
|
+
uint32_t width = xt_dv_width(kind);
|
|
204
|
+
uint32_t offset = 0;
|
|
205
|
+
xt_dv_check(thisValue, xt_arg_at(argc, argv, 0), width, &offset);
|
|
206
|
+
int little = argc > (setter ? 2 : 1) && xt_truthy(xt_arg_at(argc, argv, setter ? 2 : 1));
|
|
207
|
+
if (setter) {
|
|
208
|
+
double value = xt_to_number(xt_arg_at(argc, argv, 1));
|
|
209
|
+
uint64_t bits;
|
|
210
|
+
if (kind == XT_DV_F32) {
|
|
211
|
+
float narrowed = (float)value;
|
|
212
|
+
uint32_t raw;
|
|
213
|
+
memcpy(&raw, &narrowed, sizeof(raw));
|
|
214
|
+
bits = raw;
|
|
215
|
+
} else if (kind == XT_DV_F64) {
|
|
216
|
+
double raw = value;
|
|
217
|
+
memcpy(&bits, &raw, sizeof(bits));
|
|
218
|
+
} else if (kind == XT_DV_I8) {
|
|
219
|
+
bits = (uint64_t)(uint8_t)(int8_t)xt_to_int32(xt_number(value));
|
|
220
|
+
} else if (kind == XT_DV_I16) {
|
|
221
|
+
bits = (uint64_t)(uint16_t)(int16_t)xt_to_int32(xt_number(value));
|
|
222
|
+
} else if (kind == XT_DV_I32) {
|
|
223
|
+
bits = (uint64_t)(uint32_t)(int32_t)xt_to_int32(xt_number(value));
|
|
224
|
+
} else {
|
|
225
|
+
bits = (uint64_t)(uint32_t)xt_to_int32(xt_number(value));
|
|
226
|
+
}
|
|
227
|
+
xt_dv_write_bits(thisValue, offset, width, bits, little);
|
|
228
|
+
return XT_UNDEFINED;
|
|
229
|
+
}
|
|
230
|
+
uint64_t bits = xt_dv_read_bits(thisValue, offset, width, little);
|
|
231
|
+
if (kind == XT_DV_F32) {
|
|
232
|
+
uint32_t raw = (uint32_t)bits;
|
|
233
|
+
float value;
|
|
234
|
+
memcpy(&value, &raw, sizeof(value));
|
|
235
|
+
return xt_number((double)value);
|
|
236
|
+
}
|
|
237
|
+
if (kind == XT_DV_F64) {
|
|
238
|
+
double value;
|
|
239
|
+
memcpy(&value, &bits, sizeof(value));
|
|
240
|
+
return xt_number(value);
|
|
241
|
+
}
|
|
242
|
+
if (xt_dv_signed(kind)) {
|
|
243
|
+
int64_t signedValue = (int64_t)bits;
|
|
244
|
+
if (width < 8) {
|
|
245
|
+
uint64_t signBit = 1ULL << (width * 8 - 1);
|
|
246
|
+
if (bits & signBit) signedValue = (int64_t)(bits | (~0ULL << (width * 8)));
|
|
247
|
+
}
|
|
248
|
+
return xt_number((double)signedValue);
|
|
249
|
+
}
|
|
250
|
+
return xt_number((double)bits);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
xt_value xt_data_view_ctor(int32_t argc, xt_value *argv) {
|
|
254
|
+
xt_value buffer = xt_arg_at(argc, argv, 0);
|
|
255
|
+
if (!xt_ab_is_buffer(buffer)) {
|
|
256
|
+
xt_value message = xt_string_from_cstr("First argument to DataView constructor must be an ArrayBuffer");
|
|
257
|
+
xt_throw(xt_type_error_ctor(1, &message));
|
|
258
|
+
}
|
|
259
|
+
uint32_t bufferLength = (uint32_t)xt_to_number(xt_get(buffer, xt_string_from_cstr("byteLength")));
|
|
260
|
+
double rawOffset = argc > 1 ? xt_to_number(argv[1]) : 0;
|
|
261
|
+
uint32_t offset = rawOffset > 0 ? (uint32_t)rawOffset : 0;
|
|
262
|
+
double rawLength = argc > 2 && argv[2] != XT_UNDEFINED ? xt_to_number(argv[2]) : (double)(bufferLength - offset);
|
|
263
|
+
uint32_t length = rawLength > 0 ? (uint32_t)rawLength : 0;
|
|
264
|
+
if (offset > bufferLength || length > bufferLength - offset) {
|
|
265
|
+
xt_value message = xt_string_from_cstr("Invalid DataView length");
|
|
266
|
+
xt_throw(xt_range_error_ctor(1, &message));
|
|
267
|
+
}
|
|
268
|
+
xt_value view = xt_object_new();
|
|
269
|
+
xt_object_set(view, xt_string_from_cstr("buffer"), buffer);
|
|
270
|
+
xt_object_set(view, xt_string_from_cstr("byteOffset"), xt_number((double)offset));
|
|
271
|
+
xt_object_set(view, xt_string_from_cstr("byteLength"), xt_number((double)length));
|
|
272
|
+
static const char *const getters[] = {"getUint8", "getInt8", "getUint16", "getInt16",
|
|
273
|
+
"getUint32", "getInt32", "getFloat32", "getFloat64"};
|
|
274
|
+
static const char *const setters[] = {"setUint8", "setInt8", "setUint16", "setInt16",
|
|
275
|
+
"setUint32", "setInt32", "setFloat32", "setFloat64"};
|
|
276
|
+
for (int kind = 0; kind < 8; kind++) {
|
|
277
|
+
for (int isSetter = 0; isSetter < 2; isSetter++) {
|
|
278
|
+
xt_value environment[2] = {xt_number((double)kind), xt_number((double)isSetter)};
|
|
279
|
+
xt_value closure = xt_closure_new((void *)xt_dv_method, 2, environment);
|
|
280
|
+
xt_object_set(view, xt_string_from_cstr(isSetter ? setters[kind] : getters[kind]), closure);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return view;
|
|
284
|
+
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* xbintsc runtime — real `async` / `await`.
|
|
3
|
+
*
|
|
4
|
+
* An `async` function runs its body on a stackful coroutine (the same
|
|
5
|
+
* machinery generators use, see `xt_coroutine.c`) and immediately returns a
|
|
6
|
+
* promise. The body runs synchronously until it reaches an `await` whose
|
|
7
|
+
* operand is still pending; at that point the coroutine suspends and control
|
|
8
|
+
* returns to the caller, so the program body or the event loop can keep going.
|
|
9
|
+
* When the awaited promise settles, the promise runtime queues a microtask that
|
|
10
|
+
* resumes the coroutine exactly where it stopped — because the coroutine keeps
|
|
11
|
+
* a real C stack, `try`/`finally`, loops and locals all survive the suspension
|
|
12
|
+
* without a state-machine transform.
|
|
13
|
+
*
|
|
14
|
+
* `await` always yields: even a non-promise or an already-settled promise
|
|
15
|
+
* queues a microtask before the body resumes, matching the specification's
|
|
16
|
+
* interleaving with pending `.then` callbacks. (Top-level `await`, with no
|
|
17
|
+
* coroutine to suspend, still blocks on the event loop.)
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
#include "rt_internal.h"
|
|
21
|
+
|
|
22
|
+
#include <stdlib.h>
|
|
23
|
+
#include <string.h>
|
|
24
|
+
|
|
25
|
+
typedef struct xt_async {
|
|
26
|
+
xt_header header;
|
|
27
|
+
xt_value function;
|
|
28
|
+
xt_value this_value;
|
|
29
|
+
xt_value *args;
|
|
30
|
+
int32_t argc;
|
|
31
|
+
/* Promise returned to the caller and settled when the body finishes. */
|
|
32
|
+
xt_value promise;
|
|
33
|
+
/* Completion value, or the exception that escaped the body. */
|
|
34
|
+
xt_value value;
|
|
35
|
+
/* Values handed over by the waiter and consumed by `xt_await`. */
|
|
36
|
+
xt_value resume_value;
|
|
37
|
+
int await_threw;
|
|
38
|
+
int done;
|
|
39
|
+
int threw;
|
|
40
|
+
xt_coroutine *coroutine;
|
|
41
|
+
} xt_async;
|
|
42
|
+
|
|
43
|
+
/* The async coroutine currently running on its private stack, if any. It is
|
|
44
|
+
* only reachable through this pointer while it runs, so it is a GC root. */
|
|
45
|
+
static xt_async *g_active_async = NULL;
|
|
46
|
+
|
|
47
|
+
static void xt_async_gc_register(void);
|
|
48
|
+
|
|
49
|
+
/* Runs on the coroutine's private stack and never returns normally: it
|
|
50
|
+
* suspends back to the resumer once the body has completed. */
|
|
51
|
+
static void xt_async_run(void *arg) {
|
|
52
|
+
xt_async *async = (xt_async *)arg;
|
|
53
|
+
void *boundary = xt_try_enter();
|
|
54
|
+
if (xt_try_setjmp(boundary) == 0) {
|
|
55
|
+
xt_function *function = (xt_function *)XT_GET_PTR(async->function);
|
|
56
|
+
async->value = function->code(async->this_value, async->function, async->argc, async->args);
|
|
57
|
+
async->threw = 0;
|
|
58
|
+
} else {
|
|
59
|
+
/* `throw` inside the body (not caught by a `try`) rejects the promise. */
|
|
60
|
+
async->value = xt_try_exception(boundary);
|
|
61
|
+
async->threw = 1;
|
|
62
|
+
}
|
|
63
|
+
async->done = 1;
|
|
64
|
+
xt_coroutine_leave(async->coroutine);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* Switch onto the coroutine. It either suspends at an `await` or completes. */
|
|
68
|
+
static void xt_async_resume(xt_async *async) {
|
|
69
|
+
xt_async *previous = g_active_async;
|
|
70
|
+
g_active_async = async;
|
|
71
|
+
xt_coroutine_enter(async->coroutine);
|
|
72
|
+
g_active_async = previous;
|
|
73
|
+
if (!async->done) return;
|
|
74
|
+
xt_coroutine_release(async->coroutine);
|
|
75
|
+
async->coroutine = NULL;
|
|
76
|
+
if (async->threw) xt_promise_reject_value(async->promise, async->value);
|
|
77
|
+
else xt_promise_fulfill(async->promise, async->value);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
xt_value xt_async_call(xt_value function, xt_value thisValue, int32_t argc, xt_value *argv) {
|
|
81
|
+
xt_async *async = (xt_async *)xt_alloc(sizeof(xt_async), XT_OBJECT_KIND_ASYNC);
|
|
82
|
+
async->function = function;
|
|
83
|
+
async->this_value = thisValue;
|
|
84
|
+
async->argc = argc;
|
|
85
|
+
async->args = NULL;
|
|
86
|
+
if (argc > 0 && argv) {
|
|
87
|
+
async->args = (xt_value *)malloc(sizeof(xt_value) * (size_t)argc);
|
|
88
|
+
if (!async->args) abort();
|
|
89
|
+
memcpy(async->args, argv, sizeof(xt_value) * (size_t)argc);
|
|
90
|
+
}
|
|
91
|
+
async->promise = xt_promise_create();
|
|
92
|
+
async->value = XT_UNDEFINED;
|
|
93
|
+
async->resume_value = XT_UNDEFINED;
|
|
94
|
+
async->await_threw = 0;
|
|
95
|
+
async->done = 0;
|
|
96
|
+
async->threw = 0;
|
|
97
|
+
async->coroutine = xt_coroutine_create(xt_async_run, async);
|
|
98
|
+
xt_async_gc_register();
|
|
99
|
+
/* Start synchronously, matching JavaScript: the body runs up to its first
|
|
100
|
+
* pending `await` before the call returns. */
|
|
101
|
+
xt_async_resume(async);
|
|
102
|
+
return async->promise;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
void xt_async_wake(void *asyncPointer, xt_value value, int rejected) {
|
|
106
|
+
if (!asyncPointer) return;
|
|
107
|
+
/* Async generators park the same kind of waiter, but their completion sends
|
|
108
|
+
* a promise to the current `.next()` request instead of settling a single
|
|
109
|
+
* `async` promise. */
|
|
110
|
+
if (((xt_header *)asyncPointer)->kind == XT_OBJECT_KIND_GENERATOR) {
|
|
111
|
+
xt_generator_wake(asyncPointer, value, rejected);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
xt_async *async = (xt_async *)asyncPointer;
|
|
115
|
+
if (async->done || !async->coroutine) return;
|
|
116
|
+
async->resume_value = value;
|
|
117
|
+
async->await_threw = rejected;
|
|
118
|
+
xt_async_resume(async);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/* `await value`: every await yields once. A settled promise (or a plain value)
|
|
122
|
+
* queues a microtask before resuming, so an await always interleaves with
|
|
123
|
+
* pending `.then` callbacks exactly like the specification. */
|
|
124
|
+
xt_value xt_await(xt_value value) {
|
|
125
|
+
/* An `await` inside an async generator suspends that generator's coroutine
|
|
126
|
+
* while leaving the current `.next()` promise pending. */
|
|
127
|
+
xt_value generatorResult;
|
|
128
|
+
if (xt_generator_await(value, &generatorResult)) return generatorResult;
|
|
129
|
+
|
|
130
|
+
int state = xt_promise_state_of(value);
|
|
131
|
+
xt_async *async = g_active_async;
|
|
132
|
+
if (async && async->coroutine && xt_coroutine_is_current(async->coroutine)) {
|
|
133
|
+
if (state == XT_PROMISE_PENDING) {
|
|
134
|
+
async->await_threw = 0;
|
|
135
|
+
async->resume_value = XT_UNDEFINED;
|
|
136
|
+
xt_promise_add_async_waiter(value, async);
|
|
137
|
+
xt_coroutine_leave(async->coroutine);
|
|
138
|
+
} else {
|
|
139
|
+
int rejected = state == XT_PROMISE_REJECTED;
|
|
140
|
+
xt_value settled = (state == XT_PROMISE_FULFILLED || rejected)
|
|
141
|
+
? xt_promise_value_of(value)
|
|
142
|
+
: value;
|
|
143
|
+
async->await_threw = rejected;
|
|
144
|
+
async->resume_value = settled;
|
|
145
|
+
xt_promise_queue_async_wake(async, settled, rejected);
|
|
146
|
+
xt_coroutine_leave(async->coroutine);
|
|
147
|
+
}
|
|
148
|
+
/* The waiter/queued microtask resumed us. A rejection is rethrown inside
|
|
149
|
+
* the coroutine so its own `try`/`catch` and `finally` see it. */
|
|
150
|
+
if (async->await_threw) {
|
|
151
|
+
async->await_threw = 0;
|
|
152
|
+
xt_throw(async->resume_value);
|
|
153
|
+
return XT_UNDEFINED;
|
|
154
|
+
}
|
|
155
|
+
return async->resume_value;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (state < 0) return value;
|
|
159
|
+
if (state == XT_PROMISE_REJECTED) {
|
|
160
|
+
xt_throw(xt_promise_value_of(value));
|
|
161
|
+
return XT_UNDEFINED;
|
|
162
|
+
}
|
|
163
|
+
if (state == XT_PROMISE_FULFILLED) return xt_promise_value_of(value);
|
|
164
|
+
|
|
165
|
+
/* No coroutine to suspend (top-level `await`, or `await` reached outside an
|
|
166
|
+
* async function): block on the reactor until the promise settles, exactly
|
|
167
|
+
* like a synchronous embedder waiting for the event loop. The loop returns
|
|
168
|
+
* immediately when no work remains, so a promise nothing can settle does not
|
|
169
|
+
* hang the process here. */
|
|
170
|
+
for (int guard = 0; guard < 100000; guard++) {
|
|
171
|
+
xt_drain_microtasks();
|
|
172
|
+
state = xt_promise_state_of(value);
|
|
173
|
+
if (state != XT_PROMISE_PENDING) break;
|
|
174
|
+
if (!xt_loop_has_work()) break;
|
|
175
|
+
if (xt_loop_poll(-1) < 0) break;
|
|
176
|
+
}
|
|
177
|
+
state = xt_promise_state_of(value);
|
|
178
|
+
if (state == XT_PROMISE_REJECTED) {
|
|
179
|
+
xt_throw(xt_promise_value_of(value));
|
|
180
|
+
return XT_UNDEFINED;
|
|
181
|
+
}
|
|
182
|
+
return state == XT_PROMISE_FULFILLED ? xt_promise_value_of(value) : XT_UNDEFINED;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/* While a coroutine runs, the async object is only reachable through this
|
|
186
|
+
* static pointer. */
|
|
187
|
+
static void xt_async_gc_scan_roots(void) {
|
|
188
|
+
if (!g_active_async) return;
|
|
189
|
+
xt_gc_mark_header((xt_header *)g_active_async);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
static void xt_async_gc_register(void) {
|
|
193
|
+
static int registered = 0;
|
|
194
|
+
if (registered) return;
|
|
195
|
+
registered = 1;
|
|
196
|
+
xt_gc_register_root_provider(xt_async_gc_scan_roots);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
void xt_async_gc_trace(xt_header *header) {
|
|
200
|
+
xt_async *async = (xt_async *)header;
|
|
201
|
+
xt_gc_mark_value(async->function);
|
|
202
|
+
xt_gc_mark_value(async->this_value);
|
|
203
|
+
xt_gc_mark_value(async->promise);
|
|
204
|
+
xt_gc_mark_value(async->value);
|
|
205
|
+
xt_gc_mark_value(async->resume_value);
|
|
206
|
+
if (async->args && async->argc > 0) {
|
|
207
|
+
xt_gc_scan_region(async->args, sizeof(xt_value) * (size_t)async->argc);
|
|
208
|
+
}
|
|
209
|
+
xt_coroutine_gc_trace(async->coroutine);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
void xt_async_gc_release(xt_header *header) {
|
|
213
|
+
xt_async *async = (xt_async *)header;
|
|
214
|
+
free(async->args);
|
|
215
|
+
xt_coroutine_release(async->coroutine);
|
|
216
|
+
async->coroutine = NULL;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
xt_value xt_function_set_async(xt_value value) {
|
|
220
|
+
if (XT_IS_FUNCTION(value)) ((xt_function *)XT_GET_PTR(value))->is_async = 1;
|
|
221
|
+
return value;
|
|
222
|
+
}
|
|
@@ -54,7 +54,7 @@ static void bi_throw_type(const char *message) {
|
|
|
54
54
|
size_t len = strlen(message);
|
|
55
55
|
char *buffer = (char *)malloc(len + 16);
|
|
56
56
|
snprintf(buffer, len + 16, "TypeError: %s", message);
|
|
57
|
-
xt_throw(
|
|
57
|
+
xt_throw(xt_error_from_message(buffer));
|
|
58
58
|
free(buffer);
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -62,7 +62,7 @@ static void bi_throw_range(const char *message) {
|
|
|
62
62
|
size_t len = strlen(message);
|
|
63
63
|
char *buffer = (char *)malloc(len + 16);
|
|
64
64
|
snprintf(buffer, len + 16, "RangeError: %s", message);
|
|
65
|
-
xt_throw(
|
|
65
|
+
xt_throw(xt_error_from_message(buffer));
|
|
66
66
|
free(buffer);
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -70,7 +70,7 @@ static void bi_throw_syntax(const char *message) {
|
|
|
70
70
|
size_t len = strlen(message);
|
|
71
71
|
char *buffer = (char *)malloc(len + 16);
|
|
72
72
|
snprintf(buffer, len + 16, "SyntaxError: %s", message);
|
|
73
|
-
xt_throw(
|
|
73
|
+
xt_throw(xt_error_from_message(buffer));
|
|
74
74
|
free(buffer);
|
|
75
75
|
}
|
|
76
76
|
|