mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
compiler: merge reactive scopes across const StoreLocal (#29095)
@jbonta nerd-sniped me into making this optimization during conference
prep, posting this as a PR now that keynote is over.
Consider these two cases:
```javascript
export default function MyApp1({ count }) {
const cb = () => count;
return <div onclick={cb}>Hello World</div>;
}
export default function MyApp2({ count }) {
return <div onclick={() => count}>Hello World</div>;
}
```
Previously, the former would create two reactive scopes (one for `cb`,
one for the div) while the latter would only have a single scope for the
`div` and its inline callback. The reason we created separate scopes
before is that there's a `StoreLocal 'cb' = t0` instruction in-between,
and i had conservatively implemented the merging pass to not allow
intervening StoreLocal instructions.
The observation is that intervening StoreLocals are fine _if_ the
assigned variable's last usage is the next scope. We already have a
check that the intervening lvalues are last-used at/before the next
scope, so it's trivial to extend this to support StoreLocal.
Note that we already don't merge scopes if there are intervening
terminals, so we don't have to worry about things like conditional
StoreLocal, conditional access of the resulting value, etc.
This commit is contained in:
+29
@@ -9,6 +9,7 @@ import { CompilerError } from "..";
|
||||
import {
|
||||
IdentifierId,
|
||||
InstructionId,
|
||||
InstructionKind,
|
||||
Place,
|
||||
ReactiveBlock,
|
||||
ReactiveFunction,
|
||||
@@ -20,6 +21,7 @@ import {
|
||||
ReactiveStatement,
|
||||
makeInstructionId,
|
||||
} from "../HIR";
|
||||
import { eachInstructionLValue } from "../HIR/visitors";
|
||||
import { assertExhaustive } from "../Utils/utils";
|
||||
import { printReactiveScopeSummary } from "./PrintReactiveFunction";
|
||||
import {
|
||||
@@ -186,6 +188,33 @@ class Transform extends ReactiveFunctionTransform<ReactiveScopeDependencies | nu
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "StoreLocal": {
|
||||
/**
|
||||
* It's safe to have intervening StoreLocal instructions _if_ they are const
|
||||
* and the last usage of the variable is at or before the next scope. This is
|
||||
* similar to the case above for simple instructions.
|
||||
*
|
||||
* Reassignments are *not* safe to merge since they are a side-effect that we
|
||||
* don't want to make conditional.
|
||||
*/
|
||||
if (current !== null) {
|
||||
if (
|
||||
instr.instruction.value.lvalue.kind === InstructionKind.Const
|
||||
) {
|
||||
for (const lvalue of eachInstructionLValue(
|
||||
instr.instruction
|
||||
)) {
|
||||
current.lvalues.add(lvalue.identifier.id);
|
||||
}
|
||||
} else {
|
||||
log(
|
||||
`Reset scope @${current.block.scope.id} from StoreLocal in [${instr.instruction.id}]`
|
||||
);
|
||||
reset();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// Other instructions are known to prevent merging, so we reset the scope if present
|
||||
if (current !== null) {
|
||||
|
||||
+5
-12
@@ -24,24 +24,17 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
function component() {
|
||||
const $ = _c(2);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = [];
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
const z = t0;
|
||||
const $ = _c(1);
|
||||
let x;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
const z = [];
|
||||
const y = {};
|
||||
y.z = z;
|
||||
x = {};
|
||||
x.y = y;
|
||||
$[1] = x;
|
||||
$[0] = x;
|
||||
} else {
|
||||
x = $[1];
|
||||
x = $[0];
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
+4
-11
@@ -22,7 +22,7 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
function Component(props) {
|
||||
const $ = _c(3);
|
||||
const $ = _c(2);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = [];
|
||||
@@ -33,20 +33,13 @@ function Component(props) {
|
||||
const x = t0;
|
||||
let t1;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = x.map((item) => item);
|
||||
const y = x.map((item) => item);
|
||||
t1 = [x, y];
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
const y = t1;
|
||||
let t2;
|
||||
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t2 = [x, y];
|
||||
$[2] = t2;
|
||||
} else {
|
||||
t2 = $[2];
|
||||
}
|
||||
return t2;
|
||||
return t1;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
+4
-11
@@ -22,7 +22,7 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
function Component(props) {
|
||||
const $ = _c(3);
|
||||
const $ = _c(2);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = [];
|
||||
@@ -33,20 +33,13 @@ function Component(props) {
|
||||
const x = t0;
|
||||
let t1;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = x.map((item) => item);
|
||||
const y = x.map((item) => item);
|
||||
t1 = [x, y];
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
const y = t1;
|
||||
let t2;
|
||||
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t2 = [x, y];
|
||||
$[2] = t2;
|
||||
} else {
|
||||
t2 = $[2];
|
||||
}
|
||||
return t2;
|
||||
return t1;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
+5
-15
@@ -24,30 +24,20 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
function Component(props) {
|
||||
const $ = _c(3);
|
||||
const $ = _c(1);
|
||||
let t0;
|
||||
let x;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
x = [];
|
||||
t0 = x.map((item) => {
|
||||
const x = [];
|
||||
const y = x.map((item) => {
|
||||
item.updated = true;
|
||||
return item;
|
||||
});
|
||||
t0 = [x, y];
|
||||
$[0] = t0;
|
||||
$[1] = x;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
x = $[1];
|
||||
}
|
||||
const y = t0;
|
||||
let t1;
|
||||
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = [x, y];
|
||||
$[2] = t1;
|
||||
} else {
|
||||
t1 = $[2];
|
||||
}
|
||||
return t1;
|
||||
return t0;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
+5
-15
@@ -24,30 +24,20 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
function Component(props) {
|
||||
const $ = _c(3);
|
||||
const $ = _c(1);
|
||||
let t0;
|
||||
let x;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
x = [];
|
||||
t0 = x.map((item) => {
|
||||
const x = [];
|
||||
const y = x.map((item) => {
|
||||
item.updated = true;
|
||||
return item;
|
||||
});
|
||||
t0 = [x, y];
|
||||
$[0] = t0;
|
||||
$[1] = x;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
x = $[1];
|
||||
}
|
||||
const y = t0;
|
||||
let t1;
|
||||
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = [x, y];
|
||||
$[2] = t1;
|
||||
} else {
|
||||
t1 = $[2];
|
||||
}
|
||||
return t1;
|
||||
return t0;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
+5
-11
@@ -18,23 +18,17 @@ function foo() {
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
function foo() {
|
||||
const $ = _c(2);
|
||||
const $ = _c(1);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = () => <Child x={GLOBAL_IS_X} />;
|
||||
const getJSX = () => <Child x={GLOBAL_IS_X} />;
|
||||
|
||||
t0 = getJSX();
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
const getJSX = t0;
|
||||
let t1;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = getJSX();
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
const result = t1;
|
||||
const result = t0;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
import { Stringify, makeObject_Primitives } from "shared-runtime";
|
||||
|
||||
function Component(props) {
|
||||
const array = [props.count];
|
||||
const x = makeObject_Primitives();
|
||||
const element = <div>{array}</div>;
|
||||
console.log(x);
|
||||
return <div>{element}</div>;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [{ count: 42 }],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
import { Stringify, makeObject_Primitives } from "shared-runtime";
|
||||
|
||||
function Component(props) {
|
||||
const $ = _c(6);
|
||||
let t0;
|
||||
if ($[0] !== props.count) {
|
||||
t0 = [props.count];
|
||||
$[0] = props.count;
|
||||
$[1] = t0;
|
||||
} else {
|
||||
t0 = $[1];
|
||||
}
|
||||
const array = t0;
|
||||
const x = makeObject_Primitives();
|
||||
let t1;
|
||||
if ($[2] !== array) {
|
||||
t1 = <div>{array}</div>;
|
||||
$[2] = array;
|
||||
$[3] = t1;
|
||||
} else {
|
||||
t1 = $[3];
|
||||
}
|
||||
const element = t1;
|
||||
console.log(x);
|
||||
let t2;
|
||||
if ($[4] !== element) {
|
||||
t2 = <div>{element}</div>;
|
||||
$[4] = element;
|
||||
$[5] = t2;
|
||||
} else {
|
||||
t2 = $[5];
|
||||
}
|
||||
return t2;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [{ count: 42 }],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
### Eval output
|
||||
(kind: ok) <div><div>42</div></div>
|
||||
logs: [{ a: 0, b: 'value1', c: true }]
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import { Stringify, makeObject_Primitives } from "shared-runtime";
|
||||
|
||||
function Component(props) {
|
||||
const array = [props.count];
|
||||
const x = makeObject_Primitives();
|
||||
const element = <div>{array}</div>;
|
||||
console.log(x);
|
||||
return <div>{element}</div>;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [{ count: 42 }],
|
||||
};
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
import { Stringify } from "shared-runtime";
|
||||
|
||||
function Component(props) {
|
||||
let x;
|
||||
const array = [props.count];
|
||||
x = array;
|
||||
const element = <div>{array}</div>;
|
||||
return (
|
||||
<div>
|
||||
{element}
|
||||
{x}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [{ count: 42 }],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
import { Stringify } from "shared-runtime";
|
||||
|
||||
function Component(props) {
|
||||
const $ = _c(7);
|
||||
let x;
|
||||
let t0;
|
||||
if ($[0] !== props.count) {
|
||||
t0 = [props.count];
|
||||
$[0] = props.count;
|
||||
$[1] = t0;
|
||||
} else {
|
||||
t0 = $[1];
|
||||
}
|
||||
const array = t0;
|
||||
x = array;
|
||||
let t1;
|
||||
if ($[2] !== array) {
|
||||
t1 = <div>{array}</div>;
|
||||
$[2] = array;
|
||||
$[3] = t1;
|
||||
} else {
|
||||
t1 = $[3];
|
||||
}
|
||||
const element = t1;
|
||||
let t2;
|
||||
if ($[4] !== element || $[5] !== x) {
|
||||
t2 = (
|
||||
<div>
|
||||
{element}
|
||||
{x}
|
||||
</div>
|
||||
);
|
||||
$[4] = element;
|
||||
$[5] = x;
|
||||
$[6] = t2;
|
||||
} else {
|
||||
t2 = $[6];
|
||||
}
|
||||
return t2;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [{ count: 42 }],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
### Eval output
|
||||
(kind: ok) <div><div>42</div>42</div>
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import { Stringify } from "shared-runtime";
|
||||
|
||||
function Component(props) {
|
||||
let x;
|
||||
const array = [props.count];
|
||||
x = array;
|
||||
const element = <div>{array}</div>;
|
||||
return (
|
||||
<div>
|
||||
{element}
|
||||
{x}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [{ count: 42 }],
|
||||
};
|
||||
+5
-12
@@ -27,17 +27,10 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
function Component() {
|
||||
const $ = _c(2);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = [0, 1, 2, 3];
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
const x = t0;
|
||||
const $ = _c(1);
|
||||
let ret;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
const x = [0, 1, 2, 3];
|
||||
ret = [];
|
||||
for (const item of x) {
|
||||
if (item === 0) {
|
||||
@@ -46,9 +39,9 @@ function Component() {
|
||||
|
||||
ret.push(item / 2);
|
||||
}
|
||||
$[1] = ret;
|
||||
$[0] = ret;
|
||||
} else {
|
||||
ret = $[1];
|
||||
ret = $[0];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
+5
-11
@@ -27,10 +27,10 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
function Foo(t0) {
|
||||
const $ = _c(2);
|
||||
const $ = _c(1);
|
||||
let t1;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = (val) => {
|
||||
const outer = (val) => {
|
||||
const fact = (x) => {
|
||||
if (x <= 0) {
|
||||
return 1;
|
||||
@@ -39,19 +39,13 @@ function Foo(t0) {
|
||||
};
|
||||
return fact(val);
|
||||
};
|
||||
|
||||
t1 = outer(3);
|
||||
$[0] = t1;
|
||||
} else {
|
||||
t1 = $[0];
|
||||
}
|
||||
const outer = t1;
|
||||
let t2;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t2 = outer(3);
|
||||
$[1] = t2;
|
||||
} else {
|
||||
t2 = $[1];
|
||||
}
|
||||
return t2;
|
||||
return t1;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
+5
-11
@@ -25,28 +25,22 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
function Component(t0) {
|
||||
const $ = _c(2);
|
||||
const $ = _c(1);
|
||||
let t1;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = () => {
|
||||
const outer = () => {
|
||||
const inner = () => x;
|
||||
|
||||
const x = 3;
|
||||
return inner();
|
||||
};
|
||||
|
||||
t1 = <div>{outer()}</div>;
|
||||
$[0] = t1;
|
||||
} else {
|
||||
t1 = $[0];
|
||||
}
|
||||
const outer = t1;
|
||||
let t2;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t2 = <div>{outer()}</div>;
|
||||
$[1] = t2;
|
||||
} else {
|
||||
t2 = $[1];
|
||||
}
|
||||
return t2;
|
||||
return t1;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
+5
-11
@@ -24,23 +24,17 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
import { Stringify } from "shared-runtime";
|
||||
function useFoo() {
|
||||
const $ = _c(2);
|
||||
const $ = _c(1);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = () => <Stringify value={4} />;
|
||||
const callback = () => <Stringify value={4} />;
|
||||
|
||||
t0 = callback();
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
const callback = t0;
|
||||
let t1;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = callback();
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
return t1;
|
||||
return t0;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
+5
-11
@@ -24,24 +24,18 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
import * as SharedRuntime from "shared-runtime";
|
||||
function useFoo() {
|
||||
const $ = _c(2);
|
||||
const $ = _c(1);
|
||||
const MyLocal = SharedRuntime;
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = () => <MyLocal.Text value={4} />;
|
||||
const callback = () => <MyLocal.Text value={4} />;
|
||||
|
||||
t0 = callback();
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
const callback = t0;
|
||||
let t1;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = callback();
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
return t1;
|
||||
return t0;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
+13
-19
@@ -32,34 +32,28 @@ import { c as _c } from "react/compiler-runtime";
|
||||
const { mutate } = require("shared-runtime");
|
||||
|
||||
function Component(props) {
|
||||
const $ = _c(4);
|
||||
const $ = _c(3);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = {};
|
||||
const object = {};
|
||||
|
||||
t0 = () => {
|
||||
mutate(object);
|
||||
};
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
const object = t0;
|
||||
const onClick = t0;
|
||||
let t1;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = () => {
|
||||
mutate(object);
|
||||
};
|
||||
$[1] = t1;
|
||||
if ($[1] !== props.children) {
|
||||
t1 = <Foo callback={onClick}>{props.children}</Foo>;
|
||||
$[1] = props.children;
|
||||
$[2] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
t1 = $[2];
|
||||
}
|
||||
const onClick = t1;
|
||||
let t2;
|
||||
if ($[2] !== props.children) {
|
||||
t2 = <Foo callback={onClick}>{props.children}</Foo>;
|
||||
$[2] = props.children;
|
||||
$[3] = t2;
|
||||
} else {
|
||||
t2 = $[3];
|
||||
}
|
||||
return t2;
|
||||
return t1;
|
||||
}
|
||||
|
||||
function Foo(t0) {
|
||||
|
||||
+5
-11
@@ -34,12 +34,12 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
import { c as _c } from "react/compiler-runtime"; // @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions
|
||||
let cond = true;
|
||||
function Component(props) {
|
||||
const $ = _c(2);
|
||||
const $ = _c(1);
|
||||
let a;
|
||||
let b;
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = () => {
|
||||
const f = () => {
|
||||
if (cond) {
|
||||
a = {};
|
||||
b = [];
|
||||
@@ -51,19 +51,13 @@ function Component(props) {
|
||||
a.property = true;
|
||||
b.push(false);
|
||||
};
|
||||
|
||||
t0 = <div onClick={f} />;
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
const f = t0;
|
||||
let t1;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = <div onClick={f} />;
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
return t1;
|
||||
return t0;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
+5
-12
@@ -22,22 +22,15 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
function foo() {
|
||||
const $ = _c(2);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = [];
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
const x = t0;
|
||||
const $ = _c(1);
|
||||
let y;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
const x = [];
|
||||
y = {};
|
||||
y.x = x;
|
||||
$[1] = y;
|
||||
$[0] = y;
|
||||
} else {
|
||||
y = $[1];
|
||||
y = $[0];
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
+5
-15
@@ -16,27 +16,17 @@ function Component() {
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime"; // Forget should call the original x (x = foo()) to compute result
|
||||
function Component() {
|
||||
const $ = _c(3);
|
||||
const $ = _c(1);
|
||||
let t0;
|
||||
let x;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
x = foo();
|
||||
t0 = x((x = bar()), 5);
|
||||
let x = foo();
|
||||
const result = x((x = bar()), 5);
|
||||
t0 = [result, x];
|
||||
$[0] = t0;
|
||||
$[1] = x;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
x = $[1];
|
||||
}
|
||||
const result = t0;
|
||||
let t1;
|
||||
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = [result, x];
|
||||
$[2] = t1;
|
||||
} else {
|
||||
t1 = $[2];
|
||||
}
|
||||
return t1;
|
||||
return t0;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
+5
-11
@@ -25,29 +25,23 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
function Component(props) {
|
||||
const $ = _c(2);
|
||||
const $ = _c(1);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = () => {
|
||||
const callback = () => {
|
||||
try {
|
||||
return [];
|
||||
} catch (t1) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
t0 = callback();
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
const callback = t0;
|
||||
let t1;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = callback();
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
return t1;
|
||||
return t0;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
+6
-12
@@ -24,26 +24,20 @@ function component() {
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
function component() {
|
||||
const $ = _c(2);
|
||||
const $ = _c(1);
|
||||
const p = makePrimitive();
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = {};
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
const o = t0;
|
||||
let x;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
const o = {};
|
||||
|
||||
x = {};
|
||||
|
||||
x.t = p;
|
||||
|
||||
x.t = o;
|
||||
$[1] = x;
|
||||
$[0] = x;
|
||||
} else {
|
||||
x = $[1];
|
||||
x = $[0];
|
||||
}
|
||||
const y = x.t;
|
||||
return y;
|
||||
|
||||
Reference in New Issue
Block a user