mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[aliasing] Introduce Effect.Capture
Effect.Capture is very similar to Effect.Read, but the only difference is that this reference is stored somewhere via a Effect.Store. Previously, any operand associated with a Effect.Store in the same instruction would get aliased -- so there was no need to explicitly differentiate between a "normal read" and "read that gets stored". This difference is now explicit with FunctionExpression where every dependency is "read" but only a few are "captured" for store (and mutation). In a follow up PR, the mutating deps will have an Effect.Capture to differentiate from the other non mutating deps (Effect.Read).
This commit is contained in:
@@ -546,6 +546,8 @@ export enum Effect {
|
||||
Freeze = "freeze",
|
||||
// This reference reads the value
|
||||
Read = "read",
|
||||
// This reference reads and stores the value
|
||||
Capture = "capture",
|
||||
// This reference may write to (mutate) the value
|
||||
Mutate = "mutate",
|
||||
// This reference may alias to (mutate) the value
|
||||
|
||||
@@ -30,7 +30,12 @@ export function inferAliasForStores(
|
||||
case "ComputedStore":
|
||||
case "PropertyStore": {
|
||||
for (const operand of eachInstructionValueOperand(value)) {
|
||||
maybeAlias(aliases, lvalue.place, operand, instr.id);
|
||||
if (
|
||||
operand.effect === Effect.Capture ||
|
||||
operand.effect === Effect.Store
|
||||
) {
|
||||
maybeAlias(aliases, lvalue.place, operand, instr.id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ function inferPlace(
|
||||
)}!`
|
||||
);
|
||||
}
|
||||
case Effect.Capture:
|
||||
case Effect.Read:
|
||||
case Effect.Freeze:
|
||||
return;
|
||||
|
||||
@@ -303,6 +303,10 @@ class Environment {
|
||||
effect = Effect.Store;
|
||||
break;
|
||||
}
|
||||
case Effect.Capture: {
|
||||
effect = Effect.Capture;
|
||||
break;
|
||||
}
|
||||
case Effect.Read: {
|
||||
effect = Effect.Read;
|
||||
break;
|
||||
@@ -542,7 +546,7 @@ function inferBlock(env: Environment, block: BasicBlock) {
|
||||
}
|
||||
case "ArrayExpression": {
|
||||
valueKind = ValueKind.Mutable;
|
||||
effectKind = Effect.Read;
|
||||
effectKind = Effect.Capture;
|
||||
lvalueEffect = Effect.Store;
|
||||
break;
|
||||
}
|
||||
@@ -564,7 +568,7 @@ function inferBlock(env: Environment, block: BasicBlock) {
|
||||
case "ObjectExpression": {
|
||||
valueKind = ValueKind.Mutable;
|
||||
// Object construction captures but does not modify the key/property values
|
||||
effectKind = Effect.Read;
|
||||
effectKind = Effect.Capture;
|
||||
lvalueEffect = Effect.Store;
|
||||
break;
|
||||
}
|
||||
@@ -658,7 +662,7 @@ function inferBlock(env: Environment, block: BasicBlock) {
|
||||
const effect = isObjectType(instrValue.object.identifier)
|
||||
? Effect.Store
|
||||
: Effect.Mutate;
|
||||
env.reference(instrValue.value, Effect.Read);
|
||||
env.reference(instrValue.value, Effect.Capture);
|
||||
env.reference(instrValue.object, effect);
|
||||
|
||||
const lvalue = instr.lvalue;
|
||||
@@ -688,8 +692,8 @@ function inferBlock(env: Environment, block: BasicBlock) {
|
||||
const effect = isObjectType(instrValue.object.identifier)
|
||||
? Effect.Store
|
||||
: Effect.Mutate;
|
||||
env.reference(instrValue.value, Effect.Read);
|
||||
env.reference(instrValue.property, Effect.Read);
|
||||
env.reference(instrValue.value, Effect.Capture);
|
||||
env.reference(instrValue.property, Effect.Capture);
|
||||
env.reference(instrValue.object, effect);
|
||||
|
||||
const lvalue = instr.lvalue;
|
||||
|
||||
Reference in New Issue
Block a user