зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1131801 part 3. Get rid of the now-unused ReparentWrapperIfFound. r=peterv
This commit is contained in:
Родитель
3868298fd6
Коммит
c6f4a42302
|
@ -1070,187 +1070,6 @@ private:
|
|||
RootedObject mNewReflector;
|
||||
};
|
||||
|
||||
// static
|
||||
nsresult
|
||||
XPCWrappedNative::ReparentWrapperIfFound(XPCWrappedNativeScope* aOldScope,
|
||||
XPCWrappedNativeScope* aNewScope,
|
||||
HandleObject aNewParent,
|
||||
nsISupports* aCOMObj)
|
||||
{
|
||||
// Check if we're anywhere near the stack limit before we reach the
|
||||
// transplanting code, since it has no good way to handle errors. This uses
|
||||
// the untrusted script limit, which is not strictly necessary since no
|
||||
// actual script should run.
|
||||
AutoJSContext cx;
|
||||
JS_CHECK_RECURSION_CONSERVATIVE(cx, return NS_ERROR_FAILURE);
|
||||
|
||||
XPCNativeInterface* iface = XPCNativeInterface::GetISupports();
|
||||
if (!iface)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsRefPtr<XPCWrappedNative> wrapper;
|
||||
RootedObject flat(cx);
|
||||
nsWrapperCache* cache = nullptr;
|
||||
CallQueryInterface(aCOMObj, &cache);
|
||||
if (cache) {
|
||||
flat = cache->GetWrapper();
|
||||
if (flat) {
|
||||
wrapper = XPCWrappedNative::Get(flat);
|
||||
MOZ_ASSERT(wrapper->GetScope() == aOldScope,
|
||||
"Incorrect scope passed");
|
||||
}
|
||||
} else {
|
||||
rv = XPCWrappedNative::GetUsedOnly(aCOMObj, aOldScope, iface,
|
||||
getter_AddRefs(wrapper));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (wrapper)
|
||||
flat = wrapper->GetFlatJSObject();
|
||||
}
|
||||
|
||||
if (!flat)
|
||||
return NS_OK;
|
||||
|
||||
JSAutoCompartment ac(cx, aNewScope->GetGlobalJSObject());
|
||||
|
||||
if (aOldScope != aNewScope) {
|
||||
// Oh, so now we need to move the wrapper to a different scope.
|
||||
AutoMarkingWrappedNativeProtoPtr oldProto(cx);
|
||||
AutoMarkingWrappedNativeProtoPtr newProto(cx);
|
||||
|
||||
// Cross-scope means cross-compartment.
|
||||
MOZ_ASSERT(js::GetObjectCompartment(aOldScope->GetGlobalJSObject()) !=
|
||||
js::GetObjectCompartment(aNewScope->GetGlobalJSObject()));
|
||||
MOZ_ASSERT(aNewParent, "won't be able to find the new parent");
|
||||
|
||||
if (wrapper->HasProto()) {
|
||||
oldProto = wrapper->GetProto();
|
||||
XPCNativeScriptableInfo *info = oldProto->GetScriptableInfo();
|
||||
XPCNativeScriptableCreateInfo ci(*info);
|
||||
newProto =
|
||||
XPCWrappedNativeProto::GetNewOrUsed(aNewScope,
|
||||
oldProto->GetClassInfo(),
|
||||
&ci);
|
||||
if (!newProto) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// First, the clone of the reflector, get a copy of its
|
||||
// properties and clone its expando chain. The only part that is
|
||||
// dangerous here if we have to return early is that we must avoid
|
||||
// ending up with two reflectors pointing to the same WN. Other than
|
||||
// that, the objects we create will just go away if we return early.
|
||||
|
||||
RootedObject proto(cx, newProto->GetJSProtoObject());
|
||||
RootedObject newobj(cx, JS_CloneObject(cx, flat, proto, aNewParent));
|
||||
if (!newobj)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// At this point, both |flat| and |newobj| point to the same wrapped
|
||||
// native, which is bad, because one of them will end up finalizing
|
||||
// a wrapped native it does not own. |cloneGuard| ensures that if we
|
||||
// exit before calling clearing |flat|'s private the private of
|
||||
// |newobj| will be set to nullptr. |flat| will go away soon, because
|
||||
// we swap it with another object during the transplant and let that
|
||||
// object die.
|
||||
RootedObject propertyHolder(cx);
|
||||
{
|
||||
AutoClonePrivateGuard cloneGuard(cx, flat, newobj);
|
||||
|
||||
propertyHolder = JS_NewObjectWithGivenProto(cx, nullptr, JS::NullPtr(),
|
||||
aNewParent);
|
||||
if (!propertyHolder)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
if (!JS_CopyPropertiesFrom(cx, propertyHolder, flat))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Expandos from other compartments are attached to the target JS object.
|
||||
// Copy them over, and let the old ones die a natural death.
|
||||
if (!XrayUtils::CloneExpandoChain(cx, newobj, flat))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// We've set up |newobj|, so we make it own the WN by nulling out
|
||||
// the private of |flat|.
|
||||
//
|
||||
// NB: It's important to do this _after_ copying the properties to
|
||||
// propertyHolder. Otherwise, an object with |foo.x === foo| will
|
||||
// crash when JS_CopyPropertiesFrom tries to call wrap() on foo.x.
|
||||
JS_SetPrivate(flat, nullptr);
|
||||
}
|
||||
|
||||
// Update scope maps. This section modifies global state, so from
|
||||
// here on out we crash if anything fails.
|
||||
Native2WrappedNativeMap* oldMap = aOldScope->GetWrappedNativeMap();
|
||||
Native2WrappedNativeMap* newMap = aNewScope->GetWrappedNativeMap();
|
||||
|
||||
oldMap->Remove(wrapper);
|
||||
|
||||
if (wrapper->HasProto())
|
||||
wrapper->SetProto(newProto);
|
||||
|
||||
// If the wrapper has no scriptable or it has a non-shared
|
||||
// scriptable, then we don't need to mess with it.
|
||||
// Otherwise...
|
||||
|
||||
if (wrapper->mScriptableInfo &&
|
||||
wrapper->mScriptableInfo == oldProto->GetScriptableInfo()) {
|
||||
// The new proto had better have the same JSClass stuff as
|
||||
// the old one! We maintain a runtime wide unique map of
|
||||
// this stuff. So, if these don't match then the caller is
|
||||
// doing something bad here.
|
||||
|
||||
MOZ_ASSERT(oldProto->GetScriptableInfo()->GetScriptableShared() ==
|
||||
newProto->GetScriptableInfo()->GetScriptableShared(),
|
||||
"Changing proto is also changing JSObject Classname or "
|
||||
"helper's nsIXPScriptable flags. This is not allowed!");
|
||||
|
||||
wrapper->UpdateScriptableInfo(newProto->GetScriptableInfo());
|
||||
}
|
||||
|
||||
// Crash if the wrapper is already in the new scope.
|
||||
if (newMap->Find(wrapper->GetIdentityObject()))
|
||||
MOZ_CRASH();
|
||||
|
||||
if (!newMap->Add(wrapper))
|
||||
MOZ_CRASH();
|
||||
|
||||
flat = xpc::TransplantObject(cx, flat, newobj);
|
||||
if (!flat)
|
||||
MOZ_CRASH();
|
||||
|
||||
MOZ_ASSERT(flat);
|
||||
wrapper->mFlatJSObject = flat;
|
||||
wrapper->mFlatJSObject.setFlags(FLAT_JS_OBJECT_VALID);
|
||||
|
||||
if (cache) {
|
||||
bool preserving = cache->PreservingWrapper();
|
||||
cache->SetPreservingWrapper(false);
|
||||
cache->SetWrapper(flat);
|
||||
cache->SetPreservingWrapper(preserving);
|
||||
}
|
||||
if (!JS_CopyPropertiesFrom(cx, flat, propertyHolder))
|
||||
MOZ_CRASH();
|
||||
|
||||
// Call the scriptable hook to indicate that we transplanted.
|
||||
XPCNativeScriptableInfo* si = wrapper->GetScriptableInfo();
|
||||
if (si->GetFlags().WantPostCreate())
|
||||
(void) si->GetCallback()->PostTransplant(wrapper, cx, flat);
|
||||
}
|
||||
|
||||
// Now we can just fix up the parent and return the wrapper
|
||||
|
||||
if (aNewParent) {
|
||||
if (!JS_SetParent(cx, flat, aNewParent))
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
XPCWrappedNative::ExtendSet(XPCNativeInterface* aInterface)
|
||||
{
|
||||
|
|
|
@ -2122,12 +2122,6 @@ public:
|
|||
XPCNativeInterface* Interface,
|
||||
XPCWrappedNative** wrapper);
|
||||
|
||||
static nsresult
|
||||
ReparentWrapperIfFound(XPCWrappedNativeScope* aOldScope,
|
||||
XPCWrappedNativeScope* aNewScope,
|
||||
JS::HandleObject aNewParent,
|
||||
nsISupports* aCOMObj);
|
||||
|
||||
void FlatJSObjectFinalized();
|
||||
void FlatJSObjectMoved(JSObject *obj, const JSObject *old);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче