mirror of
https://github.com/facebookarchive/prepack.git
synced 2024-09-11 14:46:37 +03:00
Special case "x === undefined || x === null" kind of expressions (#2188)
Summary: Release note: special case expression simplification for Instant Render When instant render is enabled turn x === undefined || x === null into __cannotBecomeObject(x) so that Instant Render can easily compile it down to a single byte code. Closes https://github.com/facebook/prepack/pull/2188 Differential Revision: D8716594 Pulled By: hermanventer fbshipit-source-id: bbcb25462f79852d8deac29bfed62e86745e5589
This commit is contained in:
parent
67a47fd48f
commit
466d19ddfd
@ -318,6 +318,7 @@ function runTest(name, code, options: PrepackOptions, args) {
|
||||
options.invariantLevel = code.includes("// omit invariants") || args.verbose ? 0 : 99;
|
||||
if (code.includes("// emit concrete model")) options.emitConcreteModel = true;
|
||||
if (code.includes("// exceeds stack limit")) options.maxStackDepth = 10;
|
||||
if (code.includes("// instant render")) options.instantRender = true;
|
||||
if (code.includes("// react")) {
|
||||
options.reactEnabled = true;
|
||||
options.reactOutput = "jsx";
|
||||
|
@ -17,6 +17,7 @@ import { Realm } from "../realm.js";
|
||||
import { AbstractValue, BooleanValue, ConcreteValue, Value } from "../values/index.js";
|
||||
import { Path, To } from "../singletons.js";
|
||||
import EmptyValue from "../values/EmptyValue";
|
||||
import * as t from "babel-types";
|
||||
|
||||
export default function simplifyAndRefineAbstractValue(
|
||||
realm: Realm,
|
||||
@ -110,6 +111,33 @@ function simplify(realm, value: Value, isCondition: boolean = false): Value {
|
||||
!y.args[1].mightNotBeTrue()
|
||||
)
|
||||
return y;
|
||||
if (realm.instantRender.enabled) {
|
||||
if (op === "||" && x0 instanceof AbstractValue && y0 instanceof AbstractValue) {
|
||||
if (x0.kind === "===" && y0.kind === "===") {
|
||||
let [xa, xb] = x0.args;
|
||||
let [ya, yb] = y0.args;
|
||||
if (xa.equals(ya) && !xb.equals(yb) && nullOrUndefined(xb) && nullOrUndefined(yb)) return rewrite(xa);
|
||||
else if (xb.equals(yb) && !xa.equals(ya) && nullOrUndefined(xa) && nullOrUndefined(ya)) return rewrite(xb);
|
||||
else if (xa.equals(yb) && !xb.equals(ya) && nullOrUndefined(xb) && nullOrUndefined(ya)) return rewrite(xa);
|
||||
else if (xb.equals(ya) && !xa.equals(yb) && nullOrUndefined(xa) && nullOrUndefined(yb)) return rewrite(xb);
|
||||
function nullOrUndefined(z: Value) {
|
||||
return !z.mightNotBeNull() || !z.mightNotBeUndefined();
|
||||
}
|
||||
function rewrite(z: Value) {
|
||||
return AbstractValue.createFromBuildFunction(
|
||||
realm,
|
||||
BooleanValue,
|
||||
[xa],
|
||||
([n]) => {
|
||||
let callFunc = t.identifier("global.__cannotBecomeObject");
|
||||
return t.callExpression(callFunc, [n]);
|
||||
},
|
||||
{ kind: "global.__cannotBecomeObject(A)" }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (x.equals(x0) && y.equals(y0)) return value;
|
||||
return AbstractValue.createFromLogicalOp(realm, (value.kind: any), x, y, loc, isCondition, true);
|
||||
}
|
||||
|
@ -79,7 +79,8 @@ export type AbstractValueKind =
|
||||
| "global.JSON.parse(A)"
|
||||
| "JSON.stringify(...)"
|
||||
| "JSON.parse(...)"
|
||||
| "global.Math.imul(A, B)";
|
||||
| "global.Math.imul(A, B)"
|
||||
| "global.__cannotBecomeObject(A)";
|
||||
|
||||
// Use AbstractValue.makeKind to make a kind from one of these prefices.
|
||||
type AbstractValueKindPrefix =
|
||||
|
17
test/serializer/instant-render/NotNull.js
Normal file
17
test/serializer/instant-render/NotNull.js
Normal file
@ -0,0 +1,17 @@
|
||||
// instant render
|
||||
// add at runtime:global.__cannotBecomeObject = a => a === undefined || a === null;
|
||||
// does not contain:void 0
|
||||
|
||||
let a = global.__abstract ? __abstract(undefined, "(true)") : true;
|
||||
|
||||
let x1 = a === undefined || a === null;
|
||||
let x2 = a === undefined || null === a;
|
||||
let x3 = undefined === a || a === null;
|
||||
let x4 = undefined === a || null === a;
|
||||
|
||||
let x5 = a === null || a === undefined;
|
||||
let x6 = a === null || undefined === a;
|
||||
let x7 = null === a || a === undefined;
|
||||
let x8 = null === a || undefined === a;
|
||||
|
||||
global.inspect = function() { return [x1, x2, x3, x4, x5, x6, x7, x8].join(" "); }
|
Loading…
Reference in New Issue
Block a user