// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --ignition-generators

// Test generator states.

function Foo() {}
function Bar() {}

function assertIteratorResult(value, done, result) {
  assertEquals({ value: value, done: done}, result);
}

function assertIteratorIsClosed(iter) {
  assertIteratorResult(undefined, true, iter.next());
  // Next and throw on a closed iterator.
  assertDoesNotThrow(function() { iter.next(); });
  assertThrows(function() { iter.throw(new Bar); }, Bar);
}

var iter;
function* nextGenerator() { yield iter.next(); }
function* throwGenerator() { yield iter.throw(new Bar); }

// Throw on a suspendedStart iterator.
iter = nextGenerator();
assertThrows(function() { iter.throw(new Foo) }, Foo)
assertIteratorIsClosed(iter);
assertThrows(function() { iter.throw(new Foo) }, Foo)
assertIteratorIsClosed(iter);

// The same.
iter = throwGenerator();
assertThrows(function() { iter.throw(new Foo) }, Foo)
assertThrows(function() { iter.throw(new Foo) }, Foo)
assertIteratorIsClosed(iter);

// Next on an executing iterator raises a TypeError.
iter = nextGenerator();
assertThrows(function() { iter.next() }, TypeError)
assertIteratorIsClosed(iter);

// Throw on an executing iterator raises a TypeError.
iter = throwGenerator();
assertThrows(function() { iter.next() }, TypeError)
assertIteratorIsClosed(iter);

// Next on an executing iterator doesn't change the state of the
// generator.
iter = (function* () {
  try {
    iter.next();
    yield 1;
  } catch (e) {
    try {
      // This next() should raise the same exception, because the first
      // next() left the iter in the executing state.
      iter.next();
      yield 2;
    } catch (e) {
      yield 3;
    }
  }
  yield 4;
})();
assertIteratorResult(3, false, iter.next());
assertIteratorResult(4, false, iter.next());
assertIteratorIsClosed(iter);


// A return that doesn't close.
{
  let g = function*() { try {return 42} finally {yield 43} };

  let x = g();
  assertEquals({value: 43, done: false}, x.next());
  assertEquals({value: 42, done: true}, x.next());
}
{
  let x;
  let g = function*() { try {return 42} finally {x.throw(666)} };

  x = g();
  assertThrows(() => x.next(), TypeError);  // Still executing.
}
{
  let x;
  let g = function*() {
    try {return 42} finally {try {x.throw(666)} catch(e) {}}
  };

  x = g();
  assertEquals({value: 42, done: true}, x.next());
}
