GeneratorStart.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. 'use strict';
  2. var $TypeError = require('es-errors/type');
  3. var CreateIteratorResultObject = require('./CreateIteratorResultObject');
  4. var IsCallable = require('./IsCallable');
  5. var SLOT = require('internal-slot');
  6. var isObject = require('es-object-atoms/isObject');
  7. // https://262.ecma-international.org/16.0/#sec-generatorstart
  8. module.exports = function GeneratorStart(generator, closure) {
  9. SLOT.assert(generator, '[[GeneratorState]]');
  10. SLOT.assert(generator, '[[GeneratorContext]]');
  11. SLOT.assert(generator, '[[GeneratorBrand]]');
  12. SLOT.assert(generator, '[[Sentinel]]'); // our userland slot
  13. SLOT.assert(generator, '[[CloseIfAbrupt]]'); // our second userland slot
  14. if (!IsCallable(closure) || closure.length !== 0) {
  15. throw new $TypeError('`closure` must be a function that takes no arguments');
  16. }
  17. var sentinel = SLOT.get(closure, '[[Sentinel]]');
  18. if (!isObject(sentinel)) {
  19. throw new $TypeError('`closure.[[Sentinel]]` must be an object');
  20. }
  21. SLOT.set(generator, '[[GeneratorContext]]', function () { // steps 2-5
  22. try {
  23. var result = closure();
  24. if (result === sentinel) {
  25. SLOT.set(generator, '[[GeneratorState]]', 'COMPLETED');
  26. SLOT.set(generator, '[[GeneratorContext]]', null);
  27. return CreateIteratorResultObject(void undefined, true);
  28. }
  29. SLOT.set(generator, '[[GeneratorState]]', 'SUSPENDED-YIELD');
  30. return CreateIteratorResultObject(result, false);
  31. } catch (e) {
  32. SLOT.set(generator, '[[GeneratorState]]', 'COMPLETED');
  33. SLOT.set(generator, '[[GeneratorContext]]', null);
  34. throw e;
  35. }
  36. });
  37. SLOT.set(generator, '[[GeneratorState]]', 'SUSPENDED-START'); // step 6
  38. };