Bug 1594061 - Make FinalizationGroups work correctly when called from a different realm r=sfink

Differential Revision: https://phabricator.services.mozilla.com/D51856

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jon Coppeard 2019-11-05 18:12:09 +00:00
Родитель 72de7c7261
Коммит ba3386ca9b
3 изменённых файлов: 32 добавлений и 17 удалений

Просмотреть файл

@ -549,7 +549,7 @@ bool FinalizationGroupObject::cleanupSome(JSContext* cx, unsigned argc,
bool FinalizationGroupObject::cleanupQueuedHoldings(
JSContext* cx, HandleFinalizationGroupObject group,
HandleObject callbackArg) {
MOZ_ASSERT(cx->realm() == group->realm());
MOZ_ASSERT(cx->compartment() == group->compartment());
// 2. If CheckForEmptyCells(finalizationGroup) is false, return.
HoldingsVector* holdings = group->holdingsToBeCleanedUp();

Просмотреть файл

@ -259,30 +259,43 @@ gc();
drainJobQueue();
// Test combinations of arguments in different compartments.
function ccw() {
function ccwToObject() {
return evalcx('({})', newGlobal({newCompartment: true}));
}
function ccwToGroup() {
let global = newGlobal({newCompartment: true});
global.holdings = holdings;
return global.eval(`
new FinalizationGroup(iterator => {
for (const holding of iterator) {
holdings.push(holding);
}
})`);
}
function incrementalGC() {
startgc(1);
while (gcstate() !== "NotActive") {
gcslice(1000);
}
}
for (let x of [false, true]) {
for (let y of [false, true]) {
for (let z of [false, true]) {
let target = x ? ccw() : {};
let holding = x ? ccw() : {};
let token = x ? ccw() : {};
group.register(target, holding, token);
group.unregister(token);
group.register(target, holding, token);
target = undefined;
incrementalGC();
holdings = [];
group.cleanupSome();
assertEq(holdings.length, 1);
assertEq(holdings[0], holding);
for (let w of [false, true]) {
for (let x of [false, true]) {
for (let y of [false, true]) {
for (let z of [false, true]) {
let g = w ? ccwToGroup(w) : group;
let target = x ? ccwToObject() : {};
let holding = y ? ccwToObject() : {};
let token = z ? ccwToObject() : {};
g.register(target, holding, token);
g.unregister(token);
g.register(target, holding, token);
target = undefined;
incrementalGC();
holdings.length = 0; // Clear, don't replace.
g.cleanupSome();
assertEq(holdings.length, 1);
assertEq(holdings[0], holding);
}
}
}
}

Просмотреть файл

@ -1037,6 +1037,8 @@ static void MaybeRunFinalizationGroupCleanupTasks(JSContext* cx) {
for (const auto& g : groups) {
group = g;
AutoRealm ar(cx, group);
{
AutoReportException are(cx);
mozilla::Unused << JS::CleanupQueuedFinalizationGroup(cx, group);