Conversation
Summary: `TreeFS` told directory nodes apart from file nodes with `node instanceof Map`, which holds only when the tree was built in the same realm as the code reading it. A tree restored through `TreeFS.fromDeserializedSnapshot` is used as-is, so a snapshot deserialized in another realm traverses wrongly: every directory below the root reads as a symlink and lookups through it fail with `Expected symlink target to be populated`, while `hierarchicalLookup` treats the root as a non-directory and returns null without probing it. Nothing in a Metro process crosses a realm, but Jest does: each test file runs in its own `vm` context while `node:v8` is a host module, so a file map cache read back within a test holds `Map`s from another realm. The `metro` tests that build two `DependencyGraph`s on one config have been traversing such a tree, and pass only because the walks they make happen to fail in the direction their expectations need. File nodes are metadata tuples, so `isDirectory` checks `!Array.isArray(node)` instead, which reads an internal slot and is realm-independent. The new test round-trips a snapshot through `v8.serialize`/`deserialize` and looks up a nested file in the result. Changelog: [Internal]
Contributor
|
@vzaidman has imported this pull request. If you are a Meta employee, you can view this in D120355345. |
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.
TreeFSuses an internalinstanceof Mapcheck in its internalisDirectoryfunction, to identify whether a given node represented a directory (Map) or file (Array/tuple).The only problem with
instanceof Mapis under Jest, in tests where we're exercising the file map cache. In Jest, tests are executed in v8 contexts whereMapgets a new prototype, such that a file map cache v8-serialised in one test is deserialised but can't be traversed in another test, becauseinstanceof Mapchecks fail on the foreign maps.I discovered this while writing some unrelated tests that failed unexpectedly. We already have at least three tests in main that pass by accident (
isDirectoryreturns false despite the node being aMap, just a foreign one) and effectively weren't testing anything. (Luckily, they all pass anyway)An easy fix is to invert the implementation of
isDirectoryso that it becomes "not null and not a file", usingArray.isArray, which is portable across realms.As it turns out, this is also marginally faster.
Changelog: [Internal]
Test plan
Microbenchmark
isDirectoryis hot so just to confirm this doesn't regress:node instanceof Mapnode != null && !Array.isArray(node)Array.isArrayis marginally faster with a mix of inputs - implemented with a slot read rather than a prototype walk.