mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Fix LeaveSSA missing param declarations
Nice find from @mofeiz, we weren't adding declarations for function params in LeaveSSA. This caused us to hit an invariant for update expressions that updated params which assumed that all named variables had a declaration. This is why it's helpful to add invariants, it helps you find places where you violate them :-)
This commit is contained in:
+14
-2
@@ -430,8 +430,6 @@ function computeMemoizationInputs(
|
||||
rvalues: value.children,
|
||||
};
|
||||
}
|
||||
case "PrefixUpdate":
|
||||
case "PostfixUpdate":
|
||||
case "Debugger":
|
||||
case "ComputedDelete":
|
||||
case "PropertyDelete":
|
||||
@@ -507,6 +505,20 @@ function computeMemoizationInputs(
|
||||
rvalues: [],
|
||||
};
|
||||
}
|
||||
case "PrefixUpdate":
|
||||
case "PostfixUpdate": {
|
||||
const lvalues = [
|
||||
{ place: value.lvalue, level: MemoizationLevel.Conditional },
|
||||
];
|
||||
if (lvalue !== null) {
|
||||
lvalues.push({ place: lvalue, level: MemoizationLevel.Conditional });
|
||||
}
|
||||
return {
|
||||
// Indirection for the inner value, memoized if the value is
|
||||
lvalues,
|
||||
rvalues: [value.value],
|
||||
};
|
||||
}
|
||||
case "StoreLocal": {
|
||||
const lvalues = [
|
||||
{ place: value.lvalue.place, level: MemoizationLevel.Conditional },
|
||||
|
||||
@@ -99,6 +99,18 @@ export function leaveSSA(fn: HIRFunction): void {
|
||||
{ lvalue: LValue | LValuePattern; place: Place }
|
||||
> = new Map();
|
||||
|
||||
for (const param of fn.params) {
|
||||
if (param.identifier.name !== null) {
|
||||
declarations.set(param.identifier.name, {
|
||||
lvalue: {
|
||||
kind: InstructionKind.Let,
|
||||
place: param,
|
||||
},
|
||||
place: param,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// For non-memoizable phis, this maps original identifiers to the identifier they should be
|
||||
// *rewritten* to. The keys are the original identifiers, and the value will be _either_ the
|
||||
// phi id or, more typically, the operand that was defined prior to the phi.
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
// @debug
|
||||
function Component(a, [b], { c }) {
|
||||
let d = a++;
|
||||
let e = ++a;
|
||||
let f = b--;
|
||||
let g = --b;
|
||||
let h = c++;
|
||||
let i = --c;
|
||||
return [a, b, c, d, e, f, g, h, i];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { unstable_useMemoCache as useMemoCache } from "react"; // @debug
|
||||
function Component(a, t37, t38) {
|
||||
const $ = useMemoCache(10);
|
||||
let [b] = t37;
|
||||
let { c } = t38;
|
||||
const d = a++;
|
||||
const e = ++a;
|
||||
const f = b--;
|
||||
const g = --b;
|
||||
const h = c++;
|
||||
const i = --c;
|
||||
const c_0 = $[0] !== a;
|
||||
const c_1 = $[1] !== b;
|
||||
const c_2 = $[2] !== c;
|
||||
const c_3 = $[3] !== d;
|
||||
const c_4 = $[4] !== e;
|
||||
const c_5 = $[5] !== f;
|
||||
const c_6 = $[6] !== g;
|
||||
const c_7 = $[7] !== h;
|
||||
const c_8 = $[8] !== i;
|
||||
let t0;
|
||||
if (c_0 || c_1 || c_2 || c_3 || c_4 || c_5 || c_6 || c_7 || c_8) {
|
||||
t0 = [a, b, c, d, e, f, g, h, i];
|
||||
$[0] = a;
|
||||
$[1] = b;
|
||||
$[2] = c;
|
||||
$[3] = d;
|
||||
$[4] = e;
|
||||
$[5] = f;
|
||||
$[6] = g;
|
||||
$[7] = h;
|
||||
$[8] = i;
|
||||
$[9] = t0;
|
||||
} else {
|
||||
t0 = $[9];
|
||||
}
|
||||
return t0;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// @debug
|
||||
function Component(a, [b], { c }) {
|
||||
let d = a++;
|
||||
let e = ++a;
|
||||
let f = b--;
|
||||
let g = --b;
|
||||
let h = c++;
|
||||
let i = --c;
|
||||
return [a, b, c, d, e, f, g, h, i];
|
||||
}
|
||||
Reference in New Issue
Block a user