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
|
@@ -2,15 +2,36 @@
|
|
|
2
2
|
/* Output and inspection */
|
|
3
3
|
/* ------------------------------------------------------------------------- */
|
|
4
4
|
|
|
5
|
+
/* Write UTF-8 bytes, turning a lone surrogate half (WTF-8) into U+FFFD. Node's
|
|
6
|
+
* terminal encoding does the same, so `console.log("😀"[0])` prints one
|
|
7
|
+
* replacement character instead of emitting invalid UTF-8. */
|
|
8
|
+
static void xt_print_utf8(FILE *out, const char *bytes, size_t length) {
|
|
9
|
+
size_t offset = 0;
|
|
10
|
+
while (offset < length) {
|
|
11
|
+
unsigned char c = (unsigned char)bytes[offset];
|
|
12
|
+
if (c == 0xED && offset + 2 < length) {
|
|
13
|
+
unsigned char second = (unsigned char)bytes[offset + 1];
|
|
14
|
+
unsigned char third = (unsigned char)bytes[offset + 2];
|
|
15
|
+
if (second >= 0xA0 && second <= 0xBF && third >= 0x80 && third <= 0xBF) {
|
|
16
|
+
fwrite("\xEF\xBF\xBD", 1, 3, out);
|
|
17
|
+
offset += 3;
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
fputc((int)c, out);
|
|
22
|
+
offset++;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
5
26
|
static void xt_print_value(xt_value v, FILE *out) {
|
|
6
27
|
if (XT_IS_STRING(v)) {
|
|
7
28
|
xt_string *s = xt_as_string(v);
|
|
8
|
-
|
|
29
|
+
xt_print_utf8(out, xt_string_bytes(s), s->length);
|
|
9
30
|
return;
|
|
10
31
|
}
|
|
11
32
|
xt_value text = xt_to_string(v);
|
|
12
33
|
xt_string *s = xt_as_string(text);
|
|
13
|
-
|
|
34
|
+
xt_print_utf8(out, xt_string_bytes(s), s->length);
|
|
14
35
|
}
|
|
15
36
|
|
|
16
37
|
void xt_print(xt_value v) { xt_print_value(v, stdout); }
|
|
@@ -83,6 +104,18 @@ static void xt_inspect_string(xt_string *s, FILE *out) {
|
|
|
83
104
|
default:
|
|
84
105
|
if (c == (unsigned char)quote) { fputc('\\', out); fputc(c, out); }
|
|
85
106
|
else if (c < 0x20) fprintf(out, "\\x%02x", c);
|
|
107
|
+
else if (c == 0xED && i + 2 < s->length) {
|
|
108
|
+
unsigned char second = (unsigned char)bytes[i + 1];
|
|
109
|
+
unsigned char third = (unsigned char)bytes[i + 2];
|
|
110
|
+
if (second >= 0xA0 && second <= 0xBF && third >= 0x80 && third <= 0xBF) {
|
|
111
|
+
unsigned code = ((unsigned)(c & 0x0F) << 12) | ((unsigned)(second & 0x3F) << 6) |
|
|
112
|
+
(unsigned)(third & 0x3F);
|
|
113
|
+
fprintf(out, "\\u%04x", code);
|
|
114
|
+
i += 2;
|
|
115
|
+
} else {
|
|
116
|
+
fputc(c, out);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
86
119
|
else fputc(c, out);
|
|
87
120
|
}
|
|
88
121
|
}
|
|
@@ -146,8 +179,120 @@ static void xt_inspect(xt_value v, FILE *out, int nested) {
|
|
|
146
179
|
xt_inspect_pop();
|
|
147
180
|
return;
|
|
148
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
|
+
}
|
|
149
195
|
if (XT_IS_OBJECT(v)) {
|
|
150
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
|
+
}
|
|
151
296
|
int seen = xt_inspect_seen(obj);
|
|
152
297
|
if (seen > 0) {
|
|
153
298
|
fprintf(out, "[Circular *%d]", seen);
|
package/runtime/xt_loop.c
CHANGED
|
@@ -88,8 +88,23 @@ static int64_t xt_loop_now_ms(void) {
|
|
|
88
88
|
#endif
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
/* Fractional monotonic milliseconds for `performance.now()`. Kept separate from
|
|
92
|
+
* xt_loop_now_ms(), which only needs whole milliseconds for timer deadlines. */
|
|
93
|
+
double xt_monotonic_ms(void) {
|
|
94
|
+
#if defined(_WIN32)
|
|
95
|
+
static LARGE_INTEGER frequency;
|
|
96
|
+
if (frequency.QuadPart == 0) QueryPerformanceFrequency(&frequency);
|
|
97
|
+
LARGE_INTEGER counter;
|
|
98
|
+
QueryPerformanceCounter(&counter);
|
|
99
|
+
return (double)counter.QuadPart * 1000.0 / (double)frequency.QuadPart;
|
|
100
|
+
#else
|
|
101
|
+
struct timespec ts;
|
|
102
|
+
clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
103
|
+
return (double)ts.tv_sec * 1000.0 + (double)ts.tv_nsec / 1000000.0;
|
|
104
|
+
#endif
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
static void xt_loop_sleep_ms(int ms) { if (ms <= 0) return;
|
|
93
108
|
#if defined(_WIN32)
|
|
94
109
|
Sleep((DWORD)ms);
|
|
95
110
|
#else
|
|
@@ -228,7 +243,7 @@ static void xt_timer_run_due(void) {
|
|
|
228
243
|
xt_value xt_set_timeout(int32_t argc, xt_value *argv) {
|
|
229
244
|
xt_value callback = xt_arg_at(argc, argv, 0);
|
|
230
245
|
if (!XT_IS_FUNCTION(callback)) {
|
|
231
|
-
xt_throw(
|
|
246
|
+
xt_throw(xt_error_from_message("TypeError: The \"callback\" argument must be of type function"));
|
|
232
247
|
return XT_UNDEFINED;
|
|
233
248
|
}
|
|
234
249
|
int64_t delay = xt_timer_delay_arg(xt_arg_at(argc, argv, 1));
|
|
@@ -240,7 +255,7 @@ xt_value xt_set_timeout(int32_t argc, xt_value *argv) {
|
|
|
240
255
|
xt_value xt_set_interval(int32_t argc, xt_value *argv) {
|
|
241
256
|
xt_value callback = xt_arg_at(argc, argv, 0);
|
|
242
257
|
if (!XT_IS_FUNCTION(callback)) {
|
|
243
|
-
xt_throw(
|
|
258
|
+
xt_throw(xt_error_from_message("TypeError: The \"callback\" argument must be of type function"));
|
|
244
259
|
return XT_UNDEFINED;
|
|
245
260
|
}
|
|
246
261
|
int64_t delay = xt_timer_delay_arg(xt_arg_at(argc, argv, 1));
|
|
@@ -263,6 +278,22 @@ xt_value xt_clear_interval(int32_t argc, xt_value *argv) {
|
|
|
263
278
|
return XT_UNDEFINED;
|
|
264
279
|
}
|
|
265
280
|
|
|
281
|
+
xt_value xt_set_immediate(int32_t argc, xt_value *argv) {
|
|
282
|
+
xt_value callback = xt_arg_at(argc, argv, 0);
|
|
283
|
+
if (!XT_IS_FUNCTION(callback)) {
|
|
284
|
+
xt_value message = xt_string_from_cstr("The \"callback\" argument must be of type function");
|
|
285
|
+
xt_throw(xt_type_error_ctor(1, &message));
|
|
286
|
+
return XT_UNDEFINED;
|
|
287
|
+
}
|
|
288
|
+
int32_t extra = argc > 1 ? argc - 1 : 0;
|
|
289
|
+
uint64_t id = xt_timer_add(callback, 0, 0, extra, extra > 0 ? argv + 1 : NULL);
|
|
290
|
+
return xt_number((double)id);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
xt_value xt_clear_immediate(int32_t argc, xt_value *argv) {
|
|
294
|
+
return xt_clear_timeout(argc, argv);
|
|
295
|
+
}
|
|
296
|
+
|
|
266
297
|
int xt_loop_add(int fd, int events, xt_io_handler handler, void *userdata) {
|
|
267
298
|
if (fd < 0 || !handler) return -1;
|
|
268
299
|
xt_loop_gc_register();
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* xbintsc runtime — `performance.now()`.
|
|
3
|
+
*
|
|
4
|
+
* The namespace is dispatched two ways: `performance.now()` lowers to
|
|
5
|
+
* xt_performance_call(name, argc, argv), while reading the method as a value
|
|
6
|
+
* (`const now = performance.now`) goes through xt_performance_get(name), which
|
|
7
|
+
* returns a closure with the standard ABI. Both read the same monotonic clock.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
#include "rt_internal.h"
|
|
11
|
+
|
|
12
|
+
#include <string.h>
|
|
13
|
+
|
|
14
|
+
static xt_value xt_performance_now_value(xt_value thisValue, xt_value env, int32_t argc,
|
|
15
|
+
xt_value *argv) {
|
|
16
|
+
(void)thisValue;
|
|
17
|
+
(void)env;
|
|
18
|
+
(void)argc;
|
|
19
|
+
(void)argv;
|
|
20
|
+
return xt_number(xt_monotonic_ms());
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
xt_value xt_performance_get(xt_value name) {
|
|
24
|
+
const char *key = xt_string_data(name);
|
|
25
|
+
if (key != NULL && strcmp(key, "now") == 0) {
|
|
26
|
+
return xt_closure_new((void *)xt_performance_now_value, 0, NULL);
|
|
27
|
+
}
|
|
28
|
+
return XT_UNDEFINED;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
xt_value xt_performance_call(xt_value name, int32_t argc, xt_value *argv) {
|
|
32
|
+
(void)argc;
|
|
33
|
+
(void)argv;
|
|
34
|
+
const char *key = xt_string_data(name);
|
|
35
|
+
if (key != NULL && strcmp(key, "now") == 0) return xt_number(xt_monotonic_ms());
|
|
36
|
+
return XT_UNDEFINED;
|
|
37
|
+
}
|
package/runtime/xt_promise.c
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* xbintsc runtime — promises and
|
|
2
|
+
* xbintsc runtime — promises and the microtask queue.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Promise reactions are queued as microtasks and run when the program body
|
|
5
|
+
* finishes, by the event loop between callbacks, and on demand. `await` lives
|
|
6
|
+
* in `xt_async.c`: an `async` function runs on a coroutine, so awaiting a
|
|
7
|
+
* promise that is still pending suspends it and registers a waiter here. When
|
|
8
|
+
* the promise settles, the waiter becomes a microtask that resumes the
|
|
9
|
+
* coroutine. Everything is single-threaded and non-blocking.
|
|
8
10
|
*/
|
|
9
11
|
|
|
10
12
|
#include "rt_internal.h"
|
|
@@ -12,10 +14,6 @@
|
|
|
12
14
|
#include <stdlib.h>
|
|
13
15
|
#include <string.h>
|
|
14
16
|
|
|
15
|
-
#define XT_PROMISE_PENDING 0
|
|
16
|
-
#define XT_PROMISE_FULFILLED 1
|
|
17
|
-
#define XT_PROMISE_REJECTED 2
|
|
18
|
-
|
|
19
17
|
typedef struct xt_promise xt_promise;
|
|
20
18
|
|
|
21
19
|
typedef struct {
|
|
@@ -23,6 +21,9 @@ typedef struct {
|
|
|
23
21
|
xt_value on_fulfilled;
|
|
24
22
|
xt_value on_rejected;
|
|
25
23
|
xt_promise *result;
|
|
24
|
+
/* Non-NULL for an `async` coroutine waiting on this promise. Such a reaction
|
|
25
|
+
* has no handlers: running it resumes the coroutine instead. */
|
|
26
|
+
void *async;
|
|
26
27
|
} xt_reaction;
|
|
27
28
|
|
|
28
29
|
struct xt_promise {
|
|
@@ -87,6 +88,7 @@ static void xt_promise_gc_scan_roots(void) {
|
|
|
87
88
|
xt_gc_mark_value(reaction->on_fulfilled);
|
|
88
89
|
xt_gc_mark_value(reaction->on_rejected);
|
|
89
90
|
xt_gc_mark_header((xt_header *)reaction->result);
|
|
91
|
+
if (reaction->async) xt_gc_mark_header((xt_header *)reaction->async);
|
|
90
92
|
}
|
|
91
93
|
}
|
|
92
94
|
|
|
@@ -107,6 +109,7 @@ void xt_promise_gc_trace(xt_header *header) {
|
|
|
107
109
|
xt_gc_mark_value(reaction->on_fulfilled);
|
|
108
110
|
xt_gc_mark_value(reaction->on_rejected);
|
|
109
111
|
xt_gc_mark_header((xt_header *)reaction->result);
|
|
112
|
+
if (reaction->async) xt_gc_mark_header((xt_header *)reaction->async);
|
|
110
113
|
}
|
|
111
114
|
}
|
|
112
115
|
|
|
@@ -133,6 +136,7 @@ static void xt_promise_resolve_into(xt_promise *result, xt_value value) {
|
|
|
133
136
|
reaction->on_fulfilled = XT_UNDEFINED;
|
|
134
137
|
reaction->on_rejected = XT_UNDEFINED;
|
|
135
138
|
reaction->result = result;
|
|
139
|
+
reaction->async = NULL;
|
|
136
140
|
if (other->reaction_count >= other->reaction_capacity) {
|
|
137
141
|
other->reaction_capacity = other->reaction_capacity == 0 ? 4 : other->reaction_capacity * 2;
|
|
138
142
|
other->reactions = (xt_reaction **)realloc(other->reactions, sizeof(xt_reaction *) * other->reaction_capacity);
|
|
@@ -156,6 +160,16 @@ static xt_value xt_promise_run_reactions(void) {
|
|
|
156
160
|
while (xt_microtask_head < xt_microtask_count) {
|
|
157
161
|
xt_reaction *reaction = xt_microtasks[xt_microtask_head++];
|
|
158
162
|
xt_promise *promise = reaction->promise;
|
|
163
|
+
if (reaction->async) {
|
|
164
|
+
/* A suspended `async` coroutine: resume it with the settled value. It
|
|
165
|
+
* runs until it completes or awaits another pending promise. */
|
|
166
|
+
void *async = reaction->async;
|
|
167
|
+
int rejected = promise->state == XT_PROMISE_REJECTED;
|
|
168
|
+
xt_value settled = promise->value;
|
|
169
|
+
free(reaction);
|
|
170
|
+
xt_async_wake(async, settled, rejected);
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
159
173
|
xt_value handler = promise->state == XT_PROMISE_FULFILLED ? reaction->on_fulfilled : reaction->on_rejected;
|
|
160
174
|
if (XT_IS_FUNCTION(handler)) {
|
|
161
175
|
xt_value arg = promise->value;
|
|
@@ -181,16 +195,63 @@ void xt_drain_microtasks(void) {
|
|
|
181
195
|
}
|
|
182
196
|
}
|
|
183
197
|
|
|
184
|
-
|
|
198
|
+
/* -- helpers used by the async coroutine runtime -------------------------- */
|
|
199
|
+
|
|
200
|
+
xt_value xt_promise_create(void) { return xt_promise_value(xt_promise_new()); }
|
|
201
|
+
|
|
202
|
+
/* Queue a microtask that resumes a suspended async coroutine with an already
|
|
203
|
+
* settled value. Reusing a reaction keeps FIFO order with pending `.then`
|
|
204
|
+
* callbacks (the specification always yields once per `await`). */
|
|
205
|
+
void xt_promise_queue_async_wake(void *asyncPointer, xt_value settled, int rejected) {
|
|
206
|
+
xt_promise *promise = xt_promise_new();
|
|
207
|
+
promise->state = rejected ? XT_PROMISE_REJECTED : XT_PROMISE_FULFILLED;
|
|
208
|
+
promise->value = settled;
|
|
209
|
+
xt_reaction *reaction = (xt_reaction *)malloc(sizeof(xt_reaction));
|
|
210
|
+
if (!reaction) abort();
|
|
211
|
+
reaction->promise = promise;
|
|
212
|
+
reaction->on_fulfilled = XT_UNDEFINED;
|
|
213
|
+
reaction->on_rejected = XT_UNDEFINED;
|
|
214
|
+
reaction->result = NULL;
|
|
215
|
+
reaction->async = asyncPointer;
|
|
216
|
+
xt_microtask_push(reaction);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
void xt_promise_fulfill(xt_value promise, xt_value value) {
|
|
220
|
+
xt_promise *target = xt_as_promise(promise);
|
|
221
|
+
if (target) xt_promise_resolve_into(target, value);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
void xt_promise_reject_value(xt_value promise, xt_value value) {
|
|
225
|
+
xt_promise *target = xt_as_promise(promise);
|
|
226
|
+
if (target) xt_promise_settle(target, XT_PROMISE_REJECTED, value);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
int xt_promise_state_of(xt_value value) {
|
|
185
230
|
xt_promise *promise = xt_as_promise(value);
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
231
|
+
return promise ? promise->state : -1;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
xt_value xt_promise_value_of(xt_value value) {
|
|
235
|
+
xt_promise *promise = xt_as_promise(value);
|
|
236
|
+
return promise ? promise->value : value;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
void xt_promise_add_async_waiter(xt_value promiseValue, void *async) {
|
|
240
|
+
xt_promise *promise = xt_as_promise(promiseValue);
|
|
241
|
+
if (!promise || promise->state != XT_PROMISE_PENDING) return;
|
|
242
|
+
xt_reaction *reaction = (xt_reaction *)malloc(sizeof(xt_reaction));
|
|
243
|
+
if (!reaction) abort();
|
|
244
|
+
reaction->promise = promise;
|
|
245
|
+
reaction->on_fulfilled = XT_UNDEFINED;
|
|
246
|
+
reaction->on_rejected = XT_UNDEFINED;
|
|
247
|
+
reaction->result = NULL;
|
|
248
|
+
reaction->async = async;
|
|
249
|
+
if (promise->reaction_count >= promise->reaction_capacity) {
|
|
250
|
+
promise->reaction_capacity = promise->reaction_capacity == 0 ? 4 : promise->reaction_capacity * 2;
|
|
251
|
+
promise->reactions = (xt_reaction **)realloc(promise->reactions, sizeof(xt_reaction *) * promise->reaction_capacity);
|
|
252
|
+
if (!promise->reactions) abort();
|
|
192
253
|
}
|
|
193
|
-
|
|
254
|
+
promise->reactions[promise->reaction_count++] = reaction;
|
|
194
255
|
}
|
|
195
256
|
|
|
196
257
|
/* -- C-callable resolve / reject ------------------------------------------ */
|
|
@@ -243,9 +304,34 @@ xt_value xt_promise_reject(xt_value value) {
|
|
|
243
304
|
return xt_promise_value(promise);
|
|
244
305
|
}
|
|
245
306
|
|
|
307
|
+
static xt_value xt_promise_with_resolvers_resolve(xt_value thisValue, xt_value env, int32_t argc,
|
|
308
|
+
xt_value *argv) {
|
|
309
|
+
(void)thisValue;
|
|
310
|
+
xt_promise_fulfill(xt_closure_env(env, 0), xt_arg_at(argc, argv, 0));
|
|
311
|
+
return XT_UNDEFINED;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
static xt_value xt_promise_with_resolvers_reject(xt_value thisValue, xt_value env, int32_t argc,
|
|
315
|
+
xt_value *argv) {
|
|
316
|
+
(void)thisValue;
|
|
317
|
+
xt_promise_reject_value(xt_closure_env(env, 0), xt_arg_at(argc, argv, 0));
|
|
318
|
+
return XT_UNDEFINED;
|
|
319
|
+
}
|
|
320
|
+
|
|
246
321
|
xt_value xt_promise_static(xt_value name, int32_t argc, xt_value *argv) {
|
|
247
322
|
const char *fn = xt_string_data(name);
|
|
248
323
|
if (!fn) return XT_UNDEFINED;
|
|
324
|
+
if (strcmp(fn, "withResolvers") == 0) {
|
|
325
|
+
xt_value promise = xt_promise_create();
|
|
326
|
+
xt_value environment[1] = {promise};
|
|
327
|
+
xt_value result = xt_object_new();
|
|
328
|
+
xt_object_set(result, xt_string_from_cstr("promise"), promise);
|
|
329
|
+
xt_object_set(result, xt_string_from_cstr("resolve"),
|
|
330
|
+
xt_closure_new((void *)xt_promise_with_resolvers_resolve, 1, environment));
|
|
331
|
+
xt_object_set(result, xt_string_from_cstr("reject"),
|
|
332
|
+
xt_closure_new((void *)xt_promise_with_resolvers_reject, 1, environment));
|
|
333
|
+
return result;
|
|
334
|
+
}
|
|
249
335
|
if (strcmp(fn, "resolve") == 0) return xt_promise_resolve(xt_arg_at(argc, argv, 0));
|
|
250
336
|
if (strcmp(fn, "reject") == 0) return xt_promise_reject(xt_arg_at(argc, argv, 0));
|
|
251
337
|
if (strcmp(fn, "all") == 0 || strcmp(fn, "allSettled") == 0 || strcmp(fn, "race") == 0 || strcmp(fn, "any") == 0) {
|
|
@@ -277,7 +363,12 @@ xt_value xt_promise_static(xt_value name, int32_t argc, xt_value *argv) {
|
|
|
277
363
|
xt_promise_settle(result, XT_PROMISE_REJECTED, inner->value);
|
|
278
364
|
return xt_promise_value(result);
|
|
279
365
|
}
|
|
280
|
-
xt_value settled
|
|
366
|
+
xt_value settled;
|
|
367
|
+
if (xt_promise_state_of(item) == XT_PROMISE_FULFILLED) {
|
|
368
|
+
settled = xt_promise_value_of(item);
|
|
369
|
+
} else {
|
|
370
|
+
settled = xt_await(item);
|
|
371
|
+
}
|
|
281
372
|
if (strcmp(fn, "any") == 0 || strcmp(fn, "race") == 0) {
|
|
282
373
|
xt_promise_settle(result, XT_PROMISE_FULFILLED, settled);
|
|
283
374
|
return xt_promise_value(result);
|
|
@@ -316,6 +407,7 @@ xt_value xt_promise_method(xt_value target, const char *method, int32_t argc, xt
|
|
|
316
407
|
reaction->on_fulfilled = xt_arg_at(argc, argv, 0);
|
|
317
408
|
reaction->on_rejected = xt_arg_at(argc, argv, 1);
|
|
318
409
|
reaction->result = result;
|
|
410
|
+
reaction->async = NULL;
|
|
319
411
|
if (promise->state == XT_PROMISE_PENDING) {
|
|
320
412
|
if (promise->reaction_count >= promise->reaction_capacity) {
|
|
321
413
|
promise->reaction_capacity = promise->reaction_capacity == 0 ? 4 : promise->reaction_capacity * 2;
|
|
@@ -341,3 +433,18 @@ xt_value xt_promise_method(xt_value target, const char *method, int32_t argc, xt
|
|
|
341
433
|
*handled = 0;
|
|
342
434
|
return XT_UNDEFINED;
|
|
343
435
|
}
|
|
436
|
+
|
|
437
|
+
xt_value xt_queue_microtask(int32_t argc, xt_value *argv) {
|
|
438
|
+
xt_value callback = xt_arg_at(argc, argv, 0);
|
|
439
|
+
if (!XT_IS_FUNCTION(callback)) {
|
|
440
|
+
xt_value message = xt_string_from_cstr("The \"callback\" argument must be of type function");
|
|
441
|
+
xt_throw(xt_type_error_ctor(1, &message));
|
|
442
|
+
return XT_UNDEFINED;
|
|
443
|
+
}
|
|
444
|
+
/* Reuse the promise reaction queue: a settled promise's `then` callback is
|
|
445
|
+
* exactly a microtask, and it keeps FIFO order with pending `.then`s. */
|
|
446
|
+
xt_value promise = xt_promise_resolve(XT_UNDEFINED);
|
|
447
|
+
int handled = 0;
|
|
448
|
+
xt_promise_method(promise, "then", 1, &callback, &handled);
|
|
449
|
+
return XT_UNDEFINED;
|
|
450
|
+
}
|
|
@@ -150,7 +150,7 @@ static xt_value xt_array_reduce(xt_value value, xt_value fn, int32_t hasInitial,
|
|
|
150
150
|
accumulator = array->items[0];
|
|
151
151
|
i = 1;
|
|
152
152
|
} else {
|
|
153
|
-
xt_throw(
|
|
153
|
+
xt_throw(xt_error_from_message("TypeError: Reduce of empty array with no initial value"));
|
|
154
154
|
return XT_UNDEFINED;
|
|
155
155
|
}
|
|
156
156
|
for (; i < array->length; i++) {
|