[explicit-resource-management] Add DisposableStack constructor, use

and dispose method

This CL adds DisposableStack constructor, use() and dispose() methods
as developer exposed methods. Also, this CL fixed the use
of `using` keyword with `null` and `undefined` and adds tests for them.

Bug: 42203506
Change-Id: If50b9e33d9cbb3de2be41dc81e656d9d202b8fa8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5498999
Commit-Queue: Rezvan Mahdavi Hezaveh <rezvan@chromium.org>
Reviewed-by: Simon Zünd <szuend@chromium.org>
Cr-Commit-Position: refs/heads/main@{#93807}
This commit is contained in:
Rezvan Mahdavi Hezaveh 2024-05-08 14:21:21 -07:00 committed by test262-merge-bot
parent 55a5346f99
commit 9b4c6577f6
2 changed files with 211 additions and 0 deletions

View File

@ -0,0 +1,185 @@
// Copyright (C) 2024 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: |
Test developer exposed DisposableStack protype methods use() and dispose().
includes: [compareArray.js]
features: [explicit-resource-management]
---*/
// use() method on null should not throw --------
let valuesWithNull = [];
(function TestDisposableStackUsewithNull() {
let stack = new DisposableStack();
valuesWithNull.push(42);
stack.use(null);
valuesWithNull.push(43);
})();
assert.compareArray(valuesWithNull, [42, 43]);
// use() method on undefined should not throw --------
let valuesWithUndefined = [];
(function TestDisposableStackUseWithUndefined() {
let stack = new DisposableStack();
valuesWithUndefined.push(42);
stack.use(undefined);
valuesWithUndefined.push(43);
})();
assert.compareArray(valuesWithUndefined, [42, 43]);
// use() method on a non object --------
function TestDisposableStackUseWithNonObject() {
let stack = new DisposableStack();
stack.use(42);
};
assert.throws(
TypeError, () => TestDisposableStackUseWithNonObject(),
'use() is called on non-object');
// use() method on normal value --------
let valuesNormal = [];
(function TestDisposableStackUse() {
let stack = new DisposableStack();
const disposable = {
value: 1,
[Symbol.dispose]() {
valuesNormal.push(42);
}
};
stack.use(disposable);
stack.dispose();
})();
assert.compareArray(valuesNormal, [42]);
// use() method with null [symbol.dispose] --------
function TestDisposableStackUseWithNullDispose() {
let stack = new DisposableStack();
const disposable = {
value: 1,
[Symbol.dispose]: null,
};
stack.use(disposable);
};
assert.throws(
TypeError, () => TestDisposableStackUseWithNullDispose(),
'symbol.dispose is null');
// use() method with undefined [symbol.dispose] --------
function TestDisposableStackUseWithUndefinedDispose() {
let stack = new DisposableStack();
const disposable = {
value: 1,
[Symbol.dispose]: undefined,
};
stack.use(disposable);
};
assert.throws(
TypeError, () => TestDisposableStackUseWithUndefinedDispose(),
'symbol.dispose is undefined');
// use() method when [symbol.dispose] is not callable--------
function TestDisposableStackUseWithNonCallableDispose() {
let stack = new DisposableStack();
const disposable = {
value: 1,
[Symbol.dispose]: 42,
};
stack.use(disposable);
};
assert.throws(
TypeError, () => TestDisposableStackUseWithNonCallableDispose(),
'symbol.dispose is not callable');
// disposing a disposed stack should not throw --------
let valuesWithTwiceDisposal = [];
(function TestDisposableStackUseDisposingTwice() {
let stack = new DisposableStack();
const disposable = {
value: 1,
[Symbol.dispose]() {
valuesWithTwiceDisposal.push(42);
}
};
stack.use(disposable);
stack.dispose();
stack.dispose();
})();
assert.compareArray(valuesWithTwiceDisposal, [42]);
// use() method on disposed stack --------
function TestDisposableStackUseOnDisposedStack() {
let stack = new DisposableStack();
stack.dispose();
stack.use(disposable);
};
assert.throws(
ReferenceError, () => TestDisposableStackUseOnDisposedStack(),
'Cannot add values to a disposed stack!');
// use() method with error inside disposal method --------
function TestDisposableStackUseDisposeMethodThrows() {
{
let stack = new DisposableStack();
const disposable = {
value: 1,
[Symbol.dispose]() {
throw new Test262Error('Symbol.dispose is throwing!');
}
};
stack.use(disposable);
stack.dispose();
}
};
assert.throws(
Test262Error, () => TestDisposableStackUseDisposeMethodThrows(),
'Symbol.dispose is throwing!');
// use() method with suppressed error of two disposal method errors--------
let firstDisposeError =
new Test262Error('The first Symbol.dispose is throwing!');
let secondDisposeError =
new Test262Error('The second Symbol.dispose is throwing!');
function TestDisposableStackUseTwoDisposeMethodsThrow() {
{
let stack = new DisposableStack();
const firstDisposable = {
value: 1,
[Symbol.dispose]() {
throw firstDisposeError;
}
};
const secondDisposable = {
value: 1,
[Symbol.dispose]() {
throw secondDisposeError;
}
};
stack.use(firstDisposable);
stack.use(secondDisposable);
stack.dispose();
}
};
assert.throws(
SuppressedError, () => TestDisposableStackUseTwoDisposeMethodsThrow(),
'An error was suppressed during disposal');
function RunTestDisposableStackUseTwoDisposeMethodsThrow() {
try {
TestDisposableStackUseTwoDisposeMethodsThrow();
} catch (error) {
assert(
error instanceof SuppressedError,
'error is an instanceof SuppressedError');
assert.sameValue(error.error, firstDisposeError, 'error.error');
assert.sameValue(error.suppressed, secondDisposeError, 'error.suppressed');
}
}
RunTestDisposableStackUseTwoDisposeMethodsThrow();

View File

@ -0,0 +1,26 @@
// Copyright (C) 2024 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: using with null or undefined should not throw.
includes: [compareArray.js]
features: [explicit-resource-management]
---*/
// Use using with null --------------
let withNullvalues = [];
(function TestUsingWithNull() {
let using = null;
withNullvalues.push(42);
})();
assert.compareArray(withNullvalues, [42]);
// Use using with undefined --------------
let withUndefinedvalues = [];
(function TestUsingWithUndefined() {
let using = undefined;
withUndefinedvalues.push(42);
})();
assert.compareArray(withUndefinedvalues, [42]);