зеркало из https://github.com/mozilla/gecko-dev.git
Associate XPCWrappedNativeScopes with XPCContexts, like the DOM does with windows and contexts, so that we can push a context that's allowed to actually call XPCWrappedJS functions. bug 352791, r=jst sr=brendan
This commit is contained in:
Родитель
8a46efd79a
Коммит
7630d25e2b
|
@ -71,6 +71,7 @@ XPCContext::XPCContext(XPCJSRuntime* aRuntime,
|
|||
{
|
||||
MOZ_COUNT_CTOR(XPCContext);
|
||||
|
||||
PR_INIT_CLIST(&mScopes);
|
||||
for(const char** p = XPC_ARG_FORMATTER_FORMAT_STRINGS; *p; p++)
|
||||
JS_AddArgumentFormatter(mJSContext, *p, XPC_JSArgumentFormatter);
|
||||
}
|
||||
|
@ -80,6 +81,16 @@ XPCContext::~XPCContext()
|
|||
MOZ_COUNT_DTOR(XPCContext);
|
||||
NS_IF_RELEASE(mException);
|
||||
NS_IF_RELEASE(mSecurityManager);
|
||||
|
||||
// Iterate over our scopes and tell them that we have been destroyed
|
||||
for(PRCList *scopeptr = PR_NEXT_LINK(&mScopes);
|
||||
scopeptr != &mScopes;
|
||||
scopeptr = PR_NEXT_LINK(scopeptr))
|
||||
{
|
||||
XPCWrappedNativeScope *scope = (XPCWrappedNativeScope *)scopeptr;
|
||||
scope->SetContext(nsnull);
|
||||
}
|
||||
|
||||
// we do not call JS_RemoveArgumentFormatter because we now only
|
||||
// delete XPCContext *after* the underlying JSContext is dead
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=80:
|
||||
* vim: set ts=8 sw=4 et tw=78:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
@ -109,6 +109,7 @@
|
|||
#include "nsIProperty.h"
|
||||
#include "nsSupportsArray.h"
|
||||
#include "nsTArray.h"
|
||||
#include "prclist.h"
|
||||
|
||||
#include "nsIXPCScriptNotify.h" // used to notify: ScriptEvaluated
|
||||
|
||||
|
@ -695,12 +696,14 @@ private:
|
|||
public:
|
||||
#endif
|
||||
|
||||
// For use by XPCWrappedNativeScope.
|
||||
JSContext2XPCContextMap* GetContextMap() const {return mContextMap;}
|
||||
|
||||
private:
|
||||
XPCJSRuntime(); // no implementation
|
||||
XPCJSRuntime(nsXPConnect* aXPConnect,
|
||||
nsIJSRuntimeService* aJSRuntimeService);
|
||||
|
||||
JSContext2XPCContextMap* GetContextMap() const {return mContextMap;}
|
||||
JSBool GenerateStringIDs(JSContext* cx);
|
||||
void PurgeXPCContextList();
|
||||
|
||||
|
@ -831,6 +834,8 @@ public:
|
|||
}
|
||||
|
||||
void DebugDump(PRInt16 depth);
|
||||
void AddScope(PRCList *scope) { PR_INSERT_AFTER(scope, &mScopes); }
|
||||
void RemoveScope(PRCList *scope) { PR_REMOVE_LINK(scope); }
|
||||
|
||||
~XPCContext();
|
||||
|
||||
|
@ -848,6 +853,9 @@ private:
|
|||
LangType mCallingLangType;
|
||||
PRUint16 mSecurityManagerFlags;
|
||||
JSPackedBool mMarked;
|
||||
|
||||
// A linked list of scopes to notify when we are destroyed.
|
||||
PRCList mScopes;
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -1088,7 +1096,7 @@ xpc_TraceForValidWrapper(JSTracer *trc, XPCWrappedNative* wrapper);
|
|||
/***************************************************************************/
|
||||
// XPCWrappedNativeScope is one-to-one with a JS global object.
|
||||
|
||||
class XPCWrappedNativeScope
|
||||
class XPCWrappedNativeScope : public PRCList
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -1174,6 +1182,9 @@ public:
|
|||
|
||||
void Traverse(nsCycleCollectionTraversalCallback &cb);
|
||||
|
||||
XPCContext *GetContext() { return mContext; }
|
||||
void SetContext(XPCContext *xpcc) { mContext = nsnull; }
|
||||
|
||||
#ifndef XPCONNECT_STANDALONE
|
||||
/**
|
||||
* Fills the hash mapping global object to principal.
|
||||
|
@ -1205,6 +1216,7 @@ private:
|
|||
JSObject* mGlobalJSObject;
|
||||
JSObject* mPrototypeJSObject;
|
||||
JSObject* mPrototypeJSFunction;
|
||||
XPCContext* mContext;
|
||||
|
||||
#ifndef XPCONNECT_STANDALONE
|
||||
// The script object principal instance corresponding to our current global
|
||||
|
|
|
@ -500,6 +500,17 @@ nsXPCWrappedJSClass::IsWrappedJS(nsISupports* aPtr)
|
|||
result == WrappedJSIdentity::GetSingleton();
|
||||
}
|
||||
|
||||
static JSContext *
|
||||
GetContextFromObject(JSObject *obj)
|
||||
{
|
||||
// In order to get a context, we need a context.
|
||||
XPCCallContext ccx(NATIVE_CALLER);
|
||||
XPCWrappedNativeScope* scope =
|
||||
XPCWrappedNativeScope::FindInJSObjectScope(ccx, obj);
|
||||
XPCContext *xpcc = scope->GetContext();
|
||||
return xpcc ? xpcc->GetJSContext() : nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPCWrappedJSClass::DelegatedQueryInterface(nsXPCWrappedJS* self,
|
||||
REFNSIID aIID,
|
||||
|
@ -544,7 +555,9 @@ nsXPCWrappedJSClass::DelegatedQueryInterface(nsXPCWrappedJS* self,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
XPCCallContext ccx(NATIVE_CALLER);
|
||||
|
||||
JSContext *context = GetContextFromObject(self->GetJSObject());
|
||||
XPCCallContext ccx(NATIVE_CALLER, context);
|
||||
if(!ccx.IsValid())
|
||||
{
|
||||
*aInstancePtr = nsnull;
|
||||
|
@ -1048,7 +1061,8 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16 methodIndex,
|
|||
// the whole nsIXPCFunctionThisTranslator bit. That code uses ccx to
|
||||
// convert natives to JSObjects, but we do NOT plan to pass those JSObjects
|
||||
// to our real callee.
|
||||
XPCCallContext ccx(NATIVE_CALLER);
|
||||
JSContext *context = GetContextFromObject(wrapper->GetJSObject());
|
||||
XPCCallContext ccx(NATIVE_CALLER, context);
|
||||
if(ccx.IsValid())
|
||||
{
|
||||
xpcc = ccx.GetXPCContext();
|
||||
|
|
|
@ -151,6 +151,12 @@ XPCWrappedNativeScope::XPCWrappedNativeScope(XPCCallContext& ccx,
|
|||
|
||||
mNext = gScopes;
|
||||
gScopes = this;
|
||||
|
||||
// Grab the XPCContext associated with our context.
|
||||
mContext = mRuntime->GetContextMap()->Find(ccx.GetJSContext());
|
||||
NS_ASSERTION(mContext, "Context map is not synchronized");
|
||||
|
||||
mContext->AddScope(this);
|
||||
}
|
||||
|
||||
if(aGlobal)
|
||||
|
@ -255,6 +261,9 @@ XPCWrappedNativeScope::~XPCWrappedNativeScope()
|
|||
delete mWrappedNativeProtoMap;
|
||||
}
|
||||
|
||||
if(mContext)
|
||||
mContext->RemoveScope(this);
|
||||
|
||||
// XXX we should assert that we are dead or that xpconnect has shutdown
|
||||
// XXX might not want to do this at xpconnect shutdown time???
|
||||
NS_IF_RELEASE(mComponents);
|
||||
|
|
Загрузка…
Ссылка в новой задаче