Skip to content

Commit

Permalink
[Refactor] empty out DisposableStack slot on dispose
Browse files Browse the repository at this point in the history
  • Loading branch information
ljharb committed Jul 19, 2023
1 parent 001e23c commit 4d67178
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 19 deletions.
22 changes: 13 additions & 9 deletions aos/AddDisposableResource.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,26 @@ module.exports = function AddDisposableResource(disposeCapability, V, hint) {
throw new $TypeError('Assertion failed: `method`, when present, must be a function');
}

if (!disposeCapability['[[DisposableResourceStack]]']) {
throw new $TypeError('Assertion failed: `disposeCapability.[[DisposableResourceStack]]` must not be ~empty~');
}

var resource;
if (arguments.length < 4) {
if (arguments.length < 4) { // step 2
if (V == null) {
return 'unused'; // step 1.a
return 'unused'; // step 2.a
}
if (Type(V) !== 'Object') {
throw new $TypeError('`V` must be an Object'); // step 1.b
throw new $TypeError('`V` must be an Object'); // step 2.b
}
resource = CreateDisposableResource(V, hint); // step 1.c
} else { // step 2
resource = CreateDisposableResource(V, hint); // step 2.c
} else { // step 3
if (typeof V !== 'undefined') {
throw new $TypeError('Assertion failed: `V` must be undefined when `method` is present'); // step 2.a
throw new $TypeError('Assertion failed: `V` must be undefined when `method` is present'); // step 3.a
}
resource = CreateDisposableResource(void undefined, hint, method); // step 2.b
resource = CreateDisposableResource(void undefined, hint, method); // step 3.b
}
$push(disposeCapability['[[DisposableResourceStack]]'], resource); // step 3
$push(disposeCapability['[[DisposableResourceStack]]'], resource); // step 4

return 'unused'; // step 4
return 'unused'; // step 5
};
27 changes: 17 additions & 10 deletions aos/DisposeResources.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ module.exports = function DisposeResources(disposeCapability, completion) {

var stack = disposeCapability['[[DisposableResourceStack]]'];

if (!stack) {
throw new $TypeError('Assertion failed: `disposeCapability.[[DisposableResourceStack]]` must not be ~empty~'); // step 1
}

// for DisposableStack or AsyncDisposableStack, all are sync, or all are async.
// Only an environment record, via `using` and `await using`, can mix sync and async.
var actualHint;
Expand All @@ -40,22 +44,22 @@ module.exports = function DisposeResources(disposeCapability, completion) {
var promise = actualHint === 'async-dispose' && PromiseResolve($Promise, completion);

var rejecter = function (e) {
if (completion.type() === 'throw') { // step 1.b.i
var suppressed = completion.value(); // step 1.b.i.2
var error = new SuppressedError(e, suppressed); // steps 1.b.i.1, 1.b.i.3 - 1.b.i.5
if (completion.type() === 'throw') { // step 2.b.i
var suppressed = completion.value(); // step 2.b.i.2
var error = new SuppressedError(e, suppressed); // steps 2.b.i.1, 2.b.i.3 - 2.b.i.5
// eslint-disable-next-line no-param-reassign
completion = ThrowCompletion(error); // step 1.b.i.6
} else { // step 1.b.ii
completion = ThrowCompletion(error); // step 2.b.i.6
} else { // step 2.b.ii
// eslint-disable-next-line no-param-reassign
completion = ThrowCompletion(e); // step 1.b.ii.1
completion = ThrowCompletion(e); // step 2.b.ii.1
}
};

var getPromise = actualHint === 'async-dispose' && function getPromise(resource) {
return $then(
promise,
function () {
var result = Dispose( // step 1.a
var result = Dispose( // step 2.a
resource['[[ResourceValue]]'],
resource['[[Hint]]'],
resource['[[DisposeMethod]]']
Expand All @@ -69,13 +73,13 @@ module.exports = function DisposeResources(disposeCapability, completion) {
);
};

for (var i = stack.length - 1; i >= 0; i -= 1) { // step 1
for (var i = stack.length - 1; i >= 0; i -= 1) { // step 2
if (actualHint === 'async-dispose') {
promise = getPromise(stack[i]);
} else {
var resource = stack[i];
try {
var result = Dispose( // step 1.a
var result = Dispose( // step 2.a
resource['[[ResourceValue]]'],
resource['[[Hint]]'],
resource['[[DisposeMethod]]']
Expand All @@ -89,5 +93,8 @@ module.exports = function DisposeResources(disposeCapability, completion) {
}
}

return actualHint === 'async-dispose' ? promise : completion; // step 2
// eslint-disable-next-line no-param-reassign
disposeCapability['[[DisposableResourceStack]]'] = null; // step 3

return actualHint === 'async-dispose' ? promise : completion; // step 4
};

0 comments on commit 4d67178

Please sign in to comment.