Implement AutoCloseable for Native Resources as an Optional Route for Deterministic Memory Collection#129
Open
DavidBakerEffendi wants to merge 12 commits intobonede:mainfrom
Open
Conversation
Move internal comments to class-level Javadoc and remove empty test stubs.
bonede
pushed a commit
that referenced
this pull request
Feb 24, 2026
…after-free / double-free PR #129 introduced AutoCloseable on all tree-sitter wrapper classes using Cleaner.Cleanable (idempotent, so close()+GC never double-frees). However TSTree and TSLanguage were missing the `closed` boolean + ensureOpen() pattern that the other classes (TSParser, TSTreeCursor, TSQuery, etc.) use. Without it: - TSTree.copy() on a closed tree calls ts_tree_copy(freed_ptr), returns an undefined pointer, and registers a new Cleanable for it. If that pointer happens to alias the original, the GC-triggered cleaner on the copy would call ts_tree_delete a second time → double-free. - All other TSTree public methods (getRootNode, edit, getIncludedRanges, getChangedRanges, printDotGraphs) silently use a freed native pointer. - TSLanguage has the same gap: no closed guard means all public methods and getPtr() can operate on a freed language pointer, which affects TSParser, TSQuery, and TsLookAheadIterator that hold references to the language. Fix: - TSTree: add `closed` boolean, ensureOpen(), set closed=true in close(), and add ensureOpen() to all public methods and getPtr() (the latter automatically protects TSParser's oldTree.getPtr() calls too). - TSLanguage: same pattern – add closed/ensureOpen() and guard getPtr(), copyPtr(), nextState(), stateCount(). https://claude.ai/code/session_01GWFZFAWaU9eTj8RmRKcB9m
Author
|
Noted the review. Will address that soon |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR updates the Java bindings to implement the
AutoCloseableinterface for all classes wrapping native C structures (e.g.,TSParser,TSQuery,TSTree). This change allows these resources to be used withintry-with-resourcesblocks, ensuring deterministic cleanup of native memory and preventing resource leaks. It also integratesjava.lang.ref.Cleaneras a safety net for garbage collection and implements strict state checking to preventing "use-after-free" segfaults.Key changes
TSParser,TSLanguage,TSQuery,TSQueryCursor,TSTree,TSTreeCursor, andTsLookAheadIteratornow implementAutoCloseable.close()method invokes a registeredCleanableaction to immediately free native pointers.ensureOpen(), throwing anIllegalStateExceptionif accessed after being closed, preventing JVM crashes.CleanerRunner.registernow returns aCleanableinstance, allowing manual invocation while maintaining GC-based safety.Cleaner.Cleanableto reduce verbosity and added JavaDoc notes explaining testing limitations for classes likeTSTree.TSAutoCloseableTestto verify auto-close behavior and idempotency.Resolves #110