mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[hir] implement assignment expressions
Implements assignment expressions with operators other than `=` (such as `+=`) by lowering to an assignment. I think this isn't fully correct for something like `a.b.c += 1`, but it seems like there's more gaps in object accesses.
This commit is contained in:
@@ -901,13 +901,50 @@ function lowerExpression(
|
||||
case "AssignmentExpression": {
|
||||
const expr = exprPath as NodePath<t.AssignmentExpression>;
|
||||
const left = lowerLVal(builder, expr.get("left"));
|
||||
const right = lowerExpression(builder, expr.get("right"));
|
||||
const operator = expr.node.operator;
|
||||
todoInvariant(operator === "=", "todo: support non-simple assignment");
|
||||
|
||||
if (operator === "=") {
|
||||
const right = lowerExpression(builder, expr.get("right"));
|
||||
builder.push({
|
||||
id: 0,
|
||||
lvalue: { place: left, kind: InstructionKind.Reassign },
|
||||
value: right,
|
||||
loc: exprLoc,
|
||||
});
|
||||
return left;
|
||||
}
|
||||
|
||||
const operators: { [key: string]: t.BinaryExpression["operator"] } = {
|
||||
"+=": "+",
|
||||
"-=": "-",
|
||||
"/=": "/",
|
||||
"%=": "%",
|
||||
"*=": "*",
|
||||
"**=": "**",
|
||||
"&=": "&",
|
||||
"|=": "|",
|
||||
">>=": ">>",
|
||||
">>>=": ">>>",
|
||||
"<<=": "<<",
|
||||
"^=": "^",
|
||||
};
|
||||
const binaryOperator = operators[operator];
|
||||
invariant(
|
||||
binaryOperator != null,
|
||||
`Unhandled assignment operator '${operator}'`
|
||||
);
|
||||
|
||||
const right = lowerExpressionToPlace(builder, expr.get("right"));
|
||||
builder.push({
|
||||
id: 0,
|
||||
lvalue: { place: left, kind: InstructionKind.Reassign },
|
||||
value: right,
|
||||
value: {
|
||||
kind: "BinaryExpression",
|
||||
operator: binaryOperator,
|
||||
left,
|
||||
right,
|
||||
loc: exprLoc,
|
||||
},
|
||||
loc: exprLoc,
|
||||
});
|
||||
return left;
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function f() {
|
||||
let x = 1;
|
||||
x = x + 1;
|
||||
x += 1;
|
||||
x >>>= 1;
|
||||
}
|
||||
|
||||
function g(a) {
|
||||
a.b.c = a.b.c + 1;
|
||||
a.b.c *= 2;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## HIR
|
||||
|
||||
```
|
||||
bb0:
|
||||
[1] Let mutate x$5 = 1
|
||||
[2] Const mutate $6 = 1
|
||||
[3] Reassign mutate x$7 = Binary read x$5 + read $6
|
||||
[4] Const mutate $8 = 1
|
||||
[5] Reassign mutate x$9 = Binary read x$7 + read $8
|
||||
[6] Const mutate $10 = 1
|
||||
[7] Reassign mutate x$11 = Binary read x$9 >>> read $10
|
||||
Return
|
||||
```
|
||||
|
||||
### CFG
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
%% Basic Blocks
|
||||
subgraph bb0
|
||||
bb0_instrs["
|
||||
[1] Let mutate x$5 = 1
|
||||
[2] Const mutate $6 = 1
|
||||
[3] Reassign mutate x$7 = Binary read x$5 + read $6
|
||||
[4] Const mutate $8 = 1
|
||||
[5] Reassign mutate x$9 = Binary read x$7 + read $8
|
||||
[6] Const mutate $10 = 1
|
||||
[7] Reassign mutate x$11 = Binary read x$9 >>> read $10
|
||||
"]
|
||||
bb0_instrs --> bb0_terminal(["Return"])
|
||||
end
|
||||
|
||||
%% Jumps
|
||||
%% empty
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
function f$0() {
|
||||
let x$5 = 1;
|
||||
x$7 = x$5 + 1;
|
||||
x$9 = x$7 + 1;
|
||||
x$11 = x$9 >>> 1;
|
||||
return;
|
||||
}
|
||||
|
||||
```
|
||||
## HIR
|
||||
|
||||
```
|
||||
bb0:
|
||||
[1] Const mutate $5 = 1
|
||||
[2] Reassign mutate a$4.b.c[0:4] = Binary read a$4.b.c + read $5
|
||||
[3] Const mutate $6 = 2
|
||||
[4] Reassign mutate a$4.b.c[0:4] = Binary read a$4.b.c * read $6
|
||||
Return
|
||||
```
|
||||
|
||||
### CFG
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
%% Basic Blocks
|
||||
subgraph bb0
|
||||
bb0_instrs["
|
||||
[1] Const mutate $5 = 1
|
||||
[2] Reassign mutate a$4.b.c[0:4] = Binary read a$4.b.c + read $5
|
||||
[3] Const mutate $6 = 2
|
||||
[4] Reassign mutate a$4.b.c[0:4] = Binary read a$4.b.c * read $6
|
||||
"]
|
||||
bb0_instrs --> bb0_terminal(["Return"])
|
||||
end
|
||||
|
||||
%% Jumps
|
||||
%% empty
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
function g$0(a$4) {
|
||||
a$4 = a$4.b.c + 1;
|
||||
a$4 = a$4.b.c * 2;
|
||||
return;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
function f() {
|
||||
let x = 1;
|
||||
x = x + 1;
|
||||
x += 1;
|
||||
x >>>= 1;
|
||||
}
|
||||
|
||||
function g(a) {
|
||||
a.b.c = a.b.c + 1;
|
||||
a.b.c *= 2;
|
||||
}
|
||||
Reference in New Issue
Block a user