Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explicit resource management iterator return #4387

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%asynciteratorprototype%-@@asyncDispose
description: Return value of @@asyncDispose on %AsyncIteratorPrototype%
info: |
%AsyncIteratorPrototype% [ @@asyncDispose ] ( )

1. Let O be the this value.
2. Let promiseCapability be ! NewPromiseCapability(%Promise%).
3. Let return be GetMethod(O, "return").
4. IfAbruptRejectPromise(return, promiseCapability).
5. If return is undefined, then
a. Perform ! Call(promiseCapability.[[Resolve]], undefined, « undefined »).
6. Else,
a. Let result be Call(return, O, « undefined »).
b. IfAbruptRejectPromise(result, promiseCapability).
c. Let resultWrapper be Completion(PromiseResolve(%Promise%, result)).
d. IfAbruptRejectPromise(resultWrapper, promiseCapability).
e. Let unwrap be a new Abstract Closure that performs the following steps when called:
i. Return undefined.
f. Let onFulfilled be CreateBuiltinFunction(unwrap, 1, "", « »).
g. Perform PerformPromiseThen(resultWrapper, onFulfilled, undefined, promiseCapability).
7. Return promiseCapability.[[Promise]].

flags: [async]
includes: [asyncHelpers.js]
features: [explicit-resource-management]
---*/

asyncTest(async function () {
async function* generator() {}
const AsyncIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf(generator.prototype))

const iter = Object.create(AsyncIteratorPrototype);
var returnCalled = false;
iter.return = async function () {
returnCalled = true;
return { done: true };
};

await iter[Symbol.asyncDispose]();
assert.sameValue(returnCalled, true);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%asynciteratorprototype%-@@asyncDispose
description: Return value of @@asyncDispose on %AsyncIteratorPrototype%
info: |
%AsyncIteratorPrototype% [ @@asyncDispose ] ( )

1. Let O be the this value.
2. Let promiseCapability be ! NewPromiseCapability(%Promise%).
3. Let return be GetMethod(O, "return").
4. IfAbruptRejectPromise(return, promiseCapability).
5. If return is undefined, then
a. Perform ! Call(promiseCapability.[[Resolve]], undefined, « undefined »).
6. Else,
a. Let result be Call(return, O, « undefined »).
b. IfAbruptRejectPromise(result, promiseCapability).
c. Let resultWrapper be Completion(PromiseResolve(%Promise%, result)).
d. IfAbruptRejectPromise(resultWrapper, promiseCapability).
e. Let unwrap be a new Abstract Closure that performs the following steps when called:
i. Return undefined.
f. Let onFulfilled be CreateBuiltinFunction(unwrap, 1, "", « »).
g. Perform PerformPromiseThen(resultWrapper, onFulfilled, undefined, promiseCapability).
7. Return promiseCapability.[[Promise]].

features: [explicit-resource-management]
---*/

async function* generator() {}
const AsyncIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf(generator.prototype))

assert(AsyncIteratorPrototype[Symbol.asyncDispose]() instanceof Promise);
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%iteratorprototype%-@@dispose
description: Return value of @@dispose on %IteratorPrototype%
info: |
%IteratorPrototype% [ @@dispose ] ( )

1. Let O be the this value.
2. Let return be ? GetMethod(O, "return").
3. If return is not undefined, then
a. Perform ? Call(return, O, « »).
4. Return undefined.

features: [explicit-resource-management]
---*/

const IteratorPrototype = Object.getPrototypeOf(
Object.getPrototypeOf([][Symbol.iterator]())
);

const iter = Object.create(IteratorPrototype);
var returnCalled = false;
iter.return = function () {
returnCalled = true;
return { done: true };
};

iter[Symbol.dispose]();
assert.sameValue(returnCalled, true);
21 changes: 21 additions & 0 deletions test/built-ins/Iterator/prototype/Symbol.dispose/return-val.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%iteratorprototype%-@@dispose
description: Return value of @@dispose on %IteratorPrototype%
info: |
%IteratorPrototype% [ @@dispose ] ( )

1. Let O be the this value.
2. Let return be ? GetMethod(O, "return").
3. If return is not undefined, then
a. Perform ? Call(return, O, « »).
4. Return undefined.

features: [explicit-resource-management]
---*/
const IteratorPrototype = Object.getPrototypeOf(
Object.getPrototypeOf([][Symbol.iterator]())
);

assert.sameValue(IteratorPrototype[Symbol.dispose](), undefined);