mirror of
https://github.com/servo/servo.git
synced 2025-08-11 08:25:32 +01:00
Update web-platform-tests to revision 86b1ae6d6c823d07ca2c5c70865ed8c796d46c3d
This commit is contained in:
parent
46f8f3d009
commit
5304c69b42
421 changed files with 7514 additions and 1714 deletions
|
@ -0,0 +1,108 @@
|
|||
// META: script=resources/maybe-garbage-collect.js
|
||||
// ├──> maybeGarbageCollectAndCleanupAsync
|
||||
// ├──> maybeGarbageCollectAsync
|
||||
// └──> resolveGarbageCollection
|
||||
/*---
|
||||
esid: sec-finalization-registry-target
|
||||
info: |
|
||||
FinalizationRegistry ( cleanupCallback )
|
||||
|
||||
FinalizationRegistry.prototype.cleanupSome ( [ callback ] )
|
||||
|
||||
...
|
||||
4. If callback is not undefined and IsCallable(callback) is false, throw a TypeError exception.
|
||||
5. Perform ? CleanupFinalizationRegistry(finalizationRegistry, callback).
|
||||
6. Return undefined.
|
||||
|
||||
Execution
|
||||
|
||||
At any time, if an object obj is not live, an ECMAScript implementation may perform the following steps atomically:
|
||||
|
||||
1. For each WeakRef ref such that ref.[[Target]] is obj,
|
||||
a. Set ref.[[Target]] to empty.
|
||||
2. For each FinalizationRegistry finalizationRegistry such that finalizationRegistry.[[Cells]] contains cell, such that cell.[[Target]] is obj,
|
||||
a. Set cell.[[Target]] to empty.
|
||||
b. Optionally, perform ! HostCleanupFinalizationRegistry(finalizationRegistry).
|
||||
---*/
|
||||
|
||||
|
||||
let cleanupCallback = 0;
|
||||
let holdings = [];
|
||||
function cb(holding) {
|
||||
holdings.push(holding);
|
||||
}
|
||||
|
||||
let finalizationRegistry = new FinalizationRegistry(function() {
|
||||
cleanupCallback += 1;
|
||||
});
|
||||
|
||||
function emptyCells() {
|
||||
let target = {};
|
||||
finalizationRegistry.register(target, 'a');
|
||||
|
||||
let prom = maybeGarbageCollectAndCleanupAsync(target);
|
||||
target = null;
|
||||
|
||||
return prom;
|
||||
}
|
||||
|
||||
promise_test(() => {
|
||||
return (async () => {
|
||||
assert_implements(
|
||||
typeof FinalizationRegistry.prototype.cleanupSome === 'function',
|
||||
'FinalizationRegistry.prototype.cleanupSome is not implemented.'
|
||||
);
|
||||
|
||||
assert_implements(
|
||||
typeof queueMicrotask === 'function',
|
||||
'queueMicrotask is not implemented.'
|
||||
);
|
||||
|
||||
let ticks = 0;
|
||||
await emptyCells();
|
||||
await queueMicrotask(() => ticks++);
|
||||
|
||||
finalizationRegistry.cleanupSome(cb);
|
||||
|
||||
// cleanupSome will be invoked if there are empty cells left. If the
|
||||
// cleanupCallback already ran, then cb won't be called.
|
||||
let expectedCalled = cleanupCallback === 1 ? 0 : 1;
|
||||
// This asserts the registered object was emptied in the previous GC.
|
||||
assert_equals(holdings.length, expectedCalled, 'cleanupSome callback for the first time');
|
||||
|
||||
// At this point, we can't assert if cleanupCallback was called, because it's
|
||||
// optional. Although, we can finally assert it's not gonna be called anymore
|
||||
// for the other executions of the Garbage Collector.
|
||||
// The chance of having it called only happens right after the
|
||||
// cell.[[Target]] is set to empty.
|
||||
assert_true(cleanupCallback >= 0, 'cleanupCallback might be 0');
|
||||
assert_true(cleanupCallback <= 1, 'cleanupCallback might be 1');
|
||||
|
||||
// Restoring the cleanupCallback variable to 0 will help us asserting the
|
||||
// finalizationRegistry callback is not called again.
|
||||
cleanupCallback = 0;
|
||||
|
||||
await maybeGarbageCollectAsync();
|
||||
await queueMicrotask(() => ticks++);
|
||||
|
||||
finalizationRegistry.cleanupSome(cb);
|
||||
|
||||
assert_equals(holdings.length, expectedCalled, 'cleanupSome callback is not called anymore, no empty cells');
|
||||
assert_equals(cleanupCallback, 0, 'cleanupCallback is not called again #1');
|
||||
|
||||
await maybeGarbageCollectAsync();
|
||||
await queueMicrotask(() => ticks++);
|
||||
|
||||
finalizationRegistry.cleanupSome(cb);
|
||||
|
||||
assert_equals(holdings.length, expectedCalled, 'cleanupSome callback is not called again #2');
|
||||
assert_equals(cleanupCallback, 0, 'cleanupCallback is not called again #2');
|
||||
assert_equals(ticks, 3, 'ticks is 3');
|
||||
|
||||
if (holdings.length) {
|
||||
assert_array_equals(holdings, ['a']);
|
||||
}
|
||||
|
||||
await maybeGarbageCollectAsync();
|
||||
})().catch(resolveGarbageCollection);
|
||||
}, 'cleanupCallback has only one optional chance to be called for a GC that cleans up a registered target.');
|
|
@ -0,0 +1,114 @@
|
|||
// META: script=resources/maybe-garbage-collect.js
|
||||
// ├──> maybeGarbageCollectAndCleanupAsync
|
||||
// ├──> maybeGarbageCollectAsync
|
||||
// └──> resolveGarbageCollection
|
||||
/*---
|
||||
esid: sec-finalization-registry-target
|
||||
info: |
|
||||
FinalizationRegistry ( cleanupCallback )
|
||||
|
||||
FinalizationRegistry.prototype.cleanupSome ( [ callback ] )
|
||||
|
||||
...
|
||||
4. If callback is not undefined and IsCallable(callback) is false, throw a TypeError exception.
|
||||
5. Perform ? CleanupFinalizationRegistry(finalizationRegistry, callback).
|
||||
6. Return undefined.
|
||||
|
||||
Execution
|
||||
|
||||
At any time, if an object obj is not live, an ECMAScript implementation may perform the following steps atomically:
|
||||
|
||||
1. For each WeakRef ref such that ref.[[Target]] is obj,
|
||||
a. Set ref.[[Target]] to empty.
|
||||
2. For each FinalizationRegistry finalizationRegistry such that finalizationRegistry.[[Cells]] contains cell, such that cell.[[Target]] is obj,
|
||||
a. Set cell.[[Target]] to empty.
|
||||
b. Optionally, perform ! HostCleanupFinalizationRegistry(finalizationRegistry).
|
||||
---*/
|
||||
|
||||
|
||||
let cleanupCallback = 0;
|
||||
let holdings = [];
|
||||
function cb(holding) {
|
||||
holdings.push(holding);
|
||||
}
|
||||
|
||||
let finalizationRegistry = new FinalizationRegistry(function() {
|
||||
cleanupCallback += 1;
|
||||
});
|
||||
|
||||
function emptyCells() {
|
||||
let target = {};
|
||||
finalizationRegistry.register(target, 'a');
|
||||
|
||||
let prom = maybeGarbageCollectAndCleanupAsync(target);
|
||||
target = null;
|
||||
|
||||
return prom;
|
||||
}
|
||||
|
||||
function queueMicrotaskByMutationObserver(callback) {
|
||||
const textNode = document.createTextNode('');
|
||||
new MutationObserver(callback).observe(textNode, { characterData: true });
|
||||
textNode.data = 1;
|
||||
}
|
||||
|
||||
promise_test(() => {
|
||||
return (async () => {
|
||||
assert_implements(
|
||||
typeof FinalizationRegistry.prototype.cleanupSome === 'function',
|
||||
'FinalizationRegistry.prototype.cleanupSome is not implemented.'
|
||||
);
|
||||
|
||||
assert_implements(
|
||||
typeof MutationObserver === 'function',
|
||||
'MutationObserver is not implemented.'
|
||||
);
|
||||
|
||||
let ticks = 0;
|
||||
await emptyCells();
|
||||
await queueMicrotaskByMutationObserver(() => ticks++);
|
||||
|
||||
finalizationRegistry.cleanupSome(cb);
|
||||
|
||||
// cleanupSome will be invoked if there are empty cells left. If the
|
||||
// cleanupCallback already ran, then cb won't be called.
|
||||
let expectedCalled = cleanupCallback === 1 ? 0 : 1;
|
||||
// This asserts the registered object was emptied in the previous GC.
|
||||
assert_equals(holdings.length, expectedCalled, 'cleanupSome callback for the first time');
|
||||
|
||||
// At this point, we can't assert if cleanupCallback was called, because it's
|
||||
// optional. Although, we can finally assert it's not gonna be called anymore
|
||||
// for the other executions of the Garbage Collector.
|
||||
// The chance of having it called only happens right after the
|
||||
// cell.[[Target]] is set to empty.
|
||||
assert_true(cleanupCallback >= 0, 'cleanupCallback might be 0');
|
||||
assert_true(cleanupCallback <= 1, 'cleanupCallback might be 1');
|
||||
|
||||
// Restoring the cleanupCallback variable to 0 will help us asserting the
|
||||
// finalizationRegistry callback is not called again.
|
||||
cleanupCallback = 0;
|
||||
|
||||
await maybeGarbageCollectAsync();
|
||||
await queueMicrotaskByMutationObserver(() => ticks++);
|
||||
|
||||
finalizationRegistry.cleanupSome(cb);
|
||||
|
||||
assert_equals(holdings.length, expectedCalled, 'cleanupSome callback is not called anymore, no empty cells');
|
||||
assert_equals(cleanupCallback, 0, 'cleanupCallback is not called again #1');
|
||||
|
||||
await maybeGarbageCollectAsync();
|
||||
await queueMicrotaskByMutationObserver(() => ticks++);
|
||||
|
||||
finalizationRegistry.cleanupSome(cb);
|
||||
|
||||
assert_equals(holdings.length, expectedCalled, 'cleanupSome callback is not called again #2');
|
||||
assert_equals(cleanupCallback, 0, 'cleanupCallback is not called again #2');
|
||||
assert_equals(ticks, 3, 'ticks is 3');
|
||||
|
||||
if (holdings.length) {
|
||||
assert_array_equals(holdings, ['a']);
|
||||
}
|
||||
|
||||
await maybeGarbageCollectAsync();
|
||||
})().catch(resolveGarbageCollection);
|
||||
}, 'cleanupCallback has only one optional chance to be called for a GC that cleans up a registered target.');
|
|
@ -27,10 +27,9 @@ info: |
|
|||
|
||||
|
||||
let cleanupCallback = 0;
|
||||
let called = 0;
|
||||
let holdings = [];
|
||||
function cb(holding) {
|
||||
assert_equals(holding, 'a');
|
||||
called += 1;
|
||||
holdings.push(holding);
|
||||
}
|
||||
|
||||
let finalizationRegistry = new FinalizationRegistry(function() {
|
||||
|
@ -64,7 +63,7 @@ promise_test(() => {
|
|||
// cleanupCallback already ran, then cb won't be called.
|
||||
let expectedCalled = cleanupCallback === 1 ? 0 : 1;
|
||||
// This asserts the registered object was emptied in the previous GC.
|
||||
assert_equals(called, expectedCalled, 'cleanupSome callback for the first time');
|
||||
assert_equals(holdings.length, expectedCalled, 'cleanupSome callback for the first time');
|
||||
|
||||
// At this point, we can't assert if cleanupCallback was called, because it's
|
||||
// optional. Although, we can finally assert it's not gonna be called anymore
|
||||
|
@ -83,7 +82,7 @@ promise_test(() => {
|
|||
|
||||
finalizationRegistry.cleanupSome(cb);
|
||||
|
||||
assert_equals(called, expectedCalled, 'cleanupSome callback is not called anymore, no empty cells');
|
||||
assert_equals(holdings.length, expectedCalled, 'cleanupSome callback is not called anymore, no empty cells');
|
||||
assert_equals(cleanupCallback, 0, 'cleanupCallback is not called again #1');
|
||||
|
||||
await maybeGarbageCollectAsync();
|
||||
|
@ -91,10 +90,14 @@ promise_test(() => {
|
|||
|
||||
finalizationRegistry.cleanupSome(cb);
|
||||
|
||||
assert_equals(called, expectedCalled, 'cleanupSome callback is not called again #2');
|
||||
assert_equals(holdings.length, expectedCalled, 'cleanupSome callback is not called again #2');
|
||||
assert_equals(cleanupCallback, 0, 'cleanupCallback is not called again #2');
|
||||
await maybeGarbageCollectAsync();
|
||||
|
||||
assert_equals(ticks, 3, 'ticks is 3');
|
||||
|
||||
if (holdings.length) {
|
||||
assert_array_equals(holdings, ['a']);
|
||||
}
|
||||
|
||||
await maybeGarbageCollectAsync();
|
||||
})().catch(resolveGarbageCollection);
|
||||
}, 'cleanupCallback has only one optional chance to be called for a GC that cleans up a registered target.');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue