mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
feat(compiler): Implement constant folding for more binary expressions (#29650)
## Summary
There are already most arithmetic operators in constant propagation:
`+`, `-`, `*`, `/`.
We could add more, namely: `|`, `&`, `^`, `<<`, `>>`, `>>>` and `%`:
Input:
```js
function f() {
return [
123.45 | 0,
123.45 & 0,
123.45 ^ 0,
123 << 0,
123 >> 0,
123 >>> 0,
123.45 | 1,
123.45 & 1,
123.45 ^ 1,
123 << 1,
123 >> 1,
123 >>> 1,
3 ** 2,
3 ** 2.5,
3.5 ** 2,
2 ** 3 ** 0.5,
4 % 2,
4 % 2.5,
4 % 3,
4.5 % 2,
];
}
```
Output:
```js
function f() {
return [
123, 0, 123, 123, 123, 123, 123, 1, 122, 246, 61, 61, 9,
15.588457268119896, 12.25, 3.3219970854839125, 0, 1.5, 1, 0.5,
];
}
```
Resolves #29649
## How did you test this change?
See tests.
Note:
This PR was done without waiting for approval in #29649, so feel free to
just close it without any comment.
This commit is contained in:
@@ -369,6 +369,58 @@ function evaluateInstruction(
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "|": {
|
||||
if (typeof lhs === "number" && typeof rhs === "number") {
|
||||
result = { kind: "Primitive", value: lhs | rhs, loc: value.loc };
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "&": {
|
||||
if (typeof lhs === "number" && typeof rhs === "number") {
|
||||
result = { kind: "Primitive", value: lhs & rhs, loc: value.loc };
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "^": {
|
||||
if (typeof lhs === "number" && typeof rhs === "number") {
|
||||
result = { kind: "Primitive", value: lhs ^ rhs, loc: value.loc };
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "<<": {
|
||||
if (typeof lhs === "number" && typeof rhs === "number") {
|
||||
result = { kind: "Primitive", value: lhs << rhs, loc: value.loc };
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ">>": {
|
||||
if (typeof lhs === "number" && typeof rhs === "number") {
|
||||
result = { kind: "Primitive", value: lhs >> rhs, loc: value.loc };
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ">>>": {
|
||||
if (typeof lhs === "number" && typeof rhs === "number") {
|
||||
result = {
|
||||
kind: "Primitive",
|
||||
value: lhs >>> rhs,
|
||||
loc: value.loc,
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "%": {
|
||||
if (typeof lhs === "number" && typeof rhs === "number") {
|
||||
result = { kind: "Primitive", value: lhs % rhs, loc: value.loc };
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "**": {
|
||||
if (typeof lhs === "number" && typeof rhs === "number") {
|
||||
result = { kind: "Primitive", value: lhs ** rhs, loc: value.loc };
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "<": {
|
||||
if (typeof lhs === "number" && typeof rhs === "number") {
|
||||
result = { kind: "Primitive", value: lhs < rhs, loc: value.loc };
|
||||
|
||||
+1
-4
@@ -22,10 +22,7 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
```javascript
|
||||
function f() {
|
||||
let x;
|
||||
|
||||
x = 3 >>> 1;
|
||||
return x;
|
||||
return 1;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
import { Stringify } from "shared-runtime";
|
||||
|
||||
function foo() {
|
||||
return (
|
||||
<Stringify
|
||||
value={[
|
||||
123.45 | 0,
|
||||
123.45 & 0,
|
||||
123.45 ^ 0,
|
||||
123 << 0,
|
||||
123 >> 0,
|
||||
123 >>> 0,
|
||||
123.45 | 1,
|
||||
123.45 & 1,
|
||||
123.45 ^ 1,
|
||||
123 << 1,
|
||||
123 >> 1,
|
||||
123 >>> 1,
|
||||
3 ** 2,
|
||||
3 ** 2.5,
|
||||
3.5 ** 2,
|
||||
2 ** (3 ** 0.5),
|
||||
4 % 2,
|
||||
4 % 2.5,
|
||||
4 % 3,
|
||||
4.5 % 2,
|
||||
]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: foo,
|
||||
params: [],
|
||||
isComponent: false,
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
import { Stringify } from "shared-runtime";
|
||||
|
||||
function foo() {
|
||||
const $ = _c(1);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = (
|
||||
<Stringify
|
||||
value={[
|
||||
123, 0, 123, 123, 123, 123, 123, 1, 122, 246, 61, 61, 9,
|
||||
15.588457268119896, 12.25, 3.3219970854839125, 0, 1.5, 1, 0.5,
|
||||
]}
|
||||
/>
|
||||
);
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
return t0;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: foo,
|
||||
params: [],
|
||||
isComponent: false,
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
### Eval output
|
||||
(kind: ok) <div>{"value":[123,0,123,123,123,123,123,1,122,246,61,61,9,15.588457268119896,12.25,3.3219970854839125,0,1.5,1,0.5]}</div>
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
import { Stringify } from "shared-runtime";
|
||||
|
||||
function foo() {
|
||||
return (
|
||||
<Stringify
|
||||
value={[
|
||||
123.45 | 0,
|
||||
123.45 & 0,
|
||||
123.45 ^ 0,
|
||||
123 << 0,
|
||||
123 >> 0,
|
||||
123 >>> 0,
|
||||
123.45 | 1,
|
||||
123.45 & 1,
|
||||
123.45 ^ 1,
|
||||
123 << 1,
|
||||
123 >> 1,
|
||||
123 >>> 1,
|
||||
3 ** 2,
|
||||
3 ** 2.5,
|
||||
3.5 ** 2,
|
||||
2 ** (3 ** 0.5),
|
||||
4 % 2,
|
||||
4 % 2.5,
|
||||
4 % 3,
|
||||
4.5 % 2,
|
||||
]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: foo,
|
||||
params: [],
|
||||
isComponent: false,
|
||||
};
|
||||
Reference in New Issue
Block a user