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:
Joe Savona
2023-08-14 15:48:05 -07:00
parent cb2ba7118f
commit 45d884bb6b
4 changed files with 97 additions and 2 deletions
@@ -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.
@@ -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;
}
```
@@ -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];
}