diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index 5775431f9ad..e187687dd74 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -200,14 +200,6 @@ public: */ static JSContext* GetContextFromDocument(nsIDocument *aDocument); - /** - * When a document's scope changes (e.g., from document.open(), call this - * function to move all content wrappers from the old scope to the new one. - */ - static nsresult ReparentContentWrappersInScope(JSContext *cx, - nsIScriptGlobalObject *aOldScope, - nsIScriptGlobalObject *aNewScope); - static bool IsCallerChrome(); static bool IsCallerTrustedForRead(); diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index bbc618b821b..b22c0a801d1 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -1721,23 +1721,6 @@ nsContentUtils::TraceSafeJSContext(JSTracer* aTrc) } } -nsresult -nsContentUtils::ReparentContentWrappersInScope(JSContext *cx, - nsIScriptGlobalObject *aOldScope, - nsIScriptGlobalObject *aNewScope) -{ - JSObject *oldScopeObj = aOldScope->GetGlobalJSObject(); - JSObject *newScopeObj = aNewScope->GetGlobalJSObject(); - - if (!newScopeObj || !oldScopeObj) { - // We can't really do anything without the JSObjects. - - return NS_ERROR_NOT_AVAILABLE; - } - - return sXPConnect->MoveWrappers(cx, oldScopeObj, newScopeObj); -} - nsPIDOMWindow * nsContentUtils::GetWindowFromCaller() { diff --git a/content/html/document/src/nsHTMLDocument.cpp b/content/html/document/src/nsHTMLDocument.cpp index 12c82891e75..a929aa51307 100644 --- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -1499,7 +1499,7 @@ nsHTMLDocument::Open(const nsAString& aContentTypeOrUrl, static_cast(this), getter_AddRefs(ignored)); NS_ENSURE_SUCCESS(rv, rv); - rv = nsContentUtils::ReparentContentWrappersInScope(cx, oldScope, newScope); + rv = xpc->RescueOrphansInScope(cx, oldScope->GetGlobalJSObject()); NS_ENSURE_SUCCESS(rv, rv); } } diff --git a/js/xpconnect/idl/nsIXPConnect.idl b/js/xpconnect/idl/nsIXPConnect.idl index dcecfd1f073..3fb0a9b202f 100644 --- a/js/xpconnect/idl/nsIXPConnect.idl +++ b/js/xpconnect/idl/nsIXPConnect.idl @@ -288,7 +288,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports { 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } } %} -[uuid(d94c13ae-7585-4e7b-b7ad-482976bc6f1b)] +[uuid(e28a33ce-dfe9-4816-ae20-0f1dc8077230)] interface nsIXPConnect : nsISupports { %{ C++ @@ -524,9 +524,7 @@ interface nsIXPConnect : nsISupports in JSObjectPtr aNewParent, in nsISupports aCOMObj); void - moveWrappers(in JSContextPtr aJSContext, - in JSObjectPtr aOldScope, - in JSObjectPtr aNewScope); + rescueOrphansInScope(in JSContextPtr aJSContext, in JSObjectPtr aScope); void clearAllWrappedNativeSecurityPolicies(); diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp index 51870f78bbd..45db61ba67b 100644 --- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -1551,150 +1551,33 @@ MoveableWrapperFinder(JSDHashTable *table, JSDHashEntryHdr *hdr, return JS_DHASH_NEXT; } -static nsresult -MoveWrapper(XPCCallContext& ccx, XPCWrappedNative *wrapper, - XPCWrappedNativeScope *newScope, XPCWrappedNativeScope *oldScope) -{ - // First, check to see if this wrapper really needs to be - // reparented. - - if (wrapper->GetScope() == newScope) { - // The wrapper already got moved, nothing to do here. - return NS_OK; - } - - // For performance reasons, we wait to fix up orphaned wrappers (wrappers - // whose parents have moved to another scope) until right before they - // threaten to confuse us. - // - // If this wrapper is an orphan, reunite it with its parent. If, following - // that, the wrapper is no longer in the old scope, then we don't need to - // reparent it. - MOZ_ASSERT(wrapper->GetScope() == oldScope); - nsresult rv = wrapper->RescueOrphans(ccx); - NS_ENSURE_SUCCESS(rv, rv); - if (wrapper->GetScope() != oldScope) - return NS_OK; - - nsISupports *identity = wrapper->GetIdentityObject(); - nsCOMPtr info(do_QueryInterface(identity)); - - // ClassInfo is implemented as singleton objects. If the identity - // object here is the same object as returned by the QI, then it - // is the singleton classinfo, so we don't need to reparent it. - if (SameCOMIdentity(identity, info)) - info = nullptr; - - if (!info) - return NS_OK; - - XPCNativeScriptableCreateInfo sciProto; - XPCNativeScriptableCreateInfo sci; - const XPCNativeScriptableCreateInfo& sciWrapper = - XPCWrappedNative::GatherScriptableCreateInfo(identity, info, - sciProto, sci); - - // If the wrapper doesn't want precreate, then we don't need to - // worry about reparenting it. - if (!sciWrapper.GetFlags().WantPreCreate()) - return NS_OK; - - JSObject *newParent = oldScope->GetGlobalJSObject(); - rv = sciWrapper.GetCallback()->PreCreate(identity, ccx, - newParent, - &newParent); - if (NS_FAILED(rv)) - return rv; - - if (newParent == oldScope->GetGlobalJSObject()) { - // The old scope still works for this wrapper. We have to - // assume that the wrapper will continue to return the old - // scope from PreCreate, so don't move it. - return NS_OK; - } - - // These are pretty special circumstances. Make sure that the parent here - // is a bonafide WN with a proper parent chain. - MOZ_ASSERT(!js::IsCrossCompartmentWrapper(newParent)); - MOZ_ASSERT(IS_WRAPPER_CLASS(js::GetObjectClass(newParent))); - if (!IS_WN_WRAPPER_OBJECT(newParent)) - NS_ENSURE_STATE(MorphSlimWrapper(ccx, newParent)); - XPCWrappedNative *parentWrapper = - static_cast(js::GetObjectPrivate(newParent)); - rv = parentWrapper->RescueOrphans(ccx); - NS_ENSURE_SUCCESS(rv, rv); - - // The wrapper returned a new parent. If the new parent is in a - // different scope, then we need to reparent it, otherwise, the - // old scope is fine. - - XPCWrappedNativeScope *betterScope = parentWrapper->GetScope(); - if (betterScope == oldScope) { - // The wrapper asked for a different object, but that object - // was in the same scope. This means that the new parent - // simply hasn't been reparented yet, so reparent it first, - // and then continue reparenting the wrapper itself. - - rv = MoveWrapper(ccx, parentWrapper, newScope, oldScope); - NS_ENSURE_SUCCESS(rv, rv); - - // If the parent wanted to stay in the old scope, we have to stay with - // it. This can happen when doing document.write when the old detached - // about:blank document is still floating around in the scope. Leave it - // behind to die. - if (parentWrapper->GetScope() == oldScope) - return NS_OK; - NS_ASSERTION(parentWrapper->GetScope() == newScope, - "A _third_ scope? Oh dear..."); - - } else - NS_ASSERTION(betterScope == newScope, "Weird scope returned"); - - // Now, reparent the wrapper, since we know that it wants to be - // reparented. - - nsRefPtr junk; - rv = XPCWrappedNative::ReparentWrapperIfFound(ccx, oldScope, - newScope, parentWrapper->GetFlatJSObject(), - wrapper->GetIdentityObject(), - getter_AddRefs(junk)); - return rv; -} - -/* void moveWrappers(in JSContextPtr aJSContext, in JSObjectPtr aOldScope, in JSObjectPtr aNewScope); */ +/* void rescueOrphansInScope(in JSContextPtr aJSContext, in JSObjectPtr aScope); */ NS_IMETHODIMP -nsXPConnect::MoveWrappers(JSContext *aJSContext, - JSObject *aOldScope, - JSObject *aNewScope) +nsXPConnect::RescueOrphansInScope(JSContext *aJSContext, JSObject *aScope) { XPCCallContext ccx(NATIVE_CALLER, aJSContext); if (!ccx.IsValid()) return UnexpectedFailure(NS_ERROR_FAILURE); - XPCWrappedNativeScope *oldScope = - XPCWrappedNativeScope::FindInJSObjectScope(ccx, aOldScope); - if (!oldScope) + XPCWrappedNativeScope *scope = + XPCWrappedNativeScope::FindInJSObjectScope(ccx, aScope); + if (!scope) return UnexpectedFailure(NS_ERROR_FAILURE); - XPCWrappedNativeScope *newScope = - XPCWrappedNativeScope::FindInJSObjectScope(ccx, aNewScope); - if (!newScope) - return UnexpectedFailure(NS_ERROR_FAILURE); - - // First, look through the old scope and find all of the wrappers that - // we're going to move. + // First, look through the old scope and find all of the wrappers that we + // might need to rescue. nsTArray > wrappersToMove; { // scoped lock XPCAutoLock lock(GetRuntime()->GetMapLock()); - Native2WrappedNativeMap *map = oldScope->GetWrappedNativeMap(); + Native2WrappedNativeMap *map = scope->GetWrappedNativeMap(); wrappersToMove.SetCapacity(map->Count()); map->Enumerate(MoveableWrapperFinder, &wrappersToMove); } // Now that we have the wrappers, reparent them to the new scope. for (uint32_t i = 0, stop = wrappersToMove.Length(); i < stop; ++i) { - nsresult rv = MoveWrapper(ccx, wrappersToMove[i], newScope, oldScope); + nsresult rv = wrappersToMove[i]->RescueOrphans(ccx); NS_ENSURE_SUCCESS(rv, rv); }