mirror of https://github.com/tc39/test262.git
Implement changes for "avoid mostly-redundant `await` in async `yield*`" (#3619)
This commit is contained in:
parent
f1870753fa
commit
746197355c
|
@ -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)
|
|
@ -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
|
||||
12. If queue is not empty, then
|
||||
...
|
||||
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:
|
||||
...
|
||||
b. Let awaited be Await(resumptionValue.[[Value]]).
|
||||
...
|
||||
e. Return Completion { [[Type]]: return, [[Value]]: awaited.[[Value]], [[Target]]: empty }.
|
||||
...
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue