625 lines
31 KiB
JavaScript
625 lines
31 KiB
JavaScript
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.Modules = exports.ModuleTracer = undefined;
|
|
|
|
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _environment = require("../environment.js");
|
|
|
|
var _errors = require("../errors.js");
|
|
|
|
var _realm = require("../realm.js");
|
|
|
|
var _index = require("../methods/index.js");
|
|
|
|
var _completions = require("../completions.js");
|
|
|
|
var _singletons = require("../singletons.js");
|
|
|
|
var _index2 = require("../values/index.js");
|
|
|
|
var _babelTypes = require("babel-types");
|
|
|
|
var t = _interopRequireWildcard(_babelTypes);
|
|
|
|
var _invariant = require("../invariant.js");
|
|
|
|
var _invariant2 = _interopRequireDefault(_invariant);
|
|
|
|
var _logger = require("./logger.js");
|
|
|
|
var _types = require("./types.js");
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
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 _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
|
|
* 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.
|
|
*/
|
|
|
|
function downgradeErrorsToWarnings(realm, f) {
|
|
var savedHandler = realm.errorHandler;
|
|
function handler(e) {
|
|
e.severity = "Warning";
|
|
realm.errorHandler = savedHandler;
|
|
try {
|
|
return realm.handleError(e);
|
|
} finally {
|
|
realm.errorHandler = handler;
|
|
}
|
|
}
|
|
realm.errorHandler = handler;
|
|
try {
|
|
return f();
|
|
} finally {
|
|
realm.errorHandler = savedHandler;
|
|
}
|
|
}
|
|
|
|
var ModuleTracer = exports.ModuleTracer = function (_Tracer) {
|
|
_inherits(ModuleTracer, _Tracer);
|
|
|
|
function ModuleTracer(modules, statistics, logModules) {
|
|
_classCallCheck(this, ModuleTracer);
|
|
|
|
var _this = _possibleConstructorReturn(this, (ModuleTracer.__proto__ || Object.getPrototypeOf(ModuleTracer)).call(this));
|
|
|
|
_this.modules = modules;
|
|
_this.evaluateForEffectsNesting = 0;
|
|
_this.requireStack = [];
|
|
_this.requireSequence = [];
|
|
_this.logModules = logModules;
|
|
_this.uninitializedModuleIdsRequiredInEvaluateForEffects = new Set();
|
|
_this.statistics = statistics;
|
|
return _this;
|
|
}
|
|
// We can't say that a module has been initialized if it was initialized in a
|
|
// evaluate for effects context until we know the effects are applied.
|
|
|
|
|
|
_createClass(ModuleTracer, [{
|
|
key: "log",
|
|
value: function log(message) {
|
|
if (this.logModules) console.log("[modules] " + this.requireStack.map(function (_) {
|
|
return " ";
|
|
}).join("") + message);
|
|
}
|
|
}, {
|
|
key: "beginEvaluateForEffects",
|
|
value: function beginEvaluateForEffects(state) {
|
|
if (state !== this) {
|
|
this.log(">evaluate for effects");
|
|
this.evaluateForEffectsNesting++;
|
|
this.requireStack.push(undefined);
|
|
}
|
|
}
|
|
}, {
|
|
key: "endEvaluateForEffects",
|
|
value: function endEvaluateForEffects(state, effects) {
|
|
if (state !== this) {
|
|
var popped = this.requireStack.pop();
|
|
(0, _invariant2.default)(popped === undefined);
|
|
this.evaluateForEffectsNesting--;
|
|
this.log("<evaluate for effects");
|
|
}
|
|
}
|
|
}, {
|
|
key: "detourCall",
|
|
value: function detourCall(F, thisArgument, argumentsList, newTarget, performCall) {
|
|
var _this2 = this;
|
|
|
|
var realm = this.modules.realm;
|
|
if (F === this.modules.getRequire() && !this.modules.disallowDelayingRequiresOverride && argumentsList.length === 1) {
|
|
var moduleId = argumentsList[0];
|
|
var moduleIdValue = void 0;
|
|
if (moduleId instanceof _index2.NumberValue || moduleId instanceof _index2.StringValue) {
|
|
moduleIdValue = moduleId.value;
|
|
if (!this.modules.moduleIds.has(moduleIdValue) && this.modules.delayUnsupportedRequires) {
|
|
this.modules.logger.logError(moduleId, "Module referenced by require call has not been defined.");
|
|
}
|
|
} else {
|
|
if (this.modules.delayUnsupportedRequires) {
|
|
this.modules.logger.logError(moduleId, "First argument to require function is not a number or string value.");
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
if (!this.modules.delayUnsupportedRequires) {
|
|
if ((this.requireStack.length === 0 || this.requireStack[this.requireStack.length - 1] !== moduleIdValue) && this.modules.moduleIds.has(moduleIdValue)) {
|
|
this.requireStack.push(moduleIdValue);
|
|
try {
|
|
var value = performCall();
|
|
this.modules.recordModuleInitialized(moduleIdValue, value);
|
|
// Make this into a join point by suppressing the conditional exception.
|
|
// TODO: delete this code and let the caller deal with the conditional exception.
|
|
var completion = _singletons.Functions.incorporateSavedCompletion(realm, value);
|
|
if (completion instanceof _completions.PossiblyNormalCompletion) {
|
|
realm.stopEffectCapture(completion);
|
|
var warning = new _errors.CompilerDiagnostic("Module import may fail with an exception", completion.location, "PP0018", "Warning");
|
|
realm.handleError(warning);
|
|
}
|
|
return value;
|
|
} finally {
|
|
(0, _invariant2.default)(this.requireStack.pop() === moduleIdValue);
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
// If a require fails, recover from it and delay the factory call until runtime
|
|
this.log(">require(" + moduleIdValue + ")");
|
|
var isTopLevelRequire = this.requireStack.length === 0;
|
|
if (this.evaluateForEffectsNesting > 0) {
|
|
if (isTopLevelRequire) {
|
|
var diagnostic = new _errors.CompilerDiagnostic("Non-deterministically conditional top-level require not currently supported", realm.currentLocation, "PP0017", "FatalError");
|
|
realm.handleError(diagnostic);
|
|
throw new _errors.FatalError();
|
|
} else if (!this.modules.isModuleInitialized(moduleIdValue)) this.uninitializedModuleIdsRequiredInEvaluateForEffects.add(moduleIdValue);
|
|
return undefined;
|
|
} else {
|
|
return downgradeErrorsToWarnings(realm, function () {
|
|
var result = void 0;
|
|
try {
|
|
_this2.requireStack.push(moduleIdValue);
|
|
var requireSequenceStart = _this2.requireSequence.length;
|
|
_this2.requireSequence.push(moduleIdValue);
|
|
var acceleratedModuleIds = void 0,
|
|
effects = void 0;
|
|
var previousNumDelayedModules = _this2.statistics.delayedModules;
|
|
do {
|
|
try {
|
|
effects = realm.evaluateForEffects(function () {
|
|
return performCall();
|
|
}, _this2);
|
|
} catch (e) {}
|
|
|
|
acceleratedModuleIds = [];
|
|
if (isTopLevelRequire) {
|
|
// We gathered all effects, but didn't apply them yet.
|
|
// Let's check if there was any call to `require` in a
|
|
// evaluate-for-effects context. If so, try to initialize
|
|
// that module right now. Acceleration module initialization in this
|
|
// way might not actually be desirable, but it works around
|
|
// general prepack-limitations around joined abstract values involving
|
|
// conditionals. Long term, Prepack needs to implement a notion of refinement
|
|
// of conditional abstract values under the known path condition.
|
|
var _iteratorNormalCompletion = true;
|
|
var _didIteratorError = false;
|
|
var _iteratorError = undefined;
|
|
|
|
try {
|
|
for (var _iterator = _this2.uninitializedModuleIdsRequiredInEvaluateForEffects[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
var nestedModuleId = _step.value;
|
|
|
|
var nestedEffects = _this2.modules.tryInitializeModule(nestedModuleId, "accelerated initialization of conditional module " + nestedModuleId + " as it's required in an evaluate-for-effects context by module " + moduleIdValue);
|
|
if (_this2.modules.accelerateUnsupportedRequires && nestedEffects !== undefined && nestedEffects[0] instanceof _index2.Value && _this2.modules.isModuleInitialized(nestedModuleId)) {
|
|
acceleratedModuleIds.push(nestedModuleId);
|
|
}
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError = true;
|
|
_iteratorError = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion && _iterator.return) {
|
|
_iterator.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError) {
|
|
throw _iteratorError;
|
|
}
|
|
}
|
|
}
|
|
|
|
_this2.uninitializedModuleIdsRequiredInEvaluateForEffects.clear();
|
|
// Keep restarting for as long as we find additional modules to accelerate.
|
|
if (acceleratedModuleIds.length > 0) {
|
|
console.log("restarting require(" + moduleIdValue + ") after accelerating conditional require calls for " + acceleratedModuleIds.join());
|
|
_this2.statistics.acceleratedModules += acceleratedModuleIds.length;
|
|
}
|
|
}
|
|
} while (acceleratedModuleIds.length > 0);
|
|
|
|
if (effects === undefined || effects[0] instanceof _completions.AbruptCompletion) {
|
|
console.log("delaying require(" + moduleIdValue + ")");
|
|
_this2.statistics.delayedModules = previousNumDelayedModules + 1;
|
|
// So we are about to emit a delayed require(...) call.
|
|
// However, before we do that, let's try to require all modules that we
|
|
// know this delayed require call will require.
|
|
// This way, we ensure that those modules will be fully initialized
|
|
// before the require call executes.
|
|
// TODO #690: More needs to be done to make the delayUnsupportedRequires
|
|
// feature completely safe. Open issues are:
|
|
// 1) Side-effects on the heap of delayed factory functions are not discovered or rejected.
|
|
// 2) While we do process an appropriate list of transitively required modules here,
|
|
// it's likely just a subset / prefix of all transivitely required modules, as
|
|
// more modules would have been required if the Introspection exception had not been thrown.
|
|
// To be correct, those modules would have to be prepacked here as well.
|
|
// TODO #798: Watch out for an upcoming change to the __d module declaration where the statically known
|
|
// list of dependencies will be announced, so we'll no longer have to guess.
|
|
var nestedModulesIds = new Set();
|
|
for (var i = requireSequenceStart; i < _this2.requireSequence.length; i++) {
|
|
var _nestedModuleId = _this2.requireSequence[i];
|
|
if (nestedModulesIds.has(_nestedModuleId)) continue;
|
|
nestedModulesIds.add(_nestedModuleId);
|
|
_this2.modules.tryInitializeModule(_nestedModuleId, "initialization of module " + _nestedModuleId + " as it's required by module " + moduleIdValue);
|
|
}
|
|
|
|
result = _index2.AbstractValue.createTemporalFromBuildFunction(realm, _index2.Value, [], function (_ref) {
|
|
var _ref2 = _toArray(_ref);
|
|
|
|
return t.callExpression(t.identifier("require"), [t.valueToNode(moduleIdValue)]);
|
|
});
|
|
} else {
|
|
result = effects[0];
|
|
if (result instanceof _index2.Value) {
|
|
realm.applyEffects(effects, "initialization of module " + moduleIdValue);
|
|
_this2.modules.recordModuleInitialized(moduleIdValue, result);
|
|
} else if (result instanceof _completions.PossiblyNormalCompletion) {
|
|
var _warning = new _errors.CompilerDiagnostic("Module import may fail with an exception", result.location, "PP0018", "Warning");
|
|
realm.handleError(_warning);
|
|
result = result.value;
|
|
realm.applyEffects(effects, "initialization of module " + moduleIdValue);
|
|
_this2.modules.recordModuleInitialized(moduleIdValue, result);
|
|
} else {
|
|
(0, _invariant2.default)(false);
|
|
}
|
|
}
|
|
} finally {
|
|
var popped = _this2.requireStack.pop();
|
|
(0, _invariant2.default)(popped === moduleIdValue);
|
|
_this2.log("<require(" + moduleIdValue + ")");
|
|
}
|
|
(0, _invariant2.default)(result instanceof _index2.Value);
|
|
return result;
|
|
});
|
|
}
|
|
} else if (F === this.modules.getDefine()) {
|
|
if (this.evaluateForEffectsNesting !== 0) this.modules.logger.logError(F, "Defining a module in nested partial evaluation is not supported.");
|
|
var factoryFunction = argumentsList[0];
|
|
if (factoryFunction instanceof _index2.FunctionValue) this.modules.factoryFunctions.add(factoryFunction);else this.modules.logger.logError(factoryFunction, "First argument to define function is not a function value.");
|
|
var _moduleId = argumentsList[1];
|
|
if (_moduleId instanceof _index2.NumberValue || _moduleId instanceof _index2.StringValue) this.modules.moduleIds.add(_moduleId.value);else this.modules.logger.logError(_moduleId, "Second argument to define function is not a number or string value.");
|
|
}
|
|
return undefined;
|
|
}
|
|
}]);
|
|
|
|
return ModuleTracer;
|
|
}(_realm.Tracer);
|
|
|
|
var Modules = exports.Modules = function () {
|
|
function Modules(realm, logger, statistics, logModules, delayUnsupportedRequires, accelerateUnsupportedRequires) {
|
|
_classCallCheck(this, Modules);
|
|
|
|
this.realm = realm;
|
|
this.logger = logger;
|
|
this._require = realm.intrinsics.undefined;
|
|
this._define = realm.intrinsics.undefined;
|
|
this.factoryFunctions = new Set();
|
|
this.moduleIds = new Set();
|
|
this.initializedModules = new Map();
|
|
realm.tracers.push(this.moduleTracer = new ModuleTracer(this, statistics, logModules));
|
|
this.delayUnsupportedRequires = delayUnsupportedRequires;
|
|
this.accelerateUnsupportedRequires = accelerateUnsupportedRequires;
|
|
this.disallowDelayingRequiresOverride = false;
|
|
}
|
|
|
|
_createClass(Modules, [{
|
|
key: "resolveInitializedModules",
|
|
value: function resolveInitializedModules() {
|
|
this.initializedModules.clear();
|
|
var globalInitializedModulesMap = this._getGlobalProperty("__initializedModules");
|
|
(0, _invariant2.default)(globalInitializedModulesMap instanceof _index2.ObjectValue);
|
|
var _iteratorNormalCompletion2 = true;
|
|
var _didIteratorError2 = false;
|
|
var _iteratorError2 = undefined;
|
|
|
|
try {
|
|
for (var _iterator2 = globalInitializedModulesMap.properties.keys()[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
|
var moduleId = _step2.value;
|
|
|
|
var property = globalInitializedModulesMap.properties.get(moduleId);
|
|
(0, _invariant2.default)(property);
|
|
var moduleValue = property.descriptor && property.descriptor.value;
|
|
if (moduleValue instanceof _index2.Value) this.initializedModules.set(moduleId, moduleValue);
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError2 = true;
|
|
_iteratorError2 = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
|
_iterator2.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError2) {
|
|
throw _iteratorError2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}, {
|
|
key: "_getGlobalProperty",
|
|
value: function _getGlobalProperty(name) {
|
|
if (this.active) return this.realm.intrinsics.undefined;
|
|
this.active = true;
|
|
try {
|
|
var realm = this.realm;
|
|
return this.logger.tryQuery(function () {
|
|
return (0, _index.Get)(realm, realm.$GlobalObject, name);
|
|
}, realm.intrinsics.undefined, false);
|
|
} finally {
|
|
this.active = false;
|
|
}
|
|
}
|
|
}, {
|
|
key: "getRequire",
|
|
value: function getRequire() {
|
|
if (!(this._require instanceof _index2.FunctionValue)) this._require = this._getGlobalProperty("require");
|
|
return this._require;
|
|
}
|
|
}, {
|
|
key: "getDefine",
|
|
value: function getDefine() {
|
|
if (!(this._define instanceof _index2.FunctionValue)) this._define = this._getGlobalProperty("__d");
|
|
return this._define;
|
|
}
|
|
}, {
|
|
key: "getIsRequire",
|
|
value: function getIsRequire(formalParameters, functions) {
|
|
var realm = this.realm;
|
|
var logger = this.logger;
|
|
var modules = this;
|
|
return function (scope, node) {
|
|
if (!t.isIdentifier(node.callee) || node.arguments.length !== 1 || !node.arguments[0]) return false;
|
|
var argument = node.arguments[0];
|
|
if (!t.isNumericLiteral(argument) && !t.isStringLiteral(argument)) return false;
|
|
|
|
(0, _invariant2.default)(node.callee);
|
|
var innerName = node.callee.name;
|
|
|
|
var _loop = function _loop(f) {
|
|
var scopedBinding = scope.getBinding(innerName);
|
|
if (scopedBinding) {
|
|
if (modules.factoryFunctions.has(f) && formalParameters[1] === scopedBinding.path.node) {
|
|
(0, _invariant2.default)(scopedBinding.kind === "param");
|
|
return "continue";
|
|
}
|
|
// The name binds to some local entity, but nothing we'd know what exactly it is
|
|
return {
|
|
v: false
|
|
};
|
|
}
|
|
|
|
var doesNotMatter = true;
|
|
var reference = logger.tryQuery(function () {
|
|
return _singletons.Environment.ResolveBinding(realm, innerName, doesNotMatter, f.$Environment);
|
|
}, undefined, false);
|
|
if (reference === undefined) {
|
|
// We couldn't resolve as we came across some behavior that we cannot deal with abstractly
|
|
return {
|
|
v: false
|
|
};
|
|
}
|
|
if (_singletons.Environment.IsUnresolvableReference(realm, reference)) return {
|
|
v: false
|
|
};
|
|
var referencedBase = reference.base;
|
|
var referencedName = reference.referencedName;
|
|
if (typeof referencedName !== "string") return {
|
|
v: false
|
|
};
|
|
var value = void 0;
|
|
if (reference.base instanceof _environment.GlobalEnvironmentRecord) {
|
|
value = logger.tryQuery(function () {
|
|
return (0, _index.Get)(realm, realm.$GlobalObject, innerName);
|
|
}, realm.intrinsics.undefined, false);
|
|
} else {
|
|
(0, _invariant2.default)(referencedBase instanceof _environment.DeclarativeEnvironmentRecord);
|
|
var binding = referencedBase.bindings[referencedName];
|
|
if (!binding.initialized) return {
|
|
v: false
|
|
};
|
|
value = binding.value;
|
|
}
|
|
if (value !== modules.getRequire()) return {
|
|
v: false
|
|
};
|
|
};
|
|
|
|
var _iteratorNormalCompletion3 = true;
|
|
var _didIteratorError3 = false;
|
|
var _iteratorError3 = undefined;
|
|
|
|
try {
|
|
for (var _iterator3 = functions[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
|
|
var f = _step3.value;
|
|
|
|
var _ret = _loop(f);
|
|
|
|
switch (_ret) {
|
|
case "continue":
|
|
continue;
|
|
|
|
default:
|
|
if ((typeof _ret === "undefined" ? "undefined" : _typeof(_ret)) === "object") return _ret.v;
|
|
}
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError3 = true;
|
|
_iteratorError3 = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion3 && _iterator3.return) {
|
|
_iterator3.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError3) {
|
|
throw _iteratorError3;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
};
|
|
}
|
|
}, {
|
|
key: "recordModuleInitialized",
|
|
value: function recordModuleInitialized(moduleId, value) {
|
|
this.realm.assignToGlobal(t.memberExpression(t.memberExpression(t.identifier("global"), t.identifier("__initializedModules")), t.identifier("" + moduleId)), value);
|
|
}
|
|
}, {
|
|
key: "tryInitializeModule",
|
|
value: function tryInitializeModule(moduleId, message) {
|
|
var _this3 = this;
|
|
|
|
var realm = this.realm;
|
|
var previousDisallowDelayingRequiresOverride = this.disallowDelayingRequiresOverride;
|
|
this.disallowDelayingRequiresOverride = true;
|
|
return downgradeErrorsToWarnings(realm, function () {
|
|
try {
|
|
var _node = t.callExpression(t.identifier("require"), [t.valueToNode(moduleId)]);
|
|
|
|
var effects = realm.evaluateNodeForEffectsInGlobalEnv(_node);
|
|
realm.applyEffects(effects, message);
|
|
return effects;
|
|
} catch (err) {
|
|
if (err instanceof _errors.FatalError) return undefined;else throw err;
|
|
} finally {
|
|
_this3.disallowDelayingRequiresOverride = previousDisallowDelayingRequiresOverride;
|
|
}
|
|
});
|
|
}
|
|
}, {
|
|
key: "initializeMoreModules",
|
|
value: function initializeMoreModules() {
|
|
// partially evaluate all factory methods by calling require
|
|
var count = 0;
|
|
var _iteratorNormalCompletion4 = true;
|
|
var _didIteratorError4 = false;
|
|
var _iteratorError4 = undefined;
|
|
|
|
try {
|
|
for (var _iterator4 = this.moduleIds[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
|
|
var moduleId = _step4.value;
|
|
|
|
if (this.initializedModules.has(moduleId)) continue;
|
|
var effects = this.tryInitializeModule(moduleId, "Speculative initialization of module " + moduleId);
|
|
if (effects === undefined) continue;
|
|
var result = effects[0];
|
|
if (!(result instanceof _index2.Value)) continue; // module might throw
|
|
count++;
|
|
this.initializedModules.set(moduleId, result);
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError4 = true;
|
|
_iteratorError4 = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion4 && _iterator4.return) {
|
|
_iterator4.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError4) {
|
|
throw _iteratorError4;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (count > 0) console.log("=== speculatively initialized " + count + " additional modules");
|
|
}
|
|
}, {
|
|
key: "isModuleInitialized",
|
|
value: function isModuleInitialized(moduleId) {
|
|
var realm = this.realm;
|
|
var oldReadOnly = realm.setReadOnly(true);
|
|
var oldDisallowDelayingRequiresOverride = this.disallowDelayingRequiresOverride;
|
|
this.disallowDelayingRequiresOverride = true;
|
|
try {
|
|
var _node2 = t.callExpression(t.identifier("require"), [t.valueToNode(moduleId)]);
|
|
|
|
var _realm$evaluateNodeFo = realm.evaluateNodeForEffectsInGlobalEnv(_node2),
|
|
_realm$evaluateNodeFo2 = _slicedToArray(_realm$evaluateNodeFo, 5),
|
|
compl = _realm$evaluateNodeFo2[0],
|
|
generator = _realm$evaluateNodeFo2[1],
|
|
bindings = _realm$evaluateNodeFo2[2],
|
|
properties = _realm$evaluateNodeFo2[3],
|
|
createdObjects = _realm$evaluateNodeFo2[4];
|
|
// for lint unused
|
|
|
|
|
|
(0, _invariant2.default)(bindings);
|
|
|
|
if (compl instanceof _completions.AbruptCompletion) return undefined;
|
|
(0, _invariant2.default)(compl instanceof _index2.Value);
|
|
|
|
if (!generator.empty() || compl instanceof _index2.ObjectValue && createdObjects.has(compl)) return undefined;
|
|
// Check for escaping property assignments, if none escape, we got an existing object
|
|
var escapes = false;
|
|
var _iteratorNormalCompletion5 = true;
|
|
var _didIteratorError5 = false;
|
|
var _iteratorError5 = undefined;
|
|
|
|
try {
|
|
for (var _iterator5 = properties[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
|
|
var _ref3 = _step5.value;
|
|
|
|
var _ref4 = _slicedToArray(_ref3, 1);
|
|
|
|
var binding = _ref4[0];
|
|
|
|
var object = binding.object;
|
|
(0, _invariant2.default)(object instanceof _index2.ObjectValue);
|
|
if (!createdObjects.has(object)) escapes = true;
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError5 = true;
|
|
_iteratorError5 = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion5 && _iterator5.return) {
|
|
_iterator5.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError5) {
|
|
throw _iteratorError5;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (escapes) return undefined;
|
|
|
|
return compl;
|
|
} catch (err) {
|
|
if (err instanceof _errors.FatalError) return undefined;
|
|
throw err;
|
|
} finally {
|
|
realm.setReadOnly(oldReadOnly);
|
|
this.disallowDelayingRequiresOverride = oldDisallowDelayingRequiresOverride;
|
|
}
|
|
}
|
|
}]);
|
|
|
|
return Modules;
|
|
}();
|
|
//# sourceMappingURL=modules.js.map
|