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( bool FinalizationGroupObject::cleanupQueuedHoldings(
JSContext* cx, HandleFinalizationGroupObject group, JSContext* cx, HandleFinalizationGroupObject group,
HandleObject callbackArg) { HandleObject callbackArg) {
MOZ_ASSERT(cx->realm() == group->realm()); MOZ_ASSERT(cx->compartment() == group->compartment());
// 2. If CheckForEmptyCells(finalizationGroup) is false, return. // 2. If CheckForEmptyCells(finalizationGroup) is false, return.
HoldingsVector* holdings = group->holdingsToBeCleanedUp(); HoldingsVector* holdings = group->holdingsToBeCleanedUp();

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

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

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

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