UNPKG

prepack

Version:

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

211 lines (170 loc) 10.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.prepackVersion = undefined; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /** * 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. */ /* APIs for running Prepack for code where a model of the environment is supplied as part of the code. */ exports.prepackSources = prepackSources; exports.prepackString = prepackString; exports.prepack = prepack; exports.prepackFromAst = prepackFromAst; var _index = require("./serializer/index.js"); var _index2 = _interopRequireDefault(_index); var _construct_realm = require("./construct_realm.js"); var _construct_realm2 = _interopRequireDefault(_construct_realm); var _globals = require("./globals.js"); var _globals2 = _interopRequireDefault(_globals); var _babelTypes = require("babel-types"); var t = _interopRequireWildcard(_babelTypes); var _index3 = require("./methods/index.js"); var _prepackOptions = require("./prepack-options"); var _errors = require("./errors.js"); var _completions = require("./completions.js"); var _options = require("./options"); var _invariant = require("./invariant.js"); var _invariant2 = _interopRequireDefault(_invariant); var _package = require("../package.json"); var _types = require("./serializer/types.js"); var _ResidualHeapVisitor = require("./serializer/ResidualHeapVisitor.js"); var _modules = require("./utils/modules.js"); var _logger = require("./utils/logger.js"); var _generator = require("./utils/generator.js"); var _index4 = require("./values/index.js"); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function prepackSources(sources, options = _options.defaultOptions, debugChannel = undefined) { let realmOptions = (0, _prepackOptions.getRealmOptions)(options); realmOptions.errorHandler = options.errorHandler; let realm = (0, _construct_realm2.default)(realmOptions, debugChannel); (0, _globals2.default)(realm); if (typeof options.additionalGlobals === "function") { options.additionalGlobals(realm); } if (options.check) { realm.generator = new _generator.Generator(realm, "main"); let logger = new _logger.Logger(realm, !!options.internalDebug); let modules = new _modules.Modules(realm, logger, new _types.SerializerStatistics(), !!options.logModules, !!options.delayUnsupportedRequires, !!options.accelerateUnsupportedRequires); let [result] = realm.$GlobalEnv.executeSources(sources); if (result instanceof _completions.AbruptCompletion) throw result; (0, _invariant2.default)(options.check); checkResidualFunctions(modules, options.check[0], options.check[1]); return { code: "", map: undefined }; } else if (options.serialize || !options.residual) { let serializer = new _index2.default(realm, (0, _prepackOptions.getSerializerOptions)(options)); let serialized = serializer.init(sources, options.sourceMaps); //Turn off the debugger if there is one if (realm.debuggerInstance) { realm.debuggerInstance.shutdown(); } if (!serialized) { throw new _errors.FatalError("serializer failed"); } if (!options.residual) return serialized; let residualSources = [{ filePath: options.outputFilename || "unknown", fileContents: serialized.code, sourceMapContents: serialized.map && JSON.stringify(serialized.map) }]; realm = (0, _construct_realm2.default)(realmOptions, debugChannel); (0, _globals2.default)(realm); if (typeof options.additionalGlobals === "function") { options.additionalGlobals(realm); } realm.generator = new _generator.Generator(realm, "main"); let result = realm.$GlobalEnv.executePartialEvaluator(residualSources, options); if (result instanceof _completions.AbruptCompletion) throw result; return _extends({}, result); } else { (0, _invariant2.default)(options.residual); realm.generator = new _generator.Generator(realm, "main"); let result = realm.$GlobalEnv.executePartialEvaluator(sources, options); if (result instanceof _completions.AbruptCompletion) throw result; return _extends({}, result); } } /* deprecated: please use prepackSources instead. */ function prepackString(filename, code, sourceMap, options = _options.defaultOptions) { return prepackSources([{ filePath: filename, fileContents: code, sourceMapContents: sourceMap }], options); } /* deprecated: please use prepackSources instead. */ function prepack(code, options = _options.defaultOptions) { let filename = options.filename || "unknown"; let sources = [{ filePath: filename, fileContents: code }]; let realmOptions = (0, _prepackOptions.getRealmOptions)(options); realmOptions.errorHandler = options.errorHandler; let realm = (0, _construct_realm2.default)(realmOptions); (0, _globals2.default)(realm); let serializer = new _index2.default(realm, (0, _prepackOptions.getSerializerOptions)(options)); let serialized = serializer.init(sources, options.sourceMaps); if (!serialized) { throw new _errors.FatalError("serializer failed"); } return serialized; } /* deprecated: please use prepackSources instead. */ function prepackFromAst(ast, code, options = _options.defaultOptions) { if (ast && ast.type === "Program") { ast = t.file(ast, [], []); } (0, _invariant2.default)(ast && ast.type === "File"); let filename = options.filename || ast.loc && ast.loc.source || "unknown"; let sources = [{ filePath: filename, fileContents: code }]; let realm = (0, _construct_realm2.default)((0, _prepackOptions.getRealmOptions)(options)); (0, _globals2.default)(realm); let serializer = new _index2.default(realm, (0, _prepackOptions.getSerializerOptions)(options)); let serialized = serializer.init(sources, options.sourceMaps); if (!serialized) { throw new _errors.FatalError("serializer failed"); } return serialized; } function checkResidualFunctions(modules, startFunc, totalToAnalyze) { let realm = modules.realm; let env = realm.$GlobalEnv; realm.$GlobalObject.makeSimple(); let errorHandler = realm.errorHandler; if (!errorHandler) errorHandler = diag => realm.handleError(diag); realm.errorHandler = diag => { (0, _invariant2.default)(errorHandler); if (diag.severity === "FatalError") return errorHandler(diag);else return "Recover"; }; modules.resolveInitializedModules(); let residualHeapVisitor = new _ResidualHeapVisitor.ResidualHeapVisitor(realm, modules.logger, modules, new Map(), "NO_REFERENTIALIZE"); residualHeapVisitor.visitRoots(); if (modules.logger.hasErrors()) return; let totalFunctions = 0; let nonFatalFunctions = 0; for (let fi of residualHeapVisitor.functionInstances.values()) { totalFunctions++; if (totalFunctions <= startFunc) continue; let fv = fi.functionValue; console.log("analyzing: " + totalFunctions); let thisValue = realm.intrinsics.null; let n = fv.getLength() || 0; let args = []; for (let i = 0; i < n; i++) { let name = "dummy parameter"; let ob = _index4.AbstractValue.createFromType(realm, _index4.ObjectValue, name); ob.makeSimple("transitive"); ob.intrinsicName = name; args[i] = ob; } // todo: eventually join these effects, apply them to the global state and iterate to a fixed point try { realm.evaluateForEffectsInGlobalEnv(() => (0, _index3.EvaluateDirectCallWithArgList)(modules.realm, true, env, fv, fv, thisValue, args)); nonFatalFunctions++; } catch (e) {} if (totalFunctions >= startFunc + totalToAnalyze) break; } console.log(`Analyzed ${totalToAnalyze} functions starting at ${startFunc} of which ${nonFatalFunctions} did not have fatal errors.`); } const prepackVersion = exports.prepackVersion = _package.version; //# sourceMappingURL=prepack-standalone.js.map