Skip to content

Commit

Permalink
[explicit-resource-management] Add DisposableStack constructor, use
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Simon Zünd <[email protected]>
Cr-Commit-Position: refs/heads/main@{#93807}
  • Loading branch information
rmahdav authored and test262-merge-bot committed May 8, 2024
1 parent 55a5346 commit 9b4c657
Show file tree
Hide file tree
Showing 2 changed files with 211 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -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();
Original file line number Diff line number Diff line change
@@ -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]);

0 comments on commit 9b4c657

Please sign in to comment.