Skip to content

Commit

Permalink
[compiler][ez] Patch hoistability for ObjectMethods
Browse files Browse the repository at this point in the history
Extends #31066 to ObjectMethods (somehow missed this before).

'
  • Loading branch information
mofeiZ committed Oct 24, 2024
1 parent d19ba8e commit d0c31e9
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -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},
],
};

0 comments on commit d0c31e9

Please sign in to comment.