UNPKG

prepack

Version:

Execute a JS bundle, serialize global state and side effects to a snapshot that can be quickly restored.

220 lines (179 loc) 9.15 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CreatePerIterationEnvironment = CreatePerIterationEnvironment; exports.default = function (ast, strictCode, env, realm, labelSet) { let { init, test, update, body } = ast; if (init && init.type === "VariableDeclaration") { if (init.kind === "var") { // for (var VariableDeclarationList; Expression; Expression) Statement // 1. Let varDcl be the result of evaluating VariableDeclarationList. let 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. let oldEnv = env; // 2. Let loopEnv be NewDeclarativeEnvironment(oldEnv). let loopEnv = _singletons.Environment.NewDeclarativeEnvironment(realm, oldEnv); // 3. Let loopEnvRec be loopEnv's EnvironmentRecord. let loopEnvRec = loopEnv.environmentRecord; // 4. Let isConst be the result of performing IsConstantDeclaration of LexicalDeclaration. let isConst = init.kind === "const"; // 5. Let boundNames be the BoundNames of LexicalDeclaration. let boundNames = _singletons.Environment.BoundNames(realm, init); // 6. For each element dn of boundNames do for (let dn of boundNames) { // 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. realm.getRunningContext().lexicalEnvironment = loopEnv; // 8. Let forDcl be the result of evaluating LexicalDeclaration. let 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. let 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 « ». let perIterationLets = !isConst ? boundNames : []; let bodyResult; 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. let 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. let 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. let lastIterationEnv = realm.getRunningContext().lexicalEnvironment; // b. Let lastIterationEnvRec be lastIterationEnv's EnvironmentRecord. let lastIterationEnvRec = lastIterationEnv.environmentRecord; // c. Let outer be lastIterationEnv's outer environment reference. let outer = lastIterationEnv.parent; // d. Assert: outer is not null. (0, _invariant2.default)(outer !== null); // e. Let thisIterationEnv be NewDeclarativeEnvironment(outer). let thisIterationEnv = _singletons.Environment.NewDeclarativeEnvironment(realm, outer); // f. Let thisIterationEnvRec be thisIterationEnv's EnvironmentRecord. realm.onDestroyScope(lastIterationEnv); let thisIterationEnvRec = thisIterationEnv.environmentRecord; // g. For each element bn of perIterationBindings do, for (let bn of perIterationBindings) { // i. Perform ! thisIterationEnvRec.CreateMutableBinding(bn, false). thisIterationEnvRec.CreateMutableBinding(bn, false); // ii. Let lastValue be ? lastIterationEnvRec.GetBindingValue(bn, true). let 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. 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. let V = realm.intrinsics.undefined; // 2. Perform ? CreatePerIterationEnvironment(perIterationBindings). CreatePerIterationEnvironment(realm, perIterationBindings); let 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. let testRef = env.evaluate(test, strictCode); // ii. Let testValue be ? GetValue(testRef). let 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. let 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]]. let 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. let 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