UNPKG

prepack

Version:

Execute a JS bundle, serialize global state and side effects to a snapshot that can be quickly restored.

131 lines (94 loc) 4.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ResidualOptimizedFunctions = void 0; var _index = require("../values/index.js"); var _invariant = _interopRequireDefault(require("../invariant.js")); var _GeneratorTree = require("./GeneratorTree"); var _environment = require("../environment"); var _generator = require("../utils/generator"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ class ResidualOptimizedFunctions { constructor(generatorTree, optimizedFunctionsAndEffects, residualValues) { this._generatorTree = generatorTree; this._optimizedFunctionsAndEffects = optimizedFunctionsAndEffects; this._residualValues = residualValues; } _isDefinedInsideFunction(childFunction, maybeParentFunctions) { for (let maybeParentFunction of maybeParentFunctions) { if (childFunction === maybeParentFunction) { continue; } // for optimized functions, we should use created objects let maybeParentFunctionInfo = this._optimizedFunctionsAndEffects.get(maybeParentFunction); if (maybeParentFunctionInfo && maybeParentFunctionInfo.effects.createdObjects.has(childFunction)) return true;else { // for other functions, check environment records let env = childFunction.$Environment; while (env.parent !== null) { let envRecord = env.environmentRecord; if (envRecord instanceof _environment.FunctionEnvironmentRecord && envRecord.$FunctionObject === maybeParentFunction) return true; env = env.parent; } } } return false; } // Check if an optimized function defines the given set of functions. _definesFunctions(possibleParentFunction, functions) { let maybeParentFunctionInfo = this._optimizedFunctionsAndEffects.get(possibleParentFunction); (0, _invariant.default)(maybeParentFunctionInfo); let createdObjects = maybeParentFunctionInfo.effects.createdObjects; for (let func of functions) if (func !== possibleParentFunction && !createdObjects.has(func)) return false; return true; } // Try and get the root optimized function when passed in an optimized function // that may or may not be nested in the tree of said root, or is the root optimized function tryGetOptimizedFunctionRoot(val) { let scopes = this._residualValues.get(val); (0, _invariant.default)(scopes !== undefined); return this.tryGetOutermostOptimizedFunction(scopes); } // Try and get the optimized function that contains all the scopes passed in (may be one of the // scopes passed in) tryGetOutermostOptimizedFunction(scopes) { let functionValues = new Set(); (0, _invariant.default)(scopes !== undefined); for (let scope of scopes) { let s = scope; while (s instanceof _generator.Generator) { s = this._generatorTree.getParent(s); } if (s === "GLOBAL") return undefined; (0, _invariant.default)(s instanceof _index.FunctionValue); functionValues.add(s); } let outermostAdditionalFunctions = new Set(); // Get the set of optimized functions that may be the root for (let functionValue of functionValues) { if (this._optimizedFunctionsAndEffects.has(functionValue)) { if (!this._isDefinedInsideFunction(functionValue, functionValues)) outermostAdditionalFunctions.add(functionValue); } else { let f = this.tryGetOptimizedFunctionRoot(functionValue); if (f === undefined) return undefined; if (!this._isDefinedInsideFunction(f, functionValues)) outermostAdditionalFunctions.add(f); } } if (outermostAdditionalFunctions.size === 1) return [...outermostAdditionalFunctions][0]; // See if any of the outermost (or any of their parents) are the outermost optimized function let possibleRoots = [...outermostAdditionalFunctions]; while (possibleRoots.length > 0) { let possibleRoot = possibleRoots.shift(); if (this._definesFunctions(possibleRoot, outermostAdditionalFunctions)) return possibleRoot; let additionalFunctionEffects = this._optimizedFunctionsAndEffects.get(possibleRoot); (0, _invariant.default)(additionalFunctionEffects); let parent = additionalFunctionEffects.parentAdditionalFunction; if (parent) possibleRoots.push(parent); } return undefined; } } exports.ResidualOptimizedFunctions = ResidualOptimizedFunctions; //# sourceMappingURL=ResidualOptimizedFunctions.js.map