268 lines
10 KiB
JavaScript
268 lines
10 KiB
JavaScript
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.CreatePerIterationEnvironment = CreatePerIterationEnvironment;
|
|
|
|
exports.default = function (ast, strictCode, env, realm, labelSet) {
|
|
var init = ast.init,
|
|
test = ast.test,
|
|
update = ast.update,
|
|
body = ast.body;
|
|
|
|
|
|
if (init && init.type === "VariableDeclaration") {
|
|
if (init.kind === "var") {
|
|
// for (var VariableDeclarationList; Expression; Expression) Statement
|
|
// 1. Let varDcl be the result of evaluating VariableDeclarationList.
|
|
var varDcl = env.evaluate(init, strictCode);
|
|
|
|
// 2. ReturnIfAbrupt(varDcl).
|
|
varDcl;
|
|
|
|
// 3. Return ? ForBodyEvaluation(the first Expression, the second Expression, Statement, « », labelSet).
|
|
return ForBodyEvaluation(realm, test, update, body, [], labelSet, strictCode);
|
|
} else {
|
|
// for (LexicalDeclaration Expression; Expression) Statement
|
|
// 1. Let oldEnv be the running execution context's LexicalEnvironment.
|
|
var oldEnv = env;
|
|
|
|
// 2. Let loopEnv be NewDeclarativeEnvironment(oldEnv).
|
|
var loopEnv = _singletons.Environment.NewDeclarativeEnvironment(realm, oldEnv);
|
|
|
|
// 3. Let loopEnvRec be loopEnv's EnvironmentRecord.
|
|
var loopEnvRec = loopEnv.environmentRecord;
|
|
|
|
// 4. Let isConst be the result of performing IsConstantDeclaration of LexicalDeclaration.
|
|
var isConst = init.kind === "const";
|
|
|
|
// 5. Let boundNames be the BoundNames of LexicalDeclaration.
|
|
var boundNames = _singletons.Environment.BoundNames(realm, init);
|
|
|
|
// 6. For each element dn of boundNames do
|
|
var _iteratorNormalCompletion2 = true;
|
|
var _didIteratorError2 = false;
|
|
var _iteratorError2 = undefined;
|
|
|
|
try {
|
|
for (var _iterator2 = boundNames[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
|
var dn = _step2.value;
|
|
|
|
// a. If isConst is true, then
|
|
if (isConst) {
|
|
// i. Perform ! loopEnvRec.CreateImmutableBinding(dn, true).
|
|
loopEnvRec.CreateImmutableBinding(dn, true);
|
|
} else {
|
|
// b. Else,
|
|
// i. Perform ! loopEnvRec.CreateMutableBinding(dn, false).
|
|
loopEnvRec.CreateMutableBinding(dn, false);
|
|
}
|
|
}
|
|
|
|
// 7. Set the running execution context's LexicalEnvironment to loopEnv.
|
|
} catch (err) {
|
|
_didIteratorError2 = true;
|
|
_iteratorError2 = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
|
_iterator2.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError2) {
|
|
throw _iteratorError2;
|
|
}
|
|
}
|
|
}
|
|
|
|
realm.getRunningContext().lexicalEnvironment = loopEnv;
|
|
|
|
// 8. Let forDcl be the result of evaluating LexicalDeclaration.
|
|
var forDcl = loopEnv.evaluateCompletion(init, strictCode);
|
|
|
|
// 9. If forDcl is an abrupt completion, then
|
|
if (forDcl instanceof _completions.AbruptCompletion) {
|
|
// a. Set the running execution context's LexicalEnvironment to oldEnv.
|
|
var currentEnv = realm.getRunningContext().lexicalEnvironment;
|
|
realm.onDestroyScope(currentEnv);
|
|
if (currentEnv !== loopEnv) (0, _invariant2.default)(loopEnv.destroyed);
|
|
realm.getRunningContext().lexicalEnvironment = oldEnv;
|
|
|
|
// b. Return Completion(forDcl).
|
|
throw forDcl;
|
|
}
|
|
|
|
// 10. If isConst is false, let perIterationLets be boundNames; otherwise let perIterationLets be « ».
|
|
var perIterationLets = !isConst ? boundNames : [];
|
|
|
|
var bodyResult = void 0;
|
|
try {
|
|
// 11. Let bodyResult be ForBodyEvaluation(the first Expression, the second Expression, Statement, perIterationLets, labelSet).
|
|
bodyResult = ForBodyEvaluation(realm, test, update, body, perIterationLets, labelSet, strictCode);
|
|
} finally {
|
|
// 12. Set the running execution context's LexicalEnvironment to oldEnv.
|
|
var _currentEnv = realm.getRunningContext().lexicalEnvironment;
|
|
realm.onDestroyScope(_currentEnv);
|
|
if (_currentEnv !== loopEnv) (0, _invariant2.default)(loopEnv.destroyed);
|
|
realm.getRunningContext().lexicalEnvironment = oldEnv;
|
|
}
|
|
// 13. Return Completion(bodyResult).
|
|
return bodyResult;
|
|
}
|
|
} else {
|
|
// for (Expression; Expression; Expression) Statement
|
|
// 1. If the first Expression is present, then
|
|
if (init) {
|
|
// a. Let exprRef be the result of evaluating the first Expression.
|
|
var exprRef = env.evaluate(init, strictCode);
|
|
|
|
// b. Perform ? GetValue(exprRef).
|
|
_singletons.Environment.GetValue(realm, exprRef);
|
|
}
|
|
|
|
// 2. Return ? ForBodyEvaluation(the second Expression, the third Expression, Statement, « », labelSet).
|
|
return ForBodyEvaluation(realm, test, update, body, [], labelSet, strictCode);
|
|
}
|
|
};
|
|
|
|
var _index = require("../values/index.js");
|
|
|
|
var _completions = require("../completions.js");
|
|
|
|
var _index2 = require("../methods/index.js");
|
|
|
|
var _ForOfStatement = require("./ForOfStatement.js");
|
|
|
|
var _singletons = require("../singletons.js");
|
|
|
|
var _invariant = require("../invariant.js");
|
|
|
|
var _invariant2 = _interopRequireDefault(_invariant);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
// ECMA262 13.7.4.9
|
|
/**
|
|
* 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 CreatePerIterationEnvironment(realm, perIterationBindings) {
|
|
// 1. If perIterationBindings has any elements, then
|
|
if (perIterationBindings.length > 0) {
|
|
// a. Let lastIterationEnv be the running execution context's LexicalEnvironment.
|
|
var lastIterationEnv = realm.getRunningContext().lexicalEnvironment;
|
|
// b. Let lastIterationEnvRec be lastIterationEnv's EnvironmentRecord.
|
|
var lastIterationEnvRec = lastIterationEnv.environmentRecord;
|
|
// c. Let outer be lastIterationEnv's outer environment reference.
|
|
var outer = lastIterationEnv.parent;
|
|
// d. Assert: outer is not null.
|
|
(0, _invariant2.default)(outer !== null);
|
|
// e. Let thisIterationEnv be NewDeclarativeEnvironment(outer).
|
|
var thisIterationEnv = _singletons.Environment.NewDeclarativeEnvironment(realm, outer);
|
|
// f. Let thisIterationEnvRec be thisIterationEnv's EnvironmentRecord.
|
|
realm.onDestroyScope(lastIterationEnv);
|
|
var thisIterationEnvRec = thisIterationEnv.environmentRecord;
|
|
// g. For each element bn of perIterationBindings do,
|
|
var _iteratorNormalCompletion = true;
|
|
var _didIteratorError = false;
|
|
var _iteratorError = undefined;
|
|
|
|
try {
|
|
for (var _iterator = perIterationBindings[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
var bn = _step.value;
|
|
|
|
// i. Perform ! thisIterationEnvRec.CreateMutableBinding(bn, false).
|
|
thisIterationEnvRec.CreateMutableBinding(bn, false);
|
|
// ii. Let lastValue be ? lastIterationEnvRec.GetBindingValue(bn, true).
|
|
var lastValue = lastIterationEnvRec.GetBindingValue(bn, true);
|
|
// iii.Perform thisIterationEnvRec.InitializeBinding(bn, lastValue).
|
|
thisIterationEnvRec.InitializeBinding(bn, lastValue);
|
|
}
|
|
// h. Set the running execution context's LexicalEnvironment to thisIterationEnv.
|
|
} catch (err) {
|
|
_didIteratorError = true;
|
|
_iteratorError = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion && _iterator.return) {
|
|
_iterator.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError) {
|
|
throw _iteratorError;
|
|
}
|
|
}
|
|
}
|
|
|
|
realm.getRunningContext().lexicalEnvironment = thisIterationEnv;
|
|
}
|
|
// 2. Return undefined.
|
|
return realm.intrinsics.undefined;
|
|
}
|
|
|
|
// ECMA262 13.7.4.8
|
|
function ForBodyEvaluation(realm, test, increment, stmt, perIterationBindings, labelSet, strictCode) {
|
|
// 1. Let V be undefined.
|
|
var V = realm.intrinsics.undefined;
|
|
|
|
// 2. Perform ? CreatePerIterationEnvironment(perIterationBindings).
|
|
CreatePerIterationEnvironment(realm, perIterationBindings);
|
|
var env = realm.getRunningContext().lexicalEnvironment;
|
|
|
|
// 3. Repeat
|
|
while (true) {
|
|
// a. If test is not [empty], then
|
|
if (test) {
|
|
// i. Let testRef be the result of evaluating test.
|
|
var testRef = env.evaluate(test, strictCode);
|
|
|
|
// ii. Let testValue be ? GetValue(testRef).
|
|
var testValue = _singletons.Environment.GetValue(realm, testRef);
|
|
|
|
// iii. If ToBoolean(testValue) is false, return NormalCompletion(V).
|
|
if (!_singletons.To.ToBooleanPartial(realm, testValue)) return V;
|
|
}
|
|
|
|
// b. Let result be the result of evaluating stmt.
|
|
var result = env.evaluateCompletion(stmt, strictCode);
|
|
(0, _invariant2.default)(result instanceof _index.Value || result instanceof _completions.AbruptCompletion);
|
|
|
|
// c. If LoopContinues(result, labelSet) is false, return Completion(UpdateEmpty(result, V)).
|
|
if (!(0, _ForOfStatement.LoopContinues)(realm, result, labelSet)) {
|
|
(0, _invariant2.default)(result instanceof _completions.AbruptCompletion);
|
|
// ECMA262 13.1.7
|
|
if (result instanceof _completions.BreakCompletion) {
|
|
if (!result.target) return (0, _index2.UpdateEmpty)(realm, result, V).value;
|
|
}
|
|
throw (0, _index2.UpdateEmpty)(realm, result, V);
|
|
}
|
|
|
|
// d. If result.[[Value]] is not empty, let V be result.[[Value]].
|
|
var resultValue = (0, _ForOfStatement.InternalGetResultValue)(realm, result);
|
|
if (!(resultValue instanceof _index.EmptyValue)) V = resultValue;
|
|
|
|
// e. Perform ? CreatePerIterationEnvironment(perIterationBindings).
|
|
CreatePerIterationEnvironment(realm, perIterationBindings);
|
|
env = realm.getRunningContext().lexicalEnvironment;
|
|
|
|
// f. If increment is not [empty], then
|
|
if (increment) {
|
|
// i. Let incRef be the result of evaluating increment.
|
|
var incRef = env.evaluate(increment, strictCode);
|
|
|
|
// ii. Perform ? GetValue(incRef).
|
|
_singletons.Environment.GetValue(realm, incRef);
|
|
}
|
|
}
|
|
|
|
(0, _invariant2.default)(false);
|
|
}
|
|
|
|
// ECMA262 13.7.4.7
|
|
//# sourceMappingURL=ForStatement.js.map
|