js::RemapAllWrappersForObject(JSContext *cx, JSObject *oldTargetArg, JSObject *newTargetArg) { RootedValue origv(cx, ObjectValue(*oldTargetArg)); RootedObject newTarget(cx, newTargetArg); AutoWrapperVector toTransplant(cx); if (!toTransplant.reserve(cx->runtime->numCompartments)) return false; for (CompartmentsIter c(cx->runtime); !c.done(); c.next()) { if (WrapperMap::Ptr wp = c->lookupWrapper(origv)) { // We found a wrapper. Remember and root it. toTransplant.infallibleAppend(WrapperValue(wp)); } } for (WrapperValue *begin = toTransplant.begin(), *end = toTransplant.end(); begin != end; ++begin) { if (!RemapWrapper(cx, &begin->toObject(), newTarget)) MOZ_CRASH(); } return true; }
js::RecomputeWrappers(JSContext *cx, const CompartmentFilter &sourceFilter, const CompartmentFilter &targetFilter) { AutoMaybeTouchDeadCompartments agc(cx); AutoWrapperVector toRecompute(cx); for (CompartmentsIter c(cx->runtime); !c.done(); c.next()) { // Filter by source compartment. if (!sourceFilter.match(c)) continue; // Iterate over the wrappers, filtering appropriately. WrapperMap &pmap = c->crossCompartmentWrappers; for (WrapperMap::Enum e(pmap); !e.empty(); e.popFront()) { // Filter out non-objects. const CrossCompartmentKey &k = e.front().key; if (k.kind != CrossCompartmentKey::ObjectWrapper) continue; // Filter by target compartment. if (!targetFilter.match(k.wrapped->compartment())) continue; // Add it to the list. if (!toRecompute.append(WrapperValue(e))) return false; } } // Recompute all the wrappers in the list. for (WrapperValue *begin = toRecompute.begin(), *end = toRecompute.end(); begin != end; ++begin) { JSObject *wrapper = &begin->toObject(); JSObject *wrapped = Wrapper::wrappedObject(wrapper); if (!RemapWrapper(cx, wrapper, wrapped)) MOZ_CRASH(); } return true; }