"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GeneratorStart = GeneratorStart; exports.GeneratorValidate = GeneratorValidate; exports.GeneratorResume = GeneratorResume; exports.GeneratorResumeAbrupt = GeneratorResumeAbrupt; exports.GeneratorYield = GeneratorYield; var _completions = require("../completions.js"); var _index = require("../values/index.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 }; } // ECMA26225.3.3.1 function GeneratorStart(realm, generator, generatorBody) { // Note that generator is a new object, and we can thus write to internal slots (0, _invariant2.default)(realm.isNewObject(generator)); // 1. Assert: The value of generator.[[GeneratorState]] is undefined. (0, _invariant2.default)(generator instanceof _index.ObjectValue && generator.$GeneratorState === undefined, "The value of generator.[[GeneratorState]] is undefined"); // 2. Let genContext be the running execution context. var genContext = realm.getRunningContext(); // 3. Set the Generator component of genContext to generator. // 4. Set the code evaluation state of genContext such that when evaluation is resumed for that execution context the following steps will be performed: // a. Let result be the result of evaluating generatorBody. // b. Assert: If we return here, the generator either threw an exception or performed either an implicit or explicit return. // c. Remove genContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context. // d. Set generator.[[GeneratorState]] to "completed". // e. Once a generator enters the "completed" state it never leaves it and its associated execution context is never resumed. Any execution state associated with generator can be discarded at this point. // f. If result is a normal completion, let resultValue be undefined. // g. Else, // i. If result.[[Type]] is return, let resultValue be result.[[Value]]. // ii. Else, return Completion(result). // h. Return CreateIterResultObject(resultValue, true). // 5. Set generator.[[GeneratorContext]] to genContext. generator.$GeneratorContext = genContext; // 6. Set generator.[[GeneratorState]] to "suspendedStart". generator.$GeneratorState = "suspendedStart"; // 7. Return NormalCompletion(undefined). return realm.intrinsics.undefined; } // ECMA26225.3.3.2 /** * 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 GeneratorValidate(realm, generator) { // 1. If Type(generator) is not Object, throw a TypeError exception. if (!(generator instanceof _index.ObjectValue)) { throw realm.createErrorThrowCompletion(realm.intrinsics.SyntaxError, "Type(generator) is not Object"); } // 2. If generator does not have a [[GeneratorState]] internal slot, throw a TypeError exception. if (!("$GeneratorState" in generator)) { throw realm.createErrorThrowCompletion(realm.intrinsics.SyntaxError, "Type(generator) is not Object"); } // 3. Assert: generator also has a [[GeneratorContext]] internal slot. (0, _invariant2.default)("$GeneratorContext" in generator); // 4. Let state be generator.[[GeneratorState]]. var state = generator.$GeneratorState; // 5. If state is "executing", throw a TypeError exception. if (state === "executing") { throw realm.createErrorThrowCompletion(realm.intrinsics.SyntaxError, "Type(generator) is not Object"); } // 6. Return state. return state; } // ECMA26225.3.3.3 function GeneratorResume(realm, generator, value) { // 1. Let state be ? GeneratorValidate(generator). var state = GeneratorValidate(realm, generator); (0, _invariant2.default)(generator instanceof _index.ObjectValue); // 2. If state is "completed", return CreateIterResultObject(undefined, true). if (state === "completed") return _singletons.Create.CreateIterResultObject(realm, realm.intrinsics.undefined, true); // 3. Assert: state is either "suspendedStart" or "suspendedYield". (0, _invariant2.default)(state === "suspendedStart" || state === "suspendedYield", "state is either 'suspendedStart' or 'suspendedYield'"); // 4. Let genContext be generator.[[GeneratorContext]]. var genContext = generator.$GeneratorContext; (0, _invariant2.default)(genContext); // 5. Let methodContext be the running execution context. var methodContext = realm.getRunningContext(); // 6. Suspend methodContext. methodContext.suspend(); // 7. Set generator.[[GeneratorState]] to "executing". _singletons.Properties.ThrowIfInternalSlotNotWritable(realm, generator, "$GeneratorState").$GeneratorState = "executing"; // 8. Push genContext onto the execution context stack; genContext is now the running execution context. realm.pushContext(genContext); // 9. Resume the suspended evaluation of genContext using NormalCompletion(value) as the result of the operation that suspended it. Let result be the value returned by the resumed computation. var result = genContext.resume(); // 10. Assert: When we return here, genContext has already been removed from the execution context stack and methodContext is the currently running execution context. (0, _invariant2.default)(realm.getRunningContext() === methodContext); // 11. Return Completion(result). return result; } // ECMA26225.3.3.4 function GeneratorResumeAbrupt(realm, generator, abruptCompletion) { // 1. Let state be ? GeneratorValidate(generator). // 2. If state is "suspendedStart", then // a. Set generator.[[GeneratorState]] to "completed". // b. Once a generator enters the "completed" state it never leaves it and its associated execution context is never resumed. Any execution state associated with generator can be discarded at this point. // c. Let state be "completed". // 3. If state is "completed", then // a. If abruptCompletion.[[Type]] is return, then // i. Return CreateIterResultObject(abruptCompletion.[[Value]], true). // b. Return Completion(abruptCompletion). // 4. Assert: state is "suspendedYield". // 5. Let genContext be generator.[[GeneratorContext]]. // 6. Let methodContext be the running execution context. // 7. Suspend methodContext. // 8. Set generator.[[GeneratorState]] to "executing". // 9. Push genContext onto the execution context stack; genContext is now the running execution context. // 10. Resume the suspended evaluation of genContext using abruptCompletion as the result of the operation that suspended it. Let result be the completion record returned by the resumed computation. // 11. Assert: When we return here, genContext has already been removed from the execution context stack and methodContext is the currently running execution context. // 12. Return Completion(result). return realm.intrinsics.undefined; } // ECMA26225.3.3.5 function GeneratorYield(realm, iterNextObj) { // 1. Assert: iterNextObj is an Object that implements the IteratorResult interface. // 2. Let genContext be the running execution context. // 3. Assert: genContext is the execution context of a generator. // 4. Let generator be the value of the Generator component of genContext. // 5. Set generator.[[GeneratorState]] to "suspendedYield". // 6. Remove genContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context. // 7. Set the code evaluation state of genContext such that when evaluation is resumed with a Completion resumptionValue the following steps will be performed: // a. Return resumptionValue. // b. NOTE: This returns to the evaluation of the YieldExpression production that originally called this abstract operation. // 8. Return NormalCompletion(iterNextObj). return realm.intrinsics.undefined; // 9. NOTE: This returns to the evaluation of the operation that had most previously resumed evaluation of genContext. } //# sourceMappingURL=generator.js.map