prepack
Version:
Execute a JS bundle, serialize global state and side effects to a snapshot that can be quickly restored.
112 lines (84 loc) • 4.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _default;
var _completions = require("../completions.js");
var _index = require("../methods/index.js");
var _errors = require("../errors.js");
var _realm = require("../realm.js");
var _singletons = require("../singletons.js");
var _index2 = require("../values/index.js");
var _invariant = _interopRequireDefault(require("../invariant.js"));
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.
*/
function _default(ast, strictCode, env, realm) {
if (realm.useAbstractInterpretation) return joinTryBlockWithHandlers(ast, strictCode, env, realm);
let blockRes = env.evaluateCompletionDeref(ast.block, strictCode);
let result = blockRes;
if (blockRes instanceof _completions.ThrowCompletion && ast.handler) {
result = env.evaluateCompletionDeref(ast.handler, strictCode, blockRes);
}
if (ast.finalizer) {
result = composeResults(result, env.evaluateCompletionDeref(ast.finalizer, strictCode));
}
return realm.returnOrThrowCompletion((0, _index.UpdateEmpty)(realm, result, realm.intrinsics.undefined));
}
function composeResults(r1, r2) {
if (r2 instanceof _completions.AbruptCompletion) return r2;
return _singletons.Join.composeCompletions(r2, r1);
}
function joinTryBlockWithHandlers(ast, strictCode, env, realm) {
let savedIsInPureTryStatement = realm.isInPureTryStatement;
if (realm.isInPureScope()) {
// TODO(1264): This is used to issue a warning if we have abstract function calls in here.
// We might not need it once we have full support for handling potential errors. Even
// then we might need it to know whether we should bother tracking error handling.
realm.isInPureTryStatement = true;
}
let blockRes = env.evaluateCompletionDeref(ast.block, strictCode); // this is a join point for break and continue completions
blockRes = _singletons.Functions.incorporateSavedCompletion(realm, blockRes);
(0, _invariant.default)(blockRes !== undefined);
realm.isInPureTryStatement = savedIsInPureTryStatement;
let result = blockRes;
let handler = ast.handler;
let selector = c => c instanceof _completions.ThrowCompletion;
if (handler && blockRes instanceof _completions.Completion && blockRes.containsSelectedCompletion(selector)) {
if (blockRes instanceof _completions.ThrowCompletion) {
result = env.evaluateCompletionDeref(handler, strictCode, blockRes);
} else {
(0, _invariant.default)(blockRes instanceof _completions.JoinedAbruptCompletions || blockRes instanceof _completions.JoinedNormalAndAbruptCompletions); // put the handler under a guard that excludes normal paths from entering it.
let joinCondition = _index2.AbstractValue.createJoinConditionForSelectedCompletions(selector, blockRes);
if (joinCondition.mightNotBeFalse()) {
try {
let handlerEffects = _singletons.Path.withCondition(joinCondition, () => {
(0, _invariant.default)(blockRes instanceof _completions.Completion);
let joinedThrow = new _completions.ThrowCompletion(_singletons.Join.joinValuesOfSelectedCompletions(selector, blockRes));
let handlerEval = () => env.evaluateCompletionDeref(handler, strictCode, joinedThrow);
return realm.evaluateForEffects(handlerEval, undefined, "joinTryBlockWithHandlers");
});
_completions.Completion.makeSelectedCompletionsInfeasible(selector, blockRes);
let emptyEffects = (0, _realm.construct_empty_effects)(realm, blockRes);
handlerEffects = _singletons.Join.joinEffects(joinCondition, handlerEffects, emptyEffects);
realm.applyEffects(handlerEffects);
result = handlerEffects.result;
} catch (e) {
if (!(e instanceof _errors.InfeasiblePathError)) throw e; // It turns out that the handler is not reachable after all so just do nothing and carry on
}
}
}
}
if (ast.finalizer) {
let res = env.evaluateCompletionDeref(ast.finalizer, strictCode);
result = composeResults(result, res);
}
return realm.returnOrThrowCompletion((0, _index.UpdateEmpty)(realm, result, realm.intrinsics.undefined));
}
//# sourceMappingURL=TryStatement.js.map