LoadLocal instruction
Changes InstructionValue::Place to InstructionValue::LoadLocal for clarity, this is intended as the only instruction where a variable can appear as an operand. All other instructions operands will be temporaries.
Joe Savona committed
Mar 1, 2023 at 16:27 UTC
71db40c6ff97514fd54ea48c23370ebf4bab2e63
26 files changed
+152
-129
compiler/forget/src/HIR/BuildHIR.ts
+48
-30
@@ -110,7 +110,7 @@ export function lower(
110
param.node.loc ?? GeneratedSource,
111
InstructionKind.Let,
112
param,
113
- place
113
+ { kind: "LoadLocal", place, loc: place.loc }
114
);
115
} else {
116
builder.errors.push({
@@ -628,7 +628,7 @@ function lowerStatement(
628
const stmt = stmtPath as NodePath<t.ExpressionStatement>;
629
const expression = stmt.get("expression");
630
const value = lowerExpression(builder, expression);
631
- if (expression.isAssignmentExpression() && value.kind === "Identifier") {
631
+ if (expression.isAssignmentExpression() && value.kind === "LoadLocal") {
632
// already lowered to a place
633
return;
634
}
@@ -721,7 +721,12 @@ function lowerExpression(
721
switch (exprNode.type) {
722
case "Identifier": {
723
const expr = exprPath as NodePath<t.Identifier>;
724
- return lowerIdentifier(builder, expr);
724
+ const place = lowerIdentifier(builder, expr);
725
+ return {
726
+ kind: "LoadLocal",
727
+ place,
728
+ loc: exprLoc,
729
+ };
730
}
731
case "NullLiteral": {
732
return {
@@ -958,7 +963,11 @@ function lowerExpression(
963
});
964
return { kind: "UnsupportedNode", node: expr.node, loc: exprLoc };
965
}
961
- return last;
966
+ return {
967
+ kind: "LoadLocal", // TODO: LoadTemp
968
+ place: last,
969
+ loc: last.loc,
970
+ };
971
}
972
case "ConditionalExpression": {
973
const expr = exprPath as NodePath<t.ConditionalExpression>;
@@ -974,7 +983,7 @@ function lowerExpression(
983
builder.push({
984
id: makeInstructionId(0),
985
lvalue: { kind: InstructionKind.Reassign, place: { ...place } },
977
- value: lowerExpressionToTemporary(builder, expr.get("consequent")),
986
+ value: lowerExpression(builder, expr.get("consequent")),
987
loc: exprLoc,
988
});
989
return {
@@ -989,7 +998,7 @@ function lowerExpression(
998
builder.push({
999
id: makeInstructionId(0),
1000
lvalue: { kind: InstructionKind.Reassign, place: { ...place } },
992
- value: lowerExpressionToTemporary(builder, expr.get("alternate")),
1001
+ value: lowerExpression(builder, expr.get("alternate")),
1002
loc: exprLoc,
1003
});
1004
return {
@@ -1021,7 +1030,7 @@ function lowerExpression(
1030
},
1031
continuationBlock
1032
);
1024
- return place;
1033
+ return { kind: "LoadLocal", place, loc: place.loc };
1034
}
1035
case "LogicalExpression": {
1036
const expr = exprPath as NodePath<t.LogicalExpression>;
@@ -1037,7 +1046,11 @@ function lowerExpression(
1046
builder.push({
1047
id: makeInstructionId(0),
1048
lvalue: { kind: InstructionKind.Reassign, place: { ...place } },
1040
- value: { ...leftPlace },
1049
+ value: {
1050
+ kind: "LoadLocal",
1051
+ place: { ...leftPlace },
1052
+ loc: leftPlace.loc,
1053
+ },
1054
loc: exprLoc,
1055
});
1056
return {
@@ -1051,7 +1064,7 @@ function lowerExpression(
1064
builder.push({
1065
id: makeInstructionId(0),
1066
lvalue: { kind: InstructionKind.Reassign, place: { ...place } },
1054
- value: lowerExpressionToTemporary(builder, expr.get("right")),
1067
+ value: lowerExpression(builder, expr.get("right")),
1068
loc: exprLoc,
1069
});
1070
return {
@@ -1075,7 +1088,7 @@ function lowerExpression(
1088
builder.push({
1089
id: makeInstructionId(0),
1090
lvalue: { kind: InstructionKind.Reassign, place: { ...leftPlace } },
1078
- value: lowerExpressionToTemporary(builder, expr.get("left")),
1091
+ value: lowerExpression(builder, expr.get("left")),
1092
loc: exprLoc,
1093
});
1094
builder.terminateWithContinuation(
@@ -1088,7 +1101,7 @@ function lowerExpression(
1101
},
1102
continuationBlock
1103
);
1091
- return place;
1104
+ return { kind: "LoadLocal", place, loc: place.loc };
1105
}
1106
case "AssignmentExpression": {
1107
const expr = exprPath as NodePath<t.AssignmentExpression>;
@@ -1096,7 +1109,7 @@ function lowerExpression(
1109
1110
if (builder.currentBlockKind() === "value") {
1111
// try lowering the RHS in case it also contains errors
1099
- lowerExpressionToTemporary(builder, expr.get("right"));
1112
+ lowerExpression(builder, expr.get("right"));
1113
builder.errors.push({
1114
reason: `(BuildHIR::lowerExpression) Handle AssignmentExpression within a LogicalExpression or ConditionalExpression`,
1115
severity: ErrorSeverity.Todo,
@@ -1112,8 +1125,7 @@ function lowerExpression(
1125
left.node.loc ?? GeneratedSource,
1126
InstructionKind.Reassign,
1127
left,
1115
- // NOTE: it's okay not to lower to a temporary here because this is the entire RHS value, not a single operand
1116
- lowerExpressionToPlace(builder, expr.get("right"))
1128
+ lowerExpression(builder, expr.get("right"))
1129
);
1130
}
1131
@@ -1159,7 +1171,7 @@ function lowerExpression(
1171
},
1172
loc: exprLoc,
1173
});
1162
- return place;
1174
+ return { kind: "LoadLocal", place, loc: exprLoc };
1175
}
1176
case "MemberExpression": {
1177
// a.b.c += <right>
@@ -1243,7 +1255,7 @@ function lowerExpression(
1255
value,
1256
loc: exprLoc,
1257
});
1246
- return place;
1258
+ return { kind: "LoadLocal", place, loc: place.loc };
1259
}
1260
case "JSXElement": {
1261
const expr = exprPath as NodePath<t.JSXElement>;
@@ -1496,21 +1508,27 @@ function lowerExpression(
1508
},
1509
loc: expr.node.loc ?? GeneratedSource,
1510
});
1499
- const identifier = argument as NodePath<t.Identifier>;
1500
- const place = lowerIdentifier(builder, identifier);
1511
+ const identifier = lowerIdentifier(
1512
+ builder,
1513
+ argument as NodePath<t.Identifier>
1514
+ );
1515
builder.push({
1516
id: makeInstructionId(0),
1503
- lvalue: { place: { ...place }, kind: InstructionKind.Reassign },
1517
+ lvalue: { place: { ...identifier }, kind: InstructionKind.Reassign },
1518
value: {
1519
kind: "BinaryExpression",
1520
operator: expr.node.operator === "++" ? "+" : "-",
1507
- left: { ...place },
1521
+ left: { ...identifier },
1522
right: { ...temp },
1523
loc: exprLoc,
1524
},
1525
loc: exprLoc,
1526
});
1513
- return place;
1527
+ return {
1528
+ kind: "LoadLocal",
1529
+ place: { ...identifier },
1530
+ loc: exprLoc,
1531
+ };
1532
}
1533
default: {
1534
builder.errors.push({
@@ -1703,8 +1721,8 @@ function lowerExpressionToTemporary(
1721
exprPath: NodePath<t.Expression>
1722
): Place {
1723
const value = lowerExpression(builder, exprPath);
1706
- if (value.kind === "Identifier" && value.identifier.name === null) {
1707
- return value;
1724
+ if (value.kind === "LoadLocal" && value.place.identifier.name === null) {
1725
+ return value.place;
1726
}
1727
const exprLoc = exprPath.node.loc ?? GeneratedSource;
1728
const place: Place = buildTemporaryPlace(builder, exprLoc);
@@ -1722,8 +1740,8 @@ function lowerExpressionToPlace(
1740
exprPath: NodePath<t.Expression>
1741
): Place {
1742
const value = lowerExpression(builder, exprPath);
1725
- if (value.kind === "Identifier") {
1726
- return value;
1743
+ if (value.kind === "LoadLocal") {
1744
+ return value.place;
1745
}
1746
const exprLoc = exprPath.node.loc ?? GeneratedSource;
1747
const place: Place = buildTemporaryPlace(builder, exprLoc);
@@ -1855,15 +1873,15 @@ function lowerAssignment(
1873
value,
1874
loc,
1875
});
1858
- return place;
1876
+ return { kind: "LoadLocal", place, loc: place.loc };
1877
}
1878
case "MemberExpression": {
1879
const lvalue = lvaluePath as NodePath<t.MemberExpression>;
1880
const property = lvalue.get("property");
1881
const object = lowerExpressionToTemporary(builder, lvalue.get("object"));
1882
let valuePlace: Place;
1865
- if (value.kind === "Identifier") {
1866
- valuePlace = value;
1883
+ if (value.kind === "LoadLocal") {
1884
+ valuePlace = value.place;
1885
} else {
1886
valuePlace = buildTemporaryPlace(builder, loc);
1887
builder.push({
@@ -1958,7 +1976,7 @@ function lowerAssignment(
1976
}
1977
return hasError
1978
? { kind: "UnsupportedNode", node: lvalueNode, loc }
1961
- : arrayPlace;
1979
+ : { kind: "LoadLocal", place: arrayPlace, loc: arrayPlace.loc };
1980
}
1981
case "ObjectPattern": {
1982
const lvalue = lvaluePath as NodePath<t.ObjectPattern>;
@@ -2013,7 +2031,7 @@ function lowerAssignment(
2031
}
2032
return hasError
2033
? { kind: "UnsupportedNode", node: lvalueNode, loc }
2016
- : objectPlace;
2034
+ : { kind: "LoadLocal", place: objectPlace, loc: objectPlace.loc };
2035
}
2036
default: {
2037
builder.errors.push({
compiler/forget/src/HIR/HIR.ts
+5
-1
@@ -396,7 +396,11 @@ export type Phi = {
396
* Operands are therefore always a Place.
397
*/
398
export type InstructionValue =
399
- | Place
399
+ | {
400
+ kind: "LoadLocal";
401
+ place: Place;
402
+ loc: SourceLocation;
403
+ }
404
| {
405
kind: "Primitive";
406
value: number | boolean | string | null | undefined;
compiler/forget/src/HIR/MergeConsecutiveBlocks.ts
+7
-3
@@ -69,9 +69,13 @@ export function mergeConsecutiveBlocks(fn: HIRFunction): void {
69
kind: InstructionKind.Const,
70
},
71
value: {
72
- kind: "Identifier",
73
- identifier: operand,
74
- effect: Effect.Read,
72
+ kind: "LoadLocal",
73
+ place: {
74
+ kind: "Identifier",
75
+ identifier: operand,
76
+ effect: Effect.Read,
77
+ loc: GeneratedSource,
78
+ },
79
loc: GeneratedSource,
80
},
81
loc: GeneratedSource,
compiler/forget/src/HIR/PrintHIR.ts
+2
-2
@@ -304,8 +304,8 @@ export function printInstructionValue(instrValue: ReactiveValue): string {
304
value = `UnsupportedNode(${generate(instrValue.node).code})`;
305
break;
306
}
307
- case "Identifier": {
308
- value = printPlace(instrValue);
307
+ case "LoadLocal": {
308
+ value = `LoadLocal ${printPlace(instrValue.place)}`;
309
break;
310
}
311
case "PropertyLoad": {
compiler/forget/src/HIR/visitors.ts
+4
-4
@@ -48,8 +48,8 @@ export function* eachInstructionValueOperand(
48
yield* instrValue.args;
49
break;
50
}
51
- case "Identifier": {
52
- yield instrValue;
51
+ case "LoadLocal": {
52
+ yield instrValue.place;
53
break;
54
}
55
case "PropertyLoad": {
@@ -177,8 +177,8 @@ export function mapInstructionOperands(
177
instrValue.value = fn(instrValue.value);
178
break;
179
}
180
- case "Identifier": {
181
- instr.value = fn(instrValue);
180
+ case "LoadLocal": {
181
+ instrValue.place = fn(instrValue.place);
182
break;
183
}
184
case "NewExpression":
compiler/forget/src/Inference/AnalyseFunctions.ts
+2
-2
@@ -62,9 +62,9 @@ export default function analyseFunctions(func: HIRFunction) {
62
);
63
break;
64
}
65
- case "Identifier": {
65
+ case "LoadLocal": {
66
if (instr.lvalue.place.identifier.name === null) {
67
- state.declareTemporary(instr.lvalue.place, instr.value);
67
+ state.declareTemporary(instr.lvalue.place, instr.value.place);
68
}
69
break;
70
}
compiler/forget/src/Inference/DropMemoCalls.ts
+7
-3
@@ -40,9 +40,13 @@ export default function (func: HIRFunction) {
40
// after:
41
// foo = $19
42
instr.value = {
43
- kind: "Identifier",
44
- identifier: fn.identifier,
45
- effect: Effect.Unknown,
43
+ kind: "LoadLocal",
44
+ place: {
45
+ kind: "Identifier",
46
+ identifier: fn.identifier,
47
+ effect: Effect.Unknown,
48
+ loc: instr.value.loc,
49
+ },
50
loc: instr.value.loc,
51
};
52
}
compiler/forget/src/Inference/InferAlias.ts
+3
-3
@@ -33,11 +33,11 @@ function inferInstr(instr: Instruction, state: AliasAnalyser) {
33
const { lvalue, value: instrValue } = instr;
34
let alias: Place | null = null;
35
switch (instrValue.kind) {
36
- case "Identifier": {
37
- if (isPrimitiveType(instrValue.identifier)) {
36
+ case "LoadLocal": {
37
+ if (isPrimitiveType(instrValue.place.identifier)) {
38
return;
39
}
40
- alias = instrValue;
40
+ alias = instrValue.place;
41
break;
42
}
43
case "ComputedLoad":
compiler/forget/src/Inference/InferReferenceEffects.ts
+4
-4
@@ -188,7 +188,7 @@ class InferenceState {
188
*/
189
initialize(value: InstructionValue, kind: ValueKind) {
190
invariant(
191
- value.kind !== "Identifier",
191
+ value.kind !== "LoadLocal",
192
"Expected all top-level identifiers to be defined as variables, not values"
193
);
194
this.#values.set(value, kind);
@@ -782,12 +782,12 @@ function inferBlock(
782
state.alias(lvalue.place, instrValue.value);
783
continue;
784
}
785
- case "Identifier": {
786
- state.reference(instrValue, Effect.Capture);
785
+ case "LoadLocal": {
786
+ state.reference(instrValue.place, Effect.Capture);
787
const lvalue = instr.lvalue;
788
lvalue.place.effect = Effect.Mutate;
789
// direct aliasing: `a = b`;
790
- state.alias(lvalue.place, instrValue);
790
+ state.alias(lvalue.place, instrValue.place);
791
continue;
792
}
793
default: {
compiler/forget/src/Optimization/ConstantPropagation.ts
+2
-2
@@ -308,8 +308,8 @@ function evaluateInstruction(
308
}
309
return null;
310
}
311
- case "Identifier": {
312
- return read(constants, value);
311
+ case "LoadLocal": {
312
+ return read(constants, value.place);
313
}
314
default: {
315
// TODO: handle more cases
compiler/forget/src/Optimization/DeadCodeElimination.ts
+1
-1
@@ -100,7 +100,7 @@ function pruneableValue(value: InstructionValue): boolean {
100
case "ComputedLoad":
101
case "ComputedStore":
102
case "FunctionExpression":
103
- case "Identifier":
103
+ case "LoadLocal":
104
case "JsxExpression":
105
case "JsxFragment":
106
case "JSXText":
compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts
+5
-1
@@ -484,7 +484,11 @@ class Driver {
484
return {
485
block: defaultBlock.id,
486
place: defaultBlock.terminal.test,
487
- value: defaultBlock.terminal.test,
487
+ value: {
488
+ kind: "LoadLocal",
489
+ place: defaultBlock.terminal.test,
490
+ loc: defaultBlock.terminal.test.loc,
491
+ },
492
id: defaultBlock.terminal.id,
493
};
494
} else if (defaultBlock.instructions.length === 1) {
compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts
+3
-3
@@ -696,8 +696,8 @@ function codegenInstructionValue(
696
);
697
break;
698
}
699
- case "Identifier": {
700
- value = codegenPlace(cx, instrValue);
699
+ case "LoadLocal": {
700
+ value = codegenPlace(cx, instrValue.place);
701
break;
702
}
703
case "FunctionExpression": {
@@ -714,7 +714,7 @@ function codegenInstructionValue(
714
}
715
case "TypeCastExpression": {
716
value = t.typeCastExpression(
717
- codegenInstructionValue(cx, instrValue.value),
717
+ codegenPlace(cx, instrValue.value),
718
instrValue.type
719
);
720
break;
compiler/forget/src/ReactiveScopes/InferReactiveScopeVariables.ts
+1
-1
@@ -171,7 +171,7 @@ function mayAllocate(value: InstructionValue): boolean {
171
case "LoadGlobal":
172
case "TypeCastExpression":
173
case "BinaryExpression":
174
- case "Identifier":
174
+ case "LoadLocal":
175
case "PropertyLoad":
176
case "ComputedLoad":
177
case "JSXText":
compiler/forget/src/ReactiveScopes/PromoteUsedTemporaries.ts
+1
-1
@@ -57,7 +57,7 @@ class Visitor extends ReactiveFunctionVisitor<VisitorState> {
57
if (
58
instruction.lvalue !== null &&
59
instruction.lvalue.place.identifier.name === null &&
60
- instruction.value.kind !== "Identifier"
60
+ instruction.value.kind !== "LoadLocal"
61
) {
62
state.temporaries.set(instruction.lvalue.place.identifier, 0);
63
}
compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts
+4
-4
@@ -676,14 +676,14 @@ function visitInstructionValue(
676
value: ReactiveValue,
677
lvalue: LValue | null
678
): void {
679
- if (value.kind === "Identifier" && lvalue !== null) {
679
+ if (value.kind === "LoadLocal" && lvalue !== null) {
680
if (
681
- value.identifier.name !== null &&
681
+ value.place.identifier.name !== null &&
682
lvalue.place.identifier.name === null
683
) {
684
- context.declareTemporary(lvalue.place, value);
684
+ context.declareTemporary(lvalue.place, value.place);
685
} else {
686
- context.visitOperand(value);
686
+ context.visitOperand(value.place);
687
}
688
} else if (value.kind === "PropertyLoad") {
689
if (lvalue !== null) {
compiler/forget/src/ReactiveScopes/visitors.ts
+4
-4
@@ -91,12 +91,12 @@ export class ReactiveFunctionVisitor<TState = void> {
91
}
92
case "return": {
93
if (terminal.value !== null) {
94
- this.visitValue(terminal.id, terminal.value, state);
94
+ this.visitPlace(terminal.id, terminal.value, state);
95
}
96
break;
97
}
98
case "throw": {
99
- this.visitValue(terminal.id, terminal.value, state);
99
+ this.visitPlace(terminal.id, terminal.value, state);
100
break;
101
}
102
case "for": {
@@ -112,7 +112,7 @@ export class ReactiveFunctionVisitor<TState = void> {
112
break;
113
}
114
case "if": {
115
- this.visitValue(terminal.id, terminal.test, state);
115
+ this.visitPlace(terminal.id, terminal.test, state);
116
this.visitBlock(terminal.consequent, state);
117
if (terminal.alternate !== null) {
118
this.visitBlock(terminal.alternate, state);
@@ -120,7 +120,7 @@ export class ReactiveFunctionVisitor<TState = void> {
120
break;
121
}
122
case "switch": {
123
- this.visitValue(terminal.id, terminal.test, state);
123
+ this.visitPlace(terminal.id, terminal.test, state);
124
for (const case_ of terminal.cases) {
125
if (case_.test !== null) {
126
this.visitPlace(terminal.id, case_.test, state);
compiler/forget/src/SSA/LeaveSSA.ts
+7
-3
@@ -240,9 +240,13 @@ export function leaveSSA(fn: HIRFunction): void {
240
value:
241
initOperand !== null
242
? {
243
- kind: "Identifier",
244
- identifier: initOperand,
245
- effect: Effect.Read,
243
+ kind: "LoadLocal",
244
+ place: {
245
+ kind: "Identifier",
246
+ identifier: initOperand,
247
+ effect: Effect.Read,
248
+ loc: GeneratedSource,
249
+ },
250
loc: GeneratedSource,
251
}
252
: {
compiler/forget/src/TypeInference/InferTypes.ts
+2
-2
@@ -107,8 +107,8 @@ function* generateInstructionTypes(
107
break;
108
}
109
110
- case "Identifier": {
111
- yield equation(left, value.identifier.type);
110
+ case "LoadLocal": {
111
+ yield equation(left, value.place.identifier.type);
112
break;
113
}
114
compiler/forget/src/__tests__/fixtures/hir/assignment-in-nested-if.expect.md
+3
-5
@@ -24,14 +24,12 @@ function useBar(props) {
24
let z = undefined;
25
if (props.a) {
26
if (props.b) {
27
- let t0;
27
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
29
- t0 = baz();
30
- $[0] = t0;
28
+ z = baz();
29
+ $[0] = z;
30
} else {
32
- t0 = $[0];
31
+ z = $[0];
32
}
34
- z = t0;
33
}
34
}
35
return z;
compiler/forget/src/__tests__/fixtures/hir/capturing-function-within-block.expect.md
+4
-5
@@ -30,17 +30,16 @@ function component(a) {
30
z = $[1];
31
}
32
const c_2 = $[2] !== z;
33
- let t0;
33
+ let x;
34
if (c_2) {
35
- t0 = function () {
35
+ x = function () {
36
z;
37
};
38
$[2] = z;
39
- $[3] = t0;
39
+ $[3] = x;
40
} else {
41
- t0 = $[3];
41
+ x = $[3];
42
}
43
- const x = t0;
43
return x;
44
}
45
compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md
+3
-5
@@ -33,14 +33,12 @@ function Component(props) {
33
if (cond) {
34
a = x;
35
} else {
36
- let t0;
36
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
38
- t0 = [];
39
- $[0] = t0;
37
+ a = [];
38
+ $[0] = a;
39
} else {
41
- t0 = $[0];
40
+ a = $[0];
41
}
43
- a = t0;
42
}
43
44
useFreeze(a);
compiler/forget/src/__tests__/fixtures/hir/obj-literal-cached-in-if-else.expect.md
+6
-10
@@ -23,26 +23,22 @@ function foo(a, b, c, d) {
23
let x = undefined;
24
if (someVal) {
25
const c_0 = $[0] !== b;
26
- let t0;
26
if (c_0) {
28
- t0 = { b: b };
27
+ x = { b: b };
28
$[0] = b;
30
- $[1] = t0;
29
+ $[1] = x;
30
} else {
32
- t0 = $[1];
31
+ x = $[1];
32
}
34
- x = t0;
33
} else {
34
const c_2 = $[2] !== c;
37
- let t1;
35
if (c_2) {
39
- t1 = { c: c };
36
+ x = { c: c };
37
$[2] = c;
41
- $[3] = t1;
38
+ $[3] = x;
39
} else {
43
- t1 = $[3];
40
+ x = $[3];
41
}
45
- x = t1;
42
}
43
return x;
44
}
compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md
+8
-10
@@ -36,29 +36,27 @@ function Component(props) {
36
}
37
const y = x;
38
if (props.p1) {
39
- let t0;
39
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
41
- t0 = [];
42
- $[2] = t0;
40
+ x = [];
41
+ $[2] = x;
42
} else {
44
- t0 = $[2];
43
+ x = $[2];
44
}
46
- x = t0;
45
}
46
47
y.push(props.p2);
48
const c_3 = $[3] !== x;
49
const c_4 = $[4] !== y;
52
- let t1;
50
+ let t0;
51
if (c_3 || c_4) {
54
- t1 = <Component x={x} y={y}></Component>;
52
+ t0 = <Component x={x} y={y}></Component>;
53
$[3] = x;
54
$[4] = y;
57
- $[5] = t1;
55
+ $[5] = t0;
56
} else {
59
- t1 = $[5];
57
+ t0 = $[5];
58
}
61
- return t1;
59
+ return t0;
60
}
61
62
```
compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md
+8
-10
@@ -30,14 +30,12 @@ function Component(props) {
30
x = [];
31
x.push(props.p0);
32
y = x;
33
- let t0;
33
if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
35
- t0 = [];
36
- $[4] = t0;
34
+ x = [];
35
+ $[4] = x;
36
} else {
38
- t0 = $[4];
37
+ x = $[4];
38
}
40
- x = t0;
39
40
y.push(props.p1);
41
$[0] = props.p0;
@@ -50,16 +48,16 @@ function Component(props) {
48
}
49
const c_5 = $[5] !== x;
50
const c_6 = $[6] !== y;
53
- let t1;
51
+ let t0;
52
if (c_5 || c_6) {
55
- t1 = <Component x={x} y={y}></Component>;
53
+ t0 = <Component x={x} y={y}></Component>;
54
$[5] = x;
55
$[6] = y;
58
- $[7] = t1;
56
+ $[7] = t0;
57
} else {
60
- t1 = $[7];
58
+ t0 = $[7];
59
}
62
- return t1;
60
+ return t0;
61
}
62
63
```
compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md
+8
-10
@@ -45,14 +45,12 @@ function Component(props) {
45
}
46
case true: {
47
x.push(props.p2);
48
- let t0;
48
if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
50
- t0 = [];
51
- $[3] = t0;
49
+ y = [];
50
+ $[3] = y;
51
} else {
53
- t0 = $[3];
52
+ y = $[3];
53
}
55
- y = t0;
54
break bb1;
55
}
56
default: {
@@ -81,16 +79,16 @@ function Component(props) {
79
y.push(props.p4);
80
const c_6 = $[6] !== y;
81
const c_7 = $[7] !== child;
84
- let t1;
82
+ let t0;
83
if (c_6 || c_7) {
86
- t1 = <Component data={y}>{child}</Component>;
84
+ t0 = <Component data={y}>{child}</Component>;
85
$[6] = y;
86
$[7] = child;
89
- $[8] = t1;
87
+ $[8] = t0;
88
} else {
91
- t1 = $[8];
89
+ t0 = $[8];
90
}
93
- return t1;
91
+ return t0;
92
}
93
94
```