Optimize node operations api #13
Merged
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.
Problem
Previously,
Nodeobjects were implemented usingNan::ObjectWrap. Each JavaScriptNodeinstance held a reference to a C++TSNodeinstance which was allocated separately. APIs likeNode.parentandNode.firstChildwould instantiate nodes using V8's C++ API, which is significantly slower than instantiating objects usingnewin JavaScript.Solution
Now,
Nodesare plain JavaScript objects which directly store the fields ofTSNodeas simple JavaScriptNumbers, except for thetreefield, which is now stored as a reference to the JavaScriptTreewrapper object. When we want to pass a JavaScriptNodeto a native tree-sitter API, we transfer the node's fields to C++ via a sharedArrayBufferand reassemble the correspondingTSNodeinstance in C++. For methods that return nodes, we do the same thing in reverse.By avoiding instantiating JS objects from C++, this approach significantly speeds up tree traversals.
Node Reference Equality
Another benefit of moving the instantiation of nodes from C++ to JavaScript is that it's now very simple to memoize the nodes, so that we never get two
Nodeinstances that conceptually represent the same node. Previously, there were cases where I wanted to check for node equality, so I had added anidproperty to nodes that I could compare instead. Now, theidmethod is unnecessary and we can simply use the===operator.