[js] optimize function expressions by default

This mode improves compilation and makes optimizations easier, let's make it the 
default. I previously confirmed that enabling this mode didn't affect output 
when synced internally, and I'll do that again before landing the PR.
This commit is contained in:
Joe Savona
2023-07-11 13:06:13 +09:00
parent 830127f680
commit 61d7e6ae3d
67 changed files with 111 additions and 106 deletions
@@ -115,7 +115,7 @@ function parsePragma(pragma: string) {
let disableAllMemoization = false;
let validateRefAccessDuringRender = true;
let enableEmitFreeze = null;
let enableOptimizeFunctionExpressions = false;
let enableOptimizeFunctionExpressions = true;
let inlineUseMemo = true;
let validateHooksUsage = true;
let enableFunctionCallSignatureOptimizations = true;
@@ -137,8 +137,8 @@ function parsePragma(pragma: string) {
if (pragma.includes("@validateRefAccessDuringRender false")) {
validateRefAccessDuringRender = false;
}
if (pragma.includes("@enableOptimizeFunctionExpressions")) {
enableOptimizeFunctionExpressions = true;
if (pragma.includes("@enableOptimizeFunctionExpressions false")) {
enableOptimizeFunctionExpressions = false;
}
if (pragma.includes("@enableEmitFreeze")) {
enableEmitFreeze = {
@@ -229,7 +229,7 @@ export class Environment {
this.disableAllMemoization = config?.disableAllMemoization ?? false;
this.enableEmitFreeze = config?.enableEmitFreeze ?? null;
this.enableOptimizeFunctionExpressions =
config?.enableOptimizeFunctionExpressions ?? false;
config?.enableOptimizeFunctionExpressions ?? true;
this.assertValidMutableRanges = config?.assertValidMutableRanges ?? false;
this.#contextIdentifiers = contextIdentifiers;
@@ -27,7 +27,7 @@ function component(a) {
if (c_0) {
x = { a };
(function () {
let q = x;
const q = x;
(function () {
q.b = 1;
})();
@@ -52,18 +52,17 @@ function getNativeLogFunction(level) {
let t0;
if (c_0) {
t0 = function () {
let str;
let str = undefined;
if (arguments.length === 1 && typeof arguments[0] === "string") {
str = arguments[0];
} else {
str = Array.prototype.map
.call(arguments, function (arg) {
return inspect(arg, {
depth: 10,
});
return inspect(arg, { depth: 10 });
})
.join(", ");
}
const firstArg = arguments[0];
let logLevel = level;
if (
@@ -84,6 +83,7 @@ function getNativeLogFunction(level) {
if (groupStack.length) {
str = groupFormat("", str);
}
global.nativeLoggingHook(str, logLevel);
};
$[0] = level;
@@ -5,7 +5,7 @@
function component(a) {
let z = { a };
let x = () => {
z;
console.log(z);
};
return x;
}
@@ -32,7 +32,7 @@ function component(a) {
let t1;
if (c_2) {
t1 = () => {
z;
console.log(z);
};
$[2] = z;
$[3] = t1;
@@ -1,7 +1,7 @@
function component(a) {
let z = { a };
let x = () => {
z;
console.log(z);
};
return x;
}
@@ -29,8 +29,8 @@ function component(foo, bar) {
x = { foo };
const y = { bar };
(function () {
let a = { y };
let b = x;
const a = { y };
const b = x;
a.x = b;
})();
mutate(y);
@@ -29,8 +29,8 @@ function component(foo, bar) {
x = { foo };
const y = { bar };
(function () {
let a = [y];
let b = x;
const a = [y];
const b = x;
a.x = b;
})();
mutate(y);
@@ -29,8 +29,8 @@ function component(foo, bar) {
const x = { foo };
y = { bar };
(function () {
let a = [y];
let b = x;
const a = [y];
const b = x;
a.x = b;
})();
mutate(y);
@@ -29,8 +29,8 @@ function component(foo, bar) {
const x = { foo };
y = { bar };
(function () {
let a = { y };
let b = x;
const a = { y };
const b = x;
a.x = b;
})();
mutate(y);
@@ -26,7 +26,7 @@ function component(a) {
const x = { a };
y = {};
(function () {
y["x"] = x;
y.x = x;
})();
mutate(y);
$[0] = a;
@@ -27,8 +27,8 @@ function component(a) {
const x = { a };
y = {};
(function () {
let a_0 = y;
a_0["x"] = x;
const a_0 = y;
a_0.x = x;
})();
mutate(y);
$[0] = a;
@@ -27,7 +27,7 @@ function component(a) {
const x = { a };
y = {};
(function () {
let a_0 = y;
const a_0 = y;
a_0.x = x;
})();
mutate(y);
@@ -38,8 +38,8 @@ function component(a, b) {
z = { a };
const x = function () {
z.a = 2;
y.b;
};
x();
$[2] = a;
$[3] = y.b;
@@ -26,6 +26,7 @@ function component(a) {
const x = function () {
y.b.a = 2;
};
x();
$[0] = a;
$[1] = y;
@@ -7,7 +7,7 @@ function component(a, b) {
let y = { b };
let x = function () {
z.a = 2;
y.b;
console.log(y.b);
};
x();
return z;
@@ -29,8 +29,9 @@ function component(a, b) {
const y = { b };
const x = function () {
z.a = 2;
y.b;
console.log(y.b);
};
x();
$[0] = a;
$[1] = b;
@@ -3,7 +3,7 @@ function component(a, b) {
let y = { b };
let x = function () {
z.a = 2;
y.b;
console.log(y.b);
};
x();
return z;
@@ -5,7 +5,7 @@
function component(a) {
let z = { a };
let x = function () {
z;
console.log(z);
};
return x;
}
@@ -32,7 +32,7 @@ function component(a) {
let t1;
if (c_2) {
t1 = function () {
z;
console.log(z);
};
$[2] = z;
$[3] = t1;
@@ -1,7 +1,7 @@
function component(a) {
let z = { a };
let x = function () {
z;
console.log(z);
};
return x;
}
@@ -42,9 +42,6 @@ function component(a, b) {
if (c_2 || c_3) {
t1 = function () {
if (y) {
// we don't know for sure this mutates, so we should assume
// that there is no mutation so long as `x` isn't called
// during render
maybeMutate(z);
}
};
@@ -26,6 +26,7 @@ function component(a) {
const x = function x() {
t.foo();
};
x(t);
$[0] = a;
$[1] = t;
@@ -7,7 +7,7 @@ function component(a) {
let x;
{
x = function () {
z;
console.log(z);
};
}
return x;
@@ -35,7 +35,7 @@ function component(a) {
let t1;
if (c_2) {
t1 = function () {
z;
console.log(z);
};
$[2] = z;
$[3] = t1;
@@ -3,7 +3,7 @@ function component(a) {
let x;
{
x = function () {
z;
console.log(z);
};
}
return x;
@@ -5,7 +5,7 @@
function component(a) {
let z = { a };
let x = function () {
z.a;
console.log(z.a);
};
return x;
}
@@ -32,7 +32,7 @@ function component(a) {
let t1;
if (c_2) {
t1 = function () {
z.a;
console.log(z.a);
};
$[2] = z.a;
$[3] = t1;
@@ -1,7 +1,7 @@
function component(a) {
let z = { a };
let x = function () {
z.a;
console.log(z.a);
};
return x;
}
@@ -6,7 +6,7 @@ function component(a) {
let z = { a: { a } };
let x = function () {
(function () {
z.a.a;
console.log(z.a.a);
})();
};
return x;
@@ -44,7 +44,7 @@ function component(a) {
if (c_4) {
t2 = function () {
(function () {
z.a.a;
console.log(z.a.a);
})();
};
$[4] = z.a.a;
@@ -2,7 +2,7 @@ function component(a) {
let z = { a: { a } };
let x = function () {
(function () {
z.a.a;
console.log(z.a.a);
})();
};
return x;
@@ -5,7 +5,7 @@
function component(a) {
let z = { a: { a } };
let x = function () {
z.a.a;
console.log(z.a.a);
};
return x;
}
@@ -41,7 +41,7 @@ function component(a) {
let t2;
if (c_4) {
t2 = function () {
z.a.a;
console.log(z.a.a);
};
$[4] = z.a.a;
$[5] = t2;
@@ -1,7 +1,7 @@
function component(a) {
let z = { a: { a } };
let x = function () {
z.a.a;
console.log(z.a.a);
};
return x;
}
@@ -6,7 +6,7 @@ function component(a) {
let z = { a };
let x = function () {
{
z;
console.log(z);
}
};
return x;
@@ -34,9 +34,7 @@ function component(a) {
let t1;
if (c_2) {
t1 = function () {
{
z;
}
console.log(z);
};
$[2] = z;
$[3] = t1;
@@ -2,7 +2,7 @@ function component(a) {
let z = { a };
let x = function () {
{
z;
console.log(z);
}
};
return x;
@@ -6,7 +6,7 @@ function component(a) {
let z = { a };
let x = function () {
(function () {
z;
console.log(z);
})();
};
return x;
@@ -35,7 +35,7 @@ function component(a) {
if (c_2) {
t1 = function () {
(function () {
z;
console.log(z);
})();
};
$[2] = z;
@@ -2,7 +2,7 @@ function component(a) {
let z = { a };
let x = function () {
(function () {
z;
console.log(z);
})();
};
return x;
@@ -28,6 +28,7 @@ function Component() {
const foo = () => {
x = getObject();
};
foo();
$[0] = x;
$[1] = y;
@@ -5,7 +5,7 @@
function foo() {
const isX = GLOBAL_IS_X;
const getJSX = () => {
<Child x={isX}></Child>;
return <Child x={isX}></Child>;
};
const result = getJSX();
return result;
@@ -19,12 +19,9 @@ function foo() {
import { unstable_useMemoCache as useMemoCache } from "react";
function foo() {
const $ = useMemoCache(2);
const isX = GLOBAL_IS_X;
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = () => {
<Child x={isX}></Child>;
};
t0 = () => <Child x={GLOBAL_IS_X} />;
$[0] = t0;
} else {
t0 = $[0];
@@ -1,7 +1,7 @@
function foo() {
const isX = GLOBAL_IS_X;
const getJSX = () => {
<Child x={isX}></Child>;
return <Child x={isX}></Child>;
};
const result = getJSX();
return result;
@@ -17,10 +17,10 @@ function foo() {
```javascript
function foo() {
const x = 42;
const f = () => {
console.log(x);
console.log(42);
};
f();
return 42;
}
@@ -2,7 +2,6 @@
## Input
```javascript
// @enableOptimizeFunctionExpressions
function Component(props) {
const x = 42;
const onEvent = () => {
@@ -16,7 +15,7 @@ function Component(props) {
## Code
```javascript
import { unstable_useMemoCache as useMemoCache } from "react"; // @enableOptimizeFunctionExpressions
import { unstable_useMemoCache as useMemoCache } from "react";
function Component(props) {
const $ = useMemoCache(2);
let t0;
@@ -1,4 +1,3 @@
// @enableOptimizeFunctionExpressions
function Component(props) {
const x = 42;
const onEvent = () => {
@@ -27,6 +27,7 @@ function Component(props) {
onChange = (e) => {
console.log(x);
};
x = {};
$[0] = onChange;
} else {
@@ -25,6 +25,7 @@ function Component(p) {
const foo = () => {
x = {};
};
foo();
$[0] = x;
} else {
@@ -26,6 +26,7 @@ function Component() {
const foo = function foo() {
x = 9;
};
t0 = bar(foo);
$[0] = t0;
} else {
@@ -67,6 +67,7 @@ function Component(props) {
if (!comments.length) {
return;
}
console.log(comments.length);
};
$[7] = comments.length;
@@ -75,6 +76,7 @@ function Component(props) {
t4 = $[8];
}
onClick = t4;
allUrls.push(...urls);
$[0] = post;
$[1] = media;
@@ -38,8 +38,8 @@ function Component(props) {
if (c_0) {
const allUrls = [];
const { media: t84, comments, urls } = post;
media = t84;
const { media: t83, comments, urls } = post;
media = t83;
const c_3 = $[3] !== comments.length;
let t0;
if (c_3) {
@@ -47,6 +47,7 @@ function Component(props) {
if (!comments.length) {
return;
}
console.log(comments.length);
};
$[3] = comments.length;
@@ -55,6 +56,7 @@ function Component(props) {
t0 = $[4];
}
onClick = t0;
allUrls.push(...urls);
$[0] = post;
$[1] = media;
@@ -30,6 +30,7 @@ function component() {
let x;
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
x = t0;
x = {};
$[1] = x;
} else {
@@ -33,6 +33,7 @@ function component(a) {
t0 = $[2];
}
const x = t0;
x(t);
$[0] = a;
$[1] = t;
@@ -54,6 +54,7 @@ function CaptureNotMutate(props) {
const arr = { element };
return arr[idx];
};
aliasedElement = fn();
mutate(aliasedElement);
$[2] = props.el;
@@ -35,6 +35,7 @@ function Component() {
const fn = function () {
mutate(x_0);
};
fn();
return x;
}
@@ -36,6 +36,7 @@ function Component() {
const fn = function () {
x = x + 1;
};
fn();
$[0] = x;
} else {
@@ -36,6 +36,7 @@ function Component() {
const fn = function () {
x_0 = 42;
};
fn();
return x;
}
@@ -48,24 +48,22 @@ function Component() {
t0 = () => {
if (!someCondition) {
return fbt._("Purchase as a gift", null, { hk: "1gHj4g" });
} else if (
!iconOnly &&
showPrice &&
item?.current_gift_offer?.price?.formatted != null
) {
return fbt._(
"Gift | {price}",
[
fbt._param(
"price",
item?.current_gift_offer?.price?.formatted
),
],
{ hk: "3GTnGE" }
);
} else if (!iconOnly && !showPrice) {
return fbt._("Gift", null, { hk: "3fqfrk" });
} else {
if (
!iconOnly &&
showPrice &&
item?.current_gift_offer?.price?.formatted != null
) {
return fbt._(
"Gift | {price}",
[fbt._param("price", item?.current_gift_offer?.price?.formatted)],
{ hk: "3GTnGE" }
);
} else {
if (!iconOnly && !showPrice) {
return fbt._("Gift", null, { hk: "3fqfrk" });
}
}
}
};
$[0] = t0;
@@ -25,8 +25,7 @@ function Component(props) {
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = (e) => {
let x_0 = null; // intentionally shadow the original x
setX((currentX) => currentX + x_0); // intentionally refer to shadowed x
setX((currentX) => currentX + null);
};
$[0] = t0;
} else {
@@ -5,7 +5,7 @@
function component(a, b) {
let z = { a, b };
let x = function () {
z;
console.log(z);
};
return x;
}
@@ -34,7 +34,7 @@ function component(a, b) {
let t1;
if (c_3) {
t1 = function () {
z;
console.log(z);
};
$[3] = z;
$[4] = t1;
@@ -1,7 +1,7 @@
function component(a, b) {
let z = { a, b };
let x = function () {
z;
console.log(z);
};
return x;
}
@@ -25,6 +25,7 @@ function Component(props) {
const foo = () => {
x = {};
};
foo();
$[0] = x;
} else {
@@ -25,6 +25,7 @@ function Component(props) {
const foo = () => {
x = {};
};
foo();
$[0] = x;
} else {
@@ -2,7 +2,6 @@
## Input
```javascript
// @enableOptimizeFunctionExpressions
function Component(props) {
return () => {
let str;
@@ -20,7 +19,7 @@ function Component(props) {
## Code
```javascript
import { unstable_useMemoCache as useMemoCache } from "react"; // @enableOptimizeFunctionExpressions
import { unstable_useMemoCache as useMemoCache } from "react";
function Component(props) {
const $ = useMemoCache(2);
const c_0 = $[0] !== props.str;
@@ -1,4 +1,3 @@
// @enableOptimizeFunctionExpressions
function Component(props) {
return () => {
let str;
@@ -7,7 +7,7 @@ function VideoTab() {
const ref = useRef();
const t = ref.current;
let x = () => {
t;
console.log(t);
};
return <VideoList videos={x} />;
@@ -26,7 +26,7 @@ function VideoTab() {
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = () => {
t;
console.log(t);
};
$[0] = t0;
} else {
@@ -3,7 +3,7 @@ function VideoTab() {
const ref = useRef();
const t = ref.current;
let x = () => {
t;
console.log(t);
};
return <VideoList videos={x} />;
@@ -6,7 +6,7 @@
function VideoTab() {
const ref = useRef();
let x = () => {
ref.current.x;
console.log(ref.current.x);
};
return <VideoList videos={x} />;
@@ -24,7 +24,7 @@ function VideoTab() {
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = () => {
ref.current.x;
console.log(ref.current.x);
};
$[0] = t0;
} else {
@@ -2,7 +2,7 @@
function VideoTab() {
const ref = useRef();
let x = () => {
ref.current.x;
console.log(ref.current.x);
};
return <VideoList videos={x} />;
@@ -5,7 +5,7 @@
function VideoTab() {
const ref = useRef();
let x = () => {
ref.current;
console.log(ref.current);
};
return <VideoList videos={x} />;
@@ -23,7 +23,7 @@ function VideoTab() {
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = () => {
ref.current;
console.log(ref.current);
};
$[0] = t0;
} else {
@@ -1,7 +1,7 @@
function VideoTab() {
const ref = useRef();
let x = () => {
ref.current;
console.log(ref.current);
};
return <VideoList videos={x} />;
@@ -26,6 +26,7 @@ function Component(props) {
const onChange = (e) => {
setX(e.target.value);
};
const object = { x, onChange };
const { x: x_0, onChange: onChange_0 } = object;
@@ -26,7 +26,7 @@ function HomeDiscoStoreItemTileRating(props) {
count = 0;
const aggregates = item?.aggregates || [];
aggregates.forEach((aggregate) => {
count += aggregate.count || 0;
count = count + (aggregate.count || 0);
});
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
@@ -98,7 +98,7 @@ export async function compile(
let disableAllMemoization = false;
let validateRefAccessDuringRender = true;
let enableEmitFreeze = null;
let enableOptimizeFunctionExpressions = false;
let enableOptimizeFunctionExpressions = true;
if (firstLine.indexOf("@forgetDirective") !== -1) {
enableOnlyOnUseForgetDirective = true;
}
@@ -132,8 +132,8 @@ export async function compile(
if (firstLine.includes("@validateRefAccessDuringRender false")) {
validateRefAccessDuringRender = false;
}
if (firstLine.includes("@enableOptimizeFunctionExpressions")) {
enableOptimizeFunctionExpressions = true;
if (firstLine.includes("@enableOptimizeFunctionExpressions false")) {
enableOptimizeFunctionExpressions = false;
}
if (firstLine.includes("@enableEmitFreeze")) {
enableEmitFreeze = {