Commit graph

1295 commits

Author SHA1 Message Date
Max Brunsfeld 5e2fb7d8bb Store compressed parse state symbols and values in one array 2026-05-23 19:19:14 -07:00
Will Lillis 65e8b25413
wip(generate): emit 3-way per-state parse table layout (plan B)
Replace the per-grammar CSR-vs-hybrid choice with a per-state picker
that places each state in the smallest of dense / CSR / small. State
ids are partitioned into contiguous tiers [Dense | CSR | Small] driven
by `large_state_count` and a new `csr_state_count` field on
TSLanguage. The runtime dispatches on two range checks; the rest of
the lookup logic per tier is unchanged.

States 0 (error) and 1 (start state) are pinned to the Dense tier so
they remain at indices 0 and 1, matching the runtime's hard-coded
expectations. Cost is bounded at ~2 * SYMBOL_COUNT * 2 bytes per
grammar.

Cleanup: drop --table-fmt CLI, OptLevel::ForceHybridTable /
ForceCompressedTable, RenderError::ConflictingParseTableFlags,
heuristic_should_compress, and use_compressed_tables since the free
picker provably picks the smallest representation per state.

Tests pass against the regenerated fixtures. The size savings are
measured in a follow-up corpus run.
2026-05-19 18:18:20 -04:00
Christian Clason 2b8647fc52
fixup: language test ABI>=15 2026-05-19 17:57:49 -04:00
Will Lillis d4d7c1b68f
fix(lib): remove unused section_index field from LookaheadIterator 2026-05-19 17:57:49 -04:00
Will Lillis ea90489d7a
perf(generate): add CSR-compressed parse tables (ABI 16)
Apply Compressed Sparse Row (CSR) compression to the parse table for
grammars that benefit, replacing the original dense + small split with
three flat arrays:

  uint32_t parse_table_row_offsets[STATE_COUNT + 1]
  uint16_t parse_table_columns[TOTAL_NNZ]
  uint16_t parse_table_values[TOTAL_NNZ]

Heuristic for enabling CSR (per grammar, all three must hold):

  1. LARGE_STATE_COUNT * SYMBOL_COUNT > STATE_COUNT * 40
     Ensures the dense table is large enough relative to total state
     count that savings outweigh the small-state grouping penalty.

  2. dense table density < 45%
     Ensures CSR actually saves space. Above ~50% density, CSR's
     per-entry column indices cost more than the zeros they eliminate.
     45% adds margin below the theoretical crossover.

  3. LARGE_STATE_COUNT * SYMBOL_COUNT > 50,000
     Avoids applying a format change to tiny grammars where fixed
     overhead dominates.

Co-authored-by: Tuomas Hietanen <thorium@iki.fi>
2026-05-19 17:57:49 -04:00
Christian Clason 3a260021dd build(deps): bump wasmtime-c-api to v36.0.9 2026-05-16 11:45:39 +02:00
𝙽!𝙻 21cfae7b56
Validate Wasm language memory reads (#5569) 2026-05-06 11:54:31 -07:00
Christian Clason 85f985a778 build(deps): bump wasmtime-c-api to v36.0.8 2026-05-05 08:19:02 +02:00
Will Lillis 8d737aa238 docs: note zero point unbounded behavior in query functions 2026-04-30 04:28:59 -04:00
dependabot[bot] aedab6e0f2 build(deps): bump postcss from 8.5.8 to 8.5.12 in /lib/binding_web
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.8 to 8.5.12.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.5.8...8.5.12)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.12
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-29 11:12:37 +02:00
Wilco Kruijer fb348c3493 wasm: add Language.loadSync for synchronous loading
Co-authored-by: Amaan Qureshi <git@amaanq.com>
2026-04-26 18:58:50 -04:00
Amaan Qureshi 43dc8eadbe query: fix finished state heap invariants 2026-04-26 18:03:55 -04:00
Will Lillis 123fb1c13c perf(query): use min-heap for finished_states in next_capture
`ts_query_cursor_next_capture` linearly scanned all finished states to
find the one with the earliest next capture byte offset. With deeply
nested code, this O(n) scan per capture caused the highlight crate to
hang for minutes on large files.

Replace the linear scan with a min-heap over the finished_states array,
keyed by (next_capture_byte_offset, pattern_index, id). The heap is
maintained lazily: ts_query_cursor__advance uses plain array_push
(preserving FIFO insertion order), and next_capture sifts new elements
into the heap on entry via a tracked heap_size boundary. This preserves
the documented "order found" guarantee for next_match while giving
next_capture O(log n) per call.
2026-04-26 18:03:55 -04:00
Will Lillis 361f293a73 fix(query): widen capture list pool from uint16_t to uint32_t
Commit 1f6eac55 ("query: Use uint32_t for capture list IDs") widened
QueryState.capture_list_id to uint32_t and removed the 65536 pool cap,
but left the pool function signatures as uint16_t. This caused silent
truncation when the pool exceeded 65535 entries, leading to a segfault.
2026-04-26 18:03:55 -04:00
Petr Sumbera 77cb23fccc lib: add Solaris support to the portable endian header
Solaris does not provide <endian.h> or <sys/endian.h>, but it does expose
byte-order definitions and conversion helpers via <sys/isa_defs.h> and
<sys/byteorder.h>.

