diff --git a/test/language/statements/async-generator/yield-star-promise-not-unwrapped.js b/test/language/statements/async-generator/yield-star-promise-not-unwrapped.js new file mode 100644 index 00000000000..8ba6788cacb --- /dev/null +++ b/test/language/statements/async-generator/yield-star-promise-not-unwrapped.js @@ -0,0 +1,41 @@ +// Copyright (C) 2022 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-generator-function-definitions-runtime-semantics-evaluation +description: > + `yield*` in an async generator does not await promises returned by a manually implemented async iterator. +flags: [async] +features: [async-iteration] +---*/ + +var innerPromise = Promise.resolve("unwrapped value"); + +var asyncIter = { + [Symbol.asyncIterator]() { + return this; + }, + next() { + return { + done: false, + value: innerPromise, + }; + }, + get return() { + throw new Test262Error(".return should not be accessed"); + }, + get throw() { + throw new Test262Error(".throw should not be accessed"); + }, +}; + +async function* f() { + yield* asyncIter; +} + +f() + .next() + .then(v => { + assert.sameValue(v.value, innerPromise, "yield* should not unwrap promises from manually-implemented async iterators"); + }) + .then($DONE, $DONE) diff --git a/test/language/statements/async-generator/yield-star-return-then-getter-ticks.js b/test/language/statements/async-generator/yield-star-return-then-getter-ticks.js index 9981f2bfa06..451a91ea344 100644 --- a/test/language/statements/async-generator/yield-star-return-then-getter-ticks.js +++ b/test/language/statements/async-generator/yield-star-return-then-getter-ticks.js @@ -6,7 +6,7 @@ esid: sec-generator-function-definitions-runtime-semantics-evaluation description: > Return resumption value is awaited upon and hence is treated as a thenable. info: | - 14.4.14 Runtime Semantics: Evaluation + 15.5.5 Runtime Semantics: Evaluation YieldExpression : yield* AssignmentExpression ... @@ -27,46 +27,49 @@ info: | 2. Return Completion(received). ... - 25.5.3.7 AsyncGeneratorYield ( value ) + 27.6.3.8 AsyncGeneratorYield ( value ) ... - 5. Set value to ? Await(value). - ... - 8. Set the code evaluation state of genContext such that when evaluation is resumed with a - Completion resumptionValue the following steps will be performed: - ... - b. Let awaited be Await(resumptionValue.[[Value]]). + 12. If queue is not empty, then ... - e. Return Completion { [[Type]]: return, [[Value]]: awaited.[[Value]], [[Target]]: empty }. + 13. Else, ... + c. Set the code evaluation state of genContext such that when evaluation is resumed with a + Completion resumptionValue the following steps will be performed: + i. Return ? AsyncGeneratorUnwrapYieldResumption(resumptionValue). + + 27.6.3.7 AsyncGeneratorUnwrapYieldResumption ( resumptionValue ) + ... + 2. Let awaited be Completion(Await(resumptionValue.[[Value]])). + ... 6.2.3.1 Await ... 2. Let promise be ? PromiseResolve(%Promise%, « value »). ... - 25.6.4.5.1 PromiseResolve ( C, x ) + 27.2.4.7.1 PromiseResolve ( C, x ) ... - 3. Let promiseCapability be ? NewPromiseCapability(C). - 4. Perform ? Call(promiseCapability.[[Resolve]], undefined, « x »). + 2. Let promiseCapability be ? NewPromiseCapability(C). + 3. Perform ? Call(promiseCapability.[[Resolve]], undefined, « x »). ... - 25.6.1.5 NewPromiseCapability ( C ) + 27.2.1.5 NewPromiseCapability ( C ) ... 7. Let promise be ? Construct(C, « executor »). ... - 25.6.3.1 Promise ( executor ) + 27.2.3.1 Promise ( executor ) ... 8. Let resolvingFunctions be CreateResolvingFunctions(promise). ... - 25.6.1.3 CreateResolvingFunctions ( promise ) + 27.2.1.3 CreateResolvingFunctions ( promise ) ... 2. Let stepsResolve be the algorithm steps defined in Promise Resolve Functions (25.6.1.3.2). 3. Let resolve be CreateBuiltinFunction(stepsResolve, « [[Promise]], [[AlreadyResolved]] »). ... - 25.6.1.3.2 Promise Resolve Functions + 27.2.1.3.2 Promise Resolve Functions ... 9. Let then be Get(resolution, "then"). ... @@ -82,14 +85,11 @@ var expected = [ // `Await(innerResult)` promise resolved. "tick 1", - // `Await(value)` promise resolved. - "tick 2", - // "then" of `resumptionValue.[[Value]]` accessed. "get then", // `Await(resumptionValue.[[Value]])` promise resolved. - "tick 3", + "tick 2", // Get iterator "return" method. "get return", @@ -98,7 +98,7 @@ var expected = [ "get then", // `Await(received.[[Value]])` promise resolved. - "tick 4", + "tick 3", ]; var actual = []; @@ -127,7 +127,6 @@ Promise.resolve(0) .then(() => actual.push("tick 1")) .then(() => actual.push("tick 2")) .then(() => actual.push("tick 3")) - .then(() => actual.push("tick 4")) .then(() => { assert.compareArray(actual, expected, "Ticks for return with thenable getter"); }).then($DONE, $DONE);