mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[compiler][ez] rewrite invariant in InferReferenceEffects (#32093)
Small patch to pass aliased context values into `Object|ArrayExpression`s --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32093). * #32099 * #32104 * #32098 * #32097 * #32096 * #32095 * #32094 * __->__ #32093
This commit is contained in:
@@ -41,11 +41,16 @@ function inferOperandEffect(state: State, place: Place): null | FunctionEffect {
|
||||
if (isRefOrRefValue(place.identifier)) {
|
||||
break;
|
||||
} else if (value.kind === ValueKind.Context) {
|
||||
CompilerError.invariant(value.context.size > 0, {
|
||||
reason:
|
||||
"[InferFunctionEffects] Expected Context-kind value's capture list to be non-empty.",
|
||||
loc: place.loc,
|
||||
});
|
||||
return {
|
||||
kind: 'ContextMutation',
|
||||
loc: place.loc,
|
||||
effect: place.effect,
|
||||
places: value.context.size === 0 ? new Set([place]) : value.context,
|
||||
places: value.context,
|
||||
};
|
||||
} else if (
|
||||
value.kind !== ValueKind.Mutable &&
|
||||
|
||||
+43
-32
@@ -857,17 +857,19 @@ function inferBlock(
|
||||
break;
|
||||
}
|
||||
case 'ArrayExpression': {
|
||||
const valueKind: AbstractValue = hasContextRefOperand(state, instrValue)
|
||||
? {
|
||||
kind: ValueKind.Context,
|
||||
reason: new Set([ValueReason.Other]),
|
||||
context: new Set(),
|
||||
}
|
||||
: {
|
||||
kind: ValueKind.Mutable,
|
||||
reason: new Set([ValueReason.Other]),
|
||||
context: new Set(),
|
||||
};
|
||||
const contextRefOperands = getContextRefOperand(state, instrValue);
|
||||
const valueKind: AbstractValue =
|
||||
contextRefOperands.length > 0
|
||||
? {
|
||||
kind: ValueKind.Context,
|
||||
reason: new Set([ValueReason.Other]),
|
||||
context: new Set(contextRefOperands),
|
||||
}
|
||||
: {
|
||||
kind: ValueKind.Mutable,
|
||||
reason: new Set([ValueReason.Other]),
|
||||
context: new Set(),
|
||||
};
|
||||
continuation = {
|
||||
kind: 'initialize',
|
||||
valueKind,
|
||||
@@ -918,17 +920,19 @@ function inferBlock(
|
||||
break;
|
||||
}
|
||||
case 'ObjectExpression': {
|
||||
const valueKind: AbstractValue = hasContextRefOperand(state, instrValue)
|
||||
? {
|
||||
kind: ValueKind.Context,
|
||||
reason: new Set([ValueReason.Other]),
|
||||
context: new Set(),
|
||||
}
|
||||
: {
|
||||
kind: ValueKind.Mutable,
|
||||
reason: new Set([ValueReason.Other]),
|
||||
context: new Set(),
|
||||
};
|
||||
const contextRefOperands = getContextRefOperand(state, instrValue);
|
||||
const valueKind: AbstractValue =
|
||||
contextRefOperands.length > 0
|
||||
? {
|
||||
kind: ValueKind.Context,
|
||||
reason: new Set([ValueReason.Other]),
|
||||
context: new Set(contextRefOperands),
|
||||
}
|
||||
: {
|
||||
kind: ValueKind.Mutable,
|
||||
reason: new Set([ValueReason.Other]),
|
||||
context: new Set(),
|
||||
};
|
||||
|
||||
for (const property of instrValue.properties) {
|
||||
switch (property.kind) {
|
||||
@@ -1593,15 +1597,21 @@ function inferBlock(
|
||||
}
|
||||
case 'LoadLocal': {
|
||||
const lvalue = instr.lvalue;
|
||||
const effect =
|
||||
state.isDefined(lvalue) &&
|
||||
state.kind(lvalue).kind === ValueKind.Context
|
||||
? Effect.ConditionallyMutate
|
||||
: Effect.Capture;
|
||||
CompilerError.invariant(
|
||||
!(
|
||||
state.isDefined(lvalue) &&
|
||||
state.kind(lvalue).kind === ValueKind.Context
|
||||
),
|
||||
{
|
||||
reason:
|
||||
'[InferReferenceEffects] Unexpected LoadLocal with context kind',
|
||||
loc: lvalue.loc,
|
||||
},
|
||||
);
|
||||
state.referenceAndRecordEffects(
|
||||
freezeActions,
|
||||
instrValue.place,
|
||||
effect,
|
||||
Effect.Capture,
|
||||
ValueReason.Other,
|
||||
);
|
||||
lvalue.effect = Effect.ConditionallyMutate;
|
||||
@@ -1932,19 +1942,20 @@ function inferBlock(
|
||||
);
|
||||
}
|
||||
|
||||
function hasContextRefOperand(
|
||||
function getContextRefOperand(
|
||||
state: InferenceState,
|
||||
instrValue: InstructionValue,
|
||||
): boolean {
|
||||
): Array<Place> {
|
||||
const result = [];
|
||||
for (const place of eachInstructionValueOperand(instrValue)) {
|
||||
if (
|
||||
state.isDefined(place) &&
|
||||
state.kind(place).kind === ValueKind.Context
|
||||
) {
|
||||
return true;
|
||||
result.push(place);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getFunctionCallSignature(
|
||||
|
||||
Reference in New Issue
Block a user