fixes for bug 60303, bug 60356, bug 57370, and bug 58982 r=mccabe sr=hyatt sr=brendan

This commit is contained in:
jband%netscape.com 2000-11-30 06:58:37 +00:00
Родитель c1564bb79e
Коммит 947e54ba96
12 изменённых файлов: 271 добавлений и 83 удалений

Просмотреть файл

@ -163,6 +163,9 @@ interface nsIXPConnectWrappedJS : nsIXPConnectJSObjectHolder
readonly attribute nsIIDPtr IID;
void debugDump(in short depth);
void aggregatedQueryInterface(in nsIIDRef uuid,
[iid_is(uuid),retval] out nsQIResult result);
};
/***************************************************************************/
@ -436,5 +439,27 @@ interface nsIXPConnect : nsISupports
* context to use to execute JavaScript.
*/
void setSafeJSContextForCurrentThread(in JSContextPtr cx);
/**
* wrapJSAggregatedToNative is just like wrapJS except it is used in cases
* where the JSObject is also aggregated to some native xpcom Object.
* At present XBL is the only system that might want to do this.
*
* XXX write more!
*
* Returns:
* success:
* NS_OK
* failure:
* NS_ERROR_XPC_BAD_CONVERT_JS
* NS_ERROR_FAILURE
*/
void
wrapJSAggregatedToNative(in nsISupports aOuter,
in JSContextPtr aJSContext,
in JSObjectPtr aJSObj,
in nsIIDRef aIID,
[iid_is(aIID),retval] out nsQIResult result);
};

Просмотреть файл

@ -91,6 +91,16 @@ static void SetupRegistry()
/***************************************************************************/
#ifdef JS_THREADSAFE
#define DoBeginRequest(cx) JS_BeginRequest((cx))
#define DoEndRequest(cx) JS_EndRequest((cx))
#else
#define DoBeginRequest(cx) ((void)0)
#define DoEndRequest(cx) ((void)0)
#endif
/***************************************************************************/
#define EXITCODE_RUNTIME_ERROR 3
#define EXITCODE_FILE_NOT_FOUND 4
@ -226,6 +236,7 @@ Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
return JS_FALSE;
argv[i] = STRING_TO_JSVAL(str);
filename = JS_GetStringBytes(str);
DoBeginRequest(cx);
script = JS_CompileFile(cx, obj, filename);
if (!script)
ok = JS_FALSE;
@ -233,6 +244,7 @@ Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
ok = JS_ExecuteScript(cx, obj, script, &result);
JS_DestroyScript(cx, script);
}
DoEndRequest(cx);
if (!ok)
return JS_FALSE;
}
@ -475,11 +487,13 @@ Process(JSContext *cx, JSObject *obj, char *filename)
}
}
ungetc(ch, fh);
DoBeginRequest(cx);
script = JS_CompileFileHandle(cx, obj, filename, fh);
if (script) {
(void)JS_ExecuteScript(cx, obj, script, &result);
JS_DestroyScript(cx, script);
}
DoEndRequest(cx);
return;
}
@ -504,8 +518,9 @@ Process(JSContext *cx, JSObject *obj, char *filename)
}
bufp += strlen(bufp);
lineno++;
} while (!JS_BufferIsCompilableUnit(cx, obj,
buffer, strlen(buffer)));
} while (!JS_BufferIsCompilableUnit(cx, obj, buffer, strlen(buffer)));
DoBeginRequest(cx);
/* Clear any pending exception from previous failed compiles. */
JS_ClearPendingException(cx);
script = JS_CompileScript(cx, obj, buffer, strlen(buffer),
@ -542,6 +557,7 @@ Process(JSContext *cx, JSObject *obj, char *filename)
#endif
JS_DestroyScript(cx, script);
}
DoEndRequest(cx);
} while (!hitEOF && !gQuitting);
fprintf(gOutFile, "\n");
return;

Просмотреть файл

