first commit
This commit is contained in:
251
build/node_modules/prepack/lib/evaluators/TryStatement.js
generated
vendored
Normal file
251
build/node_modules/prepack/lib/evaluators/TryStatement.js
generated
vendored
Normal file
@@ -0,0 +1,251 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
exports.default = function (ast, strictCode, env, realm) {
|
||||
var blockRes = env.evaluateCompletionDeref(ast.block, strictCode);
|
||||
|
||||
var handlerRes = blockRes;
|
||||
var handler = ast.handler;
|
||||
if (handler) {
|
||||
// The start of the catch handler is a join point where all throw completions come together
|
||||
blockRes = _singletons.Functions.incorporateSavedCompletion(realm, blockRes);
|
||||
if (blockRes instanceof _completions.ThrowCompletion) {
|
||||
handlerRes = env.evaluateCompletionDeref(handler, strictCode, blockRes);
|
||||
// Note: The handler may have introduced new forks
|
||||
} else if (blockRes instanceof _completions.JoinedAbruptCompletions || blockRes instanceof _completions.PossiblyNormalCompletion) {
|
||||
if (blockRes instanceof _completions.PossiblyNormalCompletion) {
|
||||
// Nothing has been joined and we are going to keep it that way.
|
||||
// The current state may have advanced since the time control forked into the various paths recorded in blockRes.
|
||||
// Update the normal path and restore the global state to what it was at the time of the fork.
|
||||
var subsequentEffects = realm.getCapturedEffects(blockRes, blockRes.value);
|
||||
(0, _invariant2.default)(subsequentEffects !== undefined);
|
||||
realm.stopEffectCaptureAndUndoEffects(blockRes);
|
||||
_singletons.Join.updatePossiblyNormalCompletionWithSubsequentEffects(realm, blockRes, subsequentEffects);
|
||||
}
|
||||
// All of the forked threads of control are now joined together and the global state reflects their joint effects
|
||||
var handlerEffects = composeNestedThrowEffectsWithHandler(blockRes);
|
||||
handlerRes = handlerEffects[0];
|
||||
if (handlerRes instanceof _index2.Value) {
|
||||
// This can happen if all of the abrupt completions in blockRes were throw completions
|
||||
// and if the handler does not introduce any abrupt completions of its own.
|
||||
realm.applyEffects(handlerEffects);
|
||||
// The global state is now all joined up
|
||||
} else {
|
||||
// more than thread of control leaves the handler
|
||||
// The effects of each thread is tracked in handlerRes
|
||||
}
|
||||
} else {
|
||||
// The handler is not invoked, so just carry on.
|
||||
}
|
||||
}
|
||||
|
||||
var finalizerRes = handlerRes;
|
||||
if (ast.finalizer) {
|
||||
// The start of the finalizer is a join point where all threads of control come together.
|
||||
// However, we choose to keep the threads unjoined and to apply the finalizer separately to each thread.
|
||||
if (blockRes instanceof _completions.PossiblyNormalCompletion || blockRes instanceof _completions.JoinedAbruptCompletions) {
|
||||
// The current global state is a the point of the fork that led to blockRes
|
||||
// All subsequent effects are kept inside the branches of blockRes.
|
||||
var finalizerEffects = composeNestedEffectsWithFinalizer(blockRes);
|
||||
finalizerRes = finalizerEffects[0];
|
||||
// The result may become abrupt because of the finalizer, but it cannot become normal.
|
||||
(0, _invariant2.default)(!(finalizerRes instanceof _index2.Value));
|
||||
} else {
|
||||
// A single thread of control has produced a normal blockRes and the global state is up to date.
|
||||
finalizerRes = env.evaluateCompletion(ast.finalizer, strictCode);
|
||||
}
|
||||
}
|
||||
|
||||
if (finalizerRes instanceof _completions.AbruptCompletion) throw finalizerRes;
|
||||
if (finalizerRes instanceof _completions.PossiblyNormalCompletion) realm.composeWithSavedCompletion(finalizerRes);
|
||||
if (handlerRes instanceof _completions.PossiblyNormalCompletion) handlerRes = handlerRes.value;
|
||||
if (handlerRes instanceof _index2.Value) return (0, _index.UpdateEmpty)(realm, handlerRes, realm.intrinsics.undefined);
|
||||
throw handlerRes;
|
||||
|
||||
// The handler is a potential join point for all throw completions, but is easier to not do the join here because
|
||||
// it is tricky to join the joined and composed result of the throw completions with the non exceptional completions.
|
||||
// Unfortunately, things are still complicated because the handler may turn abrupt completions into normal
|
||||
// completions and the other way around. When this happens the container has to change its type.
|
||||
// We do this by call joinEffects to create a new container at every level of the recursion.
|
||||
function composeNestedThrowEffectsWithHandler(c) {
|
||||
var priorEffects = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
||||
|
||||
var consequent = c.consequent;
|
||||
var consequentEffects = c.consequentEffects;
|
||||
priorEffects.push(consequentEffects);
|
||||
if (consequent instanceof _completions.JoinedAbruptCompletions || consequent instanceof _completions.PossiblyNormalCompletion) {
|
||||
consequentEffects = composeNestedThrowEffectsWithHandler(consequent, priorEffects);
|
||||
} else if (consequent instanceof _completions.ThrowCompletion) {
|
||||
consequentEffects = realm.evaluateForEffects(function () {
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _didIteratorError = false;
|
||||
var _iteratorError = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator = priorEffects[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
var priorEffect = _step.value;
|
||||
realm.applyEffects(priorEffect);
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return) {
|
||||
_iterator.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(0, _invariant2.default)(ast.handler);
|
||||
return env.evaluateCompletionDeref(ast.handler, strictCode, consequent);
|
||||
});
|
||||
}
|
||||
priorEffects.pop();
|
||||
var alternate = c.alternate;
|
||||
var alternateEffects = c.alternateEffects;
|
||||
priorEffects.push(alternateEffects);
|
||||
if (alternate instanceof _completions.PossiblyNormalCompletion || alternate instanceof _completions.JoinedAbruptCompletions) {
|
||||
alternateEffects = composeNestedThrowEffectsWithHandler(alternate, priorEffects);
|
||||
} else if (alternate instanceof _completions.ThrowCompletion) {
|
||||
alternateEffects = realm.evaluateForEffects(function () {
|
||||
var _iteratorNormalCompletion2 = true;
|
||||
var _didIteratorError2 = false;
|
||||
var _iteratorError2 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator2 = priorEffects[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
||||
var priorEffect = _step2.value;
|
||||
realm.applyEffects(priorEffect);
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError2 = true;
|
||||
_iteratorError2 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
||||
_iterator2.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError2) {
|
||||
throw _iteratorError2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(0, _invariant2.default)(ast.handler);
|
||||
return env.evaluateCompletionDeref(ast.handler, strictCode, alternate);
|
||||
});
|
||||
}
|
||||
priorEffects.pop();
|
||||
return _singletons.Join.joinEffects(realm, c.joinCondition, consequentEffects, alternateEffects);
|
||||
}
|
||||
|
||||
// The finalizer is not a join point, so update each path in the completion separately.
|
||||
// Things are complicated because the finalizer may turn normal completions into abrupt completions.
|
||||
// When this happens the container has to change its type.
|
||||
// We do this by call joinEffects to create a new container at every level of the recursion.
|
||||
function composeNestedEffectsWithFinalizer(c) {
|
||||
var priorEffects = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
||||
|
||||
var consequent = c.consequent;
|
||||
var consequentEffects = c.consequentEffects;
|
||||
priorEffects.push(consequentEffects);
|
||||
if (consequent instanceof _completions.JoinedAbruptCompletions || consequent instanceof _completions.PossiblyNormalCompletion) {
|
||||
consequentEffects = composeNestedThrowEffectsWithHandler(consequent, priorEffects);
|
||||
} else {
|
||||
consequentEffects = realm.evaluateForEffects(function () {
|
||||
var _iteratorNormalCompletion3 = true;
|
||||
var _didIteratorError3 = false;
|
||||
var _iteratorError3 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator3 = priorEffects[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
|
||||
var priorEffect = _step3.value;
|
||||
realm.applyEffects(priorEffect);
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError3 = true;
|
||||
_iteratorError3 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion3 && _iterator3.return) {
|
||||
_iterator3.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError3) {
|
||||
throw _iteratorError3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(0, _invariant2.default)(ast.finalizer);
|
||||
return env.evaluateCompletionDeref(ast.finalizer, strictCode);
|
||||
});
|
||||
if (!(consequentEffects[0] instanceof _completions.AbruptCompletion)) consequentEffects[0] = consequent;
|
||||
}
|
||||
priorEffects.pop();
|
||||
var alternate = c.alternate;
|
||||
var alternateEffects = c.alternateEffects;
|
||||
priorEffects.push(alternateEffects);
|
||||
if (alternate instanceof _completions.PossiblyNormalCompletion || alternate instanceof _completions.JoinedAbruptCompletions) {
|
||||
alternateEffects = composeNestedThrowEffectsWithHandler(alternate, priorEffects);
|
||||
} else {
|
||||
alternateEffects = realm.evaluateForEffects(function () {
|
||||
var _iteratorNormalCompletion4 = true;
|
||||
var _didIteratorError4 = false;
|
||||
var _iteratorError4 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator4 = priorEffects[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
|
||||
var priorEffect = _step4.value;
|
||||
realm.applyEffects(priorEffect);
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError4 = true;
|
||||
_iteratorError4 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion4 && _iterator4.return) {
|
||||
_iterator4.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError4) {
|
||||
throw _iteratorError4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(0, _invariant2.default)(ast.finalizer);
|
||||
return env.evaluateCompletionDeref(ast.finalizer, strictCode);
|
||||
});
|
||||
if (!(alternateEffects[0] instanceof _completions.AbruptCompletion)) alternateEffects[0] = alternate;
|
||||
}
|
||||
priorEffects.pop();
|
||||
return _singletons.Join.joinEffects(realm, c.joinCondition, consequentEffects, alternateEffects);
|
||||
}
|
||||
};
|
||||
|
||||
require("../environment.js");
|
||||
|
||||
var _completions = require("../completions.js");
|
||||
|
||||
var _index = require("../methods/index.js");
|
||||
|
||||
var _singletons = require("../singletons.js");
|
||||
|
||||
var _index2 = require("../values/index.js");
|
||||
|
||||
var _invariant = require("../invariant.js");
|
||||
|
||||
var _invariant2 = _interopRequireDefault(_invariant);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
//# sourceMappingURL=TryStatement.js.map
|
||||
Reference in New Issue
Block a user