mirror of
				https://github.com/tc39/test262.git
				synced 2025-11-03 21:24:30 +01:00 
			
		
		
		
	sourceRevisionAtLastExport: 33f2fb0e53d135f0ee17cfccd9d993eb2a6f47de targetRevisionAtLastExport: 31340cbd9add103f586d501b0c3354b7b182abc0
		
			
				
	
	
		
			1265 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			1265 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// Copyright 2017 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: --allow-natives-syntax
 | 
						|
 | 
						|
let testFailed = false;
 | 
						|
let testFailure;
 | 
						|
(async function() {
 | 
						|
  const kNext = 1;
 | 
						|
  const kThrow = 2;
 | 
						|
  const kReturn = 4;
 | 
						|
  const kReturnPrimitive = kReturn | 32;
 | 
						|
 | 
						|
  function async(iterable, features = kNext, log = []) {
 | 
						|
    // Helper to turn a synchronous iterable into an asynchronous iterable,
 | 
						|
    // without using the [Async-from-Sync Iterator].
 | 
						|
    let it = iterable[Symbol.iterator]();
 | 
						|
    let methods = {
 | 
						|
      next(sentValue) {
 | 
						|
        return new Promise(function(resolve, reject) {
 | 
						|
          let {value, done} = it.next(sentValue);
 | 
						|
          Promise.resolve(value).then(function(value) {
 | 
						|
            log.push('.next() -> resolved ' + value);
 | 
						|
            resolve({value, done});
 | 
						|
          }, function(value) {
 | 
						|
            log.push('.next() -> rejected ' + value);
 | 
						|
            reject(value);
 | 
						|
          });
 | 
						|
        });
 | 
						|
      },
 | 
						|
 | 
						|
      throw(sentValue) {
 | 
						|
        return new Promise(function(resolve, reject) {
 | 
						|
          let throwMethod = it.throw;
 | 
						|
          if (typeof throwMethod !== 'function') {
 | 
						|
            log.push('.throw(' + sentValue + ')');
 | 
						|
            return reject(sentValue);
 | 
						|
          }
 | 
						|
 | 
						|
          let {value, done} = throwMethod.call(it, sentValue);
 | 
						|
          Promise.resolve(value).then(function(value) {
 | 
						|
                log.push('.throw() -> resolved ' + value);
 | 
						|
                resolve({ value, done });
 | 
						|
              }, function(value) {
 | 
						|
                log.push('.throw() -> rejected ' + value);
 | 
						|
                reject(value);
 | 
						|
              });
 | 
						|
        });
 | 
						|
      },
 | 
						|
 | 
						|
      return(sentValue) {
 | 
						|
        return new Promise(function(resolve, reject) {
 | 
						|
          let returnMethod = it.return;
 | 
						|
          if (typeof returnMethod !== 'function') {
 | 
						|
            log.push('.return(' + sentValue + ')');
 | 
						|
            if ((features & kReturnPrimitive) === kReturnPrimitive)
 | 
						|
                return resolve(sentValue);
 | 
						|
            return resolve({value: sentValue, done: true});
 | 
						|
          }
 | 
						|
 | 
						|
          let {value, done} = returnMethod.call(it, sentValue);
 | 
						|
          Promise.resolve(value).then(function(value) {
 | 
						|
            log.push('.return() -> resolved ' + value);
 | 
						|
            if ((features & kReturnPrimitive) === kReturnPrimitive)
 | 
						|
                return resolve(value);
 | 
						|
            resolve({ value, done });
 | 
						|
          }, function(value) {
 | 
						|
            log.push('.return() -> rejected ' + value);
 | 
						|
            reject(value);
 | 
						|
          });
 | 
						|
        });
 | 
						|
      }
 | 
						|
    };
 | 
						|
 | 
						|
 | 
						|
    return {
 | 
						|
      [Symbol.asyncIterator]() {
 | 
						|
        log.push('[Symbol.asyncIterator]()')
 | 
						|
        return this;
 | 
						|
      },
 | 
						|
 | 
						|
      next: (features & kNext) ? methods.next : undefined,
 | 
						|
      throw: (features & kThrow) ? methods.throw : undefined,
 | 
						|
      return: (features & kReturn) ? methods.return : undefined
 | 
						|
    };
 | 
						|
  }
 | 
						|
 | 
						|
  let testDone;
 | 
						|
  let test;
 | 
						|
  async function testBindingIdentifierVarDeclarationStatement() {
 | 
						|
    let sum = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (var value of async([100, 200, 300, 400, 500])) sum += value;
 | 
						|
    testDone = true;
 | 
						|
    return sum;
 | 
						|
  }
 | 
						|
 | 
						|
  test = testBindingIdentifierVarDeclarationStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(1500, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testBindingIdentifierVarDeclarationBlockStatement() {
 | 
						|
    let sum = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (var value of async([100, 200, 300, 400, 500])) {
 | 
						|
      'use strict';
 | 
						|
      let strict = (function() { return this === undefined; })();
 | 
						|
      assertFalse(strict);
 | 
						|
      sum += value;
 | 
						|
    }
 | 
						|
    testDone = true;
 | 
						|
    return sum;
 | 
						|
  }
 | 
						|
 | 
						|
  test = testBindingIdentifierVarDeclarationBlockStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(1500, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testObjectBindingPatternVarDeclarationStatement() {
 | 
						|
    let sum = 0, keys = [];
 | 
						|
    let collection = [
 | 
						|
      {key: 'first', value: 10}, {key: undefined, value: 20}, {value: 30},
 | 
						|
      {key: 'last', value: 40}
 | 
						|
    ];
 | 
						|
    testDone = false;
 | 
						|
    for await (var {key = 'unknown', value} of async(collection))
 | 
						|
        keys.push(key), sum += value;
 | 
						|
    testDone = true;
 | 
						|
    return {keys, sum};
 | 
						|
  }
 | 
						|
 | 
						|
  test = testObjectBindingPatternVarDeclarationStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(
 | 
						|
      {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testObjectBindingPatternVarDeclarationBlockStatement() {
 | 
						|
    let sum = 0, keys = [];
 | 
						|
    let collection = [
 | 
						|
      {key: 'first', value: 10}, {key: undefined, value: 20}, {value: 30},
 | 
						|
      {key: 'last', value: 40}
 | 
						|
    ];
 | 
						|
    testDone = false;
 | 
						|
    for await (var {key = 'unknown', value} of async(collection)) {
 | 
						|
      'use strict';
 | 
						|
      let strict = (function() { return this === undefined; })();
 | 
						|
      assertFalse(strict);
 | 
						|
      keys.push(key);
 | 
						|
      sum += value;
 | 
						|
    }
 | 
						|
    testDone = true;
 | 
						|
    return {keys, sum};
 | 
						|
  }
 | 
						|
 | 
						|
  test = testObjectBindingPatternVarDeclarationBlockStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(
 | 
						|
      {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testArrayBindingPatternVarDeclarationStatement() {
 | 
						|
    let sum = 0, keys = [];
 | 
						|
    let collection = [['first', 10], [undefined, 20], [, 30], ['last', 40]];
 | 
						|
    testDone = false;
 | 
						|
    for await (var [key = 'unknown', value] of async(collection))
 | 
						|
        keys.push(key), sum += value;
 | 
						|
    testDone = true;
 | 
						|
    return {keys, sum};
 | 
						|
  }
 | 
						|
 | 
						|
  test = testArrayBindingPatternVarDeclarationStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(
 | 
						|
      {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testArrayBindingPatternVarDeclarationBlockStatement() {
 | 
						|
    let sum = 0, keys = [];
 | 
						|
    let collection = [['first', 10], [undefined, 20], [, 30], ['last', 40]];
 | 
						|
    testDone = false;
 | 
						|
    for await (var [key = 'unknown', value] of async(collection)) {
 | 
						|
      'use strict';
 | 
						|
      let strict = (function() { return this === undefined; })();
 | 
						|
      assertFalse(strict);
 | 
						|
      keys.push(key);
 | 
						|
      sum += value;
 | 
						|
    }
 | 
						|
    testDone = true;
 | 
						|
    return {keys, sum};
 | 
						|
  }
 | 
						|
 | 
						|
  test = testArrayBindingPatternVarDeclarationBlockStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(
 | 
						|
      {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  // --------------------------------------------------------------------------
 | 
						|
 | 
						|
  async function testBindingIdentifierLetDeclarationStatement() {
 | 
						|
    let sum = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (let value of async([100, 200, 300, 400, 500])) sum += value;
 | 
						|
    testDone = true;
 | 
						|
    return sum;
 | 
						|
  }
 | 
						|
 | 
						|
  test = testBindingIdentifierLetDeclarationStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(1500, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testBindingIdentifierLetDeclarationBlockStatement() {
 | 
						|
    let sum = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (let value of async([100, 200, 300, 400, 500])) {
 | 
						|
      'use strict';
 | 
						|
      let strict = (function() { return this === undefined; })();
 | 
						|
      assertFalse(strict);
 | 
						|
      sum += value;
 | 
						|
    }
 | 
						|
    testDone = true;
 | 
						|
    return sum;
 | 
						|
  }
 | 
						|
 | 
						|
  test = testBindingIdentifierLetDeclarationBlockStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(1500, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testObjectBindingPatternLetDeclarationStatement() {
 | 
						|
    let sum = 0, keys = [];
 | 
						|
    let collection = [
 | 
						|
      {key: 'first', value: 10}, {key: undefined, value: 20}, {value: 30},
 | 
						|
      {key: 'last', value: 40}
 | 
						|
    ];
 | 
						|
    testDone = false;
 | 
						|
    for await (let {key = 'unknown', value} of async(collection))
 | 
						|
        keys.push(key), sum += value;
 | 
						|
    testDone = true;
 | 
						|
    return {keys, sum};
 | 
						|
  }
 | 
						|
 | 
						|
  test = testObjectBindingPatternLetDeclarationStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(
 | 
						|
      {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testObjectBindingPatternLetDeclarationBlockStatement() {
 | 
						|
    let sum = 0, keys = [];
 | 
						|
    let collection = [
 | 
						|
      {key: 'first', value: 10}, {key: undefined, value: 20}, {value: 30},
 | 
						|
      {key: 'last', value: 40}
 | 
						|
    ];
 | 
						|
    testDone = false;
 | 
						|
    for await (let {key = 'unknown', value} of async(collection)) {
 | 
						|
      'use strict';
 | 
						|
      let strict = (function() { return this === undefined; })();
 | 
						|
      assertFalse(strict);
 | 
						|
      keys.push(key);
 | 
						|
      sum += value;
 | 
						|
    }
 | 
						|
    testDone = true;
 | 
						|
    return {keys, sum};
 | 
						|
  }
 | 
						|
 | 
						|
  let threwEarly = false;
 | 
						|
  test = testObjectBindingPatternLetDeclarationBlockStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(
 | 
						|
      {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testObjectBindingPatternTDZLetDeclarationStatement() {
 | 
						|
    // See https://codereview.chromium.org/1218543003
 | 
						|
    let sum = 0;
 | 
						|
    testDone = false;
 | 
						|
    let value = { value: 1 };
 | 
						|
    try {
 | 
						|
      for await (let {value} of async([value])) sum += value;
 | 
						|
    } catch (error) {
 | 
						|
      threwEarly = true;
 | 
						|
      throw { sum, error, toString() { return 'TestError' } };
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  test = testObjectBindingPatternTDZLetDeclarationStatement();
 | 
						|
  assertTrue(threwEarly, 'Async function promise should be rejected');
 | 
						|
  try {
 | 
						|
    await test;
 | 
						|
  } catch (e) {
 | 
						|
    assertEquals('TestError', e.toString());
 | 
						|
    assertEquals(0, e.sum);
 | 
						|
    assertInstanceof(e.error, ReferenceError);
 | 
						|
    testDone = true;
 | 
						|
  }
 | 
						|
  assertTrue(testDone, 'Awaited promise should be rejected');
 | 
						|
 | 
						|
  async function testObjectBindingPatternTDZLetDeclarationBlockStatement() {
 | 
						|
    // See https://codereview.chromium.org/1218543003
 | 
						|
    let sum = 0;
 | 
						|
    testDone = false;
 | 
						|
    let value = { value: 1 };
 | 
						|
    try {
 | 
						|
      for await (let {value} of async([value])) {
 | 
						|
        sum += value;
 | 
						|
      }
 | 
						|
    } catch (error) {
 | 
						|
      threwEarly = true;
 | 
						|
      throw { sum, error, toString() { return 'TestError' } };
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  threwEarly = false;
 | 
						|
  test = testObjectBindingPatternTDZLetDeclarationBlockStatement();
 | 
						|
  assertTrue(threwEarly, 'Async function promise should be rejected');
 | 
						|
  try {
 | 
						|
    await test;
 | 
						|
  } catch (e) {
 | 
						|
    assertEquals('TestError', e.toString());
 | 
						|
    assertEquals(0, e.sum);
 | 
						|
    assertInstanceof(e.error, ReferenceError);
 | 
						|
    testDone = true;
 | 
						|
  }
 | 
						|
  assertTrue(testDone, 'Awaited promise should be rejected');
 | 
						|
 | 
						|
  async function testArrayBindingPatternLetDeclarationStatement() {
 | 
						|
    let sum = 0, keys = [];
 | 
						|
    let collection = [['first', 10], [undefined, 20], [, 30], ['last', 40]];
 | 
						|
    testDone = false;
 | 
						|
    for await (let [key = 'unknown', value] of async(collection))
 | 
						|
        keys.push(key), sum += value;
 | 
						|
    testDone = true;
 | 
						|
    return {keys, sum};
 | 
						|
  }
 | 
						|
 | 
						|
  test = testArrayBindingPatternLetDeclarationStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(
 | 
						|
      {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testArrayBindingPatternLetDeclarationBlockStatement() {
 | 
						|
    let sum = 0, keys = [];
 | 
						|
    let collection = [['first', 10], [undefined, 20], [, 30], ['last', 40]];
 | 
						|
    testDone = false;
 | 
						|
    for await (let [key = 'unknown', value] of async(collection)) {
 | 
						|
      'use strict';
 | 
						|
      let strict = (function() { return this === undefined; })();
 | 
						|
      assertFalse(strict);
 | 
						|
      keys.push(key);
 | 
						|
      sum += value;
 | 
						|
    }
 | 
						|
    testDone = true;
 | 
						|
    return {keys, sum};
 | 
						|
  }
 | 
						|
 | 
						|
  test = testArrayBindingPatternLetDeclarationBlockStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(
 | 
						|
      {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testArrayBindingPatternTDZLetDeclarationStatement() {
 | 
						|
    // See https://codereview.chromium.org/1218543003
 | 
						|
    let sum = 0;
 | 
						|
    testDone = false;
 | 
						|
    let value = [1];
 | 
						|
    try {
 | 
						|
      for await (let [value] of async([value])) sum += value;
 | 
						|
    } catch (error) {
 | 
						|
      threwEarly = true;
 | 
						|
      throw { sum, error, toString() { return 'TestError' } };
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  threwEarly = false;
 | 
						|
  test = testArrayBindingPatternTDZLetDeclarationStatement();
 | 
						|
  assertTrue(threwEarly, 'Async function promise should be rejected');
 | 
						|
  try {
 | 
						|
    await test;
 | 
						|
  } catch (e) {
 | 
						|
    assertEquals('TestError', e.toString());
 | 
						|
    assertEquals(0, e.sum);
 | 
						|
    assertInstanceof(e.error, ReferenceError);
 | 
						|
    testDone = true;
 | 
						|
  }
 | 
						|
  assertTrue(testDone, 'Awaited promise should be rejected');
 | 
						|
 | 
						|
  async function testArrayBindingPatternTDZLetDeclarationBlockStatement() {
 | 
						|
    // See https://codereview.chromium.org/1218543003
 | 
						|
    let sum = 0;
 | 
						|
    testDone = false;
 | 
						|
    let value = [1];
 | 
						|
    try {
 | 
						|
      for await (let [value] of async([value])) {
 | 
						|
        sum += value;
 | 
						|
      }
 | 
						|
    } catch (error) {
 | 
						|
      threwEarly = true;
 | 
						|
      throw { sum, error, toString() { return 'TestError' } };
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  threwEarly = false;
 | 
						|
  test = testArrayBindingPatternTDZLetDeclarationBlockStatement();
 | 
						|
  assertTrue(threwEarly, 'Async function promise should be rejected');
 | 
						|
  try {
 | 
						|
    await test;
 | 
						|
  } catch (e) {
 | 
						|
    assertEquals('TestError', e.toString());
 | 
						|
    assertEquals(0, e.sum);
 | 
						|
    assertInstanceof(e.error, ReferenceError);
 | 
						|
    testDone = true;
 | 
						|
  }
 | 
						|
  assertTrue(testDone, 'Awaited promise should be rejected');
 | 
						|
 | 
						|
  // --------------------------------------------------------------------------
 | 
						|
 | 
						|
  async function testBindingIdentifierConstDeclarationStatement() {
 | 
						|
    let sum = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (let value of async([100, 200, 300, 400, 500])) sum += value;
 | 
						|
    testDone = true;
 | 
						|
    return sum;
 | 
						|
  }
 | 
						|
 | 
						|
  test = testBindingIdentifierConstDeclarationStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(1500, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testBindingIdentifierConstDeclarationBlockStatement() {
 | 
						|
    let sum = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (const value of async([100, 200, 300, 400, 500])) {
 | 
						|
      'use strict';
 | 
						|
      let strict = (function() { return this === undefined; })();
 | 
						|
      assertFalse(strict);
 | 
						|
      sum += value;
 | 
						|
    }
 | 
						|
    testDone = true;
 | 
						|
    return sum;
 | 
						|
  }
 | 
						|
 | 
						|
  test = testBindingIdentifierConstDeclarationBlockStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(1500, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testObjectBindingPatternConstDeclarationStatement() {
 | 
						|
    let sum = 0, keys = [];
 | 
						|
    let collection = [
 | 
						|
      {key: 'first', value: 10}, {key: undefined, value: 20}, {value: 30},
 | 
						|
      {key: 'last', value: 40}
 | 
						|
    ];
 | 
						|
    testDone = false;
 | 
						|
    for await (const {key = 'unknown', value} of async(collection))
 | 
						|
        keys.push(key), sum += value;
 | 
						|
    testDone = true;
 | 
						|
    return {keys, sum};
 | 
						|
  }
 | 
						|
 | 
						|
  test = testObjectBindingPatternConstDeclarationStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(
 | 
						|
      {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testObjectBindingPatternConstDeclarationBlockStatement() {
 | 
						|
    let sum = 0, keys = [];
 | 
						|
    let collection = [
 | 
						|
      {key: 'first', value: 10}, {key: undefined, value: 20}, {value: 30},
 | 
						|
      {key: 'last', value: 40}
 | 
						|
    ];
 | 
						|
    testDone = false;
 | 
						|
    for await (const {key = 'unknown', value} of async(collection)) {
 | 
						|
      'use strict';
 | 
						|
      let strict = (function() { return this === undefined; })();
 | 
						|
      assertFalse(strict);
 | 
						|
      keys.push(key);
 | 
						|
      sum += value;
 | 
						|
    }
 | 
						|
    testDone = true;
 | 
						|
    return {keys, sum};
 | 
						|
  }
 | 
						|
 | 
						|
  test = testObjectBindingPatternConstDeclarationBlockStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(
 | 
						|
      {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testObjectBindingPatternTDZConstDeclarationStatement() {
 | 
						|
    // See https://codereview.chromium.org/1218543003
 | 
						|
    let sum = 0;
 | 
						|
    testDone = false;
 | 
						|
    const value = { value: 1 };
 | 
						|
    try {
 | 
						|
      for await (const {value} of async([value])) sum += value;
 | 
						|
    } catch (error) {
 | 
						|
      threwEarly = true;
 | 
						|
      throw { sum, error, toString() { return 'TestError' } };
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  threwEarly = false;
 | 
						|
  test = testObjectBindingPatternTDZConstDeclarationStatement();
 | 
						|
  assertTrue(threwEarly, 'Async function promise should be rejected');
 | 
						|
  try {
 | 
						|
    await test;
 | 
						|
  } catch (e) {
 | 
						|
    assertEquals('TestError', e.toString());
 | 
						|
    assertEquals(0, e.sum);
 | 
						|
    assertInstanceof(e.error, ReferenceError);
 | 
						|
    testDone = true;
 | 
						|
  }
 | 
						|
  assertTrue(testDone, 'Awaited promise should be rejected');
 | 
						|
 | 
						|
  async function testObjectBindingPatternTDZConstDeclarationBlockStatement() {
 | 
						|
    // See https://codereview.chromium.org/1218543003
 | 
						|
    let sum = 0;
 | 
						|
    testDone = false;
 | 
						|
    const value = { value: 1 };
 | 
						|
    try {
 | 
						|
      for await (const {value} of async([value])) {
 | 
						|
        sum += value;
 | 
						|
      }
 | 
						|
    } catch (error) {
 | 
						|
      threwEarly = true;
 | 
						|
      throw { sum, error, toString() { return 'TestError' } };
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  threwEarly = false;
 | 
						|
  test = testObjectBindingPatternTDZConstDeclarationBlockStatement();
 | 
						|
  assertTrue(threwEarly, 'Async function promise should be rejected');
 | 
						|
  try {
 | 
						|
    await test;
 | 
						|
  } catch (e) {
 | 
						|
    assertEquals('TestError', e.toString());
 | 
						|
    assertEquals(0, e.sum);
 | 
						|
    assertInstanceof(e.error, ReferenceError);
 | 
						|
    testDone = true;
 | 
						|
  }
 | 
						|
  assertTrue(testDone, 'Awaited promise should be rejected');
 | 
						|
 | 
						|
  async function testArrayBindingPatternConstDeclarationStatement() {
 | 
						|
    let sum = 0, keys = [];
 | 
						|
    let collection = [['first', 10], [undefined, 20], [, 30], ['last', 40]];
 | 
						|
    testDone = false;
 | 
						|
    for await (const [key = 'unknown', value] of async(collection))
 | 
						|
        keys.push(key), sum += value;
 | 
						|
    testDone = true;
 | 
						|
    return {keys, sum};
 | 
						|
  }
 | 
						|
 | 
						|
  test = testArrayBindingPatternConstDeclarationStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(
 | 
						|
      {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testArrayBindingPatternConstDeclarationBlockStatement() {
 | 
						|
    let sum = 0, keys = [];
 | 
						|
    let collection = [['first', 10], [undefined, 20], [, 30], ['last', 40]];
 | 
						|
    testDone = false;
 | 
						|
    for await (const [key = 'unknown', value] of async(collection)) {
 | 
						|
      'use strict';
 | 
						|
      let strict = (function() { return this === undefined; })();
 | 
						|
      assertFalse(strict);
 | 
						|
      keys.push(key);
 | 
						|
      sum += value;
 | 
						|
    }
 | 
						|
    testDone = true;
 | 
						|
    return {keys, sum};
 | 
						|
  }
 | 
						|
 | 
						|
  test = testArrayBindingPatternLetDeclarationBlockStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(
 | 
						|
      {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testArrayBindingPatternTDZConstDeclarationStatement() {
 | 
						|
    // See https://codereview.chromium.org/1218543003
 | 
						|
    let sum = 0;
 | 
						|
    testDone = false;
 | 
						|
    const value = [1];
 | 
						|
    try {
 | 
						|
      for await (const [value] of async([value])) sum += value;
 | 
						|
    } catch (error) {
 | 
						|
      threwEarly = true;
 | 
						|
      throw { sum, error, toString() { return 'TestError' } };
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  threwEarly = false;
 | 
						|
  test = testArrayBindingPatternTDZConstDeclarationStatement();
 | 
						|
  assertTrue(threwEarly, 'Async function promise should be rejected');
 | 
						|
  try {
 | 
						|
    await test;
 | 
						|
  } catch (e) {
 | 
						|
    assertEquals('TestError', e.toString());
 | 
						|
    assertEquals(0, e.sum);
 | 
						|
    assertInstanceof(e.error, ReferenceError);
 | 
						|
    testDone = true;
 | 
						|
  }
 | 
						|
  assertTrue(testDone, 'Awaited promise should be rejected');
 | 
						|
 | 
						|
  async function testArrayBindingPatternTDZConstDeclarationBlockStatement() {
 | 
						|
    // See https://codereview.chromium.org/1218543003
 | 
						|
    let sum = 0;
 | 
						|
    testDone = false;
 | 
						|
    const value = [1];
 | 
						|
    try {
 | 
						|
      for await (const [value] of async([value])) {
 | 
						|
        sum += value;
 | 
						|
      }
 | 
						|
    } catch (error) {
 | 
						|
      threwEarly = true;
 | 
						|
      throw { sum, error, toString() { return 'TestError' } };
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  threwEarly = false;
 | 
						|
  test = testArrayBindingPatternTDZConstDeclarationBlockStatement();
 | 
						|
  assertTrue(threwEarly, 'Async function promise should be rejected');
 | 
						|
  try {
 | 
						|
    await test;
 | 
						|
  } catch (e) {
 | 
						|
    assertEquals('TestError', e.toString());
 | 
						|
    assertEquals(0, e.sum);
 | 
						|
    assertInstanceof(e.error, ReferenceError);
 | 
						|
    testDone = true;
 | 
						|
  }
 | 
						|
  assertTrue(testDone, 'Awaited promise should be rejected');
 | 
						|
 | 
						|
  // --------------------------------------------------------------------------
 | 
						|
 | 
						|
  async function testBindingIdentifierLHSStatement() {
 | 
						|
    let sum = 0;
 | 
						|
    let value;
 | 
						|
    testDone = false;
 | 
						|
    for await (value of async([100, 200, 300, 400, 500])) sum += value;
 | 
						|
    testDone = true;
 | 
						|
    return sum;
 | 
						|
  }
 | 
						|
 | 
						|
  test = testBindingIdentifierLHSStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(1500, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testBindingIdentifierLHSBlockStatement() {
 | 
						|
    let sum = 0;
 | 
						|
    let value;
 | 
						|
    testDone = false;
 | 
						|
    for await (value of async([100, 200, 300, 400, 500])) {
 | 
						|
      'use strict';
 | 
						|
      let strict = (function() { return this === undefined; })();
 | 
						|
      assertFalse(strict);
 | 
						|
      sum += value;
 | 
						|
    }
 | 
						|
    testDone = true;
 | 
						|
    return sum;
 | 
						|
  }
 | 
						|
 | 
						|
  test = testBindingIdentifierLHSStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(1500, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testObjectBindingPatternLHSStatement() {
 | 
						|
    let sum = 0;
 | 
						|
    let keys = [];
 | 
						|
    let value;
 | 
						|
    let key;
 | 
						|
    let collection = [
 | 
						|
      {key: 'first', value: 1}, {key: undefined, value: 2}, {value: 3},
 | 
						|
      {key: 'last', value: 4}
 | 
						|
    ];
 | 
						|
    testDone = false;
 | 
						|
    for await ({key = 'unknown', value} of async(collection))
 | 
						|
        keys.push(key), sum += value;
 | 
						|
    testDone = true;
 | 
						|
    return {keys, sum};
 | 
						|
  }
 | 
						|
 | 
						|
  test = testObjectBindingPatternLHSStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(
 | 
						|
      {keys: ['first', 'unknown', 'unknown', 'last'], sum: 10}, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testObjectBindingPatternLHSBlockStatement() {
 | 
						|
    let sum = 0;
 | 
						|
    let keys = [];
 | 
						|
    let value;
 | 
						|
    let key;
 | 
						|
    let collection = [
 | 
						|
      {key: 'first', value: 1}, {key: undefined, value: 2}, {value: 3},
 | 
						|
      {key: 'last', value: 4}
 | 
						|
    ];
 | 
						|
    testDone = false;
 | 
						|
    for await ({key = 'unknown', value} of async(collection)) {
 | 
						|
      'use strict';
 | 
						|
      let strict = (function() { return this === undefined; })();
 | 
						|
      assertFalse(strict);
 | 
						|
      keys.push(key);
 | 
						|
      sum += value;
 | 
						|
    }
 | 
						|
    testDone = true;
 | 
						|
    return {keys, sum};
 | 
						|
  }
 | 
						|
 | 
						|
  test = testObjectBindingPatternLHSBlockStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(
 | 
						|
      {keys: ['first', 'unknown', 'unknown', 'last'], sum: 10}, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testArrayBindingPatternLHSStatement() {
 | 
						|
    let sum = 0;
 | 
						|
    let keys = [];
 | 
						|
    let value;
 | 
						|
    let key;
 | 
						|
    let collection = [['first', 1], [undefined, 2], [, 3], ['last', 4]];
 | 
						|
    testDone = false;
 | 
						|
    for await ([key = 'unknown', value] of async(collection)) {
 | 
						|
      'use strict';
 | 
						|
      let strict = (function() { return this === undefined; })();
 | 
						|
      assertFalse(strict);
 | 
						|
      keys.push(key);
 | 
						|
      sum += value;
 | 
						|
    }
 | 
						|
    testDone = true;
 | 
						|
    return {keys, sum};
 | 
						|
  }
 | 
						|
 | 
						|
  test = testArrayBindingPatternLHSStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(
 | 
						|
      {keys: ['first', 'unknown', 'unknown', 'last'], sum: 10}, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testArrayBindingPatternLHSBlockStatement() {
 | 
						|
    let sum = 0;
 | 
						|
    let keys = [];
 | 
						|
    let value;
 | 
						|
    let key;
 | 
						|
    let collection = [
 | 
						|
      {key: 'first', value: 1}, {key: undefined, value: 2}, {value: 3},
 | 
						|
      {key: 'last', value: 4}
 | 
						|
    ];
 | 
						|
    testDone = false;
 | 
						|
    for await ({key = 'unknown', value} of async(collection)) {
 | 
						|
      'use strict';
 | 
						|
      let strict = (function() { return this === undefined; })();
 | 
						|
      assertFalse(strict);
 | 
						|
      keys.push(key);
 | 
						|
      sum += value;
 | 
						|
    }
 | 
						|
    testDone = true;
 | 
						|
    return {keys, sum};
 | 
						|
  }
 | 
						|
 | 
						|
  test = testArrayBindingPatternLHSBlockStatement();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals(
 | 
						|
      {keys: ['first', 'unknown', 'unknown', 'last'], sum: 10}, await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  // --------------------------------------------------------------------------
 | 
						|
 | 
						|
  async function testBreakStatementReturnMethodNotPresent() {
 | 
						|
    let log = [];
 | 
						|
    let collection = [1, 2, 3, 4, 5];
 | 
						|
    let sum = 0;
 | 
						|
    let i = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (var x of async(collection, kNext, log)) {
 | 
						|
      sum += x;
 | 
						|
      if (++i === 3) break;
 | 
						|
    }
 | 
						|
    testDone = true;
 | 
						|
    return { sum, log };
 | 
						|
  }
 | 
						|
 | 
						|
  test = testBreakStatementReturnMethodNotPresent();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals({sum: 6, log: ['[Symbol.asyncIterator]()',
 | 
						|
                              '.next() -> resolved 1',
 | 
						|
                              '.next() -> resolved 2',
 | 
						|
                              '.next() -> resolved 3']},
 | 
						|
               await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testBreakStatementReturnMethodPresent() {
 | 
						|
    let log = [];
 | 
						|
    let collection = [1, 2, 3, 4, 5];
 | 
						|
    let sum = 0;
 | 
						|
    let i = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (var x of async(collection, kNext|kReturn, log)) {
 | 
						|
      sum += x;
 | 
						|
      if (++i === 2) break;
 | 
						|
    }
 | 
						|
    testDone = true;
 | 
						|
    return { sum, log };
 | 
						|
  }
 | 
						|
 | 
						|
  test = testBreakStatementReturnMethodPresent();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals({sum: 3, log: ['[Symbol.asyncIterator]()',
 | 
						|
                              '.next() -> resolved 1',
 | 
						|
                              '.next() -> resolved 2',
 | 
						|
                              '.return(undefined)']},
 | 
						|
               await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testBreakStatementReturnMethodAwaitIterResult() {
 | 
						|
    let log = [];
 | 
						|
    let collection = [1, 2, 3, 4, 5];
 | 
						|
    let sync_iter = collection[Symbol.iterator]();
 | 
						|
    sync_iter.return = function() {
 | 
						|
      return {
 | 
						|
        value: new Promise(function(resolve, reject) {
 | 
						|
          Promise.resolve().then(function() {
 | 
						|
            resolve('break!');
 | 
						|
          });
 | 
						|
        }),
 | 
						|
        done: true
 | 
						|
      };
 | 
						|
    };
 | 
						|
 | 
						|
    let sum = 0;
 | 
						|
    let i = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (var x of async(sync_iter, kNext|kReturn, log)) {
 | 
						|
      sum += x;
 | 
						|
      if (++i === 2) break;
 | 
						|
    }
 | 
						|
    testDone = true;
 | 
						|
    return { sum, log };
 | 
						|
  }
 | 
						|
 | 
						|
  test = testBreakStatementReturnMethodAwaitIterResult();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals({sum: 3,
 | 
						|
                log: ['[Symbol.asyncIterator]()',
 | 
						|
                      '.next() -> resolved 1',
 | 
						|
                      '.next() -> resolved 2',
 | 
						|
                      '.return() -> resolved break!' ]},
 | 
						|
               await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testBreakStatementReturnMethodAwaitRejection(log) {
 | 
						|
    let collection = [1, 2, 3, 4, 5];
 | 
						|
    let sync_iter = collection[Symbol.iterator]();
 | 
						|
    let sum = 0;
 | 
						|
    sync_iter.return = function() {
 | 
						|
      return {
 | 
						|
        value: new Promise(function(resolve, reject) {
 | 
						|
          Promise.resolve().then(function() {
 | 
						|
            reject('break! ' + sum);
 | 
						|
          });
 | 
						|
        }),
 | 
						|
        done: true
 | 
						|
      };
 | 
						|
    };
 | 
						|
 | 
						|
    let i = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (var x of async(sync_iter, kNext|kReturn, log)) {
 | 
						|
      sum += x;
 | 
						|
      if (++i === 2) break;
 | 
						|
    }
 | 
						|
    return { sum, log };
 | 
						|
  }
 | 
						|
 | 
						|
  let log = [];
 | 
						|
  test = testBreakStatementReturnMethodAwaitRejection(log);
 | 
						|
  assertFalse(testDone);
 | 
						|
  try {
 | 
						|
    await test;
 | 
						|
  } catch (e) {
 | 
						|
    assertEquals(log, ['[Symbol.asyncIterator]()',
 | 
						|
                       '.next() -> resolved 1',
 | 
						|
                       '.next() -> resolved 2',
 | 
						|
                       '.return() -> rejected break! 3']);
 | 
						|
    assertEquals('break! 3', e);
 | 
						|
    testDone = true;
 | 
						|
  }
 | 
						|
  assertTrue(testDone, 'Promise should be rejected');
 | 
						|
 | 
						|
  async function testBreakStatementReturnMethodPrimitiveValue(log) {
 | 
						|
    let collection = [1, 2, 3, 4, 5];
 | 
						|
    let sync_iter = collection[Symbol.iterator]();
 | 
						|
    sync_iter.return = function() {
 | 
						|
      return { value: 'break! primitive!', done: true };
 | 
						|
    }
 | 
						|
    let sum = 0;
 | 
						|
    let i = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (var x of async(sync_iter, kNext|kReturnPrimitive, log)) {
 | 
						|
      sum += x;
 | 
						|
      if (++i === 2) break;
 | 
						|
    }
 | 
						|
    return { sum, log };
 | 
						|
  }
 | 
						|
  log = [];
 | 
						|
  test = testBreakStatementReturnMethodPrimitiveValue(log);
 | 
						|
  assertFalse(testDone);
 | 
						|
  try {
 | 
						|
    await test;
 | 
						|
  } catch (e) {
 | 
						|
    assertEquals(['[Symbol.asyncIterator]()',
 | 
						|
                  '.next() -> resolved 1',
 | 
						|
                  '.next() -> resolved 2',
 | 
						|
                  '.return() -> resolved break! primitive!'],
 | 
						|
                 log);
 | 
						|
    assertInstanceof(e, TypeError);
 | 
						|
    testDone = true;
 | 
						|
  }
 | 
						|
  assertTrue(testDone, 'Promise should be rejected');
 | 
						|
 | 
						|
  async function testReturnStatementReturnMethodNotPresent() {
 | 
						|
    let log = [];
 | 
						|
    let collection = [1, 2, 3, 4, 5];
 | 
						|
    let sum = 0;
 | 
						|
    let i = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (var x of async(collection, kNext, log)) {
 | 
						|
      sum += x;
 | 
						|
      if (++i === 3) {
 | 
						|
        testDone = true;
 | 
						|
        return { sum, log };
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  test = testReturnStatementReturnMethodNotPresent();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals({sum: 6, log: ['[Symbol.asyncIterator]()',
 | 
						|
                              '.next() -> resolved 1',
 | 
						|
                              '.next() -> resolved 2',
 | 
						|
                              '.next() -> resolved 3']},
 | 
						|
               await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testReturnStatementReturnMethodPresent() {
 | 
						|
    let log = [];
 | 
						|
    let collection = [1, 2, 3, 4, 5];
 | 
						|
    let sum = 0;
 | 
						|
    let i = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (var x of async(collection, kNext|kReturn, log)) {
 | 
						|
      sum += x;
 | 
						|
      if (++i === 2) {
 | 
						|
        testDone = true;
 | 
						|
        return { sum, log };
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  test = testReturnStatementReturnMethodPresent();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals({sum: 3, log: ['[Symbol.asyncIterator]()',
 | 
						|
                              '.next() -> resolved 1',
 | 
						|
                              '.next() -> resolved 2',
 | 
						|
                              '.return(undefined)']},
 | 
						|
               await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testReturnStatementReturnMethodAwaitIterResult() {
 | 
						|
    let log = [];
 | 
						|
    let collection = [1, 2, 3, 4, 5];
 | 
						|
    let sync_iter = collection[Symbol.iterator]();
 | 
						|
    sync_iter.return = function() {
 | 
						|
      return {
 | 
						|
        value: new Promise(function(resolve, reject) {
 | 
						|
          Promise.resolve().then(function() {
 | 
						|
            testDone = true;
 | 
						|
            resolve('return!');
 | 
						|
          });
 | 
						|
        }),
 | 
						|
        done: true
 | 
						|
      };
 | 
						|
    };
 | 
						|
 | 
						|
    let sum = 0;
 | 
						|
    let i = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (var x of async(sync_iter, kNext|kReturn, log)) {
 | 
						|
      sum += x;
 | 
						|
      if (++i === 2) return { sum, log };
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  test = testReturnStatementReturnMethodAwaitIterResult();
 | 
						|
  assertFalse(testDone);
 | 
						|
  assertEquals({sum: 3,
 | 
						|
                log: ['[Symbol.asyncIterator]()',
 | 
						|
                      '.next() -> resolved 1',
 | 
						|
                      '.next() -> resolved 2',
 | 
						|
                      '.return() -> resolved return!' ]},
 | 
						|
               await test);
 | 
						|
  assertTrue(testDone);
 | 
						|
 | 
						|
  async function testReturnStatementReturnMethodAwaitRejection(log) {
 | 
						|
    let collection = [1, 2, 3, 4, 5];
 | 
						|
    let sync_iter = collection[Symbol.iterator]();
 | 
						|
    let sum = 0;
 | 
						|
    sync_iter.return = function() {
 | 
						|
      return {
 | 
						|
        value: new Promise(function(resolve, reject) {
 | 
						|
          Promise.resolve().then(function() {
 | 
						|
            reject('return! ' + sum);
 | 
						|
          });
 | 
						|
        }),
 | 
						|
        done: true
 | 
						|
      };
 | 
						|
    };
 | 
						|
 | 
						|
    let i = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (var x of async(sync_iter, kNext|kReturn, log)) {
 | 
						|
      sum += x;
 | 
						|
      if (++i === 2) return { sum, log };
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  log = [];
 | 
						|
  test = testReturnStatementReturnMethodAwaitRejection(log);
 | 
						|
  assertFalse(testDone);
 | 
						|
  try {
 | 
						|
    await test;
 | 
						|
  } catch (e) {
 | 
						|
    assertEquals('return! 3', e);
 | 
						|
    assertEquals(['[Symbol.asyncIterator]()',
 | 
						|
                  '.next() -> resolved 1',
 | 
						|
                  '.next() -> resolved 2',
 | 
						|
                  '.return() -> rejected return! 3'],
 | 
						|
                 log);
 | 
						|
    testDone = true;
 | 
						|
  }
 | 
						|
  assertTrue(testDone, 'Promise should be rejected');
 | 
						|
 | 
						|
  async function testReturnStatementReturnMethodPrimitiveValue(log) {
 | 
						|
    let collection = [1, 2, 3, 4, 5];
 | 
						|
    let sync_iter = collection[Symbol.iterator]();
 | 
						|
    sync_iter.return = function() {
 | 
						|
      return { value: 'return! primitive!', done: true };
 | 
						|
    }
 | 
						|
    let sum = 0;
 | 
						|
    let i = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (var x of async(sync_iter, kNext|kReturnPrimitive, log)) {
 | 
						|
      sum += x;
 | 
						|
      if (++i === 2) break;
 | 
						|
    }
 | 
						|
    return { sum, log };
 | 
						|
  }
 | 
						|
  log = [];
 | 
						|
  test = testReturnStatementReturnMethodPrimitiveValue(log);
 | 
						|
  assertFalse(testDone);
 | 
						|
  try {
 | 
						|
    await test;
 | 
						|
  } catch (e) {
 | 
						|
    assertEquals(['[Symbol.asyncIterator]()',
 | 
						|
                  '.next() -> resolved 1',
 | 
						|
                  '.next() -> resolved 2',
 | 
						|
                  '.return() -> resolved return! primitive!'],
 | 
						|
                 log);
 | 
						|
    assertInstanceof(e, TypeError);
 | 
						|
    testDone = true;
 | 
						|
  }
 | 
						|
  assertTrue(testDone, 'Promise should be rejected');
 | 
						|
 | 
						|
  async function testThrowStatementReturnMethodNotPresent() {
 | 
						|
    let log = [];
 | 
						|
    let collection = [1, 2, 3, 4, 5];
 | 
						|
    let sum = 0;
 | 
						|
    let i = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (var x of async(collection, kNext|kThrow, log)) {
 | 
						|
      sum += x;
 | 
						|
      if (++i === 3) {
 | 
						|
        throw { sum, log, toString() { return 'TestError'; } };
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return { sum, log };
 | 
						|
  }
 | 
						|
 | 
						|
  test = testThrowStatementReturnMethodNotPresent();
 | 
						|
  assertFalse(testDone);
 | 
						|
  try {
 | 
						|
    await test;
 | 
						|
  } catch (e) {
 | 
						|
    assertEquals('TestError', e.toString());
 | 
						|
    assertEquals(6, e.sum);
 | 
						|
    assertEquals(['[Symbol.asyncIterator]()', '.next() -> resolved 1',
 | 
						|
       '.next() -> resolved 2', '.next() -> resolved 3'
 | 
						|
      ], e.log);
 | 
						|
    testDone = true;
 | 
						|
  }
 | 
						|
  assertTrue(testDone, 'Awaited Promise should be rejected');
 | 
						|
 | 
						|
  async function testThrowStatementReturnMethodPresent() {
 | 
						|
    let log = [];
 | 
						|
    let collection = [1, 2, 3, 4, 5];
 | 
						|
    let sum = 0;
 | 
						|
    let i = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (var x of async(collection, kNext|kThrow|kReturn, log)) {
 | 
						|
      sum += x;
 | 
						|
      if (++i === 2) {
 | 
						|
        throw { sum, log, toString() { return 'TestError2'; } };
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return { sum, log };
 | 
						|
  }
 | 
						|
 | 
						|
  test = testThrowStatementReturnMethodPresent();
 | 
						|
  assertFalse(testDone);
 | 
						|
  try {
 | 
						|
    await test;
 | 
						|
  } catch (e) {
 | 
						|
    assertEquals('TestError2', e.toString());
 | 
						|
    assertEquals(3, e.sum);
 | 
						|
    assertEquals(['[Symbol.asyncIterator]()', '.next() -> resolved 1',
 | 
						|
       '.next() -> resolved 2', '.return(undefined)'
 | 
						|
      ], e.log);
 | 
						|
    testDone = true;
 | 
						|
  }
 | 
						|
  assertTrue(testDone, 'Awaited Promise should be rejected');
 | 
						|
 | 
						|
  async function testThrowStatementReturnMethodAwaitIterResult(log) {
 | 
						|
    let collection = [1, 2, 3, 4, 5];
 | 
						|
    let sync_iter = collection[Symbol.iterator]();
 | 
						|
    sync_iter.return = function() {
 | 
						|
      return {
 | 
						|
        value: new Promise(function(resolve, reject) {
 | 
						|
          Promise.resolve().then(function() {
 | 
						|
            testDone = true;
 | 
						|
            resolve('throw!');
 | 
						|
          });
 | 
						|
        }),
 | 
						|
        done: true
 | 
						|
      };
 | 
						|
    };
 | 
						|
 | 
						|
    let sum = 0;
 | 
						|
    let i = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (var x of async(sync_iter, kNext|kReturn, log)) {
 | 
						|
      sum += x;
 | 
						|
      if (++i === 2) throw 'Boo!!';
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  log = [];
 | 
						|
  test = testThrowStatementReturnMethodAwaitIterResult(log);
 | 
						|
  assertFalse(testDone);
 | 
						|
 | 
						|
  try {
 | 
						|
    await test;
 | 
						|
  } catch (e) {
 | 
						|
    assertEquals('Boo!!', e);
 | 
						|
    assertEquals(['[Symbol.asyncIterator]()',
 | 
						|
                  '.next() -> resolved 1',
 | 
						|
                  '.next() -> resolved 2',
 | 
						|
                  '.return() -> resolved throw!' ], log);
 | 
						|
    testDone = true;
 | 
						|
  }
 | 
						|
  assertTrue(testDone, 'Awaited Promise should be rejected');
 | 
						|
 | 
						|
  async function testThrowStatementReturnMethodAwaitRejection(log) {
 | 
						|
    let collection = [1, 2, 3, 4, 5];
 | 
						|
    let sync_iter = collection[Symbol.iterator]();
 | 
						|
    let sum = 0;
 | 
						|
    sync_iter.return = function() {
 | 
						|
      return {
 | 
						|
        value: new Promise(function(resolve, reject) {
 | 
						|
          Promise.resolve().then(function() {
 | 
						|
            reject('return! ' + sum);
 | 
						|
          });
 | 
						|
        }),
 | 
						|
        done: true
 | 
						|
      };
 | 
						|
    };
 | 
						|
 | 
						|
    let i = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (var x of async(sync_iter, kNext|kReturn, log)) {
 | 
						|
      sum += x;
 | 
						|
      if (++i === 2) throw 'Boo!!';
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  log = [];
 | 
						|
  test = testThrowStatementReturnMethodAwaitRejection(log);
 | 
						|
  assertFalse(testDone);
 | 
						|
  try {
 | 
						|
    await test;
 | 
						|
  } catch (e) {
 | 
						|
    assertEquals('Boo!!', e);
 | 
						|
    assertEquals(['[Symbol.asyncIterator]()',
 | 
						|
                  '.next() -> resolved 1',
 | 
						|
                  '.next() -> resolved 2',
 | 
						|
                  '.return() -> rejected return! 3'],
 | 
						|
                 log);
 | 
						|
    testDone = true;
 | 
						|
  }
 | 
						|
  assertTrue(testDone, 'Promise should be rejected');
 | 
						|
 | 
						|
  async function testThrowStatementReturnMethodPrimitiveValue(log) {
 | 
						|
    let collection = [1, 2, 3, 4, 5];
 | 
						|
    let sync_iter = collection[Symbol.iterator]();
 | 
						|
    sync_iter.return = function() {
 | 
						|
      return { value: 'return! primitive!', done: true };
 | 
						|
    }
 | 
						|
    let sum = 0;
 | 
						|
    let i = 0;
 | 
						|
    testDone = false;
 | 
						|
    for await (var x of async(sync_iter, kNext|kReturnPrimitive, log)) {
 | 
						|
      sum += x;
 | 
						|
      if (++i === 2) throw 'Boo!!';
 | 
						|
    }
 | 
						|
  }
 | 
						|
  log = [];
 | 
						|
  test = testThrowStatementReturnMethodPrimitiveValue(log);
 | 
						|
  assertFalse(testDone);
 | 
						|
  try {
 | 
						|
    await test;
 | 
						|
  } catch (e) {
 | 
						|
    assertEquals(['[Symbol.asyncIterator]()',
 | 
						|
                  '.next() -> resolved 1',
 | 
						|
                  '.next() -> resolved 2',
 | 
						|
                  '.return() -> resolved return! primitive!'],
 | 
						|
                 log);
 | 
						|
 | 
						|
    // AsyncIteratorClose does not require Throw completions to be of type
 | 
						|
    // Object
 | 
						|
    assertEquals('Boo!!', e);
 | 
						|
    testDone = true;
 | 
						|
  }
 | 
						|
  assertTrue(testDone, 'Promise should be rejected');
 | 
						|
})().catch(function(error) {
 | 
						|
  testFailed = true;
 | 
						|
  testFailure = error;
 | 
						|
});
 | 
						|
 | 
						|
%RunMicrotasks();
 | 
						|
 | 
						|
if (testFailed) {
 | 
						|
  throw testFailure;
 | 
						|
}
 |