prepack
Version:
Execute a JS bundle, serialize global state and side effects to a snapshot that can be quickly restored.
102 lines (72 loc) • 4.05 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _default;
var _errors = require("../errors.js");
var _index = require("../values/index.js");
var _index2 = require("../methods/index.js");
var _ForOfStatement = require("./ForOfStatement.js");
var _completions = require("../completions.js");
var _singletons = require("../singletons.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, labelSet) {
let {
body,
test
} = ast; // 1. Let V be undefined.
let V = realm.intrinsics.undefined; // 2. Repeat
let resultOrDiagnostic = realm.evaluateWithUndoForDiagnostic(() => {
while (true) {
// a. Let stmt be the result of evaluating Statement.
let stmt = env.evaluateCompletion(body, strictCode); //todo: check if stmt is JoinedNormalAndAbruptCompletions and defer to fixpoint computation below
(0, _invariant.default)(stmt instanceof _index.Value || stmt instanceof _completions.AbruptCompletion); // b. If LoopContinues(stmt, labelSet) is false, return Completion(UpdateEmpty(stmt, V)).
if ((0, _ForOfStatement.LoopContinues)(realm, stmt, labelSet) === false) {
(0, _invariant.default)(stmt instanceof _completions.AbruptCompletion); // ECMA262 13.1.7
if (stmt instanceof _completions.BreakCompletion) {
if (!stmt.target) return (0, _index2.UpdateEmpty)(realm, stmt, V).value;
}
throw (0, _index2.UpdateEmpty)(realm, stmt, V);
} // c. If stmt.[[Value]] is not empty, let V be stmt.[[Value]].
let resultValue = (0, _ForOfStatement.InternalGetResultValue)(realm, stmt);
if (!(resultValue instanceof _index.EmptyValue)) V = resultValue; // d. Let exprRef be the result of evaluating Expression.
let exprRef = env.evaluate(test, strictCode); // e. Let exprValue be ? GetValue(exprRef).
let exprValue = _singletons.Environment.GetConditionValue(realm, exprRef); // f. If ToBoolean(exprValue) is false, return NormalCompletion(V).
if (_singletons.To.ToBooleanPartial(realm, exprValue) === false) return V;
}
(0, _invariant.default)(false);
});
if (resultOrDiagnostic instanceof _index.Value) return resultOrDiagnostic; // If we get here then unrolling the loop did not work, possibly because the value of the loop condition is not known,
// so instead try to compute a fixpoint for it
let iteration = () => {
let bodyResult = env.evaluateCompletion(body, strictCode);
if (bodyResult instanceof _index.Value) bodyResult = new _completions.SimpleNormalCompletion(bodyResult);
let exprRef = env.evaluate(test, strictCode);
let testResult = _singletons.Environment.GetConditionValue(realm, exprRef);
return [testResult, bodyResult];
};
let result = realm.evaluateForFixpointEffects(iteration);
if (result !== undefined) {
let [outsideEffects, insideEffects, cond] = result;
let rval = outsideEffects.result;
let bodyGenerator = insideEffects.generator;
realm.applyEffects(outsideEffects);
let generator = realm.generator;
(0, _invariant.default)(generator !== undefined);
generator.emitDoWhileStatement(cond, bodyGenerator);
(0, _invariant.default)(rval instanceof _completions.SimpleNormalCompletion, "todo: handle loops that throw exceptions or return");
return rval.value;
} // If we get here the fixpoint computation failed as well. Report the diagnostic from the unrolling and throw.
realm.handleError(resultOrDiagnostic);
throw new _errors.FatalError();
}
//# sourceMappingURL=DoWhileStatement.js.map