void nsXPCWrappedJS::Unlink() { nsXPConnect::GetRuntimeInstance()->AssertInvalidWrappedJSNotInTable(this); if (IsValid()) { XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance(); if (rt) { if (IsRootWrapper()) rt->RemoveWrappedJS(this); if (mRefCnt > 1) RemoveFromRootSet(); } mJSObj = nullptr; } if (IsRootWrapper()) { ClearWeakReferences(); } else if (mRoot) { // unlink this wrapper nsXPCWrappedJS* cur = mRoot; while (1) { if (cur->mNext == this) { cur->mNext = mNext; break; } cur = cur->mNext; MOZ_ASSERT(cur, "failed to find wrapper in its own chain"); } // Note: unlinking this wrapper may have changed us from a multi- // compartment wrapper chain to a single-compartment wrapper chain. We // leave the wrapper in the multi-compartment table as it is likely to // need to be multi-compartment again in the future and, moreover, we // cannot get a JSContext here. // let the root go NS_RELEASE(mRoot); } mClass = nullptr; if (mOuter) { XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance(); if (rt->GCIsRunning()) { DeferredFinalize(mOuter.forget().take()); } else { mOuter = nullptr; } } }
void nsXPCWrappedJS::Unlink() { if (IsValid()) { XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance(); if (rt) { if (mRoot == this) { // remove this root wrapper from the map JSObject2WrappedJSMap* map = rt->GetWrappedJSMap(); if (map) map->Remove(this); } if (mRefCnt > 1) RemoveFromRootSet(); } mJSObj = nullptr; } if (mRoot == this) { ClearWeakReferences(); } else if (mRoot) { // unlink this wrapper nsXPCWrappedJS* cur = mRoot; while (1) { if (cur->mNext == this) { cur->mNext = mNext; break; } cur = cur->mNext; MOZ_ASSERT(cur, "failed to find wrapper in its own chain"); } // let the root go NS_RELEASE(mRoot); } NS_IF_RELEASE(mClass); if (mOuter) { XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance(); if (rt->GCIsRunning()) { nsContentUtils::DeferredFinalize(mOuter); mOuter = nullptr; } else { NS_RELEASE(mOuter); } } }