@ -539,7 +539,33 @@ nsXPConnect::WrapJS(JSContext * aJSContext, JSObject * aJSObj, const nsIID & aII
nsresult rv;
if(!XPCConvert::JSObject2NativeInterface(aJSContext, result, aJSObj,
&aIID, &rv))
&aIID, nsnull, &rv))
return rv;
return NS_OK;
}
/* void wrapJSAggregatedToNative (in nsISupports aOuter, in JSContextPtr aJSContext, in JSObjectPtr aJSObj, in nsIIDRef aIID, [iid_is (aIID), retval] out nsQIResult result); */
NS_IMETHODIMP
nsXPConnect::WrapJSAggregatedToNative(nsISupports *aOuter, JSContext * aJSContext, JSObject * aJSObj, const nsIID & aIID, void * *result)
{
NS_ENSURE_ARG_POINTER(aOuter);
NS_ENSURE_ARG_POINTER(aJSContext);
NS_ENSURE_ARG_POINTER(aJSObj);
NS_ENSURE_ARG_POINTER(result);
AUTO_PUSH_JSCONTEXT2(aJSContext, this);
*result = nsnull;
// This also ensures that we have a valid runtime
XPCContext* xpcc = GetContext(aJSContext, this);
if(!xpcc)
return NS_ERROR_FAILURE;
SET_CALLER_NATIVE(xpcc);
nsresult rv;
if(!XPCConvert::JSObject2NativeInterface(aJSContext, result, aJSObj,
&aIID, aOuter, &rv))
return rv;
return NS_OK;
}

Просмотреть файл

