From b56f413e99903badfbbd60b23352bf06943fddea Mon Sep 17 00:00:00 2001 From: Sathya Gunasekaran Date: Fri, 10 Feb 2023 17:59:58 +0000 Subject: [PATCH] [hir] Mark ArrayExpression capturing a context ref as a context ref A context ref capture is transitive. --- .../src/Inference/InferReferenceEffects.ts | 4 +- ...-fun-alias-captured-mutate-arr-2.expect.md | 46 +++++++++++++++++++ ...pturing-fun-alias-captured-mutate-arr-2.js | 11 +++++ ...g-func-alias-captured-mutate-arr.expect.md | 46 +++++++++++++++++++ ...apturing-func-alias-captured-mutate-arr.js | 11 +++++ 5 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 compiler/forget/src/__tests__/fixtures/hir/capturing-fun-alias-captured-mutate-arr-2.expect.md create mode 100644 compiler/forget/src/__tests__/fixtures/hir/capturing-fun-alias-captured-mutate-arr-2.js create mode 100644 compiler/forget/src/__tests__/fixtures/hir/capturing-func-alias-captured-mutate-arr.expect.md create mode 100644 compiler/forget/src/__tests__/fixtures/hir/capturing-func-alias-captured-mutate-arr.js diff --git a/compiler/forget/src/Inference/InferReferenceEffects.ts b/compiler/forget/src/Inference/InferReferenceEffects.ts index b0a4bc44bd..24d45a96f3 100644 --- a/compiler/forget/src/Inference/InferReferenceEffects.ts +++ b/compiler/forget/src/Inference/InferReferenceEffects.ts @@ -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; diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-fun-alias-captured-mutate-arr-2.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capturing-fun-alias-captured-mutate-arr-2.expect.md new file mode 100644 index 0000000000..308eec7a83 --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-fun-alias-captured-mutate-arr-2.expect.md @@ -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; +} + +``` + \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-fun-alias-captured-mutate-arr-2.js b/compiler/forget/src/__tests__/fixtures/hir/capturing-fun-alias-captured-mutate-arr-2.js new file mode 100644 index 0000000000..de0c6bce45 --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-fun-alias-captured-mutate-arr-2.js @@ -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; +} diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-func-alias-captured-mutate-arr.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capturing-func-alias-captured-mutate-arr.expect.md new file mode 100644 index 0000000000..ce8471adff --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-func-alias-captured-mutate-arr.expect.md @@ -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; +} + +``` + \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-func-alias-captured-mutate-arr.js b/compiler/forget/src/__tests__/fixtures/hir/capturing-func-alias-captured-mutate-arr.js new file mode 100644 index 0000000000..91dd760b6f --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-func-alias-captured-mutate-arr.js @@ -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; +}