Enhance factorifyObjects() for --delayInitializations

Summary:
This PR enables factorifyObjects() for --delayInitializations body. Will look into later for --inlineExpressions
Closes https://github.com/facebook/prepack/pull/1042

Differential Revision: D6014974

Pulled By: yinghuitan

fbshipit-source-id: 08bfb289d9f92a1cde0ed648328cb198d55f9682
This commit is contained in:
Jeffrey Tan 2017-10-09 16:39:39 -07:00 committed by Facebook Github Bot
parent 93b6c3601f
commit 6e29ba7d1c
5 changed files with 59 additions and 15 deletions

View File

@ -17,6 +17,7 @@ import traverseFast from "../utils/traverse-fast.js";
import invariant from "../invariant.js";
import { voidExpression, nullExpression } from "../utils/internalizer.js";
import type { LocationService } from "./types.js";
import { factorifyObjects } from "./factorify.js";
// This class manages information about values
// which are only referenced by residual functions,
@ -118,6 +119,12 @@ export class ResidualFunctionInitializers {
return !!this.functionInitializerInfos.get(functionValue);
}
factorifyInitializers(nameGenerator: NameGenerator) {
for (const initializer of this.initializers.values()) {
factorifyObjects(initializer.body, nameGenerator);
}
}
getInitializerStatement(functionValue: FunctionValue): void | BabelNodeStatement {
let initializerInfo = this.functionInitializerInfos.get(functionValue);
if (initializerInfo === undefined) return undefined;

View File

@ -1274,6 +1274,7 @@ export class ResidualHeapSerializer {
this.emitter.finalize();
this.residualFunctions.residualFunctionInitializers.factorifyInitializers(this.factoryNameGenerator);
let { unstrictFunctionBodies, strictFunctionBodies, requireStatistics } = this.residualFunctions.spliceFunctions(
rewrittenAdditionalFunctions
);

View File

@ -92,19 +92,44 @@ function getObjectKeys(obj: BabelNodeObjectExpression): string | false {
export function factorifyObjects(body: Array<BabelNodeStatement>, factoryNameGenerator: NameGenerator) {
let signatures = Object.create(null);
let initializerAstNodeName = "init";
for (let node of body) {
if (node.type !== "VariableDeclaration") continue;
switch (node.type) {
case "VariableDeclaration":
for (let declar of node.declarations) {
let { init } = declar;
if (!init) continue;
if (init.type !== "ObjectExpression") continue;
for (let declar of node.declarations) {
let { init } = declar;
if (!init) continue;
if (init.type !== "ObjectExpression") continue;
let keys = getObjectKeys(init);
if (!keys) continue;
let keys = getObjectKeys(init);
if (!keys) continue;
let declars = (signatures[keys] = signatures[keys] || []);
declars.push(declar);
}
break;
let declars = (signatures[keys] = signatures[keys] || []);
declars.push(declar);
case "ExpressionStatement":
const expr = node.expression;
if (expr.type !== "AssignmentExpression") {
break;
}
const { right } = expr;
if (right.type !== "ObjectExpression") {
break;
}
let keys = getObjectKeys(right);
if (!keys) continue;
initializerAstNodeName = "right";
let declars = (signatures[keys] = signatures[keys] || []);
declars.push(node.expression);
break;
default:
// Continue to next node.
break;
}
}
@ -133,11 +158,11 @@ export function factorifyObjects(body: Array<BabelNodeStatement>, factoryNameGen
//
for (let declar of declars) {
let args = [];
for (let prop of declar.init.properties) {
for (let prop of declar[initializerAstNodeName].properties) {
args.push(prop.value);
}
declar.init = t.callExpression(rootFactoryId, args);
declar[initializerAstNodeName] = t.callExpression(rootFactoryId, args);
}
//
@ -154,7 +179,7 @@ export function factorifyObjects(body: Array<BabelNodeStatement>, factoryNameGen
let sharedArgs = [];
for (let i = 0; i < keys.length; i++) {
if (isSameNode(declar.init.arguments[i], declar2.init.arguments[i])) {
if (isSameNode(declar[initializerAstNodeName].arguments[i], declar2[initializerAstNodeName].arguments[i])) {
sharedArgs.push(i);
}
}
@ -192,7 +217,7 @@ export function factorifyObjects(body: Array<BabelNodeStatement>, factoryNameGen
let subFactoryArgs = [];
let subFactoryParams = [];
let sharedArgs = declarsSub[0].init.arguments;
let sharedArgs = declarsSub[0][initializerAstNodeName].arguments;
for (let i = 0; i < sharedArgs.length; i++) {
let arg = sharedArgs[i];
if (removeArgs.indexOf(i + "") >= 0) {
@ -212,7 +237,7 @@ export function factorifyObjects(body: Array<BabelNodeStatement>, factoryNameGen
for (let declarSub of declarsSub) {
seen.add(declarSub);
let call = declarSub.init;
let call = declarSub[initializerAstNodeName];
call.callee = subFactoryId;
call.arguments = call.arguments.filter(function(val, i) {
return removeArgs.indexOf(i + "") < 0;

View File

@ -1,3 +1,4 @@
// Copies of default: 2
(function() {
var a = {"default": 1};
var b = {"default": 2};
@ -6,4 +7,4 @@
var e = {"default": 5};
heap = [a,a,b,b,c,c,d,d,e,e];
inspect = function() { return heap[0]["default"]; }
})();
})();

View File

@ -0,0 +1,10 @@
// Copies of default: 2
(function() {
var a = {"default": 1, foo: 11};
var b = {"default": 2, foo: 12};
var c = {"default": 3, foo: 13};
var d = {"default": 4, foo: 14};
var e = {"default": 5, foo: 15};
var heap = [a,a,b,b,c,c,d,d,e,e];
inspect = function() { return heap[0]["default"]; }
})();