mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
9e1f36ab3e
Early sketch of a new representation for the middle-phase of the compiler. This is a sea-of-nodes approach, representing instructions and terminals as nodes with direct and control dependencies.
Something like this:
```js
let array = [];
if (cond) {
array.push(value);
}
return array;
```
Would correspond roughly to a graph as follows. Note that the actual representation uses `Instruction` as-is, and maps dependencies into local `Place`s, but for ease of reading i've mapped operands as the node they come from (n0 etc):
```
// instructions before the 'if': note that these are dangling
// (no nodes depends on them) but they would get ordered as control deps of n7, the if node
n0 = ArrayExpression []
n1 = StoreLocal 'array' = n0
// nodes from the consequent
n2 = LoadLocal 'array'
n3 = PropertyLoad n2 . 'push'
n4 = LoadLocal 'value'
n5 = MethodCall n2 . n3 ( n4 )
// if terminal
n6 = LoadLocal 'cond'
n7 = If test=n6 consequent=n5 alternate=(not pictured)
// return terminal
n8 = LoadLocal 'array';
n9 = Return value=n8
exit=n9
```
Note that even if there are multiple returns, there will always be a single "exit" node, which is just the node corresponding to the last statement of the outer block in the original program.
Converting back to HIR is a bit tricky, but shouldn’t be too bad. For all the nodes that correspond to a given block scope we can just emit the nodes to HIR in order, since they’re already in reverse post order. The catch is that nodes for inner block scopes are also mixed in and have to be emitted at the right point. I need to experiment with this more.
What's implemented so far is very basic translation of HIR to ReactiveGraph. The only dependencies created are direct data dependencies and basic control flow, which means that e.g. code inside an if consequent will stay "inside" that consequent, but it's possible for mutations or reassignments to get reordered. The reordering happens because we reverse-postorder the graph after construction, which automatically orders strictly based on dependencies and moves things around otherwise.
There is lots left to do here, including cleaning up the node dependencies and how they map to local Places, establishing other forms of dependencies, etc.
[ghstack-poisoned]
babel-plugin-react-compiler
React Compiler is a compiler that optimizes React applications, ensuring that only the minimal parts of components and hooks will re-render when state changes. The compiler also validates that components and hooks follow the Rules of React.
This package contains the React Compiler Babel plugin use in projects that make use of Babel. You can find instructions for using this plugin here: https://react.dev/learn/react-compiler