[hir] Mark ArrayExpression capturing a context ref as a context ref

A context ref capture is transitive.
This commit is contained in:
Sathya Gunasekaran
2023-02-10 17:59:58 +00:00
parent 343ebb47bd
commit b56f413e99
5 changed files with 117 additions and 1 deletions
@@ -563,7 +563,9 @@ function inferBlock(env: Environment, block: BasicBlock) {
break;
}
case "ArrayExpression": {
valueKind = ValueKind.Mutable;
valueKind = hasContextRefOperand(env, instrValue)
? ValueKind.Context
: ValueKind.Mutable;
effectKind = Effect.Capture;
lvalueEffect = Effect.Store;
break;
@@ -0,0 +1,46 @@
## Input
```javascript
function component(foo, bar) {
let x = { foo };
let y = { bar };
(function () {
let a = [y];
let b = x;
a.x = b;
})();
mutate(y);
return x;
}
```
## Code
```javascript
function component(foo, bar) {
const $ = React.unstable_useMemoCache();
const c_0 = $[0] !== foo;
const c_1 = $[1] !== bar;
let x;
if (c_0 || c_1) {
x = { foo: foo };
const y = { bar: bar };
(function () {
let a = [y];
let b = x;
a.x = b;
})();
mutate(y);
$[0] = foo;
$[1] = bar;
$[2] = x;
} else {
x = $[2];
}
return x;
}
```
@@ -0,0 +1,11 @@
function component(foo, bar) {
let x = { foo };
let y = { bar };
(function () {
let a = [y];
let b = x;
a.x = b;
})();
mutate(y);
return x;
}
@@ -0,0 +1,46 @@
## Input
```javascript
function component(foo, bar) {
let x = { foo };
let y = { bar };
(function () {
let a = [y];
let b = x;
a.x = b;
})();
mutate(y);
return y;
}
```
## Code
```javascript
function component(foo, bar) {
const $ = React.unstable_useMemoCache();
const c_0 = $[0] !== foo;
const c_1 = $[1] !== bar;
let y;
if (c_0 || c_1) {
const x = { foo: foo };
y = { bar: bar };
(function () {
let a = [y];
let b = x;
a.x = b;
})();
mutate(y);
$[0] = foo;
$[1] = bar;
$[2] = y;
} else {
y = $[2];
}
return y;
}
```
@@ -0,0 +1,11 @@
function component(foo, bar) {
let x = { foo };
let y = { bar };
(function () {
let a = [y];
let b = x;
a.x = b;
})();
mutate(y);
return y;
}