diff --git a/js/src/builtin/FinalizationGroupObject.cpp b/js/src/builtin/FinalizationGroupObject.cpp index 55c62e5495f3..564bf90f23c4 100644 --- a/js/src/builtin/FinalizationGroupObject.cpp +++ b/js/src/builtin/FinalizationGroupObject.cpp @@ -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(); diff --git a/js/src/jit-test/tests/gc/finalizationGroup.js b/js/src/jit-test/tests/gc/finalizationGroup.js index fb886fa9315a..e921b487d45c 100644 --- a/js/src/jit-test/tests/gc/finalizationGroup.js +++ b/js/src/jit-test/tests/gc/finalizationGroup.js @@ -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); + } } } } diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 4e4ac9930c7f..d8c73159b973 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -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);