Bug 720580 - Do the last bit of wrapped global initialization once the dust has settled. r=mrbkap

This commit is contained in:
Bobby Holley 2012-03-05 15:22:45 -08:00
parent eb0a73527c
commit 87d7f5f353
3 changed files with 21 additions and 39 deletions

View File

@ -2326,7 +2326,7 @@ nsJSContext::SetOuterObject(JSObject* aOuterObject)
NS_ENSURE_SUCCESS(rv, rv);
NS_ABORT_IF_FALSE(wrapper, "bad wrapper");
wrapper->RefreshPrototype();
wrapper->FinishInitForWrappedGlobal();
JS_SetPrototype(mContext, aOuterObject, JS_GetPrototype(inner));
return NS_OK;

View File

@ -180,7 +180,14 @@ interface nsIXPConnectWrappedNative : nsIXPConnectJSObjectHolder
void debugDump(in short depth);
void refreshPrototype();
/*
* This finishes initializing a wrapped global, doing the parts that we
* couldn't do while the global and window were being simultaneously
* bootstrapped. This should be called exactly once, and only for wrapped
* globals.
*/
void finishInitForWrappedGlobal();
/*
* This returns a pointer into the instance and care should be taken
* to make sure the pointer is not kept past the life time of the

View File

@ -3081,48 +3081,23 @@ inline nsresult UnexpectedFailure(nsresult rv)
return rv;
}
/* void refreshPrototype (); */
NS_IMETHODIMP XPCWrappedNative::RefreshPrototype()
/* void finishInitForWrappedGlobal (); */
NS_IMETHODIMP XPCWrappedNative::FinishInitForWrappedGlobal()
{
// We can only be called under certain conditions.
MOZ_ASSERT(mScriptableInfo);
MOZ_ASSERT(mScriptableInfo->GetFlags().IsGlobalObject());
MOZ_ASSERT(HasProto());
// Build a CCX.
XPCCallContext ccx(NATIVE_CALLER);
if (!ccx.IsValid())
return UnexpectedFailure(NS_ERROR_FAILURE);
if (!HasProto())
return NS_OK;
if (!mFlatJSObject)
return UnexpectedFailure(NS_ERROR_FAILURE);
JSAutoEnterCompartment ac;
if (!ac.enter(ccx, GetFlatJSObject()))
return UnexpectedFailure(NS_ERROR_FAILURE);
AutoMarkingWrappedNativeProtoPtr oldProto(ccx);
AutoMarkingWrappedNativeProtoPtr newProto(ccx);
oldProto = GetProto();
XPCNativeScriptableInfo *info = oldProto->GetScriptableInfo();
XPCNativeScriptableCreateInfo ci(*info);
newProto = XPCWrappedNativeProto::GetNewOrUsed(ccx, oldProto->GetScope(),
oldProto->GetClassInfo(), &ci,
oldProto->GetOffsetsMasked());
if (!newProto)
return UnexpectedFailure(NS_ERROR_FAILURE);
// If nothing needs to change then we're done.
if (newProto.get() == oldProto.get())
return NS_OK;
if (!JS_SplicePrototype(ccx, GetFlatJSObject(), newProto->GetJSProtoObject()))
return UnexpectedFailure(NS_ERROR_FAILURE);
SetProto(newProto);
if (mScriptableInfo == oldProto->GetScriptableInfo())
UpdateScriptableInfo(newProto->GetScriptableInfo());
// Call PostCreateProrotype.
bool success = GetProto()->CallPostCreatePrototype(ccx);
if (!success)
return NS_ERROR_FAILURE;
return NS_OK;
}