mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[compiler][ez] Patch hoistability for ObjectMethods
Extends #31066 to ObjectMethods (somehow missed this before). -
This commit is contained in:
+6
-2
@@ -348,7 +348,8 @@ function collectNonNullsInBlocks(
|
||||
assumedNonNullObjects.add(maybeNonNull);
|
||||
}
|
||||
if (
|
||||
instr.value.kind === 'FunctionExpression' &&
|
||||
(instr.value.kind === 'FunctionExpression' ||
|
||||
instr.value.kind === 'ObjectMethod') &&
|
||||
!fn.env.config.enableTreatFunctionDepsAsConditional
|
||||
) {
|
||||
const innerFn = instr.value.loweredFunc;
|
||||
@@ -591,7 +592,10 @@ function collectFunctionExpressionFakeLoads(
|
||||
|
||||
for (const [_, block] of fn.body.blocks) {
|
||||
for (const {lvalue, value} of block.instructions) {
|
||||
if (value.kind === 'FunctionExpression') {
|
||||
if (
|
||||
value.kind === 'FunctionExpression' ||
|
||||
value.kind === 'ObjectMethod'
|
||||
) {
|
||||
for (const reference of value.loweredFunc.dependencies) {
|
||||
let curr: IdentifierId | undefined = reference.identifier.id;
|
||||
while (curr != null) {
|
||||
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
// @enablePropagateDepsInHIR
|
||||
import {Stringify} from 'shared-runtime';
|
||||
|
||||
function Foo({a, shouldReadA}) {
|
||||
return (
|
||||
<Stringify
|
||||
objectMethod={{
|
||||
method() {
|
||||
if (shouldReadA) return a.b.c;
|
||||
return null;
|
||||
},
|
||||
}}
|
||||
shouldInvokeFns={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Foo,
|
||||
params: [{a: null, shouldReadA: true}],
|
||||
sequentialRenders: [
|
||||
{a: null, shouldReadA: true},
|
||||
{a: null, shouldReadA: false},
|
||||
{a: {b: {c: 4}}, shouldReadA: true},
|
||||
],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime"; // @enablePropagateDepsInHIR
|
||||
import { Stringify } from "shared-runtime";
|
||||
|
||||
function Foo(t0) {
|
||||
const $ = _c(3);
|
||||
const { a, shouldReadA } = t0;
|
||||
let t1;
|
||||
if ($[0] !== shouldReadA || $[1] !== a) {
|
||||
t1 = (
|
||||
<Stringify
|
||||
objectMethod={{
|
||||
method() {
|
||||
if (shouldReadA) {
|
||||
return a.b.c;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
}}
|
||||
shouldInvokeFns={true}
|
||||
/>
|
||||
);
|
||||
$[0] = shouldReadA;
|
||||
$[1] = a;
|
||||
$[2] = t1;
|
||||
} else {
|
||||
t1 = $[2];
|
||||
}
|
||||
return t1;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Foo,
|
||||
params: [{ a: null, shouldReadA: true }],
|
||||
sequentialRenders: [
|
||||
{ a: null, shouldReadA: true },
|
||||
{ a: null, shouldReadA: false },
|
||||
{ a: { b: { c: 4 } }, shouldReadA: true },
|
||||
],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
### Eval output
|
||||
(kind: ok) [[ (exception in render) TypeError: Cannot read properties of null (reading 'b') ]]
|
||||
<div>{"objectMethod":{"method":{"kind":"Function","result":null}},"shouldInvokeFns":true}</div>
|
||||
<div>{"objectMethod":{"method":{"kind":"Function","result":4}},"shouldInvokeFns":true}</div>
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// @enablePropagateDepsInHIR
|
||||
import {Stringify} from 'shared-runtime';
|
||||
|
||||
function Foo({a, shouldReadA}) {
|
||||
return (
|
||||
<Stringify
|
||||
objectMethod={{
|
||||
method() {
|
||||
if (shouldReadA) return a.b.c;
|
||||
return null;
|
||||
},
|
||||
}}
|
||||
shouldInvokeFns={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Foo,
|
||||
params: [{a: null, shouldReadA: true}],
|
||||
sequentialRenders: [
|
||||
{a: null, shouldReadA: true},
|
||||
{a: null, shouldReadA: false},
|
||||
{a: {b: {c: 4}}, shouldReadA: true},
|
||||
],
|
||||
};
|
||||
Reference in New Issue
Block a user