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
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
/* -- method dispatch ------------------------------------------------------ */
|
|
2
2
|
|
|
3
|
+
/* A method that no built-in table recognises must throw, exactly like a
|
|
4
|
+
* missing property called as a function in JavaScript. Returning `undefined`
|
|
5
|
+
* made typos and unimplemented APIs (e.g. `"x".normalize()`) fail silently. */
|
|
6
|
+
static _Noreturn void xt_throw_no_method(const char *type, const char *method) {
|
|
7
|
+
char message[256];
|
|
8
|
+
snprintf(message, sizeof(message), "TypeError: %s has no callable method '%s'", type, method);
|
|
9
|
+
xt_value argument = xt_string_from_cstr(message);
|
|
10
|
+
xt_throw(xt_type_error_ctor(1, &argument));
|
|
11
|
+
abort();
|
|
12
|
+
}
|
|
13
|
+
|
|
3
14
|
static xt_value xt_array_method(xt_value target, const char *method, int32_t argc, xt_value *argv, int *handled) {
|
|
4
15
|
*handled = 1;
|
|
5
16
|
if (strcmp(method, "push") == 0) {
|
|
@@ -40,6 +51,7 @@ static xt_value xt_string_method(xt_value target, const char *method, int32_t ar
|
|
|
40
51
|
*handled = 1;
|
|
41
52
|
if (strcmp(method, "charAt") == 0) return xt_string_char_at(target, xt_arg_at(argc, argv, 0));
|
|
42
53
|
if (strcmp(method, "charCodeAt") == 0) return xt_string_char_code_at(target, xt_arg_at(argc, argv, 0));
|
|
54
|
+
if (strcmp(method, "codePointAt") == 0) return xt_string_code_point_at_value(target, xt_arg_at(argc, argv, 0));
|
|
43
55
|
if (strcmp(method, "indexOf") == 0) return xt_string_index_of(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1));
|
|
44
56
|
if (strcmp(method, "includes") == 0) return xt_bool(xt_truthy(xt_ne(xt_string_index_of(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1)), xt_number(-1))));
|
|
45
57
|
if (strcmp(method, "slice") == 0) return xt_string_slice(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1));
|
|
@@ -51,8 +63,8 @@ static xt_value xt_string_method(xt_value target, const char *method, int32_t ar
|
|
|
51
63
|
if (strcmp(method, "trim") == 0) return xt_string_trim(target);
|
|
52
64
|
if (strcmp(method, "replace") == 0) return xt_string_replace(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1));
|
|
53
65
|
if (strcmp(method, "repeat") == 0) return xt_string_repeat(target, xt_arg_at(argc, argv, 0));
|
|
54
|
-
if (strcmp(method, "startsWith") == 0) return xt_string_starts_with(target, xt_arg_at(argc, argv, 0));
|
|
55
|
-
if (strcmp(method, "endsWith") == 0) return xt_string_ends_with(target, xt_arg_at(argc, argv, 0));
|
|
66
|
+
if (strcmp(method, "startsWith") == 0) return xt_string_starts_with(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1));
|
|
67
|
+
if (strcmp(method, "endsWith") == 0) return xt_string_ends_with(target, xt_arg_at(argc, argv, 0), xt_arg_at(argc, argv, 1));
|
|
56
68
|
if (strcmp(method, "concat") == 0) return xt_string_concat_args(target, argc, argv);
|
|
57
69
|
*handled = 0;
|
|
58
70
|
return XT_UNDEFINED;
|
|
@@ -91,7 +103,7 @@ static xt_value xt_method_value_invoke(xt_value thisValue, xt_value env, int32_t
|
|
|
91
103
|
snprintf(message, sizeof(message),
|
|
92
104
|
"TypeError: Cannot read properties of undefined (reading '%s')",
|
|
93
105
|
method ? method : "method");
|
|
94
|
-
xt_throw(
|
|
106
|
+
xt_throw(xt_error_from_message(message));
|
|
95
107
|
}
|
|
96
108
|
return xt_call_method(thisValue, name, argc, argv);
|
|
97
109
|
}
|
|
@@ -158,6 +170,18 @@ static const xt_method_spec XT_SET_METHODS[] = {
|
|
|
158
170
|
{"entries", 0}, {"forEach", 1},
|
|
159
171
|
};
|
|
160
172
|
|
|
173
|
+
static const xt_method_spec XT_WEAKMAP_METHODS[] = {
|
|
174
|
+
{"get", 1}, {"set", 2}, {"has", 1}, {"delete", 1},
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
static const xt_method_spec XT_WEAKSET_METHODS[] = {
|
|
178
|
+
{"add", 1}, {"has", 1}, {"delete", 1},
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
static const xt_method_spec XT_WEAKREF_METHODS[] = {
|
|
182
|
+
{"deref", 0},
|
|
183
|
+
};
|
|
184
|
+
|
|
161
185
|
static const xt_method_spec XT_REGEXP_METHODS[] = {
|
|
162
186
|
{"test", 1}, {"exec", 1}, {"toString", 0},
|
|
163
187
|
};
|
|
@@ -214,6 +238,12 @@ xt_value xt_method_value(xt_value target, xt_value name) {
|
|
|
214
238
|
known = xt_method_lookup(XT_MAP_METHODS, XT_NAME_COUNT(XT_MAP_METHODS), method, &arity);
|
|
215
239
|
} else if (kind == XT_OBJECT_KIND_SET) {
|
|
216
240
|
known = xt_method_lookup(XT_SET_METHODS, XT_NAME_COUNT(XT_SET_METHODS), method, &arity);
|
|
241
|
+
} else if (kind == XT_OBJECT_KIND_WEAK_MAP) {
|
|
242
|
+
known = xt_method_lookup(XT_WEAKMAP_METHODS, XT_NAME_COUNT(XT_WEAKMAP_METHODS), method, &arity);
|
|
243
|
+
} else if (kind == XT_OBJECT_KIND_WEAK_SET) {
|
|
244
|
+
known = xt_method_lookup(XT_WEAKSET_METHODS, XT_NAME_COUNT(XT_WEAKSET_METHODS), method, &arity);
|
|
245
|
+
} else if (kind == XT_OBJECT_KIND_WEAK_REF) {
|
|
246
|
+
known = xt_method_lookup(XT_WEAKREF_METHODS, XT_NAME_COUNT(XT_WEAKREF_METHODS), method, &arity);
|
|
217
247
|
} else if (kind == XT_OBJECT_KIND_REGEXP) {
|
|
218
248
|
known = xt_method_lookup(XT_REGEXP_METHODS, XT_NAME_COUNT(XT_REGEXP_METHODS), method, &arity);
|
|
219
249
|
} else if (kind == XT_OBJECT_KIND_PROMISE) {
|
|
@@ -239,7 +269,7 @@ xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *
|
|
|
239
269
|
* resolve it as an ordinary property and call it with `target` as `this`. */
|
|
240
270
|
if (xt_is_symbol(name)) {
|
|
241
271
|
if (target == XT_UNDEFINED || target == XT_NULL) {
|
|
242
|
-
xt_throw(
|
|
272
|
+
xt_throw(xt_error_from_message("TypeError: Cannot read properties of null (reading a Symbol)"));
|
|
243
273
|
}
|
|
244
274
|
xt_value fn = xt_get(target, name);
|
|
245
275
|
if (XT_IS_FUNCTION(fn)) return xt_call_with_this(fn, target, argc, argv);
|
|
@@ -252,7 +282,7 @@ xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *
|
|
|
252
282
|
* `target` as `this`, instead of silently returning undefined. */
|
|
253
283
|
xt_value fn = xt_get(target, name);
|
|
254
284
|
if (XT_IS_FUNCTION(fn)) return xt_call_with_this(fn, target, argc, argv);
|
|
255
|
-
xt_throw(
|
|
285
|
+
xt_throw(xt_error_from_message("TypeError: value at computed index is not a function"));
|
|
256
286
|
return XT_UNDEFINED;
|
|
257
287
|
}
|
|
258
288
|
if (target == XT_UNDEFINED || target == XT_NULL) {
|
|
@@ -260,13 +290,13 @@ xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *
|
|
|
260
290
|
char message[256];
|
|
261
291
|
snprintf(message, sizeof(message),
|
|
262
292
|
"TypeError: Cannot read properties of %s (reading '%s')", base, method);
|
|
263
|
-
xt_throw(
|
|
293
|
+
xt_throw(xt_error_from_message(message));
|
|
264
294
|
}
|
|
265
295
|
int handled = 0;
|
|
266
296
|
if (xt_is_symbol(target)) {
|
|
267
297
|
if (strcmp(method, "toString") == 0) return xt_symbol_to_string(target);
|
|
268
298
|
if (strcmp(method, "valueOf") == 0) return target;
|
|
269
|
-
|
|
299
|
+
xt_throw_no_method("symbol", method);
|
|
270
300
|
}
|
|
271
301
|
if (XT_IS_OBJECT(target)) {
|
|
272
302
|
xt_object *obj = (xt_object *)XT_GET_PTR(target);
|
|
@@ -286,15 +316,23 @@ xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *
|
|
|
286
316
|
if (kind != XT_OBJECT_KIND_OBJECT && kind != XT_OBJECT_KIND_FUNCTION) {
|
|
287
317
|
xt_value result = xt_ext_container_method(target, method, argc, argv, &handled);
|
|
288
318
|
if (handled) return result;
|
|
319
|
+
/* Containers keep their methods in dedicated C dispatch tables, but
|
|
320
|
+
* still inherit `Object.prototype` (`new Map().toString()`). */
|
|
321
|
+
xt_value inherited = xt_get(target, name);
|
|
322
|
+
if (XT_IS_FUNCTION(inherited)) return xt_call_with_this(inherited, target, argc, argv);
|
|
289
323
|
}
|
|
290
324
|
xt_value fn = xt_object_get(target, name);
|
|
291
325
|
if (XT_IS_FUNCTION(fn)) return xt_call_with_this(fn, target, argc, argv);
|
|
292
326
|
xt_value result = xt_ext_object_method(target, method, argc, argv, &handled);
|
|
293
327
|
if (handled) return result;
|
|
328
|
+
/* Inherited Object.prototype methods on containers without a property bag
|
|
329
|
+
* (`new Map().toString()`, ...). */
|
|
330
|
+
xt_value inherited = xt_get(target, name);
|
|
331
|
+
if (XT_IS_FUNCTION(inherited)) return xt_call_with_this(inherited, target, argc, argv);
|
|
294
332
|
{
|
|
295
333
|
char message[256];
|
|
296
334
|
snprintf(message, sizeof(message), "TypeError: object has no callable method '%s'", method);
|
|
297
|
-
xt_throw(
|
|
335
|
+
xt_throw(xt_error_from_message(message));
|
|
298
336
|
}
|
|
299
337
|
return XT_UNDEFINED;
|
|
300
338
|
}
|
|
@@ -333,6 +371,13 @@ xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *
|
|
|
333
371
|
}
|
|
334
372
|
xt_value fn = xt_object_get(target, name);
|
|
335
373
|
if (XT_IS_FUNCTION(fn)) return xt_call_with_this(fn, target, argc, argv);
|
|
374
|
+
/* Statics of a first-class built-in constructor (`const A = Array;
|
|
375
|
+
* A.isArray(x)`). */
|
|
376
|
+
xt_value builtinStatic = xt_builtin_static_value(target, name);
|
|
377
|
+
if (builtinStatic != XT_UNDEFINED) {
|
|
378
|
+
if (XT_IS_FUNCTION(builtinStatic)) return xt_call_with_this(builtinStatic, target, argc, argv);
|
|
379
|
+
return builtinStatic;
|
|
380
|
+
}
|
|
336
381
|
if (strcmp(method, "toString") == 0) {
|
|
337
382
|
/* Source text is not retained; report a native-style representation. */
|
|
338
383
|
xt_function *self = (xt_function *)XT_GET_PTR(target);
|
|
@@ -344,32 +389,38 @@ xt_value xt_call_method(xt_value target, xt_value name, int32_t argc, xt_value *
|
|
|
344
389
|
{
|
|
345
390
|
char message[256];
|
|
346
391
|
snprintf(message, sizeof(message), "TypeError: function has no callable method '%s'", method);
|
|
347
|
-
xt_throw(
|
|
392
|
+
xt_throw(xt_error_from_message(message));
|
|
348
393
|
}
|
|
349
394
|
return XT_UNDEFINED;
|
|
350
395
|
}
|
|
351
396
|
if (XT_IS_ARRAY(target)) {
|
|
352
397
|
xt_value result = xt_ext_array_method(target, method, argc, argv, &handled);
|
|
353
398
|
if (handled) return result;
|
|
354
|
-
|
|
399
|
+
result = xt_array_method(target, method, argc, argv, &handled);
|
|
400
|
+
if (handled) return result;
|
|
401
|
+
xt_throw_no_method("array", method);
|
|
355
402
|
}
|
|
356
403
|
if (XT_IS_STRING(target)) {
|
|
357
404
|
xt_value result = xt_ext_string_method(target, method, argc, argv, &handled);
|
|
358
405
|
if (handled) return result;
|
|
359
|
-
|
|
406
|
+
result = xt_string_method(target, method, argc, argv, &handled);
|
|
407
|
+
if (handled) return result;
|
|
408
|
+
xt_throw_no_method("string", method);
|
|
360
409
|
}
|
|
361
410
|
if (XT_IS_BIGINT(target)) {
|
|
362
411
|
xt_value result = xt_bigint_method(target, method, argc, argv, &handled);
|
|
363
412
|
if (handled) return result;
|
|
413
|
+
xt_throw_no_method("bigint", method);
|
|
364
414
|
}
|
|
365
415
|
if (XT_IS_NUMBER(target)) {
|
|
366
416
|
xt_value result = xt_ext_number_method(target, method, argc, argv, &handled);
|
|
367
417
|
if (handled) return result;
|
|
418
|
+
xt_throw_no_method("number", method);
|
|
368
419
|
}
|
|
369
420
|
if (target == XT_TRUE || target == XT_FALSE) {
|
|
370
421
|
if (strcmp(method, "toString") == 0) return target == XT_TRUE ? xt_string_from_cstr("true") : xt_string_from_cstr("false");
|
|
371
422
|
if (strcmp(method, "valueOf") == 0) return target;
|
|
372
|
-
|
|
423
|
+
xt_throw_no_method("boolean", method);
|
|
373
424
|
}
|
|
374
|
-
|
|
425
|
+
xt_throw_no_method("value", method);
|
|
375
426
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* -- string methods ------------------------------------------------------- */
|
|
2
2
|
|
|
3
|
+
/* Byte-level search. `from` is a byte offset; returns a byte offset or -1. */
|
|
3
4
|
static int32_t xt_string_find(xt_string *haystack, xt_string *needle, int32_t from) {
|
|
4
5
|
if (from < 0) from = 0;
|
|
5
6
|
if ((uint32_t)from > haystack->length) return -1;
|
|
@@ -12,44 +13,67 @@ static int32_t xt_string_find(xt_string *haystack, xt_string *needle, int32_t fr
|
|
|
12
13
|
return -1;
|
|
13
14
|
}
|
|
14
15
|
|
|
16
|
+
/* JavaScript indexes strings in UTF-16 code units; the byte search above is
|
|
17
|
+
* still correct because every JS index maps to a code-point boundary. */
|
|
15
18
|
static xt_value xt_string_char_at(xt_value value, xt_value indexValue) {
|
|
16
19
|
xt_string *s = xt_as_string(value);
|
|
17
20
|
if (!s) return xt_string_from_cstr("");
|
|
18
21
|
int32_t index = xt_to_int32(indexValue);
|
|
19
|
-
if (index < 0 || (uint32_t)index >= s
|
|
20
|
-
return
|
|
22
|
+
if (index < 0 || (uint32_t)index >= xt_string_utf16_length(s)) return xt_string_from_cstr("");
|
|
23
|
+
return xt_string_unit_value(s, index);
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
static xt_value xt_string_char_code_at(xt_value value, xt_value indexValue) {
|
|
24
27
|
xt_string *s = xt_as_string(value);
|
|
25
28
|
if (!s) return xt_number(NAN);
|
|
26
29
|
int32_t index = xt_to_int32(indexValue);
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
int32_t unit = xt_string_code_unit(s, index);
|
|
31
|
+
if (unit < 0) return xt_number(NAN);
|
|
32
|
+
return xt_number((double)unit);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static xt_value xt_string_code_point_at_value(xt_value value, xt_value indexValue) {
|
|
36
|
+
xt_string *s = xt_as_string(value);
|
|
37
|
+
if (!s) return XT_UNDEFINED;
|
|
38
|
+
int32_t index = xt_to_int32(indexValue);
|
|
39
|
+
int32_t code = xt_string_code_point_at(s, index);
|
|
40
|
+
if (code < 0) return XT_UNDEFINED;
|
|
41
|
+
return xt_number((double)code);
|
|
29
42
|
}
|
|
30
43
|
|
|
31
44
|
static xt_value xt_string_index_of(xt_value value, xt_value needleValue, xt_value fromValue) {
|
|
32
45
|
xt_string *s = xt_as_string(value);
|
|
33
46
|
if (!s) return xt_number(-1);
|
|
34
47
|
xt_string *needle = xt_as_string(xt_to_string(needleValue));
|
|
48
|
+
int32_t units = (int32_t)xt_string_utf16_length(s);
|
|
35
49
|
int32_t from = fromValue == XT_UNDEFINED ? 0 : xt_to_int32(fromValue);
|
|
36
|
-
|
|
50
|
+
if (from < 0) from = 0;
|
|
51
|
+
if (from > units) from = units;
|
|
52
|
+
/* A start position inside a surrogate pair leaves a lone low half; slice the
|
|
53
|
+
* tail so a search for the whole pair correctly fails. */
|
|
54
|
+
if (!xt_string_is_boundary(s, from)) {
|
|
55
|
+
xt_string *tail = xt_as_string(xt_string_slice_units(s, from, units));
|
|
56
|
+
int32_t at = xt_string_find(tail, needle, 0);
|
|
57
|
+
return xt_number(at < 0 ? -1.0 : (double)(from + xt_string_unit_offset(tail, at)));
|
|
58
|
+
}
|
|
59
|
+
int32_t at = xt_string_find(s, needle, xt_string_byte_offset(s, from));
|
|
60
|
+
return xt_number(at < 0 ? -1.0 : (double)xt_string_unit_offset(s, at));
|
|
37
61
|
}
|
|
38
62
|
|
|
39
63
|
static xt_value xt_string_slice(xt_value value, xt_value startValue, xt_value endValue) {
|
|
40
64
|
xt_string *s = xt_as_string(value);
|
|
41
65
|
if (!s) return xt_string_from_cstr("");
|
|
42
|
-
int32_t len = (int32_t)s
|
|
66
|
+
int32_t len = (int32_t)xt_string_utf16_length(s);
|
|
43
67
|
int32_t start = startValue == XT_UNDEFINED ? 0 : xt_to_int32(startValue);
|
|
44
68
|
int32_t end = endValue == XT_UNDEFINED ? len : xt_to_int32(endValue);
|
|
45
69
|
xt_normalize_slice(len, &start, &end);
|
|
46
|
-
return
|
|
70
|
+
return xt_string_slice_units(s, start, end);
|
|
47
71
|
}
|
|
48
72
|
|
|
49
73
|
static xt_value xt_string_substring(xt_value value, xt_value startValue, xt_value endValue) {
|
|
50
74
|
xt_string *s = xt_as_string(value);
|
|
51
75
|
if (!s) return xt_string_from_cstr("");
|
|
52
|
-
int32_t len = (int32_t)s
|
|
76
|
+
int32_t len = (int32_t)xt_string_utf16_length(s);
|
|
53
77
|
int32_t start = startValue == XT_UNDEFINED ? 0 : xt_to_int32(startValue);
|
|
54
78
|
int32_t end = endValue == XT_UNDEFINED ? len : xt_to_int32(endValue);
|
|
55
79
|
if (start < 0) start = 0;
|
|
@@ -61,13 +85,13 @@ static xt_value xt_string_substring(xt_value value, xt_value startValue, xt_valu
|
|
|
61
85
|
start = end;
|
|
62
86
|
end = swap;
|
|
63
87
|
}
|
|
64
|
-
return
|
|
88
|
+
return xt_string_slice_units(s, start, end);
|
|
65
89
|
}
|
|
66
90
|
|
|
67
91
|
static xt_value xt_string_substr(xt_value value, xt_value startValue, xt_value lengthValue) {
|
|
68
92
|
xt_string *s = xt_as_string(value);
|
|
69
93
|
if (!s) return xt_string_from_cstr("");
|
|
70
|
-
int32_t len = (int32_t)s
|
|
94
|
+
int32_t len = (int32_t)xt_string_utf16_length(s);
|
|
71
95
|
int32_t start = startValue == XT_UNDEFINED ? 0 : xt_to_int32(startValue);
|
|
72
96
|
if (start < 0) start += len;
|
|
73
97
|
if (start < 0) start = 0;
|
|
@@ -75,7 +99,7 @@ static xt_value xt_string_substr(xt_value value, xt_value startValue, xt_value l
|
|
|
75
99
|
int32_t length = lengthValue == XT_UNDEFINED ? len - start : xt_to_int32(lengthValue);
|
|
76
100
|
if (length < 0) length = 0;
|
|
77
101
|
if (start + length > len) length = len - start;
|
|
78
|
-
return
|
|
102
|
+
return xt_string_slice_units(s, start, start + length);
|
|
79
103
|
}
|
|
80
104
|
|
|
81
105
|
static xt_value xt_string_split(xt_value value, xt_value separatorValue, xt_value limitValue) {
|
|
@@ -92,7 +116,10 @@ static xt_value xt_string_split(xt_value value, xt_value separatorValue, xt_valu
|
|
|
92
116
|
const char *bytes = xt_string_bytes(s);
|
|
93
117
|
const char *sepBytes = xt_string_bytes(sep);
|
|
94
118
|
if (sep->length == 0) {
|
|
95
|
-
|
|
119
|
+
/* Splitting on the empty string yields one string per UTF-16 code unit,
|
|
120
|
+
* so an emoji becomes its two surrogate halves. */
|
|
121
|
+
int32_t units = (int32_t)xt_string_utf16_length(s);
|
|
122
|
+
for (int32_t i = 0; i < units; i++) xt_array_push(result, xt_string_unit_value(s, i));
|
|
96
123
|
} else {
|
|
97
124
|
uint32_t start = 0;
|
|
98
125
|
uint32_t i = 0;
|
|
@@ -122,6 +149,7 @@ static xt_value xt_string_case(xt_value value, int upper) {
|
|
|
122
149
|
unsigned char c = (unsigned char)bytes[i];
|
|
123
150
|
mutable[i] = (char)(upper ? toupper((int)c) : tolower((int)c));
|
|
124
151
|
}
|
|
152
|
+
xt_string_finish(out);
|
|
125
153
|
return XT_FROM_PTR(XT_TAG_STRING, out);
|
|
126
154
|
}
|
|
127
155
|
|
|
@@ -153,6 +181,7 @@ static xt_value xt_string_replace(xt_value value, xt_value searchValue, xt_value
|
|
|
153
181
|
memcpy(mutable + at, repl, replacement->length);
|
|
154
182
|
memcpy(mutable + at + replacement->length, text + at + search->length,
|
|
155
183
|
s->length - (size_t)at - search->length);
|
|
184
|
+
xt_string_finish(out);
|
|
156
185
|
return XT_FROM_PTR(XT_TAG_STRING, out);
|
|
157
186
|
}
|
|
158
187
|
|
|
@@ -161,30 +190,58 @@ static xt_value xt_string_repeat(xt_value value, xt_value countValue) {
|
|
|
161
190
|
if (!s) return value;
|
|
162
191
|
int32_t count = xt_to_int32(countValue);
|
|
163
192
|
if (count < 0) {
|
|
164
|
-
xt_throw(
|
|
193
|
+
xt_throw(xt_error_from_message("RangeError: Invalid count value"));
|
|
165
194
|
return XT_UNDEFINED;
|
|
166
195
|
}
|
|
167
196
|
xt_string *out = xt_string_alloc((size_t)s->length * (size_t)count);
|
|
168
197
|
const char *bytes = xt_string_bytes(s);
|
|
169
198
|
char *mutable = xt_string_mutable(out);
|
|
170
199
|
for (int32_t i = 0; i < count; i++) memcpy(mutable + (size_t)i * s->length, bytes, s->length);
|
|
200
|
+
xt_string_finish(out);
|
|
171
201
|
return XT_FROM_PTR(XT_TAG_STRING, out);
|
|
172
202
|
}
|
|
173
203
|
|
|
174
|
-
static xt_value xt_string_starts_with(xt_value value, xt_value searchValue) {
|
|
204
|
+
static xt_value xt_string_starts_with(xt_value value, xt_value searchValue, xt_value positionValue) {
|
|
175
205
|
xt_string *s = xt_as_string(value);
|
|
176
206
|
if (!s) return XT_FALSE;
|
|
177
207
|
xt_string *search = xt_as_string(xt_to_string(searchValue));
|
|
208
|
+
const char *sBytes = xt_string_bytes(s);
|
|
209
|
+
const char *searchBytes = xt_string_bytes(search);
|
|
210
|
+
int32_t units = (int32_t)xt_string_utf16_length(s);
|
|
211
|
+
int32_t position = positionValue == XT_UNDEFINED ? 0 : xt_to_int32(positionValue);
|
|
212
|
+
if (position < 0) position = 0;
|
|
213
|
+
if (position > units) position = units;
|
|
178
214
|
if (search->length > s->length) return XT_FALSE;
|
|
179
|
-
|
|
215
|
+
if (!xt_string_is_boundary(s, position)) {
|
|
216
|
+
xt_string *tail = xt_as_string(xt_string_slice_units(s, position, units));
|
|
217
|
+
if (search->length > tail->length) return XT_FALSE;
|
|
218
|
+
return xt_bool(memcmp(xt_string_bytes(tail), searchBytes, search->length) == 0);
|
|
219
|
+
}
|
|
220
|
+
int32_t at = xt_string_byte_offset(s, position);
|
|
221
|
+
if ((uint32_t)at + search->length > s->length) return XT_FALSE;
|
|
222
|
+
return xt_bool(memcmp(sBytes + at, searchBytes, search->length) == 0);
|
|
180
223
|
}
|
|
181
224
|
|
|
182
|
-
static xt_value xt_string_ends_with(xt_value value, xt_value searchValue) {
|
|
225
|
+
static xt_value xt_string_ends_with(xt_value value, xt_value searchValue, xt_value endValue) {
|
|
183
226
|
xt_string *s = xt_as_string(value);
|
|
184
227
|
if (!s) return XT_FALSE;
|
|
185
228
|
xt_string *search = xt_as_string(xt_to_string(searchValue));
|
|
229
|
+
const char *sBytes = xt_string_bytes(s);
|
|
230
|
+
const char *searchBytes = xt_string_bytes(search);
|
|
231
|
+
int32_t units = (int32_t)xt_string_utf16_length(s);
|
|
232
|
+
int32_t end = endValue == XT_UNDEFINED ? units : xt_to_int32(endValue);
|
|
233
|
+
if (end < 0) end = 0;
|
|
234
|
+
if (end > units) end = units;
|
|
186
235
|
if (search->length > s->length) return XT_FALSE;
|
|
187
|
-
|
|
236
|
+
if (!xt_string_is_boundary(s, end)) {
|
|
237
|
+
xt_string *prefix = xt_as_string(xt_string_slice_units(s, 0, end));
|
|
238
|
+
if (search->length > prefix->length) return XT_FALSE;
|
|
239
|
+
return xt_bool(memcmp(xt_string_bytes(prefix) + prefix->length - search->length,
|
|
240
|
+
searchBytes, search->length) == 0);
|
|
241
|
+
}
|
|
242
|
+
int32_t at = xt_string_byte_offset(s, end);
|
|
243
|
+
if ((uint32_t)at < search->length) return XT_FALSE;
|
|
244
|
+
return xt_bool(memcmp(sBytes + at - search->length, searchBytes, search->length) == 0);
|
|
188
245
|
}
|
|
189
246
|
|
|
190
247
|
static xt_value xt_string_concat_args(xt_value value, int32_t argc, xt_value *argv) {
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
/* -- Array statics -------------------------------------------------------- */
|
|
2
2
|
|
|
3
|
+
/* True when `Array.from` should consume the value through the iteration
|
|
4
|
+
* protocol instead of the array-like `length` path. Typed arrays stay on the
|
|
5
|
+
* length path because their indexed properties already work that way. */
|
|
6
|
+
static int xt_array_from_is_iterable(xt_value value) {
|
|
7
|
+
if (xt_is_map(value) || xt_is_set(value) || xt_is_generator(value)) return 1;
|
|
8
|
+
if (XT_IS_OBJECT(value) && xt_typed_array_kind_of(value) < 0) {
|
|
9
|
+
return XT_IS_FUNCTION(xt_object_get(value, xt_symbol_well_known("iterator")));
|
|
10
|
+
}
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
|
|
3
14
|
xt_value xt_array_static(xt_value name, int32_t argc, xt_value *argv) {
|
|
4
15
|
const char *fn = xt_string_data(name);
|
|
5
16
|
if (!fn) return XT_UNDEFINED;
|
|
@@ -18,12 +29,26 @@ xt_value xt_array_static(xt_value name, int32_t argc, xt_value *argv) {
|
|
|
18
29
|
}
|
|
19
30
|
} else if (XT_IS_STRING(source)) {
|
|
20
31
|
xt_string *s = xt_as_string(source);
|
|
21
|
-
|
|
22
|
-
for (uint32_t i = 0; i <
|
|
23
|
-
xt_value item =
|
|
32
|
+
uint32_t points = xt_string_code_point_count(s);
|
|
33
|
+
for (uint32_t i = 0; i < points; i++) {
|
|
34
|
+
xt_value item = xt_string_code_point_value(s, (int32_t)i);
|
|
24
35
|
if (XT_IS_FUNCTION(mapper)) { xt_value args[2] = {item, xt_number((double)i)}; item = xt_closure_call(mapper, 2, args); }
|
|
25
36
|
xt_array_push(out, item);
|
|
26
37
|
}
|
|
38
|
+
} else if (xt_array_from_is_iterable(source)) {
|
|
39
|
+
/* Map, Set, generators, iterator objects and custom `[Symbol.iterator]`
|
|
40
|
+
* values do not expose a `length`; walk their `next()` protocol instead
|
|
41
|
+
* of silently producing an empty array. */
|
|
42
|
+
xt_value iterator = xt_iter_open(source);
|
|
43
|
+
for (uint32_t i = 0;; i++) {
|
|
44
|
+
if (!xt_truthy(xt_iter_has(iterator, xt_number((double)i)))) break;
|
|
45
|
+
xt_value item = xt_iter_value(iterator, xt_number((double)i));
|
|
46
|
+
if (XT_IS_FUNCTION(mapper)) {
|
|
47
|
+
xt_value args[2] = {item, xt_number((double)i)};
|
|
48
|
+
item = xt_closure_call(mapper, 2, args);
|
|
49
|
+
}
|
|
50
|
+
xt_array_push(out, item);
|
|
51
|
+
}
|
|
27
52
|
} else {
|
|
28
53
|
double length = xt_to_number(xt_get(source, xt_string_from_cstr("length")));
|
|
29
54
|
for (int32_t i = 0; i < (int32_t)length; i++) {
|
|
@@ -85,7 +85,7 @@ static xt_value xt_array_sort(xt_value value, xt_value fn) {
|
|
|
85
85
|
int hasFn = XT_IS_FUNCTION(fn);
|
|
86
86
|
xt_value *scratch = (xt_value *)malloc(sizeof(xt_value) * array->length);
|
|
87
87
|
if (!scratch) {
|
|
88
|
-
xt_throw(
|
|
88
|
+
xt_throw(xt_error_from_message("RangeError: out of memory in Array.prototype.sort"));
|
|
89
89
|
return value;
|
|
90
90
|
}
|
|
91
91
|
xt_array_merge_sort(array->items, scratch, array->length, fn, hasFn);
|
|
@@ -225,7 +225,9 @@ static xt_value xt_array_with(xt_value value, xt_value indexValue, xt_value newV
|
|
|
225
225
|
int32_t index = xt_to_int32(indexValue);
|
|
226
226
|
if (index < 0) index += (int32_t)array->length;
|
|
227
227
|
if (index < 0 || index >= (int32_t)array->length) {
|
|
228
|
-
|
|
228
|
+
xt_value message =
|
|
229
|
+
xt_add(xt_string_from_cstr("RangeError: Invalid index : "), xt_to_string(indexValue));
|
|
230
|
+
xt_throw(xt_error_from_message(xt_string_data(message)));
|
|
229
231
|
return copy;
|
|
230
232
|
}
|
|
231
233
|
array->items[index] = newValue;
|
|
@@ -266,7 +268,7 @@ xt_value xt_ext_array_method(xt_value target, const char *method, int32_t argc,
|
|
|
266
268
|
xt_value acc;
|
|
267
269
|
if (argc >= 2) acc = argv[1];
|
|
268
270
|
else if (array->length > 0) acc = array->items[i--];
|
|
269
|
-
else { xt_throw(
|
|
271
|
+
else { xt_throw(xt_error_from_message("TypeError: Reduce of empty array with no initial value")); return XT_UNDEFINED; }
|
|
270
272
|
for (; i >= 0; i--) {
|
|
271
273
|
xt_value args[4] = {acc, array->items[i], xt_number((double)i), target};
|
|
272
274
|
acc = xt_closure_call(fn, 4, args);
|
|
@@ -2,6 +2,11 @@ xt_value xt_ext_container_method(xt_value target, const char *method, int32_t ar
|
|
|
2
2
|
xt_object *obj = (xt_object *)XT_GET_PTR(target);
|
|
3
3
|
if (obj->header.kind == XT_OBJECT_KIND_MAP) return xt_map_method(target, method, argc, argv, handled);
|
|
4
4
|
if (obj->header.kind == XT_OBJECT_KIND_SET) return xt_set_method(target, method, argc, argv, handled);
|
|
5
|
+
if (obj->header.kind == XT_OBJECT_KIND_WEAK_MAP ||
|
|
6
|
+
obj->header.kind == XT_OBJECT_KIND_WEAK_SET ||
|
|
7
|
+
obj->header.kind == XT_OBJECT_KIND_WEAK_REF) {
|
|
8
|
+
return xt_weak_method(target, method, argc, argv, handled);
|
|
9
|
+
}
|
|
5
10
|
if (obj->header.kind == XT_OBJECT_KIND_DATE) return xt_date_method(target, method, argc, argv, handled);
|
|
6
11
|
if (obj->header.kind == XT_OBJECT_KIND_REGEXP) {
|
|
7
12
|
xt_regexp *regexp = (xt_regexp *)obj;
|
|
@@ -4,11 +4,111 @@ int xt_is_date(xt_value value) {
|
|
|
4
4
|
return XT_IS_OBJECT(value) && ((xt_object *)XT_GET_PTR(value))->header.kind == XT_OBJECT_KIND_DATE;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
/* Parse `YYYY-MM-DD`, optionally followed by `T`/space and
|
|
8
|
+
* `HH:MM[:SS[.mmm]]`, then `Z`, `+HH:MM`/`-HH:MM` (or the HHMM spelling).
|
|
9
|
+
* A date-only value is UTC; a date-time without an offset is local time, which
|
|
10
|
+
* is what ECMAScript specifies. Returns milliseconds since the epoch, or NaN
|
|
11
|
+
* for anything outside this subset. */
|
|
12
|
+
static int xt_date_digits(const char *text, int count, int *out) {
|
|
13
|
+
int value = 0;
|
|
14
|
+
for (int i = 0; i < count; i++) {
|
|
15
|
+
if (text[i] < '0' || text[i] > '9') return 0;
|
|
16
|
+
value = value * 10 + (text[i] - '0');
|
|
17
|
+
}
|
|
18
|
+
*out = value;
|
|
19
|
+
return 1;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static double xt_date_parse_text(const char *text) {
|
|
23
|
+
size_t length = strlen(text);
|
|
24
|
+
size_t i = 0;
|
|
25
|
+
int year = 0, month = 0, day = 0;
|
|
26
|
+
if (length < 10 || !xt_date_digits(text, 4, &year) || text[4] != '-' ||
|
|
27
|
+
!xt_date_digits(text + 5, 2, &month) || text[7] != '-' ||
|
|
28
|
+
!xt_date_digits(text + 8, 2, &day)) {
|
|
29
|
+
return NAN;
|
|
30
|
+
}
|
|
31
|
+
i = 10;
|
|
32
|
+
int hour = 0, minute = 0, second = 0, millis = 0;
|
|
33
|
+
int hasTime = 0;
|
|
34
|
+
if (i < length && (text[i] == 'T' || text[i] == ' ')) {
|
|
35
|
+
hasTime = 1;
|
|
36
|
+
i++;
|
|
37
|
+
if (i + 5 > length || !xt_date_digits(text + i, 2, &hour) || text[i + 2] != ':' ||
|
|
38
|
+
!xt_date_digits(text + i + 3, 2, &minute)) {
|
|
39
|
+
return NAN;
|
|
40
|
+
}
|
|
41
|
+
i += 5;
|
|
42
|
+
if (i + 3 <= length && text[i] == ':') {
|
|
43
|
+
if (!xt_date_digits(text + i + 1, 2, &second)) return NAN;
|
|
44
|
+
i += 3;
|
|
45
|
+
}
|
|
46
|
+
if (i + 4 <= length && text[i] == '.') {
|
|
47
|
+
if (!xt_date_digits(text + i + 1, 3, &millis)) return NAN;
|
|
48
|
+
i += 4;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
int utc = !hasTime;
|
|
52
|
+
int offsetSeconds = 0;
|
|
53
|
+
if (i < length) {
|
|
54
|
+
if (text[i] == 'Z') {
|
|
55
|
+
utc = 1;
|
|
56
|
+
i++;
|
|
57
|
+
} else if (text[i] == '+' || text[i] == '-') {
|
|
58
|
+
int sign = text[i] == '-' ? -1 : 1;
|
|
59
|
+
i++;
|
|
60
|
+
int offsetHour = 0, offsetMinute = 0;
|
|
61
|
+
if (i + 5 <= length && xt_date_digits(text + i, 2, &offsetHour) && text[i + 2] == ':' &&
|
|
62
|
+
xt_date_digits(text + i + 3, 2, &offsetMinute)) {
|
|
63
|
+
i += 5;
|
|
64
|
+
} else if (i + 4 <= length && xt_date_digits(text + i, 2, &offsetHour) &&
|
|
65
|
+
xt_date_digits(text + i + 2, 2, &offsetMinute)) {
|
|
66
|
+
i += 4;
|
|
67
|
+
} else {
|
|
68
|
+
return NAN;
|
|
69
|
+
}
|
|
70
|
+
if (offsetHour > 23 || offsetMinute > 59) return NAN;
|
|
71
|
+
offsetSeconds = sign * (offsetHour * 3600 + offsetMinute * 60);
|
|
72
|
+
utc = 1;
|
|
73
|
+
} else {
|
|
74
|
+
return NAN;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (i != length) return NAN;
|
|
78
|
+
if (month < 1 || month > 12 || day < 1 || day > 31 ||
|
|
79
|
+
hour > 23 || minute > 59 || second > 59) {
|
|
80
|
+
return NAN;
|
|
81
|
+
}
|
|
82
|
+
struct tm tm;
|
|
83
|
+
memset(&tm, 0, sizeof(tm));
|
|
84
|
+
tm.tm_year = year - 1900;
|
|
85
|
+
tm.tm_mon = month - 1;
|
|
86
|
+
tm.tm_mday = day;
|
|
87
|
+
tm.tm_hour = hour;
|
|
88
|
+
tm.tm_min = minute;
|
|
89
|
+
tm.tm_sec = second;
|
|
90
|
+
time_t seconds;
|
|
91
|
+
if (utc) {
|
|
92
|
+
seconds = xt_timegm(&tm);
|
|
93
|
+
} else {
|
|
94
|
+
tm.tm_isdst = -1;
|
|
95
|
+
seconds = mktime(&tm);
|
|
96
|
+
if (seconds == (time_t)-1) return NAN;
|
|
97
|
+
}
|
|
98
|
+
if (utc && offsetSeconds != 0) seconds -= offsetSeconds;
|
|
99
|
+
return (double)seconds * 1000.0 + (double)millis;
|
|
100
|
+
}
|
|
101
|
+
|
|
7
102
|
xt_value xt_date_ctor(int32_t argc, xt_value *argv) {
|
|
8
103
|
xt_date *date = (xt_date *)xt_alloc(sizeof(xt_date), XT_OBJECT_KIND_DATE);
|
|
9
104
|
if (argc == 0) date->time = (double)time(NULL) * 1000.0;
|
|
10
|
-
else if (argc == 1)
|
|
11
|
-
|
|
105
|
+
else if (argc == 1) {
|
|
106
|
+
if (XT_IS_STRING(argv[0])) {
|
|
107
|
+
date->time = xt_date_parse_text(xt_string_data(argv[0]));
|
|
108
|
+
} else {
|
|
109
|
+
date->time = xt_to_number(argv[0]);
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
12
112
|
struct tm tm;
|
|
13
113
|
memset(&tm, 0, sizeof(tm));
|
|
14
114
|
tm.tm_year = xt_to_int32(argv[0]) - 1900;
|
|
@@ -27,7 +127,11 @@ xt_value xt_date_static(xt_value name, int32_t argc, xt_value *argv) {
|
|
|
27
127
|
const char *fn = xt_string_data(name);
|
|
28
128
|
if (!fn) return XT_UNDEFINED;
|
|
29
129
|
if (strcmp(fn, "now") == 0) return xt_number((double)time(NULL) * 1000.0);
|
|
30
|
-
if (strcmp(fn, "parse") == 0)
|
|
130
|
+
if (strcmp(fn, "parse") == 0) {
|
|
131
|
+
xt_value input = xt_arg_at(argc, argv, 0);
|
|
132
|
+
if (!XT_IS_STRING(input)) return xt_number(NAN);
|
|
133
|
+
return xt_number(xt_date_parse_text(xt_string_data(input)));
|
|
134
|
+
}
|
|
31
135
|
if (strcmp(fn, "UTC") == 0) {
|
|
32
136
|
struct tm tm;
|
|
33
137
|
memset(&tm, 0, sizeof(tm));
|
|
@@ -68,6 +172,10 @@ static xt_value xt_date_method(xt_value target, const char *method, int32_t argc
|
|
|
68
172
|
if (strcmp(name, "getSeconds") == 0) return xt_number(tm.tm_sec);
|
|
69
173
|
if (strcmp(name, "getMilliseconds") == 0) return xt_number(fmod(date->time, 1000.0));
|
|
70
174
|
if (strcmp(method, "toISOString") == 0) {
|
|
175
|
+
if (isnan(date->time)) {
|
|
176
|
+
xt_value message = xt_string_from_cstr("Invalid time value");
|
|
177
|
+
xt_throw(xt_range_error_ctor(1, &message));
|
|
178
|
+
}
|
|
71
179
|
char buffer[64];
|
|
72
180
|
snprintf(buffer, sizeof(buffer), "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", tm.tm_year + 1900, tm.tm_mon + 1,
|
|
73
181
|
tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, (int)fmod(date->time, 1000.0));
|