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,340 @@
|
|
|
1
|
+
/* ------------------------------------------------------------------------- */
|
|
2
|
+
/* UTF-8 storage, UTF-16 view */
|
|
3
|
+
/* ------------------------------------------------------------------------- */
|
|
4
|
+
/*
|
|
5
|
+
* Strings are stored as UTF-8, but JavaScript observes them as sequences of
|
|
6
|
+
* UTF-16 code units. The helpers here bridge the two views:
|
|
7
|
+
*
|
|
8
|
+
* - a decoded code point above 0xFFFF occupies two UTF-16 units;
|
|
9
|
+
* - a surrogate half that is not part of a pair (produced by indexing or
|
|
10
|
+
* slicing through a pair) is stored as its own three-byte WTF-8 sequence;
|
|
11
|
+
* - `xt_utf8_normalize_surrogates` recombines adjacent WTF-8 halves so that
|
|
12
|
+
* concatenation and flattening keep the canonical four-byte form.
|
|
13
|
+
*
|
|
14
|
+
* Invalid UTF-8 bytes decode as U+FFFD with width 1, so a C extension that
|
|
15
|
+
* hands over arbitrary bytes can never make the walkers run off the end.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
uint32_t xt_utf8_decode(const char *data, size_t length, size_t *width) {
|
|
19
|
+
const unsigned char *bytes = (const unsigned char *)data;
|
|
20
|
+
if (length == 0) {
|
|
21
|
+
if (width) *width = 0;
|
|
22
|
+
return 0xFFFD;
|
|
23
|
+
}
|
|
24
|
+
unsigned char first = bytes[0];
|
|
25
|
+
if (first < 0x80) {
|
|
26
|
+
if (width) *width = 1;
|
|
27
|
+
return first;
|
|
28
|
+
}
|
|
29
|
+
if ((first & 0xE0) == 0xC0 && length >= 2 && (bytes[1] & 0xC0) == 0x80) {
|
|
30
|
+
if (width) *width = 2;
|
|
31
|
+
return ((uint32_t)(first & 0x1F) << 6) | (uint32_t)(bytes[1] & 0x3F);
|
|
32
|
+
}
|
|
33
|
+
if ((first & 0xF0) == 0xE0 && length >= 3 && (bytes[1] & 0xC0) == 0x80 &&
|
|
34
|
+
(bytes[2] & 0xC0) == 0x80) {
|
|
35
|
+
if (width) *width = 3;
|
|
36
|
+
return ((uint32_t)(first & 0x0F) << 12) | ((uint32_t)(bytes[1] & 0x3F) << 6) |
|
|
37
|
+
(uint32_t)(bytes[2] & 0x3F);
|
|
38
|
+
}
|
|
39
|
+
if ((first & 0xF8) == 0xF0 && length >= 4 && (bytes[1] & 0xC0) == 0x80 &&
|
|
40
|
+
(bytes[2] & 0xC0) == 0x80 && (bytes[3] & 0xC0) == 0x80) {
|
|
41
|
+
uint32_t code = ((uint32_t)(first & 0x07) << 18) | ((uint32_t)(bytes[1] & 0x3F) << 12) |
|
|
42
|
+
((uint32_t)(bytes[2] & 0x3F) << 6) | (uint32_t)(bytes[3] & 0x3F);
|
|
43
|
+
if (code >= 0x10000 && code <= 0x10FFFF) {
|
|
44
|
+
if (width) *width = 4;
|
|
45
|
+
return code;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/* Invalid or overlong sequence: consume one byte, report the replacement. */
|
|
49
|
+
if (width) *width = 1;
|
|
50
|
+
return 0xFFFD;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
size_t xt_utf8_encode(uint32_t code, char *out) {
|
|
54
|
+
if (code < 0x80) {
|
|
55
|
+
out[0] = (char)code;
|
|
56
|
+
return 1;
|
|
57
|
+
}
|
|
58
|
+
if (code < 0x800) {
|
|
59
|
+
out[0] = (char)(0xC0 | (code >> 6));
|
|
60
|
+
out[1] = (char)(0x80 | (code & 0x3F));
|
|
61
|
+
return 2;
|
|
62
|
+
}
|
|
63
|
+
if (code < 0x10000) {
|
|
64
|
+
out[0] = (char)(0xE0 | (code >> 12));
|
|
65
|
+
out[1] = (char)(0x80 | ((code >> 6) & 0x3F));
|
|
66
|
+
out[2] = (char)(0x80 | (code & 0x3F));
|
|
67
|
+
return 3;
|
|
68
|
+
}
|
|
69
|
+
out[0] = (char)(0xF0 | ((code >> 18) & 0x07));
|
|
70
|
+
out[1] = (char)(0x80 | ((code >> 12) & 0x3F));
|
|
71
|
+
out[2] = (char)(0x80 | ((code >> 6) & 0x3F));
|
|
72
|
+
out[3] = (char)(0x80 | (code & 0x3F));
|
|
73
|
+
return 4;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
void xt_utf8_measure(const char *data, size_t length, uint32_t *units, uint32_t *points) {
|
|
77
|
+
size_t offset = 0;
|
|
78
|
+
uint32_t unitCount = 0;
|
|
79
|
+
uint32_t pointCount = 0;
|
|
80
|
+
while (offset < length) {
|
|
81
|
+
size_t width = 0;
|
|
82
|
+
uint32_t code = xt_utf8_decode(data + offset, length - offset, &width);
|
|
83
|
+
if (width == 0) break;
|
|
84
|
+
unitCount += code >= 0x10000 ? 2 : 1;
|
|
85
|
+
pointCount++;
|
|
86
|
+
offset += width;
|
|
87
|
+
}
|
|
88
|
+
if (units) *units = unitCount;
|
|
89
|
+
if (points) *points = pointCount;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
uint32_t xt_utf8_utf16_length(const char *data, size_t length) {
|
|
93
|
+
uint32_t units = 0;
|
|
94
|
+
xt_utf8_measure(data, length, &units, NULL);
|
|
95
|
+
return units;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* Both halves of a surrogate pair are encoded as three-byte WTF-8 sequences:
|
|
99
|
+
* `ED A0..AF xx` for D800-DBFF and `ED B0..BF xx` for DC00-DFFF. */
|
|
100
|
+
static int xt_wtf8_surrogate(const unsigned char *bytes, size_t length, uint32_t *code, int *high) {
|
|
101
|
+
if (length < 3 || bytes[0] != 0xED || bytes[1] < 0xA0 || bytes[1] > 0xBF ||
|
|
102
|
+
bytes[2] < 0x80 || bytes[2] > 0xBF)
|
|
103
|
+
return 0;
|
|
104
|
+
*code = ((uint32_t)(bytes[0] & 0x0F) << 12) | ((uint32_t)(bytes[1] & 0x3F) << 6) |
|
|
105
|
+
(uint32_t)(bytes[2] & 0x3F);
|
|
106
|
+
*high = bytes[1] <= 0xAF;
|
|
107
|
+
return 1;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
size_t xt_utf8_normalize_surrogates(char *data, size_t length) {
|
|
111
|
+
const unsigned char *source = (const unsigned char *)data;
|
|
112
|
+
unsigned char *write = (unsigned char *)data;
|
|
113
|
+
size_t offset = 0;
|
|
114
|
+
while (offset < length) {
|
|
115
|
+
uint32_t highCode = 0;
|
|
116
|
+
int high = 0;
|
|
117
|
+
if (xt_wtf8_surrogate(source + offset, length - offset, &highCode, &high) && high) {
|
|
118
|
+
uint32_t lowCode = 0;
|
|
119
|
+
int low = 0;
|
|
120
|
+
if (offset + 3 < length &&
|
|
121
|
+
xt_wtf8_surrogate(source + offset + 3, length - offset - 3, &lowCode, &low) && !low) {
|
|
122
|
+
uint32_t code = 0x10000 + ((highCode - 0xD800) << 10) + (lowCode - 0xDC00);
|
|
123
|
+
write += xt_utf8_encode(code, (char *)write);
|
|
124
|
+
offset += 6;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
*write++ = source[offset++];
|
|
129
|
+
}
|
|
130
|
+
return (size_t)(write - (unsigned char *)data);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
void xt_string_finish(xt_string *s) {
|
|
134
|
+
if (!s || !s->flat) return;
|
|
135
|
+
size_t length = xt_utf8_normalize_surrogates(s->flat, s->length);
|
|
136
|
+
s->length = (uint32_t)length;
|
|
137
|
+
s->flat[length] = '\0';
|
|
138
|
+
xt_utf8_measure(s->flat, length, &s->utf16_length, &s->code_point_count);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
uint32_t xt_string_utf16_length(xt_string *s) {
|
|
142
|
+
if (!s || s->length == 0) return 0;
|
|
143
|
+
if (s->utf16_length) return s->utf16_length;
|
|
144
|
+
if (!s->flat) xt_string_bytes(s);
|
|
145
|
+
else xt_utf8_measure(s->flat, s->length, &s->utf16_length, &s->code_point_count);
|
|
146
|
+
return s->utf16_length;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
uint32_t xt_string_code_point_count(xt_string *s) {
|
|
150
|
+
if (!s || s->length == 0) return 0;
|
|
151
|
+
if (s->code_point_count) return s->code_point_count;
|
|
152
|
+
if (!s->flat) xt_string_bytes(s);
|
|
153
|
+
else xt_utf8_measure(s->flat, s->length, &s->utf16_length, &s->code_point_count);
|
|
154
|
+
return s->code_point_count;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* A string whose byte and UTF-16 lengths agree contains only ASCII, so the two
|
|
158
|
+
* index spaces coincide and every walker below can skip decoding. */
|
|
159
|
+
static int xt_string_is_ascii(xt_string *s) {
|
|
160
|
+
return s->length == xt_string_utf16_length(s);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
int32_t xt_string_code_unit(xt_string *s, int32_t index) {
|
|
164
|
+
if (!s || index < 0 || (uint32_t)index >= s->length) return -1;
|
|
165
|
+
if (xt_string_is_ascii(s)) return (int32_t)(unsigned char)xt_string_bytes(s)[index];
|
|
166
|
+
const char *bytes = xt_string_bytes(s);
|
|
167
|
+
size_t offset = 0;
|
|
168
|
+
int32_t unit = 0;
|
|
169
|
+
while (offset < s->length) {
|
|
170
|
+
size_t width = 0;
|
|
171
|
+
uint32_t code = xt_utf8_decode(bytes + offset, s->length - offset, &width);
|
|
172
|
+
if (code >= 0x10000) {
|
|
173
|
+
uint32_t value = code - 0x10000;
|
|
174
|
+
if (unit == index) return (int32_t)(0xD800 + (value >> 10));
|
|
175
|
+
if (unit + 1 == index) return (int32_t)(0xDC00 + (value & 0x3FF));
|
|
176
|
+
unit += 2;
|
|
177
|
+
} else {
|
|
178
|
+
if (unit == index) return (int32_t)code;
|
|
179
|
+
unit += 1;
|
|
180
|
+
}
|
|
181
|
+
offset += width;
|
|
182
|
+
}
|
|
183
|
+
return -1;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
int32_t xt_string_code_point_at(xt_string *s, int32_t index) {
|
|
187
|
+
if (!s || index < 0) return -1;
|
|
188
|
+
if (xt_string_is_ascii(s)) return index < (int32_t)s->length ? (int32_t)(unsigned char)xt_string_bytes(s)[index] : -1;
|
|
189
|
+
const char *bytes = xt_string_bytes(s);
|
|
190
|
+
size_t offset = 0;
|
|
191
|
+
int32_t unit = 0;
|
|
192
|
+
while (offset < s->length) {
|
|
193
|
+
size_t width = 0;
|
|
194
|
+
uint32_t code = xt_utf8_decode(bytes + offset, s->length - offset, &width);
|
|
195
|
+
int widthUnits = code >= 0x10000 ? 2 : 1;
|
|
196
|
+
if (unit == index) return (int32_t)code;
|
|
197
|
+
if (widthUnits == 2 && unit + 1 == index)
|
|
198
|
+
return (int32_t)(0xDC00 + ((code - 0x10000) & 0x3FF));
|
|
199
|
+
unit += widthUnits;
|
|
200
|
+
offset += width;
|
|
201
|
+
}
|
|
202
|
+
return -1;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
xt_value xt_string_from_code_point(uint32_t code) {
|
|
206
|
+
char buffer[4];
|
|
207
|
+
size_t length = xt_utf8_encode(code, buffer);
|
|
208
|
+
return xt_string_new(buffer, length);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
xt_value xt_string_from_units(const uint16_t *units, size_t count) {
|
|
212
|
+
size_t capacity = count * 4 + 1;
|
|
213
|
+
char *out = (char *)malloc(capacity);
|
|
214
|
+
if (!out) abort();
|
|
215
|
+
size_t length = 0;
|
|
216
|
+
for (size_t i = 0; i < count; i++) {
|
|
217
|
+
uint32_t code = units[i];
|
|
218
|
+
if (code >= 0xD800 && code <= 0xDBFF && i + 1 < count && units[i + 1] >= 0xDC00 &&
|
|
219
|
+
units[i + 1] <= 0xDFFF) {
|
|
220
|
+
code = 0x10000 + ((code - 0xD800) << 10) + ((uint32_t)units[i + 1] - 0xDC00);
|
|
221
|
+
i++;
|
|
222
|
+
}
|
|
223
|
+
length += xt_utf8_encode(code, out + length);
|
|
224
|
+
}
|
|
225
|
+
xt_value result = xt_string_new(out, length);
|
|
226
|
+
free(out);
|
|
227
|
+
return result;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
xt_value xt_string_unit_value(xt_string *s, int32_t index) {
|
|
231
|
+
int32_t unit = xt_string_code_unit(s, index);
|
|
232
|
+
if (unit < 0) return xt_string_from_cstr("");
|
|
233
|
+
return xt_string_from_code_point((uint32_t)unit);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
xt_value xt_string_code_point_value(xt_string *s, int32_t index) {
|
|
237
|
+
if (!s || index < 0) return XT_UNDEFINED;
|
|
238
|
+
if (xt_string_is_ascii(s))
|
|
239
|
+
return index < (int32_t)s->length
|
|
240
|
+
? xt_string_from_code_point((uint32_t)(unsigned char)xt_string_bytes(s)[index])
|
|
241
|
+
: XT_UNDEFINED;
|
|
242
|
+
const char *bytes = xt_string_bytes(s);
|
|
243
|
+
size_t offset = 0;
|
|
244
|
+
int32_t point = 0;
|
|
245
|
+
while (offset < s->length) {
|
|
246
|
+
size_t width = 0;
|
|
247
|
+
uint32_t code = xt_utf8_decode(bytes + offset, s->length - offset, &width);
|
|
248
|
+
if (point == index) return xt_string_from_code_point(code);
|
|
249
|
+
point++;
|
|
250
|
+
offset += width;
|
|
251
|
+
}
|
|
252
|
+
return XT_UNDEFINED;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
xt_value xt_string_slice_units(xt_string *s, int32_t start, int32_t end) {
|
|
256
|
+
if (!s) return xt_string_from_cstr("");
|
|
257
|
+
int32_t units = (int32_t)xt_string_utf16_length(s);
|
|
258
|
+
if (start < 0) start = 0;
|
|
259
|
+
if (start > units) start = units;
|
|
260
|
+
if (end < 0) end = 0;
|
|
261
|
+
if (end > units) end = units;
|
|
262
|
+
if (start >= end) return xt_string_from_cstr("");
|
|
263
|
+
if (xt_string_is_ascii(s)) {
|
|
264
|
+
const char *ascii = xt_string_bytes(s);
|
|
265
|
+
return xt_string_new(ascii + start, (size_t)(end - start));
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const char *bytes = xt_string_bytes(s);
|
|
269
|
+
/* Splitting a surrogate pair expands four bytes into two three-byte WTF-8
|
|
270
|
+
* halves, so leave two bytes of headroom. */
|
|
271
|
+
char *out = (char *)malloc((size_t)s->length + 8);
|
|
272
|
+
if (!out) abort();
|
|
273
|
+
size_t length = 0;
|
|
274
|
+
size_t offset = 0;
|
|
275
|
+
int32_t unit = 0;
|
|
276
|
+
while (offset < s->length) {
|
|
277
|
+
size_t width = 0;
|
|
278
|
+
uint32_t code = xt_utf8_decode(bytes + offset, s->length - offset, &width);
|
|
279
|
+
if (code >= 0x10000) {
|
|
280
|
+
uint32_t value = code - 0x10000;
|
|
281
|
+
if (start <= unit && end >= unit + 2) {
|
|
282
|
+
length += xt_utf8_encode(code, out + length);
|
|
283
|
+
} else if (start <= unit && end == unit + 1) {
|
|
284
|
+
length += xt_utf8_encode(0xD800 + (value >> 10), out + length);
|
|
285
|
+
} else if (start == unit + 1 && end >= unit + 2) {
|
|
286
|
+
length += xt_utf8_encode(0xDC00 + (value & 0x3FF), out + length);
|
|
287
|
+
}
|
|
288
|
+
unit += 2;
|
|
289
|
+
} else {
|
|
290
|
+
if (unit >= start && unit < end) length += xt_utf8_encode(code, out + length);
|
|
291
|
+
unit += 1;
|
|
292
|
+
}
|
|
293
|
+
offset += width;
|
|
294
|
+
}
|
|
295
|
+
xt_value result = xt_string_new(out, length);
|
|
296
|
+
free(out);
|
|
297
|
+
return result;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
int32_t xt_string_byte_offset(xt_string *s, int32_t unit_index) {
|
|
301
|
+
if (!s || unit_index <= 0) return 0;
|
|
302
|
+
if (xt_string_is_ascii(s)) return unit_index < (int32_t)s->length ? unit_index : (int32_t)s->length;
|
|
303
|
+
const char *bytes = xt_string_bytes(s);
|
|
304
|
+
size_t offset = 0;
|
|
305
|
+
int32_t unit = 0;
|
|
306
|
+
while (offset < s->length) {
|
|
307
|
+
if (unit >= unit_index) return (int32_t)offset;
|
|
308
|
+
size_t width = 0;
|
|
309
|
+
uint32_t code = xt_utf8_decode(bytes + offset, s->length - offset, &width);
|
|
310
|
+
int widthUnits = code >= 0x10000 ? 2 : 1;
|
|
311
|
+
if (widthUnits == 2 && unit + 1 == unit_index) return (int32_t)offset;
|
|
312
|
+
unit += widthUnits;
|
|
313
|
+
offset += width;
|
|
314
|
+
}
|
|
315
|
+
return (int32_t)s->length;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
int32_t xt_string_unit_offset(xt_string *s, int32_t byte_offset) {
|
|
319
|
+
if (!s || byte_offset <= 0) return 0;
|
|
320
|
+
if ((uint32_t)byte_offset >= s->length) return (int32_t)xt_string_utf16_length(s);
|
|
321
|
+
if (xt_string_is_ascii(s)) return byte_offset;
|
|
322
|
+
const char *bytes = xt_string_bytes(s);
|
|
323
|
+
size_t offset = 0;
|
|
324
|
+
int32_t unit = 0;
|
|
325
|
+
while (offset < (size_t)byte_offset && offset < s->length) {
|
|
326
|
+
size_t width = 0;
|
|
327
|
+
uint32_t code = xt_utf8_decode(bytes + offset, s->length - offset, &width);
|
|
328
|
+
unit += code >= 0x10000 ? 2 : 1;
|
|
329
|
+
offset += width;
|
|
330
|
+
}
|
|
331
|
+
return unit;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
int xt_string_is_boundary(xt_string *s, int32_t unit_index) {
|
|
335
|
+
int32_t units = (int32_t)xt_string_utf16_length(s);
|
|
336
|
+
if (unit_index <= 0 || unit_index >= units) return 1;
|
|
337
|
+
if (xt_string_is_ascii(s)) return 1;
|
|
338
|
+
int32_t byte = xt_string_byte_offset(s, unit_index);
|
|
339
|
+
return xt_string_unit_offset(s, byte) == unit_index;
|
|
340
|
+
}
|
package/runtime/xt_values.c
CHANGED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* xbintsc runtime — weak collections.
|
|
3
|
+
*
|
|
4
|
+
* `WeakMap`, `WeakSet` and `WeakRef` are the only values whose references the
|
|
5
|
+
* mark-sweep collector must *not* follow unconditionally. Their keys (and the
|
|
6
|
+
* target of a WeakRef) are excluded from the ordinary trace; instead the
|
|
7
|
+
* collector runs an ephemeron fixed point after marking:
|
|
8
|
+
*
|
|
9
|
+
* repeat
|
|
10
|
+
* for every live WeakMap entry whose key is marked:
|
|
11
|
+
* mark the value
|
|
12
|
+
* until nothing new is marked
|
|
13
|
+
*
|
|
14
|
+
* A value is therefore retained only while its key is otherwise reachable, and
|
|
15
|
+
* a key/value cycle that is only reachable through the WeakMap is collected.
|
|
16
|
+
* WeakRef targets that stay unmarked after that fixed point are cleared.
|
|
17
|
+
*
|
|
18
|
+
* WeakMap/WeakSet entries are removed at sweep time, so a later `has()` never
|
|
19
|
+
* observes a key whose object has been collected.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
#include "rt_internal.h"
|
|
23
|
+
|
|
24
|
+
#include <stdlib.h>
|
|
25
|
+
#include <string.h>
|
|
26
|
+
|
|
27
|
+
static int xt_is_weak_target(xt_value value) {
|
|
28
|
+
return XT_IS_OBJECT(value) || XT_IS_ARRAY(value) || XT_IS_FUNCTION(value);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static void xt_weak_key_error(void) {
|
|
32
|
+
xt_throw(xt_error_from_message("TypeError: Invalid value used as weak map key"));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
int xt_is_weak_map(xt_value value) {
|
|
36
|
+
return XT_IS_OBJECT(value) &&
|
|
37
|
+
((xt_header *)XT_GET_PTR(value))->kind == XT_OBJECT_KIND_WEAK_MAP;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
int xt_is_weak_set(xt_value value) {
|
|
41
|
+
return XT_IS_OBJECT(value) &&
|
|
42
|
+
((xt_header *)XT_GET_PTR(value))->kind == XT_OBJECT_KIND_WEAK_SET;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
int xt_is_weak_ref(xt_value value) {
|
|
46
|
+
return XT_IS_OBJECT(value) &&
|
|
47
|
+
((xt_header *)XT_GET_PTR(value))->kind == XT_OBJECT_KIND_WEAK_REF;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* -- WeakMap -------------------------------------------------------------- */
|
|
51
|
+
|
|
52
|
+
static int32_t xt_weak_map_index(xt_weak_map *map, xt_value key) {
|
|
53
|
+
for (uint32_t i = 0; i < map->count; i++) {
|
|
54
|
+
if (xt_value_equals(map->keys[i], key)) return (int32_t)i;
|
|
55
|
+
}
|
|
56
|
+
return -1;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static void xt_weak_map_set(xt_weak_map *map, xt_value key, xt_value value) {
|
|
60
|
+
int32_t index = xt_weak_map_index(map, key);
|
|
61
|
+
if (index >= 0) {
|
|
62
|
+
map->values[index] = value;
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (map->count >= map->capacity) {
|
|
66
|
+
uint32_t capacity = map->capacity == 0 ? 8 : map->capacity * 2;
|
|
67
|
+
map->keys = (xt_value *)realloc(map->keys, sizeof(xt_value) * capacity);
|
|
68
|
+
map->values = (xt_value *)realloc(map->values, sizeof(xt_value) * capacity);
|
|
69
|
+
if (!map->keys || !map->values) abort();
|
|
70
|
+
map->capacity = capacity;
|
|
71
|
+
}
|
|
72
|
+
map->keys[map->count] = key;
|
|
73
|
+
map->values[map->count] = value;
|
|
74
|
+
map->count++;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
static int xt_weak_map_delete(xt_weak_map *map, xt_value key) {
|
|
78
|
+
int32_t index = xt_weak_map_index(map, key);
|
|
79
|
+
if (index < 0) return 0;
|
|
80
|
+
for (uint32_t i = (uint32_t)index + 1; i < map->count; i++) {
|
|
81
|
+
map->keys[i - 1] = map->keys[i];
|
|
82
|
+
map->values[i - 1] = map->values[i];
|
|
83
|
+
}
|
|
84
|
+
map->count--;
|
|
85
|
+
return 1;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
xt_value xt_weak_map_ctor(int32_t argc, xt_value *argv) {
|
|
89
|
+
xt_weak_map *map = (xt_weak_map *)xt_alloc(sizeof(xt_weak_map), XT_OBJECT_KIND_WEAK_MAP);
|
|
90
|
+
map->keys = NULL;
|
|
91
|
+
map->values = NULL;
|
|
92
|
+
map->count = 0;
|
|
93
|
+
map->capacity = 0;
|
|
94
|
+
xt_value iterable = xt_arg_at(argc, argv, 0);
|
|
95
|
+
if (XT_IS_ARRAY(iterable)) {
|
|
96
|
+
xt_array *array = (xt_array *)XT_GET_PTR(iterable);
|
|
97
|
+
for (uint32_t i = 0; i < array->length; i++) {
|
|
98
|
+
xt_array *pair = xt_as_array(array->items[i]);
|
|
99
|
+
if (!pair || pair->length < 2) {
|
|
100
|
+
xt_throw(xt_error_from_message("TypeError: Iterator value is not an entry object"));
|
|
101
|
+
return XT_UNDEFINED;
|
|
102
|
+
}
|
|
103
|
+
if (!xt_is_weak_target(pair->items[0])) {
|
|
104
|
+
xt_weak_key_error();
|
|
105
|
+
return XT_UNDEFINED;
|
|
106
|
+
}
|
|
107
|
+
xt_weak_map_set(map, pair->items[0], pair->items[1]);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return XT_FROM_PTR(XT_TAG_OBJECT, map);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* -- WeakSet -------------------------------------------------------------- */
|
|
114
|
+
|
|
115
|
+
static int32_t xt_weak_set_index(xt_weak_set *set, xt_value value) {
|
|
116
|
+
for (uint32_t i = 0; i < set->count; i++) {
|
|
117
|
+
if (xt_value_equals(set->values[i], value)) return (int32_t)i;
|
|
118
|
+
}
|
|
119
|
+
return -1;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
static void xt_weak_set_add(xt_weak_set *set, xt_value value) {
|
|
123
|
+
if (xt_weak_set_index(set, value) >= 0) return;
|
|
124
|
+
if (set->count >= set->capacity) {
|
|
125
|
+
uint32_t capacity = set->capacity == 0 ? 8 : set->capacity * 2;
|
|
126
|
+
set->values = (xt_value *)realloc(set->values, sizeof(xt_value) * capacity);
|
|
127
|
+
if (!set->values) abort();
|
|
128
|
+
set->capacity = capacity;
|
|
129
|
+
}
|
|
130
|
+
set->values[set->count++] = value;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
static int xt_weak_set_delete(xt_weak_set *set, xt_value value) {
|
|
134
|
+
int32_t index = xt_weak_set_index(set, value);
|
|
135
|
+
if (index < 0) return 0;
|
|
136
|
+
for (uint32_t i = (uint32_t)index + 1; i < set->count; i++) {
|
|
137
|
+
set->values[i - 1] = set->values[i];
|
|
138
|
+
}
|
|
139
|
+
set->count--;
|
|
140
|
+
return 1;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
xt_value xt_weak_set_ctor(int32_t argc, xt_value *argv) {
|
|
144
|
+
xt_weak_set *set = (xt_weak_set *)xt_alloc(sizeof(xt_weak_set), XT_OBJECT_KIND_WEAK_SET);
|
|
145
|
+
set->values = NULL;
|
|
146
|
+
set->count = 0;
|
|
147
|
+
set->capacity = 0;
|
|
148
|
+
xt_value iterable = xt_arg_at(argc, argv, 0);
|
|
149
|
+
if (XT_IS_ARRAY(iterable)) {
|
|
150
|
+
xt_array *array = (xt_array *)XT_GET_PTR(iterable);
|
|
151
|
+
for (uint32_t i = 0; i < array->length; i++) {
|
|
152
|
+
if (!xt_is_weak_target(array->items[i])) {
|
|
153
|
+
xt_weak_key_error();
|
|
154
|
+
return XT_UNDEFINED;
|
|
155
|
+
}
|
|
156
|
+
xt_weak_set_add(set, array->items[i]);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return XT_FROM_PTR(XT_TAG_OBJECT, set);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/* -- WeakRef -------------------------------------------------------------- */
|
|
163
|
+
|
|
164
|
+
xt_value xt_weak_ref_ctor(int32_t argc, xt_value *argv) {
|
|
165
|
+
xt_value target = xt_arg_at(argc, argv, 0);
|
|
166
|
+
if (!xt_is_weak_target(target)) {
|
|
167
|
+
xt_throw(xt_error_from_message("TypeError: WeakRef target must be an object"));
|
|
168
|
+
return XT_UNDEFINED;
|
|
169
|
+
}
|
|
170
|
+
xt_weak_ref *ref = (xt_weak_ref *)xt_alloc(sizeof(xt_weak_ref), XT_OBJECT_KIND_WEAK_REF);
|
|
171
|
+
ref->target = target;
|
|
172
|
+
return XT_FROM_PTR(XT_TAG_OBJECT, ref);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
xt_value xt_weak_method(xt_value target, const char *method, int32_t argc, xt_value *argv,
|
|
176
|
+
int *handled) {
|
|
177
|
+
*handled = 1;
|
|
178
|
+
if (xt_is_weak_map(target)) {
|
|
179
|
+
xt_weak_map *map = (xt_weak_map *)XT_GET_PTR(target);
|
|
180
|
+
xt_value key = xt_arg_at(argc, argv, 0);
|
|
181
|
+
if (strcmp(method, "set") == 0) {
|
|
182
|
+
if (!xt_is_weak_target(key)) {
|
|
183
|
+
xt_weak_key_error();
|
|
184
|
+
return XT_UNDEFINED;
|
|
185
|
+
}
|
|
186
|
+
xt_weak_map_set(map, key, xt_arg_at(argc, argv, 1));
|
|
187
|
+
return target;
|
|
188
|
+
}
|
|
189
|
+
if (strcmp(method, "get") == 0) {
|
|
190
|
+
if (!xt_is_weak_target(key)) return XT_UNDEFINED;
|
|
191
|
+
int32_t index = xt_weak_map_index(map, key);
|
|
192
|
+
return index >= 0 ? map->values[index] : XT_UNDEFINED;
|
|
193
|
+
}
|
|
194
|
+
if (strcmp(method, "has") == 0) {
|
|
195
|
+
return xt_bool(xt_is_weak_target(key) && xt_weak_map_index(map, key) >= 0);
|
|
196
|
+
}
|
|
197
|
+
if (strcmp(method, "delete") == 0) {
|
|
198
|
+
return xt_bool(xt_is_weak_target(key) && xt_weak_map_delete(map, key));
|
|
199
|
+
}
|
|
200
|
+
} else if (xt_is_weak_set(target)) {
|
|
201
|
+
xt_weak_set *set = (xt_weak_set *)XT_GET_PTR(target);
|
|
202
|
+
xt_value value = xt_arg_at(argc, argv, 0);
|
|
203
|
+
if (strcmp(method, "add") == 0) {
|
|
204
|
+
if (!xt_is_weak_target(value)) {
|
|
205
|
+
xt_weak_key_error();
|
|
206
|
+
return XT_UNDEFINED;
|
|
207
|
+
}
|
|
208
|
+
xt_weak_set_add(set, value);
|
|
209
|
+
return target;
|
|
210
|
+
}
|
|
211
|
+
if (strcmp(method, "has") == 0) {
|
|
212
|
+
return xt_bool(xt_is_weak_target(value) && xt_weak_set_index(set, value) >= 0);
|
|
213
|
+
}
|
|
214
|
+
if (strcmp(method, "delete") == 0) {
|
|
215
|
+
return xt_bool(xt_is_weak_target(value) && xt_weak_set_delete(set, value));
|
|
216
|
+
}
|
|
217
|
+
} else if (xt_is_weak_ref(target)) {
|
|
218
|
+
if (strcmp(method, "deref") == 0) return ((xt_weak_ref *)XT_GET_PTR(target))->target;
|
|
219
|
+
}
|
|
220
|
+
*handled = 0;
|
|
221
|
+
return XT_UNDEFINED;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* -- collector integration ------------------------------------------------ */
|
|
225
|
+
|
|
226
|
+
static int xt_weak_heap_value(xt_value value) {
|
|
227
|
+
return XT_IS_STRING(value) || XT_IS_OBJECT(value) || XT_IS_ARRAY(value) ||
|
|
228
|
+
XT_IS_FUNCTION(value) || XT_IS_BIGINT(value);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
int xt_weak_gc_process_once(void) {
|
|
232
|
+
int changed = 0;
|
|
233
|
+
for (xt_header *header = xt_gc_heap_head(); header; header = header->gc_next) {
|
|
234
|
+
if ((header->flags & XT_GC_MARK) == 0) continue;
|
|
235
|
+
if (header->kind != XT_OBJECT_KIND_WEAK_MAP) continue;
|
|
236
|
+
xt_weak_map *map = (xt_weak_map *)header;
|
|
237
|
+
for (uint32_t i = 0; i < map->count; i++) {
|
|
238
|
+
if (!xt_gc_value_is_marked(map->keys[i])) continue;
|
|
239
|
+
xt_value value = map->values[i];
|
|
240
|
+
if (!xt_weak_heap_value(value)) continue;
|
|
241
|
+
if (xt_gc_value_is_marked(value)) continue;
|
|
242
|
+
xt_gc_mark_value(value);
|
|
243
|
+
changed = 1;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return changed;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
void xt_weak_gc_clear(void) {
|
|
250
|
+
for (xt_header *header = xt_gc_heap_head(); header; header = header->gc_next) {
|
|
251
|
+
if ((header->flags & XT_GC_MARK) == 0) continue;
|
|
252
|
+
if (header->kind != XT_OBJECT_KIND_WEAK_REF) continue;
|
|
253
|
+
xt_weak_ref *ref = (xt_weak_ref *)header;
|
|
254
|
+
if (!xt_gc_value_is_marked(ref->target)) ref->target = XT_UNDEFINED;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
void xt_weak_gc_compact(void) {
|
|
259
|
+
for (xt_header *header = xt_gc_heap_head(); header; header = header->gc_next) {
|
|
260
|
+
if ((header->flags & XT_GC_MARK) == 0) continue;
|
|
261
|
+
if (header->kind == XT_OBJECT_KIND_WEAK_MAP) {
|
|
262
|
+
xt_weak_map *map = (xt_weak_map *)header;
|
|
263
|
+
uint32_t write = 0;
|
|
264
|
+
for (uint32_t read = 0; read < map->count; read++) {
|
|
265
|
+
if (!xt_gc_value_is_marked(map->keys[read])) continue;
|
|
266
|
+
map->keys[write] = map->keys[read];
|
|
267
|
+
map->values[write] = map->values[read];
|
|
268
|
+
write++;
|
|
269
|
+
}
|
|
270
|
+
map->count = write;
|
|
271
|
+
} else if (header->kind == XT_OBJECT_KIND_WEAK_SET) {
|
|
272
|
+
xt_weak_set *set = (xt_weak_set *)header;
|
|
273
|
+
uint32_t write = 0;
|
|
274
|
+
for (uint32_t read = 0; read < set->count; read++) {
|
|
275
|
+
if (!xt_gc_value_is_marked(set->values[read])) continue;
|
|
276
|
+
set->values[write++] = set->values[read];
|
|
277
|
+
}
|
|
278
|
+
set->count = write;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|