[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
mofeiZ committed
Jan 22, 2025 at 14:34 UTC
b6b33bfb92c095160df7370fb488acb89c55b5ca
2 files changed
+49
-33
compiler/packages/babel-plugin-react-compiler/src/Inference/InferFunctionEffects.ts
+6
-1
@@ -41,11 +41,16 @@ function inferOperandEffect(state: State, place: Place): null | FunctionEffect {
41
if (isRefOrRefValue(place.identifier)) {
42
break;
43
} else if (value.kind === ValueKind.Context) {
44
+ CompilerError.invariant(value.context.size > 0, {
45
+ reason:
46
+ "[InferFunctionEffects] Expected Context-kind value's capture list to be non-empty.",
47
+ loc: place.loc,
48
+ });
49
return {
50
kind: 'ContextMutation',
51
loc: place.loc,
52
effect: place.effect,
48
- places: value.context.size === 0 ? new Set([place]) : value.context,
53
+ places: value.context,
54
};
55
} else if (
56
value.kind !== ValueKind.Mutable &&
compiler/packages/babel-plugin-react-compiler/src/Inference/InferReferenceEffects.ts
+43
-32
@@ -857,17 +857,19 @@ function inferBlock(
857
break;
858
}
859
case 'ArrayExpression': {
860
- const valueKind: AbstractValue = hasContextRefOperand(state, instrValue)
861
- ? {
862
- kind: ValueKind.Context,
863
- reason: new Set([ValueReason.Other]),
864
- context: new Set(),
865
- }
866
- : {
867
- kind: ValueKind.Mutable,
868
- reason: new Set([ValueReason.Other]),
869
- context: new Set(),
870
- };
860
+ const contextRefOperands = getContextRefOperand(state, instrValue);
861
+ const valueKind: AbstractValue =
862
+ contextRefOperands.length > 0
863
+ ? {
864
+ kind: ValueKind.Context,
865
+ reason: new Set([ValueReason.Other]),
866
+ context: new Set(contextRefOperands),
867
+ }
868
+ : {
869
+ kind: ValueKind.Mutable,
870
+ reason: new Set([ValueReason.Other]),
871
+ context: new Set(),
872
+ };
873
continuation = {
874
kind: 'initialize',
875
valueKind,
@@ -918,17 +920,19 @@ function inferBlock(
920
break;
921
}
922
case 'ObjectExpression': {
921
- const valueKind: AbstractValue = hasContextRefOperand(state, instrValue)
922
- ? {
923
- kind: ValueKind.Context,
924
- reason: new Set([ValueReason.Other]),
925
- context: new Set(),
926
- }
927
- : {
928
- kind: ValueKind.Mutable,
929
- reason: new Set([ValueReason.Other]),
930
- context: new Set(),
931
- };
923
+ const contextRefOperands = getContextRefOperand(state, instrValue);
924
+ const valueKind: AbstractValue =
925
+ contextRefOperands.length > 0
926
+ ? {
927
+ kind: ValueKind.Context,
928
+ reason: new Set([ValueReason.Other]),
929
+ context: new Set(contextRefOperands),
930
+ }
931
+ : {
932
+ kind: ValueKind.Mutable,
933
+ reason: new Set([ValueReason.Other]),
934
+ context: new Set(),
935
+ };
936
937
for (const property of instrValue.properties) {
938
switch (property.kind) {
@@ -1593,15 +1597,21 @@ function inferBlock(
1597
}
1598
case 'LoadLocal': {
1599
const lvalue = instr.lvalue;
1596
- const effect =
1597
- state.isDefined(lvalue) &&
1598
- state.kind(lvalue).kind === ValueKind.Context
1599
- ? Effect.ConditionallyMutate
1600
- : Effect.Capture;
1600
+ CompilerError.invariant(
1601
+ !(
1602
+ state.isDefined(lvalue) &&
1603
+ state.kind(lvalue).kind === ValueKind.Context
1604
+ ),
1605
+ {
1606
+ reason:
1607
+ '[InferReferenceEffects] Unexpected LoadLocal with context kind',
1608
+ loc: lvalue.loc,
1609
+ },
1610
+ );
1611
state.referenceAndRecordEffects(
1612
freezeActions,
1613
instrValue.place,
1604
- effect,
1614
+ Effect.Capture,
1615
ValueReason.Other,
1616
);
1617
lvalue.effect = Effect.ConditionallyMutate;
@@ -1932,19 +1942,20 @@ function inferBlock(
1942
);
1943
}
1944
1935
-function hasContextRefOperand(
1945
+function getContextRefOperand(
1946
state: InferenceState,
1947
instrValue: InstructionValue,
1938
-): boolean {
1948
+): Array<Place> {
1949
+ const result = [];
1950
for (const place of eachInstructionValueOperand(instrValue)) {
1951
if (
1952
state.isDefined(place) &&
1953
state.kind(place).kind === ValueKind.Context
1954
) {
1944
- return true;
1955
+ result.push(place);
1956
}
1957
}
1947
- return false;
1958
+ return result;
1959
}
1960
1961
export function getFunctionCallSignature(