@ -692,7 +692,8 @@ XPCConvert::JSData2Native(JSContext* cx, void* d, jsval s,
if(!JSVAL_IS_OBJECT(s) || !(obj = JSVAL_TO_OBJECT(s)))
return JS_FALSE;
return JSObject2NativeInterface(cx, (void**)d, obj, iid, pErr);
return JSObject2NativeInterface(cx, (void**)d, obj, iid,
nsnull, pErr);
}
default:
NS_ASSERTION(0, "bad type");
@ -810,7 +811,9 @@ XPCConvert::NativeInterface2JSObject(JSContext* cx,
JSBool
XPCConvert::JSObject2NativeInterface(JSContext* cx,
void** dest, JSObject* src,
const nsID* iid, nsresult* pErr)
const nsID* iid,
nsISupports* aOuter,
nsresult* pErr)
{
NS_ASSERTION(cx, "bad param");
NS_ASSERTION(dest, "bad param");
@ -842,8 +845,12 @@ XPCConvert::JSObject2NativeInterface(JSContext* cx,
// else...
// does the JSObject have 'nsISupportness'? (as do DOM objects)
if(GetISupportsFromJSObject(cx, src, &iface))
// Does the JSObject have 'nsISupportness'? (as do DOM objects.)
// Note that if we have a non-null aOuter then it means that we are
// forcing the creation of a wrapper even if the object *does* have
// 'nsISupportness'. This allows wrapJSAggregatedToNative to work
// with JSObjects that happen to have 'nsISupportness'.
if(!aOuter && GetISupportsFromJSObject(cx, src, &iface))
{
if(iface)
return NS_SUCCEEDED(iface->QueryInterface(*iid, dest));
@ -858,7 +865,7 @@ XPCConvert::JSObject2NativeInterface(JSContext* cx,
if(xpcc)
{
nsXPCWrappedJS* wrappedJS =
nsXPCWrappedJS::GetNewOrUsedWrapper(xpcc, src, *iid);
nsXPCWrappedJS::GetNewOrUsedWrapper(xpcc, src, *iid, aOuter);
if(wrappedJS)
{
*dest = NS_STATIC_CAST(nsXPTCStubBase*, wrappedJS);
@ -973,7 +980,8 @@ XPCConvert::JSValToXPCException(JSContext* cx,
{
return NS_REINTERPRET_CAST(nsIXPCException*,
nsXPCWrappedJS::GetNewOrUsedWrapper(xpcc, obj,
NS_GET_IID(nsIXPCException)));
NS_GET_IID(nsIXPCException),
nsnull));
}
}

Просмотреть файл

@ -46,7 +46,8 @@
* in some more global way at runtime.
*/
struct ResultMap {nsresult rv; const char* name; const char* format;} map[] = {
static struct ResultMap
{nsresult rv; const char* name; const char* format;} map[] = {
#define XPC_MSG_DEF(val, format) \
{(val), #val, format},
#include "xpc.msg"

Просмотреть файл

@ -277,6 +277,7 @@ XPCJSRuntime::SyncXPCContextList(JSContext* cx /* = nsnull */)
if(cx && cx == cur)
found = xpcc;
}
return found;
}

Просмотреть файл

@ -250,10 +250,12 @@ public:
#ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN
void DEBUG_AddWrappedNative(nsIXPConnectWrappedNative* wrapper)
{JS_HashTableAdd(DEBUG_WrappedNativeHashtable, wrapper, wrapper);}
{nsAutoLock lock(mMapLock);
JS_HashTableAdd(DEBUG_WrappedNativeHashtable, wrapper, wrapper);}
void DEBUG_RemoveWrappedNative(nsIXPConnectWrappedNative* wrapper)
{JS_HashTableRemove(DEBUG_WrappedNativeHashtable, wrapper);}
{nsAutoLock lock(mMapLock);
JS_HashTableRemove(DEBUG_WrappedNativeHashtable, wrapper);}
private:
JSHashTable *DEBUG_WrappedNativeHashtable;
@ -751,7 +753,7 @@ public:
NS_DECL_NSIXPCONNECTWRAPPEDJS
// Note that both nsXPTCStubBase and nsIXPConnectWrappedJS declare
// a GetInterfaceInfo methos\d with the same sig. So, the declaration
// GetInterfaceInfo methods with the same sig. So, the declaration
// for it here comes from the NS_DECL_NSIXPCONNECTWRAPPEDJS macro
NS_IMETHOD CallMethod(PRUint16 methodIndex,
@ -765,7 +767,8 @@ public:
*/
static nsXPCWrappedJS* GetNewOrUsedWrapper(XPCContext* xpcc,
JSObject* aJSObj,
REFNSIID aIID);
REFNSIID aIID,
nsISupports* aOuter);
JSObject* GetJSObject() const {return mJSObj;}
nsXPCWrappedJSClass* GetClass() const {return mClass;}
@ -773,23 +776,29 @@ public:
nsXPCWrappedJS* GetRootWrapper() const {return mRoot;}
nsXPCWrappedJS* Find(REFNSIID aIID);
nsXPCWrappedJS* FindInherited(REFNSIID aIID);
JSBool IsValid() const {return mJSObj != nsnull;}
void SystemIsBeingShutDown(JSRuntime* rt);
JSBool IsAggregatedToNative() const {return mRoot->mOuter != nsnull;}
nsISupports* GetAggregatedNativeObject() const {return mRoot->mOuter;}
virtual ~nsXPCWrappedJS();
private:
nsXPCWrappedJS(); // not implemented
nsXPCWrappedJS(XPCContext* xpcc,
JSObject* aJSObj,
nsXPCWrappedJSClass* aClass,
nsXPCWrappedJS* root);
nsXPCWrappedJS* root,
nsISupports* aOuter);
private:
JSObject* mJSObj;
nsXPCWrappedJSClass* mClass;
nsXPCWrappedJS* mRoot;
nsXPCWrappedJS* mNext;
nsISupports* mOuter; // only set in root
};
/***************************************************************************/
@ -1125,7 +1134,9 @@ public:
static JSBool JSObject2NativeInterface(JSContext* cx,
void** dest, JSObject* src,
const nsID* iid, nsresult* pErr);
const nsID* iid,
nsISupports* aOuter,
nsresult* pErr);
static JSBool NativeArray2JS(JSContext* cx,
jsval* d, const void** s,
@ -1373,6 +1384,8 @@ public:
private:
xpcPerThreadData();
void SyncJSContexts();
private:
nsIXPCException* mException;
nsDeque* mJSContextStack;
@ -1515,6 +1528,16 @@ private:
nsCString mCategory;
};
/***************************************************************************/
class AutoJSRequest
{
public:
AutoJSRequest(JSContext* aCX)
: mCX(JS_GetContextThread(aCX) ? (JS_BeginRequest(aCX), aCX) : nsnull) {}
~AutoJSRequest() { if(mCX) JS_EndRequest(mCX); }
private:
JSContext* mCX;
};
/***************************************************************************/
// the include of declarations of the maps comes last because they have

Просмотреть файл

@ -222,8 +222,10 @@ xpcPerThreadData::Cleanup()
if(mOwnSafeJSContext)
{
JS_SetContextThread(mOwnSafeJSContext);
JS_DestroyContext(mOwnSafeJSContext);
mOwnSafeJSContext = nsnull;
SyncJSContexts();
}
}
@ -310,6 +312,7 @@ xpcPerThreadData::GetSafeJSContext()
mSafeJSContext = JS_NewContext(rt, 8192);
if(mSafeJSContext)
{
AutoJSRequest req(mSafeJSContext); // scoped JS Request
JSObject *glob;
glob = JS_NewObject(mSafeJSContext, &global_class, NULL, NULL);
if(!glob ||
@ -342,6 +345,7 @@ xpcPerThreadData::SetSafeJSContext(JSContext *cx)
{
JS_DestroyContext(mOwnSafeJSContext);
mOwnSafeJSContext = nsnull;
SyncJSContexts();
}
mSafeJSContext = cx;
@ -421,3 +425,10 @@ xpcPerThreadData::CleanupAllThreads()
PR_SetThreadPrivate(gTLSIndex, nsnull);
}
void
xpcPerThreadData::SyncJSContexts()
{
nsCOMPtr<nsXPConnect> xpc = dont_AddRef(nsXPConnect::GetXPConnect());
if(xpc)
xpc->SyncJSContexts();
}

Просмотреть файл

@ -40,6 +40,29 @@
// NOTE: much of the fancy footwork is done in xpcstubs.cpp
NS_IMETHODIMP
nsXPCWrappedJS::AggregatedQueryInterface(REFNSIID aIID, void** aInstancePtr)
{
NS_ASSERTION(IsAggregatedToNative(), "bad AggregatedQueryInterface call");
if(!IsValid())
return NS_ERROR_UNEXPECTED;
// Put this here rather that in DelegatedQueryInterface because it needs
// to be in QueryInterface before the possible delegation to 'outer', but
// we don't want to do this check twice in one call in the normal case:
// once in QueryInterface and once in DelegatedQueryInterface.
if(aIID.Equals(NS_GET_IID(nsIXPConnectWrappedJS)))
{
NS_ADDREF(this);
*aInstancePtr = (void*) NS_STATIC_CAST(nsIXPConnectWrappedJS*,this);
return NS_OK;
}
return mClass->DelegatedQueryInterface(this, aIID, aInstancePtr);
}
NS_IMETHODIMP
nsXPCWrappedJS::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
@ -52,25 +75,25 @@ nsXPCWrappedJS::QueryInterface(REFNSIID aIID, void** aInstancePtr)
return NS_ERROR_NULL_POINTER;
}
// Always check for this first so that our 'outer' can get this interface
// from us without recurring into a call to the outer's QI!
if(aIID.Equals(NS_GET_IID(nsIXPConnectWrappedJS)))
{
NS_ADDREF_THIS();
NS_ADDREF(this);
*aInstancePtr = (void*) NS_STATIC_CAST(nsIXPConnectWrappedJS*,this);
return NS_OK;
}
if(aIID.Equals(NS_GET_IID(nsIXPConnectJSObjectHolder)))
{
NS_ADDREF_THIS();
*aInstancePtr = (void*) NS_STATIC_CAST(nsIXPConnectJSObjectHolder*,this);
return NS_OK;
}
nsISupports* outer = GetAggregatedNativeObject();
if(outer)
return outer->QueryInterface(aIID, aInstancePtr);
// else...
return mClass->DelegatedQueryInterface(this, aIID, aInstancePtr);
}
// do chained ref counting
nsrefcnt
@ -90,6 +113,11 @@ nsXPCWrappedJS::Release(void)
{
NS_PRECONDITION(mRoot, "bad root");
NS_PRECONDITION(0 != mRefCnt, "dup release");
#ifdef DEBUG_jband
NS_ASSERTION(IsValid(), "post xpconnect shutdown call of nsXPCWrappedJS::Release");
#endif
nsrefcnt cnt = (nsrefcnt) PR_AtomicDecrement((PRInt32*)&mRefCnt);
NS_LOG_RELEASE(this, cnt, "nsXPCWrappedJS");
if(0 == cnt)
@ -121,7 +149,8 @@ nsXPCWrappedJS::GetJSObject(JSObject** aJSObj)
nsXPCWrappedJS*
nsXPCWrappedJS::GetNewOrUsedWrapper(XPCContext* xpcc,
JSObject* aJSObj,
REFNSIID aIID)
REFNSIID aIID,
nsISupports* aOuter)
{
JSObject2WrappedJSMap* map;
JSObject* rootJSObj;
@ -173,7 +202,8 @@ nsXPCWrappedJS::GetNewOrUsedWrapper(XPCContext* xpcc,
if(rootJSObj == aJSObj)
{
// the root will do double duty as the interface wrapper
wrapper = root = new nsXPCWrappedJS(xpcc, aJSObj, clazz, nsnull);
wrapper = root = new nsXPCWrappedJS(xpcc, aJSObj, clazz, nsnull,
aOuter);
if(root)
{ // scoped lock
nsAutoLock lock(rt->GetMapLock());
@ -190,7 +220,7 @@ nsXPCWrappedJS::GetNewOrUsedWrapper(XPCContext* xpcc,
if(!rootClazz)
goto return_wrapper;
root = new nsXPCWrappedJS(xpcc, rootJSObj, rootClazz, nsnull);
root = new nsXPCWrappedJS(xpcc, rootJSObj, rootClazz, nsnull, aOuter);
NS_RELEASE(rootClazz);
if(!root)
@ -208,7 +238,7 @@ nsXPCWrappedJS::GetNewOrUsedWrapper(XPCContext* xpcc,
if(!wrapper)
{
wrapper = new nsXPCWrappedJS(xpcc, aJSObj, clazz, root);
wrapper = new nsXPCWrappedJS(xpcc, aJSObj, clazz, root, aOuter);
if(!wrapper)
goto return_wrapper;
}
@ -229,11 +259,13 @@ return_wrapper:
nsXPCWrappedJS::nsXPCWrappedJS(XPCContext* xpcc,
JSObject* aJSObj,
nsXPCWrappedJSClass* aClass,
nsXPCWrappedJS* root)
nsXPCWrappedJS* root,
nsISupports* aOuter)
: mJSObj(aJSObj),
mClass(aClass),
mRoot(root ? root : this),
mNext(nsnull)
mNext(nsnull),
mOuter(root ? nsnull : aOuter)
{
#ifdef DEBUG_stats_jband
static int count = 0;
@ -245,6 +277,7 @@ nsXPCWrappedJS::nsXPCWrappedJS(XPCContext* xpcc,
NS_INIT_REFCNT();
NS_ADDREF_THIS();
NS_ADDREF(aClass);
NS_IF_ADDREF(mOuter);
NS_ASSERTION(xpcc && xpcc->GetJSContext(), "bad context");
JS_AddNamedRoot(xpcc->GetJSContext(), &mJSObj,
"nsXPCWrappedJS::mJSObj");
@ -271,6 +304,9 @@ nsXPCWrappedJS::~nsXPCWrappedJS()
JS_RemoveRootRT(rt->GetJSRuntime(), &mJSObj);
}
NS_IF_RELEASE(mClass);
// XXX Should this moved out of the 'if' block?
// XXX OR... Should this called in SystemIsBeingShutDown?
NS_IF_RELEASE(mOuter);
}
if(mNext)
NS_DELETEXPCOM(mNext); // cascaded delete
@ -282,13 +318,37 @@ nsXPCWrappedJS::Find(REFNSIID aIID)
if(aIID.Equals(NS_GET_IID(nsISupports)))
return mRoot;
nsXPCWrappedJS* cur = mRoot;
do
for(nsXPCWrappedJS* cur = mRoot; cur; cur = cur->mNext)
{
if(aIID.Equals(cur->GetIID()))
return cur;
}
} while(nsnull != (cur = cur->mNext));
return nsnull;
}
// check if asking for an interface that some wrapper in the chain inherits from
nsXPCWrappedJS*
nsXPCWrappedJS::FindInherited(REFNSIID aIID)
{
NS_ASSERTION(!aIID.Equals(NS_GET_IID(nsISupports)), "bad call sequence");
for(nsXPCWrappedJS* cur = mRoot; cur; cur = cur->mNext)
{
nsCOMPtr<nsIInterfaceInfo> iface = cur->GetClass()->GetInterfaceInfo();
nsCOMPtr<nsIInterfaceInfo> iface_parent;
// Skip the first iface - we know we don't care about nsISupports here.
while(NS_SUCCEEDED(iface->GetParent(getter_AddRefs(iface_parent))) &&
iface_parent)
{
iface = iface_parent;
PRBool found;
if(NS_SUCCEEDED(iface->IsIID(&aIID, &found)) && found)
return cur;
}
}
return nsnull;
}
@ -391,4 +451,3 @@ nsXPCWrappedJS::DebugDump(PRInt16 depth)
#endif
return NS_OK;
}

Просмотреть файл

@ -91,14 +91,10 @@ nsXPCWrappedJSClass::GetNewOrUsedClass(XPCJSRuntime* rt,
nsAutoLock lock(rt->GetMapLock());
IID2WrappedJSClassMap* map = rt->GetWrappedJSClassMap();
clazz = map->Find(aIID);
NS_IF_ADDREF(clazz);
}
if(clazz)
{
NS_ADDREF(clazz);
}
else
if(!clazz)
{
nsCOMPtr<nsIInterfaceInfoManager> iimgr =
dont_AddRef(nsXPConnect::GetInterfaceInfoManager());
@ -279,18 +275,15 @@ nsXPCWrappedJSClass::DelegatedQueryInterface(nsXPCWrappedJS* self,
REFNSIID aIID,
void** aInstancePtr)
{
nsXPCWrappedJS* sibling;
// This includes checking for nsISupports and the iid of self.
// And it also checks for other wrappers that have been constructed
// for this object.
if(nsnull != (sibling = self->Find(aIID)))
if(aIID.Equals(NS_GET_IID(nsIXPConnectJSObjectHolder)))
{
NS_ADDREF(sibling);
*aInstancePtr = (void*) sibling;
NS_ADDREF(self);
*aInstancePtr = (void*) NS_STATIC_CAST(nsIXPConnectJSObjectHolder*,self);
return NS_OK;
}
// Objects internal to xpconnect are the only objects that even know *how*
// to ask for this iid. And none of them bother refcoutning the thing.
if(aIID.Equals(NS_GET_IID(WrappedJSIdentity)))
{
// asking to find out if this is a wrapper object
@ -298,40 +291,36 @@ nsXPCWrappedJSClass::DelegatedQueryInterface(nsXPCWrappedJS* self,
return NS_OK;
}
// else...
nsXPCWrappedJS* sibling;
// check if asking for an interface that we inherit from
nsCOMPtr<nsIInterfaceInfo> current = GetInterfaceInfo();
nsCOMPtr<nsIInterfaceInfo> parent;
while(NS_SUCCEEDED(current->GetParent(getter_AddRefs(parent))) && parent)
// Checks for any existing wrapper explicitly constructed for this iid.
// This includes the current 'self' wrapper. This also deals with the
// nsISupports case (for which it returns mRoot).
if(nsnull != (sibling = self->Find(aIID)))
{
current = parent;
nsIID* iid;
if(NS_SUCCEEDED(current->GetIID(&iid)) && iid)
{
PRBool found = aIID.Equals(*iid);
nsMemory::Free(iid);
if(found)
{
*aInstancePtr = (void*) self;
NS_ADDREF(self);
return NS_OK;
}
}
NS_ADDREF(sibling);
*aInstancePtr = (void*) sibling;
return NS_OK;
}
// else...
// Check if asking for an interface from which one of our wrappers inherits.
if(nsnull != (sibling = self->FindInherited(aIID)))
{
NS_ADDREF(sibling);
*aInstancePtr = (void*) sibling;
return NS_OK;
}
// else we do the more expensive stuff...
// check if the JSObject claims to implement this interface
JSObject* jsobj = CallQueryInterfaceOnJSObject(self->GetJSObject(), aIID);
if(jsobj)
{
AutoPushCompatibleJSContext autoContext(mRuntime->GetJSRuntime());
JSContext* cx = autoContext.GetJSContext();
if(cx && XPCConvert::JSObject2NativeInterface(cx, aInstancePtr,
jsobj, &aIID, nsnull))
if(cx && XPCConvert::JSObject2NativeInterface(cx, aInstancePtr, jsobj,
&aIID, nsnull, nsnull))
return NS_OK;
}

Просмотреть файл

@ -83,12 +83,11 @@ nsXPCWrappedNativeClass::GetNewOrUsedClass(XPCContext* xpcc,
nsAutoLock lock(rt->GetMapLock());
IID2WrappedNativeClassMap* map = rt->GetWrappedNativeClassMap();
clazz = map->Find(aIID);
}
if(clazz)
{
NS_ADDREF(clazz);
return clazz;
if(clazz)
{
NS_ADDREF(clazz);
return clazz;
}
}
nsCOMPtr<nsIInterfaceInfoManager> iimgr =
@ -558,6 +557,14 @@ nsXPCWrappedNativeClass::CallWrappedMethod(JSContext* cx,
XPCJSRuntime* rt;
nsXPConnect* xpc;
// This is used to gate calls to JS_SuspendRequest/JS_ResumeRequest
// XXX Looking at cx->requestDepth is currently necessary because the DOM
// nsJSContexts break the nice rules and don't do their work within
// JS Requests. Calling JS_SuspendRequest with a zero requestDepth
// would cause the requestDepth to wrap around to a big number and
// Bad Things would happen.
JSBool useJSRequest = JS_GetContextThread(cx) && cx->requestDepth;
#ifdef DEBUG_stats_jband
PRIntervalTime startTime = PR_IntervalNow();
PRIntervalTime endTime = 0;
@ -908,10 +915,16 @@ nsXPCWrappedNativeClass::CallWrappedMethod(JSContext* cx,
ccdata.init(callee, vtblIndex, wrapper, cx, argc, argv, vp);
oldccdata = cc->SetData(&ccdata);
if(useJSRequest)
JS_SuspendRequest(cx);
// do the invoke
invokeResult = XPTC_InvokeByIndex(callee, vtblIndex,
paramCount, dispatchParams);
if(useJSRequest)
JS_ResumeRequest(cx);
xpcc->SetLastResult(invokeResult);
cc->SetData(oldccdata);
@ -1107,6 +1120,7 @@ JSObject*
nsXPCWrappedNativeClass::NewFunObj(JSContext *cx, JSObject *obj,
const XPCNativeMemberDescriptor* desc)
{
JSFunction *fun;
NS_ASSERTION(desc->IsMethod(), "we can only create FunObjs for methods");
if(-1 == desc->argc)
@ -1125,10 +1139,13 @@ nsXPCWrappedNativeClass::NewFunObj(JSContext *cx, JSObject *obj,
return nsnull;
}
JSFunction *fun = JS_NewFunction(cx, WrappedNative_CallMethod,
(uintN) desc->argc,
JSFUN_BOUND_METHOD, obj,
GetMemberName(desc));
{
AutoJSRequest req(cx); // scoped JS Request
fun = JS_NewFunction(cx, WrappedNative_CallMethod,
(uintN) desc->argc,
JSFUN_BOUND_METHOD, obj,
GetMemberName(desc));
}
if(!fun)
return nsnull;
return JS_GetFunctionObject(fun);
@ -1269,6 +1286,7 @@ nsXPCWrappedNativeClass::NewInstanceJSObject(XPCContext* xpcc,
JSObject* aGlobalObject,
nsXPCWrappedNative* self)
{
JSObject* jsobj;
JSContext* cx = xpcc->GetJSContext();
JSClass* jsclazz = self->GetDynamicScriptable() ?
&WrappedNativeWithCall_class :
@ -1279,8 +1297,11 @@ nsXPCWrappedNativeClass::NewInstanceJSObject(XPCContext* xpcc,
// after creation. If we just pass nsnull as the prototype argument, the
// engine will do a scope search for the class name to find the constructor,
// which is an expense we don't need, and will always fail anyway.
JSObject* jsobj = JS_NewObject(cx, jsclazz, aGlobalObject, aGlobalObject);
{
AutoJSRequest req(cx); // scoped JS Request
jsobj = JS_NewObject(cx, jsclazz, aGlobalObject, aGlobalObject);
}
if(!jsobj || !JS_SetPrototype(cx, jsobj, nsnull) ||
!JS_SetPrivate(cx, jsobj, self))
return nsnull;

Просмотреть файл

@ -772,6 +772,14 @@ WrappedNative_Finalize(JSContext *cx, JSObject *obj)
if(!wrapper || !wrapper->IsValid())
return;
#ifdef DEBUG
{
static const int FREQUENCY = 50;
static int hit_count = 0;
//if(!(++hit_count % FREQUENCY))
// NS_ASSERTION(0, "ignore me and see me crash!");
}
#endif
// Defer this push until we know we have a valid wrapper to work with.
// This call can *startup* XPConnect after it has been shutdown!
AUTO_PUSH_JSCONTEXT(cx);