Add a __sun branch so the portable header defines __BYTE_ORDER and the
htobe*/le*toh conversions on Solaris.

Co-authored-by: Amaan Qureshi <git@amaanq.com>
2026-04-26 13:23:32 -04:00
Daniel Jalkut 0f6780b9a3 lexer: pass code-unit length to U16_NEXT in UTF-16 decoders
`ts_decode_utf16_le` and `ts_decode_utf16_be` passed a byte length to
`U16_NEXT_LE` and `U16_NEXT_BE`, but those macros count `uint16_t` code
units. If a lead surrogate was the last code unit in a chunk, the decoder
could peek past the chunk and combine it with adjacent memory.

This commit passes the code-unit length to the UTF-16 macros, and fails
with `TS_DECODE_ERROR` when a chunk is too short to contain even one full
code unit. This lets the lexer retry with a fresh chunk or advance through
the invalid byte as it already does.

Co-authored-by: Will Lillis <will.lillis24@gmail.com>
Co-authored-by: Amaan Qureshi <git@amaanq.com>
2026-04-26 03:38:47 -04:00
Christian Clason 8178cfddd8 build(deps): bump wasmtime-c-api to v36.0.7 2026-04-10 00:41:06 +02:00
dependabot[bot] b018c20018 build(deps): bump vite from 7.3.1 to 7.3.2 in /lib/binding_web
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.3.1 to 7.3.2.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v7.3.2/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.3.2/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 7.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-07 10:10:18 +02:00
dependabot[bot] 422d7cc503 build(deps): bump the npm group across 1 directory with 4 updates
Bumps the npm group with 4 updates in the /lib/binding_web directory: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node), [dts-buddy](https://github.com/sveltejs/dts-buddy), [esbuild](https://github.com/evanw/esbuild) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).

Updates `@types/node` from 24.10.1 to 25.5.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `dts-buddy` from 0.6.2 to 0.7.0
- [Release notes](https://github.com/sveltejs/dts-buddy/releases)
- [Changelog](https://github.com/sveltejs/dts-buddy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/dts-buddy/compare/v0.6.2...v0.7.0)

Updates `esbuild` from 0.27.1 to 0.27.4
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/v0.27.4/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.27.1...v0.27.4)

Updates `typescript-eslint` from 8.48.1 to 8.58.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.58.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 25.5.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm
- dependency-name: dts-buddy
  dependency-version: 0.7.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm
- dependency-name: esbuild
  dependency-version: 0.27.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: typescript-eslint
  dependency-version: 8.58.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-04 01:21:32 -04:00
dependabot[bot] 7c1e6861fb build(deps): bump the npm group across 1 directory with 4 updates
Bumps the npm group with 4 updates in the /lib/binding_web directory: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node), [dts-buddy](https://github.com/sveltejs/dts-buddy), [esbuild](https://github.com/evanw/esbuild) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).


Updates `@types/node` from 24.10.1 to 25.5.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `dts-buddy` from 0.6.2 to 0.7.0
- [Release notes](https://github.com/sveltejs/dts-buddy/releases)
- [Changelog](https://github.com/sveltejs/dts-buddy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/dts-buddy/compare/v0.6.2...v0.7.0)

Updates `esbuild` from 0.27.1 to 0.27.4
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/v0.27.4/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.27.1...v0.27.4)

Updates `typescript-eslint` from 8.48.1 to 8.58.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.58.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 25.5.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm
- dependency-name: dts-buddy
  dependency-version: 0.7.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm
- dependency-name: esbuild
  dependency-version: 0.27.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: typescript-eslint
  dependency-version: 8.58.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-03 17:46:45 +02:00
Max Brunsfeld d3ff0ce81d
Fix wasm loading of languages w/ multiple reserved word sets (#5475) 2026-03-30 22:27:57 -07:00
Will Lillis 791d7cead4 perf(cli): minor allocation and write call reductions
- Cache tree byte range length to avoid redundant FFI calls per test
- Combine 5 separate XML attribute write! calls into one
- Pre-allocate format_sexp output buffer to avoid repeated growth
2026-03-31 01:27:05 -04:00
Will Lillis 01dc3dba18 fix(parser): sort error recovery reductions for deterministic ordering
The `LookaheadIterator` visits symbols in group order for small parse
states, which can produce `reduce_actions` in a different order than the
original linear symbol scan (pre c1379718). Since reductions are applied
sequentially and the last reduction version survives, different orderings
lead to different error recovery outcomes (e.g. losing nodes from ERROR
trees).

Sort the reduce_actions array by symbol (descending) after collection.
The array is typically 1-5 entries, so the insertion sort cost is
negligible and the full optimization speedup is preserved.
2026-03-29 21:36:29 -04:00
Will Lillis 0535b0ca37 fix(lib): correct various typos 2026-03-28 05:23:10 -04:00
Will Lillis cf8719f132 fix(rust): correct various typos 2026-03-28 05:23:10 -04:00
Will Lillis 1a82df3cac fix(rust): address new nightly lints 2026-03-28 05:23:10 -04:00
Will Lillis c1379718ab perf(parser): use LookaheadIterator in error recovery's all-symbol scan
In `ts_parser__do_all_potential_reductions`, when `lookahead_symbol` is
0 (error recovery), the code scanned every symbol from 1 to
`token_count` calling ts_language_table_entry for each with most returning
empty. Replace with `LookaheadIterator` which efficiently visits only symbols
with valid actions, yielding 7-20x fewer lookups for typical grammars.

Error recovery throughput improves ~29% (JS) / ~39% (C). Valid-code
parsing is unaffected.
2026-03-28 05:21:50 -04:00
Aaron Paterson cb01ffcc3f docs: update WASM build requirements for wasi-sdk
Since v0.26.1, `tree-sitter build --wasm` uses wasi-sdk instead of
Emscripten. The CLI automatically downloads wasi-sdk on first use,
so Emscripten, Docker, and Podman are no longer required.

Update the web binding README to reflect this change.

See #4393 for the original switch to wasi-sdk.
2026-03-27 15:07:54 +01:00
dependabot[bot] 6821fa7611 build(deps): bump flatted from 3.3.2 to 3.4.2 in /lib/binding_web
Bumps [flatted](https://github.com/WebReflection/flatted) from 3.3.2 to 3.4.2.
- [Commits](https://github.com/WebReflection/flatted/compare/v3.3.2...v3.4.2)

---
updated-dependencies:
- dependency-name: flatted
  dependency-version: 3.4.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-27 14:55:06 +01:00
Will Lillis 08d676b417 fix(lib): document invariants that must be upheld for TSInputEdit 2026-03-22 23:17:01 -04:00
Riley Bruins cf302b07d1 fix(query): don't add copies for quantifier steps outside alternations 2026-03-04 10:32:50 +01:00
Riley Bruins a95fff5477 refactor(query): remove alternative_is_immediate
This is implied by `is_pass_through`.
2026-03-04 02:44:53 -05:00
Will Lillis b27de1038f fix(rust): remove unused dependencies from loader and lib 2026-03-02 09:14:28 +01:00
Riley Bruins 4ae90615d1 chore(parser): return NULL, not false, for incomplete parse
Small nit; `NULL` is returned everywhere else in this function for an
incomplete parse.
2026-03-01 03:41:27 -05:00
dependabot[bot] f9bcce2e01 build(deps): bump rollup from 4.49.0 to 4.59.0 in /lib/binding_web
Bumps [rollup](https://github.com/rollup/rollup) from 4.49.0 to 4.59.0.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.49.0...v4.59.0)

---
updated-dependencies:
- dependency-name: rollup
  dependency-version: 4.59.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-28 15:11:12 +01:00
dependabot[bot] 3a295c7493 build(deps): bump minimatch in /lib/binding_web
Bumps  and [minimatch](https://github.com/isaacs/minimatch). These dependencies needed to be updated together.

Updates `minimatch` from 9.0.5 to 9.0.9
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v9.0.5...v9.0.9)

Updates `minimatch` from 3.1.2 to 3.1.5
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v9.0.5...v9.0.9)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-version: 9.0.9
  dependency-type: indirect
- dependency-name: minimatch
  dependency-version: 3.1.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-28 15:08:24 +01:00
Christian Clason 4d7d35818b build(deps): bump wasmtime to v36.0.6 2026-02-24 14:29:07 -05:00
lucasew 4e9fededff fix(lib): cast NULL in ts_subtree_children macro
Explicitly casting NULL to (Subtree *) in the ternary expression ensures
type consistency. This resolves ambiguous type inference issues encountered
by strict static analysis tools and C-to-Go transpilers (like ccgo).

Signed-off-by: lucasew <lucas59356@gmail.com>
2026-02-21 01:37:03 -05:00
Christian Clason a21ee02710 build(deps): bump wasmtime to v36.0.5 LTS
Wasmtime v34 introduced breaking ABI changes to `wasmtime_func_t` and
`wasmtime_table_t` structures. The `__private` field changed from
`size_t` to `void*`, requiring code updates to store complete
`wasmtime_func_t` structures instead of raw indices.

Changes:
- `BuiltinFunctionIndices`: `uint32_t` -> `wasmtime_func_t`
- `stdlib_fn_indices`: `uint32_t*` -> `wasmtime_func_t*`
- `FunctionDefinition.storage_location`: `uint32_t*` -> `void*`
- `get_builtin_extern()`: simplified to return stored func directly
- Lexer functions: use temp array for func storage, store table index
- Zero-initialize `builtin_fn_indices` so `store_id == 0` sentinel
  reliably detects missing stdlib exports
- Free `lexer_funcs` on error paths in `ts_wasm_store_new`
- Remove stale `(uint32_t *)` casts from `lexer_definitions`

Co-Authored-By: Amaan Qureshi <git@amaanq.com>
Co-Authored-By: nzinfo <li.monan@gmail.com>
2026-02-19 23:40:40 -05:00
Sergey Reshetnikov 5e23ccaac2 fix(lib): add RedoxOS support to portable/endian.h 2026-02-18 16:36:15 +01:00
Sergey Reshetnikov 5784924c59 use provided by RedoxOS byte orders implementations 2026-02-18 16:36:15 +01:00
Amaan Qureshi b8fcf27661 build(rust): update deps 2026-02-18 00:59:34 -05:00
Amaan Qureshi ebd2a56b5d treewide: add taplo config and reformat toml files 2026-02-18 00:59:34 -05:00
Amaan Qureshi 77c8f075f3 lib: fix clippy warnings from edition bump 2026-02-18 00:59:34 -05:00
Amaan Qureshi 0188262b4a rust: bump edition to 2024, MSRV to 1.90, and remove unnecessary allows 2026-02-18 00:59:34 -05:00
dependabot[bot] f3a9b493c0 build(deps): bump the cargo group with 5 updates
Bumps the cargo group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [anyhow](https://github.com/dtolnay/anyhow) | `1.0.100` | `1.0.101` |
| [clap](https://github.com/clap-rs/clap) | `4.5.56` | `4.5.57` |
| [regex](https://github.com/rust-lang/regex) | `1.12.2` | `1.12.3` |
| [regex-syntax](https://github.com/rust-lang/regex) | `0.8.8` | `0.8.9` |
| [schemars](https://github.com/GREsau/schemars) | `1.2.0` | `1.2.1` |


Updates `anyhow` from 1.0.100 to 1.0.101
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.100...1.0.101)

Updates `clap` from 4.5.56 to 4.5.57
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.56...clap_complete-v4.5.57)

Updates `regex` from 1.12.2 to 1.12.3
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.12.2...1.12.3)

Updates `regex-syntax` from 0.8.8 to 0.8.9
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/regex-syntax-0.8.8...regex-syntax-0.8.9)

Updates `schemars` from 1.2.0 to 1.2.1
- [Release notes](https://github.com/GREsau/schemars/releases)
- [Changelog](https://github.com/GREsau/schemars/blob/master/CHANGELOG.md)
- [Commits](https://github.com/GREsau/schemars/compare/v1.2.0...v1.2.1)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-version: 1.0.101
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo
- dependency-name: clap
  dependency-version: 4.5.57
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo
- dependency-name: regex
  dependency-version: 1.12.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo
- dependency-name: regex-syntax
  dependency-version: 0.8.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo
- dependency-name: schemars
  dependency-version: 1.2.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-10 10:50:33 +01:00
Chad McElligott 081c90b769
web: add default export to CJS bundle 2026-02-09 22:23:12 -05:00
Will Lillis 596a4d69bb fix(query): prevent cross-branch capture contamination in alternations with quantifiers
When a branch inside an alternation has a + or * quantifier, the
quantifier's pass_through step loops back to the branch's first step.
The alternation linking also sets that step's alternative_index to
point to the next branch. This causes the quantifier loop-back to
incorrectly explore other branches in the case of a failed match that
follows a successful match, contaminating captures.

This is corrected by redirecting the quantifier loop-back to a
"clean" copy of the target step without the alternative index pointing
to the next alternation branch.

Co-authored-by: Riley Bruins <ribru17@hotmail.com>
2026-02-09 21:57:29 -05:00
Will Lillis 48e921883a fix(rust)!: return u32 from Node::child_count
This matches the type returned from the underlying C library, and also
composes more cleanly with other functions like `Node::child`
2026-02-09 21:05:48 -05:00
Amaan Qureshi 22cda59a19 lib: clean up strict aliasing fixes in array.h 2026-02-08 11:09:31 +01:00