mirror of
https://github.com/facebookarchive/prepack.git
synced 2024-10-05 19:07:43 +03:00
Support optimized Array.filter and make filter-map compositions correct (#2582)
Summary: Adds optimized operator support for `Array.filter`, and makes compositions in which `Array.filter` is called on a mapped array correct. Aliasing information kept in the mapped array is exposed to the `Array.filter` call, which collects it in the resulting array. Resolves #2580 Pull Request resolved: https://github.com/facebook/prepack/pull/2582 Differential Revision: D10204091 Pulled By: sb98052 fbshipit-source-id: a365d3d7120cbae344c64c540e5b63a889b6c699
This commit is contained in:
parent
8ca388ab0e
commit
31697d5de0
@ -17,6 +17,7 @@ import {
|
||||
BoundFunctionValue,
|
||||
ConcreteValue,
|
||||
ECMAScriptSourceFunctionValue,
|
||||
NativeFunctionValue,
|
||||
NullValue,
|
||||
NumberValue,
|
||||
ObjectValue,
|
||||
@ -418,10 +419,25 @@ export default function(realm: Realm, obj: ObjectValue): void {
|
||||
if (thisArg) {
|
||||
args.push(thisArg);
|
||||
}
|
||||
let possibleNestedOptimizedFunctions;
|
||||
|
||||
// If callbackfn is a native function, it cannot be optimized, and cannot alias locations
|
||||
// other than ones accesible via global, which leaked value analysis disregards.
|
||||
if (!(callbackfn instanceof NativeFunctionValue)) {
|
||||
invariant(callbackfn instanceof ECMAScriptSourceFunctionValue || callbackfn instanceof BoundFunctionValue);
|
||||
possibleNestedOptimizedFunctions = [
|
||||
{
|
||||
func: callbackfn,
|
||||
thisValue: thisArg || realm.intrinsics.undefined,
|
||||
kind: "filter",
|
||||
},
|
||||
];
|
||||
}
|
||||
return ArrayValue.createTemporalWithWidenedNumericProperty(
|
||||
realm,
|
||||
args,
|
||||
createOperationDescriptor("UNKNOWN_ARRAY_METHOD_PROPERTY_CALL")
|
||||
createOperationDescriptor("UNKNOWN_ARRAY_METHOD_PROPERTY_CALL"),
|
||||
possibleNestedOptimizedFunctions
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -188,8 +188,12 @@ function createArrayWithWidenedNumericProperty(
|
||||
): ArrayValue {
|
||||
let abstractArrayValue = new ArrayValue(realm, intrinsicName);
|
||||
|
||||
if (possibleNestedOptimizedFunctions !== undefined && possibleNestedOptimizedFunctions.length > 0) {
|
||||
if (realm.arrayNestedOptimizedFunctionsEnabled && (!realm.react.enabled || realm.react.optimizeNestedFunctions)) {
|
||||
if (
|
||||
realm.arrayNestedOptimizedFunctionsEnabled &&
|
||||
(!realm.react.enabled || realm.react.optimizeNestedFunctions) &&
|
||||
possibleNestedOptimizedFunctions !== undefined
|
||||
) {
|
||||
if (possibleNestedOptimizedFunctions.length > 0) {
|
||||
evaluatePossibleNestedOptimizedFunctionsAndStoreEffects(
|
||||
realm,
|
||||
abstractArrayValue,
|
||||
|
@ -0,0 +1,19 @@
|
||||
// arrayNestedOptimizedFunctionsEnabled
|
||||
// does contain: return 42
|
||||
|
||||
function f(c) {
|
||||
var arr = Array.from(c);
|
||||
let obj = { foo: 42 };
|
||||
|
||||
function op(x) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
let mapped = arr.filter(op);
|
||||
mapped[0].foo = 0;
|
||||
|
||||
return obj.foo;
|
||||
}
|
||||
global.__optimize && __optimize(f);
|
||||
|
||||
inspect = () => f([0]);
|
@ -0,0 +1,24 @@
|
||||
// arrayNestedOptimizedFunctionsEnabled
|
||||
// does not contain: return 42
|
||||
|
||||
function f(c) {
|
||||
var arr = Array.from(c);
|
||||
let obj = { foo: 42 };
|
||||
|
||||
function op1(x) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
function op2(x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let mapped = arr.map(op1);
|
||||
let mapped2 = mapped.filter(op2);
|
||||
mapped2[0].foo = 0;
|
||||
|
||||
return obj.foo;
|
||||
}
|
||||
global.__optimize && __optimize(f);
|
||||
|
||||
inspect = () => f([0]);
|
@ -0,0 +1,18 @@
|
||||
// arrayNestedOptimizedFunctionsEnabled
|
||||
// does contain:return true
|
||||
|
||||
function f(c, g) {
|
||||
var arr = Array.from(c);
|
||||
let obj = { foo: true };
|
||||
|
||||
function op(x) {
|
||||
return obj.foo;
|
||||
}
|
||||
|
||||
let mapped = arr.filter(op);
|
||||
|
||||
return mapped;
|
||||
}
|
||||
global.__optimize && __optimize(f);
|
||||
|
||||
inspect = () => f([0], () => {});
|
Loading…
Reference in New Issue
Block a user